Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/Primitives/PortRectangle.cs @ 13833

Last change on this file since 13833 was 13833, checked in by jkarder, 8 years ago

#2205: worked on optimization networks

  • added layout algorithm prototype
  • fixed bug in LoadVisualProperties methods
File size: 9.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Drawing;
24using System.Drawing.Drawing2D;
25using System.Linq;
26using HeuristicLab.Common;
27using HeuristicLab.Core.Networks;
28using HeuristicLab.Visualization;
29
30namespace HeuristicLab.Networks.Views.NetworkVisualization {
31  [Primitive(typeof(IPort), true)]
32  public class PortRectangle : FixedSizeRectangle, INetworkItemPrimitive<IPort> {
33    private const int size = 10;
34
35    protected readonly INodeVisualProperties nodeVisualProperties;
36
37    protected IPortVisualProperties VisualProperties {
38      get { return (IPortVisualProperties)networkItem.VisualProperties; }
39      set {
40        if (networkItem.VisualProperties == value) return;
41        networkItem.VisualProperties = value;
42      }
43    }
44    protected bool IgnoreVisualPropertiesChanges { get; set; }
45
46    public override Size Size {
47      get {
48        return new Size((int)Math.Round(size * Chart.WorldToPixelRatio.Width),
49                        (int)Math.Round(size * Chart.WorldToPixelRatio.Height));
50      }
51    }
52
53    protected IPort networkItem;
54    public IPort NetworkItem {
55      get { return networkItem; }
56      set {
57        if (networkItem == value) return;
58        if (networkItem != null) DeregisterNetworkItemEvents();
59        networkItem = value;
60        if (networkItem != null) RegisterNetworkItemEvents();
61        LoadVisualProperties();
62        OnNetworkItemChanged();
63      }
64    }
65
66    public override Brush Brush {
67      get { return base.Brush; }
68      set {
69        if (base.Brush == value) return;
70        base.Brush = value;
71        SaveVisualProperties();
72      }
73    }
74
75    public override Pen Pen {
76      get { return base.Pen; }
77      set {
78        if (base.Pen == value) return;
79        base.Pen = value;
80        SaveVisualProperties();
81      }
82    }
83
84    public PortRectangle(IChart chart, IPort port, INode node)
85      : base(chart, PointD.Empty, Size.Empty) {
86      nodeVisualProperties = (INodeVisualProperties)node.VisualProperties;
87      nodeVisualProperties.Changed += NodeVisualProperties_Changed;
88      NetworkItem = port;
89    }
90
91    protected virtual void RegisterNetworkItemEvents() {
92      if (VisualProperties != null) {
93        VisualProperties.Changed += VisualProperties_Changed;
94      }
95      networkItem.NameChanged += NetworkItem_NameChanged;
96      var connectablePort = networkItem as IConnectablePort;
97      if (connectablePort != null) {
98        connectablePort.ConnectedPortChanged += Port_ConnectedPortChanged;
99      }
100    }
101
102    protected virtual void DeregisterNetworkItemEvents() {
103      if (VisualProperties != null) {
104        VisualProperties.Changed -= VisualProperties_Changed;
105      }
106      networkItem.NameChanged -= NetworkItem_NameChanged;
107      var connectablePort = networkItem as IConnectablePort;
108      if (connectablePort != null) {
109        connectablePort.ConnectedPortChanged -= Port_ConnectedPortChanged;
110      }
111    }
112
113    #region Overrides
114    public override void SetPosition(PointD point) {
115      base.SetPosition(point);
116      SaveVisualProperties();
117    }
118
119    public override void Draw(Graphics graphics) {
120      base.Draw(graphics);
121
122      var p = Chart.TransformWorldToPixel(Point);
123
124      if (networkItem != null && VisualProperties != null) {
125        using (var font = new Font(FontFamily.GenericSansSerif, (float)Math.Round(8.25 * Chart.WorldToPixelRatio.Width))) {
126          var textSize = graphics.MeasureString(networkItem.Name, font);
127          var vp = VisualProperties;
128          switch (vp.Orientation) {
129            case Orientation.North: p = new Point((int)(p.X - textSize.Width / 2), (int)(p.Y - Size.Height - textSize.Height)); break;
130            case Orientation.East: p = new Point(p.X + Size.Width, (int)(p.Y - textSize.Height / 2)); break;
131            case Orientation.South: p = new Point((int)(p.X - textSize.Width / 2), p.Y + Size.Height); break;
132            case Orientation.West: p = new Point((int)(p.X - Size.Width - textSize.Width), (int)(p.Y - textSize.Height / 2)); break;
133          }
134
135          graphics.DrawString(networkItem.Name, font, Brushes.Black, p);
136        }
137      }
138    }
139
140    public override void PostDraw(Graphics graphics) {
141      base.PostDraw(graphics);
142
143      if (Selected) {
144        var p = Chart.TransformWorldToPixel(Point);
145        using (var pen = new Pen(Color.LightGray, 3) { DashStyle = DashStyle.Dash })
146          graphics.DrawRectangle(pen, p.X - Size.Width / 2, p.Y - Size.Height / 2, Size.Width, Size.Height);
147      }
148    }
149
150    #endregion
151
152    #region Events
153
154    public event EventHandler NetworkItemChanged;
155
156    protected virtual void OnNetworkItemChanged() {
157      var handler = NetworkItemChanged;
158      if (handler != null) handler(this, EventArgs.Empty);
159    }
160
161    #endregion
162
163    #region Event Handlers
164
165    private void NodeVisualProperties_Changed(object sender, EventArgs e) {
166      if (IgnoreVisualPropertiesChanges) return;
167
168      LoadVisualProperties();
169    }
170
171    private void VisualProperties_Changed(object sender, EventArgs e) {
172      if (IgnoreVisualPropertiesChanges) return;
173
174      LoadVisualProperties();
175    }
176
177    private void NetworkItem_NameChanged(object sender, EventArgs e) {
178      OnRedrawRequired();
179    }
180
181    private void Port_ConnectedPortChanged(object sender, EventArgs e) {
182      var connectionLines = Chart.Group.GetAllPrimitives(Point).OfType<ConnectionLine>();
183      var outgoingLines = connectionLines.Where(x => x.StartPortRectangle == this);
184      foreach (var l in outgoingLines) Chart.Group.Remove(l);
185
186      var connectablePort = (IConnectablePort)networkItem;
187      var connectedPort = connectablePort.ConnectedPort as IConnectablePort;
188      if (connectedPort == null) return;
189
190      var nodeRectangles = Chart.Group.Primitives.OfType<NodeRectangle>();
191      PortRectangle endPortRectangle = null;
192      foreach (var nodeRectangle in nodeRectangles) {
193        endPortRectangle = (PortRectangle)nodeRectangle.GetPortPrimitive(connectedPort);
194        if (endPortRectangle != null) break;
195      }
196
197      if (endPortRectangle == null) return;
198
199      var connectionShape = new ConnectionLine(Chart, this, endPortRectangle);
200      Chart.Group.Add(connectionShape);
201    }
202
203    #endregion
204
205    #region Helpers
206    private void LoadVisualProperties() {
207      IPortVisualProperties vp = new PortVisualProperties();
208
209      if (networkItem != null)
210        if (VisualProperties == null) VisualProperties = vp;
211        else vp = VisualProperties;
212
213      IgnoreVisualPropertiesChanges = true;
214      try {
215        var p = PointD.Empty;
216        double nodeWidth = nodeVisualProperties.UpperRight.X - nodeVisualProperties.LowerLeft.X;
217        double nodeHeight = nodeVisualProperties.UpperRight.Y - nodeVisualProperties.LowerLeft.Y;
218
219        switch (vp.Orientation) {
220          case Orientation.North:
221            p.X = nodeVisualProperties.LowerLeft.X + vp.Offset * nodeWidth;
222            p.Y = nodeVisualProperties.UpperRight.Y;
223            break;
224          case Orientation.East:
225            p.X = nodeVisualProperties.UpperRight.X;
226            p.Y = nodeVisualProperties.UpperRight.Y - vp.Offset * nodeHeight;
227            break;
228          case Orientation.South:
229            p.X = nodeVisualProperties.UpperRight.X - vp.Offset * nodeWidth;
230            p.Y = nodeVisualProperties.LowerLeft.Y;
231            break;
232          case Orientation.West:
233            p.X = nodeVisualProperties.LowerLeft.X;
234            p.Y = nodeVisualProperties.LowerLeft.Y + vp.Offset * nodeHeight;
235            break;
236        }
237
238        SetPosition(p);
239        Brush = new SolidBrush(vp.BrushColor);
240        Pen = new Pen(vp.PenColor);
241      } finally { IgnoreVisualPropertiesChanges = false; }
242    }
243
244    private void SaveVisualProperties() {
245      if (networkItem == null || IgnoreVisualPropertiesChanges) return;
246
247      var vp = VisualProperties;
248      IgnoreVisualPropertiesChanges = true;
249      try {
250        var lowerLeft = nodeVisualProperties.LowerLeft;
251        var upperRight = nodeVisualProperties.UpperRight;
252
253        if (lowerLeft.X <= Point.X && Point.X <= upperRight.X) {
254          // check N/S
255          if (Point.Y.IsAlmost(upperRight.Y)) {
256            vp.Orientation = Orientation.North;
257            vp.Offset = (Point.X - lowerLeft.X) / (upperRight.X - lowerLeft.X);
258          } else if (Point.Y.IsAlmost(lowerLeft.Y)) {
259            vp.Orientation = Orientation.South;
260            vp.Offset = (upperRight.X - Point.X) / (upperRight.X - lowerLeft.X);
261          }
262        }
263        if (lowerLeft.Y <= Point.Y && Point.Y <= upperRight.Y) {
264          // check E/W
265          if (Point.X.IsAlmost(upperRight.X)) {
266            vp.Orientation = Orientation.East;
267            vp.Offset = (upperRight.Y - Point.Y) / (upperRight.Y - lowerLeft.Y);
268          } else if (Point.X.IsAlmost(lowerLeft.X)) {
269            vp.Orientation = Orientation.West;
270            vp.Offset = (Point.Y - lowerLeft.Y) / (upperRight.Y - lowerLeft.Y);
271          }
272        }
273
274        vp.BrushColor = ((SolidBrush)Brush).Color;
275        vp.PenColor = Pen.Color;
276      } finally { IgnoreVisualPropertiesChanges = false; }
277    }
278
279    #endregion
280  }
281}
Note: See TracBrowser for help on using the repository browser.