Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2205: worked on optimization networks

  • improved network visualization
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      if (VisualProperties == null)
208        VisualProperties = new PortVisualProperties();
209
210      var vp = VisualProperties;
211      IgnoreVisualPropertiesChanges = true;
212      try {
213        var p = PointD.Empty;
214        double nodeWidth = nodeVisualProperties.UpperRight.X - nodeVisualProperties.LowerLeft.X;
215        double nodeHeight = nodeVisualProperties.UpperRight.Y - nodeVisualProperties.LowerLeft.Y;
216
217        switch (vp.Orientation) {
218          case Orientation.North:
219            p.X = nodeVisualProperties.LowerLeft.X + vp.Offset * nodeWidth;
220            p.Y = nodeVisualProperties.UpperRight.Y;
221            break;
222          case Orientation.East:
223            p.X = nodeVisualProperties.UpperRight.X;
224            p.Y = nodeVisualProperties.UpperRight.Y - vp.Offset * nodeHeight;
225            break;
226          case Orientation.South:
227            p.X = nodeVisualProperties.UpperRight.X - vp.Offset * nodeWidth;
228            p.Y = nodeVisualProperties.LowerLeft.Y;
229            break;
230          case Orientation.West:
231            p.X = nodeVisualProperties.LowerLeft.X;
232            p.Y = nodeVisualProperties.LowerLeft.Y + vp.Offset * nodeHeight;
233            break;
234        }
235
236        SetPosition(p);
237        Brush = new SolidBrush(vp.BrushColor);
238        Pen = new Pen(vp.PenColor);
239      } finally { IgnoreVisualPropertiesChanges = false; }
240    }
241
242    private void SaveVisualProperties() {
243      if (networkItem == null || IgnoreVisualPropertiesChanges) return;
244
245      var vp = VisualProperties;
246      IgnoreVisualPropertiesChanges = true;
247      try {
248        var lowerLeft = nodeVisualProperties.LowerLeft;
249        var upperRight = nodeVisualProperties.UpperRight;
250
251        if (lowerLeft.X <= Point.X && Point.X <= upperRight.X) {
252          // check N/S
253          if (Point.Y.IsAlmost(upperRight.Y)) {
254            vp.Orientation = Orientation.North;
255            vp.Offset = (Point.X - lowerLeft.X) / (upperRight.X - lowerLeft.X);
256          } else if (Point.Y.IsAlmost(lowerLeft.Y)) {
257            vp.Orientation = Orientation.South;
258            vp.Offset = (upperRight.X - Point.X) / (upperRight.X - lowerLeft.X);
259          }
260        }
261        if (lowerLeft.Y <= Point.Y && Point.Y <= upperRight.Y) {
262          // check E/W
263          if (Point.X.IsAlmost(upperRight.X)) {
264            vp.Orientation = Orientation.East;
265            vp.Offset = (upperRight.Y - Point.Y) / (upperRight.Y - lowerLeft.Y);
266          } else if (Point.X.IsAlmost(lowerLeft.X)) {
267            vp.Orientation = Orientation.West;
268            vp.Offset = (Point.Y - lowerLeft.Y) / (upperRight.Y - lowerLeft.Y);
269          }
270        }
271
272        vp.BrushColor = ((SolidBrush)Brush).Color;
273        vp.PenColor = Pen.Color;
274      } finally { IgnoreVisualPropertiesChanges = false; }
275    }
276
277    #endregion
278  }
279}
Note: See TracBrowser for help on using the repository browser.