-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.g2d.element.handler.impl;\r
-\r
-import java.awt.geom.Point2D;\r
-import java.util.HashMap;\r
-import java.util.Map;\r
-import java.util.Map.Entry;\r
-\r
-import org.simantics.g2d.canvas.ICanvasContext;\r
-import org.simantics.g2d.canvas.IMouseCaptureHandle;\r
-import org.simantics.g2d.diagram.participant.DiagramParticipant;\r
-import org.simantics.g2d.diagram.participant.ElementInteractor;\r
-import org.simantics.g2d.element.ElementUtils;\r
-import org.simantics.g2d.element.IElement;\r
-import org.simantics.g2d.element.handler.HandleMouseEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonReleasedEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseClickEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDragBegin;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;\r
-import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
-import org.simantics.utils.datastructures.hints.IHintContext.MouseSpecificKeyOf;\r
-\r
-/**\r
- * Base implementation for handlers that handle grabbable objects.\r
- * \r
- * TODO Esc button cancels grab\r
- * \r
- * @author Toni Kalajainen\r
- */\r
-public abstract class AbstractGrabbable implements HandleMouseEvent {\r
-\r
- private static final long serialVersionUID = -3620527648364111724L;\r
- Double strayDistance;\r
- protected int grabMouseButton = MouseEvent.LEFT_BUTTON;\r
- \r
- /**\r
- * Create grabbable\r
- * @param strayDistance stray distance or null for no limit\r
- */\r
- public AbstractGrabbable(Double strayDistance)\r
- {\r
- this.strayDistance = strayDistance;\r
- }\r
-\r
- public AbstractGrabbable()\r
- {\r
- this.strayDistance = 1000.0;\r
- }\r
- \r
- @Override\r
- public boolean handleMouseEvent(IElement e, ICanvasContext ctx, MouseEvent me) {\r
- int pointerId = me.mouseId;\r
- GrabInfo gi = getGrabInfo(e, ctx, pointerId);\r
- \r
- if ((me instanceof MouseClickEvent)||(me instanceof MouseDragBegin)) {\r
- return gi!=null; \r
- }\r
- \r
- if ((me instanceof MouseMovedEvent)) {\r
- MouseMovedEvent mme = (MouseMovedEvent) me;\r
- if (gi==null) return false;\r
-\r
- gi.prevPosCanvas.setLocation( gi.dragPosCanvas );\r
- gi.prevPosControl.setLocation( gi.dragPosControl );\r
- gi.prevPosElement.setLocation( gi.dragPosElement );\r
- \r
- // Update drag positions\r
- gi.dragPosControl.setLocation(me.controlPosition);\r
- ElementUtils.controlToCanvasCoordinate(ctx, mme.controlPosition, gi.dragPosCanvas); \r
- ElementUtils.controlToElementCoordinate(e, ctx, mme.controlPosition, gi.dragPosElement);\r
- // Check if pointer has strayed too far, if so release grab\r
- double dist = gi.dragPosControl.distance(gi.grabPosControl); \r
-\r
- // Pointer has strayed too far -> release the pointer from the button\r
- if (dist>strayDistance)\r
- {\r
- releaseGrab(e, ctx, pointerId);\r
- onGrabCancel(gi, ctx);\r
- return true;\r
- }\r
-\r
- // Handle event\r
- onDrag(gi, ctx);\r
- // Consume event\r
- return true;\r
- }\r
- \r
- // Mouse released\r
- if (me instanceof MouseButtonReleasedEvent)\r
- {\r
- MouseButtonEvent mbe = (MouseButtonEvent) me;\r
- if (mbe.button != grabMouseButton) return false;\r
- if (gi==null) return false; \r
- releaseGrab(e, ctx, pointerId);\r
- onRelease(gi, ctx);\r
- return true;\r
- }\r
- // Mouse pressed\r
- if (me instanceof MouseButtonPressedEvent)\r
- {\r
- MouseButtonEvent mbe = (MouseButtonEvent) me;\r
- if (mbe.button != grabMouseButton) return false;\r
- if (!onGrabCheck(e, ctx, pointerId, me.controlPosition))\r
- return false;\r
- gi = grabMouse(e, ctx, pointerId, me.controlPosition);\r
- onGrab(gi,ctx);\r
- return true;\r
- }\r
- \r
- return false;\r
- }\r
- \r
- /**\r
- * Checks whether grab accepted\r
- * @param e element\r
- * @param pickPos pick position in element coordinates \r
- * @return true if position is grabbable\r
- */\r
- protected abstract boolean onGrabCheck(IElement e, ICanvasContext ctx, int pointerId, Point2D pickPos);\r
- \r
- protected abstract void onGrab(GrabInfo gi, ICanvasContext ctx);\r
-\r
- /**\r
- * Event when grab is released (and not canceled)\r
- * Invoked after grab is released.\r
- * @param gi\r
- * @param ctx\r
- */\r
- protected abstract void onRelease(GrabInfo gi, ICanvasContext ctx);\r
- \r
- protected abstract void onDrag(GrabInfo gi, ICanvasContext ctx);\r
- \r
- /**\r
- * Event notified when grab is canceled. Canceling occurs automatically\r
- * when mouse strays too far and when user sends cancel command (presses esc) \r
- * \r
- * @param e\r
- * @param grabPos\r
- */\r
- protected abstract void onGrabCancel(GrabInfo gi, ICanvasContext ctx);\r
- \r
- protected void cancelGrab() { \r
- }\r
- \r
- public static class GrabInfo {\r
- // Grabbed element\r
- public IElement e;\r
- // grabbing pointer\r
- public int pointerId;\r
- // Grab position\r
- public Point2D grabPosControl = new Point2D.Double();\r
- public Point2D grabPosCanvas = new Point2D.Double();\r
- public Point2D grabPosElement = new Point2D.Double();\r
- // Drag position\r
- public Point2D dragPosControl = new Point2D.Double(); \r
- public Point2D dragPosCanvas = new Point2D.Double();\r
- public Point2D dragPosElement = new Point2D.Double();\r
- // Prev position\r
- public Point2D prevPosControl = new Point2D.Double(); \r
- public Point2D prevPosCanvas = new Point2D.Double();\r
- public Point2D prevPosElement = new Point2D.Double();\r
- // Capture handle\r
- private IMouseCaptureHandle hnd;\r
- } \r
-\r
- /**\r
- * Remove GrabInfo object\r
- * @param e\r
- * @param ctx\r
- * @param pointerId\r
- */\r
- private void removeGrabInfo(IElement e, ICanvasContext ctx, int pointerId)\r
- {\r
- DiagramParticipant dp = ctx.getSingleItem(DiagramParticipant.class);\r
- Key key = new MouseSpecificKeyOf(pointerId, GrabInfo.class);\r
- dp.removeElementHint(e, key);\r
- }\r
- \r
- /**\r
- * Set GrabInfo object\r
- * @param e\r
- * @param ctx\r
- * @param pointerId\r
- * @param gi\r
- */\r
- private void setGrabInfo(IElement e, ICanvasContext ctx, int pointerId, GrabInfo gi)\r
- {\r
- DiagramParticipant dp = ctx.getSingleItem(DiagramParticipant.class);\r
- Key key = new MouseSpecificKeyOf(pointerId, GrabInfo.class);\r
- dp.setElementHint(e, key, gi);\r
- \r
- }\r
- \r
- /**\r
- * Get GrabInfo Object\r
- * @param e\r
- * @param ctx\r
- * @param pointerId\r
- * @return\r
- */\r
- private GrabInfo getGrabInfo(IElement e, ICanvasContext ctx, int pointerId)\r
- {\r
- DiagramParticipant dp = ctx.getSingleItem(DiagramParticipant.class);\r
- Key key = new MouseSpecificKeyOf(pointerId, GrabInfo.class); \r
- return dp.getElementHint(e, key);\r
- }\r
- \r
- /**\r
- * Get all pointer grabs\r
- * @return\r
- */\r
- protected Map<Integer, GrabInfo> getGrabs(IElement e, ICanvasContext ctx)\r
- {\r
- DiagramParticipant dp = ctx.getSingleItem(DiagramParticipant.class);\r
- Map<Key, Object> map = dp.getElementHints(e);\r
- if (map==null) return null;\r
- Map<Integer, GrabInfo> result = new HashMap<Integer, GrabInfo>();\r
- for (Entry<Key, Object> entry : map.entrySet())\r
- {\r
- if (!(entry.getValue() instanceof GrabInfo)) continue;\r
- GrabInfo gi = (GrabInfo) entry.getValue();\r
- result.put(gi.pointerId, gi);\r
- }\r
- return result;\r
- } \r
- \r
- protected int getGrabCount(IElement e, ICanvasContext ctx)\r
- {\r
- DiagramParticipant dp = ctx.getSingleItem(DiagramParticipant.class);\r
- Map<Key, Object> map = dp.getElementHints(e);\r
- if (map==null) return 0;\r
- int result = 0;\r
- for (Entry<Key, Object> entry : map.entrySet())\r
- {\r
- if (!(entry.getValue() instanceof GrabInfo)) continue;\r
- result ++;\r
- }\r
- return result;\r
- }\r
- \r
- /**\r
- * Release grab of a pointer\r
- * @param e\r
- * @param ctx\r
- * @param pointerId\r
- */\r
- protected void releaseGrab(IElement e, ICanvasContext ctx, int pointerId)\r
- {\r
- GrabInfo gi = getGrabInfo(e, ctx, pointerId);\r
- if (gi==null) return;\r
- gi.hnd.release();\r
- removeGrabInfo(e, ctx, pointerId);\r
- }\r
- \r
- /**\r
- * Grab a pointer\r
- * @param e\r
- * @param ctx\r
- * @param pointerId\r
- * @param grabPointControl\r
- * @return\r
- */\r
- private GrabInfo grabMouse(IElement e, ICanvasContext ctx, int pointerId, Point2D grabPointControl)\r
- {\r
- // Release previous capture, if exists\r
- releaseGrab(e, ctx, pointerId); \r
- \r
- ElementInteractor ei = ctx.getSingleItem(ElementInteractor.class);\r
- IMouseCaptureHandle hnd = ei.captureMouse(e, pointerId);\r
- if (hnd == null) return null;\r
-\r
- Point2D grabPointCanvas = ElementUtils.controlToCanvasCoordinate(ctx, grabPointControl, new Point2D.Double());\r
- Point2D grabPointElement = ElementUtils.controlToElementCoordinate(e, ctx, grabPointControl, new Point2D.Double());\r
- \r
- GrabInfo gi = new GrabInfo();\r
- gi.e = e;\r
- gi.hnd = hnd;\r
- gi.pointerId = pointerId;\r
- gi.grabPosControl.setLocation(grabPointControl);\r
- gi.grabPosCanvas.setLocation(grabPointCanvas);\r
- gi.grabPosElement.setLocation(grabPointElement);\r
- \r
- gi.dragPosControl.setLocation(grabPointControl);\r
- gi.dragPosCanvas.setLocation(grabPointCanvas);\r
- gi.dragPosElement.setLocation(grabPointElement);\r
- \r
- gi.prevPosControl.setLocation(grabPointControl);\r
- gi.prevPosCanvas.setLocation(grabPointCanvas);\r
- gi.prevPosElement.setLocation(grabPointElement);\r
- \r
- setGrabInfo(e, ctx, pointerId, gi);\r
- \r
- return gi;\r
- } \r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 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
+ *******************************************************************************/
+package org.simantics.g2d.element.handler.impl;
+
+import java.awt.geom.Point2D;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.simantics.g2d.canvas.ICanvasContext;
+import org.simantics.g2d.canvas.IMouseCaptureHandle;
+import org.simantics.g2d.diagram.participant.DiagramParticipant;
+import org.simantics.g2d.diagram.participant.ElementInteractor;
+import org.simantics.g2d.element.ElementUtils;
+import org.simantics.g2d.element.IElement;
+import org.simantics.g2d.element.handler.HandleMouseEvent;
+import org.simantics.scenegraph.g2d.events.MouseEvent;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonEvent;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonReleasedEvent;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseClickEvent;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDragBegin;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;
+import org.simantics.utils.datastructures.hints.IHintContext.Key;
+import org.simantics.utils.datastructures.hints.IHintContext.MouseSpecificKeyOf;
+
+/**
+ * Base implementation for handlers that handle grabbable objects.
+ *
+ * TODO Esc button cancels grab
+ *
+ * @author Toni Kalajainen
+ */
+public abstract class AbstractGrabbable implements HandleMouseEvent {
+
+ private static final long serialVersionUID = -3620527648364111724L;
+ Double strayDistance;
+ protected int grabMouseButton = MouseEvent.LEFT_BUTTON;
+
+ /**
+ * Create grabbable
+ * @param strayDistance stray distance or null for no limit
+ */
+ public AbstractGrabbable(Double strayDistance)
+ {
+ this.strayDistance = strayDistance;
+ }
+
+ public AbstractGrabbable()
+ {
+ this.strayDistance = 1000.0;
+ }
+
+ @Override
+ public boolean handleMouseEvent(IElement e, ICanvasContext ctx, MouseEvent me) {
+ int pointerId = me.mouseId;
+ GrabInfo gi = getGrabInfo(e, ctx, pointerId);
+
+ if ((me instanceof MouseClickEvent)||(me instanceof MouseDragBegin)) {
+ return gi!=null;
+ }
+
+ if ((me instanceof MouseMovedEvent)) {
+ MouseMovedEvent mme = (MouseMovedEvent) me;
+ if (gi==null) return false;
+
+ gi.prevPosCanvas.setLocation( gi.dragPosCanvas );
+ gi.prevPosControl.setLocation( gi.dragPosControl );
+ gi.prevPosElement.setLocation( gi.dragPosElement );
+
+ // Update drag positions
+ gi.dragPosControl.setLocation(me.controlPosition);
+ ElementUtils.controlToCanvasCoordinate(ctx, mme.controlPosition, gi.dragPosCanvas);
+ ElementUtils.controlToElementCoordinate(e, ctx, mme.controlPosition, gi.dragPosElement);
+ // Check if pointer has strayed too far, if so release grab
+ double dist = gi.dragPosControl.distance(gi.grabPosControl);
+
+ // Pointer has strayed too far -> release the pointer from the button
+ if (dist>strayDistance)
+ {
+ releaseGrab(e, ctx, pointerId);
+ onGrabCancel(gi, ctx);
+ return true;
+ }
+
+ // Handle event
+ onDrag(gi, ctx);
+ // Consume event
+ return true;
+ }
+
+ // Mouse released
+ if (me instanceof MouseButtonReleasedEvent)
+ {
+ MouseButtonEvent mbe = (MouseButtonEvent) me;
+ if (mbe.button != grabMouseButton) return false;
+ if (gi==null) return false;
+ releaseGrab(e, ctx, pointerId);
+ onRelease(gi, ctx);
+ return true;
+ }
+ // Mouse pressed
+ if (me instanceof MouseButtonPressedEvent)
+ {
+ MouseButtonEvent mbe = (MouseButtonEvent) me;
+ if (mbe.button != grabMouseButton) return false;
+ if (!onGrabCheck(e, ctx, pointerId, me.controlPosition))
+ return false;
+ gi = grabMouse(e, ctx, pointerId, me.controlPosition);
+ onGrab(gi,ctx);
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Checks whether grab accepted
+ * @param e element
+ * @param pickPos pick position in element coordinates
+ * @return true if position is grabbable
+ */
+ protected abstract boolean onGrabCheck(IElement e, ICanvasContext ctx, int pointerId, Point2D pickPos);
+
+ protected abstract void onGrab(GrabInfo gi, ICanvasContext ctx);
+
+ /**
+ * Event when grab is released (and not canceled)
+ * Invoked after grab is released.
+ * @param gi
+ * @param ctx
+ */
+ protected abstract void onRelease(GrabInfo gi, ICanvasContext ctx);
+
+ protected abstract void onDrag(GrabInfo gi, ICanvasContext ctx);
+
+ /**
+ * Event notified when grab is canceled. Canceling occurs automatically
+ * when mouse strays too far and when user sends cancel command (presses esc)
+ *
+ * @param e
+ * @param grabPos
+ */
+ protected abstract void onGrabCancel(GrabInfo gi, ICanvasContext ctx);
+
+ protected void cancelGrab() {
+ }
+
+ public static class GrabInfo {
+ // Grabbed element
+ public IElement e;
+ // grabbing pointer
+ public int pointerId;
+ // Grab position
+ public Point2D grabPosControl = new Point2D.Double();
+ public Point2D grabPosCanvas = new Point2D.Double();
+ public Point2D grabPosElement = new Point2D.Double();
+ // Drag position
+ public Point2D dragPosControl = new Point2D.Double();
+ public Point2D dragPosCanvas = new Point2D.Double();
+ public Point2D dragPosElement = new Point2D.Double();
+ // Prev position
+ public Point2D prevPosControl = new Point2D.Double();
+ public Point2D prevPosCanvas = new Point2D.Double();
+ public Point2D prevPosElement = new Point2D.Double();
+ // Capture handle
+ private IMouseCaptureHandle hnd;
+ }
+
+ /**
+ * Remove GrabInfo object
+ * @param e
+ * @param ctx
+ * @param pointerId
+ */
+ private void removeGrabInfo(IElement e, ICanvasContext ctx, int pointerId)
+ {
+ DiagramParticipant dp = ctx.getSingleItem(DiagramParticipant.class);
+ Key key = new MouseSpecificKeyOf(pointerId, GrabInfo.class);
+ dp.removeElementHint(e, key);
+ }
+
+ /**
+ * Set GrabInfo object
+ * @param e
+ * @param ctx
+ * @param pointerId
+ * @param gi
+ */
+ private void setGrabInfo(IElement e, ICanvasContext ctx, int pointerId, GrabInfo gi)
+ {
+ DiagramParticipant dp = ctx.getSingleItem(DiagramParticipant.class);
+ Key key = new MouseSpecificKeyOf(pointerId, GrabInfo.class);
+ dp.setElementHint(e, key, gi);
+
+ }
+
+ /**
+ * Get GrabInfo Object
+ * @param e
+ * @param ctx
+ * @param pointerId
+ * @return
+ */
+ private GrabInfo getGrabInfo(IElement e, ICanvasContext ctx, int pointerId)
+ {
+ DiagramParticipant dp = ctx.getSingleItem(DiagramParticipant.class);
+ Key key = new MouseSpecificKeyOf(pointerId, GrabInfo.class);
+ return dp.getElementHint(e, key);
+ }
+
+ /**
+ * Get all pointer grabs
+ * @return
+ */
+ protected Map<Integer, GrabInfo> getGrabs(IElement e, ICanvasContext ctx)
+ {
+ DiagramParticipant dp = ctx.getSingleItem(DiagramParticipant.class);
+ Map<Key, Object> map = dp.getElementHints(e);
+ if (map==null) return null;
+ Map<Integer, GrabInfo> result = new HashMap<Integer, GrabInfo>();
+ for (Entry<Key, Object> entry : map.entrySet())
+ {
+ if (!(entry.getValue() instanceof GrabInfo)) continue;
+ GrabInfo gi = (GrabInfo) entry.getValue();
+ result.put(gi.pointerId, gi);
+ }
+ return result;
+ }
+
+ protected int getGrabCount(IElement e, ICanvasContext ctx)
+ {
+ DiagramParticipant dp = ctx.getSingleItem(DiagramParticipant.class);
+ Map<Key, Object> map = dp.getElementHints(e);
+ if (map==null) return 0;
+ int result = 0;
+ for (Entry<Key, Object> entry : map.entrySet())
+ {
+ if (!(entry.getValue() instanceof GrabInfo)) continue;
+ result ++;
+ }
+ return result;
+ }
+
+ /**
+ * Release grab of a pointer
+ * @param e
+ * @param ctx
+ * @param pointerId
+ */
+ protected void releaseGrab(IElement e, ICanvasContext ctx, int pointerId)
+ {
+ GrabInfo gi = getGrabInfo(e, ctx, pointerId);
+ if (gi==null) return;
+ gi.hnd.release();
+ removeGrabInfo(e, ctx, pointerId);
+ }
+
+ /**
+ * Grab a pointer
+ * @param e
+ * @param ctx
+ * @param pointerId
+ * @param grabPointControl
+ * @return
+ */
+ private GrabInfo grabMouse(IElement e, ICanvasContext ctx, int pointerId, Point2D grabPointControl)
+ {
+ // Release previous capture, if exists
+ releaseGrab(e, ctx, pointerId);
+
+ ElementInteractor ei = ctx.getSingleItem(ElementInteractor.class);
+ IMouseCaptureHandle hnd = ei.captureMouse(e, pointerId);
+ if (hnd == null) return null;
+
+ Point2D grabPointCanvas = ElementUtils.controlToCanvasCoordinate(ctx, grabPointControl, new Point2D.Double());
+ Point2D grabPointElement = ElementUtils.controlToElementCoordinate(e, ctx, grabPointControl, new Point2D.Double());
+
+ GrabInfo gi = new GrabInfo();
+ gi.e = e;
+ gi.hnd = hnd;
+ gi.pointerId = pointerId;
+ gi.grabPosControl.setLocation(grabPointControl);
+ gi.grabPosCanvas.setLocation(grabPointCanvas);
+ gi.grabPosElement.setLocation(grabPointElement);
+
+ gi.dragPosControl.setLocation(grabPointControl);
+ gi.dragPosCanvas.setLocation(grabPointCanvas);
+ gi.dragPosElement.setLocation(grabPointElement);
+
+ gi.prevPosControl.setLocation(grabPointControl);
+ gi.prevPosCanvas.setLocation(grabPointCanvas);
+ gi.prevPosElement.setLocation(grabPointElement);
+
+ setGrabInfo(e, ctx, pointerId, gi);
+
+ return gi;
+ }
+
+}