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