]> gerrit.simantics Code Review - simantics/district.git/blobdiff - org.simantics.district.network.ui/src/org/simantics/district/network/ui/nodes/NetworkDrawingNode.java
Support copying of attributes from DN.MappedComponent
[simantics/district.git] / org.simantics.district.network.ui / src / org / simantics / district / network / ui / nodes / NetworkDrawingNode.java
index b2c157184f07cf0c96b9eb342b3dc438f7cf53b8..b94639e2311080c9881044f0228a4c06e14bbc6d 100644 (file)
@@ -4,6 +4,7 @@ import java.awt.BasicStroke;
 import java.awt.Color;
 import java.awt.Graphics2D;
 import java.awt.Stroke;
+import java.awt.geom.AffineTransform;
 import java.awt.geom.Path2D;
 import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
@@ -16,11 +17,16 @@ import org.simantics.db.Resource;
 import org.simantics.db.WriteGraph;
 import org.simantics.db.common.request.WriteRequest;
 import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.request.Write;
+import org.simantics.diagram.elements.DiagramNodeUtil;
 import org.simantics.diagram.ui.DiagramModelHints;
+import org.simantics.district.network.DistrictNetworkUtil;
 import org.simantics.district.network.ModelledCRS;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
 import org.simantics.district.network.ui.DNEdgeBuilder;
 import org.simantics.district.network.ui.NetworkDrawingParticipant;
 import org.simantics.g2d.canvas.Hints;
+import org.simantics.g2d.canvas.ICanvasContext;
 import org.simantics.g2d.canvas.IToolMode;
 import org.simantics.g2d.diagram.IDiagram;
 import org.simantics.scenegraph.g2d.G2DNode;
@@ -35,15 +41,19 @@ import org.simantics.scenegraph.utils.NodeUtil;
 
 public class NetworkDrawingNode extends G2DNode {
 
+    static class DrawingNode {
+
+        private List<Point2D> routeNodes = new ArrayList<>();
+    }
+
     private static final long serialVersionUID = -3475301184009620573L;
     
     private Point2D currentMousePos = null;
-    
-    private List<Point2D> nodes = new ArrayList<>();
 
-    private Resource diagramResource;
+    private List<DrawingNode> nodes = new ArrayList<>();
+    private DrawingNode currentRouteNode = null;
 
-    private boolean committed;
+    private Resource diagramResource;
 
     private NetworkDrawingParticipant participant;
 
@@ -55,6 +65,7 @@ public class NetworkDrawingNode extends G2DNode {
             4.0f, new float[]{4.0f}, 0.0f);
 
     private static final Color BLUE_ALPHA = new Color(0, 0, 255, 100);
+    private static final Color RED_ALPHA = new Color(255, 0, 0, 100);
 
     private boolean scaleStroke = true;
     
@@ -79,36 +90,47 @@ public class NetworkDrawingNode extends G2DNode {
     public void render(Graphics2D g2d) {
         if (nodes.isEmpty())
             return;
-        
-        Path2D path = new Path2D.Double();
-        Iterator<Point2D> nodeIter = nodes.iterator();
-        if (nodeIter.hasNext()) {
-            Point2D node = nodeIter.next();
-            path.moveTo(node.getX(), node.getY());
-        }
-        while (nodeIter.hasNext()) {
-            Point2D node = nodeIter.next();
-            path.lineTo(node.getX(), node.getY());
-        }
-        if (currentMousePos != null)
-            path.lineTo(currentMousePos.getX(), currentMousePos.getY());
-        
+
         Color old = g2d.getColor();
         Stroke oldStroke = g2d.getStroke();
-        
-        if (DASHED_STROKE != null) {
-            if (scaleStroke && DASHED_STROKE instanceof BasicStroke) {
-                BasicStroke bs = GeometryUtils.scaleStroke(DASHED_STROKE, (float) (1.0 / GeometryUtils.getScale(g2d.getTransform())));
-                g2d.setStroke(bs);
-            } else {
-                g2d.setStroke(DASHED_STROKE);
+
+        Iterator<DrawingNode> dnodeIterator = nodes.iterator();
+        while (dnodeIterator.hasNext()) {
+            Path2D path = new Path2D.Double();
+            DrawingNode dnode = dnodeIterator.next();
+            Iterator<Point2D> nodeIter = dnode.routeNodes.iterator();
+            if (nodeIter.hasNext()) {
+                Point2D node = nodeIter.next();
+                path.moveTo(node.getX(), node.getY());
+            }
+            while (nodeIter.hasNext()) {
+                Point2D node = nodeIter.next();
+                path.lineTo(node.getX(), node.getY());
+            }
+            if (!dnodeIterator.hasNext()) {
+                if (currentMousePos != null)
+                    path.lineTo(currentMousePos.getX(), currentMousePos.getY());
+            }
+            
+            if (DASHED_STROKE != null) {
+                if (scaleStroke && DASHED_STROKE instanceof BasicStroke) {
+                    BasicStroke bs = GeometryUtils.scaleStroke(DASHED_STROKE, (float) (1.0 / GeometryUtils.getScale(g2d.getTransform())));
+                    g2d.setStroke(bs);
+                } else {
+                    g2d.setStroke(DASHED_STROKE);
+                }
             }
+            
+            g2d.setColor(BLUE_ALPHA);
+            g2d.draw(path);
+            
+            g2d.setColor(RED_ALPHA);
+            BasicStroke stroke = GeometryUtils.scaleStroke(DASHED_STROKE, (float) (1.0 / GeometryUtils.getScale(g2d.getTransform())));
+            g2d.setStroke(stroke);
+            Point2D currentPoint = path.getCurrentPoint();
+            g2d.draw(new Rectangle2D.Double(currentPoint.getX() - 0.0001 / 2, currentPoint.getY() - 0.0001 / 2, 0.0001, 0.0001));
         }
         
-        g2d.setColor(BLUE_ALPHA);
-
-        g2d.draw(path);
-        
         g2d.setStroke(oldStroke);
         g2d.setColor(old);
     }
@@ -128,34 +150,48 @@ public class NetworkDrawingNode extends G2DNode {
         // nodes to path2d
         IToolMode mode = getToolMode();
         if (mode == Hints.CONNECTTOOL || e.hasAnyModifier(MouseEvent.ALT_MASK | MouseEvent.ALT_GRAPH_MASK)) {
-            Point2D start = null;
-            Point2D end = null;
-            Iterator<Point2D> nodeIter = nodes.iterator();
-            while (nodeIter.hasNext()) {
-                if (end == null) {
-                    start = nodeIter.next();
-                } else {
-                    start = end;
-                }
-                end = nodeIter.next();
-                
-                createEdge(start, end);
+            // ok, new routenode starts from here
+            Point2D localPos = NodeUtil.worldToLocal(this, e.controlPosition, new Point2D.Double());
+            Point2D.Double pos = new Point2D.Double(localPos.getX(), localPos.getY());
+            if (currentRouteNode != null) {
+                //currentRouteNode.routeNodes.add(pos);
+                currentRouteNode = new DrawingNode();
+                currentRouteNode.routeNodes.add(pos);
+                nodes.add(currentRouteNode);
+            } else {
+                // ok, this must be creation of dh_point
+                double scale = getTransform().getScaleY();
+                double x = ModelledCRS.xToLongitude(pos.getX() / scale);
+                double y = ModelledCRS.yToLatitude(-pos.getY() / scale);
+                Simantics.getSession().asyncRequest(new Write() {
+                    
+                    @Override
+                    public void perform(WriteGraph graph) throws DatabaseException {
+                        graph.markUndoPoint();
+                        Resource defaultMapping = graph.getSingleObject(diagramResource, DistrictNetworkResource.getInstance(graph).VertexDefaultMapping);
+                        DistrictNetworkUtil.createVertex(graph, diagramResource, new double[] { x, y }, 0, defaultMapping); // TODO: elevation can be fetched from e.g. elevation API
+                    }
+                });
             }
-            
-            nodes.clear();
-            committed = true;
-            
             repaint();
-            
             return true;
         }
         return super.mouseDoubleClicked(e);
     }
 
-    private void createEdge(Point2D start, Point2D end) {
+    private void createEdge(DrawingNode node) {
         
-        double padding = GeometryUtils.getScale(getTransform());
+        Point2D start = node.routeNodes.get(0);
+        Point2D end = node.routeNodes.get(node.routeNodes.size() - 1);
         
+        double currentPadding = DistrictNetworkVertexNode.width;
+        AffineTransform test = getTransform();
+        ICanvasContext ctx = DiagramNodeUtil.getCanvasContext(this);
+        AffineTransform tr = ctx.getHintStack().getHint(Hints.KEY_CANVAS_TRANSFORM);
+        AffineTransform testing = new AffineTransform(tr); 
+        testing.concatenate(test);
+        double calculateScaleRecip = DistrictNetworkNodeUtils.calculateScaleRecip(testing);
+        double padding = currentPadding * calculateScaleRecip;
         /*
          *  To convert y-coordinates to map coordinates in ruler, use:
          *    double val = (y-offsetY)/scaleY;
@@ -163,23 +199,33 @@ public class NetworkDrawingNode extends G2DNode {
          *    String str = formatValue(val);
          */
         // TODO: fix scale
-        double scale = 100000;
-//        double scale = 1;
-        double startLat = ModelledCRS.yToLatitude(start.getY() / scale);
-        double startLon = ModelledCRS.xToLongitude(start.getX() / scale);
+        double scaleY = getTransform().getScaleY();
+        double scaleX = getTransform().getScaleX();
+        
+        double startLat = ModelledCRS.yToLatitude(-start.getY() / scaleY);
+        double startLon = ModelledCRS.xToLongitude(start.getX() / scaleX);
         
-        double endLat = ModelledCRS.yToLatitude(end.getY() / scale);
-        double endLon = ModelledCRS.xToLongitude(end.getX() / scale);
+        double endLat = ModelledCRS.yToLatitude(-end.getY() / scaleY);
+        double endLon = ModelledCRS.xToLongitude(end.getX() / scaleX);
         
         double[] startCoords = new double[] { startLon, startLat };
         double[] endCoords = new double[] { endLon, endLat };
         
+        double[] detailedGeometryCoords = new double[node.routeNodes.size() * 2];
+        int i = 0;
+        for (Point2D p : node.routeNodes) {
+            double lat = ModelledCRS.yToLatitude(-p.getY() / scaleY);
+            double lon = ModelledCRS.xToLongitude(p.getX() / scaleX);
+            detailedGeometryCoords[i++] = lon;
+            detailedGeometryCoords[i++] = lat;
+        }
+        
         DNEdgeBuilder builder = new DNEdgeBuilder(diagramResource, diagram);
         Simantics.getSession().asyncRequest(new WriteRequest() {
             
             @Override
             public void perform(WriteGraph graph) throws DatabaseException {
-                builder.create(graph, startCoords, endCoords, padding / scale);
+                builder.create(graph, startCoords, 0, endCoords, 0, detailedGeometryCoords, padding);
             }
         });
         
@@ -190,22 +236,38 @@ public class NetworkDrawingNode extends G2DNode {
         // check ToolMode
         IToolMode mode = getToolMode();
         if (mode == Hints.CONNECTTOOL || e.hasAnyModifier(MouseEvent.ALT_MASK | MouseEvent.ALT_GRAPH_MASK)) {
-            if (committed) {
-                committed = false;
-                return false;
-            }
             if (e.button == MouseEvent.RIGHT_BUTTON && !nodes.isEmpty()) {
                 nodes.remove(nodes.size() - 1);
             } else if (e.button == MouseEvent.LEFT_BUTTON) {
                 Point2D localPos = NodeUtil.worldToLocal(this, e.controlPosition, new Point2D.Double());
-                nodes.add(new Point2D.Double(localPos.getX(), localPos.getY()));
+                if (currentRouteNode == null && canStartEdge(localPos)) {
+                    // ok, we can start from here
+                    currentRouteNode = new DrawingNode();
+                    currentRouteNode.routeNodes.add(new Point2D.Double(localPos.getX(), localPos.getY()));
+                    nodes.add(currentRouteNode);
+                } else if (currentRouteNode != null && canStartEdge(localPos)) {
+                    // let's commit our new routenode
+                    currentRouteNode.routeNodes.add(new Point2D.Double(localPos.getX(), localPos.getY()));
+                    Iterator<DrawingNode> nodeIter = nodes.iterator();
+                    while (nodeIter.hasNext()) {
+                        createEdge(nodeIter.next());
+                    }
+                    currentRouteNode = null;
+                    nodes.clear();
+                } else if (currentRouteNode != null) {
+                    currentRouteNode.routeNodes.add(new Point2D.Double(localPos.getX(), localPos.getY()));
+                }
             }
             repaint();
             return true;
         }
         return super.mouseClicked(e);
     }
-    
+
+    private boolean canStartEdge(Point2D currentPos) {
+        return participant.isHoveringOverNode(currentPos);
+    }
+
     private IToolMode getToolMode() {
         return participant.getHint(Hints.KEY_TOOL);
     }
@@ -213,28 +275,28 @@ public class NetworkDrawingNode extends G2DNode {
     @Override
     protected boolean mouseMoved(MouseMovedEvent e) {
         IToolMode mode = getToolMode();
-        if (mode == Hints.CONNECTTOOL || e.hasAnyModifier(MouseEvent.ALT_MASK | MouseEvent.ALT_GRAPH_MASK)) {
-            boolean repaint = false;
-            Point2D p = NodeUtil.worldToLocal(this, e.controlPosition, new Point2D.Double());
-            if (participant.pickHoveredElement(p)) {
-                repaint = true;
-            }
-            if (!nodes.isEmpty()) {
-                currentMousePos = p;
-                
-                repaint();
-                return true;
-            }
-            currentMousePos = null;
-            if (repaint == true)
-                repaint();
+        boolean repaint = false;
+        Point2D p = NodeUtil.worldToLocal(this, e.controlPosition, new Point2D.Double());
+        boolean isConnectionTool = mode == Hints.CONNECTTOOL || e.hasAnyModifier(MouseEvent.ALT_MASK | MouseEvent.ALT_GRAPH_MASK);
+        if (participant.pickHoveredElement(p, isConnectionTool)) {
+            repaint = true;
+        }
+        if (!nodes.isEmpty()) {
+            currentMousePos = p;
+            
+            repaint();
+            return true;
         }
+        currentMousePos = null;
+        if (repaint == true)
+            repaint();
         return super.mouseMoved(e);
     }
     
     @Override
     protected boolean keyPressed(KeyPressedEvent e) {
         if (e.keyCode == java.awt.event.KeyEvent.VK_ESCAPE) {
+            currentRouteNode = null;
             nodes.clear();
             repaint();
             return true;