--- /dev/null
+package org.simantics.district.network.ui.nodes;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.geom.Line2D;
+import java.awt.geom.Path2D;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+import org.simantics.district.network.ui.styles.DistrictNetworkStaticInfoStyle;
+import org.simantics.scenegraph.ParentNode;
+import org.simantics.scenegraph.g2d.G2DNode;
+import org.simantics.scenegraph.g2d.nodes.spatial.RTreeNode;
+import org.simantics.scenegraph.utils.NodeUtil;
+import org.simantics.utils.datastructures.Pair;
+
+public class DistrictNetworkEdgeArrayNode extends G2DNode implements DeferredNode {
+
+ private static final long serialVersionUID = -8377444630205663419L;
+
+ public static final String NODE_KEY = "DISTRICT_NETWORK_EDGE_ARRAY";
+
+ private static final String RENDERER_ID = "edgeArrayDeferredRenderer";
+
+ private DistrictNetworkEdgeNode edgeNode = null;
+ private Double arrowLength;
+ private Path2D arrowPath;
+
+ @Override
+ public void render(Graphics2D g2d) {
+ ParentNode<?> root = (ParentNode<?>) NodeUtil.getNearestParentOfType(this, RTreeNode.class);
+ DeferredRenderingNode deferred = root != null ? (DeferredRenderingNode) root.getNode(DistrictNetworkStaticInfoStyle.STATIC_INFO_DEFERRED) : null;
+ if (deferred != null)
+ deferred.deferNode(g2d.getTransform(), this);
+ else
+ renderDeferred(g2d);
+ }
+
+ @Override
+ public void renderDeferred(Graphics2D g2d) {
+
+ // Draw arrow
+ if (arrowLength != null) {
+ double scale = DistrictNetworkEdgeNode.scaleStroke ? (Double) g2d.getRenderingHint(DistrictRenderingHints.KEY_VIEW_SCALE_UNDER_SPATIAL_ROOT) : 1.0;
+ g2d.setColor(Color.BLACK);
+ float lw = DistrictNetworkEdgeNode.STROKE.getLineWidth() / (float)scale;
+ g2d.setStroke(new BasicStroke(lw, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
+
+ double l = arrowLength;
+ double w = 2 * (double) lw * Math.signum(l);
+ if (Math.abs(w) > Math.abs(l)) w = l;
+ double offset = 2 * (double) lw;
+
+ int zoomLevel = (Integer) g2d.getRenderingHint(DistrictRenderingHints.KEY_VIEW_ZOOM_LEVEL);
+
+ Point2D centerPoint = edgeNode.getCenterPoint(zoomLevel);
+ Point2D direction = edgeNode.getDirection(zoomLevel);
+ double centerX = centerPoint.getX(), centerY = centerPoint.getY();
+ double deltaX = direction.getX(), deltaY = direction.getY();
+
+ // Ensure the line is always rendered on top of the edge
+ // to prevent overlap with static info rendered below it.
+ double odx = offset * deltaY;
+ double ody = offset * deltaX;
+ if (odx < 0) {
+ odx = -odx;
+ ody = -ody;
+ }
+
+ double x0 = centerX - l/2 * deltaX + ody;
+ double y0 = centerY - l/2 * deltaY - odx;
+ double x1 = centerX + (l/2 - w) * deltaX + ody;
+ double y1 = centerY + (l/2 - w) * deltaY - odx;
+
+ g2d.draw(new Line2D.Double(x0, y0, x1, y1));
+
+ arrowPath = new Path2D.Double();
+ arrowPath.moveTo(x1 + w * deltaX, y1 + w * deltaY);
+ arrowPath.lineTo(x1 + w * deltaY, y1 - w * deltaX);
+ arrowPath.lineTo(x1 - w * deltaY, y1 + w * deltaX);
+ arrowPath.closePath();
+ g2d.fill(arrowPath);
+ }
+ }
+
+ @Override
+ public Rectangle2D getBoundsInLocal() {
+ return null;
+ }
+
+ public void setEdgeNode(DistrictNetworkEdgeNode edgeNode) {
+ this.edgeNode = edgeNode;
+ }
+
+ public void setArrowLength(Double length) {
+ this.arrowLength = length;
+ }
+
+ public static Pair<String, Class<DeferredRenderingNode>> renderer() {
+ return Pair.make(RENDERER_ID, DeferredRenderingNode.class);
+ }
+
+}
private static final long serialVersionUID = 8049769475036519806L;
- private static final BasicStroke STROKE = new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
+ public static final BasicStroke STROKE = new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
private static final Color SELECTION_COLOR = new Color(255, 0, 255, 96);
private DistrictNetworkEdge edge;
private transient int zoomLevel = 0;
- private static boolean scaleStroke = true;
+ static final boolean scaleStroke = true;
private Color color;
private Double stroke;
private transient Color dynamicColor = null;
private boolean hidden = false;
- private Double arrowLength;
-
private static double startX;
private static double startY;
private static double endX;
private static double endY;
- private Path2D arrowPath;
-
@Override
public void init() {
}
g2d.setStroke(bs);
g2d.draw(path);
- // Draw arrow
- if (arrowLength != null) {
- g2d.setColor(Color.BLACK);
- float lw = STROKE.getLineWidth() / (float)scale;
- g2d.setStroke(new BasicStroke(lw, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
-
- double l = arrowLength;
- double w = 2 * (double) lw * Math.signum(l);
- if (Math.abs(w) > Math.abs(l)) w = l;
- double offset = 2 * (double) lw;
-
- Point2D centerPoint = getCenterPoint(zoomLevel);
- Point2D direction = getDirection(zoomLevel);
- double centerX = centerPoint.getX(), centerY = centerPoint.getY();
- double deltaX = direction.getX(), deltaY = direction.getY();
-
- // Ensure the line is always rendered on top of the edge
- // to prevent overlap with static info rendered below it.
- double odx = offset * deltaY;
- double ody = offset * deltaX;
- if (odx < 0) {
- odx = -odx;
- ody = -ody;
- }
-
- double x0 = centerX - l/2 * deltaX + ody;
- double y0 = centerY - l/2 * deltaY - odx;
- double x1 = centerX + (l/2 - w) * deltaX + ody;
- double y1 = centerY + (l/2 - w) * deltaY - odx;
-
- g2d.draw(new Line2D.Double(x0, y0, x1, y1));
-
- arrowPath = new Path2D.Double();
- arrowPath.moveTo(x1 + w * deltaX, y1 + w * deltaY);
- arrowPath.lineTo(x1 + w * deltaY, y1 - w * deltaX);
- arrowPath.lineTo(x1 - w * deltaY, y1 + w * deltaX);
- arrowPath.closePath();
- g2d.fill(arrowPath);
- }
-
// Reset
g2d.setStroke(oldStroke);
g2d.setColor(oldColor);
@PropertySetter(value = "arrowLength")
public void setArrowLength(Double length) {
- arrowLength = length;
+ // find if there is a child deferred arrow node
+ DistrictNetworkEdgeArrayNode child = getOrCreateNode(DistrictNetworkEdgeArrayNode.NODE_KEY, DistrictNetworkEdgeArrayNode.class);
+ child.setEdgeNode(this);
+ child.setArrowLength(length);
+ //arrowLength = length;
}
@PropertySetter(value = "SVG")
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.DeferredRenderingNode;
+import org.simantics.district.network.ui.nodes.DistrictNetworkEdgeArrayNode;
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.scenegraph.g2d.G2DParentNode;
import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;
import org.simantics.scenegraph.g2d.events.command.CommandEvent;
+import org.simantics.utils.datastructures.Pair;
import org.simantics.utils.datastructures.hints.HintListenerAdapter;
import org.simantics.utils.datastructures.hints.IHintContext.Key;
import org.simantics.utils.datastructures.hints.IHintListener;
private DynamicVisualisationContributionsNode node;
private AffineTransform transform;
private DistrictNetworkHoverInfoNode hoverInfoNode;
+ private DeferredRenderingNode deferredEdgeArrowRendererNode;
public DynamicVisualisationContributionsParticipant(AffineTransform tr) {
this.transform = tr;
hoverInfoNode.setLookupId("districtNetworkHoverInfoNode");
hoverInfoNode.setTransform(transform);
hoverInfoNode.setZIndex(Integer.MAX_VALUE - 500);
+
+ Pair<String, Class<DeferredRenderingNode>> dearn = DistrictNetworkEdgeArrayNode.renderer();
+ deferredEdgeArrowRendererNode = parent.addNode(dearn.first, dearn.second);
}
@EventHandler(priority = 0)
colorContributions = colorContributionSupplier.get().collect(Collectors.toMap(c -> c.getLabel(), c -> c));
return colorContributions;
}
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + " [" + coloringObject.getName() + " (" + coloringObject.getResource() + "), contributions=" + colorContributionsToString() + "]";
+ }
+
+ private String colorContributionsToString() {
+
+ return colorContributions.keySet().stream().map(key -> {
+ DynamicColorContribution dynamicColorContribution = colorContributions.get(key);
+ return key + "=" + dynamicColorContribution.getLabel();
+ }).collect(Collectors.joining(", ", "{", "}"));
+ }
}
public static class DynamicColoringMap {