DN.ConnectionLineStyle : DIA.Style
DN.ElevationRectangleStyle : DIA.Style
-// Style for user component-specified text grid entries
-DN.DistrictNetworkHoverInfoStyle : DIA.Style
-
// Style for user component-specified static info text for network branches
DN.DistrictNetworkStaticInfoStyle : DIA.Style
<resource uri="http://www.simantics.org/DistrictNetwork-1.0/ConnectionLineStyle"
class="org.simantics.district.network.ui.styles.ConnectionLineStyle">
</resource>
- <resource uri="http://www.simantics.org/DistrictNetwork-1.0/DistrictNetworkHoverInfoStyle"
- class="org.simantics.district.network.ui.styles.DistrictNetworkHoverInfoStyle">
- <this />
- </resource>
<resource uri="http://www.simantics.org/DistrictNetwork-1.0/DistrictNetworkStaticInfoStyle"
class="org.simantics.district.network.ui.styles.DistrictNetworkStaticInfoStyle">
<this />
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.db.Resource;
import org.simantics.diagram.ui.DiagramModelHints;
import org.simantics.district.network.ui.adapters.DistrictNetworkEdgeElement;
import org.simantics.district.network.ui.adapters.DistrictNetworkVertexElement;
-import org.simantics.district.network.ui.nodes.DistrictNetworkEdgeNode;
import org.simantics.district.network.ui.nodes.DistrictNetworkVertexNode;
-import org.simantics.district.network.ui.nodes.HoverSensitiveNode;
import org.simantics.district.network.ui.nodes.NetworkDrawingNode;
import org.simantics.district.network.ui.participants.DynamicVisualisationContributionsParticipant;
import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;
import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant;
import org.simantics.g2d.element.ElementHints;
import org.simantics.g2d.element.IElement;
+import org.simantics.maps.MapScalingTransform;
+import org.simantics.scenegraph.INode;
import org.simantics.scenegraph.Node;
import org.simantics.scenegraph.g2d.G2DParentNode;
-import org.simantics.scenegraph.g2d.IG2DNode;
-import org.simantics.utils.datastructures.hints.IHintContext.Key;
-import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;
+import org.simantics.scenegraph.utils.GeometryUtils;
public class NetworkDrawingParticipant extends AbstractDiagramParticipant {
public static final String NETWORK_DRAWING_NODE = "networkDrawingNode";
- @Dependency
+ @Dependency
PickContext pick;
-
- /**
- * A hint key for terminal pick distance in control pixels.
- * @see #PICK_DIST
- */
- public static final Key KEY_PICK_DISTANCE = new KeyOf(Double.class, "PICK_DISTANCE");
- /**
- * Default terminal pick distance in control pixels.
- * @see #DEFAULT_PICK_DISTANCE
- */
- public static final double PICK_DIST = 10;
-
private NetworkDrawingNode node;
-
private DynamicVisualisationContributionsParticipant dynamicVisualisationContributionsParticipant;
private AffineTransform transform;
-
+
+ /**
+ * Holds the current element for which hover information is shown.
+ * This is just to optimize the
+ */
+ private IElement currentHoverElement;
+
public NetworkDrawingParticipant(DynamicVisualisationContributionsParticipant dynamicVisualisationContributionsParticipant, AffineTransform transform) {
this.dynamicVisualisationContributionsParticipant = dynamicVisualisationContributionsParticipant;
this.transform = transform;
node.setTransform(transform);
node.setNetworkDrawingParticipant(this);
}
-
+
@Override
protected void onDiagramSet(IDiagram newDiagram, IDiagram oldDiagram) {
node.setDiagram(newDiagram);
}
- public boolean pickHoveredElement(Point2D currentMousePos, boolean isConnectionTool) {
- PickRequest req = new PickRequest(new Rectangle2D.Double(currentMousePos.getX(), currentMousePos.getY(), 1e-8, 1e-8)).context(getContext());
+ public boolean pickHoveredElement(Point2D canvasPos, boolean isConnectionTool, AffineTransform viewTransform) {
+ 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;
+ };
- List<IElement> snap = diagram.getSnapshot();
+ Collections.sort(pickables, nearestVerticesFirst);
- hoverNodes2(pickables, true, isConnectionTool, currentMousePos);
- // we repaint ourselves once the async calulation is ready
+ updateHoveredElement(pickables, true, isConnectionTool, viewTransform);
+ // Will repaint once the async hover info calculation is ready, no need to do it here
return false;
-
-// boolean changed = false;
-// changed |= hoverNodes(snap, false, isConnectionTool, currentMousePos);
-// changed |= hoverNodes(pickables, true, isConnectionTool, currentMousePos);
- //return changed;
}
- private boolean hoverNodes2(List<IElement> elements, boolean hover, boolean isConnectionTool, Point2D p) {
+ private boolean updateHoveredElement(List<IElement> elements, boolean hover, boolean isConnectionTool, AffineTransform viewTransform) {
if (elements == null || elements.isEmpty()) {
+ currentHoverElement = null;
return dynamicVisualisationContributionsParticipant.doHover(false, isConnectionTool);
} else {
- boolean changed = dynamicVisualisationContributionsParticipant.doHover(true, isConnectionTool);
- if (changed) {
- // we prefer the first picked element only
- IElement elem = elements.get(0);
- G2DParentNode node = elem.getHint(DistrictNetworkVertexElement.KEY_DN_VERTEX_NODE);
- if (node instanceof DistrictNetworkVertexNode) {
- } else {
- node = elem.getHint(DistrictNetworkEdgeElement.KEY_DN_EDGE_NODE);
- }
- Resource mapElement = elem.getHint(ElementHints.KEY_OBJECT);
- Resource runtimeDiagram = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RUNTIME_RESOURCE);
- dynamicVisualisationContributionsParticipant.hoverNode(runtimeDiagram, mapElement, node);
- }
- return changed;
- }
- }
+ dynamicVisualisationContributionsParticipant.doHover(true, isConnectionTool);
- private boolean hoverNodes(List<IElement> elements, boolean hover, boolean isConnectionTool, Point2D p) {
- boolean changed = false;
- for (IElement elem : elements) {
- Node node = elem.getHint(DistrictNetworkVertexElement.KEY_DN_VERTEX_NODE);
- if (node instanceof DistrictNetworkVertexNode) {
- changed |= ((DistrictNetworkVertexNode) node).hover(hover, isConnectionTool);
- if (hover)
- ((DistrictNetworkVertexNode) node).setMousePosition(p);
- } else {
+ // we prefer the first picked element only
+ IElement elem = elements.get(0);
+ if (elem.equals(currentHoverElement))
+ return false;
+
+ INode node = elem.getHint(DistrictNetworkVertexElement.KEY_DN_VERTEX_NODE);
+ if (node == null)
node = elem.getHint(DistrictNetworkEdgeElement.KEY_DN_EDGE_NODE);
- if (node instanceof DistrictNetworkEdgeNode) {
- for (IG2DNode n : ((DistrictNetworkEdgeNode) node).getNodes()) {
- if (n instanceof HoverSensitiveNode) {
- changed |= ((HoverSensitiveNode)n).hover(hover, isConnectionTool);
- if (hover)
- ((HoverSensitiveNode)n).setMousePosition(p);
- }
- }
- }
- }
+ if (node == null)
+ return false;
+
+ Resource mapElement = elem.getHint(ElementHints.KEY_OBJECT);
+ Resource runtimeDiagram = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RUNTIME_RESOURCE);
+ currentHoverElement = elem;
+ dynamicVisualisationContributionsParticipant.hoverNode(runtimeDiagram, mapElement, node, MapScalingTransform.zoomLevel(viewTransform));
+ return true;
}
- return changed;
}
- public boolean isHoveringOverNode(Point2D currentMousePos) {
- PickRequest req = new PickRequest(currentMousePos).context(getContext());
- List<IElement> pickables = new ArrayList<IElement>();
+ public boolean isHoveringOverNode(Point2D canvasPos, AffineTransform viewTransform) {
+ PickRequest req = new PickRequest(getPickRect(canvasPos, viewTransform)).context(getContext());
+ List<IElement> pickables = new ArrayList<>();
pick.pick(diagram, req, pickables);
for (IElement elem : pickables) {
Node node = elem.getHint(DistrictNetworkVertexElement.KEY_DN_VERTEX_NODE);
return false;
}
+ private Rectangle2D getPickRect(Point2D canvasPos, AffineTransform viewTransform) {
+ double pixelScale = 1.0 / GeometryUtils.getScale(viewTransform);
+ if (Double.isInfinite(pixelScale))
+ pixelScale = 1e-8;
+
+ Rectangle2D pickRect = GeometryUtils.expandRectangle(
+ new Rectangle2D.Double(canvasPos.getX(), canvasPos.getY(), 0, 0),
+ pixelScale * 4);
+
+ return pickRect;
+ }
+
public AffineTransform getTransform() {
return transform;
}
+
}
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.ToIntFunction;
-import org.simantics.district.network.ui.styles.DistrictNetworkHoverInfoStyle;
import org.simantics.scenegraph.INode;
import org.simantics.scenegraph.NodeException;
import org.simantics.scenegraph.ParentNode;
import org.simantics.scenegraph.g2d.G2DNode;
-import org.simantics.scenegraph.g2d.G2DParentNode;
import org.simantics.scenegraph.g2d.nodes.spatial.RTreeNode;
import org.simantics.scenegraph.profile.common.ProfileVariables;
import org.simantics.scenegraph.utils.DPIUtil;
private static final long serialVersionUID = 1L;
+ private static final String HOVER_INFO_DEFERRED = "hoverInfo";
+
public static final String NODE_KEY = "DISTRICT_NETWORK_HOVER_INFO";
private static final int PAD = 15;
*/
private Rectangle2D bgRect = new Rectangle2D.Double();
- private static AtomicReference<G2DParentNode> activeNode = new AtomicReference<>();
+ private static AtomicReference<INode> activeNode = new AtomicReference<>();
@Override
public void render(Graphics2D g) {
ParentNode<?> root = (ParentNode<?>) NodeUtil.getNearestParentOfType(this, RTreeNode.class);
- DeferredRenderingNode deferred = root != null ? (DeferredRenderingNode) root.getNode(DistrictNetworkHoverInfoStyle.HOVER_INFO_DEFERRED) : null;
+ DeferredRenderingNode deferred = root != null ? (DeferredRenderingNode) root.getNode(HOVER_INFO_DEFERRED) : null;
if (deferred != null)
deferred.deferNode(g.getTransform(), this);
else
@Override
public boolean hover(boolean hover, boolean isConnectionTool) {
-// hover = hover && activeNode.updateAndGet(current -> current == null ? this : current) == this;
boolean changed = hover != this.hover;
this.hover = hover;
-
-// if (changed) {
-// if (!hover) activeNode.updateAndGet(current -> current == this ? null : current);
-// repaint();
-// }
-
return changed;
}
activeNode.set(null);
}
- public void hover2(G2DParentNode hoveredNode) {
+ public void setHoveredNode(INode hoveredNode) {
ParentNode<?> root = (ParentNode<?>) NodeUtil.getNearestParentOfType(parent, RTreeNode.class);
if (root != null) {
throw new NullPointerException("Scenegraph child node was not found: " + "");
}
- INode existing = NodeUtil.getChildById(child, DistrictNetworkHoverInfoStyle.HOVER_INFO_DEFERRED);
+ INode existing = NodeUtil.getChildById(child, HOVER_INFO_DEFERRED);
if (existing == null) {
if (child instanceof ParentNode<?>) {
- existing = ((ParentNode<?>) child).addNode(DistrictNetworkHoverInfoStyle.HOVER_INFO_DEFERRED, DeferredRenderingNode.class);
+ existing = ((ParentNode<?>) child).addNode(HOVER_INFO_DEFERRED, DeferredRenderingNode.class);
((DeferredRenderingNode)existing).setZIndex(Integer.MAX_VALUE);
} else {
throw new NodeException("Cannot claim child node for non-parent-node " + child);
import org.simantics.g2d.canvas.ICanvasContext;
import org.simantics.g2d.canvas.IToolMode;
import org.simantics.g2d.diagram.IDiagram;
-import org.simantics.maps.elevation.server.SingletonTiffTileInterface;
-import org.simantics.maps.elevation.server.prefs.MapsElevationServerPreferences;
import org.simantics.scenegraph.g2d.G2DNode;
import org.simantics.scenegraph.g2d.events.EventTypes;
import org.simantics.scenegraph.g2d.events.KeyEvent.KeyPressedEvent;
private static final Color RED_ALPHA = new Color(255, 0, 0, 100);
private boolean scaleStroke = true;
-
+ private AffineTransform lastViewTransform = new AffineTransform();
+
@Override
public void init() {
super.init();
@Override
public void render(Graphics2D g2d) {
+ // Must store this for hover info functionality
+ lastViewTransform = g2d.getTransform();
+
if (nodes.isEmpty())
return;
}
private boolean canStartEdge(Point2D currentPos) {
- return participant.isHoveringOverNode(currentPos);
+ return participant.isHoveringOverNode(currentPos, lastViewTransform);
}
private IToolMode getToolMode() {
Point2D p = NodeUtil.worldToLocal(this, e.controlPosition, new Point2D.Double());
boolean isConnectionTool = mode == Hints.CONNECTTOOL || e.hasAnyModifier(MouseEvent.ALT_MASK | MouseEvent.ALT_GRAPH_MASK);
// To boost pan perf hovering is only considered if no mouse button is pressed)
- if (e.buttons == 0 && participant.pickHoveredElement(p, isConnectionTool)) {
+ if (e.buttons == 0 && participant.pickHoveredElement(p, isConnectionTool, lastViewTransform)) {
repaint = true;
}
if (!nodes.isEmpty()) {
currentMousePos = p;
-
repaint();
return true;
}
repaint();
return super.mouseMoved(e);
}
-
+
@Override
protected boolean keyPressed(KeyPressedEvent e) {
if (e.keyCode == java.awt.event.KeyEvent.VK_ESCAPE) {
return true;
}
return super.keyPressed(e);
-
}
}
\ No newline at end of file
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledFuture;
import org.simantics.g2d.canvas.ICanvasContext;
import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant;
import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;
-import org.simantics.layer0.Layer0;
+import org.simantics.scenegraph.INode;
import org.simantics.scenegraph.g2d.G2DParentNode;
import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;
import org.simantics.scenegraph.g2d.events.command.CommandEvent;
}
}
};
-
+
private DynamicVisualisationContributionsNode node;
private AffineTransform transform;
-
private DistrictNetworkHoverInfoNode hoverInfoNode;
public DynamicVisualisationContributionsParticipant(AffineTransform tr) {
getHintStack().addKeyHintListener(getThread(), DistrictDiagramViewer.KEY_MAP_SIZING_OBJECTS, hintListener);
getHintStack().addKeyHintListener(getThread(), DistrictDiagramViewer.KEY_MAP_SIZE_BAR_OPTIONS, hintListener);
}
-
+
@Override
public void removedFromContext(ICanvasContext ctx) {
// Ensure hover polling is stopped
node.setTransform(transform);
node.setEnabled(true);
node.setZIndex(1000);
-
+
hoverInfoNode = parent.addNode("districtNetworkHoverInfoNode", DistrictNetworkHoverInfoNode.class);
hoverInfoNode.setLookupId("districtNetworkHoverInfoNode");
hoverInfoNode.setTransform(transform);
hoverInfoNode.setZIndex(Integer.MAX_VALUE - 500);
}
-
+
@EventHandler(priority = 0)
protected boolean handleKeyEvent(CommandEvent e) {
if (e.command.equals(DistrictDiagramViewer.MAP_COLOR_BAR_OPTIONS_CHANGE)) {
}
return false;
}
-
-// @Override
-// protected boolean handleCommand(CommandEvent e) {
-// if (e.command.equals(DistrictDiagramViewer.MAP_COLOR_BAR_OPTIONS_CHANGE)) {
-// ICanvasContext context = (ICanvasContext) e.getContext();
-// ColorBarOptions options = context.getHintStack().getHint(DistrictDiagramViewer.KEY_MAP_COLOR_BAR_OPTIONS);
-// this.colorBarsOptions = options;
-// repaint();
-// return true;
-// } else {
-// return super.handleCommand(e);
-// }
-// }
-
+
protected void updateNode() {
node.setDynamicColoringObjects(getDynamicColoringObjects());
node.setColorBarOptions(getColorBarOptions());
node.setSizeBarOptions(getSizeBarOptions());
}
- private Map<String,DynamicColorContribution> getDynamicColoringObjects() {
- Map<String,DynamicColorContribution> objects = getHint(DistrictDiagramViewer.KEY_MAP_COLORING_OBJECTS);
- return objects;
+ private Map<String, DynamicColorContribution> getDynamicColoringObjects() {
+ return getHint(DistrictDiagramViewer.KEY_MAP_COLORING_OBJECTS);
}
private ColorBarOptions getColorBarOptions() {
- ColorBarOptions options = getHint(DistrictDiagramViewer.KEY_MAP_COLOR_BAR_OPTIONS);
- return options;
+ return getHint(DistrictDiagramViewer.KEY_MAP_COLOR_BAR_OPTIONS);
}
private Map<String, DynamicSizeContribution> getDynamicSizingObjects() {
- Map<String, DynamicSizeContribution> objects = getHint(DistrictDiagramViewer.KEY_MAP_SIZING_OBJECTS);
- return objects;
+ return getHint(DistrictDiagramViewer.KEY_MAP_SIZING_OBJECTS);
}
private SizeBarOptions getSizeBarOptions() {
- SizeBarOptions options = getHint(DistrictDiagramViewer.KEY_MAP_SIZE_BAR_OPTIONS);
- return options;
+ return getHint(DistrictDiagramViewer.KEY_MAP_SIZE_BAR_OPTIONS);
}
private ScheduledFuture<?> hoverUpdateSchedule;
private static final Object COMPLETE = new Object();
-
- public void hoverNode(Resource runtimeDiagram, Resource mapElement, G2DParentNode hoveredNode) {
+
+ public void hoverNode(Resource runtimeDiagram, Resource mapElement, INode hoveredNode, int zoomLevel) {
IThreadWorkQueue thread = getThread();
Simantics.getSession().asyncRequest(new ReadRequest() {
-
@Override
public void run(ReadGraph graph) throws DatabaseException {
DynamicVisualisation visualisation = graph.syncRequest(new RuntimeDynamicVisualisationsRequest(runtimeDiagram));
if (visualisation == null)
return;
- if (hoverUpdateSchedule != null && !hoverUpdateSchedule.isDone()) {
- hoverUpdateSchedule.cancel(false);
- }
- hoverUpdateSchedule = ThreadUtils.getNonBlockingWorkExecutor().scheduleWithFixedDelay(() -> {
-
- CompletableFuture<Object> future = new CompletableFuture<>();
- try {
- Simantics.getSession().syncRequest(new ReadRequest() {
-
- @Override
- public void run(ReadGraph graph) throws DatabaseException {
- boolean keyVariablesVertexHover = visualisation.isKeyVariablesVertexHover();
- boolean keyVariablesEdgesHover = visualisation.isKeyVariablesEdgesHover();
-
- Resource mapElementInstanceOf = graph.getPossibleObject(mapElement, Layer0.getInstance(graph).InstanceOf);
- if (mapElementInstanceOf == null) {
- future.complete(COMPLETE);
- return;
- }
-
- DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
-
- boolean doHover = true;
- if (mapElementInstanceOf.equals(DN.Vertex) && !keyVariablesVertexHover) {
- doHover = false;
- } else if (mapElementInstanceOf.equals(DN.Edge) && !keyVariablesEdgesHover) {
- doHover = false;
- }
- final boolean finalDoHover = doHover;
-
- StyleResult results = DistrictNetworkHoverInfoStyle.doCalculateStyleResult(graph, runtimeDiagram, mapElement);
- if (results != null) {
- Point2D location = DistrictNetworkHoverInfoStyle.calculatePoint(graph, mapElement);
- thread.asyncExec(() -> {
- if (isRemoved())
- return;
- if (finalDoHover) {
- hoverInfoNode.setLabels(results.getLabels());
- hoverInfoNode.setOrigin(results.getOrigin());
-
- hoverInfoNode.setMousePosition(location);
- hoverInfoNode.hover2(hoveredNode);
- } else {
- hoverInfoNode.hover2(null);
- }
- future.complete(COMPLETE);
- });
- } else {
- future.complete(COMPLETE);
- }
+ cancelCurrentHoverUpdate();
+ hoverUpdateSchedule = ThreadUtils.getNonBlockingWorkExecutor().scheduleWithFixedDelay(
+ () -> updateHoverInfo(runtimeDiagram, mapElement, hoveredNode, zoomLevel, visualisation, thread),
+ 0,
+ visualisation.getInterval(),
+ TimeUnit.MILLISECONDS);
+ }
+ });
+ }
+
+ private void updateHoverInfo(Resource runtimeDiagram, Resource mapElement, INode hoveredNode, int zoomLevel, DynamicVisualisation visualisation, IThreadWorkQueue thread) {
+ CompletableFuture<Object> future = new CompletableFuture<>();
+ try {
+ Simantics.getSession().syncRequest(new ReadRequest() {
+ @Override
+ public void run(ReadGraph graph) throws DatabaseException {
+ Set<Resource> mapElementTypes = graph.getTypes(mapElement);
+ if (mapElementTypes.isEmpty()) {
+ future.complete(COMPLETE);
+ return;
+ }
+
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+
+ boolean doHover =
+ (mapElementTypes.contains(DN.Vertex) && visualisation.isKeyVariablesVertexHover())
+ || (mapElementTypes.contains(DN.Edge) && visualisation.isKeyVariablesEdgesHover());
+
+ StyleResult results = DistrictNetworkHoverInfoStyle.doCalculateStyleResult(graph, runtimeDiagram, mapElement);
+ if (results != null) {
+ Point2D location = DistrictNetworkHoverInfoStyle.calculatePoint(hoveredNode, zoomLevel);
+ thread.asyncExec(() -> {
+ if (isRemoved())
+ return;
+ if (doHover) {
+ hoverInfoNode.setLabels(results.getLabels());
+ hoverInfoNode.setOrigin(results.getOrigin());
+ hoverInfoNode.setMousePosition(location);
+ hoverInfoNode.setHoveredNode(hoveredNode);
+ } else {
+ hoverInfoNode.setHoveredNode(null);
}
+ future.complete(COMPLETE);
});
- } catch (DatabaseException e) {
- future.completeExceptionally(e);
- }
- // this waits until everything is done
- try {
- future.get();
- } catch (InterruptedException | ExecutionException e) {
- LOGGER.debug("Interrupted hovering", e);
+ } else {
+ future.complete(COMPLETE);
}
- }, 0, visualisation.getInterval(), TimeUnit.MILLISECONDS);
- }
- });
+ }
+ });
+ } catch (DatabaseException e) {
+ future.completeExceptionally(e);
+ }
+ // this waits until everything is done
+ try {
+ future.get();
+ } catch (InterruptedException | ExecutionException e) {
+ LOGGER.debug("Interrupted hovering", e);
+ }
}
public boolean doHover(boolean hover, boolean isConnectionTool) {
+ if (!hover)
+ cancelCurrentHoverUpdate();
return hoverInfoNode.hover(hover, isConnectionTool);
}
+
+ private void cancelCurrentHoverUpdate() {
+ if (hoverUpdateSchedule != null && !hoverUpdateSchedule.isDone())
+ hoverUpdateSchedule.cancel(false);
+ }
+
}
package org.simantics.district.network.ui.styles;
import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
import java.util.Collections;
import java.util.List;
import org.simantics.db.Resource;
import org.simantics.db.common.procedure.adapter.TransientCacheListener;
import org.simantics.db.common.request.ResourceRead;
+import org.simantics.db.common.utils.CommonDBUtils;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.exception.MissingVariableException;
import org.simantics.db.layer0.exception.MissingVariableValueException;
import org.simantics.db.layer0.exception.PendingVariableException;
-import org.simantics.db.layer0.util.Layer0Utils;
import org.simantics.db.layer0.variable.Variable;
import org.simantics.db.layer0.variable.Variables;
-import org.simantics.diagram.profile.StyleBase;
import org.simantics.diagram.stubs.DiagramResource;
import org.simantics.district.network.DistrictNetworkUtil;
import org.simantics.district.network.ontology.DistrictNetworkResource;
-import org.simantics.district.network.ui.nodes.DeferredRenderingNode;
-import org.simantics.district.network.ui.nodes.DistrictNetworkHoverInfoNode;
+import org.simantics.district.network.ui.nodes.DistrictNetworkEdgeNode;
import org.simantics.district.network.ui.nodes.DistrictNetworkNodeUtils;
+import org.simantics.district.network.ui.nodes.DistrictNetworkVertexNode;
import org.simantics.layer0.Layer0;
-import org.simantics.modeling.ModelingResources;
import org.simantics.scenegraph.INode;
-import org.simantics.scenegraph.ParentNode;
-import org.simantics.scenegraph.g2d.nodes.spatial.RTreeNode;
-import org.simantics.scenegraph.profile.EvaluationContext;
-import org.simantics.scenegraph.profile.common.ProfileVariables;
-import org.simantics.scenegraph.utils.NodeUtil;
import org.simantics.scl.compiler.top.ValueNotFound;
import org.simantics.scl.osgi.SCLOsgi;
import org.simantics.scl.runtime.SCLContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class DistrictNetworkHoverInfoStyle extends StyleBase<DistrictNetworkHoverInfoStyle.StyleResult> {
-
- public static final String HOVER_INFO_DEFERRED = "hoverInfo";
-
- private static final Logger LOGGER = LoggerFactory.getLogger(DistrictNetworkHoverInfoStyle.class);
-
- private static final String ACTIONS_MODULE = "Actions";
- private static final String HOVER_CONTRIBUTION = "hoverContribution";
-
- public static class StyleResult {
- Point2D origin;
- List<Tuple3> labels;
-
- public StyleResult(Point2D origin, List<Tuple3> labels) {
- this.origin = origin;
- this.labels = labels;
- }
-
- public Point2D getOrigin() {
- return origin;
- }
-
- public List<Tuple3> getLabels() {
- return labels;
- }
- }
-
- public DistrictNetworkHoverInfoStyle(Resource style) throws DatabaseException {
- super(style);
- }
-
- String currentRowKey;
-
- protected Resource getConfigurationComponent(ReadGraph graph, Resource element) throws DatabaseException {
- ModelingResources MOD = ModelingResources.getInstance(graph);
- DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
-
- Resource mappedElement = graph.getPossibleObject(element, DN.MappedComponent);
- return mappedElement != null ? graph.getPossibleObject(mappedElement, MOD.ElementToComponent) : null;
- }
-
- @Override
- public StyleResult calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource mapElement,
- Variable configuration) throws DatabaseException {
- //return doCalculateStyleResult(graph, runtimeDiagram, mapElement);
- return new StyleResult(calculatePoint(graph, mapElement), Collections.emptyList());
+public class DistrictNetworkHoverInfoStyle {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DistrictNetworkHoverInfoStyle.class);
+
+ private static final String ACTIONS_MODULE = "Actions";
+ private static final String HOVER_CONTRIBUTION = "hoverContribution";
+
+ public static class StyleResult {
+ Point2D origin;
+ List<Tuple3> labels;
+
+ public StyleResult(Point2D origin, List<Tuple3> labels) {
+ this.origin = origin;
+ this.labels = labels;
+ }
+
+ public Point2D getOrigin() {
+ return origin;
+ }
+
+ public List<Tuple3> getLabels() {
+ return labels;
+ }
}
public static StyleResult doCalculateStyleResult(ReadGraph graph, Resource runtimeDiagram, Resource mapElement) throws DatabaseException {
return new StyleResult(point, result);
}
-
+
public static Point2D calculatePoint(ReadGraph graph, Resource mapElement) throws DatabaseException {
Point2D point;
DiagramResource DIA = DiagramResource.getInstance(graph);
return point;
}
- @Override
- public void applyStyleForNode(EvaluationContext observer, INode parent, StyleResult results) {
-// if (results == null) {
-// cleanupStyleForNode(observer, parent);
-// return;
-// }
-//
-// DistrictNetworkHoverInfoNode node = ProfileVariables.claimChild(parent, "*", DistrictNetworkHoverInfoNode.NODE_KEY, DistrictNetworkHoverInfoNode.class, observer);
-// if (node == null)
-// return;
-//
-// ParentNode<?> root = (ParentNode<?>) NodeUtil.getNearestParentOfType(parent, RTreeNode.class);
-// if (root != null) {
-// DeferredRenderingNode deferred = ProfileVariables.claimChild(root, "", HOVER_INFO_DEFERRED, DeferredRenderingNode.class, observer);
-// deferred.setZIndex(Integer.MAX_VALUE);
-// }
-//
-// node.setLabels(results.getLabels());
-// node.setOrigin(results.getOrigin());
- }
-
- @Override
- protected void cleanupStyleForNode(EvaluationContext observer, INode node) {
- ProfileVariables.denyChild(node, "*", DistrictNetworkHoverInfoNode.NODE_KEY);
- }
-
- private static Function1<Variable, List<Tuple3>> getUCTextGridFunctionCached(ReadGraph graph, Resource componentType)
- throws DatabaseException {
- return graph.syncRequest(new UCTextGridFunctionRequest(componentType), TransientCacheListener.instance());
- }
-
- private static final class UCTextGridFunctionRequest extends ResourceRead<Function1<Variable, List<Tuple3>>> {
- public UCTextGridFunctionRequest(Resource resource) {
- super(resource);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Function1<Variable, List<Tuple3>> perform(ReadGraph graph) throws DatabaseException {
- Resource actionsModule = Layer0Utils.getPossibleChild(graph, resource, ACTIONS_MODULE);
- if (actionsModule == null || !graph.isInstanceOf(actionsModule, Layer0.getInstance(graph).SCLModule))
- return null;
-
- String uri = graph.getURI(actionsModule);
- SCLContext sclContext = SCLContext.getCurrent();
- Object oldGraph = sclContext.get("graph");
- try {
- sclContext.put("graph", graph);
- return (Function1<Variable, List<Tuple3>>) SCLOsgi.MODULE_REPOSITORY.getValue(uri, HOVER_CONTRIBUTION);
- } catch (ValueNotFound e1) {
- return null;
- } finally {
- sclContext.put("graph", oldGraph);
- }
- }
- }
+ public static Point2D calculatePoint(INode node, int zoomLevel) {
+ if (node instanceof DistrictNetworkVertexNode) {
+ DistrictNetworkVertexNode vertex = (DistrictNetworkVertexNode) node;
+ Rectangle2D b = vertex.getBounds();
+ return new Point2D.Double(b.getCenterX(), b.getCenterY());
+ } else if (node instanceof DistrictNetworkEdgeNode) {
+ DistrictNetworkEdgeNode edge = (DistrictNetworkEdgeNode) node;
+ return (Point2D) edge.getCenterPoint(zoomLevel).clone();
+ }
+ return null;
+ }
+
+ private static Function1<Variable, List<Tuple3>> getUCTextGridFunctionCached(ReadGraph graph, Resource componentType)
+ throws DatabaseException {
+ return graph.syncRequest(new UCTextGridFunctionRequest(componentType), TransientCacheListener.instance());
+ }
+
+ private static final class UCTextGridFunctionRequest extends ResourceRead<Function1<Variable, List<Tuple3>>> {
+ public UCTextGridFunctionRequest(Resource resource) {
+ super(resource);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Function1<Variable, List<Tuple3>> perform(ReadGraph graph) throws DatabaseException {
+ Resource actionsModule = CommonDBUtils.getPossibleChild(graph, resource, ACTIONS_MODULE);
+ if (actionsModule == null || !graph.isInstanceOf(actionsModule, Layer0.getInstance(graph).SCLModule))
+ return null;
+
+ String uri = graph.getURI(actionsModule);
+ SCLContext sclContext = SCLContext.getCurrent();
+ Object oldGraph = sclContext.get("graph");
+ try {
+ sclContext.put("graph", graph);
+ return (Function1<Variable, List<Tuple3>>) SCLOsgi.MODULE_REPOSITORY.getValue(uri, HOVER_CONTRIBUTION);
+ } catch (ValueNotFound e1) {
+ return null;
+ } finally {
+ sclContext.put("graph", oldGraph);
+ }
+ }
+ }
+
}