Changeset 5418 in josm


Ignore:
Timestamp:
Aug 10, 2012 9:01:12 PM (9 months ago)
Author:
akks
Message:

fix #7082 (?) - CTRL-drag in selection mode problem, see #7888: SelectAction and MoveCommand rework

Location:
trunk/src/org/openstreetmap/josm
Files:
2 edited

Legend:

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

    r5394 r5418  
    120120    private Point startingDraggingPos; 
    121121    /** 
     122     * point where user pressed the mouse to start movement 
     123     */ 
     124    EastNorth startEN; 
     125    /** 
    122126     * The last known position of the mouse. 
    123127     */ 
     
    198202    } 
    199203 
     204    int previousModifiers; 
     205     
    200206     /** 
    201207     * This is called whenever the keyboard modifier status changes 
     
    206212        // We don't have a mouse event, so we pass the old mouse event but the 
    207213        // new modifiers. 
     214        int modif = ((InputEvent) e).getModifiers(); 
     215        if (previousModifiers == modif) 
     216            return; 
     217        previousModifiers = modif; 
    208218        if(giveUserFeedback(oldEvent, ((InputEvent) e).getModifiers())) { 
    209219            mv.repaint(); 
     
    397407        mouseDownTime = System.currentTimeMillis(); 
    398408        lastMousePos = e.getPoint(); 
     409        startEN = mv.getEastNorth(lastMousePos.x,lastMousePos.y); 
    399410 
    400411        // primitives under cursor are stored in c collection 
     
    424435            } 
    425436            selectPrims(cycleManager.cycleSetup(nearestPrimitive, e.getPoint()), false, false); 
     437            useLastMoveCommandIfPossible(); 
    426438            break; 
    427439        case select: 
     
    509521 
    510522        if (!initialMoveThresholdExceeded) { 
    511             int dxp = lastMousePos.x - e.getX(); 
    512             int dyp = lastMousePos.y - e.getY(); 
    513             int dp = (int) Math.sqrt(dxp * dxp + dyp * dyp); 
     523            int dp = (int) lastMousePos.distance(e.getX(), e.getY()); 
    514524            if (dp < initialMoveThreshold) 
    515525                return; 
     
    518528 
    519529        EastNorth currentEN = mv.getEastNorth(e.getX(), e.getY()); 
    520         EastNorth lastEN = mv.getEastNorth(lastMousePos.x, lastMousePos.y); 
    521         //EastNorth startEN = mv.getEastNorth(startingDraggingPos.x, startingDraggingPos.y); 
    522         double dx = currentEN.east() - lastEN.east(); 
    523         double dy = currentEN.north() - lastEN.north(); 
    524         if (dx == 0 && dy == 0) 
    525             return; 
    526  
     530        if (e.getPoint().equals(lastMousePos)) 
     531            return; 
     532         
    527533        if (virtualManager.hasVirtualWays()) { 
    528             virtualManager.processVirtualNodeMovements(dx, dy); 
     534            virtualManager.processVirtualNodeMovements(currentEN); 
    529535        } else { 
    530             if (!updateCommandWhileDragging(dx, dy, currentEN)) return; 
     536            if (!updateCommandWhileDragging(currentEN)) return; 
    531537        } 
    532538 
     
    561567 
    562568            // Select Draw Tool if no selection has been made 
    563             if (getCurrentDataSet().getSelected().size() == 0 && !cancelDrawMode) { 
     569            if (getCurrentDataSet().getSelected().isEmpty() && !cancelDrawMode) { 
    564570                Main.map.selectDrawTool(true); 
    565571                return; 
     
    646652     * Create or update data modfication command whle dragging mouse - implementation of  
    647653     * continuous moving, scaling and rotation 
    648      * @param dx, @param dy - mouse displacement 
    649      * @param currentEN - 
     654     * @param currentEN - mouse position 
    650655     * @return  
    651656     */ 
    652     private boolean updateCommandWhileDragging(double dx, double dy, EastNorth currentEN) { 
     657    private boolean updateCommandWhileDragging(EastNorth currentEN) { 
    653658        // Currently we support only transformations which do not affect relations. 
    654659        // So don't add them in the first place to make handling easier 
     
    659664            return false; 
    660665        } 
    661         Command c = !Main.main.undoRedo.commands.isEmpty() 
    662                 ? Main.main.undoRedo.commands.getLast() : null; 
    663         if (c instanceof SequenceCommand) { 
    664             c = ((SequenceCommand) c).getLastCommand(); 
    665         } 
     666        Command c = getLastCommand(); 
    666667        if (mode == Mode.move) { 
    667668            getCurrentDataSet().beginUpdate(); 
    668669            if (c instanceof MoveCommand && affectedNodes.equals(((MoveCommand) c).getParticipatingPrimitives())) { 
    669                 ((MoveCommand) c).moveAgain(dx, dy); 
     670                ((MoveCommand) c).saveCheckpoint(); 
     671                ((MoveCommand) c).applyVectorTo(currentEN); 
    670672            } else { 
    671673                Main.main.undoRedo.add( 
    672                         c = new MoveCommand(selection, dx, dy)); 
    673             } 
    674             getCurrentDataSet().endUpdate(); 
     674                        c = new MoveCommand(selection, startEN, currentEN)); 
     675            } 
    675676            for (Node n : affectedNodes) { 
    676677                if (n.getCoor().isOutSideWorld()) { 
    677678                    // Revert move 
    678                     ((MoveCommand) c).moveAgain(-dx, -dy); 
     679                    ((MoveCommand) c).resetToCheckpoint(); 
    679680                    JOptionPane.showMessageDialog( 
    680681                            Main.parent, 
     
    686687                } 
    687688            } 
     689            getCurrentDataSet().endUpdate(); 
    688690        } else if (mode == Mode.rotate) { 
    689691            getCurrentDataSet().beginUpdate(); 
     
    704706        } 
    705707        return true; 
     708    } 
     709     
     710    /** 
     711     * Adapt last move command (if it is suitabble) to work with next drag, startedd at point startEN 
     712     */ 
     713    private void useLastMoveCommandIfPossible() { 
     714        Command c = getLastCommand(); 
     715        Collection<Node> affectedNodes = AllNodesVisitor.getAllNodes(getCurrentDataSet().getSelected()); 
     716        if (c instanceof MoveCommand && affectedNodes.equals(((MoveCommand) c).getParticipatingPrimitives())) { 
     717            // old command was created with different base point of movement, we need to recalculate it 
     718            ((MoveCommand) c).changeStartPoint(startEN); 
     719        } 
     720    } 
     721        
     722    /** 
     723     * Obtain command in undoRedo stack to "continue" when dragging 
     724     */ 
     725    private Command getLastCommand() { 
     726        Command c = !Main.main.undoRedo.commands.isEmpty() 
     727                ? Main.main.undoRedo.commands.getLast() : null; 
     728        if (c instanceof SequenceCommand) { 
     729            c = ((SequenceCommand) c).getLastCommand(); 
     730        } 
     731        return c; 
    706732    } 
    707733     
     
    10361062        } 
    10371063 
    1038         private void processVirtualNodeMovements(double dx, double dy) { 
     1064        private void processVirtualNodeMovements(EastNorth currentEN) { 
    10391065            Collection<Command> virtualCmds = new LinkedList<Command>(); 
    10401066            virtualCmds.add(new AddCommand(virtualNode)); 
     
    10451071                virtualCmds.add(new ChangeCommand(w, wnew)); 
    10461072            } 
    1047             virtualCmds.add(new MoveCommand(virtualNode, dx, dy)); 
     1073            virtualCmds.add(new MoveCommand(virtualNode, startEN, currentEN)); 
    10481074            String text = trn("Add and move a virtual new node to way", 
    10491075                    "Add and move a virtual new node to {0} ways", virtualWays.size(), 
  • trunk/src/org/openstreetmap/josm/command/MoveCommand.java

    r4918 r5418  
    3333    private Collection<Node> nodes = new LinkedList<Node>(); 
    3434    /** 
     35     * Starting position, base command point, current (mouse-drag) position = startEN + (x,y) =  
     36     */ 
     37    private EastNorth startEN; 
     38 
     39    /** 
    3540     * x difference movement. Coordinates are in northern/eastern 
    3641     */ 
     
    4045     */ 
    4146    private double y; 
     47 
     48    private double backupX; 
     49    private double backupY; 
    4250 
    4351    /** 
     
    4755    public static class OldState { 
    4856        LatLon latlon; 
     57        EastNorth en; // cached EastNorth to be used for applying exact displacenment 
    4958        boolean modified; 
    5059    } 
     
    6675        this(objects, offset.getX(), offset.getY()); 
    6776    } 
    68  
     77     
    6978    /** 
    7079     * Create a MoveCommand and assign the initial object set and movement vector. 
     
    7281    public MoveCommand(Collection<OsmPrimitive> objects, double x, double y) { 
    7382        super(); 
     83        startEN = null; 
     84        saveCheckpoint(); // (0,0) displacement will be saved 
    7485        this.x = x; 
    7586        this.y = y; 
     
    7889            OldState os = new OldState(); 
    7990            os.latlon = new LatLon(n.getCoor()); 
     91            os.en = n.getEastNorth(); 
    8092            os.modified = n.isModified(); 
    8193            oldState.add(os); 
     
    8395    } 
    8496 
     97     public MoveCommand(Collection<OsmPrimitive> objects, EastNorth start, EastNorth end) { 
     98         this(objects, end.getX()-start.getX(), end.getY()-start.getY()); 
     99         startEN =  start; 
     100     } 
     101 
     102     public MoveCommand(OsmPrimitive p, EastNorth start, EastNorth end) { 
     103         this(Collections.singleton(p), end.getX()-start.getX(), end.getY()-start.getY()); 
     104         startEN =  start; 
     105     } 
     106      
    85107    /** 
    86108     * Move the same set of objects again by the specified vector. The vectors 
     
    102124        moveAgain(x - this.x, y - this.y); 
    103125    } 
     126     
     127    /** 
     128     * Change the displacement vector to have endpoint @param currentEN  
     129     * starting point is  startEN 
     130     */ 
     131    public void applyVectorTo(EastNorth currentEN) { 
     132        if (startEN == null)  
     133            return; 
     134        x = currentEN.getX() - startEN.getX(); 
     135        y = currentEN.getY() - startEN.getY(); 
     136        updateCoordinates(); 
     137    } 
     138 
     139     /** 
     140     * Changes base point of movement 
     141     * @param newDraggedStartPoint - new starting point after movement (where user clicks to start new drag) 
     142     */ 
     143    public void changeStartPoint(EastNorth newDraggedStartPoint) { 
     144        startEN = new EastNorth(newDraggedStartPoint.getX()-x, newDraggedStartPoint.getY()-y); 
     145     } 
     146 
     147    /** 
     148     * Save curent displacement to restore in case of some problems 
     149     */ 
     150    public void saveCheckpoint() { 
     151        backupX = x; 
     152        backupY = y; 
     153    } 
     154 
     155    /** 
     156     * Restore old displacement in case of some problems 
     157     */ 
     158    public void resetToCheckpoint() { 
     159        x = backupX; 
     160        y = backupY; 
     161        updateCoordinates(); 
     162    } 
     163 
     164    private void updateCoordinates() { 
     165        Iterator<OldState> it = oldState.iterator(); 
     166        for (Node n : nodes) { 
     167            OldState os = it.next(); 
     168            n.setEastNorth(os.en.add(x, y)); 
     169        } 
     170    } 
    104171 
    105172    @Override public boolean executeCommand() { 
Note: See TracChangeset for help on using the changeset viewer.