Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
07/22/10 00:44:01 (14 years ago)
Author:
swagner
Message:

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/Netron.Diagramming.Core-3.0.2672.12446/Diagram elements/Group/CollapsibleGroupShape.cs

    r3038 r4068  
    11using System;
    22using System.Collections.Generic;
    3 using System.Text;
    43using System.Drawing;
    54using System.Windows.Forms;
    6 namespace Netron.Diagramming.Core
    7 {
    8     // ----------------------------------------------------------------------
    9     /// <summary>
    10     /// This is an extension of the <see cref="GroupShape"/> which paints
    11     /// itself and allows to collapse/expand its content. Note that it does
    12     /// not inherit from the <see cref="GroupShape"/> though because it requires
    13     /// the <see cref="ShapeMaterialBase"/> mechanism and, hence, inherits
    14     /// from the <see cref="ComplexShapeBase"/> class.
    15     /// </summary>
    16     // ----------------------------------------------------------------------
    17     public partial class CollapsibleGroupShape : ComplexShapeBase, IGroup
    18     {
    19         #region Fields
    20 
    21         // ------------------------------------------------------------------
    22         /// <summary>
    23         /// Implementation of IVersion - the current version of
    24         /// CollapsibleGroupShape.
    25         /// </summary>
    26         // ------------------------------------------------------------------
    27         protected const double collapsibleGroupShapeVersion = 1.0;
    28 
    29         // ------------------------------------------------------------------
    30         /// <summary>
    31         /// the Entities field
    32         /// </summary>
    33         // ------------------------------------------------------------------
    34         private CollectionBase<IDiagramEntity> mEntities;
    35 
    36         // ------------------------------------------------------------------
    37         /// <summary>
    38         /// in essence, whether the group shape should be painted
    39         /// </summary>
    40         // ------------------------------------------------------------------
    41         private bool mEmphasizeGroup = true;
    42 
    43         // ------------------------------------------------------------------
    44         /// <summary>
    45         /// the collapse/expand icon
    46         /// </summary>
    47         // ------------------------------------------------------------------
    48         private SwitchIconMaterial xicon;
    49 
    50         // ------------------------------------------------------------------
    51         /// <summary>
    52         /// the rectangle before it's being collapsed
    53         /// </summary>
    54         // ------------------------------------------------------------------
    55         private Rectangle rectangleMemory;
    56 
    57         // ------------------------------------------------------------------
    58         /// <summary>
    59         /// the location memory of the externally connected connectors
    60         /// </summary>
    61         // ------------------------------------------------------------------
    62         private Dictionary<IConnector, Point> connectorMemory;
    63 
    64         // ------------------------------------------------------------------
    65         /// <summary>
    66         /// global offset when a collapsed group is moved around
    67         /// </summary>
    68         // ------------------------------------------------------------------
    69         private Point groupConnectorOffset = Point.Empty;
    70 
    71         // ------------------------------------------------------------------
    72         /// <summary>
    73         /// the Collapsed field
    74         /// </summary>
    75         // ------------------------------------------------------------------
    76         private bool mCollapsed;
    77 
    78         // ------------------------------------------------------------------
    79         /// <summary>
    80         /// the expand hyperlink
    81         /// </summary>
    82         // ------------------------------------------------------------------
    83         private ClickableLabelMaterial expandLabel;
    84 
    85         // ------------------------------------------------------------------
    86         /// <summary>
    87         /// Specifies if ungrouping is allowed.
    88         /// </summary>
    89         // ------------------------------------------------------------------
    90         bool mAllowUnGroup = false;
    91 
    92         #endregion
    93 
    94         #region Properties
    95 
    96         // ------------------------------------------------------------------
    97         /// <summary>
    98         /// Gets the current version.
    99         /// </summary>
    100         // ------------------------------------------------------------------
    101         public override double Version
    102         {
    103             get
    104             {
    105                 return collapsibleGroupShapeVersion;
     5namespace Netron.Diagramming.Core {
     6  // ----------------------------------------------------------------------
     7  /// <summary>
     8  /// This is an extension of the <see cref="GroupShape"/> which paints
     9  /// itself and allows to collapse/expand its content. Note that it does
     10  /// not inherit from the <see cref="GroupShape"/> though because it requires
     11  /// the <see cref="ShapeMaterialBase"/> mechanism and, hence, inherits
     12  /// from the <see cref="ComplexShapeBase"/> class.
     13  /// </summary>
     14  // ----------------------------------------------------------------------
     15  public partial class CollapsibleGroupShape : ComplexShapeBase, IGroup {
     16    #region Fields
     17
     18    // ------------------------------------------------------------------
     19    /// <summary>
     20    /// Implementation of IVersion - the current version of
     21    /// CollapsibleGroupShape.
     22    /// </summary>
     23    // ------------------------------------------------------------------
     24    protected const double collapsibleGroupShapeVersion = 1.0;
     25
     26    // ------------------------------------------------------------------
     27    /// <summary>
     28    /// the Entities field
     29    /// </summary>
     30    // ------------------------------------------------------------------
     31    private CollectionBase<IDiagramEntity> mEntities;
     32
     33    // ------------------------------------------------------------------
     34    /// <summary>
     35    /// in essence, whether the group shape should be painted
     36    /// </summary>
     37    // ------------------------------------------------------------------
     38    private bool mEmphasizeGroup = true;
     39
     40    // ------------------------------------------------------------------
     41    /// <summary>
     42    /// the collapse/expand icon
     43    /// </summary>
     44    // ------------------------------------------------------------------
     45    private SwitchIconMaterial xicon;
     46
     47    // ------------------------------------------------------------------
     48    /// <summary>
     49    /// the rectangle before it's being collapsed
     50    /// </summary>
     51    // ------------------------------------------------------------------
     52    private Rectangle rectangleMemory;
     53
     54    // ------------------------------------------------------------------
     55    /// <summary>
     56    /// the location memory of the externally connected connectors
     57    /// </summary>
     58    // ------------------------------------------------------------------
     59    private Dictionary<IConnector, Point> connectorMemory;
     60
     61    // ------------------------------------------------------------------
     62    /// <summary>
     63    /// global offset when a collapsed group is moved around
     64    /// </summary>
     65    // ------------------------------------------------------------------
     66    private Point groupConnectorOffset = Point.Empty;
     67
     68    // ------------------------------------------------------------------
     69    /// <summary>
     70    /// the Collapsed field
     71    /// </summary>
     72    // ------------------------------------------------------------------
     73    private bool mCollapsed;
     74
     75    // ------------------------------------------------------------------
     76    /// <summary>
     77    /// the expand hyperlink
     78    /// </summary>
     79    // ------------------------------------------------------------------
     80    private ClickableLabelMaterial expandLabel;
     81
     82    // ------------------------------------------------------------------
     83    /// <summary>
     84    /// Specifies if ungrouping is allowed.
     85    /// </summary>
     86    // ------------------------------------------------------------------
     87    bool mAllowUnGroup = false;
     88
     89    #endregion
     90
     91    #region Properties
     92
     93    // ------------------------------------------------------------------
     94    /// <summary>
     95    /// Gets the current version.
     96    /// </summary>
     97    // ------------------------------------------------------------------
     98    public override double Version {
     99      get {
     100        return collapsibleGroupShapeVersion;
     101      }
     102    }
     103
     104    // ------------------------------------------------------------------
     105    /// <summary>
     106    /// Gets or sets if un-grouping of the entities is allowed.
     107    /// </summary>
     108    // ------------------------------------------------------------------
     109    public virtual bool CanUnGroup {
     110      get {
     111        return mAllowUnGroup;
     112      }
     113      set {
     114        mAllowUnGroup = value;
     115      }
     116    }
     117
     118    /// <summary>
     119    /// Gets or sets whether the group is in a collapsed state
     120    /// </summary>
     121    public bool Collapsed {
     122      get { return mCollapsed; }
     123      set { mCollapsed = value; }
     124    }
     125
     126
     127    /// <summary>
     128    /// Gets or sets whether the group as a shape should be painted on the canvas.
     129    /// </summary>
     130    /// <value><c>true</c> to paint the group shape; otherwise, <c>false</c>.</value>
     131    public bool EmphasizeGroup {
     132      get { return mEmphasizeGroup; }
     133      set { mEmphasizeGroup = value; }
     134    }
     135    /// <summary>
     136    /// Gets the friendly name of the entity to be displayed in the UI
     137    /// </summary>
     138    /// <value></value>
     139    public override string EntityName {
     140      get {
     141        return "Group shape";
     142      }
     143    }
     144
     145    /// <summary>
     146    /// Gets or sets the rectangle.
     147    /// </summary>
     148    /// <value>The rectangle.</value>
     149    public override Rectangle Rectangle {
     150      get {
     151        return mRectangle;
     152      }
     153    }
     154    /// <summary>
     155    /// Gets or sets the entities directly underneath. To get the whole branch of entities in case of nested groups, <see cref="Leafs"/>.
     156    /// </summary>
     157    public CollectionBase<IDiagramEntity> Entities {
     158      get { return mEntities; }
     159      set {
     160
     161        throw new InconsistencyException("You cannot set the entities, use the already instantiated collection to add or remove items.");
     162
     163
     164      }
     165    }
     166    /// <summary>
     167    /// Gets the whole branch of entities if this group has sub-groups. Contrary to the <see cref="GroupShape"/> the result WILLl contain the group shapes.
     168    /// </summary>
     169    /// <value>The branch.</value>
     170    public CollectionBase<IDiagramEntity> Leafs {
     171      get {
     172        CollectionBase<IDiagramEntity> flatList = new CollectionBase<IDiagramEntity>();
     173        foreach (IDiagramEntity entity in mEntities) {
     174          if (entity is IGroup) {
     175            Utils.TraverseCollect(entity as IGroup, ref flatList);
     176          }
     177          flatList.Add(entity);
     178        }
     179        return flatList;
     180      }
     181    }
     182
     183    #endregion
     184
     185    #region Constructor
     186    ///<summary>
     187    ///Default constructor
     188    ///</summary>
     189    public CollapsibleGroupShape(IModel model)
     190      : base(model) {
     191      this.mEntities = new CollectionBase<IDiagramEntity>();
     192      this.mEntities.OnItemAdded += new EventHandler<CollectionEventArgs<IDiagramEntity>>(mEntities_OnItemAdded);
     193      this.mEntities.OnClear += new EventHandler(mEntities_OnClear);
     194      this.mEntities.OnItemRemoved += new EventHandler<CollectionEventArgs<IDiagramEntity>>(mEntities_OnItemRemoved);
     195
     196      xicon = new SwitchIconMaterial(SwitchIconType.PlusMinus);
     197      this.Children.Add(xicon);
     198      //do this before attaching the next event handler, otherwise the shape will be added twice to the paintables
     199      xicon.Collapsed = false;
     200
     201      xicon.OnCollapse += new EventHandler(xicon_OnCollapse);
     202      xicon.OnExpand += new EventHandler(xicon_OnExpand);
     203
     204      connectorMemory = new Dictionary<IConnector, Point>();
     205
     206      expandLabel = new ClickableLabelMaterial("Expand...");
     207      this.Children.Add(expandLabel);
     208      expandLabel.Visible = false;
     209      expandLabel.OnClick += new EventHandler(expandLabel_OnClick);
     210    }
     211
     212    void expandLabel_OnClick(object sender, EventArgs e) {
     213      xicon.Collapsed = false;
     214    }
     215
     216    void xicon_OnExpand(object sender, EventArgs e) {
     217      Expand();
     218    }
     219
     220    void xicon_OnCollapse(object sender, EventArgs e) {
     221      Collapse();
     222    }
     223    #endregion
     224
     225    #region Methods
     226
     227    /// <summary>
     228    /// Collapses this instance.
     229    /// </summary>
     230    public void Collapse() {
     231      rectangleMemory = mRectangle;
     232      mRectangle = new Rectangle(mRectangle.Location, new Size(110, 25));
     233
     234      foreach (IDiagramEntity entity in Entities) {
     235        RemoveFromPaintables(entity);
     236      }
     237      this.Resizable = false;
     238
     239
     240      connectorMemory.Clear();//forget the previous memory
     241      groupConnectorOffset = Point.Empty;
     242      //use the flattened collection (Leafs) in case there are sub-groups
     243      MoveConnectors(Leafs, new Point((int)(Rectangle.Left + Rectangle.Width / 2), Rectangle.Bottom));
     244
     245      Rectangle rec = rectangleMemory;
     246      rec.Inflate(20, 20);
     247      Invalidate(rec);
     248      mCollapsed = true;
     249      expandLabel.Visible = true;
     250    }
     251    internal void RemoveFromPaintables(IDiagramEntity entity) {
     252      this.Model.Paintables.Remove(entity);
     253      if (entity is CollapsibleGroupShape && !(entity as CollapsibleGroupShape).Collapsed) {
     254        foreach (IDiagramEntity ent in (entity as CollapsibleGroupShape).Entities) {
     255          RemoveFromPaintables(ent);
     256        }
     257
     258      }
     259    }
     260
     261    internal void AddToPaintables(IDiagramEntity entity) {
     262      this.Model.Paintables.Add(entity);
     263      if (entity is CollapsibleGroupShape && !(entity as CollapsibleGroupShape).Collapsed) {
     264        foreach (IDiagramEntity ent in (entity as CollapsibleGroupShape).Entities) {
     265          AddToPaintables(ent);
     266        }
     267
     268      }
     269
     270    }
     271    /// <summary>
     272    /// Expands this instance.
     273    /// </summary>
     274    public void Expand() {
     275      mRectangle = rectangleMemory;
     276      foreach (IDiagramEntity entity in Entities) {
     277        AddToPaintables(entity);
     278      }
     279      this.Resizable = true;
     280      UnMoveConnectors();
     281      Invalidate(mRectangle);
     282      mCollapsed = false;
     283      connectorMemory.Clear();
     284      expandLabel.Visible = false;
     285    }
     286
     287
     288
     289    /// <summary>
     290    /// Moves the connectors of the children to the central group connector location.
     291    /// </summary>
     292    internal void MoveConnectors(CollectionBase<IDiagramEntity> entities, Point point) {
     293      IConnection cnn;
     294      foreach (IDiagramEntity entity in entities) {
     295        if (entity is IGroup) {
     296          continue; //since we use a flattened collection (the Leafs) we don't care about the groups here
     297          //the inclusion of the subgroups in the Leafs is however important to make the subgroups
     298          //(in)visible when collapsed/expanded.
     299        }
     300        if (entity is IShape) {
     301          foreach (IConnector cn in (entity as IShape).Connectors) {
     302            if (cn.AttachedConnectors.Count > 0) {
     303              foreach (IConnector cn2 in cn.AttachedConnectors) {
     304                if (cn2.Parent is IConnection) {
     305                  cnn = cn2.Parent as IConnection;
     306                  //the ends have to be connected
     307                  if (cnn.From.AttachedTo.Parent is IShape && cnn.To.AttachedTo.Parent is IShape) {
     308                    if (entities.Contains(cnn.From.AttachedTo.Parent as IShape) && entities.Contains(cnn.To.AttachedTo.Parent as IShape))
     309                      continue;//both endconnectors are internal
     310                    else//one of the connectors is external
     311                                        {
     312                      if (entities.Contains(cnn.From.AttachedTo.Parent as IShape)) //the From is internal
     313                                            {
     314                        MoveConnector(cnn.From, point);
     315                      } else //the To is internal                           
     316                                            {
     317                        MoveConnector(cnn.To, point);
     318                      }
     319                    }
     320                  }
     321                }
     322              }
    106323            }
     324          }
    107325        }
    108 
    109         // ------------------------------------------------------------------
    110         /// <summary>
    111         /// Gets or sets if un-grouping of the entities is allowed.
    112         /// </summary>
    113         // ------------------------------------------------------------------
    114         public virtual bool CanUnGroup
    115         {
    116             get
    117             {
    118                 return mAllowUnGroup;
    119             }
    120             set
    121             {
    122                 mAllowUnGroup = value;
    123             }
     326      }
     327    }
     328
     329    /// <summary>
     330    /// Moves the connector to the given location.
     331    /// </summary>
     332    /// <param name="cn">The cn.</param>
     333    /// <param name="point">The point.</param>
     334    private void MoveConnector(IConnector cn, Point point) {
     335      connectorMemory.Add(cn, cn.Point);//luckily the Point is a struct so the value will be actually copied and we can safely change the value next
     336      cn.MoveBy(new Point(point.X - cn.Point.X, point.Y - cn.Point.Y));
     337      cn.Enabled = false;
     338    }
     339
     340    /// <summary>
     341    /// Moves the connectors back from the central group connector to their original location.
     342    /// </summary>
     343    private void UnMoveConnectors() {
     344      //some things will go wrong here if the content of the Entities has changed
     345
     346      //recall the memory and move them;
     347
     348      Dictionary<IConnector, Point>.KeyCollection keys = connectorMemory.Keys;
     349      Point p;
     350      foreach (IConnector cn in keys) {
     351        p = connectorMemory[cn];
     352        cn.MoveBy(new Point(p.X - cn.Point.X + groupConnectorOffset.X, p.Y - cn.Point.Y + groupConnectorOffset.Y));
     353        cn.Enabled = true;
     354      }
     355    }
     356
     357    /// <summary>
     358    /// The custom menu to be added to the base menu of this entity
     359    /// </summary>
     360    /// <returns>ToolStripItem[]</returns>
     361    public override ToolStripItem[] Menu() {
     362      return null;
     363    }
     364    /// <summary>
     365    /// Handles the OnItemRemoved of the Entities
     366    /// </summary>
     367    /// <param name="sender">The sender.</param>
     368    /// <param name="e">The e.</param>
     369    void mEntities_OnItemRemoved(object sender, CollectionEventArgs<IDiagramEntity> e) {
     370      CalculateRectangle();
     371    }
     372
     373    /// <summary>
     374    /// Handles the OnClear event of the Entities.
     375    /// </summary>
     376    /// <param name="sender">The source of the event.</param>
     377    /// <param name="e">The <see cref="T:System.EventArgs"/> instance containing the event data.</param>
     378    void mEntities_OnClear(object sender, EventArgs e) {
     379      mRectangle = Rectangle.Empty;
     380    }
     381
     382    /// <summary>
     383    /// Handles the OnItemAdded event of the Entities
     384    /// </summary>
     385    /// <param name="sender">The sender.</param>
     386    /// <param name="e">The e.</param>
     387    void mEntities_OnItemAdded(object sender, CollectionEventArgs<IDiagramEntity> e) {
     388      //if(mEntities.Count == 1)
     389      //    mRectangle = e.Item.Rectangle;
     390      //else
     391      //{
     392      //    mRectangle = Rectangle.Union((Rectangle) mRectangle, e.Item.Rectangle);
     393      //}
     394      CalculateRectangle();
     395    }
     396
     397    /// <summary>
     398    /// Calculates the bounding rectangle of this group.
     399    /// </summary>
     400    public void CalculateRectangle() {
     401      if (mEntities == null || mEntities.Count == 0)
     402        return;
     403      Rectangle rec = mEntities[0].Rectangle;
     404      foreach (IDiagramEntity entity in Entities) {
     405        //cascade the calculation if necessary
     406        if ((entity is CollapsibleGroupShape) && !(entity as CollapsibleGroupShape).Collapsed) (entity as IGroup).CalculateRectangle();
     407
     408        rec = Rectangle.Union(rec, entity.Rectangle);
     409      }
     410      rec.Inflate(20, 20);
     411      this.mRectangle = rec;
     412      rec.Offset(5, 5);
     413      xicon.Transform(new Rectangle(rec.Location, new Size(16, 16)));
     414
     415      expandLabel.Transform(new Rectangle(rec.Location.X + 20, rec.Location.Y, 50, 12));
     416    }
     417
     418
     419    /// <summary>
     420    /// Paints the entity on the control
     421    /// <remarks>This method should not be called since the painting occurs via the <see cref="Model.Paintables"/>.</remarks>
     422    /// </summary>
     423    /// <param name="g"></param>
     424    public override void Paint(System.Drawing.Graphics g) {
     425      Rectangle rec = Rectangle;
     426      Utils.DrawRoundRect(g, ArtPalette.ConnectionShadow, rec);
     427
     428      base.Paint(g);
     429    }
     430
     431    /// <summary>
     432    /// Tests whether the group is hit by the mouse
     433    /// </summary>
     434    /// <param name="p"></param>
     435    /// <returns></returns>
     436    public override bool Hit(System.Drawing.Point p) {
     437      if (mCollapsed)
     438        return mRectangle.Contains(p);
     439
     440      foreach (IDiagramEntity entity in mEntities) {
     441        if (entity.Hit(p))
     442          return true;
     443      }
     444      return false;
     445    }
     446
     447    /// <summary>
     448    /// Invalidates the entity
     449    /// </summary>
     450    public override void Invalidate() {
     451
     452      if (mRectangle == null)
     453        return;
     454
     455      Rectangle rec = mRectangle;
     456      rec.Inflate(20, 20);
     457      Model.RaiseOnInvalidateRectangle(rec);
     458    }
     459
     460    /// <summary>
     461    /// Moves the entity on the canvas
     462    /// </summary>
     463    /// <param name="p"></param>
     464    public override void MoveBy(System.Drawing.Point p) {
     465      base.MoveBy(p);
     466
     467      Rectangle recBefore = mRectangle;
     468      recBefore.Inflate(20, 20);
     469
     470      //no need to invalidate since it'll be done by the individual move actions
     471      foreach (IDiagramEntity entity in mEntities) {
     472        entity.MoveBy(p);
     473      }
     474
     475      mRectangle.X += p.X;
     476      mRectangle.Y += p.Y;
     477      //shift the latent copy of the real rectangle if the group is in a collapsed state
     478      if (mCollapsed) {
     479        rectangleMemory.X += p.X;
     480        rectangleMemory.Y += p.Y;
     481        //the global offset has to be memorized; when we'll expand the group this offset has to be added to the original values
     482        groupConnectorOffset.Offset(p);
     483      }
     484
     485
     486      //refresh things
     487      this.Invalidate(recBefore);//position before the move
     488      this.Invalidate();//current position
     489
     490    }
     491
     492    public override bool MouseDown(MouseEventArgs e) {
     493      // Was a material hit in the base ComplexShape?
     494      if (base.MouseDown(e)) {
     495        return true;
     496      }
     497
     498      // If not, should we pass it on to the entities in this
     499      // group?
     500      foreach (IDiagramEntity entity in this.mEntities) {
     501        if (entity.Hit(e.Location)) {
     502          if (entity.MouseDown(e)) {
     503            return true;
     504          }
    124505        }
    125 
    126         /// <summary>
    127         /// Gets or sets whether the group is in a collapsed state
    128         /// </summary>
    129         public bool Collapsed
    130         {
    131             get { return mCollapsed; }
    132             set { mCollapsed = value; }
    133         }
    134 
    135 
    136         /// <summary>
    137         /// Gets or sets whether the group as a shape should be painted on the canvas.
    138         /// </summary>
    139         /// <value><c>true</c> to paint the group shape; otherwise, <c>false</c>.</value>
    140         public bool EmphasizeGroup
    141         {
    142             get { return mEmphasizeGroup; }
    143             set { mEmphasizeGroup = value; }
    144         }
    145         /// <summary>
    146         /// Gets the friendly name of the entity to be displayed in the UI
    147         /// </summary>
    148         /// <value></value>
    149         public override string EntityName
    150         {
    151             get
    152             {
    153                 return "Group shape";
    154             }
    155         }
    156 
    157         /// <summary>
    158         /// Gets or sets the rectangle.
    159         /// </summary>
    160         /// <value>The rectangle.</value>
    161         public override Rectangle Rectangle
    162         {
    163             get
    164             {
    165                 return mRectangle;
    166             }
    167         }
    168         /// <summary>
    169         /// Gets or sets the entities directly underneath. To get the whole branch of entities in case of nested groups, <see cref="Leafs"/>.
    170         /// </summary>
    171         public CollectionBase<IDiagramEntity> Entities
    172         {
    173             get { return mEntities; }
    174             set
    175             {
    176 
    177                 throw new InconsistencyException("You cannot set the entities, use the already instantiated collection to add or remove items.");
    178 
    179 
    180             }
    181         }
    182         /// <summary>
    183         /// Gets the whole branch of entities if this group has sub-groups. Contrary to the <see cref="GroupShape"/> the result WILLl contain the group shapes.
    184         /// </summary>
    185         /// <value>The branch.</value>
    186         public CollectionBase<IDiagramEntity> Leafs
    187         {
    188             get
    189             {
    190                 CollectionBase<IDiagramEntity> flatList = new CollectionBase<IDiagramEntity>();
    191                 foreach (IDiagramEntity entity in mEntities)
    192                 {
    193                     if (entity is IGroup)
    194                     {                       
    195                         Utils.TraverseCollect(entity as IGroup, ref flatList);
    196                     }
    197                     flatList.Add(entity);
    198                 }
    199                 return flatList;
    200             }
    201         }
    202 
    203         #endregion
    204 
    205         #region Constructor
    206         ///<summary>
    207         ///Default constructor
    208         ///</summary>
    209         public CollapsibleGroupShape(IModel model)
    210             : base(model)
    211         {
    212             this.mEntities = new CollectionBase<IDiagramEntity>();
    213             this.mEntities.OnItemAdded += new EventHandler<CollectionEventArgs<IDiagramEntity>>(mEntities_OnItemAdded);
    214             this.mEntities.OnClear += new EventHandler(mEntities_OnClear);
    215             this.mEntities.OnItemRemoved += new EventHandler<CollectionEventArgs<IDiagramEntity>>(mEntities_OnItemRemoved);
    216 
    217             xicon = new SwitchIconMaterial(SwitchIconType.PlusMinus);
    218             this.Children.Add(xicon);
    219             //do this before attaching the next event handler, otherwise the shape will be added twice to the paintables
    220             xicon.Collapsed = false;
    221 
    222             xicon.OnCollapse += new EventHandler(xicon_OnCollapse);
    223             xicon.OnExpand += new EventHandler(xicon_OnExpand);
    224 
    225             connectorMemory = new Dictionary<IConnector, Point>();
    226 
    227             expandLabel = new ClickableLabelMaterial("Expand...");
    228             this.Children.Add(expandLabel);
    229             expandLabel.Visible = false;
    230             expandLabel.OnClick += new EventHandler(expandLabel_OnClick);
    231         }
    232 
    233         void expandLabel_OnClick(object sender, EventArgs e)
    234         {
    235             xicon.Collapsed = false;
    236         }
    237 
    238         void xicon_OnExpand(object sender, EventArgs e)
    239         {
    240             Expand();
    241         }
    242 
    243         void xicon_OnCollapse(object sender, EventArgs e)
    244         {
    245             Collapse();
    246         }
    247         #endregion
    248 
    249         #region Methods
    250 
    251         /// <summary>
    252         /// Collapses this instance.
    253         /// </summary>
    254         public void Collapse()
    255         {
    256             rectangleMemory = mRectangle;
    257             mRectangle = new Rectangle(mRectangle.Location, new Size(110, 25));
    258 
    259             foreach (IDiagramEntity entity in Entities)
    260             {
    261                 RemoveFromPaintables(entity);
    262             }
    263             this.Resizable = false;
    264          
    265 
    266             connectorMemory.Clear();//forget the previous memory
    267             groupConnectorOffset = Point.Empty;
    268             //use the flattened collection (Leafs) in case there are sub-groups
    269             MoveConnectors(Leafs, new Point((int)(Rectangle.Left + Rectangle.Width / 2), Rectangle.Bottom));
    270 
    271             Rectangle rec = rectangleMemory;
    272             rec.Inflate(20, 20);
    273             Invalidate(rec);
    274             mCollapsed = true;
    275             expandLabel.Visible = true;
    276         }
    277         internal void RemoveFromPaintables(IDiagramEntity entity)
    278         {
    279             this.Model.Paintables.Remove(entity);
    280             if (entity is CollapsibleGroupShape && !(entity as CollapsibleGroupShape).Collapsed)
    281             {
    282                 foreach (IDiagramEntity  ent in (entity as CollapsibleGroupShape).Entities)
    283                 {
    284                     RemoveFromPaintables(ent);
    285                 }
    286                
    287             }
    288         }
    289 
    290         internal void AddToPaintables(IDiagramEntity entity)
    291         {
    292             this.Model.Paintables.Add(entity);
    293             if (entity is CollapsibleGroupShape && !(entity as CollapsibleGroupShape).Collapsed)
    294             {
    295                 foreach (IDiagramEntity ent in (entity as CollapsibleGroupShape).Entities)
    296                 {
    297                     AddToPaintables(ent);
    298                 }
    299 
    300             }
    301 
    302         }
    303         /// <summary>
    304         /// Expands this instance.
    305         /// </summary>
    306         public void Expand()
    307         {
    308             mRectangle = rectangleMemory;
    309             foreach (IDiagramEntity entity in Entities)
    310             {
    311                 AddToPaintables(entity);
    312             }
    313             this.Resizable = true;
    314             UnMoveConnectors();
    315             Invalidate(mRectangle);
    316             mCollapsed = false;
    317             connectorMemory.Clear();
    318             expandLabel.Visible = false;
    319         }
    320 
    321    
    322 
    323         /// <summary>
    324         /// Moves the connectors of the children to the central group connector location.
    325         /// </summary>
    326         internal void MoveConnectors(CollectionBase<IDiagramEntity> entities, Point point)
    327         {
    328             IConnection cnn;
    329             foreach (IDiagramEntity entity in entities)
    330             {
    331                 if (entity is IGroup)
    332                 {
    333                     continue; //since we use a flattened collection (the Leafs) we don't care about the groups here
    334                     //the inclusion of the subgroups in the Leafs is however important to make the subgroups
    335                     //(in)visible when collapsed/expanded.
    336                 }
    337                 if (entity is IShape )
    338                 {
    339                     foreach (IConnector cn in (entity as IShape).Connectors)
    340                     {
    341                         if (cn.AttachedConnectors.Count > 0)
    342                         {
    343                             foreach (IConnector cn2 in cn.AttachedConnectors)
    344                             {
    345                                 if (cn2.Parent is IConnection)
    346                                 {
    347                                     cnn = cn2.Parent as IConnection;
    348                                     //the ends have to be connected
    349                                     if (cnn.From.AttachedTo.Parent is IShape && cnn.To.AttachedTo.Parent is IShape)
    350                                     {
    351                                         if (entities.Contains(cnn.From.AttachedTo.Parent as IShape) && entities.Contains(cnn.To.AttachedTo.Parent as IShape))
    352                                             continue;//both endconnectors are internal
    353                                         else//one of the connectors is external
    354                                         {
    355                                             if (entities.Contains(cnn.From.AttachedTo.Parent as IShape)) //the From is internal
    356                                             {
    357                                                 MoveConnector(cnn.From, point);
    358                                             }
    359                                             else //the To is internal                           
    360                                             {
    361                                                 MoveConnector(cnn.To, point);
    362                                             }
    363                                         }
    364                                     }
    365                                 }
    366                             }
    367                         }
    368                     }
    369                 }
    370             }
    371         }
    372 
    373         /// <summary>
    374         /// Moves the connector to the given location.
    375         /// </summary>
    376         /// <param name="cn">The cn.</param>
    377         /// <param name="point">The point.</param>
    378         private void MoveConnector(IConnector cn, Point point)
    379         {
    380             connectorMemory.Add(cn, cn.Point);//luckily the Point is a struct so the value will be actually copied and we can safely change the value next
    381             cn.MoveBy(new Point(point.X - cn.Point.X, point.Y - cn.Point.Y));
    382             cn.Enabled = false;
    383         }
    384 
    385         /// <summary>
    386         /// Moves the connectors back from the central group connector to their original location.
    387         /// </summary>
    388         private void UnMoveConnectors()
    389         {
    390             //some things will go wrong here if the content of the Entities has changed
    391 
    392             //recall the memory and move them;
    393 
    394             Dictionary<IConnector, Point>.KeyCollection keys = connectorMemory.Keys;
    395             Point p;
    396             foreach (IConnector cn in keys)
    397             {
    398                 p = connectorMemory[cn];
    399                 cn.MoveBy(new Point(p.X - cn.Point.X + groupConnectorOffset.X, p.Y - cn.Point.Y + groupConnectorOffset.Y));
    400                 cn.Enabled = true;
    401             }
    402         }
    403 
    404         /// <summary>
    405         /// The custom menu to be added to the base menu of this entity
    406         /// </summary>
    407         /// <returns>ToolStripItem[]</returns>
    408         public override ToolStripItem[] Menu()
    409         {
    410             return null;
    411         }
    412         /// <summary>
    413         /// Handles the OnItemRemoved of the Entities
    414         /// </summary>
    415         /// <param name="sender">The sender.</param>
    416         /// <param name="e">The e.</param>
    417         void mEntities_OnItemRemoved(object sender, CollectionEventArgs<IDiagramEntity> e)
    418         {
    419             CalculateRectangle();
    420         }
    421 
    422         /// <summary>
    423         /// Handles the OnClear event of the Entities.
    424         /// </summary>
    425         /// <param name="sender">The source of the event.</param>
    426         /// <param name="e">The <see cref="T:System.EventArgs"/> instance containing the event data.</param>
    427         void mEntities_OnClear(object sender, EventArgs e)
    428         {
    429             mRectangle = Rectangle.Empty;
    430         }
    431 
    432         /// <summary>
    433         /// Handles the OnItemAdded event of the Entities
    434         /// </summary>
    435         /// <param name="sender">The sender.</param>
    436         /// <param name="e">The e.</param>
    437         void mEntities_OnItemAdded(object sender, CollectionEventArgs<IDiagramEntity> e)
    438         {
    439             //if(mEntities.Count == 1)
    440             //    mRectangle = e.Item.Rectangle;
    441             //else
    442             //{
    443             //    mRectangle = Rectangle.Union((Rectangle) mRectangle, e.Item.Rectangle);
    444             //}
    445             CalculateRectangle();
    446         }
    447 
    448         /// <summary>
    449         /// Calculates the bounding rectangle of this group.
    450         /// </summary>
    451         public void CalculateRectangle()
    452         {
    453             if (mEntities == null || mEntities.Count == 0)
    454                 return;
    455             Rectangle rec = mEntities[0].Rectangle;
    456             foreach (IDiagramEntity entity in Entities)
    457             {
    458                 //cascade the calculation if necessary
    459                 if ((entity is CollapsibleGroupShape) && !(entity as CollapsibleGroupShape).Collapsed) (entity as IGroup).CalculateRectangle();
    460 
    461                 rec = Rectangle.Union(rec, entity.Rectangle);
    462             }
    463             rec.Inflate(20, 20);
    464             this.mRectangle = rec;
    465             rec.Offset(5, 5);
    466             xicon.Transform(new Rectangle(rec.Location, new Size(16, 16)));
    467 
    468             expandLabel.Transform(new Rectangle(rec.Location.X + 20, rec.Location.Y,50, 12));
    469         }
    470 
    471 
    472         /// <summary>
    473         /// Paints the entity on the control
    474         /// <remarks>This method should not be called since the painting occurs via the <see cref="Model.Paintables"/>.</remarks>
    475         /// </summary>
    476         /// <param name="g"></param>
    477         public override void Paint(System.Drawing.Graphics g)
    478         {
    479             Rectangle rec = Rectangle;
    480             Utils.DrawRoundRect(g, ArtPalette.ConnectionShadow, rec);
    481 
    482             base.Paint(g);
    483         }
    484 
    485         /// <summary>
    486         /// Tests whether the group is hit by the mouse
    487         /// </summary>
    488         /// <param name="p"></param>
    489         /// <returns></returns>
    490         public override bool Hit(System.Drawing.Point p)
    491         {
    492             if (mCollapsed)
    493                 return mRectangle.Contains(p);
    494 
    495             foreach (IDiagramEntity entity in mEntities)
    496             {
    497                 if (entity.Hit(p))
    498                     return true;
    499             }
    500             return false;
    501         }
    502 
    503         /// <summary>
    504         /// Invalidates the entity
    505         /// </summary>
    506         public override void Invalidate()
    507         {
    508 
    509             if (mRectangle == null)
    510                 return;
    511 
    512             Rectangle rec = mRectangle;
    513             rec.Inflate(20, 20);
    514             Model.RaiseOnInvalidateRectangle(rec);
    515         }
    516 
    517         /// <summary>
    518         /// Moves the entity on the canvas
    519         /// </summary>
    520         /// <param name="p"></param>
    521         public override void MoveBy(System.Drawing.Point p)
    522         {
    523             base.MoveBy(p);
    524 
    525             Rectangle recBefore = mRectangle;
    526             recBefore.Inflate(20, 20);
    527 
    528             //no need to invalidate since it'll be done by the individual move actions
    529             foreach (IDiagramEntity entity in mEntities)
    530             {
    531                 entity.MoveBy(p);
    532             }
    533 
    534             mRectangle.X += p.X;
    535             mRectangle.Y += p.Y;
    536             //shift the latent copy of the real rectangle if the group is in a collapsed state
    537             if (mCollapsed)
    538             {
    539                 rectangleMemory.X += p.X;
    540                 rectangleMemory.Y += p.Y;
    541                 //the global offset has to be memorized; when we'll expand the group this offset has to be added to the original values
    542                 groupConnectorOffset.Offset(p);
    543             }
    544 
    545 
    546             //refresh things
    547             this.Invalidate(recBefore);//position before the move
    548             this.Invalidate();//current position
    549 
    550         }
    551 
    552         public override bool MouseDown(MouseEventArgs e)
    553         {
    554             // Was a material hit in the base ComplexShape?
    555             if (base.MouseDown(e))
    556             {
    557                 return true;
    558             }
    559 
    560             // If not, should we pass it on to the entities in this
    561             // group?
    562             foreach (IDiagramEntity entity in this.mEntities)
    563             {
    564                 if (entity.Hit(e.Location))
    565                 {
    566                     if (entity.MouseDown(e))
    567                     {
    568                         return true;
    569                     }
    570                 }
    571             }
    572 
    573             return false;
    574         }
    575 
    576 
    577         #endregion
    578     }
     506      }
     507
     508      return false;
     509    }
     510
     511
     512    #endregion
     513  }
    579514
    580515
Note: See TracChangeset for help on using the changeset viewer.