]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/connection/HighlightActionPointsAction.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / g2d / nodes / connection / HighlightActionPointsAction.java
index 7f7bd3cd9b99f434f16c68b6a55adfcd2ab3b357..ff5871bc10363befcce43bccb3c804ba513fdf9d 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
- * 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.scenegraph.g2d.nodes.connection;\r
-\r
-import java.awt.AlphaComposite;\r
-import java.awt.BasicStroke;\r
-import java.awt.Color;\r
-import java.awt.Composite;\r
-import java.awt.Graphics2D;\r
-import java.awt.Shape;\r
-import java.awt.Stroke;\r
-import java.awt.geom.AffineTransform;\r
-import java.awt.geom.Point2D;\r
-import java.awt.geom.Rectangle2D;\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-\r
-import org.simantics.diagram.connection.RouteGraph;\r
-import org.simantics.diagram.connection.RouteLineHalf;\r
-import org.simantics.diagram.connection.actions.IAction;\r
-import org.simantics.diagram.connection.rendering.IRouteGraphRenderer;\r
-import org.simantics.scenegraph.utils.Quality;\r
-import org.simantics.scenegraph.utils.QualityHints;\r
-\r
-/**\r
- * @author Tuukka Lehtonen\r
- */\r
-public class HighlightActionPointsAction implements IAction {\r
-\r
-    public static enum Action {\r
-        REMOVE,\r
-        RECONNECT\r
-    }\r
-\r
-    public static class Pick {\r
-        public static final Pick MISS = new Pick(null, null);\r
-\r
-        Action                   action;\r
-        RouteLineHalf            line;\r
-\r
-        public Pick(Action action, RouteLineHalf line) {\r
-            this.action = action;\r
-            this.line = line;\r
-        }\r
-\r
-        public boolean hasAction(Action action) {\r
-            return this.action == action;\r
-        }\r
-\r
-        public boolean hasResult() {\r
-            return action != null && line != null;\r
-        }\r
-\r
-        public boolean matches(Action action, RouteLineHalf line) {\r
-            if (this.action == null || this.line == null)\r
-                return false;\r
-            return this.action.equals(action) && this.line.equals(line);\r
-        }\r
-    }\r
-\r
-    private static final Shape          CROSS_SHAPE             = ActionShapes.CROSS_SHAPE;\r
-    private static final Shape          SCISSOR_SHAPE           = ActionShapes.transformShape(ActionShapes.SCISSOR_SHAPE, 1, 1, 0, 0, -Math.PI/2);\r
-\r
-    private static final Color          CROSS_COLOR             = new Color(0xe4, 0x40, 0x61);\r
-    private static final Color          SCISSOR_COLOR           = new Color(20, 20, 20);\r
-\r
-    public static final Stroke          STROKE                  = new BasicStroke(0.1f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);\r
-    public static final AlphaComposite  NO_HIT_COMPOSITE        = AlphaComposite.SrcOver.derive(0.8f);\r
-    public static final AlphaComposite  HIT_COMPOSITE           = AlphaComposite.SrcOver.derive(0.2f);\r
-\r
-    public static final double          DEGENERATED_LINE_LENGTH = 1;\r
-    public static final double          CUT_DIST_FROM_END       = 0.75;\r
-\r
-    RouteGraph                          rg;\r
-\r
-    transient Collection<RouteLineHalf> lhs                     = new ArrayList<RouteLineHalf>();\r
-    transient AffineTransform           transform               = new AffineTransform();\r
-    transient Rectangle2D               rect                    = new Rectangle2D.Double();\r
-    transient Point2D                   point                   = new Point2D.Double();\r
-\r
-    public HighlightActionPointsAction(RouteGraph rg) {\r
-        this.rg = rg;\r
-    }\r
-\r
-    public void setRouteGraph(RouteGraph rg) {\r
-        this.rg = rg;\r
-    }\r
-\r
-    @Override\r
-    public void render(Graphics2D g, IRouteGraphRenderer renderer, double mouseX, double mouseY) {\r
-        // Cannot perform cut or delete segment actions\r
-        // on connections between 2 terminals.\r
-        boolean simpleConnection = (rg.isSimpleConnection() || rg.getTerminals().size() <= 2);\r
-        boolean branchedConnection = rg.getTerminals().size() > 2;\r
-        if (!branchedConnection || simpleConnection)\r
-            return;\r
-\r
-        AffineTransform preTr = g.getTransform();\r
-        double realViewScale = 1.0 / getScale(preTr);\r
-        //System.out.println(realViewScale);\r
-        // Don't render any of the actions if they could not be seen anyway.\r
-        if (realViewScale > 0.7)\r
-            return;\r
-\r
-        lhs.clear();\r
-        rg.getLineHalves(lhs);\r
-\r
-        Pick pick = pickAction(rg, lhs, preTr, mouseX, mouseY);\r
-\r
-        Composite originalComposite = g.getComposite();\r
-        Composite basicComposite = pick.action != null ? HIT_COMPOSITE : NO_HIT_COMPOSITE;\r
-        g.setComposite(basicComposite);\r
-\r
-        // Always render these in high quality because otherwise the shapes\r
-        // will render with ugly artifacts when zoom level is a bit higher.\r
-        QualityHints origQualityHints = QualityHints.getQuality(g);\r
-        QualityHints.getHints(Quality.HIGH).setQuality(g);\r
-\r
-        // Render line removal markers\r
-        if (!simpleConnection) {\r
-            g.setPaint(CROSS_COLOR);\r
-            for (RouteLineHalf lh : lhs) {\r
-                if (removeLocation(lh, point) == null)\r
-                    continue;\r
-                boolean hit = pick.matches(Action.REMOVE, lh);\r
-                if (hit)\r
-                    g.setComposite(originalComposite);\r
-                g.translate(point.getX(), point.getY());\r
-                g.fill(CROSS_SHAPE);\r
-                g.setTransform(preTr);\r
-                if (hit)\r
-                    g.setComposite(basicComposite);\r
-            }\r
-        }\r
-\r
-        // Render reconnection markers if the connection is branched.\r
-        if (branchedConnection) {\r
-            g.setPaint(SCISSOR_COLOR);\r
-            for (RouteLineHalf lh : lhs) {\r
-                if (reconnectLocation(lh, point) == null)\r
-                    continue;\r
-                boolean hit = pick.matches(Action.RECONNECT, lh);\r
-                if (hit)\r
-                    g.setComposite(originalComposite);\r
-                transform.setToTranslation(point.getX(), point.getY());\r
-                if (!lh.getLine().isHorizontal())\r
-                    transform.rotate(Math.PI/2);\r
-                transform.translate(0, 0.35);\r
-                g.transform(transform);\r
-                g.fill(SCISSOR_SHAPE);\r
-                g.setTransform(preTr);\r
-                if (hit)\r
-                    g.setComposite(basicComposite);\r
-            }\r
-        }\r
-\r
-        origQualityHints.setQuality(g);\r
-        g.setComposite(originalComposite);\r
-    }\r
-\r
-    public Pick pickAction(RouteGraph rg, AffineTransform viewTr, double mouseX, double mouseY) {\r
-        boolean branchedConnection = rg.getTerminals().size() > 2;\r
-        boolean simpleConnection = (rg.isSimpleConnection() || rg.getTerminals().size() <= 2);\r
-        if (!branchedConnection || simpleConnection)\r
-            return null;\r
-\r
-        lhs.clear();\r
-        return pickAction(rg, rg.getLineHalves(lhs), viewTr, mouseX, mouseY);\r
-    }\r
-\r
-    public Pick pickAction(RouteGraph rg, Collection<RouteLineHalf> lhs, AffineTransform viewTr, double mouseX, double mouseY) {\r
-        boolean branchedConnection = rg.getTerminals().size() > 2;\r
-        boolean simpleConnection = (rg.isSimpleConnection() || rg.getTerminals().size() <= 2);\r
-        if (!branchedConnection || simpleConnection || viewTr == null)\r
-            return Pick.MISS;\r
-\r
-        double viewScale = 1.0 / getScale(viewTr);\r
-        if (viewScale > 0.7)\r
-            return Pick.MISS;\r
-\r
-        double nearest = Double.MAX_VALUE;\r
-        RouteLineHalf selected = null;\r
-        Action selectedAction = null;\r
-\r
-        // Pick line removal markers\r
-        if (!simpleConnection) {\r
-            double s = ActionShapes.CROSS_WIDTH * 0.25;\r
-            for (RouteLineHalf lh : lhs) {\r
-                if (removeLocation(lh, point) == null)\r
-                    continue;\r
-                double x = point.getX();\r
-                double y = point.getY();\r
-                rect.setFrameFromCenter(x, y, x-s, y-s);\r
-                boolean hit = rect.contains(mouseX, mouseY);\r
-                if (hit) {\r
-                    double distSq = distSq(x, y, mouseX, mouseY);\r
-                    if (distSq < nearest) {\r
-                        nearest = distSq;\r
-                        selected = lh;\r
-                        selectedAction = Action.REMOVE;\r
-                    }\r
-                }\r
-            }\r
-        }\r
-\r
-        // Pick reconnection markers if the connection is branched.\r
-        if (branchedConnection) {\r
-            double w = ActionShapes.SCISSOR_HEIGHT * 0.4;\r
-            double h = ActionShapes.SCISSOR_WIDTH * 0.3;\r
-            for (RouteLineHalf lh : lhs) {\r
-                if (reconnectLocation(lh, point) == null)\r
-                    continue;\r
-                double x = point.getX();\r
-                double y = point.getY();\r
-                rect.setFrameFromCenter(x, y, x-w, y-h);\r
-                boolean hit = rect.contains(mouseX, mouseY);\r
-                if (hit) {\r
-                    double distSq = distSq(x, y, mouseX, mouseY);\r
-                    if (distSq < nearest) {\r
-                        nearest = distSq;\r
-                        selected = lh;\r
-                        selectedAction = Action.RECONNECT;\r
-                    }\r
-                }\r
-            }\r
-        }\r
-\r
-        return selected == null ? Pick.MISS : new Pick(selectedAction, selected);\r
-    }\r
-\r
-    private static Point2D removeLocation(RouteLineHalf lh, Point2D p) {\r
-        if (lh.getLine().getTerminal() == null)\r
-            return null;\r
-\r
-        double x = lh.getLink().getX();\r
-        double y = lh.getLink().getY();\r
-        if (lh.getLine().isHorizontal()) {\r
-            x = (lh.getLine().getBegin().getX() + lh.getLine().getEnd().getX()) * .5;\r
-        } else {\r
-            y = (lh.getLine().getBegin().getY() + lh.getLine().getEnd().getY()) * .5;\r
-        }\r
-        p.setLocation(x, y);\r
-        return p;\r
-    }\r
-\r
-    private static Point2D reconnectLocation(RouteLineHalf lh, Point2D p) {\r
-        if (lh.getLine().getLength() < DEGENERATED_LINE_LENGTH*3)\r
-            return null;\r
-\r
-        final double dist = CUT_DIST_FROM_END;\r
-        double x = lh.getLink().getX();\r
-        double y = lh.getLink().getY();\r
-        if (lh.getLine().isHorizontal()) {\r
-            if (lh.getLink() == lh.getLine().getBegin())\r
-                x += dist*2;\r
-            else\r
-                x -= dist*2;\r
-        } else {\r
-            if (lh.getLink() == lh.getLine().getBegin())\r
-                y += dist*2;\r
-            else\r
-                y -= dist*2;\r
-        }\r
-        p.setLocation(x, y);\r
-        return p;\r
-    }\r
-\r
-    private static double distSq(double x1, double y1, double x2, double y2) {\r
-        double dx = x2 - x1;\r
-        double dy = y2 - y1;\r
-        return dx * dx + dy * dy;\r
-    }\r
-\r
-    private static double getScale(AffineTransform at)\r
-    {\r
-        double m00 = at.getScaleX();\r
-        double m11 = at.getScaleY();\r
-        double m10 = at.getShearY();\r
-        double m01 = at.getShearX();\r
-\r
-        return Math.sqrt(Math.abs(m00*m11 - m10*m01));\r
-    }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2011 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.scenegraph.g2d.nodes.connection;
+
+import java.awt.AlphaComposite;
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.simantics.diagram.connection.RouteGraph;
+import org.simantics.diagram.connection.RouteLineHalf;
+import org.simantics.diagram.connection.actions.IAction;
+import org.simantics.diagram.connection.rendering.IRouteGraphRenderer;
+import org.simantics.scenegraph.utils.Quality;
+import org.simantics.scenegraph.utils.QualityHints;
+
+/**
+ * @author Tuukka Lehtonen
+ */
+public class HighlightActionPointsAction implements IAction {
+
+    public static enum Action {
+        REMOVE,
+        RECONNECT
+    }
+
+    public static class Pick {
+        public static final Pick MISS = new Pick(null, null);
+
+        Action                   action;
+        RouteLineHalf            line;
+
+        public Pick(Action action, RouteLineHalf line) {
+            this.action = action;
+            this.line = line;
+        }
+
+        public boolean hasAction(Action action) {
+            return this.action == action;
+        }
+
+        public boolean hasResult() {
+            return action != null && line != null;
+        }
+
+        public boolean matches(Action action, RouteLineHalf line) {
+            if (this.action == null || this.line == null)
+                return false;
+            return this.action.equals(action) && this.line.equals(line);
+        }
+    }
+
+    private static final Shape          CROSS_SHAPE             = ActionShapes.CROSS_SHAPE;
+    private static final Shape          SCISSOR_SHAPE           = ActionShapes.transformShape(ActionShapes.SCISSOR_SHAPE, 1, 1, 0, 0, -Math.PI/2);
+
+    private static final Color          CROSS_COLOR             = new Color(0xe4, 0x40, 0x61);
+    private static final Color          SCISSOR_COLOR           = new Color(20, 20, 20);
+
+    public static final Stroke          STROKE                  = new BasicStroke(0.1f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
+    public static final AlphaComposite  NO_HIT_COMPOSITE        = AlphaComposite.SrcOver.derive(0.8f);
+    public static final AlphaComposite  HIT_COMPOSITE           = AlphaComposite.SrcOver.derive(0.2f);
+
+    public static final double          DEGENERATED_LINE_LENGTH = 1;
+    public static final double          CUT_DIST_FROM_END       = 0.75;
+
+    RouteGraph                          rg;
+
+    transient Collection<RouteLineHalf> lhs                     = new ArrayList<RouteLineHalf>();
+    transient AffineTransform           transform               = new AffineTransform();
+    transient Rectangle2D               rect                    = new Rectangle2D.Double();
+    transient Point2D                   point                   = new Point2D.Double();
+
+    public HighlightActionPointsAction(RouteGraph rg) {
+        this.rg = rg;
+    }
+
+    public void setRouteGraph(RouteGraph rg) {
+        this.rg = rg;
+    }
+
+    @Override
+    public void render(Graphics2D g, IRouteGraphRenderer renderer, double mouseX, double mouseY) {
+        // Cannot perform cut or delete segment actions
+        // on connections between 2 terminals.
+        boolean simpleConnection = (rg.isSimpleConnection() || rg.getTerminals().size() <= 2);
+        boolean branchedConnection = rg.getTerminals().size() > 2;
+        if (!branchedConnection || simpleConnection)
+            return;
+
+        AffineTransform preTr = g.getTransform();
+        double realViewScale = 1.0 / getScale(preTr);
+        //System.out.println(realViewScale);
+        // Don't render any of the actions if they could not be seen anyway.
+        if (realViewScale > 0.7)
+            return;
+
+        lhs.clear();
+        rg.getLineHalves(lhs);
+
+        Pick pick = pickAction(rg, lhs, preTr, mouseX, mouseY);
+
+        Composite originalComposite = g.getComposite();
+        Composite basicComposite = pick.action != null ? HIT_COMPOSITE : NO_HIT_COMPOSITE;
+        g.setComposite(basicComposite);
+
+        // Always render these in high quality because otherwise the shapes
+        // will render with ugly artifacts when zoom level is a bit higher.
+        QualityHints origQualityHints = QualityHints.getQuality(g);
+        QualityHints.getHints(Quality.HIGH).setQuality(g);
+
+        // Render line removal markers
+        if (!simpleConnection) {
+            g.setPaint(CROSS_COLOR);
+            for (RouteLineHalf lh : lhs) {
+                if (removeLocation(lh, point) == null)
+                    continue;
+                boolean hit = pick.matches(Action.REMOVE, lh);
+                if (hit)
+                    g.setComposite(originalComposite);
+                g.translate(point.getX(), point.getY());
+                g.fill(CROSS_SHAPE);
+                g.setTransform(preTr);
+                if (hit)
+                    g.setComposite(basicComposite);
+            }
+        }
+
+        // Render reconnection markers if the connection is branched.
+        if (branchedConnection) {
+            g.setPaint(SCISSOR_COLOR);
+            for (RouteLineHalf lh : lhs) {
+                if (reconnectLocation(lh, point) == null)
+                    continue;
+                boolean hit = pick.matches(Action.RECONNECT, lh);
+                if (hit)
+                    g.setComposite(originalComposite);
+                transform.setToTranslation(point.getX(), point.getY());
+                if (!lh.getLine().isHorizontal())
+                    transform.rotate(Math.PI/2);
+                transform.translate(0, 0.35);
+                g.transform(transform);
+                g.fill(SCISSOR_SHAPE);
+                g.setTransform(preTr);
+                if (hit)
+                    g.setComposite(basicComposite);
+            }
+        }
+
+        origQualityHints.setQuality(g);
+        g.setComposite(originalComposite);
+    }
+
+    public Pick pickAction(RouteGraph rg, AffineTransform viewTr, double mouseX, double mouseY) {
+        boolean branchedConnection = rg.getTerminals().size() > 2;
+        boolean simpleConnection = (rg.isSimpleConnection() || rg.getTerminals().size() <= 2);
+        if (!branchedConnection || simpleConnection)
+            return null;
+
+        lhs.clear();
+        return pickAction(rg, rg.getLineHalves(lhs), viewTr, mouseX, mouseY);
+    }
+
+    public Pick pickAction(RouteGraph rg, Collection<RouteLineHalf> lhs, AffineTransform viewTr, double mouseX, double mouseY) {
+        boolean branchedConnection = rg.getTerminals().size() > 2;
+        boolean simpleConnection = (rg.isSimpleConnection() || rg.getTerminals().size() <= 2);
+        if (!branchedConnection || simpleConnection || viewTr == null)
+            return Pick.MISS;
+
+        double viewScale = 1.0 / getScale(viewTr);
+        if (viewScale > 0.7)
+            return Pick.MISS;
+
+        double nearest = Double.MAX_VALUE;
+        RouteLineHalf selected = null;
+        Action selectedAction = null;
+
+        // Pick line removal markers
+        if (!simpleConnection) {
+            double s = ActionShapes.CROSS_WIDTH * 0.25;
+            for (RouteLineHalf lh : lhs) {
+                if (removeLocation(lh, point) == null)
+                    continue;
+                double x = point.getX();
+                double y = point.getY();
+                rect.setFrameFromCenter(x, y, x-s, y-s);
+                boolean hit = rect.contains(mouseX, mouseY);
+                if (hit) {
+                    double distSq = distSq(x, y, mouseX, mouseY);
+                    if (distSq < nearest) {
+                        nearest = distSq;
+                        selected = lh;
+                        selectedAction = Action.REMOVE;
+                    }
+                }
+            }
+        }
+
+        // Pick reconnection markers if the connection is branched.
+        if (branchedConnection) {
+            double w = ActionShapes.SCISSOR_HEIGHT * 0.4;
+            double h = ActionShapes.SCISSOR_WIDTH * 0.3;
+            for (RouteLineHalf lh : lhs) {
+                if (reconnectLocation(lh, point) == null)
+                    continue;
+                double x = point.getX();
+                double y = point.getY();
+                rect.setFrameFromCenter(x, y, x-w, y-h);
+                boolean hit = rect.contains(mouseX, mouseY);
+                if (hit) {
+                    double distSq = distSq(x, y, mouseX, mouseY);
+                    if (distSq < nearest) {
+                        nearest = distSq;
+                        selected = lh;
+                        selectedAction = Action.RECONNECT;
+                    }
+                }
+            }
+        }
+
+        return selected == null ? Pick.MISS : new Pick(selectedAction, selected);
+    }
+
+    private static Point2D removeLocation(RouteLineHalf lh, Point2D p) {
+        if (lh.getLine().getTerminal() == null)
+            return null;
+
+        double x = lh.getLink().getX();
+        double y = lh.getLink().getY();
+        if (lh.getLine().isHorizontal()) {
+            x = (lh.getLine().getBegin().getX() + lh.getLine().getEnd().getX()) * .5;
+        } else {
+            y = (lh.getLine().getBegin().getY() + lh.getLine().getEnd().getY()) * .5;
+        }
+        p.setLocation(x, y);
+        return p;
+    }
+
+    private static Point2D reconnectLocation(RouteLineHalf lh, Point2D p) {
+        if (lh.getLine().getLength() < DEGENERATED_LINE_LENGTH*3)
+            return null;
+
+        final double dist = CUT_DIST_FROM_END;
+        double x = lh.getLink().getX();
+        double y = lh.getLink().getY();
+        if (lh.getLine().isHorizontal()) {
+            if (lh.getLink() == lh.getLine().getBegin())
+                x += dist*2;
+            else
+                x -= dist*2;
+        } else {
+            if (lh.getLink() == lh.getLine().getBegin())
+                y += dist*2;
+            else
+                y -= dist*2;
+        }
+        p.setLocation(x, y);
+        return p;
+    }
+
+    private static double distSq(double x1, double y1, double x2, double y2) {
+        double dx = x2 - x1;
+        double dy = y2 - y1;
+        return dx * dx + dy * dy;
+    }
+
+    private static double getScale(AffineTransform at)
+    {
+        double m00 = at.getScaleX();
+        double m11 = at.getScaleY();
+        double m10 = at.getShearY();
+        double m01 = at.getShearX();
+
+        return Math.sqrt(Math.abs(m00*m11 - m10*m01));
+    }
+
+}