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.GMLNode; import maps.gml.GMLCoordinates; /** A tool for merging nodes. */ public class MergeNodesTool extends AbstractTool { private static final Color HOVER_COLOUR = Color.BLUE; private static final Color MERGE_COLOUR = Color.RED; private static final int HIGHLIGHT_SIZE = 6; private Listener listener; private NodeDecorator hoverHighlight; private NodeDecorator mergeHighlight; private GMLNode hover; private GMLNode merge; private boolean merging; /** Construct a MergeNodesTool. @param editor The editor instance. */ public MergeNodesTool(GMLEditor editor) { super(editor); listener = new Listener(); hoverHighlight = new SquareNodeDecorator(HOVER_COLOUR, HIGHLIGHT_SIZE); mergeHighlight = new SquareNodeDecorator(MERGE_COLOUR, HIGHLIGHT_SIZE); } @Override public String getName() { return "Merge nodes"; } @Override public void activate() { editor.getViewer().addMouseListener(listener); editor.getViewer().addMouseMotionListener(listener); hover = null; merge = null; merging = false; } @Override public void deactivate() { editor.getViewer().removeMouseListener(listener); editor.getViewer().removeMouseMotionListener(listener); editor.getViewer().clearAllNodeDecorators(); editor.getViewer().repaint(); } private void hover(GMLNode node) { if (hover == node) { return; } if (hover != null) { editor.getViewer().clearNodeDecorator(hover); } hover = node; if (hover != null) { editor.getViewer().setNodeDecorator(hoverHighlight, hover); } editor.getViewer().repaint(); } private void setMerge(GMLNode node) { if (merge == node) { return; } if (node == hover) { return; } if (merge != null) { editor.getViewer().clearNodeDecorator(merge); } merge = node; if (merge != null) { editor.getViewer().setNodeDecorator(mergeHighlight, merge); } editor.getViewer().repaint(); } private class Listener implements MouseListener, MouseMotionListener { @Override public void mouseMoved(MouseEvent e) { Point p = fixEventPoint(e.getPoint()); GMLCoordinates c = editor.getViewer().getCoordinatesAtPoint(p.x, p.y); GMLNode node = editor.getMap().findNearestNode(c.getX(), c.getY()); hover(node); } @Override public void mouseDragged(MouseEvent e) { if (hover == null) { return; } if (!merging) { return; } Point p = fixEventPoint(e.getPoint()); GMLCoordinates c = editor.getViewer().getCoordinatesAtPoint(p.x, p.y); GMLNode node = editor.getMap().findNearestNode(c.getX(), c.getY()); setMerge(node); } @Override public void mouseReleased(MouseEvent e) { if (e.getButton() == MouseEvent.BUTTON1) { if (merging) { if (hover != null && merge != null) { editor.getMap().replaceNode(hover, merge); editor.getMap().removeNode(hover); editor.setChanged(); } if (hover != null) { editor.getViewer().clearNodeDecorator(hover); } if (merge != null) { editor.getViewer().clearNodeDecorator(merge); } editor.getViewer().repaint(); hover = null; merge = null; merging = false; } } } @Override public void mousePressed(MouseEvent e) { if (e.getButton() == MouseEvent.BUTTON1) { merging = true; } } @Override public void mouseClicked(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); } } }