From c1ed4cfe81c1c84f8c94c977900c10b3ae8449e9 Mon Sep 17 00:00:00 2001 From: jkauttio Date: Tue, 29 Oct 2013 11:52:18 +0000 Subject: [PATCH] Add radio buttons in main toolbar for different diagram editor modes. #fixes #4486 git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@28145 ac1ea38d-2e2b-0410-8846-a27921b304fc --- org.simantics.sysdyn.ui/icons/cursor.png | Bin 0 -> 354 bytes org.simantics.sysdyn.ui/icons/dependency.png | Bin 0 -> 387 bytes org.simantics.sysdyn.ui/icons/flow.png | Bin 0 -> 349 bytes .../sysdyn/ui/editor/DiagramViewer.java | 2 +- .../editor/participant/PointerInteractor.java | 148 --------------- .../editor/participant/SysdynConnectTool.java | 2 +- .../participant/SysdynPointerInteractor.java | 170 ++++++++++++++++++ .../ui/elements/SysdynElementHints.java | 8 +- .../ui/handlers/DiagramToolHandler.java | 61 +++++++ 9 files changed, 240 insertions(+), 151 deletions(-) create mode 100644 org.simantics.sysdyn.ui/icons/cursor.png create mode 100644 org.simantics.sysdyn.ui/icons/dependency.png create mode 100644 org.simantics.sysdyn.ui/icons/flow.png delete mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/PointerInteractor.java create mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynPointerInteractor.java create mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/DiagramToolHandler.java diff --git a/org.simantics.sysdyn.ui/icons/cursor.png b/org.simantics.sysdyn.ui/icons/cursor.png new file mode 100644 index 0000000000000000000000000000000000000000..532f532d87ef60b5f2cdcdeb573ec949d2918def GIT binary patch literal 354 zcmV-o0iFJdP)I0T{~(qIu$a8Oa`;1VJZ+NJ#? z)Z`G6Xm=;i@Oy^O@W4+X<|%s@Z9U8K%Cou=JW=N{umR|dc<1KC5j-&Bmny}u z1Gr;ImmX!ZVOvnb2Z3IG9yvhp5kdn#W^JX2LP{w9t>Mgm0h`0-w1g7ei1zafe zdny~;a&&9~i}?5QG&nFlE(hRq9e(XsJj>7i0YpGB?|)P=F8}}l07*qoM6N<$f=`l= A>i_@% literal 0 HcmV?d00001 diff --git a/org.simantics.sysdyn.ui/icons/dependency.png b/org.simantics.sysdyn.ui/icons/dependency.png new file mode 100644 index 0000000000000000000000000000000000000000..6a604a309e7996e66446f40a00738e16c33b4199 GIT binary patch literal 387 zcmV-}0et?6P)yuc*MEaBesr!D8U4O1jzC=z~2({oOHzJ5*9Rxt1jmh!wXe@vk4 zJwTo2Eb$|O@#_Rf=fj*O;wzk9KgC2vpsEmMiwVL6rW!<5jEn6}h%n&ZaXYw-JzoNQ zoh^9ht=XGRXF?v{d$6QfbT*GhW3*QYcf+f6h2~^t2a?nvc~rH6tnPe3O}5U>K67X; zT5vN5C*|X}wuL_|uCcMchN9TPboz$X;s3&tZ4}A{-o+xssS$pyBwe hA6PhNiT}Ro>#A+qW*AYQLZl(!&BX$x7Ik;qO170ssEM z@$bKXf%rGW?|(r27bf-TSv zD}TdX0CM*JhkLO)8|Y^+n~Q^sK~hqR;q|N647YFGy>NTZJsWr!5CaSfwJm@a><8NX v2&h?| pickTerminals(Point2D controlPos) - { - Rectangle2D controlPickRect = new Rectangle2D.Double(controlPos.getX()-PointerInteractor.PICK_DIST, controlPos.getY()-PointerInteractor.PICK_DIST, PointerInteractor.PICK_DIST*2+1, PointerInteractor.PICK_DIST*2+1); - Shape canvasPickRect = GeometryUtils.transformShape(controlPickRect, util.getInverseTransform()); - List ti = TerminalUtil.pickTerminals(diagram, canvasPickRect, false, true); - return ti; - } -} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynConnectTool.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynConnectTool.java index 9182e3b1..797b1825 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynConnectTool.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynConnectTool.java @@ -309,7 +309,7 @@ public class SysdynConnectTool extends ConnectTool2 { endFlagNode.setTransform(AffineTransform.getTranslateInstance(mouseCanvasPos.getX(), mouseCanvasPos.getY())); } - List tiList = ((org.simantics.sysdyn.ui.editor.participant.PointerInteractor)pi).pickTerminals(me.controlPosition); + List tiList = ((org.simantics.sysdyn.ui.editor.participant.SysdynPointerInteractor)pi).pickTerminals(me.controlPosition); TerminalInfo ti = null; IConnectionAdvisor advisor = diagram.getHint(DiagramHints.CONNECTION_ADVISOR); diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynPointerInteractor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynPointerInteractor.java new file mode 100644 index 00000000..55df6463 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynPointerInteractor.java @@ -0,0 +1,170 @@ +package org.simantics.sysdyn.ui.editor.participant; +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ + +import java.awt.Shape; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.util.List; + +import org.simantics.g2d.canvas.Hints; +import org.simantics.g2d.canvas.ICanvasParticipant; +import org.simantics.g2d.canvas.IToolMode; +import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency; +import org.simantics.g2d.canvas.impl.DependencyReflection.Reference; +import org.simantics.g2d.connection.IConnectionAdvisor; +import org.simantics.g2d.diagram.DiagramHints; +import org.simantics.g2d.diagram.handler.PickContext; +import org.simantics.g2d.diagram.participant.Selection; +import org.simantics.g2d.diagram.participant.TerminalPainter; +import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor; +import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil; +import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil.TerminalInfo; +import org.simantics.g2d.element.ElementClasses; +import org.simantics.g2d.element.IElementClassProvider; +import org.simantics.g2d.participant.KeyUtil; +import org.simantics.g2d.participant.MouseUtil; +import org.simantics.g2d.participant.TransformUtil; +import org.simantics.g2d.utils.GeometryUtils; +import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler; +import org.simantics.scenegraph.g2d.events.MouseEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent; +import org.simantics.sysdyn.ui.editor.participant.SysdynElementClassProviders.ISysdynElementClassProvider; +import org.simantics.sysdyn.ui.editor.routing.DependencyRouter; +import org.simantics.sysdyn.ui.editor.routing.FlowRouter; +import org.simantics.sysdyn.ui.elements.AuxiliaryFactory; +import org.simantics.sysdyn.ui.elements.CloudFactory; +import org.simantics.sysdyn.ui.elements.InputFactory; +import org.simantics.sysdyn.ui.elements.ModuleFactory; +import org.simantics.sysdyn.ui.elements.SysdynElementHints; +import org.simantics.sysdyn.ui.elements.connections.ConnectionClasses; + +/** + * Pointer tool does the following operations with mouse: + * - Selections + * - Scale + * - Rotate + * - Translate + * - Draws connections + * + * Pointer tool is active only when KEY_TOOLMODE is PointerToolMode + * + * TODO Pick rectangle not a point + * + * @author Toni Kalajainen + */ +public class SysdynPointerInteractor extends PointerInteractor { + + @Dependency Selection selection; + @Dependency KeyUtil keys; + @Dependency TransformUtil util; + @Dependency PickContext pickContext; + @Dependency MouseUtil mice; + @Reference TerminalPainter terminalPainter; + + public SysdynPointerInteractor(boolean clickSelect, boolean boxSelect, boolean dragElement, boolean dndDragElement, boolean connect, boolean doubleClickEdit, IElementClassProvider newConnectionClassProvider) { + super(clickSelect, boxSelect, dragElement, dndDragElement, connect, doubleClickEdit, newConnectionClassProvider); + } + + @EventHandler(priority = TOOL_PRIORITY) + public boolean handlePress(MouseButtonPressedEvent me) { + if (!connects()) + return false; + if (elementClassProvider == null) + return false; + + IToolMode mode = getHint(Hints.KEY_TOOL); + if (!Hints.CONNECTTOOL.equals(mode)) + return false; + + IToolMode sysdynMode = getHint(SysdynElementHints.SYSDYN_KEY_TOOL); + + assertDependencies(); + + TerminalInfo ti = pickTerminal(me.controlPosition); + Point2D curCanvasPos = util.controlToCanvas(me.controlPosition, null); + + ICanvasParticipant bsi = null; + + if (me.button == MouseEvent.LEFT_BUTTON) { + if (SysdynElementHints.DEPENDENCY_TOOL.equals(sysdynMode)) + bsi = getDependencyConnectTool(ti, me.mouseId, curCanvasPos); + else if (SysdynElementHints.FLOW_TOOL.equals(sysdynMode)) + bsi = getFlowConnectTool(ti, me.mouseId, curCanvasPos); + else + bsi = getDependencyConnectTool(ti, me.mouseId, curCanvasPos); + } + else if (me.button == MouseEvent.RIGHT_BUTTON) { + if (SysdynElementHints.DEPENDENCY_TOOL.equals(sysdynMode) || + SysdynElementHints.FLOW_TOOL.equals(sysdynMode)) + return false; + else + bsi = getFlowConnectTool(ti, me.mouseId, curCanvasPos); + } + + if (bsi != null) { + getContext().add(bsi); + return true; + } + + return false; + } + + private ICanvasParticipant getDependencyConnectTool(TerminalInfo ti, int mouseId, Point2D curCanvasPos) { + // can not have dependencies that start from thin air + if (ti == null) + return null; + // can not have dependencies that start from clouds + if (ti.e.getElementClass().getId().equals(CloudFactory.class.getSimpleName())) + return null; + + diagram.setHint(DiagramHints.ROUTE_ALGORITHM, new DependencyRouter()); + diagram.setHint(DiagramHints.KEY_USE_CONNECTION_FLAGS, false); + ISysdynElementClassProvider secp = (ISysdynElementClassProvider)elementClassProvider; + secp.put(ElementClasses.CONNECTION, elementClassProvider.get(ConnectionClasses.DEPENDENCY)); + + // not sure if this is necessary + IConnectionAdvisor advisor = diagram.getHint(DiagramHints.CONNECTION_ADVISOR); + if (advisor == null || advisor.canBeginConnection(null, ti.e, ti.t)) { + return new SysdynConnectTool(ti, mouseId, curCanvasPos); + } + + return null; + } + + private ICanvasParticipant getFlowConnectTool(TerminalInfo ti, int mouseId, Point2D curCanvasPos) { + // flows must start from thin air or clouds + if (ti != null && (ti.e.getElementClass().getId().equals(AuxiliaryFactory.class.getSimpleName()) || + ti.e.getElementClass().getId().equals(InputFactory.class.getSimpleName()) || + ti.e.getElementClass().getId().equals(ModuleFactory.class.getSimpleName()))) + return null; + + diagram.setHint(DiagramHints.ROUTE_ALGORITHM, new FlowRouter()); + diagram.setHint(DiagramHints.KEY_USE_CONNECTION_FLAGS, true); + ISysdynElementClassProvider secp = (ISysdynElementClassProvider)elementClassProvider; + secp.put(ElementClasses.CONNECTION, elementClassProvider.get(ConnectionClasses.FLOW)); + + // not sure if this is necessary + IConnectionAdvisor advisor = diagram.getHint(DiagramHints.CONNECTION_ADVISOR); + if (ti == null || advisor == null || advisor.canBeginConnection(null, ti.e, ti.t)) { + return new SysdynConnectTool(ti, mouseId, curCanvasPos); + } + + return null; + } + + public List pickTerminals(Point2D controlPos) { + 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); + Shape canvasPickRect = GeometryUtils.transformShape(controlPickRect, util.getInverseTransform()); + return TerminalUtil.pickTerminals(diagram, canvasPickRect, false, true); + } +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementHints.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementHints.java index 1b921020..4a46af46 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementHints.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementHints.java @@ -11,6 +11,8 @@ *******************************************************************************/ package org.simantics.sysdyn.ui.elements; +import org.simantics.g2d.canvas.IToolMode; +import org.simantics.g2d.canvas.impl.ToolMode; import org.simantics.utils.datastructures.hints.IHintContext.Key; import org.simantics.utils.datastructures.hints.IHintContext.KeyOf; @@ -18,6 +20,10 @@ public class SysdynElementHints { public static final Key KEY_INPUT_REFERENCE = new KeyOf(String.class, "INPUT_REFERENCE"); public static final Key KEY_ORIENTATION = new KeyOf(String.class, "ORIENTATION"); - public static final Key KEY_LOCATION = new KeyOf(String.class, "LOCATION"); + public static final Key KEY_LOCATION = new KeyOf(String.class, "LOCATION"); + + public static final Key SYSDYN_KEY_TOOL = new KeyOf(ToolMode.class, "SysdynKeyTool"); + public static final IToolMode DEPENDENCY_TOOL = new ToolMode("DependencyTool"); + public static final IToolMode FLOW_TOOL = new ToolMode("FlowTool"); } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/DiagramToolHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/DiagramToolHandler.java new file mode 100644 index 00000000..e162c85f --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/DiagramToolHandler.java @@ -0,0 +1,61 @@ +package org.simantics.sysdyn.ui.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.handlers.RadioState; +import org.simantics.g2d.canvas.Hints; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.canvas.IToolMode; +import org.simantics.sysdyn.ui.elements.SysdynElementHints; +import org.simantics.utils.threads.ThreadUtils; + +public class DiagramToolHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + final ICanvasContext context = (ICanvasContext)HandlerUtil.getActiveEditor(event).getAdapter(ICanvasContext.class); + if (context == null) { + throw new ExecutionException("Could not get context from editor"); + } + + String value = (String)event.getCommand().getState(RadioState.STATE_ID).getValue(); + + final IToolMode mode; + if ("pointer".equals(value)) { + mode = Hints.POINTERTOOL; + } + else if ("dependency".equals(value)) { + mode = SysdynElementHints.DEPENDENCY_TOOL; + } + else if ("flow".equals(value)) { + mode = SysdynElementHints.FLOW_TOOL; + } + else { + return null; + } + + ThreadUtils.syncExec(context.getThreadAccess(), new Runnable() { + @Override + public void run() { + if (mode.equals(SysdynElementHints.DEPENDENCY_TOOL) || mode.equals(SysdynElementHints.FLOW_TOOL)) { + // if one of the connection modes is selected, use the + // default connection tool as the base and indicate the + // desired connection type in another hint (this is done + // to make sure all features of the connection tool work + // as expected) + context.getDefaultHintContext().setHint(Hints.KEY_TOOL, Hints.CONNECTTOOL); + context.getDefaultHintContext().setHint(SysdynElementHints.SYSDYN_KEY_TOOL, mode); + } + else { + context.getDefaultHintContext().setHint(Hints.KEY_TOOL, mode); + context.getDefaultHintContext().removeHint(SysdynElementHints.SYSDYN_KEY_TOOL); + } + } + }); + + return null; + } + +} -- 2.47.1