X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.g2d%2Fsrc%2Forg%2Fsimantics%2Fg2d%2Fdiagram%2Fhandler%2FPickRequest.java;h=912e79cd9ce3e8caec89606ba61c495e797c0923;hp=265caa805b604210e12612d49b22a2126ada9c35;hb=72542227673047d71c3c3f281e478c1bea82eb81;hpb=28438fa467ae60dd63515be2df724c6ff9c299c9 diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/handler/PickRequest.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/handler/PickRequest.java index 265caa805..912e79cd9 100644 --- a/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/handler/PickRequest.java +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/handler/PickRequest.java @@ -14,12 +14,17 @@ package org.simantics.g2d.diagram.handler; import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.geom.Area; +import java.awt.geom.Line2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; +import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; +import org.simantics.diagram.connection.RouteLine; +import org.simantics.diagram.connection.RoutePoint; +import org.simantics.diagram.connection.segments.Segment; import org.simantics.g2d.canvas.ICanvasContext; import org.simantics.g2d.connection.handler.ConnectionHandler; import org.simantics.g2d.element.IElement; @@ -28,8 +33,11 @@ import org.simantics.g2d.element.handler.TerminalTopology; import org.simantics.g2d.element.handler.impl.ConnectionSelectionOutline; import org.simantics.g2d.elementclass.BranchPoint; import org.simantics.g2d.elementclass.MonitorHandler; +import org.simantics.g2d.elementclass.RouteGraphConnectionClass; import org.simantics.g2d.utils.GeometryUtils; +import org.simantics.scenegraph.g2d.nodes.connection.RouteGraphNode; import org.simantics.scenegraph.utils.TransformedRectangle; +import org.simantics.utils.datastructures.Pair; /** * @@ -172,6 +180,64 @@ public class PickRequest { }); } }; + + /* + * First use the default sorting if available, then sort successive connections by their distance to cursor. + */ + public static PickSorter connectionSorter(PickSorter sorter, double x, double y) { + return new PickSorter() { + + private double getDistanceSqToRouteGraphConnection(RouteGraphNode rgn, double x, double y) { + double minDistanceSq = Double.MAX_VALUE; + for (RouteLine line : rgn.getRouteGraph().getAllLines()) { + ArrayList segments = new ArrayList(); + line.collectSegments(segments); + for (Segment segment : segments) { + RoutePoint p1 = segment.p1; + RoutePoint p2 = segment.p2; + + double distanceSq = Line2D.ptSegDistSq(p1.getX(), p1.getY(), p2.getX(), p2.getY(), x, y); + if (distanceSq < minDistanceSq) { + minDistanceSq = distanceSq; + } + } + } + return minDistanceSq; + } + + @Override + public void sort(List elements) { + if (sorter != null) + sorter.sort(elements); + + List> connections = new ArrayList<>(elements.size()); + int tail = 0; + for (int i = 0; i < elements.size(); i++) { + IElement element = elements.get(i); + RouteGraphNode rgn = element.getHint(RouteGraphConnectionClass.KEY_RG_NODE); + if (rgn != null) { + double distanceSq = getDistanceSqToRouteGraphConnection(rgn, x, y); + connections.add(new Pair(distanceSq, element)); + } + + if (rgn == null || i == elements.size() - 1) { + Collections.sort(connections, new Comparator>() { + @Override + public int compare(Pair connection1, Pair connection2) { + return Double.compare(connection2.first, connection1.first); + } + }); + for (Pair connection : connections) { + elements.set(tail, connection.second); + tail++; + } + connections.clear(); + tail = i + 1; + } + } + } + }; + } } }