]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
* Fix: only one dependency is dragged at a time (refs #753)
authormiettinen <miettinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Wed, 5 Sep 2012 06:08:28 +0000 (06:08 +0000)
committermiettinen <miettinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Wed, 5 Sep 2012 06:08:28 +0000 (06:08 +0000)
* If multiple dependencies are within the range, the preference is 1) selected dependency 2) the nearest dependency
* Changed the hitTest function tolerance to distance instead of the distance squared

git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@25644 ac1ea38d-2e2b-0410-8846-a27921b304fc

org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/Arcs.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyEdgeClass.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyNode.java

index 51d4240f30a946a3617dc66622af80198538bbbe..d22b298e6fb4432b589d457ab7cf16a0a11d83ca 100644 (file)
@@ -192,14 +192,15 @@ public class Arcs {
         double dy = y-cy;\r
         double dist = dx*dx + dy*dy;\r
         \r
-//        System.out.println("HitTest: x0=" + x0 + " y0=" + y0 + " y=" + y + " x=" + x + " dist=" + dist + " r2=" + r*r);\r
+        //System.out.println("HitTest: x0=" + x0 + " y0=" + y0 + " y=" + y + " x=" + x + " dist=" + dist + " r2=" + r*r);\r
         \r
-        if(dist < (r+tolerance)*(r+tolerance) &&\r
-            dist > (r-tolerance)*(r-tolerance)) {\r
+        double tolerance2 = tolerance * tolerance;\r
+        if(dist < (r+tolerance2)*(r+tolerance2) &&\r
+            dist > (r-tolerance2)*(r-tolerance2)) {\r
             double ang = Arcs.normalizeAngle(Math.atan2(-dy, dx));\r
-//             System.out.println("test " + angle0 + " " + ang + " " + angle1);\r
+               //System.out.println("test " + angle0 + " " + ang + " " + angle1);\r
             if(Arcs.areClockwiseOrdered(angle0, ang, angle1) == clockWise) {\r
-//             System.out.println("hit");\r
+               //System.out.println("hit");\r
                 return true;\r
             }\r
         }\r
@@ -207,5 +208,54 @@ public class Arcs {
         return false;\r
         \r
        }\r
+\r
+       /**\r
+        * Calculates the radial distance between an arc and a point\r
+        * @param beginBounds Begin coordinate of the arc\r
+        * @param endBounds End coordinate of the arc\r
+        * @param angle The central angle of the arc\r
+        * @param x x coordinate of the measured point\r
+        * @param y x coordinate of the measured point \r
+        * @return The radial distance between the the arc and (x,y); Double.NaN if the\r
+        *  distance is not real.\r
+        */\r
+       public static double getRadialDistance(Rectangle2D beginBounds,\r
+                       Rectangle2D endBounds, double angle, double x, double y) {\r
+\r
+               boolean clockWise = angle > 0;\r
+               \r
+               double x0 = beginBounds.getCenterX();\r
+        double y0 = beginBounds.getCenterY();\r
+        double x1 = endBounds.getCenterX();\r
+        double y1 = endBounds.getCenterY();\r
+        \r
+        double offset = \r
+            Math.abs(angle) < 1.0e-6\r
+            ? 1e3 * Math.signum(angle)\r
+            : Math.tan(Math.PI*0.5-angle)*0.5;\r
+        double cx = 0.5*(x0+x1) + offset * (y1-y0);\r
+        double cy = 0.5*(y0+y1) + offset * (x0-x1);\r
+        double dx0 = x0 - cx;\r
+        double dy0 = y0 - cy;\r
+        double dx1 = x1 - cx;\r
+        double dy1 = y1 - cy;\r
+        double r = Math.sqrt(dx0*dx0 + dy0*dy0);\r
+        double angle0 = Arcs.nextIntersectingAngle(cx, cy, r, \r
+            Math.atan2(-dy0, dx0), beginBounds, angle < 0.0);\r
+        double angle1 = Arcs.nextIntersectingAngle(cx, cy, r, \r
+            Math.atan2(-dy1, dx1), endBounds, angle > 0.0);\r
+        \r
+        double dx = x-cx;\r
+        double dy = y-cy;\r
+        double dist2 = dx*dx + dy*dy;\r
+               \r
+           double ang = Arcs.normalizeAngle(Math.atan2(-dy, dx));\r
+               if(!Arcs.areClockwiseOrdered(angle0, ang, angle1) == clockWise) {\r
+               return Double.NaN;\r
+           }\r
+               double radialDistance = Math.abs(Math.sqrt(dist2) - r);\r
+               System.out.println("radialDistance " + radialDistance);\r
+           return radialDistance;\r
+       }\r
     \r
 }\r
index 64d9863165ad6655e7fafc70a507f4e1ddef21d6..7f39198a8087033996fb69180fd04fbbf91fb0e7 100644 (file)
@@ -82,7 +82,7 @@ public class DependencyEdgeClass {
                System.out.println("pickTest no node!");\r
                return false;\r
             }\r
-            return Arcs.hitTest(node.getBeginBounds(), node.getEndBounds(), node.getAngle(), pickRect.getCenterX(), pickRect.getCenterY(), 3.0);\r
+            return Arcs.hitTest(node.getBeginBounds(), node.getEndBounds(), node.getAngle(), pickRect.getCenterX(), pickRect.getCenterY(), 1.7);\r
             \r
            }\r
 \r
index 3c00d95db3e9a35929a09ad3ea4d5f90239c1cba..d98d89fb78b2fecc088ead0facfee799d20fe45e 100644 (file)
@@ -22,15 +22,19 @@ import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;\r
 import java.beans.PropertyChangeEvent;\r
 import java.beans.PropertyChangeListener;\r
+import java.util.Collection;\r
 \r
 import org.simantics.diagram.elements.TextNode;\r
 import org.simantics.g2d.utils.Alignment;\r
 import org.simantics.scenegraph.ISelectionPainterNode;\r
+import org.simantics.scenegraph.g2d.IG2DNode;\r
 import org.simantics.scenegraph.g2d.events.EventTypes;\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.MouseDragBegin;\r
 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;\r
+import org.simantics.scenegraph.g2d.nodes.ConnectionNode;\r
+import org.simantics.scenegraph.g2d.nodes.SingleElementNode;\r
 import org.simantics.scenegraph.utils.NodeUtil;\r
 import org.simantics.sysdyn.ui.editor.routing.DependencyRouter;\r
 import org.simantics.utils.datastructures.Pair;\r
@@ -45,6 +49,8 @@ public class DependencyNode extends TextNode implements ISelectionPainterNode {
     public static final String INSIDE = "Inside";\r
     public static final String OUTSIDE = "Outside";\r
 \r
+    public static final double HITMARGIN = 1.7;\r
+    \r
     private static final long serialVersionUID = 1294351381209071074L;\r
 \r
     private static final BasicStroke STROKE = new BasicStroke(1.0f);\r
@@ -235,6 +241,12 @@ public class DependencyNode extends TextNode implements ISelectionPainterNode {
         Point2D localPos = NodeUtil.worldToLocal(this, event.controlPosition, new Point2D.Double());\r
         return Arcs.hitTest(beginBounds, endBounds, angle, localPos.getX(), localPos.getY(), tolerance);\r
     }\r
+    \r
+    protected double getRadialDistanse(Point2D coord) {\r
+       if(beginBounds == null || endBounds == null) return Double.NaN;\r
+        Point2D localPos = NodeUtil.worldToLocal(this, coord, new Point2D.Double());\r
+        return Arcs.getRadialDistance(beginBounds, endBounds, angle, localPos.getX(), localPos.getY());\r
+    }\r
 \r
     @Override\r
     public Rectangle2D getBoundsInLocal() {\r
@@ -251,7 +263,7 @@ public class DependencyNode extends TextNode implements ISelectionPainterNode {
     \r
     @Override\r
     protected boolean mouseMoved(MouseMovedEvent event) {\r
-        boolean hit = hitTest(event, 3.0);\r
+        boolean hit = hitTest(event, HITMARGIN);\r
         if(dragging) {\r
             Point2D localPos = NodeUtil.worldToLocal(this, event.controlPosition, new Point2D.Double());\r
             \r
@@ -269,14 +281,65 @@ public class DependencyNode extends TextNode implements ISelectionPainterNode {
         return false;\r
     }\r
 \r
+    private static boolean isEventDummy(MouseDragBegin e) {\r
+       if (e.controlPosition.distance(0, 0) == 0 \r
+                       && e.screenPosition.distance(0, 0) == 0\r
+                       && e.buttons == 0) {\r
+               return true;\r
+       } else {\r
+               return false;\r
+       }\r
+    }\r
+    \r
     @Override\r
     protected boolean mouseDragged(MouseDragBegin e) {\r
-        if(!dragging && hitTest(e, 3.0)) {\r
-            dragging = true;\r
-            return true; // consume event\r
-        } else {\r
-            return false;\r
-        }\r
+       // Get rid of dummy events from dragGestureRecognized\r
+       if (isEventDummy(e)) {\r
+               return false;\r
+       }\r
+       //System.out.println(this.toString() + " event: " + e.toString());\r
+       boolean selected = NodeUtil.isSelected(this, 2);\r
+       double myRadialDistance = this.getRadialDistanse(e.controlPosition);\r
+       Collection<?> nodes = this.getParent().getParent().getParent().getNodes();\r
+       if (!selected) {\r
+               for (Object temp1 : nodes) {\r
+                       if (temp1 instanceof ConnectionNode) {\r
+                               for ( IG2DNode temp2 : ((ConnectionNode)temp1).getNodes()) {\r
+                                       if (temp2 instanceof SingleElementNode) {\r
+                                               for ( IG2DNode temp3 : ((SingleElementNode)temp2).getNodes()) {\r
+                                                       if (temp3 instanceof DependencyNode){\r
+                                                               DependencyNode otherDependencyNode = (DependencyNode)temp3;\r
+                                                               System.out.println(otherDependencyNode.toString());\r
+                                                               if (otherDependencyNode == this) {\r
+                                                                       System.out.println("We have this!");\r
+                                                                       continue;\r
+                                                               }\r
+                                                               double otherNodeDist = otherDependencyNode.getRadialDistanse(e.controlPosition);\r
+                                                               if (Double.isNaN(otherNodeDist)) {\r
+                                                                       System.out.println("We have NaN!");\r
+                                                                       continue;\r
+                                                               }\r
+                                                       if (otherDependencyNode.isDragging()) {\r
+                                                                       return true;\r
+                                                               } \r
+                                                               if (NodeUtil.isSelected(otherDependencyNode, 2) && (otherNodeDist < HITMARGIN)) {\r
+                                                                       return false;\r
+                                                               } \r
+                                                               if (otherNodeDist < myRadialDistance) {\r
+                                                                       return false;\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+               if ( (myRadialDistance < HITMARGIN) && !dragging) {\r
+               dragging = true;\r
+                       return true;\r
+               }\r
+        return false;\r
     }\r
 \r
     @Override\r
@@ -291,4 +354,8 @@ public class DependencyNode extends TextNode implements ISelectionPainterNode {
         }\r
         return false;\r
     }\r
+    \r
+    protected boolean isDragging() {\r
+       return dragging;\r
+    }\r
 }\r