package gis2.scenario; 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.FilledShapeDecorator; import maps.gml.GMLRoad; import maps.gml.GMLBuilding; import maps.gml.GMLSpace; import maps.gml.GMLShape; import maps.gml.GMLCoordinates; /** Abstract base class for tools that operate on GML shapes. */ public abstract class ShapeTool extends AbstractTool { private static final Color HIGHLIGHT_COLOUR = new Color(0, 0, 255, 128); private Listener listener; private FilledShapeDecorator highlight; private GMLShape highlightShape; /** Construct a ShapeTool. @param editor The editor instance. */ public ShapeTool(ScenarioEditor editor) { super(editor); listener = new Listener(); highlight = new FilledShapeDecorator(HIGHLIGHT_COLOUR, HIGHLIGHT_COLOUR, HIGHLIGHT_COLOUR); } @Override public void activate() { editor.getViewer().addMouseListener(listener); editor.getViewer().addMouseMotionListener(listener); highlightShape = null; } @Override public void deactivate() { editor.getViewer().removeMouseListener(listener); editor.getViewer().removeMouseMotionListener(listener); editor.getViewer().clearAllBuildingDecorators(); editor.getViewer().clearAllRoadDecorators(); editor.getViewer().clearAllSpaceDecorators(); editor.getViewer().repaint(); } /** Handle a click on a shape. @param shape The shape that was clicked. */ protected abstract void processClick(GMLShape shape); /** Find out if a shape should be highlighted or not. Only highlighted shapes can be clicked. @param shape The shape to check. @return True if the shape should be highlighted, false otherwise. */ protected abstract boolean shouldHighlight(GMLShape shape); private void highlight(GMLShape newShape) { if (!shouldHighlight(newShape)) { return; } if (highlightShape == newShape) { return; } if (highlightShape != null) { if (highlightShape instanceof GMLBuilding) { editor.getViewer().clearBuildingDecorator((GMLBuilding)highlightShape); } if (highlightShape instanceof GMLRoad) { editor.getViewer().clearRoadDecorator((GMLRoad)highlightShape); } if (highlightShape instanceof GMLSpace) { editor.getViewer().clearSpaceDecorator((GMLSpace)highlightShape); } } highlightShape = newShape; if (highlightShape != null) { if (highlightShape instanceof GMLBuilding) { editor.getViewer().setBuildingDecorator(highlight, (GMLBuilding)highlightShape); } if (highlightShape instanceof GMLRoad) { editor.getViewer().setRoadDecorator(highlight, (GMLRoad)highlightShape); } if (highlightShape instanceof GMLSpace) { editor.getViewer().setSpaceDecorator(highlight, (GMLSpace)highlightShape); } } editor.getViewer().repaint(); } private class Listener implements MouseListener, MouseMotionListener { @Override public void mouseClicked(MouseEvent e) { if (highlightShape != null && e.getButton() == MouseEvent.BUTTON1) { processClick(highlightShape); } } @Override public void mouseMoved(MouseEvent e) { Point p = fixEventPoint(e.getPoint()); GMLCoordinates c = editor.getViewer().getCoordinatesAtPoint(p.x, p.y); highlight(editor.getMap().findShapeUnder(c.getX(), c.getY())); } @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); } } }