]> gerrit.simantics Code Review - simantics/district.git/blobdiff - org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/DistrictNetworkEdgeNode.java
NPE fix for district scene graph nodes
[simantics/district.git] / org.simantics.district.network.ui / src / org / simantics / district / network / ui / nodes / DistrictNetworkEdgeNode.java
index 21f3d741e77d81755376faa7047b3762266d0a92..8f8c08e6cc36f7f838e86c2254217f1fff1179fa 100644 (file)
@@ -13,11 +13,11 @@ import java.awt.geom.Rectangle2D;
 import org.simantics.district.network.ModelledCRS;
 import org.simantics.district.network.ui.DistrictNetworkEdge;
 import org.simantics.district.network.ui.adapters.DistrictNetworkEdgeElementFactory;
-import org.simantics.maps.MapScalingTransform;
 import org.simantics.scenegraph.INode;
 import org.simantics.scenegraph.ISelectionPainterNode;
 import org.simantics.scenegraph.g2d.G2DNode;
 import org.simantics.scenegraph.g2d.G2DParentNode;
+import org.simantics.scenegraph.g2d.G2DRenderingHints;
 import org.simantics.scenegraph.g2d.nodes.SVGNode;
 import org.simantics.scenegraph.utils.GeometryUtils;
 import org.simantics.scenegraph.utils.NodeUtil;
@@ -33,7 +33,7 @@ public class DistrictNetworkEdgeNode extends G2DParentNode implements ISelection
     private Rectangle2D bounds;
     private transient Path2D path;
 
-    private boolean scaleStroke = true;
+    private static boolean scaleStroke = true;
     private Color color;
     private Double stroke;
     private transient Color dynamicColor = null;
@@ -50,6 +50,8 @@ public class DistrictNetworkEdgeNode extends G2DParentNode implements ISelection
     private transient Rectangle2D symbolRect;
     private transient AffineTransform symbolTransform;
 
+    private boolean hidden = false;
+    
     private Double arrowLength;
 
     private static double startX;
@@ -65,102 +67,139 @@ public class DistrictNetworkEdgeNode extends G2DParentNode implements ISelection
     public void render(Graphics2D g2d) {
         AffineTransform ot = null;
         AffineTransform t = getTransform();
+        double scale = scaleStroke ? (Double) g2d.getRenderingHint(DistrictRenderingHints.KEY_VIEW_SCALE_UNDER_SPATIAL_ROOT) : 1.0;
         if (t != null && !t.isIdentity()) {
-            ot = g2d.getTransform();
-            g2d.transform(getTransform());
+            //ot = g2d.getTransform();
+            ot = (AffineTransform) g2d.getRenderingHint(G2DRenderingHints.KEY_TRANSFORM_UNDER_SPATIAL_ROOT);
+            if (ot == null)
+                ot = g2d.getTransform();
+            g2d.transform(t);
+            if (scaleStroke) {
+                AffineTransform work = DistrictNetworkNodeUtils.sharedTransform.get();
+                work.setTransform(ot);
+                work.concatenate(t);
+                scale = DistrictNetworkNodeUtils.getScale(work);
+            }
         }
 
-        Object aaHint = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
-        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-
-        Color oldColor = g2d.getColor();
-        BasicStroke oldStroke = (BasicStroke) g2d.getStroke();
-
-        BasicStroke bs = null;
-        if (scaleStroke) {
-            double scale = GeometryUtils.getScale(g2d.getTransform());
-            scale = Math.max(10000, Math.min(scale, 50000));
-            double str = stroke != null ? Math.abs(stroke) : 1.0;
-            bs = GeometryUtils.scaleStroke(STROKE, (float) (str / scale));
-        } else {
-            bs = STROKE;
-        }
-        int zoomLevel = MapScalingTransform.zoomLevel(ot);
-        path = calculatePath(edge, path, zoomLevel > 15);
+        if (!hidden) {
+            Object aaHint = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
+            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+    
+            Color oldColor = g2d.getColor();
+            BasicStroke oldStroke = (BasicStroke) g2d.getStroke();
+    
+            BasicStroke bs = null;
+            if (scaleStroke) {
+                bs = GeometryUtils.scaleStroke(STROKE, getStrokeWidth(scale));
+            } else {
+                bs = STROKE;
+            }
 
-        if (isSelected()) {
-            g2d.setColor(SELECTION_COLOR);
-            g2d.setStroke(GeometryUtils.scaleStroke(bs, 4f));
+            int zoomLevel = (Integer) g2d.getRenderingHint(DistrictRenderingHints.KEY_VIEW_ZOOM_LEVEL);
+            path = calculatePath(edge, path, zoomLevel > 13);
+    
+            if (isSelected()) {
+                g2d.setColor(SELECTION_COLOR);
+                g2d.setStroke(GeometryUtils.scaleAndOffsetStrokeWidth(bs, 1.f, (float)(2 * STROKE.getLineWidth() / scale)));
+                g2d.draw(path);
+            }
+    
+            g2d.setColor(dynamicColor != null ? dynamicColor : color);
+            g2d.setStroke(bs);
             g2d.draw(path);
-        }
-
-        g2d.setColor(dynamicColor != null ? dynamicColor : color);
-        g2d.setStroke(bs);
-        g2d.draw(path);
-
-        // Draw arrow
-        if (arrowLength != null) {
-            g2d.setColor(Color.BLACK);
-            g2d.setStroke(new BasicStroke(bs.getLineWidth(), BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
-            
-            double l = arrowLength;
-            double w = 2 * (double) bs.getLineWidth() * Math.signum(l);
-            if (Math.abs(w) > Math.abs(l)) w = l;
-            double offset = 2 * (double) bs.getLineWidth();
-            
-            double centerX = (startX + endX) / 2, centerY = (startY + endY) / 2;
-            double deltaX = endX - startX, deltaY = endY - startY;
-            double length = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
-            deltaX /= length;
-            deltaY /= length;
-            
-            double x0 = centerX - l/2 * deltaX + offset * deltaY;
-            double y0 = centerY - l/2 * deltaY - offset * deltaX;
-            double x1 = centerX + (l/2 - w) * deltaX + offset * deltaY;
-            double y1 = centerY + (l/2 - w) * deltaY - offset * deltaX;
-            
-            g2d.draw(new Line2D.Double(x0, y0, x1, y1));
+    
+            // 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;
+                
+                double centerX = (startX + endX) / 2, centerY = (startY + endY) / 2;
+                double deltaX = endX - startX, deltaY = endY - startY;
+                double length = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
+                deltaX /= length;
+                deltaY /= length;
+                
+                double x0 = centerX - l/2 * deltaX + offset * deltaY;
+                double y0 = centerY - l/2 * deltaY - offset * deltaX;
+                double x1 = centerX + (l/2 - w) * deltaX + offset * deltaY;
+                double y1 = centerY + (l/2 - w) * deltaY - offset * deltaX;
+                
+                g2d.draw(new Line2D.Double(x0, y0, x1, y1));
+                
+                Path2D path = new Path2D.Double();
+                path.moveTo(x1 + w * deltaX, y1 + w * deltaY);
+                path.lineTo(x1 + w * deltaY, y1 - w * deltaX);
+                path.lineTo(x1 - w * deltaY, y1 + w * deltaX);
+                path.closePath();
+                g2d.fill(path);
+            }
             
-            Path2D path = new Path2D.Double();
-            path.moveTo(x1 + w * deltaX, y1 + w * deltaY);
-            path.lineTo(x1 + w * deltaY, y1 - w * deltaX);
-            path.lineTo(x1 - w * deltaY, y1 + w * deltaX);
-            path.closePath();
-            g2d.fill(path);
-        }
-        
-        // Reset
-        g2d.setStroke(oldStroke);
-        g2d.setColor(oldColor);
-        
-        // Render SVG symbol
-        double viewScaleRecip = 10;
-        if (scaleStroke) {
-            double scale = GeometryUtils.getScale(g2d.getTransform());
-            scale = Math.max(10000, Math.min(scale, 50000));
-            viewScaleRecip /= scale;
+            // Reset
+            g2d.setStroke(oldStroke);
+            g2d.setColor(oldColor);
+            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aaHint);
         }
-        
-        Point2D p = getCenterPoint();
-        symbolRect = DistrictNetworkNodeUtils.calculateDrawnGeometry(p, NORMAL, symbolRect, viewScaleRecip);
-        symbolTransform = DistrictNetworkNodeUtils.getTransformToRectangle(symbolRect, symbolTransform);
-        
+
         for (INode nn : getNodes()) {
             G2DNode g2dNode = (G2DNode)nn;
-            g2dNode.setTransform(symbolTransform);
+            if (g2dNode instanceof SVGNode) {
+                // Render SVG symbol
+                double viewScaleRecip = 10;
+                if (scaleStroke) {
+                    viewScaleRecip /= scale;
+                }
+
+                // If the node is hidden from the start, then the center point cannot be calculated yet.
+                Point2D p = getCenterPoint();
+                if (p == null)
+                    break;
+
+                symbolRect = DistrictNetworkNodeUtils.calculateDrawnGeometry(p, NORMAL, symbolRect, viewScaleRecip);
+                symbolTransform = DistrictNetworkNodeUtils.getTransformToRectangle(symbolRect, symbolTransform);
+
+                g2dNode.setTransform(symbolTransform);
+            }
             g2dNode.render(g2d);
         }
-        
-        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aaHint);
 
         if (ot != null)
             g2d.setTransform(ot);
     }
 
+    public float getStrokeWidth(AffineTransform tr, boolean selection) {
+        double scale = DistrictNetworkNodeUtils.getScale(tr);
+        float width = STROKE.getLineWidth() * getStrokeWidth(scale);
+        if (selection) width = width + (float) (2 * STROKE.getLineWidth() / scale);
+        return width;
+    }
+    
+    private float getStrokeWidth(double scale) {
+        if (scaleStroke) {
+            double str = stroke != null ? Math.abs(stroke) : 1.0;
+            float strokeWidth = (float) (str / scale);
+            return strokeWidth;
+        }
+        else {
+            return 1.f;
+        }
+    }
+
+    public Path2D getPath() {
+        return path;
+    }
+    
     private Point2D getCenterPoint() {
+        if (path == null)
+            return null;
         if (centerPoint == null)
             centerPoint = new Point2D.Double();
-        
         Rectangle2D bounds = path.getBounds2D();
         centerPoint.setLocation(bounds.getCenterX(), bounds.getCenterY());
         return centerPoint;
@@ -251,7 +290,7 @@ public class DistrictNetworkEdgeNode extends G2DParentNode implements ISelection
     }
     
     @PropertySetter(value = "arrowLength")
-    public void setArroLength(Double length) {
+    public void setArrowLength(Double length) {
         arrowLength = length;
     }
 
@@ -262,4 +301,9 @@ public class DistrictNetworkEdgeNode extends G2DParentNode implements ISelection
                 ((SVGNode)nn).setData(value);
     }
     
+
+    @PropertySetter(value = "hidden")
+    public void setHidden(Boolean value) {
+        this.hidden = value;
+    }
 }