2 package org.simantics.district.network.ui;
4 import java.awt.geom.AffineTransform;
5 import java.awt.geom.Point2D;
6 import java.awt.geom.Rectangle2D;
7 import java.util.ArrayList;
8 import java.util.Collections;
11 import org.simantics.db.Resource;
12 import org.simantics.diagram.ui.DiagramModelHints;
13 import org.simantics.district.network.ui.adapters.DistrictNetworkEdgeElement;
14 import org.simantics.district.network.ui.adapters.DistrictNetworkVertexElement;
15 import org.simantics.district.network.ui.nodes.DistrictNetworkVertexNode;
16 import org.simantics.district.network.ui.nodes.NetworkDrawingNode;
17 import org.simantics.district.network.ui.participants.DNPickSorter;
18 import org.simantics.district.network.ui.participants.DynamicVisualisationContributionsParticipant;
19 import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;
20 import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;
21 import org.simantics.g2d.diagram.IDiagram;
22 import org.simantics.g2d.diagram.handler.PickContext;
23 import org.simantics.g2d.diagram.handler.PickRequest;
24 import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant;
25 import org.simantics.g2d.element.ElementHints;
26 import org.simantics.g2d.element.IElement;
27 import org.simantics.maps.MapScalingTransform;
28 import org.simantics.scenegraph.INode;
29 import org.simantics.scenegraph.Node;
30 import org.simantics.scenegraph.g2d.G2DParentNode;
31 import org.simantics.scenegraph.utils.GeometryUtils;
33 public class NetworkDrawingParticipant extends AbstractDiagramParticipant {
35 public static final String NETWORK_DRAWING_NODE = "networkDrawingNode";
40 private NetworkDrawingNode node;
41 private DynamicVisualisationContributionsParticipant dynamicVisualisationContributionsParticipant;
42 private AffineTransform transform;
45 * Holds the current element for which hover information is shown.
46 * This exists only to optimize the hover updating procedure.
48 private IElement currentHoverElement;
50 public NetworkDrawingParticipant(DynamicVisualisationContributionsParticipant dynamicVisualisationContributionsParticipant, AffineTransform transform) {
51 this.dynamicVisualisationContributionsParticipant = dynamicVisualisationContributionsParticipant;
52 this.transform = transform;
56 public void initSG(G2DParentNode parent) {
57 node = parent.addNode(NETWORK_DRAWING_NODE, NetworkDrawingNode.class);
58 node.setTransform(transform);
59 node.setNetworkDrawingParticipant(this);
63 protected void onDiagramSet(IDiagram newDiagram, IDiagram oldDiagram) {
64 node.setDiagram(newDiagram);
67 public boolean pickHoveredElement(Point2D canvasPos, boolean isConnectionTool, AffineTransform viewTransform) {
68 PickRequest req = new PickRequest(getPickRect(canvasPos, viewTransform)).context(getContext());
69 List<IElement> pickables = new ArrayList<>();
70 pick.pick(diagram, req, pickables);
72 Collections.sort(pickables, DNPickSorter.nearestVerticesFirst(false, DNPickSorter.centerDistSq(canvasPos.getX(), canvasPos.getY())));
74 updateHoveredElement(pickables, true, isConnectionTool, viewTransform);
75 // Will repaint once the async hover info calculation is ready, no need to do it here
79 private boolean updateHoveredElement(List<IElement> elements, boolean hover, boolean isConnectionTool, AffineTransform viewTransform) {
80 if (elements == null || elements.isEmpty()) {
81 currentHoverElement = null;
82 return dynamicVisualisationContributionsParticipant.doHover(false, isConnectionTool);
84 dynamicVisualisationContributionsParticipant.doHover(true, isConnectionTool);
86 // we prefer the first picked element only
87 IElement elem = elements.get(0);
88 if (elem.equals(currentHoverElement))
91 INode node = elem.getHint(DistrictNetworkVertexElement.KEY_DN_VERTEX_NODE);
93 node = elem.getHint(DistrictNetworkEdgeElement.KEY_DN_EDGE_NODE);
97 Resource mapElement = elem.getHint(ElementHints.KEY_OBJECT);
98 Resource runtimeDiagram = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RUNTIME_RESOURCE);
99 currentHoverElement = elem;
100 dynamicVisualisationContributionsParticipant.hoverNode(runtimeDiagram, mapElement, node, MapScalingTransform.zoomLevel(viewTransform));
105 public boolean isHoveringOverNode(Point2D canvasPos, AffineTransform viewTransform) {
106 PickRequest req = new PickRequest(getPickRect(canvasPos, viewTransform)).context(getContext());
107 List<IElement> pickables = new ArrayList<>();
108 pick.pick(diagram, req, pickables);
109 for (IElement elem : pickables) {
110 Node node = elem.getHint(DistrictNetworkVertexElement.KEY_DN_VERTEX_NODE);
111 if (node instanceof DistrictNetworkVertexNode) {
118 private Rectangle2D getPickRect(Point2D canvasPos, AffineTransform viewTransform) {
119 double pixelScale = 1.0 / GeometryUtils.getScale(viewTransform);
120 if (Double.isInfinite(pixelScale))
123 Rectangle2D pickRect = GeometryUtils.expandRectangle(
124 new Rectangle2D.Double(canvasPos.getX(), canvasPos.getY(), 0, 0),
130 public AffineTransform getTransform() {