package org.simantics.district.network.ui.participants;
import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.request.ReadRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
+import org.simantics.district.network.profile.RuntimeDynamicVisualisationsRequest;
import org.simantics.district.network.ui.DistrictDiagramViewer;
+import org.simantics.district.network.ui.nodes.DistrictNetworkHoverInfoNode;
import org.simantics.district.network.ui.nodes.DynamicVisualisationContributionsNode;
+import org.simantics.district.network.ui.styles.DistrictNetworkHoverInfoStyle;
+import org.simantics.district.network.ui.styles.DistrictNetworkHoverInfoStyle.StyleResult;
import org.simantics.district.network.visualisations.model.ColorBarOptions;
import org.simantics.district.network.visualisations.model.DynamicColorContribution;
import org.simantics.district.network.visualisations.model.DynamicSizeContribution;
+import org.simantics.district.network.visualisations.model.DynamicVisualisation;
import org.simantics.district.network.visualisations.model.SizeBarOptions;
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.g2d.G2DParentNode;
import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;
import org.simantics.scenegraph.g2d.events.command.CommandEvent;
import org.simantics.utils.datastructures.hints.IHintContext.Key;
import org.simantics.utils.datastructures.hints.IHintListener;
import org.simantics.utils.datastructures.hints.IHintObservable;
+import org.simantics.utils.threads.IThreadWorkQueue;
+import org.simantics.utils.threads.ThreadUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class DynamicVisualisationContributionsParticipant extends AbstractCanvasParticipant {
+ private static final Logger LOGGER = LoggerFactory.getLogger(DynamicVisualisationContributionsParticipant.class);
+
IHintListener hintListener = new HintListenerAdapter() {
public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {
ICanvasContext cc = getContext();
private DynamicVisualisationContributionsNode node;
private AffineTransform transform;
-
+
+ private DistrictNetworkHoverInfoNode hoverInfoNode;
+
public DynamicVisualisationContributionsParticipant(AffineTransform tr) {
this.transform = tr;
}
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)
SizeBarOptions options = getHint(DistrictDiagramViewer.KEY_MAP_SIZE_BAR_OPTIONS);
return options;
}
+
+ private ScheduledFuture<?> hoverUpdateSchedule;
+
+ public void hoverNode(Resource runtimeDiagram, Resource mapElement, G2DParentNode hoveredNode) {
+ 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.getSingleObject(mapElement, Layer0.getInstance(graph).InstanceOf);
+ 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(new Object());
+ });
+ } else {
+ future.complete(new Object());
+ }
+ }
+ });
+ } catch (DatabaseException e) {
+ future.completeExceptionally(e);
+ }
+ // this waits until everything is done
+ try {
+ future.get();
+ } catch (InterruptedException | ExecutionException e) {
+ LOGGER.debug("Interrupted hovering", e);
+ }
+ }, 0, visualisation.getInterval(), TimeUnit.MILLISECONDS);
+ }
+ });
+ }
+
+ public boolean doHover(boolean hover, boolean isConnectionTool) {
+ return hoverInfoNode.hover(hover, isConnectionTool);
+ }
}