Changeset 5394 in josm for trunk


Ignore:
Timestamp:
2012-08-05T08:53:20+02:00 (12 years ago)
Author:
akks
Message:

see #7888, smaller refactoring or SelectAction (cycling) (behavior should not change)

File:
1 edited

Legend:

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

    r5370 r5394  
    177177        mv.setVirtualNodesEnabled(Main.pref.getInteger("mappaint.node.virtual-size", 8) != 0);
    178178        drawTargetHighlight = Main.pref.getBoolean("draw.target-highlight", true);
     179        cycleManager.init();
     180        virtualManager.init();
    179181        // This is required to update the cursors when ctrl/shift/alt is pressed
    180182        try {
     
    375377    @Override
    376378    public void mousePressed(MouseEvent e) {
     379        mouseDownButton = e.getButton();
    377380        // 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)
    379382            return;
    380383       
     
    396399
    397400        // 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);
    402405       
    403406        switch(mode) {
    404407        case rotate:
    405408        case scale:
     409            //  if nothing was selected, select primitive under cursor for scaling or rotating
    406410            if (getCurrentDataSet().getSelected().isEmpty()) {
    407                 getCurrentDataSet().setSelected(c);
     411                getCurrentDataSet().setSelected(MapView.asColl(nearestPrimitive));
    408412            }
    409413
     
    414418            break;
    415419        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) {
    417423                virtualManager.setupVirtual(e.getPoint());
    418424            }
    419            
    420             selectPrims(cycleManager.cycleSetup(c, e.getPoint()), false, false);
     425            selectPrims(cycleManager.cycleSetup(nearestPrimitive, e.getPoint()), false, false);
    421426            break;
    422427        case select:
    423428        default:
     429            // start working with rectangle or lasso
    424430            selectionManager.register(mv, lassoMode);
    425431            selectionManager.mousePressed(e);
     
    453459        if (!mv.isActiveLayerVisible())
    454460            return;
    455 
     461       
    456462        // Swing sends random mouseDragged events when closing dialogs by double-clicking their top-left icon on Windows
    457463        // Ignore such false events to prevent issues like #7078
    458464        if (mouseDownButton == MouseEvent.BUTTON1 && mouseReleaseTime > mouseDownTime)
    459465            return;
    460 
     466       
    461467        cancelDrawMode = true;
    462468        if (mode == Mode.select)
     
    827833        private boolean cyclePrims = false;
    828834        private OsmPrimitive cycleStart = null;
    829 
     835        private boolean waitForMouseUpParameter;
     836        private boolean multipleMatchesParameter;
    830837        /**
    831          *
    832          * @param osm nearest primitive found by simple method
    833          * @param e
    834          * @return
     838         * read preferences
    835839         */
    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) {
    837852            OsmPrimitive osm = null;
    838853
    839             if (single != null && !single.isEmpty()) {
    840                 osm = single.iterator().next();
     854            if (nearest != null) {
     855                osm = nearest;
    841856
    842857                // Point p = e.getPoint();
    843                 boolean waitForMouseUp = Main.pref.getBoolean("mappaint.select.waits-for-mouse-up", false);
    844858//              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                   
    848862                    cycleList = MapView.asColl(osm);
    849863
    850                     if (waitForMouseUp) {
     864                    if (waitForMouseUpParameter) {
    851865                        // prefer a selected nearest node or way, if possible
    852866                        osm = mv.getNearestNodeOrWay(p, OsmPrimitive.isSelectablePredicate, true);
    853867                    }
    854868                } else {
     869                    // Alt + left mouse button pressed: we need to build cycle list
    855870                    cycleList = mv.getAllNearest(p, OsmPrimitive.isSelectablePredicate);
    856871
     
    858873                        cyclePrims = false;
    859874
     875                        // find first already selected element in cycle list
    860876                        OsmPrimitive old = osm;
    861877                        for (OsmPrimitive o : cycleList) {
     
    869885                        // special case:  for cycle groups of 2, we can toggle to the
    870886                        // true nearest primitive on mousePressed right away
    871                         if (cycleList.size() == 2 && !waitForMouseUp) {
     887                        if (cycleList.size() == 2 && !waitForMouseUpParameter) {
    872888                            if (!(osm.equals(old) || osm.isNew() || ctrl)) {
    873889                                cyclePrims = false;
     
    891907         * Modifies current selection state and returns the next element in a
    892908         * 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
    897910         * @return the next element of cycle list
    898          * <code>prims</code>.
    899911         */
    900912        private Collection<OsmPrimitive> cyclePrims() {
    901             Collection<OsmPrimitive> prims = cycleList;
    902913            OsmPrimitive nxt = null;
    903914
    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
    925930                    }
    926931                }
    927 
    928                 if (ctrl) {
    929                     // a member of prims was found in the current dataset selection
    930                     if (foundInDS != null) {
    931                         // mouse was moved to a different selection group w/ a previous sel
    932                         if (!prims.contains(cycleStart)) {
    933                             ds.clearSelection(prims);
    934                             cycleStart = foundInDS;
    935                         } else if (cycleStart.equals(nxt)) {
    936                             // loop detected, insert deselect step
    937                             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)
    938943                        }
    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);
    943960                    }
    944961                } 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;
    946965                }
    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);
    951971        }
    952972    }
     
    956976        private Node virtualNode = null;
    957977        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       
    959989        /**
    960990         * Calculate a virtual node if there is enough visual space to draw a
     
    969999         */
    9701000        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               
    9761003                Collection<WaySegment> selVirtualWays = new LinkedList<WaySegment>();
    9771004                Pair<Node, Node> vnp = null, wnp = new Pair<Node, Node>(null, null);
     
    9851012                    if (WireframeMapRenderer.isLargeSegment(p1, p2, virtualSpace)) {
    9861013                        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) {
    9881015                            // Check that only segments on top of each other get added to the
    9891016                            // virtual ways list. Otherwise ways that coincidentally have their
Note: See TracChangeset for help on using the changeset viewer.