]> gerrit.simantics Code Review - simantics/sysdyn.git/blob
ef74d7b5afb6ac62dce7bba836025fc8d75c8b0f
[simantics/sysdyn.git] /
1 package org.simantics.sysdyn.ui.editor.participant;\r
2 /*******************************************************************************\r
3  * Copyright (c) 2010 Association for Decentralized Information Management in\r
4  * Industry THTH ry.\r
5  * All rights reserved. This program and the accompanying materials\r
6  * are made available under the terms of the Eclipse Public License v1.0\r
7  * which accompanies this distribution, and is available at\r
8  * http://www.eclipse.org/legal/epl-v10.html\r
9  *\r
10  * Contributors:\r
11  *     VTT Technical Research Centre of Finland - initial API and implementation\r
12  *******************************************************************************/\r
13 \r
14 import java.awt.Shape;\r
15 import java.awt.geom.Point2D;\r
16 import java.awt.geom.Rectangle2D;\r
17 import java.util.List;\r
18 \r
19 import org.simantics.g2d.canvas.Hints;\r
20 import org.simantics.g2d.canvas.ICanvasParticipant;\r
21 import org.simantics.g2d.canvas.IToolMode;\r
22 import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;\r
23 import org.simantics.g2d.canvas.impl.DependencyReflection.Reference;\r
24 import org.simantics.g2d.connection.IConnectionAdvisor;\r
25 import org.simantics.g2d.diagram.DiagramHints;\r
26 import org.simantics.g2d.diagram.handler.PickContext;\r
27 import org.simantics.g2d.diagram.handler.PickRequest.PickSorter;\r
28 import org.simantics.g2d.diagram.participant.Selection;\r
29 import org.simantics.g2d.diagram.participant.TerminalPainter;\r
30 import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor;\r
31 import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil;\r
32 import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil.TerminalInfo;\r
33 import org.simantics.g2d.element.ElementClasses;\r
34 import org.simantics.g2d.element.IElementClassProvider;\r
35 import org.simantics.g2d.participant.KeyUtil;\r
36 import org.simantics.g2d.participant.MouseUtil;\r
37 import org.simantics.g2d.participant.TransformUtil;\r
38 import org.simantics.g2d.utils.GeometryUtils;\r
39 import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;\r
40 import org.simantics.scenegraph.g2d.events.MouseEvent;\r
41 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent;\r
42 import org.simantics.sysdyn.ui.editor.participant.SysdynElementClassProviders.ISysdynElementClassProvider;\r
43 import org.simantics.sysdyn.ui.editor.routing.DependencyRouter;\r
44 import org.simantics.sysdyn.ui.editor.routing.FlowRouter;\r
45 import org.simantics.sysdyn.ui.elements.AuxiliaryFactory;\r
46 import org.simantics.sysdyn.ui.elements.CloudFactory;\r
47 import org.simantics.sysdyn.ui.elements.InputFactory;\r
48 import org.simantics.sysdyn.ui.elements.ModuleFactory;\r
49 import org.simantics.sysdyn.ui.elements.SysdynElementHints;\r
50 import org.simantics.sysdyn.ui.elements.connections.ConnectionClasses;\r
51 \r
52 /**\r
53  * Pointer tool does the following operations with mouse:\r
54  *   - Selections\r
55  *   - Scale\r
56  *   - Rotate\r
57  *   - Translate\r
58  *   - Draws connections\r
59  *\r
60  * Pointer tool is active only when KEY_TOOLMODE is PointerToolMode\r
61  *\r
62  * TODO Pick rectangle not a point\r
63  *\r
64  * @author Toni Kalajainen\r
65  */\r
66 public class SysdynPointerInteractor extends PointerInteractor {\r
67 \r
68         @Dependency Selection selection;\r
69         @Dependency KeyUtil keys;\r
70         @Dependency TransformUtil util;\r
71         @Dependency PickContext pickContext;\r
72         @Dependency MouseUtil mice;\r
73         @Reference TerminalPainter terminalPainter;\r
74 \r
75         public SysdynPointerInteractor(boolean clickSelect, boolean boxSelect, boolean dragElement, boolean dndDragElement, boolean connect, boolean doubleClickEdit, IElementClassProvider newConnectionClassProvider, PickSorter pickSorter) {\r
76                 super(clickSelect, boxSelect, dragElement, dndDragElement, connect, doubleClickEdit, newConnectionClassProvider, pickSorter);\r
77         }\r
78 \r
79         @Override\r
80         @EventHandler(priority = TOOL_PRIORITY)\r
81         public boolean handlePress(MouseButtonPressedEvent me) {\r
82                 if (!connects()) \r
83                         return false;\r
84                 if (elementClassProvider == null)\r
85                         return false;\r
86                 \r
87                 // There should (maybe) be only one sysdynConnectTool associated with \r
88                 // the canvas context at a time. If this is not the case, right-clicks\r
89                 // are not always handled correctly mid-connection as they are instead \r
90                 // treated as commands to create a new cloud and a new flow. There\r
91                 // might be a more sensible way to fix this.\r
92                 if (getContext().containsItemByClass(SysdynConnectTool.class)) {\r
93                         return false;\r
94                 }\r
95                 \r
96                 IToolMode mode = getHint(Hints.KEY_TOOL);\r
97                 if (!Hints.CONNECTTOOL.equals(mode))\r
98                         return false;\r
99                 \r
100                 IToolMode sysdynMode = getHint(SysdynElementHints.SYSDYN_KEY_TOOL);\r
101                 \r
102                 assertDependencies();\r
103                 \r
104                 TerminalInfo ti = pickTerminal(me.controlPosition);\r
105                 Point2D curCanvasPos = util.controlToCanvas(me.controlPosition, null);\r
106                 \r
107                 ICanvasParticipant bsi = null;\r
108                 \r
109                 if (me.button == MouseEvent.LEFT_BUTTON) {\r
110                         if (SysdynElementHints.LOCK_TOOL.equals(sysdynMode))\r
111                                 // Do nothing.\r
112                                 return false;\r
113                         else if (SysdynElementHints.DEPENDENCY_TOOL.equals(sysdynMode))\r
114                                 bsi = getDependencyConnectTool(ti, me.mouseId, curCanvasPos);\r
115                         else if (SysdynElementHints.FLOW_TOOL.equals(sysdynMode))\r
116                                 bsi = getFlowConnectTool(ti, me.mouseId, curCanvasPos);\r
117                         else\r
118                                 bsi = getDependencyConnectTool(ti, me.mouseId, curCanvasPos);\r
119                 }\r
120                 else if (me.button == MouseEvent.RIGHT_BUTTON) {\r
121                         if (SysdynElementHints.LOCK_TOOL.equals(sysdynMode) ||\r
122                                         SysdynElementHints.DEPENDENCY_TOOL.equals(sysdynMode) ||\r
123                                         SysdynElementHints.FLOW_TOOL.equals(sysdynMode))\r
124                                 return false;\r
125                         else\r
126                                 bsi = getFlowConnectTool(ti, me.mouseId, curCanvasPos);\r
127                 }\r
128                 \r
129                 if (bsi != null) {\r
130                         getContext().add(bsi);\r
131                         return true;\r
132                 }\r
133                 \r
134                 return false;\r
135         }\r
136         \r
137         private ICanvasParticipant getDependencyConnectTool(TerminalInfo ti, int mouseId, Point2D curCanvasPos) {\r
138                 // can not have dependencies that start from thin air\r
139                 if (ti == null)\r
140                         return null;\r
141                 // can not have dependencies that start from clouds\r
142                 if (ti.e.getElementClass().getId().equals(CloudFactory.class.getSimpleName())) \r
143                         return null;\r
144                 \r
145                 diagram.setHint(DiagramHints.ROUTE_ALGORITHM, new DependencyRouter());\r
146                 diagram.setHint(DiagramHints.KEY_USE_CONNECTION_FLAGS, false);\r
147                 ISysdynElementClassProvider secp = (ISysdynElementClassProvider)elementClassProvider;\r
148                 secp.put(ElementClasses.CONNECTION, elementClassProvider.get(ConnectionClasses.DEPENDENCY));\r
149 \r
150                 // not sure if this is necessary\r
151                 IConnectionAdvisor advisor = diagram.getHint(DiagramHints.CONNECTION_ADVISOR);\r
152                 if (advisor == null || advisor.canBeginConnection(null, ti.e, ti.t)) {\r
153                         return new SysdynConnectTool(ti, mouseId, curCanvasPos);\r
154                 }\r
155                 \r
156                 return null;\r
157         }\r
158         \r
159         private ICanvasParticipant getFlowConnectTool(TerminalInfo ti, int mouseId, Point2D curCanvasPos) {\r
160                 // flows must not start from auxiliaries, inputs or modules\r
161                 if (ti != null && (ti.e.getElementClass().getId().equals(AuxiliaryFactory.class.getSimpleName()) || \r
162                                 ti.e.getElementClass().getId().equals(InputFactory.class.getSimpleName()) || \r
163                                 ti.e.getElementClass().getId().equals(ModuleFactory.class.getSimpleName()))) \r
164                         return null;\r
165                 \r
166                 diagram.setHint(DiagramHints.ROUTE_ALGORITHM, new FlowRouter());\r
167                 diagram.setHint(DiagramHints.KEY_USE_CONNECTION_FLAGS, true);\r
168                 ISysdynElementClassProvider secp = (ISysdynElementClassProvider)elementClassProvider;\r
169                 secp.put(ElementClasses.CONNECTION, elementClassProvider.get(ConnectionClasses.FLOW));\r
170                 \r
171                 // not sure if this is necessary\r
172                 IConnectionAdvisor advisor = diagram.getHint(DiagramHints.CONNECTION_ADVISOR);\r
173                 if (ti == null || advisor == null || advisor.canBeginConnection(null, ti.e, ti.t)) {\r
174                         return new SysdynConnectTool(ti, mouseId, curCanvasPos);\r
175                 }\r
176                 \r
177                 return null;\r
178         }\r
179 \r
180         @Override\r
181         public List<TerminalInfo> pickTerminals(Point2D controlPos) {\r
182                 Rectangle2D controlPickRect = new Rectangle2D.Double(controlPos.getX()-SysdynPointerInteractor.PICK_DIST, controlPos.getY()-SysdynPointerInteractor.PICK_DIST, SysdynPointerInteractor.PICK_DIST*2+1, SysdynPointerInteractor.PICK_DIST*2+1);\r
183                 Shape       canvasPickRect  = GeometryUtils.transformShape(controlPickRect, util.getInverseTransform());\r
184                 return TerminalUtil.pickTerminals(diagram, canvasPickRect, false, true);\r
185         }\r
186 }\r