diff --git a/src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyAction.java b/src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyAction.java index 2ab6d49a948..bd154e650c8 100644 --- a/src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyAction.java +++ b/src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyAction.java @@ -74,53 +74,56 @@ */ public class ImproveWayAccuracyAction extends MapMode implements DataSelectionListener, DataSetListener, ModifierExListener { - private static final String CROSSHAIR = /* ICON(cursor/)*/ "crosshair"; + protected static final String CROSSHAIR = /* ICON(cursor/)*/ "crosshair"; - enum State { + protected enum State { SELECTING, IMPROVING } - private State state; + protected State state; - private MapView mv; + protected MapView mv; - private static final long serialVersionUID = 42L; + protected static final long serialVersionUID = 42L; - private transient Way targetWay; - private transient Node candidateNode; - private transient WaySegment candidateSegment; + protected transient Way targetWay; + protected transient Node candidateNode; + protected transient WaySegment candidateSegment; - private Point mousePos; - private boolean dragging; + protected Point mousePos; + protected boolean dragging; - private final Cursor cursorSelect = ImageProvider.getCursor(/* ICON(cursor/)*/ "normal", /* ICON(cursor/modifier/)*/ "mode"); - private final Cursor cursorSelectHover = ImageProvider.getCursor(/* ICON(cursor/)*/ "hand", /* ICON(cursor/modifier/)*/ "mode"); - private final Cursor cursorImprove = ImageProvider.getCursor(CROSSHAIR, null); - private final Cursor cursorImproveAdd = ImageProvider.getCursor(CROSSHAIR, /* ICON(cursor/modifier/)*/ "addnode"); - private final Cursor cursorImproveDelete = ImageProvider.getCursor(CROSSHAIR, /* ICON(cursor/modifier/)*/ "delete_node"); - private final Cursor cursorImproveAddLock = ImageProvider.getCursor(CROSSHAIR, /* ICON(cursor/modifier/)*/ "add_node_lock"); - private final Cursor cursorImproveLock = ImageProvider.getCursor(CROSSHAIR, /* ICON(cursor/modifier/)*/ "lock"); + protected Node endpoint1 = null; + protected Node endpoint2 = null; - private Color guideColor; + protected final Cursor cursorSelect = ImageProvider.getCursor(/* ICON(cursor/)*/ "normal", /* ICON(cursor/modifier/)*/ "mode"); + protected final Cursor cursorSelectHover = ImageProvider.getCursor(/* ICON(cursor/)*/ "hand", /* ICON(cursor/modifier/)*/ "mode"); + protected final Cursor cursorImprove = ImageProvider.getCursor(CROSSHAIR, null); + protected final Cursor cursorImproveAdd = ImageProvider.getCursor(CROSSHAIR, /* ICON(cursor/modifier/)*/ "addnode"); + protected final Cursor cursorImproveDelete = ImageProvider.getCursor(CROSSHAIR, /* ICON(cursor/modifier/)*/ "delete_node"); + protected final Cursor cursorImproveAddLock = ImageProvider.getCursor(CROSSHAIR, /* ICON(cursor/modifier/)*/ "add_node_lock"); + protected final Cursor cursorImproveLock = ImageProvider.getCursor(CROSSHAIR, /* ICON(cursor/modifier/)*/ "lock"); - private static final CachingProperty SELECT_TARGET_WAY_STROKE + protected Color guideColor; + + protected static final CachingProperty SELECT_TARGET_WAY_STROKE = new StrokeProperty("improvewayaccuracy.stroke.select-target", "2").cached(); - private static final CachingProperty MOVE_NODE_STROKE + protected static final CachingProperty MOVE_NODE_STROKE = new StrokeProperty("improvewayaccuracy.stroke.move-node", "1 6").cached(); - private static final CachingProperty MOVE_NODE_INTERSECTING_STROKE + protected static final CachingProperty MOVE_NODE_INTERSECTING_STROKE = new StrokeProperty("improvewayaccuracy.stroke.move-node-intersecting", "1 2 6").cached(); - private static final CachingProperty ADD_NODE_STROKE + protected static final CachingProperty ADD_NODE_STROKE = new StrokeProperty("improvewayaccuracy.stroke.add-node", "1").cached(); - private static final CachingProperty DELETE_NODE_STROKE + protected static final CachingProperty DELETE_NODE_STROKE = new StrokeProperty("improvewayaccuracy.stroke.delete-node", "1").cached(); - private static final CachingProperty DOT_SIZE + protected static final CachingProperty DOT_SIZE = new IntegerProperty("improvewayaccuracy.dot-size", 6).cached(); - private boolean selectionChangedBlocked; + protected boolean selectionChangedBlocked; protected String oldModeHelpText; - private final transient AbstractMapViewPaintable temporaryLayer = new AbstractMapViewPaintable() { + protected final transient AbstractMapViewPaintable temporaryLayer = new AbstractMapViewPaintable() { @Override public void paint(Graphics2D g, MapView mv, Bounds bbox) { ImproveWayAccuracyAction.this.paint(g, mv, bbox); @@ -141,6 +144,10 @@ public ImproveWayAccuracyAction() { readPreferences(); } + protected ImproveWayAccuracyAction(String name, String iconName, String tooltip, Shortcut shortcut, Cursor cursor) { + super(name, iconName, tooltip, shortcut, cursor); + } + // ------------------------------------------------------------------------- // Mode methods // ------------------------------------------------------------------------- @@ -267,87 +274,90 @@ public void paint(Graphics2D g, MapView mv, Bounds bbox) { // Drawing preview lines and highlighting the node // that is going to be moved. // Non-native highlighting is used here as well. + MapViewPath b = new MapViewPath(mv); + findEndpoints(g); + drawPreviewLines(g, b); + highlightCandidateNode(g, mv, b); + } + } - // Finding endpoints - Node p1 = null; - Node p2 = null; - if (ctrl && candidateSegment != null) { - g.setStroke(ADD_NODE_STROKE.get()); - try { - p1 = candidateSegment.getFirstNode(); - p2 = candidateSegment.getSecondNode(); - } catch (ArrayIndexOutOfBoundsException e) { - Logging.error(e); - } - } else if (!alt && !ctrl && candidateNode != null) { - g.setStroke(MOVE_NODE_STROKE.get()); - List> wpps = targetWay.getNodePairs(false); - for (Pair wpp : wpps) { - if (wpp.a == candidateNode) { - p1 = wpp.b; - } - if (wpp.b == candidateNode) { - p2 = wpp.a; - } - if (p1 != null && p2 != null) { - break; - } - } - } else if (alt && !ctrl && candidateNode != null) { - g.setStroke(DELETE_NODE_STROKE.get()); - List nodes = targetWay.getNodes(); - int index = nodes.indexOf(candidateNode); - - // Only draw line if node is not first and/or last - if (index > 0 && index < (nodes.size() - 1)) { - p1 = nodes.get(index - 1); - p2 = nodes.get(index + 1); - } else if (targetWay.isClosed()) { - p1 = targetWay.getNode(1); - p2 = targetWay.getNode(nodes.size() - 2); - } - // TODO: indicate what part that will be deleted? (for end nodes) + protected void findEndpoints(Graphics2D g) { + endpoint1 = null; + endpoint2 = null; + if (ctrl && candidateSegment != null) { + g.setStroke(ADD_NODE_STROKE.get()); + try { + endpoint1 = candidateSegment.getFirstNode(); + endpoint2 = candidateSegment.getSecondNode(); + } catch (ArrayIndexOutOfBoundsException e) { + Logging.error(e); } - - - // Drawing preview lines - MapViewPath b = new MapViewPath(mv); - if (alt && !ctrl) { - // In delete mode - if (p1 != null && p2 != null) { - b.moveTo(p1); - b.lineTo(p2); + } else if (!alt && !ctrl && candidateNode != null) { + g.setStroke(MOVE_NODE_STROKE.get()); + List> wpps = targetWay.getNodePairs(false); + for (Pair wpp : wpps) { + if (wpp.a == candidateNode) { + endpoint1 = wpp.b; } - } else { - // In add or move mode - if (p1 != null) { - b.moveTo(mousePos.x, mousePos.y); - b.lineTo(p1); + if (wpp.b == candidateNode) { + endpoint2 = wpp.a; } - if (p2 != null) { - b.moveTo(mousePos.x, mousePos.y); - b.lineTo(p2); + if (endpoint1 != null && endpoint2 != null) { + break; } } - g.draw(b.computeClippedLine(g.getStroke())); - - // Highlighting candidateNode - if (candidateNode != null) { - p1 = candidateNode; - g.fill(new MapViewPath(mv).shapeAround(p1, SymbolShape.SQUARE, DOT_SIZE.get())); + } else if (alt && !ctrl && candidateNode != null) { + g.setStroke(DELETE_NODE_STROKE.get()); + List nodes = targetWay.getNodes(); + int index = nodes.indexOf(candidateNode); + + // Only draw line if node is not first and/or last + if (index > 0 && index < (nodes.size() - 1)) { + endpoint1 = nodes.get(index - 1); + endpoint2 = nodes.get(index + 1); + } else if (targetWay.isClosed()) { + endpoint1 = targetWay.getNode(1); + endpoint2 = targetWay.getNode(nodes.size() - 2); } + // TODO: indicate what part that will be deleted? (for end nodes) + } + } - if (!alt && !ctrl && candidateNode != null) { - b.reset(); - drawIntersectingWayHelperLines(mv, b); - g.setStroke(MOVE_NODE_INTERSECTING_STROKE.get()); - g.draw(b.computeClippedLine(g.getStroke())); + protected void drawPreviewLines(Graphics2D g, MapViewPath b) { + if (alt && !ctrl) { + // In delete mode + if (endpoint1 != null && endpoint2 != null) { + b.moveTo(endpoint1); + b.lineTo(endpoint2); + } + } else { + // In add or move mode + if (endpoint1 != null) { + b.moveTo(mousePos.x, mousePos.y); + b.lineTo(endpoint1); } + if (endpoint2 != null) { + b.moveTo(mousePos.x, mousePos.y); + b.lineTo(endpoint2); + } + } + g.draw(b.computeClippedLine(g.getStroke())); + } + protected void highlightCandidateNode(Graphics2D g, MapView mv, MapViewPath b) { + if (candidateNode != null) { + g.fill(new MapViewPath(mv).shapeAround(candidateNode, SymbolShape.SQUARE, DOT_SIZE.get())); + } + + if (!alt && !ctrl && candidateNode != null) { + b.reset(); + drawIntersectingWayHelperLines(b); + g.setStroke(MOVE_NODE_INTERSECTING_STROKE.get()); + g.draw(b.computeClippedLine(g.getStroke())); } } - protected void drawIntersectingWayHelperLines(MapView mv, MapViewPath b) { + protected void drawIntersectingWayHelperLines(MapViewPath b) { for (final OsmPrimitive referrer : candidateNode.getReferrers()) { if (!(referrer instanceof Way) || targetWay.equals(referrer)) { continue; @@ -404,8 +414,7 @@ public void mouseMoved(MouseEvent e) { return; } - mousePos = e.getPoint(); - + updateMousePosition(e); updateKeyModifiers(e); updateCursorDependentObjectsIfNeeded(); updateCursor(); @@ -422,7 +431,7 @@ public void mouseReleased(MouseEvent e) { DataSet ds = getLayerManager().getEditDataSet(); updateKeyModifiers(e); - mousePos = e.getPoint(); + updateMousePosition(e); if (state == State.SELECTING) { if (targetWay != null) { @@ -537,10 +546,19 @@ public void mouseExited(MouseEvent e) { // ------------------------------------------------------------------------- // Custom methods // ------------------------------------------------------------------------- + + /** + * Sets mouse position based on mouse event; + * this method allows extending classes to override position + */ + protected void updateMousePosition(MouseEvent e) { + mousePos = e.getPoint(); + } + /** * Sets new cursor depending on state, mouse position */ - private void updateCursor() { + protected void updateCursor() { if (!isEnabled()) { mv.setNewCursor(null, this); return; @@ -640,7 +658,7 @@ public void startImproving(Way targetWay) { * state if a single way or node is selected. Extracts a way by a node in * the second case. */ - private void updateStateByCurrentSelection() { + protected void updateStateByCurrentSelection() { final List nodeList = new ArrayList<>(); final List wayList = new ArrayList<>(); final DataSet ds = getLayerManager().getEditDataSet(); diff --git a/src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyHelper.java b/src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyHelper.java index e12f985a371..086a18c7af7 100644 --- a/src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyHelper.java +++ b/src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyHelper.java @@ -21,9 +21,9 @@ * * @author Alexander Kachkaev <alexander@kachkaev.ru>, 2011 */ -final class ImproveWayAccuracyHelper { +class ImproveWayAccuracyHelper { - private ImproveWayAccuracyHelper() { + protected ImproveWayAccuracyHelper() { // Hide default constructor for utils classes } @@ -69,8 +69,8 @@ public static Node findCandidateNode(MapView mv, Way w, Point p) { EastNorth pEN = mv.getEastNorth(p.x, p.y); - Double bestDistance = Double.MAX_VALUE; - Double currentDistance; + double bestDistance = Double.MAX_VALUE; + double currentDistance; List> wpps = w.getNodePairs(false); Node result = null; @@ -125,10 +125,10 @@ public static WaySegment findCandidateSegment(MapView mv, Way w, Point p) { EastNorth pEN = mv.getEastNorth(p.x, p.y); - Double currentDistance; - Double currentAngle; - Double bestDistance = Double.MAX_VALUE; - Double bestAngle = 0.0; + double currentDistance; + double currentAngle; + double bestDistance = Double.MAX_VALUE; + double bestAngle = 0.0; int candidate = -1;