]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.g2d/src/org/simantics/g2d/element/handler/impl/DefaultTransform.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / element / handler / impl / DefaultTransform.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.g2d.element.handler.impl;\r
13 \r
14 import java.awt.geom.AffineTransform;\r
15 import java.awt.geom.Point2D;\r
16 import java.util.Collection;\r
17 \r
18 import org.simantics.g2d.canvas.ICanvasContext;\r
19 import org.simantics.g2d.diagram.IDiagram;\r
20 import org.simantics.g2d.element.ElementHints;\r
21 import org.simantics.g2d.element.IElement;\r
22 import org.simantics.g2d.element.handler.LifeCycle;\r
23 import org.simantics.g2d.element.handler.Move;\r
24 import org.simantics.g2d.element.handler.Rotate;\r
25 import org.simantics.g2d.element.handler.Scale;\r
26 import org.simantics.g2d.element.handler.Transform;\r
27 import org.simantics.g2d.element.handler.Validator;\r
28 \r
29 /**\r
30  * This class implements Transform, Move, Rotate, and Scale.\r
31  * It maintains element position in element variable ElementHints.KEY_TRANSFORM.\r
32  * \r
33  * @author Toni Kalajainen\r
34  */\r
35 public class DefaultTransform implements Transform, Move, Rotate, Scale, Validator, LifeCycle {\r
36 \r
37     private static final long serialVersionUID = -2394690413166528179L;\r
38 \r
39     public static final DefaultTransform INSTANCE = new DefaultTransform(null);\r
40 \r
41     Double aspectRatio;\r
42 \r
43     public DefaultTransform() {\r
44         this(null);\r
45     }\r
46 \r
47     public DefaultTransform(Double aspectRatio) {\r
48         this.aspectRatio = aspectRatio;\r
49     }\r
50 \r
51     @Override\r
52     public Double getFixedAspectRatio(IElement e) {\r
53         return aspectRatio;\r
54     }\r
55 \r
56     @Override\r
57     public Point2D getScale(IElement e) {\r
58         AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM);\r
59         return _getScale(at);\r
60     }\r
61 \r
62     @Override\r
63     public void setScale(IElement e, Point2D newScale) {\r
64         Point2D oldScale = getScale(e);\r
65         double sx = newScale.getX() / oldScale.getX();\r
66         double sy = newScale.getY() / oldScale.getY();\r
67         AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM);\r
68         at = new AffineTransform(at);\r
69         at.scale(sx, sy);\r
70         e.setHint(ElementHints.KEY_TRANSFORM, at);\r
71     }\r
72 \r
73     @Override\r
74     public Point2D getMaximumScale(IElement e) {\r
75         return null;\r
76     }\r
77 \r
78     @Override\r
79     public Point2D getMinimumScale(IElement e) {\r
80         return null;\r
81     }\r
82 \r
83     private static Point2D _getScale(AffineTransform at) {\r
84         double m00 = at.getScaleX();\r
85         double m11 = at.getScaleY();\r
86         double m10 = at.getShearY();\r
87         double m01 = at.getShearX();\r
88         // Project unit vector to canvas\r
89         double sx = Math.sqrt(m00 * m00 + m10 * m10);\r
90         double sy = Math.sqrt(m01 * m01 + m11 * m11);\r
91         return new Point2D.Double(sx, sy);\r
92     }\r
93 \r
94     @Override\r
95     public void validate(final IElement e, final ICanvasContext ctx, Collection<Issue> lst) {\r
96         /*\r
97                 if (aspectRatio != null) {\r
98                         // Validate aspect ratio\r
99                         final Point2D scale = getScale(e);\r
100                         double currentRatio = scale.getX() / scale.getY();\r
101                         if (Math.abs(currentRatio - aspectRatio) > 0.000001) {\r
102                                 lst.add(new Issue() {\r
103                                         @Override\r
104                                         public String getMessage() {\r
105                                                 return "Aspect ratio is wrong";\r
106                                         }\r
107 \r
108                                         @Override\r
109                                         public void addSuggestions(\r
110                                                         Collection<Suggestion> suggestionList) {\r
111                                                 suggestionList.add(new Suggestion() {\r
112                                                         @Override\r
113                                                         public boolean fix() {\r
114                                                                 double newSx = scale.getX();\r
115                                                                 double newSy = newSx * aspectRatio;\r
116                                                                 Point2D newScale = new Point2D.Double(newSx,\r
117                                                                                 newSy);\r
118                                                                 setScale(e, newScale);\r
119                                                                 ctx.setDirty();\r
120                                                                 return true;\r
121                                                         }\r
122 \r
123                                                         @Override\r
124                                                         public String getMessage() {\r
125                                                                 return "Scale height, keep width";\r
126                                                         }\r
127                                                 });\r
128                                         }\r
129                                 });\r
130                         }\r
131                         // TODO min scale validator\r
132                         // TODO max scale validator\r
133                 }\r
134 \r
135                 if (e.getHint(ElementHints.KEY_TRANSFORM) == null) {\r
136                         Issue i = new Issue() {\r
137                                 @Override\r
138                                 public String getMessage() {\r
139                                         return "Transform is missing";\r
140                                 }\r
141 \r
142                                 @Override\r
143                                 public void addSuggestions(Collection<Suggestion> suggestionList) {\r
144                                         Suggestion s = new Suggestion() {\r
145                                                 @Override\r
146                                                 public boolean fix() {\r
147                                                         e.setHint(ElementHints.KEY_TRANSFORM,\r
148                                                                         new AffineTransform());\r
149                                                         return true;\r
150                                                 }\r
151 \r
152                                                 @Override\r
153                                                 public String getMessage() {\r
154                                                         return "Set default transform";\r
155                                                 }\r
156                                         };\r
157                                         suggestionList.add(s);\r
158                                 }\r
159                         };\r
160                         lst.add(i);\r
161                 }\r
162          */\r
163     }\r
164 \r
165     @Override\r
166     public void rotate(IElement e, double theta, Point2D origo) {\r
167         if (Double.isNaN(theta)) return;\r
168         AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM);\r
169         at = (AffineTransform) at.clone();\r
170         Point2D localOrigo = at.transform(origo, null);\r
171         at.preConcatenate(AffineTransform.getRotateInstance(theta, localOrigo.getX(), localOrigo.getY()));\r
172         // This code concatenated the matrix from the wrong side\r
173         //at.rotate(theta, origo.getX(), origo.getY());\r
174         e.setHint(ElementHints.KEY_TRANSFORM, at);\r
175     }\r
176 \r
177     @Override\r
178     public double getAngle(IElement e) {\r
179         AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM);\r
180         double m01 = at.getShearX();\r
181         double m11 = at.getScaleY();\r
182         return -Math.atan2(m01, m11);\r
183     }\r
184 \r
185     @Override\r
186     public Point2D getPosition(IElement e) {\r
187         AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM);\r
188         Point2D p = new Point2D.Double(at.getTranslateX(), at.getTranslateY());\r
189         return p;\r
190     }\r
191 \r
192     @Override\r
193     public void moveTo(IElement e, double x, double y) {\r
194         AffineTransform origAt = e.getHint(ElementHints.KEY_TRANSFORM);\r
195 \r
196         AffineTransform result = new AffineTransform(origAt);\r
197         result.preConcatenate(AffineTransform.getTranslateInstance(x - origAt.getTranslateX(), y - origAt.getTranslateY()));\r
198         e.setHint(ElementHints.KEY_TRANSFORM, result);\r
199     }\r
200 \r
201     @Override\r
202     public AffineTransform getTransform(IElement e) {\r
203 \r
204         AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM);\r
205 \r
206         IElement parentElement = e.getHint(ElementHints.KEY_PARENT_ELEMENT);\r
207         if(parentElement == null) return at;\r
208 \r
209         Transform parentTransform = parentElement.getElementClass().getSingleItem(Transform.class);\r
210         assert(parentTransform!=null);\r
211 \r
212         AffineTransform result = (AffineTransform)at.clone();\r
213         AffineTransform parentAT = parentTransform.getTransform(parentElement);\r
214         result.preConcatenate(AffineTransform.getTranslateInstance(parentAT.getTranslateX(), parentAT.getTranslateY()));\r
215 \r
216         return result;\r
217 \r
218     }\r
219 \r
220     @Override\r
221     public void setTransform(IElement e, AffineTransform at) {\r
222         e.setHint(ElementHints.KEY_TRANSFORM, at.clone());\r
223     }\r
224 \r
225     @Override\r
226     public void onElementActivated(IDiagram d, IElement e) {\r
227     }\r
228 \r
229     @Override\r
230     public void onElementCreated(IElement e) {\r
231         e.setHint(ElementHints.KEY_TRANSFORM, new AffineTransform());\r
232     }\r
233 \r
234     @Override\r
235     public void onElementDeactivated(IDiagram d, IElement e) {\r
236     }\r
237 \r
238     @Override\r
239     public void onElementDestroyed(IElement e) {\r
240     }\r
241 \r
242 \r
243 }\r