Changeset 10869 in josm
- Timestamp:
- 2016-08-21T23:15:36+02:00 (8 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/mapmode/ParallelWayAction.java
r10853 r10869 14 14 import java.awt.event.MouseEvent; 15 15 import java.util.Collection; 16 import java.util.Collections; 17 import java.util.EnumMap; 18 import java.util.EnumSet; 16 19 import java.util.LinkedHashSet; 20 import java.util.Map; 21 import java.util.Optional; 17 22 import java.util.Set; 23 import java.util.stream.Stream; 18 24 19 25 import javax.swing.JOptionPane; … … 21 27 import org.openstreetmap.josm.Main; 22 28 import org.openstreetmap.josm.data.Bounds; 23 import org.openstreetmap.josm.data.Preferences.PreferenceChangeEvent;24 29 import org.openstreetmap.josm.data.SystemOfMeasurement; 25 30 import org.openstreetmap.josm.data.coor.EastNorth; … … 28 33 import org.openstreetmap.josm.data.osm.Way; 29 34 import org.openstreetmap.josm.data.osm.WaySegment; 35 import org.openstreetmap.josm.data.osm.visitor.paint.MapPath2D; 30 36 import org.openstreetmap.josm.data.osm.visitor.paint.PaintColors; 37 import org.openstreetmap.josm.data.preferences.AbstractToStringProperty; 38 import org.openstreetmap.josm.data.preferences.BooleanProperty; 39 import org.openstreetmap.josm.data.preferences.CachingProperty; 31 40 import org.openstreetmap.josm.data.preferences.ColorProperty; 41 import org.openstreetmap.josm.data.preferences.DoubleProperty; 42 import org.openstreetmap.josm.data.preferences.IntegerProperty; 43 import org.openstreetmap.josm.data.preferences.StringProperty; 32 44 import org.openstreetmap.josm.gui.MapFrame; 33 45 import org.openstreetmap.josm.gui.MapView; … … 38 50 import org.openstreetmap.josm.gui.util.GuiHelper; 39 51 import org.openstreetmap.josm.gui.util.ModifierListener; 52 import org.openstreetmap.josm.tools.CheckParameterUtil; 40 53 import org.openstreetmap.josm.tools.Geometry; 41 54 import org.openstreetmap.josm.tools.ImageProvider; … … 80 93 */ 81 94 public class ParallelWayAction extends MapMode implements ModifierListener, MapViewPaintable { 95 96 private static final StringProperty HELPER_LINE_STROKE = new StringProperty(prefKey("stroke.hepler-line"), "1"); 97 private static final StringProperty REF_LINE_STROKE = new StringProperty(prefKey("stroke.ref-line"), "1 2 2"); 98 99 // @formatter:off 100 // CHECKSTYLE.OFF: SingleSpaceSeparator 101 private static final CachingProperty<Double> SNAP_THRESHOLD = new DoubleProperty(prefKey("snap-threshold-percent"), 0.70).cached(); 102 private static final CachingProperty<Boolean> SNAP_DEFAULT = new BooleanProperty(prefKey("snap-default"), true).cached(); 103 private static final CachingProperty<Boolean> COPY_TAGS_DEFAULT = new BooleanProperty(prefKey("copy-tags-default"), true).cached(); 104 private static final CachingProperty<Integer> INITIAL_MOVE_DELAY = new IntegerProperty(prefKey("initial-move-delay"), 200).cached(); 105 private static final CachingProperty<Double> SNAP_DISTANCE_METRIC = new DoubleProperty(prefKey("snap-distance-metric"), 0.5).cached(); 106 private static final CachingProperty<Double> SNAP_DISTANCE_IMPERIAL = new DoubleProperty(prefKey("snap-distance-imperial"), 1).cached(); 107 private static final CachingProperty<Double> SNAP_DISTANCE_CHINESE = new DoubleProperty(prefKey("snap-distance-chinese"), 1).cached(); 108 private static final CachingProperty<Double> SNAP_DISTANCE_NAUTICAL = new DoubleProperty(prefKey("snap-distance-nautical"), 0.1).cached(); 109 private static final CachingProperty<Color> MAIN_COLOR = new ColorProperty(marktr("make parallel helper line"), (Color) null).cached(); 110 111 private static final CachingProperty<Map<Modifier, Boolean>> SNAP_MODIFIER_COMBO 112 = new KeyboardModifiersProperty(prefKey("snap-modifier-combo"), "?sC").cached(); 113 private static final CachingProperty<Map<Modifier, Boolean>> COPY_TAGS_MODIFIER_COMBO 114 = new KeyboardModifiersProperty(prefKey("copy-tags-modifier-combo"), "As?").cached(); 115 private static final CachingProperty<Map<Modifier, Boolean>> ADD_TO_SELECTION_MODIFIER_COMBO 116 = new KeyboardModifiersProperty(prefKey("add-to-selection-modifier-combo"), "aSc").cached(); 117 private static final CachingProperty<Map<Modifier, Boolean>> TOGGLE_SELECTED_MODIFIER_COMBO 118 = new KeyboardModifiersProperty(prefKey("toggle-selection-modifier-combo"), "asC").cached(); 119 private static final CachingProperty<Map<Modifier, Boolean>> SET_SELECTED_MODIFIER_COMBO 120 = new KeyboardModifiersProperty(prefKey("set-selection-modifier-combo"), "asc").cached(); 121 // CHECKSTYLE.ON: SingleSpaceSeparator 122 // @formatter:on 82 123 83 124 private enum Mode { … … 89 130 private Mode mode; 90 131 private boolean copyTags; 91 private boolean copyTagsDefault;92 132 93 133 private boolean snap; 94 private boolean snapDefault;95 96 private double snapThreshold;97 private double snapDistanceMetric;98 private double snapDistanceImperial;99 private double snapDistanceChinese;100 private double snapDistanceNautical;101 102 private transient ModifiersSpec snapModifierCombo;103 private transient ModifiersSpec copyTagsModifierCombo;104 private transient ModifiersSpec addToSelectionModifierCombo;105 private transient ModifiersSpec toggleSelectedModifierCombo;106 private transient ModifiersSpec setSelectedModifierCombo;107 108 private int initialMoveDelay;109 134 110 135 private final MapView mv; … … 124 149 private transient Stroke helpLineStroke; 125 150 private transient Stroke refLineStroke; 126 private Color mainColor;127 151 128 152 /** … … 137 161 putValue("help", ht("/Action/Parallel")); 138 162 mv = mapFrame.mapView; 139 updateModeLocalPreferences();140 Main.pref.addPreferenceChangeListener(this);141 163 } 142 164 … … 146 168 setMode(Mode.NORMAL); 147 169 pWays = null; 148 updateAllPreferences(); // All default values should've been set now149 170 150 171 super.enterMode(); … … 154 175 mv.addTemporaryLayer(this); 155 176 156 helpLineStroke = GuiHelper.getCustomizedStroke(getStringPref("stroke.hepler-line", "1")); 157 refLineStroke = GuiHelper.getCustomizedStroke(getStringPref("stroke.ref-line", "1 2 2")); 158 mainColor = new ColorProperty(marktr("make parallel helper line"), (Color) null).get(); 159 if (mainColor == null) 160 mainColor = PaintColors.SELECTED.get(); 177 helpLineStroke = GuiHelper.getCustomizedStroke(HELPER_LINE_STROKE.get()); 178 refLineStroke = GuiHelper.getCustomizedStroke(REF_LINE_STROKE.get()); 161 179 162 180 //// Needed to update the mouse cursor if modifiers are changed when the mouse is motionless … … 200 218 } 201 219 202 // Separated due to "race condition" between default values203 private void updateAllPreferences() {204 updateModeLocalPreferences();205 }206 207 private void updateModeLocalPreferences() {208 // @formatter:off209 // CHECKSTYLE.OFF: SingleSpaceSeparator210 snapThreshold = Main.pref.getDouble(prefKey("snap-threshold-percent"), 0.70);211 snapDefault = Main.pref.getBoolean(prefKey("snap-default"), true);212 copyTagsDefault = Main.pref.getBoolean(prefKey("copy-tags-default"), true);213 initialMoveDelay = Main.pref.getInteger(prefKey("initial-move-delay"), 200);214 snapDistanceMetric = Main.pref.getDouble(prefKey("snap-distance-metric"), 0.5);215 snapDistanceImperial = Main.pref.getDouble(prefKey("snap-distance-imperial"), 1);216 snapDistanceChinese = Main.pref.getDouble(prefKey("snap-distance-chinese"), 1);217 snapDistanceNautical = Main.pref.getDouble(prefKey("snap-distance-nautical"), 0.1);218 219 snapModifierCombo = new ModifiersSpec(getStringPref("snap-modifier-combo", "?sC"));220 copyTagsModifierCombo = new ModifiersSpec(getStringPref("copy-tags-modifier-combo", "As?"));221 addToSelectionModifierCombo = new ModifiersSpec(getStringPref("add-to-selection-modifier-combo", "aSc"));222 toggleSelectedModifierCombo = new ModifiersSpec(getStringPref("toggle-selection-modifier-combo", "asC"));223 setSelectedModifierCombo = new ModifiersSpec(getStringPref("set-selection-modifier-combo", "asc"));224 // CHECKSTYLE.ON: SingleSpaceSeparator225 // @formatter:on226 }227 228 220 @Override 229 221 public boolean layerIsSupported(Layer layer) { … … 253 245 switch (mode) { 254 246 case NORMAL: 255 if (matchesCurrentModifiers( setSelectedModifierCombo)) {247 if (matchesCurrentModifiers(SET_SELECTED_MODIFIER_COMBO)) { 256 248 newCursor = ImageProvider.getCursor("normal", "parallel"); 257 } else if (matchesCurrentModifiers( addToSelectionModifierCombo)) {249 } else if (matchesCurrentModifiers(ADD_TO_SELECTION_MODIFIER_COMBO)) { 258 250 newCursor = ImageProvider.getCursor("normal", "parallel_add"); 259 } else if (matchesCurrentModifiers( toggleSelectedModifierCombo)) {251 } else if (matchesCurrentModifiers(TOGGLE_SELECTED_MODIFIER_COMBO)) { 260 252 newCursor = ImageProvider.getCursor("normal", "parallel_remove"); 261 253 } … … 325 317 Way nearestWay = mv.getNearestWay(e.getPoint(), OsmPrimitive::isSelectable); 326 318 if (nearestWay == null) { 327 if (matchesCurrentModifiers( setSelectedModifierCombo)) {319 if (matchesCurrentModifiers(SET_SELECTED_MODIFIER_COMBO)) { 328 320 clearSourceWays(); 329 321 } … … 332 324 } 333 325 boolean isSelected = nearestWay.isSelected(); 334 if (matchesCurrentModifiers( addToSelectionModifierCombo)) {326 if (matchesCurrentModifiers(ADD_TO_SELECTION_MODIFIER_COMBO)) { 335 327 if (!isSelected) { 336 328 addSourceWay(nearestWay); 337 329 } 338 } else if (matchesCurrentModifiers( toggleSelectedModifierCombo)) {330 } else if (matchesCurrentModifiers(TOGGLE_SELECTED_MODIFIER_COMBO)) { 339 331 if (isSelected) { 340 332 removeSourceWay(nearestWay); … … 342 334 addSourceWay(nearestWay); 343 335 } 344 } else if (matchesCurrentModifiers( setSelectedModifierCombo)) {336 } else if (matchesCurrentModifiers(SET_SELECTED_MODIFIER_COMBO)) { 345 337 clearSourceWays(); 346 338 addSourceWay(nearestWay); … … 380 372 } 381 373 382 if ((System.currentTimeMillis() - mousePressedTime) < initialMoveDelay)374 if ((System.currentTimeMillis() - mousePressedTime) < INITIAL_MOVE_DELAY.get()) 383 375 return; 384 376 // Assuming this event only is emitted when the mouse has moved … … 409 401 double snappedRealD = realD; 410 402 411 // TODO: abuse of isToTheRightSideOfLine function. 412 boolean toTheRight = Geometry.isToTheRightSideOfLine(referenceSegment.getFirstNode(), 403 boolean toTheRight = Geometry.angleIsClockwise( 413 404 referenceSegment.getFirstNode(), referenceSegment.getSecondNode(), new Node(enp)); 414 405 … … 419 410 SystemOfMeasurement som = SystemOfMeasurement.getSystemOfMeasurement(); 420 411 if (som.equals(SystemOfMeasurement.CHINESE)) { 421 snapDistance = snapDistanceChinese* SystemOfMeasurement.CHINESE.aValue;412 snapDistance = SNAP_DISTANCE_CHINESE.get() * SystemOfMeasurement.CHINESE.aValue; 422 413 } else if (som.equals(SystemOfMeasurement.IMPERIAL)) { 423 snapDistance = snapDistanceImperial* SystemOfMeasurement.IMPERIAL.aValue;414 snapDistance = SNAP_DISTANCE_IMPERIAL.get() * SystemOfMeasurement.IMPERIAL.aValue; 424 415 } else if (som.equals(SystemOfMeasurement.NAUTICAL_MILE)) { 425 snapDistance = snapDistanceNautical* SystemOfMeasurement.NAUTICAL_MILE.aValue;416 snapDistance = SNAP_DISTANCE_NAUTICAL.get() * SystemOfMeasurement.NAUTICAL_MILE.aValue; 426 417 } else { 427 snapDistance = snapDistanceMetric; // Metric system by default418 snapDistance = SNAP_DISTANCE_METRIC.get(); // Metric system by default 428 419 } 429 420 double closestWholeUnit; … … 434 425 closestWholeUnit = realD + (snapDistance-modulo); 435 426 } 436 if (Math.abs(closestWholeUnit - realD) < ( snapThreshold* snapDistance)) {427 if (Math.abs(closestWholeUnit - realD) < (SNAP_THRESHOLD.get() * snapDistance)) { 437 428 snappedRealD = closestWholeUnit; 438 429 } else { … … 453 444 } 454 445 455 private boolean matchesCurrentModifiers(ModifiersSpec spec) { 456 return spec.matchWithKnown(alt, shift, ctrl); 446 private boolean matchesCurrentModifiers(CachingProperty<Map<Modifier, Boolean>> spec) { 447 return matchesCurrentModifiers(spec.get()); 448 } 449 450 private boolean matchesCurrentModifiers(Map<Modifier, Boolean> spec) { 451 EnumSet<Modifier> modifiers = EnumSet.noneOf(Modifier.class); 452 if (ctrl) { 453 modifiers.add(Modifier.CTRL); 454 } 455 if (alt) { 456 modifiers.add(Modifier.ALT); 457 } 458 if (shift) { 459 modifiers.add(Modifier.SHIFT); 460 } 461 return spec.entrySet().stream().allMatch(entry -> modifiers.contains(entry.getKey()) == entry.getValue().booleanValue()); 457 462 } 458 463 … … 460 465 public void paint(Graphics2D g, MapView mv, Bounds bbox) { 461 466 if (mode == Mode.DRAGGING) { 462 // sanity checks 463 if (mv == null) 464 return; 467 CheckParameterUtil.ensureParameterNotNull(mv, "mv"); 468 469 Color mainColor = MAIN_COLOR.get(); 470 if (mainColor == null) { 471 mainColor = PaintColors.SELECTED.get(); 472 } 465 473 466 474 // FIXME: should clip the line (gets insanely slow when zoomed in on a very long line 467 475 g.setStroke(refLineStroke); 468 476 g.setColor(mainColor); 469 Point p1 = mv.getPoint(referenceSegment.getFirstNode().getEastNorth()); 470 Point p2 = mv.getPoint(referenceSegment.getSecondNode().getEastNorth()); 471 g.drawLine(p1.x, p1.y, p2.x, p2.y); 477 MapPath2D line = new MapPath2D(); 478 line.moveTo(mv.getState().getPointFor(referenceSegment.getFirstNode())); 479 line.lineTo(mv.getState().getPointFor(referenceSegment.getSecondNode())); 480 g.draw(line); 472 481 473 482 g.setStroke(helpLineStroke); 474 483 g.setColor(mainColor); 475 p1 = mv.getPoint(helperLineStart); 476 p2 = mv.getPoint(helperLineEnd); 477 g.drawLine(p1.x, p1.y, p2.x, p2.y); 484 line = new MapPath2D(); 485 line.moveTo(mv.getState().getPointFor(helperLineStart)); 486 line.lineTo(mv.getState().getPointFor(helperLineEnd)); 487 g.draw(line); 478 488 } 479 489 } 480 490 481 491 private boolean isModifiersValidForDragMode() { 482 return (!alt && !shift && !ctrl) || matchesCurrentModifiers( snapModifierCombo)483 || matchesCurrentModifiers( copyTagsModifierCombo);492 return (!alt && !shift && !ctrl) || matchesCurrentModifiers(SNAP_MODIFIER_COMBO) 493 || matchesCurrentModifiers(COPY_TAGS_MODIFIER_COMBO); 484 494 } 485 495 486 496 private void updateFlagsOnlyChangeableOnPress() { 487 copyTags = copyTagsDefault != matchesCurrentModifiers(copyTagsModifierCombo);497 copyTags = COPY_TAGS_DEFAULT.get().booleanValue() != matchesCurrentModifiers(COPY_TAGS_MODIFIER_COMBO); 488 498 } 489 499 490 500 private void updateFlagsChangeableAlways() { 491 snap = snapDefault != matchesCurrentModifiers(snapModifierCombo);501 snap = SNAP_DEFAULT.get().booleanValue() != matchesCurrentModifiers(SNAP_MODIFIER_COMBO); 492 502 } 493 503 … … 564 574 } 565 575 566 private static String getStringPref(String subKey, String def) { 567 return Main.pref.get(prefKey(subKey), def); 568 } 569 570 @Override 571 public void preferenceChanged(PreferenceChangeEvent e) { 572 if (e.getKey().startsWith(prefKey(""))) { 573 updateAllPreferences(); 574 } 575 } 576 577 @Override 578 public void destroy() { 579 super.destroy(); 580 Main.pref.removePreferenceChangeListener(this); 576 /** 577 * A property that holds the keyboard modifiers. 578 * @author Michael Zangl 579 * @since 10869 580 */ 581 private static class KeyboardModifiersProperty extends AbstractToStringProperty<Map<Modifier, Boolean>> { 582 583 KeyboardModifiersProperty(String key, String defaultValue) { 584 super(key, createFromString(defaultValue)); 585 } 586 587 KeyboardModifiersProperty(String key, Map<Modifier, Boolean> defaultValue) { 588 super(key, defaultValue); 589 } 590 591 @Override 592 protected String toString(Map<Modifier, Boolean> t) { 593 StringBuilder sb = new StringBuilder(); 594 for (Modifier mod : Modifier.values()) { 595 Boolean val = t.get(mod); 596 if (val == null) { 597 sb.append('?'); 598 } else if (val) { 599 sb.append(Character.toUpperCase(mod.shortChar)); 600 } else { 601 sb.append(mod.shortChar); 602 } 603 } 604 return sb.toString(); 605 } 606 607 @Override 608 protected Map<Modifier, Boolean> fromString(String string) { 609 return createFromString(string); 610 } 611 612 private static Map<Modifier, Boolean> createFromString(String string) { 613 Map<Modifier, Boolean> ret = new EnumMap<>(Modifier.class); 614 for (char c : string.toCharArray()) { 615 if (c == '?') { 616 continue; 617 } 618 Optional<Modifier> mod = Modifier.findWithShortCode(c); 619 if (mod.isPresent()) { 620 ret.put(mod.get(), Character.isUpperCase(c)); 621 } else { 622 Main.debug("Ignoring unknown modifier {0}", c); 623 } 624 } 625 return Collections.unmodifiableMap(ret); 626 } 627 } 628 629 private enum Modifier { 630 CTRL('c'), 631 ALT('a'), 632 SHIFT('s'); 633 634 private final char shortChar; 635 636 Modifier(char shortChar) { 637 this.shortChar = Character.toLowerCase(shortChar); 638 } 639 640 /** 641 * Find the modifier with the given short code 642 * @param charCode The short code 643 * @return The modifier 644 */ 645 public static Optional<Modifier> findWithShortCode(int charCode) { 646 return Stream.of(values()).filter(m -> m.shortChar == Character.toLowerCase(charCode)).findAny(); 647 } 581 648 } 582 649 } -
trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/PaintColors.java
r10824 r10869 61 61 } 62 62 63 /** 64 * Gets the default value for this color. 65 * @return The default value 66 */ 63 67 public Color getDefaultValue() { 64 68 return property.getDefaultValue(); 65 69 } 66 70 71 /** 72 * Get the given color 73 * @return The color 74 */ 67 75 public Color get() { 68 76 return property.get();
Note:
See TracChangeset
for help on using the changeset viewer.