]> gerrit.simantics Code Review - simantics/district.git/commitdiff
Fixed regressions in box selection and element color function validation 45/2345/2
authorTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Sun, 21 Oct 2018 13:39:21 +0000 (16:39 +0300)
committerTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Sun, 21 Oct 2018 13:42:26 +0000 (16:42 +0300)
* 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

org.simantics.district.network.ui/src/org/simantics/district/network/ui/adapters/DistrictNetworkEdgeElement.java
org.simantics.district.network.ui/src/org/simantics/district/network/ui/function/Functions.java
org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkVertexNode.java
org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/NetworkDrawingNode.java

index cbc6a578638e9a1d679915613af759de27b751be..9595f232debb6339459ff11203b5e2f56139bed4 100644 (file)
@@ -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;
index 3aa6f2752cc04363acf417762d1e1ab680ea3ac7..cc9b336f69a796680b8fc8bd1c972900f9d35ece 100644 (file)
@@ -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<String, String> {
index 58e47f4bcf285dff9f5585aafc7d6a8e5f0eb49e..0cd5ea884fd29058c2e12907eca01112a3e2dbe0 100644 (file)
@@ -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) {
index aaf26a10855545bd97f3eb585a573981d775bba2..71ccb781a1f1a0b0bf74df1d14430a5937a6e6db 100644 (file)
@@ -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);