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/UndoRedo/Commands/TransformCommand.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: 6.8 KB
Line 
1using System;
2using System.Collections;
3using System.Drawing;
4namespace Netron.Diagramming.Core {
5  /// <summary>
6  /// ICommand implementation of the transform action
7  /// </summary>
8  class TransformCommand : Command {
9    #region Fields
10    Hashtable transformers;
11
12    double scalex, scaley;
13    Point origin;
14    #endregion
15
16    #region Properties
17
18
19
20    #endregion
21
22    #region Constructor
23    /// <summary>
24    /// Initializes a new instance of the <see cref="T:TransformCommand"/> class.
25    /// </summary>
26    /// <param name="controller">The controller.</param>
27    /// <param name="origin">The origin.</param>
28    /// <param name="scalex">The scalex.</param>
29    /// <param name="scaley">The scaley.</param>
30    /// <param name="transformers">The transformers.</param>
31    public TransformCommand(IController controller, Point origin, double scalex, double scaley, Hashtable transformers)
32      : base(controller) {
33      this.Text = "Transform selection";
34      this.transformers = transformers;
35      this.origin = origin;
36      this.scalex = scalex;
37      this.scaley = scaley;
38    }
39    #endregion
40
41    #region Methods
42
43    /// <summary>
44    /// Perform redo of this command.
45    /// </summary>
46    public override void Redo() {
47      //necessary to invalidate
48      Rectangle recBefore = CalculateRectangle(this.transformers);
49      recBefore.Inflate(20, 20);
50      Transform(this.origin, scalex, scaley, transformers);
51      Rectangle recAfter = CalculateRectangle(this.transformers);
52      recAfter.Inflate(20, 20);
53      this.Controller.View.Invalidate(recBefore);
54      this.Controller.View.Invalidate(recAfter);
55
56    }
57    /// <summary>
58    /// Calculates the bounding rectangle of the transformed items.
59    /// </summary>
60    /// <param name="transformers">The transformers.</param>
61    /// <returns></returns>
62    public static Rectangle CalculateRectangle(Hashtable transformers) {
63      Rectangle rec = Rectangle.Empty;
64      if (transformers == null || transformers.Count == 0)
65        return Rectangle.Empty;
66      bool first = true;
67      foreach (object val in transformers.Values) {
68        EntityBone bone = (EntityBone)val;
69        if (bone.Rectangle.Equals(Rectangle.Empty))
70          continue;
71        if (first) {
72          rec = bone.Rectangle;
73          first = false;
74        } else
75          rec = Rectangle.Union(rec, bone.Rectangle);
76
77      }
78      return rec;
79    }
80
81    /// <summary>
82    /// Perform undo of this command.
83    /// </summary>
84    public override void Undo() {
85      //necessary to invalidate
86      Rectangle recBefore = CalculateRectangle(this.transformers);
87      recBefore.Inflate(20, 20);
88      Transform(this.origin, 1, 1, transformers);
89      Rectangle recAfter = CalculateRectangle(this.transformers);
90      recAfter.Inflate(20, 20);
91      this.Controller.View.Invalidate(recBefore);
92      this.Controller.View.Invalidate(recAfter);
93    }
94
95    public static void Transform(
96        Point origin,
97        double scalex,
98        double scaley,
99        Hashtable transformers) {
100      Rectangle r;
101      int x, y, w, h;
102
103      //the new location of the connector
104
105      EntityBone bone;
106      IConnection conn;
107      IShape shape;
108
109      //Scale the entities; this could be done via matrix transform but it seems some rounding is necessary since I got terrible
110      //decimal accumulation mistakes without rounding off the double data type.
111      //However, if one rotation of shapes will be added the matrix tranfromation will be unavoidable.
112      foreach (object key in transformers.Keys) {
113        bone = (EntityBone)transformers[key];
114        r = bone.Rectangle;
115        //Scale the rectangle if not empty. If the rectangle is empty it is a connection.
116        if (r.Equals(Rectangle.Empty)) //the bone represents a connection
117                {
118          conn = key as IConnection;
119          //scaling of the From connector
120          if (!bone.ConnectorPoints[0].Equals(Point.Empty)) {
121
122            x = Convert.ToInt32(Math.Round(((double)bone.ConnectorPoints[0].X - (double)origin.X) * scalex + origin.X - conn.From.Point.X, 1));
123            y = Convert.ToInt32(Math.Round(((double)bone.ConnectorPoints[0].Y - (double)origin.Y) * scaley + origin.Y - conn.From.Point.Y, 1));
124            //it's important to use the Move method because shifting the Point could entail additional moves on the attached connectors
125            conn.From.MoveBy(new Point(x, y));
126          }
127          //scaling of the To connector
128          if (!bone.ConnectorPoints[1].Equals(Point.Empty)) {
129            x = Convert.ToInt32(Math.Round(((double)bone.ConnectorPoints[1].X - (double)origin.X) * scalex + origin.X - conn.To.Point.X, 1));
130            y = Convert.ToInt32(Math.Round(((double)bone.ConnectorPoints[1].Y - (double)origin.Y) * scaley + origin.Y - conn.To.Point.Y, 1));
131            conn.To.MoveBy(new Point(x, y));
132          }
133        } else    //it's a shape
134                {
135          shape = key as IShape;
136
137          //TransformShape(ref origin, scalex, scaley, ref r, ref bone, key, out x, out y, out w, out h, out a, out b, out p, out shape);
138          x = Convert.ToInt32(Math.Round(
139              (r.X - origin.X) * scalex + origin.X, 1));
140
141          y = Convert.ToInt32(Math.Round(
142              (r.Y - origin.Y) * scaley + origin.Y, 1));
143
144          w = Convert.ToInt32(r.Width * scalex);
145
146          h = Convert.ToInt32(r.Height * scaley);
147
148          // Only perform the tranform if the rectangle's height
149          // and width are less than or equal to the shape's 
150          // min/max size.
151          if ((w <= shape.MaxSize.Width) &&
152              (h <= shape.MaxSize.Height) &&
153              (w >= shape.MinSize.Width) &&
154              (h >= shape.MinSize.Height)) {
155            shape.Transform(x, y, w, h);
156          }
157
158        }
159
160      }
161
162    }
163
164    //private static void TransformShape(ref Point origin, double scalex, double scaley, ref Rectangle r, ref EntityBone bone, object key, out int x, out int y, out int w, out int h, out double a, out double b, out Point p, out IShape shape)
165    //{
166
167
168    //    //(key as IDiagramEntity).Rectangle = new Rectangle(x, y, w, h);
169
170    //    if(bone.ConnectorPoints != null)
171    //    {
172    //        shape = key as IShape;
173    //        for(int m = 0; m < bone.ConnectorPoints.Length; m++)
174    //        {
175    //            a = Math.Round(((double) bone.ConnectorPoints[m].X - (double) r.X) / (double) r.Width, 1) * w + x - shape.Connectors[m].Point.X;
176    //            b = Math.Round(((double) bone.ConnectorPoints[m].Y - (double) r.Y) / (double) r.Height, 1) * h + y - shape.Connectors[m].Point.Y;
177    //            p = new Point(Convert.ToInt32(a), Convert.ToInt32(b));
178    //            shape.Connectors[m].Move(p);
179    //        }
180    //    }
181    //}
182
183
184
185    #endregion
186  }
187
188}
Note: See TracBrowser for help on using the repository browser.