]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.g2d/src/org/simantics/g2d/participant/MousePanZoomInteractor.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / participant / MousePanZoomInteractor.java
diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/participant/MousePanZoomInteractor.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/participant/MousePanZoomInteractor.java
new file mode 100644 (file)
index 0000000..53b2567
--- /dev/null
@@ -0,0 +1,434 @@
+/*******************************************************************************\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
+/*\r
+ *\r
+ * @author Toni Kalajainen\r
+ */\r
+package org.simantics.g2d.participant;\r
+\r
+import java.awt.Cursor;\r
+import java.awt.geom.Point2D;\r
+\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.canvas.IMouseCursorContext;\r
+import org.simantics.g2d.canvas.IMouseCursorHandle;\r
+import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant;\r
+import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;\r
+import org.simantics.g2d.participant.MouseUtil.MouseInfo;\r
+import org.simantics.scenegraph.g2d.events.Event;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent;\r
+import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;\r
+import org.simantics.scenegraph.g2d.events.KeyEvent.KeyReleasedEvent;\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.MouseMovedEvent;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseWheelMovedEvent;\r
+import org.simantics.scenegraph.g2d.nodes.NavigationNode;\r
+import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
+import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;\r
+\r
+/**\r
+ * Mouse pan & zoom\r
+ * \r
+ * Keyboard pan & zoom & zoom to fit etc\r
+ * \r
+ * This interactor depends on : - TransformUtil - MouseUtil - KeyUtil -\r
+ * PanZoomRotateHandler\r
+ * \r
+ * TODO Add rotate mode\r
+ * \r
+ * @deprecated this logic has been moved into scenegraph {@link NavigationNode}.\r
+ *             Using this participant will cause double navigation.\r
+ */\r
+@Deprecated\r
+public class MousePanZoomInteractor extends AbstractCanvasParticipant {\r
+\r
+    @Dependency TransformUtil util;\r
+    @Dependency MouseUtil mice;\r
+    @Dependency KeyUtil keys;\r
+    @Dependency PanZoomRotateHandler pzr;\r
+\r
+    /** Event priority for initiating pan / zoom */\r
+    public final static int MOUSE_PAN_PRIORITY = Integer.MAX_VALUE - 2000;\r
+\r
+    /** Event priority when panning is enabled */\r
+    public final static int PAN_PRIORITY = Integer.MAX_VALUE - 1000;\r
+    public final static int ZOOM_PRIORITY = Integer.MAX_VALUE - 1000 +1;\r
+\r
+    /** Cursor when panning */\r
+    public final static Cursor PAN_CURSOR = new Cursor(Cursor.MOVE_CURSOR);\r
+\r
+    /** Cursor when panning */\r
+    public final static Cursor ZOOM_CURSOR = new Cursor(Cursor.N_RESIZE_CURSOR);\r
+\r
+    /** Is pan enabled */\r
+    public final static Key KEY_MOUSE_PAN_ENABLED = new KeyOf(Boolean.class);\r
+\r
+    /** Is zoom enabled */\r
+    public final static Key KEY_MOUSE_ZOOM_ENABLED = new KeyOf(Boolean.class);\r
+\r
+    /** are mouse wheel action enabled */\r
+    public final static Key KEY_MOUSE_WHEEL_ZOOM_PAN_ENABLED = new KeyOf(Boolean.class);\r
+\r
+    /** The speed of mouse zoom , eg 0..100..X */\r
+    public final static Key KEY_MOUSE_ZOOM_SPEED = new KeyOf(Double.class);\r
+\r
+    /** Default mouse zoom speed */\r
+    public final static double DEFAULT_MOUSE_ZOOM_SPEED = 100;\r
+\r
+    /** The speed of mouse zoom , eg 0..100..X */\r
+    public final static Key KEY_MOUSE_WHEEL_ZOOM_SPEED = new KeyOf(Double.class);\r
+\r
+    /** Default mouse zoom speed */\r
+    public final static double DEFAULT_MOUSE_WHEEL_ZOOM_SPEED = 1000;\r
+\r
+    /** The speed of mouse zoom , eg 0..100..X */\r
+    public final static Key KEY_MOUSE_WHEEL_TRANSLATE_AMOUNT = new KeyOf(Double.class);\r
+\r
+    /** Default mouse zoom speed */\r
+    public final static double DEFAULT_MOUSE_WHEEL_TRANSLATE_AMOUNT = 10;\r
+\r
+    @Override\r
+    public void addedToContext(ICanvasContext ctx) {\r
+        super.addedToContext(ctx);\r
+        // Set Default values\r
+        setHint(KEY_MOUSE_ZOOM_SPEED, DEFAULT_MOUSE_ZOOM_SPEED);\r
+        setHint(KEY_MOUSE_ZOOM_ENABLED, true);\r
+        setHint(KEY_MOUSE_PAN_ENABLED, true);\r
+        setHint(KEY_MOUSE_WHEEL_ZOOM_PAN_ENABLED, true);\r
+        setHint(KEY_MOUSE_WHEEL_ZOOM_SPEED, DEFAULT_MOUSE_WHEEL_ZOOM_SPEED);\r
+        setHint(KEY_MOUSE_WHEEL_TRANSLATE_AMOUNT, DEFAULT_MOUSE_WHEEL_TRANSLATE_AMOUNT);\r
+    }\r
+\r
+    /**\r
+     * Inits mouse pan and zoom interactors.\r
+     * Eats mouse presses if shift is pressed.\r
+     * \r
+     * @param e\r
+     * @return\r
+     */\r
+    @EventHandler(priority = MOUSE_PAN_PRIORITY)\r
+    public boolean handleEvent(MouseEvent e) {\r
+        assertDependencies();\r
+        if (e.context instanceof MouseUtil)\r
+            return false;\r
+\r
+        if ((e instanceof MouseButtonPressedEvent) && (e.stateMask & MouseEvent.SHIFT_MASK) != 0 && ((MouseButtonPressedEvent)e).button==MouseEvent.LEFT_BUTTON)\r
+            return true;\r
+\r
+        // Mouse pan & zoom\r
+        if (e instanceof MouseMovedEvent) {\r
+            MouseMovedEvent mme = (MouseMovedEvent) e;\r
+            MouseInfo mi = mice.getMouseInfo(mme.mouseId);\r
+            if (mi == null)\r
+                return false;\r
+            if ((e.stateMask & MouseEvent.SHIFT_MASK) != 0 & mi.isMouseButtonPressed(MouseEvent.LEFT_BUTTON))\r
+            {\r
+                if (!isPanEnabled())\r
+                    return false;\r
+                if (!isPanning()) {\r
+                    getContext().add( new PanMode(mme.mouseId, mme.controlPosition, MouseEvent.LEFT_BUTTON) );\r
+                }\r
+                return true;\r
+            }\r
+            if (mi.isMouseButtonPressed(MouseEvent.MIDDLE_BUTTON))\r
+            {\r
+                if (!isPanEnabled())\r
+                    return false;\r
+                if (!isPanning()) {\r
+                    getContext().add( new PanMode(mme.mouseId, mme.controlPosition, MouseEvent.MIDDLE_BUTTON) );\r
+                }\r
+                return true;\r
+            }\r
+            if ((e.stateMask & MouseEvent.SHIFT_MASK) != 0 & mi.isMouseButtonPressed(MouseEvent.RIGHT_BUTTON))\r
+            {\r
+                if (!isZoomEnabled())\r
+                    return false;\r
+                if (!isZooming()) {\r
+                    Point2D diagramPosition = util.getInverseTransform().transform(mme.controlPosition, new Point2D.Double());\r
+\r
+                    getContext().add( new ZoomMode(mme.mouseId, mme.controlPosition, diagramPosition, MouseEvent.RIGHT_BUTTON) );\r
+                }\r
+                return true;\r
+            }\r
+        }\r
+\r
+        // Mouse wheel zoom / scroll\r
+        if (e instanceof MouseWheelMovedEvent) {\r
+            if (!isMouseWheelZoomPanEnabled())\r
+                return false;\r
+            MouseWheelMovedEvent we = (MouseWheelMovedEvent) e;\r
+            //if (!mm.isMouseButtonPressed(we.mouseId, MouseEvent.MIDDLE_BUTTON))\r
+            /*\r
+            if (!ctrl())\r
+                       {\r
+                               if (we.scrollType == MouseWheelMovedEvent.WHEEL_UNIT_SCROLL)\r
+                               {\r
+                                       double dy = we.wheelRotation * getMouseWheelTranslateAmount();\r
+                                       if (shift())\r
+                                               util.translateWithControlCoordinates(new Point2D.Double(dy, 0));\r
+                                       else\r
+                                               util.translateWithControlCoordinates(new Point2D.Double(0, dy));\r
+                                       return true;\r
+                               }\r
+                       } else\r
+             */\r
+            {\r
+                if (we.scrollType == MouseWheelMovedEvent.WHEEL_UNIT_SCROLL)\r
+                {\r
+                    double dy = we.wheelRotation;\r
+                    double zoom = getMouseWheelZoomSpeed();\r
+                    double base = 1.00 + (zoom / 10000);\r
+                    double scaleFactor = Math.pow(base, dy);\r
+\r
+                    scaleFactor = pzr.limitScaleFactor(scaleFactor);\r
+                    util.zoomAroundControlPoint(scaleFactor, we.controlPosition);\r
+                    //ti.zoom(scaleFactor);\r
+                    return true;\r
+                }\r
+            }\r
+        }\r
+        return false;\r
+    }\r
+\r
+    public boolean isPanEnabled()\r
+    {\r
+        Boolean h = getHint(KEY_MOUSE_PAN_ENABLED);\r
+        if (h==null) return false;\r
+        return h;\r
+    }\r
+\r
+    public boolean isPanning()\r
+    {\r
+        return !getContext().getItemsByClass(PanMode.class).isEmpty();\r
+    }\r
+\r
+    public boolean isZooming()\r
+    {\r
+        return !getContext().getItemsByClass(ZoomMode.class).isEmpty();\r
+    }\r
+\r
+    public boolean isZoomEnabled()\r
+    {\r
+        Boolean h = getHint(KEY_MOUSE_ZOOM_ENABLED);\r
+        if (h==null) return false;\r
+        return h;\r
+    }\r
+\r
+    public boolean isMouseWheelZoomPanEnabled()\r
+    {\r
+        Boolean h = getHint(KEY_MOUSE_WHEEL_ZOOM_PAN_ENABLED);\r
+        if (h==null) return false;\r
+        return h;\r
+    }\r
+\r
+    /**\r
+     * is Shift key down\r
+     * @return\r
+     */\r
+    /*public boolean shift()\r
+       {\r
+               return keys.isKeyPressed(KeyEvent.VK_SHIFT);\r
+       }\r
+\r
+       public boolean ctrl()\r
+       {\r
+               return keys.isKeyPressed(KeyEvent.VK_CONTROL);\r
+       }*/\r
+\r
+    public double getMouseZoomSpeed()\r
+    {\r
+        Double h = getHint(KEY_MOUSE_ZOOM_SPEED);\r
+        if (h==null) return DEFAULT_MOUSE_ZOOM_SPEED;\r
+        return h;\r
+    }\r
+\r
+    public double getMouseWheelZoomSpeed()\r
+    {\r
+        Double h = getHint(KEY_MOUSE_WHEEL_ZOOM_SPEED);\r
+        if (h==null) return DEFAULT_MOUSE_WHEEL_ZOOM_SPEED;\r
+        return h;\r
+    }\r
+\r
+    public double getMouseWheelTranslateAmount()\r
+    {\r
+        Double h = getHint(KEY_MOUSE_WHEEL_TRANSLATE_AMOUNT);\r
+        if (h==null) return DEFAULT_MOUSE_WHEEL_TRANSLATE_AMOUNT;\r
+        return h;\r
+    }\r
+\r
+    /**\r
+     * Shift and left mouse button is pressed, do panning\r
+     */\r
+    class PanMode extends AbstractCanvasParticipant\r
+    {\r
+        @Dependency TransformUtil util;\r
+        final int mouseId;\r
+        int releaseButton;\r
+        // Mouse system coordinates\r
+        Point2D mousePos;\r
+        IMouseCursorHandle cursor;\r
+\r
+        public PanMode(int mouseId, Point2D mousePos, int releaseButton) {\r
+            super();\r
+            this.mouseId = mouseId;\r
+            this.mousePos = new Point2D.Double(mousePos.getX(), mousePos.getY());\r
+            this.releaseButton = releaseButton;\r
+        }\r
+\r
+        @Override\r
+        public void addedToContext(ICanvasContext ctx) {\r
+            super.addedToContext(ctx);\r
+            IMouseCursorContext mctx = getContext().getMouseCursorContext();\r
+            if (mctx!=null)\r
+                cursor = mctx.setCursor(mouseId, PAN_CURSOR);\r
+        }\r
+\r
+        @EventHandler(priority = PAN_PRIORITY)\r
+        public boolean handleEvent(Event e) {\r
+            if (e instanceof MouseButtonReleasedEvent) {\r
+                MouseButtonReleasedEvent mpe = (MouseButtonReleasedEvent) e;\r
+                if (mpe.button == releaseButton && mpe.mouseId == mouseId)\r
+                {\r
+                    remove();\r
+                    return false;\r
+                }\r
+            }\r
+\r
+            if (e instanceof KeyReleasedEvent) {\r
+                KeyReleasedEvent ke = (KeyReleasedEvent) e;\r
+                if (ke.keyCode == java.awt.event.KeyEvent.VK_SHIFT)\r
+                {\r
+                    remove();\r
+                    return false;\r
+                }\r
+            }\r
+\r
+            if (e instanceof MouseMovedEvent) {\r
+                if (e.getContext() instanceof MouseUtil) return true;\r
+                MouseMovedEvent mme = (MouseMovedEvent) e;\r
+                if (mme.mouseId == mouseId) {\r
+                    Point2D oldPos = mousePos;\r
+                    Point2D newPos = mme.controlPosition;\r
+\r
+                    double dx = newPos.getX() - oldPos.getX();\r
+                    double dy = newPos.getY() - oldPos.getY();\r
+                    if (dx==0 && dy==0) return true;\r
+\r
+                    this.mousePos.setLocation(newPos);\r
+\r
+                    util.translateWithControlCoordinates(new Point2D.Double(dx, dy));\r
+                    return true;\r
+                }\r
+            }\r
+\r
+            return false;\r
+        }\r
+\r
+        @Override\r
+        public void removedFromContext(ICanvasContext ctx) {\r
+            if (cursor!=null) {\r
+                cursor.remove();\r
+                cursor = null;\r
+            }\r
+            super.removedFromContext(ctx);\r
+        }\r
+\r
+    }\r
+\r
+    /**\r
+     * Shift and right mouse button is pressed, do zooming\r
+     */\r
+    class ZoomMode extends AbstractCanvasParticipant\r
+    {\r
+        final int mouseId;\r
+        int releaseButton;\r
+\r
+        // Mouse system coordinates\r
+        Point2D prevMousePos;\r
+        Point2D origControlMousePos;\r
+        Point2D origDiagramMousePos;\r
+        IMouseCursorHandle cursor;\r
+\r
+        public ZoomMode(int mouseId, Point2D controlMousePos, Point2D mouseDiagramPos, int releaseButton) {\r
+            super();\r
+            this.mouseId = mouseId;\r
+            this.prevMousePos = (Point2D) controlMousePos.clone();\r
+            this.origControlMousePos = (Point2D) controlMousePos.clone();\r
+            this.origDiagramMousePos = (Point2D) mouseDiagramPos.clone();\r
+            this.releaseButton = releaseButton;\r
+        }\r
+\r
+        @Override\r
+        public void addedToContext(ICanvasContext ctx) {\r
+            super.addedToContext(ctx);\r
+            IMouseCursorContext mctx = getContext().getMouseCursorContext();\r
+            if (mctx!=null)\r
+                cursor = mctx.setCursor(mouseId, ZOOM_CURSOR);\r
+        }\r
+\r
+        @EventHandler(priority = ZOOM_PRIORITY)\r
+        public boolean handleEvent(Event e) {\r
+            if (e instanceof MouseButtonReleasedEvent) {\r
+                MouseButtonReleasedEvent mpe = (MouseButtonReleasedEvent) e;\r
+                if (mpe.button == releaseButton && mpe.mouseId == mouseId)\r
+                {\r
+                    remove();\r
+                    return false;\r
+                }\r
+            }\r
+\r
+            if (e instanceof KeyReleasedEvent) {\r
+                KeyReleasedEvent ke = (KeyReleasedEvent) e;\r
+                if (ke.keyCode == java.awt.event.KeyEvent.VK_SHIFT)\r
+                {\r
+                    remove();\r
+                    return false;\r
+                }\r
+            }\r
+\r
+            if (e instanceof MouseMovedEvent) {\r
+                if (e.getContext() instanceof MouseUtil) return true;\r
+                MouseMovedEvent mme = (MouseMovedEvent) e;\r
+                if (mme.mouseId == mouseId) {\r
+                    Point2D oldPos = prevMousePos;\r
+                    Point2D newPos = mme.controlPosition;\r
+\r
+                    double dy = newPos.getY() - oldPos.getY();\r
+//                                     double dx = newPos.getX() - oldPos.getX();\r
+                    this.prevMousePos.setLocation(newPos);\r
+\r
+                    double zoomSpeed = getMouseZoomSpeed();\r
+                    double base = 1.00 + (zoomSpeed / 10000);\r
+                    double scaleFactor = Math.pow(base, -dy);\r
+\r
+                    scaleFactor = pzr.limitScaleFactor(scaleFactor);\r
+                    util.zoomAroundDiagramPoint(scaleFactor, origDiagramMousePos);\r
+                    return true;\r
+                }\r
+            }\r
+\r
+            return false;\r
+        }\r
+\r
+        @Override\r
+        public void removedFromContext(ICanvasContext ctx) {\r
+            if (cursor!=null) {\r
+                cursor.remove();\r
+                cursor = null;\r
+            }\r
+\r
+            super.removedFromContext(ctx);\r
+        }\r
+    }\r
+\r
+}\r