package maps.gml.editor; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.Color; import java.awt.Point; import java.awt.Insets; import maps.gml.view.NodeDecorator; import maps.gml.view.SquareNodeDecorator; import maps.gml.view.EdgeDecorator; import maps.gml.view.LineEdgeDecorator; import maps.gml.GMLNode; import maps.gml.GMLEdge; import maps.gml.GMLCoordinates; import maps.gml.GMLTools; import rescuecore2.misc.geometry.Point2D; import rescuecore2.misc.geometry.Line2D; import rescuecore2.misc.geometry.GeometryTools2D; /** A tool for splitting edges. */ public class SplitEdgeTool extends AbstractTool { private static final Color EDGE_COLOUR = Color.BLUE; private static final Color NODE_COLOUR = Color.BLACK; private static final int NODE_SIZE = 6; private Listener listener; private NodeDecorator nodeHighlight; private EdgeDecorator edgeHighlight; private GMLNode node; private GMLEdge edge; /** Construct a SplitEdgeTool. @param editor The editor instance. */ public SplitEdgeTool(GMLEditor editor) { super(editor); listener = new Listener(); nodeHighlight = new SquareNodeDecorator(NODE_COLOUR, NODE_SIZE); edgeHighlight = new LineEdgeDecorator(EDGE_COLOUR); edge = null; node = null; } @Override public String getName() { return "Split edge"; } @Override public void activate() { editor.getViewer().addMouseListener(listener); editor.getViewer().addMouseMotionListener(listener); node = null; edge = null; } @Override public void deactivate() { editor.getViewer().removeMouseListener(listener); editor.getViewer().removeMouseMotionListener(listener); editor.getViewer().clearAllNodeDecorators(); editor.getViewer().clearAllEdgeDecorators(); editor.getViewer().repaint(); if (node != null) { editor.getMap().removeNode(node); } } private void update(GMLCoordinates c) { if (node == null) { node = editor.getMap().createNode(c); editor.getViewer().setNodeDecorator(nodeHighlight, node); } GMLEdge newEdge = editor.getMap().findNearestEdge(c.getX(), c.getY()); if (newEdge != edge) { if (edge != null) { editor.getViewer().clearEdgeDecorator(edge); } edge = newEdge; editor.getViewer().setEdgeDecorator(edgeHighlight, edge); } // Snap the node coordinates to the edge Line2D line = GMLTools.toLine(edge); Point2D point = new Point2D(c.getX(), c.getY()); Point2D closest = GeometryTools2D.getClosestPointOnSegment(line, point); c.setX(closest.getX()); c.setY(closest.getY()); node.setCoordinates(c); editor.getViewer().repaint(); } private void split() { if (node == null || edge == null) { return; } editor.getMap().splitEdge(edge, node); editor.getMap().removeEdge(edge); editor.setChanged(); editor.getViewer().clearAllNodeDecorators(); editor.getViewer().clearAllEdgeDecorators(); editor.getViewer().repaint(); node = null; edge = null; } private class Listener implements MouseListener, MouseMotionListener { @Override public void mouseMoved(MouseEvent e) { Point p = fixEventPoint(e.getPoint()); GMLCoordinates c = editor.snap(editor.getViewer().getCoordinatesAtPoint(p.x, p.y)); update(c); } @Override public void mouseClicked(MouseEvent e) { if (e.getButton() == MouseEvent.BUTTON1) { split(); } } @Override public void mousePressed(MouseEvent e) { } @Override public void mouseReleased(MouseEvent e) { } @Override public void mouseDragged(MouseEvent e) { } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { } private Point fixEventPoint(Point p) { Insets insets = editor.getViewer().getInsets(); return new Point(p.x - insets.left, p.y - insets.top); } } }