import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Comparator;
import java.util.List;
import org.simantics.db.Resource;
import org.simantics.district.network.ui.adapters.DistrictNetworkVertexElement;
import org.simantics.district.network.ui.nodes.DistrictNetworkVertexNode;
import org.simantics.district.network.ui.nodes.NetworkDrawingNode;
+import org.simantics.district.network.ui.participants.DNPickSorter;
import org.simantics.district.network.ui.participants.DynamicVisualisationContributionsParticipant;
import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;
import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;
/**
* Holds the current element for which hover information is shown.
- * This is just to optimize the
+ * This exists only to optimize the hover updating procedure.
*/
private IElement currentHoverElement;
PickRequest req = new PickRequest(getPickRect(canvasPos, viewTransform)).context(getContext());
List<IElement> pickables = new ArrayList<>();
pick.pick(diagram, req, pickables);
-
-
- Comparator<IElement> nearestVerticesFirst = (IElement e1, IElement e2) -> {
- // If there are any vertices in the elements, prefer those primarily.
- DistrictNetworkVertexNode v1 = e1.getHint(DistrictNetworkVertexElement.KEY_DN_VERTEX_NODE);
- DistrictNetworkVertexNode v2 = e2.getHint(DistrictNetworkVertexElement.KEY_DN_VERTEX_NODE);
-
- // Don't reorder edges
- if ((v1 == null && v2 == null))
- return 0;
-
- // Sort vertices in nearest first order
- if (v1 != null && v2 != null) {
- Rectangle2D b1 = v1.getBounds();
- Rectangle2D b2 = v2.getBounds();
- double dist1 = canvasPos.distanceSq(b1.getCenterX(), b1.getCenterY());
- double dist2 = canvasPos.distanceSq(b2.getCenterX(), b2.getCenterY());
- return dist1 < dist2 ? -1 : dist1 > dist2 ? 1 : 0;
- }
-
- // Always vertices before edges
- return v1 != null && v2 == null ? -1 : 1;
- };
- Collections.sort(pickables, nearestVerticesFirst);
+ Collections.sort(pickables, DNPickSorter.nearestVerticesFirst(false, DNPickSorter.centerDistSq(canvasPos.getX(), canvasPos.getY())));
updateHoveredElement(pickables, true, isConnectionTool, viewTransform);
// Will repaint once the async hover info calculation is ready, no need to do it here
--- /dev/null
+package org.simantics.district.network.ui.participants;
+
+import java.awt.geom.Rectangle2D;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.function.ToDoubleFunction;
+
+import org.simantics.district.network.ui.adapters.DistrictNetworkEdgeElement;
+import org.simantics.district.network.ui.adapters.DistrictNetworkVertexElement;
+import org.simantics.district.network.ui.nodes.DistrictNetworkVertexNode;
+import org.simantics.g2d.diagram.handler.PickRequest;
+import org.simantics.g2d.diagram.handler.PickRequest.PickSorter;
+import org.simantics.g2d.element.ElementHints;
+import org.simantics.g2d.element.IElement;
+import org.simantics.scenegraph.g2d.IG2DNode;
+import org.simantics.scenegraph.g2d.nodes.SingleElementNode;
+
+/**
+ * @author Jani Simomaa
+ * @author Tuukka Lehtonen
+ */
+public class DNPickSorter implements PickSorter {
+
+ public static ToDoubleFunction<Rectangle2D> centerDistSq(double x, double y) {
+ return r -> {
+ double dx = r.getCenterX() - x;
+ double dy = r.getCenterY() - y;
+ return dx * dx + dy * dy;
+ };
+ }
+
+ public static ToDoubleFunction<Rectangle2D> centerDistSq(Rectangle2D r1) {
+ return centerDistSq(r1.getCenterX(), r1.getCenterY());
+ }
+
+ /**
+ * @param nearestLast if <code>true</code> the nearest elements are sorted
+ * into the tail of the list, if <code>false</code>
+ * nearest elements are at the beginning of the list
+ * @param distanceFunction function used for calculating the distance of each
+ * element's bounding box
+ * @return comparator implementing the requested diagram element comparison
+ */
+ public static Comparator<IElement> nearestVerticesFirst(boolean nearestLast, ToDoubleFunction<Rectangle2D> distanceFunction) {
+ int sign = nearestLast ? 1 : -1;
+ return (IElement e1, IElement e2) -> {
+ // If there are any vertices in the elements, prefer those primarily.
+ DistrictNetworkVertexNode v1 = e1.getHint(DistrictNetworkVertexElement.KEY_DN_VERTEX_NODE);
+ DistrictNetworkVertexNode v2 = e2.getHint(DistrictNetworkVertexElement.KEY_DN_VERTEX_NODE);
+
+ // Don't reorder edges
+ if ((v1 == null && v2 == null))
+ return 0;
+
+ // Sort vertices in nearest first order
+ if (v1 != null && v2 != null) {
+ double dist1 = distanceFunction.applyAsDouble(v1.getBounds());
+ double dist2 = distanceFunction.applyAsDouble(v2.getBounds());
+ return dist1 < dist2 ? sign : dist1 > dist2 ? -sign : 0;
+ }
+
+ // Always vertices before edges
+ return v1 != null && v2 == null ? sign : -sign;
+ };
+ }
+
+ private static IG2DNode getNode(IElement element) {
+ IG2DNode node = element.getHint(DistrictNetworkEdgeElement.KEY_DN_EDGE_NODE);
+ if (node == null)
+ node = element.getHint(DistrictNetworkVertexElement.KEY_DN_VERTEX_NODE);
+ if (node == null) {
+ node = element.getHint(ElementHints.KEY_SG_NODE);
+ if (node instanceof SingleElementNode) {
+ SingleElementNode snode = (SingleElementNode) node;
+ node = snode.getNodes().iterator().next();
+ }
+ }
+ return node;
+ }
+
+ private static Comparator<IElement> zSorter() {
+ return (e1, e2) -> {
+ IG2DNode e1node = getNode(e1);
+ IG2DNode e2node = getNode(e2);
+ if (e1node.getZIndex() < e2node.getZIndex())
+ return -1;
+ else if (e1node.getZIndex() > e2node.getZIndex())
+ return 1;
+ return 0;
+ };
+ };
+
+ @Override
+ public void sort(List<IElement> elements) {
+ Collections.sort(elements, zSorter());
+ }
+
+ @Override
+ public void sort(PickRequest req, List<IElement> elements) {
+ Collections.sort(elements, zSorter());
+ Collections.sort(elements, nearestVerticesFirst( true, centerDistSq( req.pickArea.getBounds2D() ) ));
+ }
+
+}
\ No newline at end of file
package org.simantics.district.network.ui.participants;
import java.awt.geom.Point2D;
-import java.util.Collections;
-import java.util.List;
import java.util.Set;
-import org.simantics.district.network.ui.adapters.DistrictNetworkEdgeElement;
-import org.simantics.district.network.ui.adapters.DistrictNetworkVertexElement;
import org.simantics.g2d.canvas.ICanvasContext;
import org.simantics.g2d.canvas.ICanvasParticipant;
-import org.simantics.g2d.diagram.handler.PickRequest.PickSorter;
import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor;
import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil.TerminalInfo;
-import org.simantics.g2d.element.ElementHints;
import org.simantics.g2d.element.IElement;
-import org.simantics.scenegraph.g2d.IG2DNode;
import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;
-import org.simantics.scenegraph.g2d.events.KeyEvent.KeyReleasedEvent;
import org.simantics.scenegraph.g2d.events.KeyEvent;
-import org.simantics.scenegraph.g2d.nodes.SingleElementNode;
+import org.simantics.scenegraph.g2d.events.KeyEvent.KeyReleasedEvent;
public class DNPointerInteractor extends PointerInteractor {
private RoutingMode routingMode;
- private static class DNPickSorter implements PickSorter {
-
- @Override
- public void sort(List<IElement> elements) {
- Collections.sort(elements, (e1, e2) -> {
- IG2DNode e1node = getNode(e1);
- IG2DNode e2node = getNode(e2);
- if (e1node.getZIndex() < e2node.getZIndex())
- return -1;
- else if (e1node.getZIndex() > e2node.getZIndex())
- return 1;
- return 0;
- });
- }
-
- private static IG2DNode getNode(IElement element) {
- IG2DNode node = element.getHint(DistrictNetworkEdgeElement.KEY_DN_EDGE_NODE);
- if (node == null)
- node = element.getHint(DistrictNetworkVertexElement.KEY_DN_VERTEX_NODE);
- if (node == null) {
- node = element.getHint(ElementHints.KEY_SG_NODE);
- if (node instanceof SingleElementNode) {
- SingleElementNode snode = (SingleElementNode) node;
- node = snode.getNodes().iterator().next();
- }
- }
- return node;
- }
- }
-
public DNPointerInteractor() {
super(new DNPickSorter());
}
@Override
public double getPickDistance() {
- return 0.00001;
+ return 4;
}
}