Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/Netron.Diagramming.Core-3.0.2672.12446/Diagram elements/Group/GroupShape.cs @ 4068

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

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

File size: 15.2 KB
Line 
1using System;
2using System.Drawing;
3using System.Windows.Forms;
4namespace Netron.Diagramming.Core {
5  // ----------------------------------------------------------------------
6  /// <summary>
7  /// This entity represents a group of entities and corresponds to the
8  /// '(un)grouping' feature.
9  /// </summary>
10  // ----------------------------------------------------------------------
11  partial class GroupShape : DiagramEntityBase, IGroup {
12    #region Fields
13
14    // ------------------------------------------------------------------
15    /// <summary>
16    /// Implementation of IVersion - the current version of
17    /// GroupShape.
18    /// </summary>
19    // ------------------------------------------------------------------
20    protected const double groupShapeVersion = 1.0;
21
22    // ------------------------------------------------------------------
23    /// <summary>
24    /// The spacing between the bounds (union) of the entities and the
25    /// outter edge of the group.
26    /// </summary>
27    // ------------------------------------------------------------------
28    protected int myMargin = 10;
29
30    // ------------------------------------------------------------------
31    /// <summary>
32    /// The Entities field.
33    /// </summary>
34    // ------------------------------------------------------------------
35    private CollectionBase<IDiagramEntity> mEntities;
36
37    // ------------------------------------------------------------------
38    /// <summary>
39    /// Specifies if ungrouping is allowed.
40    /// </summary>
41    // ------------------------------------------------------------------
42    bool mAllowUnGroup = false;
43
44    // ------------------------------------------------------------------
45    /// <summary>
46    /// in essence, whether the group shape should be painted.
47    /// </summary>
48    // ------------------------------------------------------------------
49    private bool mEmphasizeGroup = true;
50
51    #endregion
52
53    #region Properties
54
55    // ------------------------------------------------------------------
56    /// <summary>
57    /// Gets the current version.
58    /// </summary>
59    // ------------------------------------------------------------------
60    public override double Version {
61      get {
62        return groupShapeVersion;
63      }
64    }
65
66    // ------------------------------------------------------------------
67    /// <summary>
68    /// Gets or sets the current magnification level used by the view.
69    /// Overriden to update each entity in this group.
70    /// </summary>
71    // ------------------------------------------------------------------
72    public override SizeF Magnification {
73      get {
74        return base.Magnification;
75      }
76      set {
77        base.Magnification = value;
78        foreach (IDiagramEntity entiy in Entities) {
79          entiy.Magnification = value;
80        }
81      }
82    }
83
84    // ------------------------------------------------------------------
85    /// <summary>
86    /// The spacing between the bounds (union) of the entities and the
87    /// outter edge of the group.
88    /// </summary>
89    // ------------------------------------------------------------------
90    public int Margin {
91      get {
92        return myMargin;
93      }
94      set {
95        myMargin = value;
96        Invalidate();
97      }
98    }
99
100    // ------------------------------------------------------------------
101    /// <summary>
102    /// Gets or sets whether the group as a shape should be painted on
103    /// the canvas.
104    /// </summary>
105    /// <value><c>true</c> To paint the group shape; otherwise,
106    /// <c>false</c>.</value>
107    // ------------------------------------------------------------------
108    public bool EmphasizeGroup {
109      get { return mEmphasizeGroup; }
110      set { mEmphasizeGroup = value; }
111    }
112
113    // ------------------------------------------------------------------
114    /// <summary>
115    /// Gets or sets if un-grouping of the entities is allowed.
116    /// </summary>
117    // ------------------------------------------------------------------
118    public virtual bool CanUnGroup {
119      get {
120        return mAllowUnGroup;
121      }
122      set {
123        mAllowUnGroup = value;
124      }
125    }
126
127    // ------------------------------------------------------------------
128    /// <summary>
129    /// Gets the friendly name of the entity to be displayed in the UI.
130    /// </summary>
131    /// <value></value>
132    // ------------------------------------------------------------------
133    public override string EntityName {
134      get {
135        return "Group shape";
136      }
137    }
138
139    // ------------------------------------------------------------------
140    /// <summary>
141    /// Gets or sets the rectangle.
142    /// </summary>
143    /// <value>The rectangle.</value>
144    // ------------------------------------------------------------------
145    public override Rectangle Rectangle {
146      get {
147        return mRectangle;
148      }
149    }
150
151    // ------------------------------------------------------------------
152    /// <summary>
153    /// Gets or sets the entities directly underneath. To get the whole
154    /// branch of entities in case of nested groups, <see cref="Leafs"/>.
155    /// </summary>
156    // ------------------------------------------------------------------
157    public CollectionBase<IDiagramEntity> Entities {
158      get {
159        return mEntities;
160      }
161      set {
162        mEntities = value;
163        AttachEventsToEnityCollection(mEntities);
164      }
165    }
166
167    // ------------------------------------------------------------------
168    /// <summary>
169    /// Gets the whole branch of entities if this group has sub-groups.
170    /// The result will not contain the group shapes.
171    /// </summary>
172    /// <value>The branch.</value>
173    // ------------------------------------------------------------------
174    public CollectionBase<IDiagramEntity> Leafs {
175      get {
176        CollectionBase<IDiagramEntity> flatList =
177            new CollectionBase<IDiagramEntity>();
178
179        foreach (IDiagramEntity entity in mEntities) {
180          if (entity is IGroup)
181            Utils.TraverseCollect(entity as IGroup, ref flatList);
182          else
183            flatList.Add(entity);
184        }
185        return flatList;
186      }
187    }
188    #endregion
189
190    #region Constructor
191
192    // ------------------------------------------------------------------
193    /// <summary>
194    /// Default constructor.
195    /// </summary>
196    // ------------------------------------------------------------------
197    public GroupShape()
198      : base() {
199      this.PaintStyle = null;
200      PenStyle = null;
201    }
202
203    // ------------------------------------------------------------------
204    ///<summary>
205    ///Constructor that receives the parent Model.
206    ///</summary>
207    ///<param name="model">Model</param>
208    // ------------------------------------------------------------------
209    public GroupShape(IModel model)
210      : base(model) {
211      this.PaintStyle = null;
212      PenStyle = null;
213    }
214    #endregion
215
216    #region Methods
217
218    // ------------------------------------------------------------------
219    /// <summary>
220    /// Initializes the group shape.
221    /// </summary>
222    // ------------------------------------------------------------------
223    protected override void Initialize() {
224      base.Initialize();
225      this.mEntities = new CollectionBase<IDiagramEntity>();
226      AttachEventsToEnityCollection(mEntities);
227    }
228
229    // ------------------------------------------------------------------
230    /// <summary>
231    /// Hooks-up the required events to monitor the collection of entities
232    /// specified.
233    /// </summary>
234    /// <param name="entities">CollectionBase<IDiagramEntity></param>
235    // ------------------------------------------------------------------
236    protected virtual void AttachEventsToEnityCollection(
237        CollectionBase<IDiagramEntity> entities) {
238      this.mEntities.OnItemAdded +=
239          new EventHandler<CollectionEventArgs<IDiagramEntity>>(
240          OnEntityAdded);
241
242      this.mEntities.OnClear += new EventHandler(OnClearEntities);
243
244      this.mEntities.OnItemRemoved +=
245          new EventHandler<CollectionEventArgs<IDiagramEntity>>(
246          OnEntityRemoved);
247    }
248
249    // ------------------------------------------------------------------
250    /// <summary>
251    /// The custom menu to be added to the base menu of this entity.
252    /// </summary>
253    /// <returns>ToolStripItem[]</returns>
254    // ------------------------------------------------------------------
255    public override ToolStripItem[] Menu() {
256      return null;
257    }
258
259    // ------------------------------------------------------------------
260    /// <summary>
261    /// Handles the OnItemRemoved of the Entities
262    /// </summary>
263    /// <param name="sender">object</param>
264    /// <param name="e">CollectionEventArgs<IDiagramEntity></param>
265    // ------------------------------------------------------------------
266    protected virtual void OnEntityRemoved(
267        object sender,
268        CollectionEventArgs<IDiagramEntity> e) {
269      CalculateRectangle();
270    }
271
272    // ------------------------------------------------------------------
273    /// <summary>
274    /// Handles the OnClear event of the Entities.
275    /// </summary>
276    /// <param name="sender">The source of the event.</param>
277    /// <param name="e">The <see cref="T:System.EventArgs"/> Instance
278    /// containing the event data.</param>
279    // ------------------------------------------------------------------
280    protected virtual void OnClearEntities(object sender, EventArgs e) {
281      mRectangle = Rectangle.Empty;
282    }
283
284    // ------------------------------------------------------------------
285    /// <summary>
286    /// Handles the OnItemAdded event of the Entities
287    /// </summary>
288    /// <param name="sender">The sender.</param>
289    /// <param name="e">The e.</param>
290    // ------------------------------------------------------------------
291    protected virtual void OnEntityAdded(
292        object sender,
293        CollectionEventArgs<IDiagramEntity> e) {
294      // I'm changing the behavior of the Group.  Rather than the
295      // entities still being attached to the Model and this not,
296      // I'm switching that - the Group is added to the Model and
297      // the entities are removed because they're contained within
298      // this.
299      if (Model.Paintables.Contains(e.Item)) {
300        Model.Paintables.Remove(e.Item);
301      }
302      e.Item.Group = this;
303      CalculateRectangle();
304      Invalidate();
305    }
306
307    // ------------------------------------------------------------------
308    /// <summary>
309    /// Calculates the bounding rectangle of this group.
310    /// </summary>
311    // ------------------------------------------------------------------
312    public void CalculateRectangle() {
313      if (mEntities == null || mEntities.Count == 0)
314        return;
315      Rectangle rec = mEntities[0].Rectangle;
316      foreach (IDiagramEntity entity in Entities) {
317        //cascade the calculation if necessary
318        if (entity is IGroup) (entity as IGroup).CalculateRectangle();
319
320        rec = Rectangle.Union(rec, entity.Rectangle);
321      }
322
323      rec.Inflate(myMargin, myMargin);
324      this.mRectangle = rec;
325    }
326
327    // ------------------------------------------------------------------
328    /// <summary>
329    /// Paints the entity on the control
330    /// <remarks>This method should not be called since the painting
331    /// occurs via the <see cref="Model.Paintables"/>.
332    /// Use the <see cref="CollapsibleGroupShape"/> if you want a visible
333    /// group.
334    /// </remarks>
335    /// </summary>
336    /// <param name="g">Graphics</param>
337    // ------------------------------------------------------------------
338    public override void Paint(Graphics g) {
339      // Only draw the background and border of the group if we're
340      // supposed to.
341      if (EmphasizeGroup) {
342        if (mPaintStyle != null) {
343          g.FillRectangle(mPaintStyle.GetBrush(mRectangle), mRectangle);
344        }
345
346        if ((Hovered) && (ArtPalette.EnableShadows)) {
347          g.DrawRectangle(ArtPalette.HighlightPen, mRectangle);
348        } else if (mPenStyle != null) {
349          g.DrawRectangle(mPenStyle.DrawingPen(), mRectangle);
350        }
351      }
352
353      // Now draw each entity (child) in this group.
354      foreach (IDiagramEntity entity in mEntities) {
355        entity.Paint(g);
356      }
357    }
358
359    // ------------------------------------------------------------------
360    /// <summary>
361    /// Tests whether the group is hit by the mouse
362    /// </summary>
363    /// <param name="p">Point</param>
364    /// <returns>bool</returns>
365    // ------------------------------------------------------------------
366    public override bool Hit(Point p) {
367      if (EmphasizeGroup) {
368        Rectangle r = new Rectangle(p, new Size(5, 5));
369        return Rectangle.Contains(r);
370      } else {
371        foreach (IDiagramEntity entity in mEntities) {
372          if (entity.Hit(p)) {
373            return true;
374          }
375        }
376
377        // If we made it this far then no entity was hit so
378        // return false.
379        return false;
380      }
381    }
382
383    // ------------------------------------------------------------------
384    /// <summary>
385    /// Invalidates the entity
386    /// </summary>
387    // ------------------------------------------------------------------
388    public override void Invalidate() {
389
390      if (mRectangle == null)
391        return;
392
393      Rectangle rec = mRectangle;
394      rec.Inflate(20, 20);
395      Model.RaiseOnInvalidateRectangle(rec);
396    }
397
398    // ------------------------------------------------------------------
399    /// <summary>
400    /// Moves the entity on the canvas
401    /// </summary>
402    /// <param name="p">Point</param>
403    // ------------------------------------------------------------------
404    public override void MoveBy(Point p) {
405
406      Rectangle recBefore = mRectangle;
407      recBefore.Inflate(20, 20);
408
409      // No need to invalidate since it'll be done by the individual
410      // move actions.
411      foreach (IDiagramEntity entity in mEntities) {
412        entity.MoveBy(p);
413      }
414      mRectangle.X += p.X;
415      mRectangle.Y += p.Y;
416
417      //refresh things
418      this.Invalidate(recBefore);//position before the move
419      this.Invalidate();//current position
420
421    }
422
423    #endregion
424
425    // ------------------------------------------------------------------
426    /// <summary>
427    /// Passes the mouse down event to all entities in the collection.
428    /// </summary>
429    /// <param name="e">MouseEventArgs</param>
430    /// <returns>bool: Returns 'true' if the mouse down event was
431    /// handled here, 'false' if not.</returns>
432    // ------------------------------------------------------------------
433    public override bool MouseDown(MouseEventArgs e) {
434      base.MouseDown(e);
435      bool result = false;
436
437      // Only pass the mouse down event on if we're already selected.
438      if (IsSelected == false) {
439        return false;
440      }
441
442      foreach (IDiagramEntity entity in mEntities) {
443        if (entity.Hit(e.Location)) {
444          if (entity.MouseDown(e)) {
445            result = true;
446          }
447        }
448      }
449      return result;
450    }
451  }
452}
Note: See TracBrowser for help on using the repository browser.