- Timestamp:
- 2012-08-05T08:53:20+02:00 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java
r5370 r5394 177 177 mv.setVirtualNodesEnabled(Main.pref.getInteger("mappaint.node.virtual-size", 8) != 0); 178 178 drawTargetHighlight = Main.pref.getBoolean("draw.target-highlight", true); 179 cycleManager.init(); 180 virtualManager.init(); 179 181 // This is required to update the cursors when ctrl/shift/alt is pressed 180 182 try { … … 375 377 @Override 376 378 public void mousePressed(MouseEvent e) { 379 mouseDownButton = e.getButton(); 377 380 // return early 378 if (!mv.isActiveLayerVisible() || !(Boolean) this.getValue("active") || (mouseDownButton = e.getButton())!= MouseEvent.BUTTON1)381 if (!mv.isActiveLayerVisible() || !(Boolean) this.getValue("active") || mouseDownButton != MouseEvent.BUTTON1) 379 382 return; 380 383 … … 396 399 397 400 // primitives under cursor are stored in c collection 398 Collection<OsmPrimitive> c = MapView.asColl(399 mv.getNearestNodeOrWay(e.getPoint(), OsmPrimitive.isSelectablePredicate, true));400 401 determineMapMode( !c.isEmpty());401 402 OsmPrimitive nearestPrimitive = mv.getNearestNodeOrWay(e.getPoint(), OsmPrimitive.isSelectablePredicate, true); 403 404 determineMapMode(nearestPrimitive!=null); 402 405 403 406 switch(mode) { 404 407 case rotate: 405 408 case scale: 409 // if nothing was selected, select primitive under cursor for scaling or rotating 406 410 if (getCurrentDataSet().getSelected().isEmpty()) { 407 getCurrentDataSet().setSelected( c);411 getCurrentDataSet().setSelected(MapView.asColl(nearestPrimitive)); 408 412 } 409 413 … … 414 418 break; 415 419 case move: 416 if (!cancelDrawMode && c.iterator().next() instanceof Way) { 420 // also include case when some primitive is under cursor and no shift+ctrl / alt+ctrl is pressed 421 // so this is not movement, but selection on primitive under cursor 422 if (!cancelDrawMode && nearestPrimitive instanceof Way) { 417 423 virtualManager.setupVirtual(e.getPoint()); 418 424 } 419 420 selectPrims(cycleManager.cycleSetup(c, e.getPoint()), false, false); 425 selectPrims(cycleManager.cycleSetup(nearestPrimitive, e.getPoint()), false, false); 421 426 break; 422 427 case select: 423 428 default: 429 // start working with rectangle or lasso 424 430 selectionManager.register(mv, lassoMode); 425 431 selectionManager.mousePressed(e); … … 453 459 if (!mv.isActiveLayerVisible()) 454 460 return; 455 461 456 462 // Swing sends random mouseDragged events when closing dialogs by double-clicking their top-left icon on Windows 457 463 // Ignore such false events to prevent issues like #7078 458 464 if (mouseDownButton == MouseEvent.BUTTON1 && mouseReleaseTime > mouseDownTime) 459 465 return; 460 466 461 467 cancelDrawMode = true; 462 468 if (mode == Mode.select) … … 827 833 private boolean cyclePrims = false; 828 834 private OsmPrimitive cycleStart = null; 829 835 private boolean waitForMouseUpParameter; 836 private boolean multipleMatchesParameter; 830 837 /** 831 * 832 * @param osm nearest primitive found by simple method 833 * @param e 834 * @return 838 * read preferences 835 839 */ 836 private Collection<OsmPrimitive> cycleSetup(Collection<OsmPrimitive> single, Point p) { 840 private void init() { 841 waitForMouseUpParameter = Main.pref.getBoolean("mappaint.select.waits-for-mouse-up", false); 842 multipleMatchesParameter = Main.pref.getBoolean("selectaction.cycles.multiple.matches", false); 843 } 844 845 /** 846 * Determine prmitive to be selected and build cycleList 847 * @param nearest primitive found by simple method 848 * @param p point where user clicked 849 * @return single-element collection with OsmPrimitive to be selected 850 */ 851 private Collection<OsmPrimitive> cycleSetup(OsmPrimitive nearest, Point p) { 837 852 OsmPrimitive osm = null; 838 853 839 if ( single != null && !single.isEmpty()) {840 osm = single.iterator().next();854 if (nearest != null) { 855 osm = nearest; 841 856 842 857 // Point p = e.getPoint(); 843 boolean waitForMouseUp = Main.pref.getBoolean("mappaint.select.waits-for-mouse-up", false);844 858 // updateKeyModifiers(e); // cycleSetup called only after updateModifiers ! 845 alt = alt || Main.pref.getBoolean("selectaction.cycles.multiple.matches", false);846 847 if (!alt) {859 860 if (!(alt || multipleMatchesParameter)) { 861 // no real cycling, just one element in cycle list 848 862 cycleList = MapView.asColl(osm); 849 863 850 if (waitForMouseUp ) {864 if (waitForMouseUpParameter) { 851 865 // prefer a selected nearest node or way, if possible 852 866 osm = mv.getNearestNodeOrWay(p, OsmPrimitive.isSelectablePredicate, true); 853 867 } 854 868 } else { 869 // Alt + left mouse button pressed: we need to build cycle list 855 870 cycleList = mv.getAllNearest(p, OsmPrimitive.isSelectablePredicate); 856 871 … … 858 873 cyclePrims = false; 859 874 875 // find first already selected element in cycle list 860 876 OsmPrimitive old = osm; 861 877 for (OsmPrimitive o : cycleList) { … … 869 885 // special case: for cycle groups of 2, we can toggle to the 870 886 // true nearest primitive on mousePressed right away 871 if (cycleList.size() == 2 && !waitForMouseUp ) {887 if (cycleList.size() == 2 && !waitForMouseUpParameter) { 872 888 if (!(osm.equals(old) || osm.isNew() || ctrl)) { 873 889 cyclePrims = false; … … 891 907 * Modifies current selection state and returns the next element in a 892 908 * selection cycle given by 893 * <code>prims</code>. 894 * 895 * @param prims the primitives that form the selection cycle 896 * @param mouse event 909 * <code>cycleList</code> field 897 910 * @return the next element of cycle list 898 * <code>prims</code>.899 911 */ 900 912 private Collection<OsmPrimitive> cyclePrims() { 901 Collection<OsmPrimitive> prims = cycleList;902 913 OsmPrimitive nxt = null; 903 914 904 if (prims.size() > 1) { 905 // updateKeyModifiers(e); // already called before ! 906 907 DataSet ds = getCurrentDataSet(); 908 OsmPrimitive first = prims.iterator().next(), foundInDS = null; 909 nxt = first; 910 911 for (Iterator<OsmPrimitive> i = prims.iterator(); i.hasNext();) { 912 if (cyclePrims && shift) { 913 if (!(nxt = i.next()).isSelected()) { 914 break; // take first primitive in prims list not in sel 915 } 916 } else { 917 if ((nxt = i.next()).isSelected()) { 918 foundInDS = nxt; 919 if (cyclePrims || ctrl) { 920 ds.clearSelection(foundInDS); 921 nxt = i.hasNext() ? i.next() : first; 922 } 923 break; // take next primitive in prims list 924 } 915 if (cycleList.size() <= 1) { 916 // no real cycling, just return one-element collection with nearest primitive in it 917 return cycleList; 918 } 919 // updateKeyModifiers(e); // already called before ! 920 921 DataSet ds = getCurrentDataSet(); 922 OsmPrimitive first = cycleList.iterator().next(), foundInDS = null; 923 nxt = first; 924 925 if (cyclePrims && shift) { 926 for (Iterator<OsmPrimitive> i = cycleList.iterator(); i.hasNext();) { 927 nxt = i.next(); 928 if (!nxt.isSelected()) { 929 break; // take first primitive in cycleList not in sel 925 930 } 926 931 } 927 928 if (ctrl){929 // a member of prims was found in the current dataset selection930 if (foundInDS != null) {931 // mouse was moved to a different selection group w/ a previous sel932 if (!prims.contains(cycleStart)) {933 ds.clearSelection(prims);934 cycleStart = foundInDS;935 } else if (cycleStart.equals(nxt)) {936 // loop detected, insert deselect step937 ds.addSelected(nxt);932 // if primitives 1,2,3 are under cursor, [Alt-press] [Shift-release] gives 1 -> 12 -> 123 933 } else { 934 for (Iterator<OsmPrimitive> i = cycleList.iterator(); i.hasNext();) { 935 nxt = i.next(); 936 if (nxt.isSelected()) { 937 foundInDS = nxt; 938 // first selected primitive in cycleList is found 939 if (cyclePrims || ctrl) { 940 ds.clearSelection(foundInDS); // deselect it 941 nxt = i.hasNext() ? i.next() : first; 942 // return next one in cycle list (last->first) 938 943 } 939 } else { 940 // setup for iterating a sel group again or a new, different one.. 941 nxt = (prims.contains(cycleStart)) ? cycleStart : first; 942 cycleStart = nxt; 944 break; // take next primitive in cycleList 945 } 946 } 947 } 948 949 // if "no-alt-cycling" is enabled, Ctrl-Click arrives here. 950 if (ctrl) { 951 // a member of cycleList was found in the current dataset selection 952 if (foundInDS != null) { 953 // mouse was moved to a different selection group w/ a previous sel 954 if (!cycleList.contains(cycleStart)) { 955 ds.clearSelection(cycleList); 956 cycleStart = foundInDS; 957 } else if (cycleStart.equals(nxt)) { 958 // loop detected, insert deselect step 959 ds.addSelected(nxt); 943 960 } 944 961 } else { 945 cycleStart = null; 962 // setup for iterating a sel group again or a new, different one.. 963 nxt = (cycleList.contains(cycleStart)) ? cycleStart : first; 964 cycleStart = nxt; 946 965 } 947 } 948 949 // pass on prims, if it had less than 2 elements 950 return (nxt != null) ? MapView.asColl(nxt) : prims; 966 } else { 967 cycleStart = null; 968 } 969 // return one-element collection with one element to be selected (or added to selection) 970 return MapView.asColl(nxt); 951 971 } 952 972 } … … 956 976 private Node virtualNode = null; 957 977 private Collection<WaySegment> virtualWays = new LinkedList<WaySegment>(); 958 978 private int nodeVirtualSize; 979 private int virtualSnapDistSq2; 980 private int virtualSpace; 981 982 private void init() { 983 nodeVirtualSize = Main.pref.getInteger("mappaint.node.virtual-size", 8); 984 int virtualSnapDistSq = Main.pref.getInteger("mappaint.node.virtual-snap-distance", 8); 985 virtualSnapDistSq2 = virtualSnapDistSq*virtualSnapDistSq; 986 virtualSpace = Main.pref.getInteger("mappaint.node.virtual-space", 70); 987 } 988 959 989 /** 960 990 * Calculate a virtual node if there is enough visual space to draw a … … 969 999 */ 970 1000 private boolean setupVirtual(Point p) { 971 if (Main.pref.getInteger("mappaint.node.virtual-size", 8) > 0) { 972 int virtualSnapDistSq = Main.pref.getInteger("mappaint.node.virtual-snap-distance", 8); 973 int virtualSpace = Main.pref.getInteger("mappaint.node.virtual-space", 70); 974 virtualSnapDistSq *= virtualSnapDistSq; 975 1001 if (nodeVirtualSize > 0) { 1002 976 1003 Collection<WaySegment> selVirtualWays = new LinkedList<WaySegment>(); 977 1004 Pair<Node, Node> vnp = null, wnp = new Pair<Node, Node>(null, null); … … 985 1012 if (WireframeMapRenderer.isLargeSegment(p1, p2, virtualSpace)) { 986 1013 Point2D pc = new Point2D.Double((p1.getX() + p2.getX()) / 2, (p1.getY() + p2.getY()) / 2); 987 if (p.distanceSq(pc) < virtualSnapDistSq ) {1014 if (p.distanceSq(pc) < virtualSnapDistSq2) { 988 1015 // Check that only segments on top of each other get added to the 989 1016 // virtual ways list. Otherwise ways that coincidentally have their
Note:
See TracChangeset
for help on using the changeset viewer.