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 @ 2768

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

added solution folders and sources for the netron library (ticket #867)

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