Free cookie consent management tool by TermsFeed Policy Generator

source: tags/3.3.1/HeuristicLab.Operators.Views.GraphVisualization/3.3/General/GraphVisualizationInfoView.cs @ 11754

Last change on this file since 11754 was 4068, checked in by swagner, 14 years ago

Sorted usings and removed unused usings in entire solution (#1094)

File size: 16.2 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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 System.Threading;
27using System.Windows.Forms;
28using HeuristicLab.Collections;
29using HeuristicLab.MainForm;
30using HeuristicLab.MainForm.WindowsForms;
31using Netron.Diagramming.Core;
32
33namespace HeuristicLab.Operators.Views.GraphVisualization {
34  [View("GraphVisualizationInfo View")]
35  [Content(typeof(IGraphVisualizationInfo), true)]
36  public partial class GraphVisualizationInfoView : AsynchronousContentView {
37    private BidirectionalLookup<IShapeInfo, IShape> shapeInfoShapeMapping;
38    private BidirectionalLookup<IConnectionInfo, IConnection> connectionInfoConnectionMapping;
39    private LinePenStyle connectionPenStyle;
40
41    public GraphVisualizationInfoView() {
42      InitializeComponent();
43      this.shapeInfoShapeMapping = new BidirectionalLookup<IShapeInfo, IShape>();
44      this.connectionInfoConnectionMapping = new BidirectionalLookup<IConnectionInfo, IConnection>();
45      this.connectionPenStyle = new LinePenStyle();
46      this.connectionPenStyle.EndCap = LineCap.ArrowAnchor;
47    }
48
49    public IController Controller {
50      get { return this.graphVisualization.Controller; }
51    }
52
53    public new IGraphVisualizationInfo Content {
54      get { return (IGraphVisualizationInfo)base.Content; }
55      set { base.Content = value; }
56    }
57
58    protected override void OnContentChanged() {
59      base.OnContentChanged();
60      this.UpdateContent();
61    }
62
63    protected override void SetEnabledStateOfControls() {
64      base.SetEnabledStateOfControls();
65      DeleteTool deleteTool = (DeleteTool)this.Controller.Tools.Where(t => t.Name == ControllerBase.DeleteToolName).FirstOrDefault();
66      HeuristicLab.Netron.Controller controller = this.Controller as HeuristicLab.Netron.Controller;
67      if (Content == null && deleteTool != null && controller != null)
68        controller.RemoveTool(deleteTool);
69      else {
70        if ((ReadOnly || Locked) && deleteTool != null && controller != null)
71          controller.RemoveTool(deleteTool);
72        else if ((!ReadOnly && !Locked) && deleteTool == null)
73          this.Controller.AddTool(new DeleteTool(ControllerBase.DeleteToolName));
74      }
75    }
76
77    private void UpdateContent() {
78      foreach (IConnectionInfo connectionInfo in this.connectionInfoConnectionMapping.FirstValues.ToList())
79        this.RemoveConnectionInfo(connectionInfo);
80      this.connectionInfoConnectionMapping.Clear();
81      foreach (IShapeInfo shapeInfo in this.shapeInfoShapeMapping.FirstValues.ToList())
82        this.RemoveShapeInfo(shapeInfo);
83      this.shapeInfoShapeMapping.Clear();
84
85      if (Content != null) {
86        foreach (IShapeInfo shapeInfo in this.Content.ShapeInfos)
87          this.AddShapeInfo(shapeInfo);
88        foreach (IConnectionInfo connectionInfo in this.Content.ConnectionInfos)
89          this.AddConnectionInfo(connectionInfo);
90        this.UpdateLayoutRoot();
91      }
92    }
93    private void UpdateLayoutRoot() {
94      IShapeInfo shapeInfo = this.Content.InitialShape;
95      if (shapeInfo != null)
96        this.graphVisualization.Controller.Model.LayoutRoot = this.shapeInfoShapeMapping.GetByFirst(shapeInfo);
97      else
98        this.graphVisualization.Controller.Model.LayoutRoot = null;
99    }
100    private void VisualizationInfo_InitialShapeChanged(object sender, EventArgs e) {
101      this.UpdateLayoutRoot();
102    }
103
104    protected override void RegisterContentEvents() {
105      base.RegisterContentEvents();
106      this.Content.InitialShapeChanged += new EventHandler(VisualizationInfo_InitialShapeChanged);
107
108      this.Content.ObserveableShapeInfos.ItemsAdded += new CollectionItemsChangedEventHandler<IShapeInfo>(ShapeInfos_ItemsAdded);
109      this.Content.ObserveableShapeInfos.ItemsRemoved += new CollectionItemsChangedEventHandler<IShapeInfo>(ShapeInfos_ItemsRemoved);
110      this.Content.ObserveableShapeInfos.CollectionReset += new CollectionItemsChangedEventHandler<IShapeInfo>(ShapeInfos_CollectionReset);
111
112      this.Content.ObservableConnectionInfos.ItemsAdded += new CollectionItemsChangedEventHandler<IConnectionInfo>(ConnectionInfos_ItemsAdded);
113      this.Content.ObservableConnectionInfos.ItemsRemoved += new CollectionItemsChangedEventHandler<IConnectionInfo>(ConnectionInfos_ItemsRemoved);
114      this.Content.ObservableConnectionInfos.CollectionReset += new CollectionItemsChangedEventHandler<IConnectionInfo>(ConnectionInfos_CollectionReset);
115    }
116
117    protected override void DeregisterContentEvents() {
118      base.DeregisterContentEvents();
119      this.Content.InitialShapeChanged -= new EventHandler(VisualizationInfo_InitialShapeChanged);
120
121      this.Content.ObserveableShapeInfos.ItemsAdded -= new CollectionItemsChangedEventHandler<IShapeInfo>(ShapeInfos_ItemsAdded);
122      this.Content.ObserveableShapeInfos.ItemsRemoved -= new CollectionItemsChangedEventHandler<IShapeInfo>(ShapeInfos_ItemsRemoved);
123      this.Content.ObserveableShapeInfos.CollectionReset -= new CollectionItemsChangedEventHandler<IShapeInfo>(ShapeInfos_CollectionReset);
124
125      this.Content.ObservableConnectionInfos.ItemsAdded -= new CollectionItemsChangedEventHandler<IConnectionInfo>(ConnectionInfos_ItemsAdded);
126      this.Content.ObservableConnectionInfos.ItemsRemoved -= new CollectionItemsChangedEventHandler<IConnectionInfo>(ConnectionInfos_ItemsRemoved);
127      this.Content.ObservableConnectionInfos.CollectionReset -= new CollectionItemsChangedEventHandler<IConnectionInfo>(ConnectionInfos_CollectionReset);
128    }
129
130    #region ShapeInfos
131    private void ShapeInfos_CollectionReset(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IShapeInfo> e) {
132      foreach (IShapeInfo shapeInfo in e.OldItems)
133        this.RemoveShapeInfo(shapeInfo);
134      foreach (IShapeInfo shapeInfo in e.Items)
135        this.AddShapeInfo(shapeInfo);
136    }
137    private void ShapeInfos_ItemsAdded(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IShapeInfo> e) {
138      foreach (IShapeInfo shapeInfo in e.Items)
139        this.AddShapeInfo(shapeInfo);
140    }
141    private void ShapeInfos_ItemsRemoved(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IShapeInfo> e) {
142      foreach (IShapeInfo shapeInfo in e.Items)
143        this.RemoveShapeInfo(shapeInfo);
144    }
145
146    private void AddShapeInfo(IShapeInfo shapeInfo) {
147      this.RegisterShapeInfoEvents(shapeInfo);
148      IShape shape = shapeInfo.CreateShape();
149      this.RegisterShapeEvents(shape);
150      this.shapeInfoShapeMapping.Add(shapeInfo, shape);
151
152      this.graphVisualization.Controller.Model.AddShape(shape);
153      this.graphVisualization.Invalidate();
154    }
155    private void RemoveShapeInfo(IShapeInfo shapeInfo) {
156      this.DeregisterShapeInfoEvents(shapeInfo);
157      IShape shape = this.shapeInfoShapeMapping.GetByFirst(shapeInfo);
158      this.DeregisterShapeEvents(shape);
159      this.shapeInfoShapeMapping.RemoveByFirst(shapeInfo);
160
161      if (this.graphVisualization.Controller.Model.Shapes.Contains(shape)) {
162        this.graphVisualization.Controller.Model.RemoveShape(shape);
163        this.graphVisualization.Controller.Model.Selection.Clear();
164        this.graphVisualization.Invalidate();
165      }
166    }
167
168    private void RegisterShapeInfoEvents(IShapeInfo shapeInfo) {
169      shapeInfo.Changed += new EventHandler(shapeInfo_Changed);
170    }
171    private void DeregisterShapeInfoEvents(IShapeInfo shapeInfo) {
172      shapeInfo.Changed -= new EventHandler(shapeInfo_Changed);
173    }
174
175    private void shapeInfo_Changed(object sender, EventArgs e) {
176      IShapeInfo shapeInfo = (IShapeInfo)sender;
177      IShape shape = this.shapeInfoShapeMapping.GetByFirst(shapeInfo);
178      this.DeregisterShapeEvents(shape);
179      shapeInfo.UpdateShape(shape);
180      shape.Invalidate();
181      this.RegisterShapeEvents(shape);
182    }
183    #endregion
184
185    #region ConnectionInfos
186    private void ConnectionInfos_CollectionReset(object sender, CollectionItemsChangedEventArgs<IConnectionInfo> e) {
187      foreach (IConnectionInfo connectionInfo in e.Items)
188        this.RemoveConnectionInfo(connectionInfo);
189      foreach (IConnectionInfo connectionInfo in e.Items)
190        this.AddConnectionInfo(connectionInfo);
191    }
192    private void ConnectionInfos_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IConnectionInfo> e) {
193      foreach (IConnectionInfo connectionInfo in e.Items)
194        this.AddConnectionInfo(connectionInfo);
195    }
196    private void ConnectionInfos_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IConnectionInfo> e) {
197      foreach (IConnectionInfo connectionInfo in e.Items)
198        this.RemoveConnectionInfo(connectionInfo);
199    }
200
201    private void AddConnectionInfo(IConnectionInfo connectionInfo) {
202      this.RegisterConnectionInfoEvents(connectionInfo);
203      IShape shapeFrom = this.shapeInfoShapeMapping.GetByFirst(connectionInfo.From);
204      IShape shapeTo = this.shapeInfoShapeMapping.GetByFirst(connectionInfo.To);
205
206      IConnector connectorFrom = shapeFrom.Connectors.Where(c => c.Name == connectionInfo.ConnectorFrom).FirstOrDefault();
207      IConnector connectorTo = shapeTo.Connectors.Where(c => c.Name == connectionInfo.ConnectorTo).FirstOrDefault();
208      if (connectorFrom != null && connectorTo != null) {
209        Connection connection = new Connection(connectorFrom.Point, connectorTo.Point);
210        connection.From.AllowMove = false;
211        connection.To.AllowMove = false;
212        connectorFrom.AttachConnector(connection.From);
213        connectorTo.AttachConnector(connection.To);
214        connection.PenStyle = this.connectionPenStyle;
215        this.connectionInfoConnectionMapping.Add(connectionInfo, connection);
216        this.graphVisualization.Controller.Model.AddConnection(connection);
217        this.graphVisualization.Invalidate();
218      }
219    }
220
221    private void RemoveConnectionInfo(IConnectionInfo connectionInfo) {
222      DeregisterConnectionInfoEvents(connectionInfo);
223      IConnection connection = this.connectionInfoConnectionMapping.GetByFirst(connectionInfo);
224      this.connectionInfoConnectionMapping.RemoveByFirst(connectionInfo);
225      this.RemoveConnection(connection);
226
227    }
228    private void RemoveConnection(IConnection connection) {
229      if (connection.From.AttachedTo != null)
230        connection.From.DetachFromParent();
231      if (connection.To.AttachedTo != null)
232        connection.To.DetachFromParent();
233      if (this.Controller.Model.Connections.Contains(connection)) {
234        this.graphVisualization.Controller.Model.Remove(connection);
235        this.graphVisualization.Invalidate();
236      }
237    }
238
239    private void RegisterConnectionInfoEvents(IConnectionInfo connectionInfo) {
240      connectionInfo.Changed += new EventHandler(connectionInfo_Changed);
241    }
242    private void DeregisterConnectionInfoEvents(IConnectionInfo connectionInfo) {
243      connectionInfo.Changed -= new EventHandler(connectionInfo_Changed);
244    }
245    private void connectionInfo_Changed(object sender, EventArgs e) {
246      IConnectionInfo connectionInfo = (IConnectionInfo)sender;
247      IConnection connection = this.connectionInfoConnectionMapping.GetByFirst(connectionInfo);
248      this.RemoveConnectionInfo(connectionInfo);
249      this.AddConnectionInfo(connectionInfo);
250    }
251    #endregion
252
253    #region netron events - shapes, graphvisualization
254    private void RegisterShapeEvents(IShape shape) {
255      shape.OnEntityChange += new EventHandler<EntityEventArgs>(shape_OnEntityChange);
256      shape.OnMouseEnter += new EventHandler<EntityMouseEventArgs>(shape_OnMouseEnter);
257      shape.OnMouseLeave += new EventHandler<EntityMouseEventArgs>(shape_OnMouseLeave);
258    }
259
260    private void DeregisterShapeEvents(IShape shape) {
261      shape.OnEntityChange -= new EventHandler<EntityEventArgs>(shape_OnEntityChange);
262      shape.OnMouseEnter -= new EventHandler<EntityMouseEventArgs>(shape_OnMouseEnter);
263      shape.OnMouseLeave -= new EventHandler<EntityMouseEventArgs>(shape_OnMouseLeave);
264    }
265
266    private Cursor oldCursor;
267    private void shape_OnMouseEnter(object sender, EntityMouseEventArgs e) {
268      this.oldCursor = this.Cursor;
269      this.Controller.View.CurrentCursor = CursorPalette.Move;
270    }
271
272    private void shape_OnMouseLeave(object sender, EntityMouseEventArgs e) {
273      this.Controller.View.CurrentCursor = this.oldCursor;
274      this.oldCursor = null;
275    }
276
277    private void shape_OnEntityChange(object sender, EntityEventArgs e) {
278      IShape shape = e.Entity as IShape;
279      IShapeInfo shapeInfo = this.shapeInfoShapeMapping.GetBySecond(shape);
280      this.DeregisterShapeInfoEvents(shapeInfo);
281      shapeInfo.UpdateShapeInfo(shape);
282      this.RegisterShapeInfoEvents(shapeInfo);
283      this.graphVisualization.Invalidate();
284    }
285
286
287    private void graphVisualization_OnEntityAdded(object sender, EntityEventArgs e) {
288      IConnection connection = e.Entity as IConnection;
289      if (connection != null && !this.connectionInfoConnectionMapping.ContainsSecond(connection)) {
290        IConnector connectorFrom = connection.From.AttachedTo;
291        IConnector connectorTo = connection.To.AttachedTo;
292        this.RemoveConnection(connection); //is added again by the model events
293
294        if (connectorFrom != null && connectorTo != null) {
295          IShape shapeFrom = (IShape)connectorFrom.Parent;
296          IShape shapeTo = (IShape)connectorTo.Parent;
297          IShapeInfo shapeInfoFrom = this.shapeInfoShapeMapping.GetBySecond(shapeFrom);
298          IShapeInfo shapeInfoTo = this.shapeInfoShapeMapping.GetBySecond(shapeTo);
299          string connectorFromName = connectorFrom.Name;
300          string connectorToName = connectorTo.Name;
301
302          if (shapeInfoFrom != shapeInfoTo) //avoid self references
303            this.Content.AddConnectionInfo(new ConnectionInfo(shapeInfoFrom, connectorFromName, shapeInfoTo, connectorToName));
304        }
305      }
306    }
307
308    private void graphVisualization_OnEntityRemoved(object sender, EntityEventArgs e) {
309      IShape shape = e.Entity as IShape;
310      if (shape != null && this.shapeInfoShapeMapping.ContainsSecond(shape)) {
311        IShapeInfo shapeInfo = this.shapeInfoShapeMapping.GetBySecond(shape);
312        this.Content.RemoveShapeInfo(shapeInfo);
313      }
314
315      IConnection connection = e.Entity as IConnection;
316      if (connection != null && this.connectionInfoConnectionMapping.ContainsSecond(connection)) {
317        IConnectionInfo connectionInfo = connectionInfoConnectionMapping.GetBySecond(connection);
318        this.Content.RemoveConnectionInfo(connectionInfo);
319      }
320    }
321    #endregion
322
323    public void RelayoutGraph() {
324      if (this.shapeInfoShapeMapping.Count > 0
325        && this.connectionInfoConnectionMapping.Count > 0
326        && this.Content.InitialShape != null) { //otherwise the layout does not work
327        string layoutName = "Standard TreeLayout";
328        this.graphVisualization.Controller.RunActivity(layoutName);
329        this.graphVisualization.Invalidate();
330
331        //fix to avoid negative shape positions after layouting
332        Thread.Sleep(300);
333        int minX = this.graphVisualization.Controller.Model.Shapes.Min(s => s.Location.X);
334        int shiftX = minX < 0 ? Math.Abs(minX) + 50 : 0;
335        int minY = this.graphVisualization.Controller.Model.Shapes.Min(s => s.Location.Y);
336        int shiftY = minY < 0 ? Math.Abs(minY) + 50 : 0;
337        if (minX < 0 || minY < 0) {
338          foreach (IShape s in this.Controller.Model.Shapes)
339            s.MoveBy(new Point(shiftX, shiftY));
340        }
341      }
342    }
343  }
344}
Note: See TracBrowser for help on using the repository browser.