Changeset 4396 in josm


Ignore:
Timestamp:
2011-09-02T14:04:22+02:00 (8 years ago)
Author:
xeen
Message:

several more fixes regarding the new selection highlighting introduced in r4327

  • properly unregister AWT listener in SelectAction (fixes #6749)
  • provide user feedback for merge-to-node feature (also fix #6748)
  • fix some repaint issues
File:
1 edited

Legend:

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

    r4360 r4396  
    1212import java.awt.Toolkit;
    1313import java.awt.event.AWTEventListener;
    14 import java.awt.event.ActionEvent;
    1514import java.awt.event.InputEvent;
    1615import java.awt.event.KeyEvent;
     
    7069    enum Mode { move, rotate, scale, select }
    7170
    72     // contains all possible cases the cursor can be in the SelectAction except the
    73     // the move pointer (latter is a system one and not an image)
    74     private enum SelectActionCursor {
     71    // contains all possible cases the cursor can be in the SelectAction
     72    static private enum SelectActionCursor {
    7573        rect("normal", "selection"),
    7674        rect_add("normal", "select_add"),
     
    8482        virtual_node("normal", "addnode"),
    8583        scale("scale", null),
    86         rotate("rotate", null);
     84        rotate("rotate", null),
     85        merge("crosshair", null),
     86        merge_to_node("crosshair", "joinnode"),
     87        move(Cursor.MOVE_CURSOR);
    8788
    8889        private final Cursor c;
    8990        private SelectActionCursor(String main, String sub) {
    9091            c = ImageProvider.getCursor(main, sub);
     92        }
     93        private SelectActionCursor(int systemCursor) {
     94            c = Cursor.getPredefinedCursor(systemCursor);
    9195        }
    9296        public Cursor cursor() {
     
    154158        initialMoveThreshold = Main.pref.getInteger("edit.initial-move-threshold", 5);
    155159        drawTargetHighlight = Main.pref.getBoolean("draw.target-highlight", true);
    156         // This is required to update the cursors when ctrl/shift/alt is pressed
    157         try {
    158             Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.KEY_EVENT_MASK);
    159         } catch (SecurityException ex) {
    160             System.out.println(ex);
    161         }
    162160    }
    163161
     
    169167        mv.setVirtualNodesEnabled(
    170168                Main.pref.getInteger("mappaint.node.virtual-size", 8) != 0);
     169        // This is required to update the cursors when ctrl/shift/alt is pressed
     170        try {
     171            Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.KEY_EVENT_MASK);
     172        } catch (SecurityException ex) {}
    171173    }
    172174
     
    178180        mv.removeMouseMotionListener(this);
    179181        mv.setVirtualNodesEnabled(false);
     182        try {
     183            Toolkit.getDefaultToolkit().removeAWTEventListener(this);
     184        } catch (SecurityException ex) {}
    180185        removeHighlighting();
    181186    }
     
    196201                break;
    197202            }
    198 
    199             // nearbyStuff cannot be empty as otherwise we would be in
    200             // Move.select and not Move.move
    201             OsmPrimitive osm = nearbyStuff.iterator().next();
     203            final Iterator<OsmPrimitive> it = nearbyStuff.iterator();
     204            final OsmPrimitive osm = it.hasNext() ? it.next() : null;
     205
     206            if(dragInProgress()) {
     207                c = ctrl ? "merge" : "move";
     208                if(osm != null && osm instanceof Node) {
     209                    c += "_to_node";
     210                }
     211                break;
     212            }
    202213
    203214            c = (osm instanceof Node) ? "node" : c;
    204215            c = (osm instanceof Way) ? "way" : c;
    205 
    206216            if(shift) {
    207217                c += "_add";
     
    246256    /**
    247257     * handles adding highlights and updating the cursor for the given mouse event.
     258     * Please note that the highlighting for merging while moving is handled via mouseDragged.
    248259     * @param MouseEvent which should be used as base for the feedback
    249260     * @return true if repaint is required
     
    255266    /**
    256267     * handles adding highlights and updating the cursor for the given mouse event.
     268     * Please note that the highlighting for merging while moving is handled via mouseDragged.
    257269     * @param MouseEvent which should be used as base for the feedback
    258270     * @param define custom keyboard modifiers if the ones from MouseEvent are outdated or similar
     
    310322        // We don't have a mouse event, so we pass the old mouse event but the
    311323        // new modifiers.
    312         giveUserFeedback(oldEvent, ((InputEvent) e).getModifiers());
     324        if(giveUserFeedback(oldEvent, ((InputEvent) e).getModifiers())) {
     325            mv.repaint();
     326        }
    313327    }
    314328
     
    338352
    339353        if (mode == Mode.move) {
    340             mv.setNewCursor(Cursor.MOVE_CURSOR, this);
     354            // If ctrl is pressed we are in merge mode. Look for a nearby node,
     355            // highlight it and adjust the cursor accordingly.
     356            final OsmPrimitive p = ctrl ? (OsmPrimitive)findNodeToMergeTo(e) : null;
     357            boolean needsRepaint = removeHighlighting();
     358            if(p != null) {
     359                p.setHighlighted(true);
     360                oldHighlights.add(p);
     361                needsRepaint = true;
     362            }
     363            mv.setNewCursor(getCursor(MapView.asColl(p)), this);
     364            if(needsRepaint) {
     365                mv.repaint();
     366            }
    341367        }
    342368
     
    463489            mv.repaint();
    464490        }
     491    }
     492
     493    /** returns true whenever elements have been grabbed and moved (i.e. the initial
     494     * thresholds have been exceeded) and is still in progress (i.e. mouse button
     495     * still pressed)
     496     */
     497    final private boolean dragInProgress() {
     498        return didMouseDrag && startingDraggingPos != null;
    465499    }
    466500
     
    595629        } else if (alt && ctrl) {
    596630            mode = Mode.scale;
    597         } else if (hasSelectionNearby) {
     631        } else if (hasSelectionNearby || dragInProgress()) {
    598632            mode = Mode.move;
    599633        } else {
     
    731765                    }
    732766                } else {
    733                     mergePrims(getCurrentDataSet().getSelectedNodes(), e);
     767                    mergePrims(e);
    734768                }
    735769                getCurrentDataSet().fireSelectionChanged();
     
    815849    }
    816850
    817     private void mergePrims(Collection<Node> affectedNodes, MouseEvent e) {
    818         boolean ctrl = (e.getModifiers() & ActionEvent.CTRL_MASK) != 0;
    819 
    820         if (ctrl && !affectedNodes.isEmpty()) {
    821             Collection<Node> target = mv.getNearestNodes(e.getPoint(), affectedNodes, OsmPrimitive.isSelectablePredicate);
    822             if (!target.isEmpty()) {
    823                 Collection<Node> nodesToMerge = new LinkedList<Node>(affectedNodes);
    824                 Node t = target.iterator().next();
    825                 nodesToMerge.add(t);
    826                 Command cmd = MergeNodesAction.mergeNodes(Main.main.getEditLayer(), nodesToMerge, t);
    827                 if (cmd != null) {
    828                     Main.main.undoRedo.add(cmd);
    829                     getCurrentDataSet().setSelected(t);
    830                 }
    831             }
    832         }
     851    /** Merges the selected nodes to the one closest to the given mouse position iff the control
     852     * key is pressed. If there is no such node, no action will be done and no error will be
     853     * reported. If there is, it will execute the merge and add it to the undo buffer. */
     854    final private void mergePrims(MouseEvent e) {
     855        updateKeyModifiers(e);
     856        Collection<Node> selNodes = getCurrentDataSet().getSelectedNodes();
     857        if (!ctrl || selNodes.isEmpty())
     858            return;
     859
     860        Node target = findNodeToMergeTo(e);
     861        if (target == null)
     862            return;
     863
     864        Collection<Node> nodesToMerge = new LinkedList<Node>(selNodes);
     865        nodesToMerge.add(target);
     866        Command cmd = MergeNodesAction.mergeNodes(Main.main.getEditLayer(), nodesToMerge, target);
     867        if (cmd != null) {
     868            Main.main.undoRedo.add(cmd);
     869            getCurrentDataSet().setSelected(target);
     870        }
     871    }
     872
     873    /** tries to find a node to merge to when in move-merge mode for the current mouse
     874     * position. Either returns the node or null, if no suitable one is nearby. */
     875    final private Node findNodeToMergeTo(MouseEvent e) {
     876        Collection<Node> target = mv.getNearestNodes(e.getPoint(),
     877                getCurrentDataSet().getSelectedNodes(),
     878                OsmPrimitive.isSelectablePredicate);
     879        return target.isEmpty() ? null : target.iterator().next();
    833880    }
    834881
Note: See TracChangeset for help on using the changeset viewer.