Changeset 3550 in josm for trunk/src/org


Ignore:
Timestamp:
2010-09-19T23:43:49+02:00 (14 years ago)
Author:
bastiK
Message:

see #5457 (patch by Christian Müller) - make it easier to select ways and nodes, if there are multiple primitives under the cursor

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java

    r3523 r3550  
    1616import java.util.Collections;
    1717import java.util.HashSet;
     18import java.util.Iterator;
    1819import java.util.LinkedList;
    19 import java.util.List;
    2020import java.util.Set;
    2121import java.util.TreeSet;
     
    203203                    virtualWays.size());
    204204            Main.main.undoRedo.add(new SequenceCommand(text, virtualCmds));
    205             selectPrims(Collections.singleton((OsmPrimitive)virtualNode), false, false, false, false);
     205            getCurrentDataSet().setSelected(Collections.singleton((OsmPrimitive)virtualNode));
    206206            virtualWays.clear();
    207207            virtualNode = null;
     
    269269    }
    270270
    271     private Collection<OsmPrimitive> getNearestCollectionVirtual(Point p, boolean allSegements) {
     271    private Collection<OsmPrimitive> getNearestCollectionVirtual(Point p) {
     272        int snapDistance = Main.pref.getInteger("mappaint.node.virtual-snap-distance", 8);
     273        int virtualSpace = Main.pref.getInteger("mappaint.node.virtual-space", 70);
     274        snapDistance *= snapDistance;
     275
    272276        MapView c = Main.map.mapView;
    273         int snapDistance = Main.pref.getInteger("mappaint.node.virtual-snap-distance", 8);
    274         snapDistance *= snapDistance;
     277
     278        Collection<OsmPrimitive> sel = getCurrentDataSet().getSelected();
    275279        OsmPrimitive osm = c.getNearestNode(p, OsmPrimitive.isSelectablePredicate);
    276         virtualWays.clear();
    277         virtualNode = null;
    278         Node virtualWayNode = null;
    279 
    280         if (osm == null)
    281         {
    282             Collection<WaySegment> nearestWaySegs = allSegements
    283             ? c.getNearestWaySegments(p, OsmPrimitive.isSelectablePredicate)
    284                     : Collections.singleton(c.getNearestWaySegment(p, OsmPrimitive.isSelectablePredicate));
    285 
    286             for(WaySegment nearestWS : nearestWaySegs) {
     280
     281        if (osm != null) {
     282            for (Node n : c.getNearestNodes(p, OsmPrimitive.isSelectablePredicate)) {
     283                if (sel.contains(n)) {
     284                    osm = n;
     285                }
     286            }
     287        } else {
     288            Node virtualWayNode = null;
     289            Way w = null;
     290
     291            Collection<WaySegment> virtualWaysInSel = new ArrayList<WaySegment>();
     292            osm = c.getNearestWay(p, OsmPrimitive.isSelectablePredicate);
     293
     294            for(WaySegment nearestWS : c.getNearestWaySegments(p, OsmPrimitive.isSelectablePredicate)) {
    287295                if (nearestWS == null) {
    288296                    continue;
    289297                }
    290 
    291                 osm = nearestWS.way;
    292                 if(Main.pref.getInteger("mappaint.node.virtual-size", 8) > 0)
    293                 {
    294                     Way w = (Way)osm;
     298                if (sel.contains(w = nearestWS.way)) {
     299                    osm = w;
     300                }
     301
     302                if (Main.pref.getInteger("mappaint.node.virtual-size", 8) > 0) {
    295303                    Point p1 = c.getPoint(w.getNode(nearestWS.lowerIndex));
    296304                    Point p2 = c.getPoint(w.getNode(nearestWS.lowerIndex+1));
    297                     if(SimplePaintVisitor.isLargeSegment(p1, p2, Main.pref.getInteger("mappaint.node.virtual-space", 70)))
     305                    if(SimplePaintVisitor.isLargeSegment(p1, p2, virtualSpace))
    298306                    {
    299307                        Point pc = new Point((p1.x+p2.x)/2, (p1.y+p2.y)/2);
     
    304312                            // virtual node at the same spot will be joined which is likely unwanted
    305313                            if(virtualWayNode != null) {
    306                                 if(  !w.getNode(nearestWS.lowerIndex+1).equals(virtualWayNode)
     314                                if(!w.getNode(nearestWS.lowerIndex+1).equals(virtualWayNode)
    307315                                        && !w.getNode(nearestWS.lowerIndex).equals(virtualWayNode)) {
    308316                                    continue;
     
    312320                            }
    313321
    314                             virtualWays.add(nearestWS);
     322                            (!sel.contains(w) ? virtualWays : virtualWaysInSel).add(nearestWS);
    315323                            if(virtualNode == null) {
    316324                                virtualNode = new Node(Main.map.mapView.getLatLon(pc.x, pc.y));
     
    320328                }
    321329            }
    322         }
     330
     331            if (virtualNode != null) {
     332                virtualWays = virtualWaysInSel.isEmpty() ? virtualWays : virtualWaysInSel;
     333                osm = virtualWays.iterator().next().way;
     334            }
     335        }
     336
    323337        if (osm == null)
    324338            return Collections.emptySet();
     
    338352        if(!Main.map.mapView.isActiveLayerVisible())
    339353            return;
     354
    340355        // request focus in order to enable the expected keyboard shortcuts
    341         //
    342356        Main.map.mapView.requestFocus();
    343357
     
    347361            return;
    348362        boolean ctrl = (e.getModifiers() & ActionEvent.CTRL_MASK) != 0;
    349         boolean alt = (e.getModifiers() & (ActionEvent.ALT_MASK|InputEvent.ALT_GRAPH_MASK)) != 0;
    350363        boolean shift = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0;
    351364
     
    360373        initialMoveThresholdExceeded = false;
    361374
    362         Collection<OsmPrimitive> osmColl = getNearestCollectionVirtual(e.getPoint(), alt);
     375        Collection<OsmPrimitive> osmColl = getNearestCollectionVirtual(e.getPoint());
    363376
    364377        if (ctrl && shift) {
     
    383396            selectionManager.mousePressed(e);
    384397        }
    385         if(mode != Mode.move || shift || ctrl)
    386         {
     398
     399        if(mode != Mode.move || shift || ctrl) {
    387400            virtualNode = null;
    388401            virtualWays.clear();
     
    421434            boolean ctrl = (e.getModifiers() & ActionEvent.CTRL_MASK) != 0;
    422435            boolean shift = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0;
     436            boolean alt = (e.getModifiers() & (ActionEvent.ALT_MASK|InputEvent.ALT_GRAPH_MASK)) != 0
     437                            || Main.pref.getBoolean("selectaction.rotates", false);
     438
     439            virtualWays.clear();
     440            virtualNode = null;
     441
    423442            if (!didMove) {
    424                 selectPrims(
    425                         Main.map.mapView.getNearestCollection(e.getPoint(), OsmPrimitive.isSelectablePredicate),
    426                         shift, ctrl, true, false);
     443                Collection<OsmPrimitive> c = Main.map.mapView.getNearestCollection(e.getPoint(), OsmPrimitive.isSelectablePredicate);
     444                if (!c.isEmpty() && alt) {
     445                    if (c.iterator().next() instanceof Node) {
     446                        // there is at least one node under the cursor:
     447                        //   - make sure (first element of new list) equals (result of getNearestCollection)
     448                        //   - do not consider ways at all, but all nearest nodes
     449                        c = new ArrayList<OsmPrimitive>(Main.map.mapView.getNearestNodes(e.getPoint(), OsmPrimitive.isSelectablePredicate));
     450                    } else {
     451                        // consider all ways..
     452                        c = Main.map.mapView.getAllNearest(e.getPoint(), OsmPrimitive.isSelectablePredicate);
     453                    }
     454                }
     455                selectPrims(c, shift, ctrl, true, false);
    427456
    428457                // If the user double-clicked a node, change to draw mode
    429                 List<OsmPrimitive> sel = new ArrayList<OsmPrimitive>(getCurrentDataSet().getSelected());
    430                 if(e.getClickCount() >=2 && sel.size() == 1 && sel.get(0) instanceof Node) {
     458                c = getCurrentDataSet().getSelected();
     459                if(e.getClickCount() >=2 && c.size() == 1 && c.iterator().next() instanceof Node) {
    431460                    // We need to do it like this as otherwise drawAction will see a double
    432461                    // click and switch back to SelectMode
     
    501530    }
    502531
     532    private boolean selMorePrims = false;
     533    private OsmPrimitive selCycleStart = null;
     534
    503535    public void selectPrims(Collection<OsmPrimitive> selectionList, boolean shift,
    504536            boolean ctrl, boolean released, boolean area) {
    505537        DataSet ds = getCurrentDataSet();
    506         if ((shift && ctrl) || (ctrl && !released))
     538        if ((shift && ctrl) || (ctrl && !released) || (!virtualWays.isEmpty()))
    507539            return; // not allowed together
     540
     541        // toggle through possible objects on mouse release
     542        if (released && !area) {
     543            if (selectionList.size() > 1) {
     544                Collection<OsmPrimitive> coll = ds.getSelected();
     545
     546                OsmPrimitive first, foundInDS, node, nxt;
     547                first = nxt = selectionList.iterator().next();
     548                foundInDS = node = null;
     549
     550                for (Iterator<OsmPrimitive> i = selectionList.iterator(); i.hasNext(); ) {
     551                    if (selMorePrims && shift) {
     552                        if (!coll.contains(nxt = i.next())) {
     553                            break; // take first primitive not in dsSel or last if all contained
     554                        }
     555                    } else {
     556                        if (coll.contains(nxt = i.next())) {
     557                            foundInDS = nxt;
     558                            if (selMorePrims || ctrl) {
     559                                ds.clearSelection(nxt);
     560                                nxt = i.hasNext() ? i.next() : first;
     561                            }
     562                            break; // take next primitive of selList
     563                        } else if (nxt instanceof Node && node == null) {
     564                            node = nxt;
     565                        }
     566                    }
     567                }
     568
     569                if (ctrl) {
     570                    if (foundInDS != null) {
     571                        // a member of selList was foundInDS
     572                        if (!selectionList.contains(selCycleStart)) {
     573                            selCycleStart = foundInDS;
     574                        }
     575                        // check if selCycleStart == prim (equals next(foundInDS))
     576                        if (selCycleStart.equals(nxt)) {
     577                            ds.addSelected(nxt);   // cycle complete, prim toggled below
     578                            selCycleStart = null;  // check: might do w/out ??
     579                        }
     580                    } else {
     581                        // no member of selList was foundInDS (sets were disjunct), setup for new cycle
     582                        selCycleStart = nxt = (node != null) ? node : first;
     583                    }
     584                }
     585
     586                selectionList = new ArrayList<OsmPrimitive>(1); // do not modify the passed object..
     587                selectionList.add(nxt);
     588            }
     589        }
     590
     591        // hard-wiring to false due to performance reasons, should do w/out
     592        selMorePrims = (released || area) ? false : ds.getSelected().containsAll(selectionList);
    508593
    509594        if (ctrl) {
Note: See TracChangeset for help on using the changeset viewer.