X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.g2d%2Fsrc%2Forg%2Fsimantics%2Fg2d%2Felement%2Fhandler%2Fimpl%2FAbstractGrabbable.java;h=13ff4693263c2dd0a1208e2cabd0bd44b91930ef;hb=fe29fd8956c3881e261ec4eee1cdd2ac27bc0554;hp=a235d34c1f042b4cf30c983796329a6e179566a7;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/element/handler/impl/AbstractGrabbable.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/element/handler/impl/AbstractGrabbable.java index a235d34c1..13ff46932 100644 --- a/bundles/org.simantics.g2d/src/org/simantics/g2d/element/handler/impl/AbstractGrabbable.java +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/element/handler/impl/AbstractGrabbable.java @@ -1,309 +1,309 @@ -/******************************************************************************* - * 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 getGrabs(IElement e, ICanvasContext ctx) - { - DiagramParticipant dp = ctx.getSingleItem(DiagramParticipant.class); - Map map = dp.getElementHints(e); - if (map==null) return null; - Map result = new HashMap(); - for (Entry 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 map = dp.getElementHints(e); - if (map==null) return 0; - int result = 0; - for (Entry 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; - } - -} +/******************************************************************************* + * 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 getGrabs(IElement e, ICanvasContext ctx) + { + DiagramParticipant dp = ctx.getSingleItem(DiagramParticipant.class); + Map map = dp.getElementHints(e); + if (map==null) return null; + Map result = new HashMap(); + for (Entry 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 map = dp.getElementHints(e); + if (map==null) return 0; + int result = 0; + for (Entry 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; + } + +}