X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.district.network.ui%2Fsrc%2Forg%2Fsimantics%2Fdistrict%2Fnetwork%2Fui%2Fnodes%2FNetworkDrawingNode.java;h=335f9e118cd1d8c14bd640cc6bd850f6dadb3a18;hb=45d87b504f16ba0fb8e6c16cd4c8e4efe7af049e;hp=b2c157184f07cf0c96b9eb342b3dc438f7cf53b8;hpb=02ecca5e61d2eb17de40cc058be678b414aaad00;p=simantics%2Fdistrict.git 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 b2c15718..335f9e11 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 @@ -4,25 +4,34 @@ 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; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.concurrent.TimeUnit; import org.simantics.Simantics; 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.DNEdgeBuilder; +import org.simantics.district.network.DistrictNetworkUtil; import org.simantics.district.network.ModelledCRS; -import org.simantics.district.network.ui.DNEdgeBuilder; +import org.simantics.district.network.ontology.DistrictNetworkResource; 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.maps.elevation.server.SingletonTiffTileInterface; +import org.simantics.maps.elevation.server.prefs.MapsElevationServerPreferences; import org.simantics.scenegraph.g2d.G2DNode; import org.simantics.scenegraph.g2d.events.EventTypes; import org.simantics.scenegraph.g2d.events.KeyEvent.KeyPressedEvent; @@ -32,18 +41,27 @@ import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDoubleClickedEvent; import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent; import org.simantics.scenegraph.utils.GeometryUtils; import org.simantics.scenegraph.utils.NodeUtil; +import org.simantics.utils.threads.ThreadUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class NetworkDrawingNode extends G2DNode { + private static final Logger LOGGER = LoggerFactory.getLogger(NetworkDrawingNode.class); + + static class DrawingNode { + + private List routeNodes = new ArrayList<>(); + } + private static final long serialVersionUID = -3475301184009620573L; private Point2D currentMousePos = null; - - private List nodes = new ArrayList<>(); - private Resource diagramResource; + private List nodes = new ArrayList<>(); + private DrawingNode currentRouteNode = null; - private boolean committed; + private Resource diagramResource; private NetworkDrawingParticipant participant; @@ -55,6 +73,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 +98,47 @@ public class NetworkDrawingNode extends G2DNode { public void render(Graphics2D g2d) { if (nodes.isEmpty()) return; - - Path2D path = new Path2D.Double(); - Iterator 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 dnodeIterator = nodes.iterator(); + while (dnodeIterator.hasNext()) { + Path2D path = new Path2D.Double(); + DrawingNode dnode = dnodeIterator.next(); + Iterator 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 +158,61 @@ 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 nodeIter = nodes.iterator(); - while (nodeIter.hasNext()) { - if (end == null) { - start = nodeIter.next(); - } else { - start = end; - } - end = nodeIter.next(); + // 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); + + boolean leftButton = e.button == MouseEvent.LEFT_BUTTON; - createEdge(start, end); + ThreadUtils.getNonBlockingWorkExecutor().schedule(() -> { + Simantics.getSession().asyncRequest(new Write() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + graph.markUndoPoint(); + Resource mapping = null; + if (leftButton) { + mapping = graph.getSingleObject(diagramResource, DistrictNetworkResource.getInstance(graph).LeftClickDefaultMapping); + } else { + mapping = graph.getSingleObject(diagramResource, DistrictNetworkResource.getInstance(graph).RightClickDefaultMapping); + } + if (mapping == null) { + mapping = graph.getSingleObject(diagramResource, DistrictNetworkResource.getInstance(graph).VertexDefaultMapping); + } + DistrictNetworkUtil.createVertex(graph, diagramResource, new double[] { x, y }, Double.MAX_VALUE, mapping); + } + }); + }, 100, TimeUnit.MILLISECONDS); } - - 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,26 +220,36 @@ 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, Double.MAX_VALUE, endCoords, Double.MAX_VALUE, detailedGeometryCoords, padding); } }); - + } @Override @@ -190,22 +257,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 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 +296,29 @@ 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); + // To boost pan perf hovering is only considered if no mouse button is pressed) + if (e.buttons == 0 && 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;