From a4105d9cb79a428fbe3a4aa918fc6d1527f1988a Mon Sep 17 00:00:00 2001 From: Tuukka Lehtonen Date: Sun, 21 Oct 2018 16:39:21 +0300 Subject: [PATCH] Fixed regressions in box selection and element color function validation * Edge element box selection didn't work because the contained picking logic was not implemented properly in the edge element class. * Element coloring brightness function validation did not set "graph" key for SCLContext which caused compilation to fail occasionally which broke the function evaluation. * Fixed vertex selection visualization to stroke the edge of the normal rendered rectangular shape which is much cleaner than the old default selection visualization that was geometrically out of place for some reason. gitlab #2 Change-Id: Ib1f5e03a1eeb6101ffe0f527c5a54ece97e1ea8e --- .../adapters/DistrictNetworkEdgeElement.java | 82 ++++++++++--------- .../network/ui/function/Functions.java | 14 +++- .../ui/nodes/DistrictNetworkVertexNode.java | 53 +++++++----- .../network/ui/nodes/NetworkDrawingNode.java | 4 + 4 files changed, 91 insertions(+), 62 deletions(-) diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElement.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElement.java index cbc6a578..9595f232 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElement.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElement.java @@ -4,6 +4,7 @@ import java.awt.Color; import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.geom.Line2D; +import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.util.Collection; import java.util.Collections; @@ -22,7 +23,6 @@ import org.simantics.g2d.element.handler.InternalSize; import org.simantics.g2d.element.handler.Outline; import org.simantics.g2d.element.handler.Pick; import org.simantics.g2d.element.handler.SceneGraph; -import org.simantics.g2d.element.handler.SelectionOutline; import org.simantics.g2d.element.handler.impl.ConnectionSelectionOutline; import org.simantics.g2d.element.handler.impl.DefaultTransform; import org.simantics.g2d.element.handler.impl.SimpleElementLayers; @@ -115,48 +115,14 @@ public class DistrictNetworkEdgeElement { } } - private Shape getSelectionShape(IElement e) { - for (SelectionOutline so : e.getElementClass().getItemsByClass(SelectionOutline.class)) { - Shape shape = so.getSelectionShape(e); - if (shape != null) - return shape; - } - // Using on-diagram coordinates because neither connections nor - // edges have a non-identity transform which means that - // coordinates are always absolute. Therefore branch point - // shape also needs to be calculated in absolute coordinates. - Shape shape = ElementUtils.getElementShapeOrBoundsOnDiagram(e); - return shape; - } - @Override public boolean pickTest(IElement e, Shape s, PickPolicy policy) { DistrictNetworkEdge edge = e.getHint(KEY_DN_EDGE); if (edge != null) { Rectangle2D bounds = getBounds(s); - switch (policy) { - case PICK_CONTAINED_OBJECTS: - Shape selectionShape = getSelectionShape(e); - return bounds.contains(selectionShape.getBounds2D()); - - case PICK_INTERSECTING_OBJECTS: - double tolerance = (bounds.getHeight() + bounds.getHeight()) * 0.25 / MapScalingTransform.getScaleX(); - Line2D line = new Line2D.Double(edge.getStartPoint(), edge.getEndPoint()); - double sx = bounds.getCenterX() / MapScalingTransform.getScaleX(); - double sy = bounds.getCenterY() / MapScalingTransform.getScaleY(); - double ssx = ModelledCRS.xToLongitude(sx); - double ssy = ModelledCRS.yToLatitude(-sy); // Invert for Simantics diagram coordinate system - double distSq = line.ptSegDistSq(ssx, ssy); -// System.out.println("s: " + sx + ", " + sy); -// System.out.println("ss: " + ssx + ", " + ssy); -// System.out.println("p1: " + edge.getStartPoint()); -// System.out.println("p2: " + edge.getEndPoint()); -// System.out.println("line: " + "(" + line.getX1() + ", " + line.getY1() + ", " + line.getX2() + ", " + line.getY2() + ")"); -// System.out.println("distance from line is " + Math.sqrt(distSq) + " with tolerance " + tolerance); - if (distSq <= tolerance * tolerance) { - return true; - } + case PICK_CONTAINED_OBJECTS: return pickContainedObjects(edge, bounds); + case PICK_INTERSECTING_OBJECTS: return pickIntersectingObjects(edge, bounds); } return false; } @@ -164,6 +130,48 @@ public class DistrictNetworkEdgeElement { return false; } + private boolean pickContainedObjects(DistrictNetworkEdge edge, Rectangle2D bounds) { + double bminx = bounds.getMinX() / MapScalingTransform.getScaleX(); + double bminy = bounds.getMinY() / MapScalingTransform.getScaleY(); + double bmaxx = bounds.getMaxX() / MapScalingTransform.getScaleX(); + double bmaxy = bounds.getMaxY() / MapScalingTransform.getScaleY(); + + double bsminx = ModelledCRS.xToLongitude(bminx); + double bsminy = ModelledCRS.yToLatitude(-bminy); // Invert for Simantics diagram coordinate system + double bsmaxx = ModelledCRS.xToLongitude(bmaxx); + double bsmaxy = ModelledCRS.yToLatitude(-bmaxy); // Invert for Simantics diagram coordinate system + + double boundsMinY = Math.min(bsminy, bsmaxy); + double boundsMaxY = Math.max(bsminy, bsmaxy); + + Point2D start = edge.getStartPoint(); + Point2D end = edge.getEndPoint(); + + double eminx = Math.min(start.getX(), end.getX()); + double eminy = Math.min(start.getY(), end.getY()); + double emaxx = Math.max(start.getX(), end.getX()); + double emaxy = Math.max(start.getY(), end.getY()); + + return eminx >= bsminx && eminy >= boundsMinY && emaxx <= bsmaxx && emaxy <= boundsMaxY; + } + + private boolean pickIntersectingObjects(DistrictNetworkEdge edge, Rectangle2D bounds) { + double tolerance = (bounds.getHeight() + bounds.getHeight()) * 0.25 / MapScalingTransform.getScaleX(); + Line2D line = new Line2D.Double(edge.getStartPoint(), edge.getEndPoint()); + double sx = bounds.getCenterX() / MapScalingTransform.getScaleX(); + double sy = bounds.getCenterY() / MapScalingTransform.getScaleY(); + double ssx = ModelledCRS.xToLongitude(sx); + double ssy = ModelledCRS.yToLatitude(-sy); // Invert for Simantics diagram coordinate system + double distSq = line.ptSegDistSq(ssx, ssy); +// System.out.println("s: " + sx + ", " + sy); +// System.out.println("ss: " + ssx + ", " + ssy); +// System.out.println("p1: " + edge.getStartPoint()); +// System.out.println("p2: " + edge.getEndPoint()); +// System.out.println("line: " + "(" + line.getX1() + ", " + line.getY1() + ", " + line.getX2() + ", " + line.getY2() + ")"); +// System.out.println("distance from line is " + Math.sqrt(distSq) + " with tolerance " + tolerance); + return distSq <= tolerance * tolerance; + } + private Rectangle2D getBounds(Shape shape) { if (shape instanceof Rectangle2D) return (Rectangle2D) shape; diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/function/Functions.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/function/Functions.java index 3aa6f275..cc9b336f 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/function/Functions.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/function/Functions.java @@ -601,10 +601,16 @@ public class Functions { importEntry = graph.getPossibleURI(sclmain); } } - return new BrightnessExpressionValidator( - importEntry != null - ? Arrays.asList(importEntry) - : Collections.emptyList()); + SCLContext ctx = SCLContext.getCurrent(); + Object oldGraph = ctx.put("graph", graph); + try { + return new BrightnessExpressionValidator( + importEntry != null + ? Arrays.asList(importEntry) + : Collections.emptyList()); + } finally { + ctx.put("graph", oldGraph); + } } private static class BrightnessExpressionValidator implements Function1 { diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkVertexNode.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkVertexNode.java index 58e47f4b..0cd5ea88 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkVertexNode.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkVertexNode.java @@ -41,6 +41,8 @@ public class DistrictNetworkVertexNode extends G2DNode implements ISelectionPain private transient Color dynamicColor; private Rectangle2D bounds; + private transient Point2D point; + private transient Rectangle2D rect; private double nodeSize = 1; @@ -69,44 +71,52 @@ public class DistrictNetworkVertexNode extends G2DNode implements ISelectionPain } Color oldColor = g2d.getColor(); + Color newColor = dynamicColor != null ? dynamicColor : color; + boolean changeColor = !oldColor.equals(newColor); - double scaleRecip = 1; + double viewScaleRecip = 1; if (scaleStroke) { double scale = GeometryUtils.getScale(g2d.getTransform()); scale = Math.max(10000, Math.min(scale, 50000)); - scaleRecip = 1.0 / scale; + viewScaleRecip = 1.0 / scale; } - scaleRecip = scaleRecip * nodeSize; + double scaleRecip = viewScaleRecip * nodeSize; // Translate lat and lon to X and Y - Point2D res = calculatePoint2D(vertex); - - Rectangle2D toDraw; - if (hover) { - toDraw = new Rectangle2D.Double(res.getX() - (HOVERED.getWidth() / 2 * scaleRecip), res.getY() - (HOVERED.getHeight() / 2 * scaleRecip), HOVERED.getWidth() * scaleRecip, HOVERED.getHeight() * scaleRecip); - } else { - toDraw = new Rectangle2D.Double(res.getX() - (NORMAL.getWidth() / 2 * scaleRecip), res.getY() - (NORMAL.getHeight() / 2 * scaleRecip), NORMAL.getWidth() * scaleRecip, NORMAL.getHeight() * scaleRecip); - } + Point2D p = point = calculatePoint2D(vertex, point); + Rectangle2D toDraw = calculateDrawnGeometry(p, hover ? HOVERED : NORMAL, rect, scaleRecip); if (NodeUtil.isSelected(this, 1)) { + changeColor = true; g2d.setColor(SELECTION_COLOR); - BasicStroke ss = GeometryUtils.scaleStroke(STROKE, (float) scaleRecip*2); + BasicStroke ss = GeometryUtils.scaleStroke(STROKE, (float) viewScaleRecip*5); g2d.setStroke(ss); g2d.draw(toDraw); } // render - g2d.setColor(dynamicColor != null ? dynamicColor : color); + if (changeColor) + g2d.setColor(newColor); g2d.fill(toDraw); // Reset settings - g2d.setColor(oldColor); + if (changeColor) + g2d.setColor(oldColor); if (oaaHint != null) g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aaHint); if (ot != null) g2d.setTransform(ot); } + private Rectangle2D calculateDrawnGeometry(Point2D p, Rectangle2D margin, Rectangle2D result, double scaleRecip) { + if (result == null) + result = new Rectangle2D.Double(); + double mw = margin.getWidth(); + double mh = margin.getHeight(); + result.setFrame(p.getX() - (mw / 2 * scaleRecip), p.getY() - (mh / 2 * scaleRecip), mw * scaleRecip, mh * scaleRecip); + return result; + } + @Override public Rectangle2D getBounds() { return super.getBounds(); @@ -137,19 +147,20 @@ public class DistrictNetworkVertexNode extends G2DNode implements ISelectionPain } private Rectangle2D calculateBounds(Rectangle2D rect) { - Point2D calcPoint = calculatePoint2D(vertex); + Point2D calcPoint = calculatePoint2D(vertex, point); AffineTransform at = getTransform(); return new Rectangle2D.Double(calcPoint.getX(), calcPoint.getY(), width / at.getScaleX(), height / at.getScaleY()).getBounds2D(); } - private static Point2D calculatePoint2D(DistrictNetworkVertex vertex) { - Point2D point= vertex.getPoint(); + private static Point2D calculatePoint2D(DistrictNetworkVertex vertex, Point2D result) { + Point2D point = vertex.getPoint(); double x = ModelledCRS.longitudeToX(point.getX()); double y = ModelledCRS.latitudeToY(-point.getY()); // Inverse because Simantics Diagram is inverted - - // Apply the scaling - Point2D res = new Point2D.Double(x, y); - return res; + if (result == null) + result = new Point2D.Double(x, y); + else + result.setLocation(x, y); + return result; } public void setVertex(DistrictNetworkVertex vertex) { diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/NetworkDrawingNode.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/NetworkDrawingNode.java index aaf26a10..71ccb781 100644 --- a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/NetworkDrawingNode.java +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/NetworkDrawingNode.java @@ -134,9 +134,13 @@ public class NetworkDrawingNode extends G2DNode { while (nodeIter.hasNext()) { if (end == null) { start = nodeIter.next(); + if (!nodeIter.hasNext()) { + break; + } } else { start = end; } + end = nodeIter.next(); createEdge(start, end); -- 2.45.1