Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2205: worked on optimization networks

  • refactored network visualization
File size: 9.2 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 bool IgnoreVisualPropertiesChanges { get; set; }
38
39    public override Size Size {
40      get {
41        return new Size((int)Math.Round(size * Chart.WorldToPixelRatio.Width),
42                        (int)Math.Round(size * Chart.WorldToPixelRatio.Height));
43      }
44    }
45
46    protected IPort networkItem;
47    public IPort NetworkItem {
48      get { return networkItem; }
49      set {
50        if (networkItem == value) return;
51        if (networkItem != null) DeregisterNetworkItemEvents();
52        networkItem = value;
53        if (networkItem != null) RegisterNetworkItemEvents();
54        LoadVisualProperties();
55        OnNetworkItemChanged();
56      }
57    }
58
59    public PortRectangle(IChart chart, IPort port, INode node)
60      : base(chart, PointD.Empty, Size.Empty, Pens.Black, Brushes.Red) {
61      nodeVisualProperties = (INodeVisualProperties)node.VisualProperties;
62      nodeVisualProperties.Changed += NodeVisualProperties_Changed;
63      NetworkItem = port;
64    }
65
66    protected virtual void RegisterNetworkItemEvents() {
67      networkItem.NameChanged += NetworkItem_NameChanged;
68      if (networkItem.VisualProperties != null) {
69        networkItem.VisualProperties.Changed += VisualProperties_Changed;
70      }
71      var connectablePort = networkItem as IConnectablePort;
72      if (connectablePort != null) {
73        connectablePort.ConnectedPortChanged += Port_ConnectedPortChanged;
74      }
75    }
76
77    protected virtual void DeregisterNetworkItemEvents() {
78      networkItem.NameChanged -= NetworkItem_NameChanged;
79      if (networkItem.VisualProperties != null) {
80        networkItem.VisualProperties.Changed -= VisualProperties_Changed;
81      }
82      var connectablePort = networkItem as IConnectablePort;
83      if (connectablePort != null) {
84        connectablePort.ConnectedPortChanged -= Port_ConnectedPortChanged;
85      }
86    }
87
88    #region Overrides
89    public override void SetPosition(PointD point) {
90      base.SetPosition(point);
91      SaveVisualProperties();
92    }
93
94    public override void Draw(Graphics graphics) {
95      base.Draw(graphics);
96
97      var p = Chart.TransformWorldToPixel(Point);
98
99      if (networkItem != null && networkItem.VisualProperties != null) {
100        using (var font = new Font(FontFamily.GenericSansSerif, (float)Math.Round(8.25 * Chart.WorldToPixelRatio.Width))) {
101          var textSize = graphics.MeasureString(networkItem.Name, font);
102          var vp = (IPortVisualProperties)networkItem.VisualProperties;
103          switch (vp.Orientation) {
104            case Orientation.North: p = new Point((int)(p.X - textSize.Width / 2), (int)(p.Y - Size.Height - textSize.Height)); break;
105            case Orientation.East: p = new Point(p.X + Size.Width, (int)(p.Y - textSize.Height / 2)); break;
106            case Orientation.South: p = new Point((int)(p.X - textSize.Width / 2), p.Y + Size.Height); break;
107            case Orientation.West: p = new Point((int)(p.X - Size.Width - textSize.Width), (int)(p.Y - textSize.Height / 2)); break;
108          }
109
110          graphics.DrawString(networkItem.Name, font, Brushes.Black, p);
111        }
112      }
113    }
114
115    public override void PostDraw(Graphics graphics) {
116      base.PostDraw(graphics);
117
118      if (Selected) {
119        var p = Chart.TransformWorldToPixel(Point);
120        using (var pen = new Pen(Color.LightGray, 3) { DashStyle = DashStyle.Dash })
121          graphics.DrawRectangle(pen, p.X - Size.Width / 2, p.Y - Size.Height / 2, Size.Width, Size.Height);
122      }
123    }
124
125    #endregion
126
127    #region Events
128
129    public event EventHandler NetworkItemChanged;
130
131    protected virtual void OnNetworkItemChanged() {
132      var handler = NetworkItemChanged;
133      if (handler != null) handler(this, EventArgs.Empty);
134    }
135
136    #endregion
137
138    #region Event Handlers
139
140    private void NodeVisualProperties_Changed(object sender, EventArgs e) {
141      if (IgnoreVisualPropertiesChanges) return;
142
143      LoadVisualProperties();
144    }
145
146    private void VisualProperties_Changed(object sender, EventArgs e) {
147      if (IgnoreVisualPropertiesChanges) return;
148
149      LoadVisualProperties();
150    }
151
152    private void NetworkItem_NameChanged(object sender, EventArgs e) {
153      OnRedrawRequired();
154    }
155
156    private void Port_ConnectedPortChanged(object sender, EventArgs e) {
157      var connectionLines = Chart.Group.GetAllPrimitives(Point).OfType<ConnectionLine>();
158      var outgoingLines = connectionLines.Where(x => x.StartPortRectangle == this);
159      foreach (var l in outgoingLines) Chart.Group.Remove(l);
160
161      var connectablePort = (IConnectablePort)networkItem;
162      var connectedPort = connectablePort.ConnectedPort as IConnectablePort;
163      if (connectedPort == null) return;
164
165      var nodeRectangles = Chart.Group.Primitives.OfType<NodeRectangle>();
166      PortRectangle endPortRectangle = null;
167      foreach (var nodeRectangle in nodeRectangles) {
168        endPortRectangle = (PortRectangle)nodeRectangle.GetPortPrimitive(connectedPort);
169        if (endPortRectangle != null) break;
170      }
171
172      if (endPortRectangle == null) return;
173
174      var connectionShape = new ConnectionLine(Chart, this, endPortRectangle);
175      Chart.Group.Add(connectionShape);
176    }
177
178    #endregion
179
180    #region Helpers
181
182    private IPortVisualProperties CreateDefaultVisualProperties() {
183      return new PortVisualProperties(Orientation.South, 0.5);
184    }
185
186    private void LoadVisualProperties() {
187      if (networkItem.VisualProperties == null)
188        networkItem.VisualProperties = CreateDefaultVisualProperties();
189
190      var vp = (IPortVisualProperties)networkItem.VisualProperties;
191      var p = PointD.Empty;
192      double nodeWidth = nodeVisualProperties.UpperRight.X - nodeVisualProperties.LowerLeft.X;
193      double nodeHeight = nodeVisualProperties.UpperRight.Y - nodeVisualProperties.LowerLeft.Y;
194
195      switch (vp.Orientation) {
196        case Orientation.North:
197          p.X = nodeVisualProperties.LowerLeft.X + vp.Offset * nodeWidth;
198          p.Y = nodeVisualProperties.UpperRight.Y;
199          break;
200        case Orientation.East:
201          p.X = nodeVisualProperties.UpperRight.X;
202          p.Y = nodeVisualProperties.UpperRight.Y - vp.Offset * nodeHeight;
203          break;
204        case Orientation.South:
205          p.X = nodeVisualProperties.UpperRight.X - vp.Offset * nodeWidth;
206          p.Y = nodeVisualProperties.LowerLeft.Y;
207          break;
208        case Orientation.West:
209          p.X = nodeVisualProperties.LowerLeft.X;
210          p.Y = nodeVisualProperties.LowerLeft.Y + vp.Offset * nodeHeight;
211          break;
212      }
213
214      SetPosition(p);
215    }
216
217    private void SaveVisualProperties() {
218      if (networkItem == null) return;
219
220      var vp = (IPortVisualProperties)networkItem.VisualProperties;
221
222      IgnoreVisualPropertiesChanges = true;
223      try {
224        var lowerLeft = nodeVisualProperties.LowerLeft;
225        var upperRight = nodeVisualProperties.UpperRight;
226
227        if (lowerLeft.X <= Point.X && Point.X <= upperRight.X) {
228          // check N/S
229          if (Point.Y.IsAlmost(upperRight.Y)) {
230            vp.Orientation = Orientation.North;
231            vp.Offset = (Point.X - lowerLeft.X) / (upperRight.X - lowerLeft.X);
232          } else if (Point.Y.IsAlmost(lowerLeft.Y)) {
233            vp.Orientation = Orientation.South;
234            vp.Offset = (upperRight.X - Point.X) / (upperRight.X - lowerLeft.X);
235          }
236        }
237        if (lowerLeft.Y <= Point.Y && Point.Y <= upperRight.Y) {
238          // check E/W
239          if (Point.X.IsAlmost(upperRight.X)) {
240            vp.Orientation = Orientation.East;
241            vp.Offset = (upperRight.Y - Point.Y) / (upperRight.Y - lowerLeft.Y);
242          } else if (Point.X.IsAlmost(lowerLeft.X)) {
243            vp.Orientation = Orientation.West;
244            vp.Offset = (Point.Y - lowerLeft.Y) / (upperRight.Y - lowerLeft.Y);
245          }
246        }
247      } finally {
248        IgnoreVisualPropertiesChanges = false;
249      }
250    }
251
252    #endregion
253  }
254}
Note: See TracBrowser for help on using the repository browser.