package org.simantics.district.network.ui.nodes; import java.awt.Color; import java.awt.Graphics2D; import java.awt.geom.Path2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; 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.diagram.ui.DiagramModelHints; 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.IToolMode; import org.simantics.g2d.diagram.IDiagram; import org.simantics.scenegraph.g2d.G2DNode; import org.simantics.scenegraph.g2d.events.EventTypes; import org.simantics.scenegraph.g2d.events.MouseEvent; import org.simantics.scenegraph.g2d.events.MouseEvent.MouseClickEvent; import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDoubleClickedEvent; import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent; import org.simantics.scenegraph.utils.NodeUtil; public class NetworkDrawingNode extends G2DNode { private static final long serialVersionUID = -3475301184009620573L; private List nodes = new ArrayList<>(); private Rectangle2D rect = new Rectangle2D.Double(10, 10, 10, 10); private Set paths = new HashSet<>(); private Resource diagramResource; private boolean committed; private NetworkDrawingParticipant participant; private IDiagram diagram; @Override public void init() { super.init(); addEventHandler(this); } public void setNetworkDrawingParticipant(NetworkDrawingParticipant participant) { this.participant = participant; } public void setDiagram(IDiagram diagram) { if (diagram != null) { this.diagram = diagram; this.diagramResource = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE); } } @Override public void render(Graphics2D g2d) { Color old = g2d.getColor(); g2d.setColor(Color.BLUE); paths.forEach(p -> { g2d.draw(p); }); g2d.setColor(old); } @Override public Rectangle2D getBoundsInLocal() { return rect.getBounds2D(); } @Override public int getEventMask() { return EventTypes.MouseMask; } @Override protected boolean mouseDoubleClicked(MouseDoubleClickedEvent e) { // 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(); createEdge(start, end); } nodes.clear(); committed = true; repaint(); return true; } return super.mouseDoubleClicked(e); } private void createEdge(Point2D start, Point2D end) { double[] startCoords = new double[] { start.getX(), start.getY() }; double[] endCoords = new double[] { end.getX(), end.getY() }; DNEdgeBuilder builder = new DNEdgeBuilder(diagramResource, diagram); Simantics.getSession().asyncRequest(new WriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { builder.create(graph, startCoords, endCoords); } }); } @Override protected boolean mouseClicked(MouseClickEvent e) { // check ToolMode IToolMode mode = getToolMode(); if (mode == Hints.CONNECTTOOL || e.hasAnyModifier(MouseEvent.ALT_MASK | MouseEvent.ALT_GRAPH_MASK)) { if (committed) { committed = false; return false; } Point2D localPos = NodeUtil.worldToLocal(this, e.controlPosition, new Point2D.Double()); nodes.add(new Point2D.Double(localPos.getX(), localPos.getY())); } return super.mouseClicked(e); } private IToolMode getToolMode() { return participant.getHint(Hints.KEY_TOOL); } @Override protected boolean mouseMoved(MouseMovedEvent e) { return super.mouseMoved(e); } }