Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/Model/GraphVisualizationInfo.cs @ 2893

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

added context menu to OperatorGraphView (ticket #867)

File size: 13.6 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 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.Linq;
25using System.Text;
26using HeuristicLab.Core;
27using Netron.Diagramming.Core;
28using System.Drawing;
29using HeuristicLab.Collections;
30
31namespace HeuristicLab.Operators.Views.GraphVisualization {
32  public sealed class GraphVisualizationInfo : DeepCloneable {
33    private BidirectionalLookup<IOperator, IShapeInfo> shapeInfoMapping;
34    private BidirectionalLookup<IOperator, IObservableKeyedCollection<string, IParameter>> operatorParameterCollectionMapping;
35    private Dictionary<IValueParameter<IOperator>, IOperator> parameterOperatorMapping;
36
37    private GraphVisualizationInfo() {
38      this.shapeInfoMapping = new BidirectionalLookup<IOperator, IShapeInfo>();
39      this.operatorParameterCollectionMapping = new BidirectionalLookup<IOperator, IObservableKeyedCollection<string, IParameter>>();
40      this.parameterOperatorMapping = new Dictionary<IValueParameter<IOperator>, IOperator>();
41
42      this.shapeInfos = new ObservableSet<IShapeInfo>();
43      this.connections = new ObservableDictionary<KeyValuePair<IShapeInfo, string>, IShapeInfo>();
44    }
45
46    public GraphVisualizationInfo(OperatorGraph operatorGraph)
47      : this() {
48      this.operatorGraph = operatorGraph;
49      this.operatorGraph.InitialOperatorChanged += new EventHandler(operatorGraph_InitialOperatorChanged);
50      operatorGraph.Operators.ItemsAdded += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IOperator>(Operators_ItemsAdded);
51      operatorGraph.Operators.ItemsRemoved += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IOperator>(Operators_ItemsRemoved);
52      operatorGraph.Operators.CollectionReset += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IOperator>(Operators_CollectionReset);
53
54      foreach (IOperator op in operatorGraph.Operators)
55        if (!this.shapeInfoMapping.ContainsFirst(op))
56          this.AddOperator(op);
57
58      this.UpdateInitialShape();
59    }
60
61    public event EventHandler InitialShapeChanged;
62    private void operatorGraph_InitialOperatorChanged(object sender, EventArgs e) {
63      this.UpdateInitialShape();
64    }
65
66    private void UpdateInitialShape() {
67      OperatorShapeInfo old = this.oldInitialShape as OperatorShapeInfo;
68      if (old != null)
69        old.HeadColor = oldInitialShapeColor;
70
71      OperatorShapeInfo newInitialShapeInfo = this.InitialShape as OperatorShapeInfo;
72      if (newInitialShapeInfo != null) {
73        oldInitialShapeColor = newInitialShapeInfo.HeadColor;
74        newInitialShapeInfo.HeadColor = Color.LightGreen;
75      }
76
77      oldInitialShape = this.InitialShape;
78      if (this.InitialShapeChanged != null)
79        this.InitialShapeChanged(this, new EventArgs());
80    }
81
82    private IShapeInfo oldInitialShape;
83    private Color oldInitialShapeColor;
84    public IShapeInfo InitialShape {
85      get {
86        IOperator op = this.operatorGraph.InitialOperator;
87        if (op == null)
88          return null;
89        return this.shapeInfoMapping.GetByFirst(op);
90      }
91      set {
92        if (value == null)
93          this.OperatorGraph.InitialOperator = null;
94        else
95          this.OperatorGraph.InitialOperator = this.shapeInfoMapping.GetBySecond(value);
96      }
97    }
98
99    private OperatorGraph operatorGraph;
100    public OperatorGraph OperatorGraph {
101      get { return this.operatorGraph; }
102    }
103
104    private ObservableSet<IShapeInfo> shapeInfos;
105    public INotifyObservableCollectionItemsChanged<IShapeInfo> ObserveableShapeInfos {
106      get { return this.shapeInfos; }
107    }
108    public IEnumerable<IShapeInfo> ShapeInfos {
109      get { return this.shapeInfos; }
110    }
111    public IOperator GetOperatorForShapeInfo(IShapeInfo shapeInfo) {
112      return this.shapeInfoMapping.GetBySecond(shapeInfo);
113    }
114
115    private ObservableDictionary<KeyValuePair<IShapeInfo, string>, IShapeInfo> connections;
116    public INotifyObservableDictionaryItemsChanged<KeyValuePair<IShapeInfo, string>, IShapeInfo> ObservableConnections {
117      get { return this.connections; }
118    }
119    public IEnumerable<KeyValuePair<KeyValuePair<IShapeInfo, string>, IShapeInfo>> Connections {
120      get { return this.connections; }
121    }
122
123    #region methods to manipulate operatorgraph by the shape info
124    internal void AddShapeInfo(IOperator op, IShapeInfo shapeInfo) {
125      this.RegisterOperatorEvents(op);
126      this.operatorParameterCollectionMapping.Add(op, op.Parameters);
127      this.shapeInfoMapping.Add(op, shapeInfo);
128      this.shapeInfos.Add(shapeInfo);
129
130      foreach (IParameter param in op.Parameters)
131        this.AddParameter(op, param);
132
133      this.operatorGraph.Operators.Add(op);
134    }
135
136    internal void RemoveShapeInfo(IShapeInfo shapeInfo) {
137      IOperator op = this.shapeInfoMapping.GetBySecond(shapeInfo);
138      this.operatorGraph.Operators.Remove(op);
139    }
140
141    internal void AddConnection(IShapeInfo shapeInfoFrom, string connectorName, IShapeInfo shapeInfoTo) {
142      IOperator opFrom = this.shapeInfoMapping.GetBySecond(shapeInfoFrom);
143      IOperator opTo = this.shapeInfoMapping.GetBySecond(shapeInfoTo);
144
145      IValueParameter<IOperator> param = (IValueParameter<IOperator>)opFrom.Parameters[connectorName];
146      param.Value = opTo;
147    }
148
149    internal void ChangeConnection(IShapeInfo shapeInfoFrom, string connectorName, IShapeInfo shapeInfoTo) {
150      IOperator opFrom = this.shapeInfoMapping.GetBySecond(shapeInfoFrom);
151      IOperator opTo = this.shapeInfoMapping.GetBySecond(shapeInfoTo);
152
153      IValueParameter<IOperator> param = (IValueParameter<IOperator>)opFrom.Parameters[connectorName];
154      param.Value = opTo;
155    }
156
157    internal void RemoveConnection(IShapeInfo shapeInfoFrom, string connectorName) {
158      IOperator opFrom = this.shapeInfoMapping.GetBySecond(shapeInfoFrom);
159      IValueParameter<IOperator> param = (IValueParameter<IOperator>)opFrom.Parameters[connectorName];
160      param.Value = null;
161    }
162    #endregion
163
164    #region operator events
165    private void AddOperator(IOperator op) {
166      if (!this.shapeInfoMapping.ContainsFirst(op)) {
167        this.RegisterOperatorEvents(op);
168        IShapeInfo shapeInfo = Factory.CreateShapeInfo(op);
169        this.operatorParameterCollectionMapping.Add(op, op.Parameters);
170        this.shapeInfoMapping.Add(op, shapeInfo);
171        foreach (IParameter param in op.Parameters)
172          this.AddParameter(op, param);
173
174        this.shapeInfos.Add(shapeInfo);
175      }
176    }
177
178    private void RemoveOperator(IOperator op) {
179      this.DeregisterOperatorEvents(op);
180      foreach (IParameter param in op.Parameters)
181        this.RemoveParameter(op, param);
182
183      IShapeInfo shapeInfo = this.shapeInfoMapping.GetByFirst(op);
184      this.operatorParameterCollectionMapping.RemoveByFirst(op);
185      this.shapeInfoMapping.RemoveByFirst(op);
186      this.shapeInfos.Remove(shapeInfo);
187    }
188
189    private void Operators_ItemsAdded(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IOperator> e) {
190      foreach (IOperator op in e.Items)
191        this.AddOperator(op);
192    }
193    private void Operators_ItemsRemoved(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IOperator> e) {
194      foreach (IOperator op in e.Items)
195        this.RemoveOperator(op);
196    }
197    private void Operators_CollectionReset(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IOperator> e) {
198      foreach (IOperator op in e.OldItems)
199        this.RemoveOperator(op);
200      foreach (IOperator op in e.Items)
201        this.AddOperator(op);
202    }
203
204    private void RegisterOperatorEvents(IOperator op) {
205      op.Parameters.ItemsAdded += new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsAdded);
206      op.Parameters.ItemsRemoved += new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsRemoved);
207      op.Parameters.ItemsReplaced += new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsReplaced);
208      op.Parameters.CollectionReset += new CollectionItemsChangedEventHandler<IParameter>(Parameters_CollectionReset);
209    }
210    private void DeregisterOperatorEvents(IOperator op) {
211      op.Parameters.ItemsAdded -= new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsAdded);
212      op.Parameters.ItemsRemoved -= new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsRemoved);
213      op.Parameters.ItemsReplaced -= new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsReplaced);
214      op.Parameters.CollectionReset -= new CollectionItemsChangedEventHandler<IParameter>(Parameters_CollectionReset);
215    }
216    #endregion
217
218    #region parameter events
219    private void AddParameter(IOperator op, IParameter param) {
220      IValueParameter<IOperator> opParam = param as IValueParameter<IOperator>;
221      if (opParam != null) {
222        this.RegisterOperatorParameterEvents(opParam);
223        this.parameterOperatorMapping.Add(opParam, op);
224        IShapeInfo shapeInfo = this.shapeInfoMapping.GetByFirst(op);
225        shapeInfo.AddConnector(param.Name);
226
227        if (opParam.Value != null) {
228          if (!this.shapeInfoMapping.ContainsFirst(opParam.Value))
229            this.AddOperator(opParam.Value);
230          this.connections.Add(new KeyValuePair<IShapeInfo, string>(shapeInfo, param.Name), this.shapeInfoMapping.GetByFirst(opParam.Value));
231        }
232      }
233    }
234
235    private void RemoveParameter(IOperator op, IParameter param) {
236      IValueParameter<IOperator> opParam = param as IValueParameter<IOperator>;
237      if (opParam != null) {
238        this.DeregisterOperatorParameterEvents(opParam);
239        this.parameterOperatorMapping.Remove(opParam);
240        IShapeInfo shapeInfo = this.shapeInfoMapping.GetByFirst(op);
241
242        this.connections.Remove(new KeyValuePair<IShapeInfo, string>(shapeInfo, param.Name));
243        shapeInfo.RemoveConnector(param.Name);
244      }
245    }
246
247    private void opParam_ValueChanged(object sender, EventArgs e) {
248      IValueParameter<IOperator> opParam = (IValueParameter<IOperator>)sender;
249      if (opParam != null) {
250        IOperator op = this.parameterOperatorMapping[opParam];
251        IShapeInfo shapeInfo = this.shapeInfoMapping.GetByFirst(op);
252        KeyValuePair<IShapeInfo, string> connectionFrom = new KeyValuePair<IShapeInfo, string>(shapeInfo, opParam.Name);
253
254        if (opParam.Value == null)
255          this.connections.Remove(connectionFrom);
256        else {
257          if (!this.shapeInfoMapping.ContainsFirst(opParam.Value))
258            this.AddOperator(opParam.Value);
259          this.connections[connectionFrom] = this.shapeInfoMapping.GetByFirst(opParam.Value);
260        }
261      }
262    }
263
264    private void Parameters_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IParameter> e) {
265      IObservableKeyedCollection<string, IParameter> parameterCollection = sender as IObservableKeyedCollection<string, IParameter>;
266      IOperator op = this.operatorParameterCollectionMapping.GetBySecond(parameterCollection);
267      foreach (IParameter param in e.Items)
268        AddParameter(op, param);
269    }
270    private void Parameters_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IParameter> e) {
271      IObservableKeyedCollection<string, IParameter> parameterCollection = sender as IObservableKeyedCollection<string, IParameter>;
272      IOperator op = this.operatorParameterCollectionMapping.GetBySecond(parameterCollection);
273      foreach (IParameter param in e.Items)
274        RemoveParameter(op, param);
275    }
276    private void Parameters_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IParameter> e) {
277      IObservableKeyedCollection<string, IParameter> parameterCollection = sender as IObservableKeyedCollection<string, IParameter>;
278      IOperator op = this.operatorParameterCollectionMapping.GetBySecond(parameterCollection);
279      foreach (IParameter param in e.OldItems)
280        RemoveParameter(op, param);
281      foreach (IParameter param in e.Items)
282        AddParameter(op, param);
283    }
284    private void Parameters_CollectionReset(object sender, CollectionItemsChangedEventArgs<IParameter> e) {
285      IObservableKeyedCollection<string, IParameter> parameterCollection = sender as IObservableKeyedCollection<string, IParameter>;
286      IOperator op = this.operatorParameterCollectionMapping.GetBySecond(parameterCollection);
287      foreach (IParameter param in e.OldItems)
288        RemoveParameter(op, param);
289      foreach (IParameter param in e.Items)
290        AddParameter(op, param);
291    }
292
293    private void RegisterOperatorParameterEvents(IValueParameter<IOperator> opParam) {
294      opParam.ValueChanged += new EventHandler(opParam_ValueChanged);
295    }
296    private void DeregisterOperatorParameterEvents(IValueParameter<IOperator> opParam) {
297      opParam.ValueChanged -= new EventHandler(opParam_ValueChanged);
298    }
299    #endregion
300  }
301}
Note: See TracBrowser for help on using the repository browser.