Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/GraphVisualizationInfoView.cs @ 2898

Last change on this file since 2898 was 2893, checked in by mkommend, 14 years ago

added context menu to OperatorGraphView (ticket #867)

File size: 17.3 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.Collections.Generic;
24using System.ComponentModel;
25using System.Drawing;
26using System.Data;
27using System.Linq;
28using System.Text;
29using System.Windows.Forms;
30using HeuristicLab.MainForm;
31using HeuristicLab.Core;
32using HeuristicLab.Core.Views;
33using Netron.Diagramming.Core;
34using HeuristicLab.Parameters;
35using HeuristicLab.MainForm.WindowsForms;
36using HeuristicLab.Collections;
37
38namespace HeuristicLab.Operators.Views.GraphVisualization {
39  [Content(typeof(GraphVisualizationInfo), false)]
40  public partial class GraphVisualizationInfoView : ContentView {
41    private BidirectionalLookup<IShapeInfo, IShape> shapeInfoShapeMapping;
42    private BidirectionalLookup<IShapeInfo, INotifyObservableDictionaryItemsChanged<string, IShapeInfo>> shapeInfoConnectionsMapping;
43    private BidirectionalLookup<IConnection, KeyValuePair<IConnector, IConnector>> connectionConnectorsMapping;
44
45    private bool causedUpdateOfShapeInfo;
46    public GraphVisualizationInfoView() {
47      InitializeComponent();
48      this.causedUpdateOfShapeInfo = false;
49      this.shapeInfoShapeMapping = new BidirectionalLookup<IShapeInfo, IShape>();
50      this.shapeInfoConnectionsMapping = new BidirectionalLookup<IShapeInfo, INotifyObservableDictionaryItemsChanged<string, IShapeInfo>>();
51      this.connectionConnectorsMapping = new BidirectionalLookup<IConnection, KeyValuePair<IConnector, IConnector>>();
52    }
53
54    public GraphVisualizationInfoView(GraphVisualizationInfo content)
55      : this() {
56      this.Content = content;
57    }
58
59    public IController Controller {
60      get { return this.graphVisualization.Controller; }
61    }
62
63    public new GraphVisualizationInfo Content {
64      get { return (GraphVisualizationInfo)base.Content; }
65      set { base.Content = value; }
66    }
67
68    protected override void OnContentChanged() {
69      base.OnContentChanged();
70      this.UpdateContent();
71    }
72
73    private void UpdateContent() {
74      foreach (IShapeInfo shapeInfo in this.shapeInfoShapeMapping.FirstValues)
75        this.RemoveShapeInfo(shapeInfo);
76
77      this.shapeInfoShapeMapping.Clear();
78      this.shapeInfoConnectionsMapping.Clear();
79      this.connectionConnectorsMapping.Clear();
80
81      foreach (IShapeInfo shapeInfo in this.Content.ShapeInfos)
82        if (!this.shapeInfoShapeMapping.ContainsFirst(shapeInfo))
83          this.AddShapeInfo(shapeInfo);
84
85      foreach (KeyValuePair<KeyValuePair<IShapeInfo, string>, IShapeInfo> connection in this.Content.Connections)
86        this.AddConnection(connection.Key.Key, connection.Key.Value, connection.Value);
87
88      this.UpdateLayoutRoot();
89    }
90
91    private void UpdateLayoutRoot() {
92      IShapeInfo shapeInfo = this.Content.InitialShape;
93      if (shapeInfo != null)
94        this.graphVisualization.Controller.Model.LayoutRoot = this.shapeInfoShapeMapping.GetByFirst(shapeInfo);
95      else
96        this.graphVisualization.Controller.Model.LayoutRoot = null;
97    }
98
99    private void VisualizationInfo_InitialShapeChanged(object sender, EventArgs e) {
100      this.UpdateLayoutRoot();
101    }
102
103    protected override void RegisterContentEvents() {
104      base.RegisterContentEvents();
105      this.Content.InitialShapeChanged += new EventHandler(VisualizationInfo_InitialShapeChanged);
106      this.Content.ObserveableShapeInfos.ItemsAdded += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IShapeInfo>(ShapeInfos_ItemsAdded);
107      this.Content.ObserveableShapeInfos.ItemsRemoved += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IShapeInfo>(ShapeInfos_ItemsRemoved);
108      this.Content.ObserveableShapeInfos.CollectionReset += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IShapeInfo>(ShapeInfos_CollectionReset);
109
110      this.Content.ObservableConnections.ItemsAdded += new CollectionItemsChangedEventHandler<KeyValuePair<KeyValuePair<IShapeInfo, string>, IShapeInfo>>(Connections_ItemsAdded);
111      this.Content.ObservableConnections.ItemsRemoved += new CollectionItemsChangedEventHandler<KeyValuePair<KeyValuePair<IShapeInfo, string>, IShapeInfo>>(Connections_ItemsRemoved);
112      this.Content.ObservableConnections.ItemsReplaced += new CollectionItemsChangedEventHandler<KeyValuePair<KeyValuePair<IShapeInfo, string>, IShapeInfo>>(Connections_ItemsReplaced);
113      this.Content.ObservableConnections.CollectionReset += new CollectionItemsChangedEventHandler<KeyValuePair<KeyValuePair<IShapeInfo, string>, IShapeInfo>>(Connections_CollectionReset);
114    }
115
116    protected override void DeregisterContentEvents() {
117      base.DeregisterContentEvents();
118      this.Content.InitialShapeChanged -= new EventHandler(VisualizationInfo_InitialShapeChanged);
119      this.Content.ObserveableShapeInfos.ItemsAdded -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IShapeInfo>(ShapeInfos_ItemsAdded);
120      this.Content.ObserveableShapeInfos.ItemsRemoved -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IShapeInfo>(ShapeInfos_ItemsRemoved);
121      this.Content.ObserveableShapeInfos.CollectionReset -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IShapeInfo>(ShapeInfos_CollectionReset);
122
123      this.Content.ObservableConnections.ItemsAdded -= new CollectionItemsChangedEventHandler<KeyValuePair<KeyValuePair<IShapeInfo, string>, IShapeInfo>>(Connections_ItemsAdded);
124      this.Content.ObservableConnections.ItemsRemoved -= new CollectionItemsChangedEventHandler<KeyValuePair<KeyValuePair<IShapeInfo, string>, IShapeInfo>>(Connections_ItemsRemoved);
125      this.Content.ObservableConnections.ItemsReplaced -= new CollectionItemsChangedEventHandler<KeyValuePair<KeyValuePair<IShapeInfo, string>, IShapeInfo>>(Connections_ItemsReplaced);
126      this.Content.ObservableConnections.CollectionReset -= new CollectionItemsChangedEventHandler<KeyValuePair<KeyValuePair<IShapeInfo, string>, IShapeInfo>>(Connections_CollectionReset);
127    }
128
129    private void ShapeInfos_CollectionReset(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IShapeInfo> e) {
130      foreach (IShapeInfo shapeInfo in e.OldItems)
131        this.RemoveShapeInfo(shapeInfo);
132      foreach (IShapeInfo shapeInfo in e.Items)
133        this.AddShapeInfo(shapeInfo);
134    }
135
136    private void ShapeInfos_ItemsAdded(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IShapeInfo> e) {
137      foreach (IShapeInfo shapeInfo in e.Items)
138        this.AddShapeInfo(shapeInfo);
139    }
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
149      IShape shape = shapeInfo.CreateShape();
150      shape.OnEntityChange += new EventHandler<EntityEventArgs>(shape_OnEntityChange);
151      this.shapeInfoShapeMapping.Add(shapeInfo, shape);
152
153      this.graphVisualization.Controller.Model.AddShape(shape);
154      this.graphVisualization.Invalidate();
155    }
156
157    private void RemoveShapeInfo(IShapeInfo shapeInfo) {
158      this.DeregisterShapeInfoEvents(shapeInfo);
159      IShape shape = this.shapeInfoShapeMapping.GetByFirst(shapeInfo);
160      shape.OnEntityChange -= new EventHandler<EntityEventArgs>(shape_OnEntityChange);
161
162      IConnection connection;
163      foreach (IConnector connector in shape.Connectors) {
164        connection = this.GetConnection(shapeInfo, connector.Name);
165        this.RemoveConnection(connection);
166      }
167
168      this.shapeInfoShapeMapping.RemoveByFirst(shapeInfo);
169      this.shapeInfoConnectionsMapping.RemoveByFirst(shapeInfo);
170
171      if (this.graphVisualization.Controller.Model.Shapes.Contains(shape)) {
172        this.graphVisualization.Controller.Model.RemoveShape(shape);
173      }
174      this.graphVisualization.Invalidate();
175    }
176
177    private void RegisterShapeInfoEvents(IShapeInfo shapeInfo) {
178      shapeInfo.Changed += new ChangedEventHandler(shapeInfo_Changed);
179    }
180
181    private void DeregisterShapeInfoEvents(IShapeInfo shapeInfo) {
182      shapeInfo.Changed -= new ChangedEventHandler(shapeInfo_Changed);
183    }
184
185    private void Connections_CollectionReset(object sender, CollectionItemsChangedEventArgs<KeyValuePair<KeyValuePair<IShapeInfo, string>, IShapeInfo>> e) {
186      IConnection connection;
187      foreach (KeyValuePair<KeyValuePair<IShapeInfo, string>, IShapeInfo> pair in e.Items) {
188        connection = this.GetConnection(pair.Key.Key, pair.Key.Value);
189        this.RemoveConnection(connection);
190      }
191      foreach (KeyValuePair<KeyValuePair<IShapeInfo, string>, IShapeInfo> pair in e.Items)
192        this.AddConnection(pair.Key.Key, pair.Key.Value, pair.Value);
193    }
194
195    private void Connections_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<KeyValuePair<KeyValuePair<IShapeInfo, string>, IShapeInfo>> e) {
196      IConnection connection;
197      foreach (KeyValuePair<KeyValuePair<IShapeInfo, string>, IShapeInfo> pair in e.Items) {
198        connection = this.GetConnection(pair.Key.Key, pair.Key.Value);
199        this.RemoveConnection(connection);
200      }
201      foreach (KeyValuePair<KeyValuePair<IShapeInfo, string>, IShapeInfo> pair in e.Items)
202        this.AddConnection(pair.Key.Key, pair.Key.Value, pair.Value);
203    }
204
205    private void Connections_ItemsAdded(object sender, CollectionItemsChangedEventArgs<KeyValuePair<KeyValuePair<IShapeInfo, string>, IShapeInfo>> e) {
206      foreach (KeyValuePair<KeyValuePair<IShapeInfo, string>, IShapeInfo> pair in e.Items)
207        this.AddConnection(pair.Key.Key, pair.Key.Value, pair.Value);
208    }
209
210    private void Connections_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<KeyValuePair<KeyValuePair<IShapeInfo, string>, IShapeInfo>> e) {
211      IConnection connection;
212      foreach (KeyValuePair<KeyValuePair<IShapeInfo, string>, IShapeInfo> pair in e.Items) {
213        connection = this.GetConnection(pair.Key.Key, pair.Key.Value);
214        this.RemoveConnection(connection);
215      }
216    }
217
218    private void AddConnection(IShapeInfo shapeInfoFrom, string connectorName, IShapeInfo shapeInfoTo) {
219      IShape shapeFrom = this.shapeInfoShapeMapping.GetByFirst(shapeInfoFrom);
220      IShape shapeTo = this.shapeInfoShapeMapping.GetByFirst(shapeInfoTo);
221
222      IConnector connectorFrom = shapeFrom.Connectors.Where(c => c.Name == connectorName).First();
223      IConnector connectorTo = shapeTo.Connectors.Where(c => c.Name == "Predecessor").FirstOrDefault();
224      KeyValuePair<IConnector, IConnector> connectorPair = new KeyValuePair<IConnector, IConnector>(connectorFrom, connectorTo);
225      if (!this.connectionConnectorsMapping.ContainsSecond(connectorPair)) {
226        IConnection connection = Factory.CreateConnection(connectorFrom, connectorTo);
227        this.connectionConnectorsMapping.Add(connection, connectorPair);
228        this.graphVisualization.Controller.Model.AddConnection(connection);
229        this.graphVisualization.Invalidate();
230      }
231    }
232
233    private IConnection GetConnection(IShapeInfo shapeInfoFrom, string connectorName) {
234      IShape shape = this.shapeInfoShapeMapping.GetByFirst(shapeInfoFrom);
235      IConnector connector = shape.Connectors.Where(c => c.Name == connectorName).First();
236
237      if (!this.connectionConnectorsMapping.SecondValues.Any(p => p.Key == connector))
238        return null;
239
240      KeyValuePair<IConnector, IConnector> connectorPair = this.connectionConnectorsMapping.SecondValues.Where(p => p.Key == connector).FirstOrDefault();
241      return this.connectionConnectorsMapping.GetBySecond(connectorPair);
242    }
243
244    private void ChangeConnection(IShapeInfo shapeInfoFrom, string connectorName, IShapeInfo shapeInfoTo) {
245      IConnection connection = this.GetConnection(shapeInfoFrom, connectorName);
246      IShape shapeTo = this.shapeInfoShapeMapping.GetByFirst(shapeInfoFrom);
247      IConnector connectorTo = shapeTo.Connectors.Where(c => c.Name == "Predecessor").First();
248
249      connection.To.DetachFromParent();
250      connection.To.AttachTo(connectorTo);
251      this.graphVisualization.Invalidate();
252    }
253
254    private void RemoveConnection(IConnection connection) {
255      if (connection == null)
256        return;
257
258      if (connection.From.AttachedTo != null)
259        connection.From.DetachFromParent();
260      if (connection.To.AttachedTo != null)
261        connection.To.DetachFromParent();
262
263      if (this.connectionConnectorsMapping.ContainsFirst(connection))
264        this.connectionConnectorsMapping.RemoveByFirst(connection);
265      if (this.graphVisualization.Controller.Model.Connections.Contains(connection))
266        this.graphVisualization.Controller.Model.Remove(connection);
267      this.graphVisualization.Invalidate();
268    }
269
270
271    private void shapeInfo_Changed(object sender, ChangedEventArgs e) {
272      if (this.causedUpdateOfShapeInfo)
273        return;
274
275      IShapeInfo shapeInfo = (IShapeInfo)sender;
276      IShape shape = this.shapeInfoShapeMapping.GetByFirst(shapeInfo);
277      shapeInfo.UpdateShape(shape);
278      shape.Invalidate();
279    }
280
281
282    private void shape_OnEntityChange(object sender, EntityEventArgs e) {
283      this.causedUpdateOfShapeInfo = true;
284      IShape shape = e.Entity as IShape;
285      IShapeInfo shapeInfo = this.shapeInfoShapeMapping.GetBySecond(shape);
286
287      shapeInfo.Location = shape.Location;
288      shapeInfo.Size = new Size(shape.Width, shape.Height);
289
290      this.graphVisualization.Invalidate();
291      this.causedUpdateOfShapeInfo = false;
292    }
293
294    private void graphVisualization_OnEntityAdded(object sender, EntityEventArgs e) {
295      IConnection connection = e.Entity as IConnection;
296      if (connection != null && !this.connectionConnectorsMapping.ContainsFirst(connection)) {
297        IConnector connectorFrom = connection.From.AttachedTo;
298        IConnector connectorTo = connection.To.AttachedTo;
299        this.RemoveConnection(connection); //is added again by the model events
300
301        if (connectorFrom != null && connectorTo != null) {
302          IShape shapeFrom = (IShape)connectorFrom.Parent;
303          IShape shapeTo = (IShape)connectorTo.Parent;
304          IShapeInfo shapeInfoFrom = this.shapeInfoShapeMapping.GetBySecond(shapeFrom);
305          IShapeInfo shapeInfoTo = this.shapeInfoShapeMapping.GetBySecond(shapeTo);
306          string connectorName = connectorFrom.Name;
307
308          this.Content.AddConnection(shapeInfoFrom, connectorName, shapeInfoTo);
309        }
310      }
311    }
312
313    private void graphVisualization_OnEntityRemoved(object sender, EntityEventArgs e) {
314      IShape shape = e.Entity as IShape;
315      if (shape != null && this.shapeInfoShapeMapping.ContainsSecond(shape)) {
316        IShapeInfo shapeInfo = this.shapeInfoShapeMapping.GetBySecond(shape);
317        this.Content.RemoveShapeInfo(shapeInfo);
318      }
319
320      IConnection connection = e.Entity as IConnection;
321      if (connection != null && this.connectionConnectorsMapping.ContainsFirst(connection)) {
322        IShape parentShape = (IShape)connection.From.AttachedTo.Parent;
323        IShapeInfo shapeInfo = this.shapeInfoShapeMapping.GetBySecond(parentShape);
324        string connectorName = connection.From.AttachedTo.Name;
325
326        this.Content.RemoveConnection(shapeInfo, connectorName);
327      }
328    }
329
330    #region methods for toolbar items
331    internal void RelayoutOperatorGraph() {
332      if (this.shapeInfoShapeMapping.Count > 0
333        && this.connectionConnectorsMapping.Count > 0
334        && this.Content.InitialShape != null) { //otherwise the layout does not work
335        string layoutName = "Standard TreeLayout";
336        this.graphVisualization.Controller.RunActivity(layoutName);
337        this.graphVisualization.Invalidate();
338      }
339    }
340
341    internal void ActivateConnectionTool() {
342      this.graphVisualization.Controller.ActivateTool(ControllerBase.ConnectionToolName);
343    }
344
345    internal void ActivateZoomAreaTool() {
346      this.graphVisualization.Controller.ActivateTool(ControllerBase.ZoomAreaToolName);
347    }
348
349    internal void ActivateZoomInTool() {
350      this.graphVisualization.Controller.ActivateTool(ControllerBase.ZoomInToolName);
351    }
352
353    internal void ActivateZoomOutTool() {
354      this.graphVisualization.Controller.ActivateTool(ControllerBase.ZoomOutToolName);
355    }
356
357    internal void ActivatePanTool() {
358      this.graphVisualization.Controller.ActivateTool(ControllerBase.PanToolName);
359    }
360
361    internal void ActivateSelectTool() {
362      this.graphVisualization.Controller.ActivateTool(ControllerBase.SelectionToolName);
363    }
364    #endregion
365  }
366}
Note: See TracBrowser for help on using the repository browser.