]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram/src/org/simantics/diagram/handler/SimpleElementTransformHandler.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / handler / SimpleElementTransformHandler.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.diagram.handler;\r
13 \r
14 import java.awt.geom.Point2D;\r
15 import java.util.ArrayList;\r
16 import java.util.HashSet;\r
17 import java.util.List;\r
18 import java.util.Set;\r
19 \r
20 import org.simantics.db.ReadGraph;\r
21 import org.simantics.db.Resource;\r
22 import org.simantics.db.exception.DatabaseException;\r
23 import org.simantics.db.request.Read;\r
24 import org.simantics.diagram.elements.ElementTransforms;\r
25 import org.simantics.diagram.stubs.DiagramResource;\r
26 import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;\r
27 import org.simantics.g2d.diagram.DiagramMutator;\r
28 import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant;\r
29 import org.simantics.g2d.diagram.participant.Selection;\r
30 import org.simantics.g2d.element.ElementHints;\r
31 import org.simantics.g2d.element.IElement;\r
32 import org.simantics.g2d.element.handler.Rotate;\r
33 import org.simantics.g2d.element.handler.Scale;\r
34 import org.simantics.g2d.participant.MouseUtil;\r
35 import org.simantics.g2d.participant.MouseUtil.MouseInfo;\r
36 import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;\r
37 import org.simantics.scenegraph.g2d.events.command.CommandEvent;\r
38 import org.simantics.scenegraph.g2d.events.command.Commands;\r
39 import org.simantics.ui.SimanticsUI;\r
40 import org.simantics.utils.ui.ErrorLogger;\r
41 \r
42 /**\r
43  * Handles commands {@link Commands#ROTATE_ELEMENT_CCW},\r
44  * {@link Commands#ROTATE_ELEMENT_CW}, {@link Commands#FLIP_ELEMENT_HORIZONTAL},\r
45  * {@link Commands#FLIP_ELEMENT_VERTICAL} and {@link Commands#SCALE_ELEMENT} for\r
46  * rotating (in 90 degree steps), flipping and continuously scaling the current\r
47  * selection.\r
48  *\r
49  * @author Tuukka Lehtonen\r
50  */\r
51 public class SimpleElementTransformHandler extends AbstractDiagramParticipant {\r
52 \r
53     @Dependency protected Selection selection;\r
54     @Dependency protected MouseUtil mouseUtil;\r
55 \r
56     protected final boolean rotation;\r
57     protected final boolean flip;\r
58     protected final boolean scale;\r
59 \r
60     public SimpleElementTransformHandler() {\r
61         this(true, true, false);\r
62     }\r
63 \r
64     public SimpleElementTransformHandler(boolean enableRotation, boolean enableFlip, boolean enableScale) {\r
65         this.rotation = enableRotation;\r
66         this.flip = enableFlip;\r
67         this.scale = enableScale;\r
68     }\r
69 \r
70     public boolean isRotateEnabled() {\r
71         return rotation;\r
72     }\r
73 \r
74     public boolean isFlipEnabled() {\r
75         return flip;\r
76     }\r
77 \r
78     public boolean isScaleEnabled() {\r
79         return scale;\r
80     }\r
81 \r
82     @EventHandler(priority = 0)\r
83     public boolean handleCommand(CommandEvent ke) {\r
84         if (isRotateEnabled() && (ke.command.equals( Commands.ROTATE_ELEMENT_CCW ) || ke.command.equals( Commands.ROTATE_ELEMENT_CW ))) {\r
85             return rotate(ke.command.equals( Commands.ROTATE_ELEMENT_CW ));\r
86         } else if (isFlipEnabled() && (ke.command.equals( Commands.FLIP_ELEMENT_HORIZONTAL ) || ke.command.equals( Commands.FLIP_ELEMENT_VERTICAL))) {\r
87             return flip(ke.command.equals( Commands.FLIP_ELEMENT_VERTICAL ));\r
88         } else if (isScaleEnabled() && Commands.SCALE_ELEMENT.equals(ke.command)) {\r
89             return startSelectionMouseScale(0);\r
90         }\r
91         return false;\r
92     }\r
93 \r
94     /**\r
95      * @param xAxis\r
96      */\r
97     private boolean flip(boolean xAxis) {\r
98 //      final double sx = ke.command.equals( Commands.FLIP_ELEMENT_HORIZONTAL ) ? -1 : 1;\r
99 //      final double sy = ke.command.equals( Commands.FLIP_ELEMENT_VERTICAL ) ? -1 : 1;\r
100 //      DiagramUtils.mutateDiagram(diagram, new Callback<DiagramMutator>() {\r
101 //          @Override\r
102 //          public void run(DiagramMutator mutator) {\r
103 //              scaleAllSelections(mutator, sx, sy);\r
104 //          }\r
105 //      });\r
106 //      DiagramUtils.validateAndFix(diagram, getContext());\r
107 //      setDirty();\r
108 \r
109         Resource[] elements = getSelection();\r
110         if (elements.length == 0)\r
111             return false;\r
112 \r
113         ElementTransforms.flip(elements, xAxis);\r
114         return true;\r
115     }\r
116 \r
117     /**\r
118      * @param clockwise\r
119      */\r
120     private boolean rotate(boolean clockwise) {\r
121 //      final double rotation = ke.command.equals(Commands.ROTATE_ELEMENT_CCW) ? -90 : 90;\r
122 //      DiagramUtils.mutateDiagram(diagram, new Callback<DiagramMutator>() {\r
123 //          @Override\r
124 //          public void run(DiagramMutator mutator) {\r
125 //              rotateAllSelections(mutator, rotation);\r
126 //          }\r
127 //      });\r
128 //      DiagramUtils.validateAndFix(diagram, getContext());\r
129 //      setDirty();\r
130 \r
131         Resource[] elements = getSelection();\r
132         if (elements.length == 0)\r
133             return false;\r
134 \r
135         ElementTransforms.rotate(elements, clockwise);\r
136         return true;\r
137     }\r
138 \r
139     protected Resource[] getSelection() {\r
140         Set<IElement> els = selection.getSelection(0);\r
141         final Set<Resource> resources = new HashSet<Resource>();\r
142         for (IElement el : els) {\r
143             Object o = el.getHint(ElementHints.KEY_OBJECT);\r
144             if (o instanceof Resource)\r
145                 resources.add((Resource) o);\r
146         }\r
147         try {\r
148             return SimanticsUI.getSession().syncRequest(new Read<Resource[]>() {\r
149                 @Override\r
150                 public Resource[] perform(ReadGraph graph) throws DatabaseException {\r
151                     List<Resource> result = getSelection(graph, resources);\r
152                     return result.toArray(new Resource[result.size()]);\r
153                 }\r
154             });\r
155         } catch (DatabaseException e) {\r
156             ErrorLogger.defaultLogError(e);\r
157             return Resource.NONE;\r
158         }\r
159     }\r
160 \r
161     protected List<Resource> getSelection(ReadGraph graph, Set<Resource> resources) throws DatabaseException {\r
162         DiagramResource dr = DiagramResource.getInstance(graph);\r
163         List<Resource> result = new ArrayList<Resource>();\r
164         for (Resource r : resources) {\r
165             if (graph.isInstanceOf(r, dr.Element) /*&& graph.isInstanceOf(r, dr.Monitor)*/)\r
166                 result.add(r);\r
167         }\r
168         return result;\r
169     }\r
170 \r
171     protected MouseScaleMode createMouseScaleMode(int mouseId, MouseInfo mi, Set<IElement> s) {\r
172         return new MouseScaleMode(mouseId, mi, s);\r
173     }\r
174     \r
175     boolean startSelectionMouseScale(int mouseId) {\r
176         Set<IElement> s = selection.getSelection(mouseId);\r
177         if (s.isEmpty())\r
178             return false;\r
179         // Prevent multiple mouse scale modes from being activated.\r
180         for (MouseScaleMode msm : getContext().getItemsByClass(MouseScaleMode.class))\r
181             if (msm.getMouseId() == mouseId)\r
182                 return false;\r
183         MouseInfo mi = mouseUtil.getMouseInfo(mouseId);\r
184         getContext().add( createMouseScaleMode(mouseId, mi, s) );\r
185         return true;\r
186     }\r
187 \r
188     void scaleAllSelections(DiagramMutator mutator, double xscale, double yscale) {\r
189         for (Set<IElement> s : selection.getSelections().values()) {\r
190             for (IElement e : s) {\r
191                 Scale scale = e.getElementClass().getAtMostOneItemOfClass(Scale.class);\r
192                 if (scale != null) {\r
193                     mutator.modifyTransform(e);\r
194                     Point2D sc = scale.getScale(e);\r
195                     sc.setLocation(xscale*sc.getX(), yscale*sc.getY());\r
196                     scale.setScale(e, sc);\r
197                 }\r
198             }\r
199         }\r
200     }\r
201 \r
202     void rotateAllSelections(DiagramMutator mutator, double degrees) {\r
203         double angrad = Math.toRadians(degrees);\r
204         Point2D origin = new Point2D.Double(0, 0);\r
205         for (Set<IElement> s : selection.getSelections().values()) {\r
206             for (IElement e : s) {\r
207                 Rotate rotate = e.getElementClass().getAtMostOneItemOfClass(Rotate.class);\r
208                 if (rotate != null) {\r
209                     mutator.modifyTransform(e);\r
210                     rotate.rotate(e, angrad, origin);\r
211                 }\r
212             }\r
213         }\r
214     }\r
215 \r
216 }\r