1 /*******************************************************************************
\r
2 * Copyright (c) 2010 Association for Decentralized Information Management in
\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
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.sysdyn.ui.editor.participant;
\r
14 import java.awt.geom.AffineTransform;
\r
15 import java.awt.geom.Point2D;
\r
16 import java.util.Set;
\r
18 import org.simantics.db.Resource;
\r
19 import org.simantics.db.common.request.Queries;
\r
20 import org.simantics.db.exception.DatabaseException;
\r
21 import org.simantics.diagram.adapter.GraphToDiagramSynchronizer;
\r
22 import org.simantics.diagram.elements.TextNode;
\r
23 import org.simantics.diagram.query.DiagramRequests;
\r
24 import org.simantics.g2d.canvas.SGDesignation;
\r
25 import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;
\r
26 import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;
\r
27 import org.simantics.g2d.diagram.DiagramHints;
\r
28 import org.simantics.g2d.diagram.DiagramMutator;
\r
29 import org.simantics.g2d.diagram.DiagramUtils;
\r
30 import org.simantics.g2d.diagram.IDiagram;
\r
31 import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant;
\r
32 import org.simantics.g2d.diagram.participant.ElementPainter;
\r
33 import org.simantics.g2d.diagram.participant.Selection;
\r
34 import org.simantics.g2d.element.ElementClass;
\r
35 import org.simantics.g2d.element.ElementUtils;
\r
36 import org.simantics.g2d.element.IElement;
\r
37 import org.simantics.g2d.participant.MouseUtil;
\r
38 import org.simantics.g2d.participant.MouseUtil.MouseInfo;
\r
39 import org.simantics.scenegraph.g2d.G2DParentNode;
\r
40 import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;
\r
41 import org.simantics.scenegraph.g2d.events.KeyEvent;
\r
42 import org.simantics.scenegraph.g2d.events.KeyEvent.KeyPressedEvent;
\r
43 import org.simantics.scenegraph.g2d.events.KeyEvent.KeyReleasedEvent;
\r
44 import org.simantics.scenegraph.g2d.events.MouseEvent;
\r
45 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;
\r
46 import org.simantics.scenegraph.g2d.nodes.ShapeNode;
\r
47 import org.simantics.sysdyn.SysdynResource;
\r
48 import org.simantics.sysdyn.ui.elements.AuxiliaryFactory;
\r
49 import org.simantics.sysdyn.ui.elements.CloudFactory;
\r
50 import org.simantics.sysdyn.ui.elements.InputFactory;
\r
51 import org.simantics.sysdyn.ui.elements.LoopFactory;
\r
52 import org.simantics.sysdyn.ui.elements.ShadowFactory;
\r
53 import org.simantics.sysdyn.ui.elements.StockFactory;
\r
54 import org.simantics.sysdyn.ui.elements.ValveFactory;
\r
55 import org.simantics.ui.SimanticsUI;
\r
56 import org.simantics.utils.datastructures.Callback;
\r
57 import org.simantics.utils.ui.ExceptionUtils;
\r
59 public class CreateVariablesShortcutParticipant extends AbstractDiagramParticipant {
\r
61 private GraphToDiagramSynchronizer synchronizer;
\r
63 private VariableInformation variableInformation;
\r
66 MouseUtil mouseUtil;
\r
69 Selection selection;
\r
72 ElementPainter diagramPainter;
\r
75 G2DParentNode parent;
\r
77 private boolean createVar;
\r
78 private IDiagram createVarDiagram;
\r
80 @SGInit(designation = SGDesignation.CANVAS)
\r
81 public void init(G2DParentNode parent) {
\r
82 this.parent = parent;
\r
85 public void removeSG() {
\r
94 node = variableInformation.node;
\r
97 MouseInfo mi = mouseUtil.getMouseInfo(0);
\r
101 Point2D newPos = mi.canvasPosition;
\r
102 double x = newPos.getX();
\r
103 double y = newPos.getY();
\r
105 AffineTransform origAt = node.getTransform();
\r
106 double oldX = origAt.getTranslateX();
\r
107 double oldY = origAt.getTranslateY();
\r
108 AffineTransform move = new AffineTransform();
\r
109 move.setToTranslation(x - oldX, y - oldY);
\r
110 AffineTransform at2 = new AffineTransform(origAt);
\r
111 at2.preConcatenate(move);
\r
112 node.setTransform(at2);
\r
116 public CreateVariablesShortcutParticipant(GraphToDiagramSynchronizer synchronizer) {
\r
117 this.synchronizer = synchronizer;
\r
120 @EventHandler(priority = -10)
\r
121 public boolean handleKeyboardEvent(KeyEvent ke) {
\r
123 KeyPressedEvent kpe;
\r
124 if (ke instanceof KeyPressedEvent) {
\r
126 kpe = (KeyPressedEvent) ke;
\r
128 if (!kpe.isShiftDown() || isEditing())
\r
131 if (kpe.keyCode == java.awt.event.KeyEvent.VK_A) {
\r
132 variableInformation = new VariableInformation(
\r
133 java.awt.event.KeyEvent.VK_A,
\r
134 SysdynResource.URIs.AuxiliarySymbol,
\r
135 (ShapeNode)AuxiliaryFactory.AUX_STATIC_IMAGE.init(parent)
\r
137 } else if (kpe.keyCode == java.awt.event.KeyEvent.VK_S) {
\r
138 variableInformation = new VariableInformation(
\r
139 java.awt.event.KeyEvent.VK_S,
\r
140 SysdynResource.URIs.StockSymbol,
\r
141 (ShapeNode)StockFactory.STOCK_IMAGE.init(parent)
\r
143 } else if (kpe.keyCode == java.awt.event.KeyEvent.VK_C) {
\r
144 variableInformation = new VariableInformation(
\r
145 java.awt.event.KeyEvent.VK_C,
\r
146 SysdynResource.URIs.CloudSymbol,
\r
147 (ShapeNode)CloudFactory.CLOUD_IMAGE.init(parent)
\r
149 } else if (kpe.keyCode == java.awt.event.KeyEvent.VK_V) {
\r
150 variableInformation = new VariableInformation(
\r
151 java.awt.event.KeyEvent.VK_V,
\r
152 SysdynResource.URIs.ValveSymbol,
\r
153 (ShapeNode)ValveFactory.VALVE_STATIC_IMAGE.init(parent)
\r
155 } else if (kpe.keyCode == java.awt.event.KeyEvent.VK_I) {
\r
156 variableInformation = new VariableInformation(
\r
157 java.awt.event.KeyEvent.VK_I,
\r
158 SysdynResource.URIs.InputSymbol,
\r
159 (ShapeNode)InputFactory.INPUT_IMAGE.init(parent)
\r
161 } else if (kpe.keyCode == java.awt.event.KeyEvent.VK_G) {
\r
162 variableInformation = new VariableInformation(
\r
163 java.awt.event.KeyEvent.VK_G,
\r
164 SysdynResource.URIs.ShadowSymbol,
\r
165 (ShapeNode)ShadowFactory.GHOST_IMAGE.init(parent)
\r
167 } else if (kpe.keyCode == java.awt.event.KeyEvent.VK_L) {
\r
168 variableInformation = new VariableInformation(
\r
169 java.awt.event.KeyEvent.VK_L,
\r
170 SysdynResource.URIs.LoopSymbol,
\r
171 (ShapeNode)LoopFactory.LOOP_STATIC_IMAGE.init(parent)
\r
175 if (variableInformation != null) {
\r
181 KeyReleasedEvent kre;
\r
182 if (ke instanceof KeyReleasedEvent) {
\r
183 kre = (KeyReleasedEvent) ke;
\r
185 if (variableInformation != null
\r
186 && (kre.keyCode == variableInformation.shortcutKey || kre.keyCode == java.awt.event.KeyEvent.VK_SHIFT)) {
\r
187 if (node != null) {
\r
188 // If there is a variable to be created, do it when a key is released.
\r
191 createVariableOnDiagram(createVarDiagram);
\r
193 variableInformation = null;
\r
204 @EventHandler(priority = -10)
\r
205 public boolean handleMouse(MouseMovedEvent e) {
\r
207 if (variableInformation != null ) {
\r
210 if (node != null) {
\r
218 @EventHandler(priority = 100)
\r
219 public boolean handleMouseEvent(MouseEvent me) {
\r
222 MouseEvent.MouseClickEvent mce;
\r
223 if (me instanceof MouseEvent.MouseClickEvent) {
\r
224 mce = (MouseEvent.MouseClickEvent) me;
\r
231 mce.button == MouseEvent.LEFT_BUTTON &&
\r
232 variableInformation != null &&
\r
233 mce.stateMask == MouseEvent.SHIFT_MASK
\r
239 final IDiagram d = getHint(DiagramHints.KEY_DIAGRAM);
\r
243 // Need to create a new variable, save the diagram to do this later.
\r
245 createVarDiagram = d;
\r
251 private void createVariableOnDiagram(IDiagram d) {
\r
252 DiagramUtils.mutateDiagram(d, new Callback<DiagramMutator>() {
\r
254 public void run(DiagramMutator m) {
\r
262 .resource(variableInformation.symbolURI));
\r
263 ElementClass ec = SimanticsUI.getSession().syncRequest(
\r
264 DiagramRequests.getElementClass(r, diagram));
\r
266 IElement element = m.newElement(ec);
\r
268 // MouseUtil mutil = new MouseUtil();
\r
269 MouseInfo minfo = mouseUtil.getMouseInfo(0);
\r
271 //at least when using breakpoints this is possible
\r
275 Point2D p = minfo.canvasPosition;
\r
276 //FIXME - Arto element doesn't know its size at first. Hopefully temp fix.
\r
277 p.setLocation(p.getX()-5.46, p.getY()+1);
\r
279 ElementUtils.setPos(element, p);
\r
281 } catch (DatabaseException e) {
\r
282 ExceptionUtils.logAndShowError(e);
\r
288 synchronizer.getCanvasContext().getContentContext().setDirty();
\r
292 private class VariableInformation {
\r
293 public String symbolURI;
\r
294 public ShapeNode node;
\r
295 public int shortcutKey;
\r
297 public VariableInformation(int shortcutKey, String symbolURI, ShapeNode node) {
\r
298 this.symbolURI = symbolURI;
\r
300 this.shortcutKey = shortcutKey;
\r
304 private boolean isEditing() {
\r
305 int selectionId = 0;
\r
306 Set<IElement> ss = selection.getSelection(selectionId);
\r
307 if (ss.isEmpty()) {
\r
310 for (IElement e : ss) {
\r
311 for(Object o : e.getHints().values()) {
\r
312 if (o instanceof TextNode) {
\r
313 TextNode tn = (TextNode) o;
\r
314 if(tn.isEditMode())
\r