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
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
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
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
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
\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
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
}\r
return false;\r
}\r
+ \r
+ protected boolean isDragging() {\r
+ return dragging;\r
+ }\r
}\r