Ticket #1902: TargetHighlight.patch

File TargetHighlight.patch, 16.1 KB (added by xeen, 12 years ago)
  • src/org/openstreetmap/josm/actions/mapmode/DrawAction.java

    Cannot display: file marked as a binary type.
    svn:mime-type = application/octet-stream
    
    Property changes on: images\cursor\modifier\joinnode.png
    ___________________________________________________________________
    Name: svn:mime-type
       + application/octet-stream
    
    Cannot display: file marked as a binary type.
    svn:mime-type = application/octet-stream
    
    Property changes on: images\cursor\modifier\joinway.png
    ___________________________________________________________________
    Name: svn:mime-type
       + application/octet-stream
    
     
    6565    private boolean ctrl;
    6666    private boolean alt;
    6767    private boolean shift;
    68     private boolean mouseOnExistingNode;
     68    private Node mouseOnExistingNode;
     69    private Set<Way> mouseOnExistingWays = new HashSet<Way>();
     70    private Set<OsmPrimitive> oldHighlights = new HashSet<OsmPrimitive>();
    6971    private boolean drawHelperLine;
    7072    private boolean wayIsFinished = false;
     73    private boolean drawTargetHighlight;
     74    private boolean drawTargetCursor;
    7175    private Point mousePos;
    7276    private Color selectedColor;
    7377
     
    9296        return Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR);
    9397    }
    9498
     99    /**
     100     * Sets a special cursor to indicate that the next click will automatically join into
     101     * an existing node or way (if feature is enabled)
     102     *
     103     * @param way If true, the cursor will indicate it is joined into a way; node otherwise
     104     */
     105    private void setJoinCursor(boolean way) {
     106        if(!drawTargetCursor) {
     107            resetCursor();
     108            return;
     109        }
     110        try {
     111            Main.map.mapView.setCursor(
     112                    ImageProvider.getCursor("crosshair", (way ? "joinway" : "joinnode"))
     113            );
     114            return;
     115        } catch (Exception e) {
     116            e.printStackTrace();
     117        }
     118        resetCursor();
     119    }
     120
     121    /**
     122     * Resets the cursor to the default cursor for drawing mode (i.e. crosshair)
     123     */
     124    private void resetCursor() {
     125        Main.map.mapView.setCursor(getCursor());
     126    }
     127
     128    /**
     129     * Takes the data from computeHelperLine to determine which ways/nodes should be highlighted
     130     * (if feature enabled). Also sets the target cursor if appropriate.
     131     */
     132    private void addHighlighting() {
     133        // if ctrl key is held ("no join"), don't highlight anything
     134        if (ctrl) {
     135            removeHighlighting();
     136            resetCursor();
     137            return;
     138        }
     139
     140        if (mouseOnExistingNode != null) {
     141            setJoinCursor(false);
     142            // Clean old highlights
     143            removeHighlighting();
     144            if(drawTargetHighlight) {
     145                oldHighlights.add(mouseOnExistingNode);
     146                mouseOnExistingNode.highlighted = true;
     147            }
     148            return;
     149        }
     150
     151        // Insert the node into all the nearby way segments
     152        if(mouseOnExistingWays.size() == 0) {
     153            removeHighlighting();
     154            resetCursor();
     155            return;
     156        }
     157
     158        setJoinCursor(true);
     159        // Clean old highlights
     160        removeHighlighting();
     161
     162        if(!drawTargetHighlight) return;
     163        oldHighlights.addAll(mouseOnExistingWays);
     164        for(Way w : mouseOnExistingWays) {
     165            w.highlighted = true;
     166        }
     167    }
     168
     169    /**
     170     * Removes target highlighting from primitives
     171     */
     172    private void removeHighlighting() {
     173        for(OsmPrimitive prim : oldHighlights) {
     174            prim.highlighted = false;
     175        }
     176    }
     177
    95178    @Override public void enterMode() {
    96179        super.enterMode();
    97180        selectedColor = Main.pref.getColor(marktr("selected"), Color.red);
    98181        drawHelperLine = Main.pref.getBoolean("draw.helper-line", true);
     182        drawTargetHighlight = Main.pref.getBoolean("draw.target-highlight", true);
     183        drawTargetCursor = Main.pref.getBoolean("draw.target-cursor", true);
    99184        wayIsFinished = false;
    100        
     185
    101186        Main.map.mapView.addMouseListener(this);
    102187        Main.map.mapView.addMouseMotionListener(this);
    103188        Main.map.mapView.addTemporaryLayer(this);
    104189        DataSet.selListeners.add(this);
     190
    105191        try {
    106192            Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.KEY_EVENT_MASK);
    107193        } catch (SecurityException ex) {
     
    109195        // would like to but haven't got mouse position yet:
    110196        // computeHelperLine(false, false, false);
    111197    }
     198
    112199    @Override public void exitMode() {
    113200        super.exitMode();
    114201        Main.map.mapView.removeMouseListener(this);
    115202        Main.map.mapView.removeMouseMotionListener(this);
    116203        Main.map.mapView.removeTemporaryLayer(this);
    117204        DataSet.selListeners.remove(this);
     205        removeHighlighting();
    118206        try {
    119207            Toolkit.getDefaultToolkit().removeAWTEventListener(this);
    120208        } catch (SecurityException ex) {
     
    146234        Main.ds.setSelected();
    147235        mouseClicked(e);
    148236    }
    149    
     237
    150238    /**
    151239     * If user clicked with the left button, add a node at the current mouse
    152240     * position.
     
    183271
    184272        if (!ctrl)
    185273            n = Main.map.mapView.getNearestNode(mousePos);
    186      
     274
    187275        if (n != null) {
    188276            // user clicked on node
    189277            if (shift || selection.isEmpty()) {
     
    258346        if (!shift && selection.size() > 0 && !wayIsFinishedTemp) {
    259347            Node selectedNode = null;
    260348            Way selectedWay = null;
    261            
     349
    262350            for (OsmPrimitive p : selection) {
    263351                if (p instanceof Node) {
    264352                    if (selectedNode != null) {
     
    276364                    selectedWay = (Way) p;
    277365                }
    278366            }
    279            
     367
    280368            // No nodes or ways have been selected, try again with no selection
    281369            // This occurs when a relation has been selected
    282370            if(selectedNode == null && selectedWay == null) {
     
    291379                if (selectedWay.isFirstLastNode(lastUsedNode)) {
    292380                    n0 = lastUsedNode;
    293381                } else {
    294                     // We have a way selected, but no suitable node to continue from. Start anew. 
     382                    // We have a way selected, but no suitable node to continue from. Start anew.
    295383                    tryAgain(e);
    296384                    return;
    297385                }
     
    325413                    return;
    326414                }
    327415            }
    328            
     416
    329417            // User clicked last node again, finish way
    330418            if(n0 == n) {
    331419                lastUsedNode = null;
     
    378466            extendedWay = true;
    379467            Main.ds.setSelected(way);
    380468        }
    381      
     469
    382470        String title;
    383471        if (!extendedWay) {
    384472            if (!newNode) {
     
    403491        Main.main.undoRedo.add(c);
    404492        if(!wayIsFinished) lastUsedNode = n;
    405493        computeHelperLine();
     494        removeHighlighting();
    406495        Main.map.mapView.repaint();
    407496    }
    408497
     
    419508        shift = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0;
    420509        mousePos = e.getPoint();
    421510
     511        addHighlighting();
    422512        computeHelperLine();
    423513    }
    424514
     
    443533        Node selectedNode = null;
    444534        Way selectedWay = null;
    445535        Node currentMouseNode = null;
    446         mouseOnExistingNode = false;
     536        mouseOnExistingNode = null;
     537        mouseOnExistingWays = new HashSet<Way>();
    447538
    448539        Main.map.statusLine.setAngle(-1);
    449540        Main.map.statusLine.setHeading(-1);
     
    453544            currentMouseNode = Main.map.mapView.getNearestNode(mousePos);
    454545        }
    455546
     547        // We need this for highlighting and we'll only do so if we actually want to re-use
     548        // *and* there is no node nearby (because nodes beat ways when re-using)
     549        if(!ctrl && currentMouseNode == null) {
     550            List<WaySegment> wss = Main.map.mapView.getNearestWaySegments(mousePos);
     551            for(WaySegment ws : wss)
     552                mouseOnExistingWays.add(ws.way);
     553        }
     554
    456555        if (currentMouseNode != null) {
    457556            // user clicked on node
    458557            if (selection.isEmpty()) return;
    459558            currentMouseEastNorth = currentMouseNode.eastNorth;
    460             mouseOnExistingNode = true;
     559            mouseOnExistingNode = currentMouseNode;
    461560        } else {
    462561            // no node found in clicked area
    463562            currentMouseEastNorth = Main.map.mapView.getEastNorth(mousePos.x, mousePos.y);
     
    510609        Main.map.statusLine.setDist(distance);
    511610        updateStatusLine();
    512611
    513         if (!drawHelperLine || wayIsFinished) return;
    514 
     612        if ((!drawHelperLine || wayIsFinished) && !drawTargetHighlight) return;
    515613        Main.map.mapView.repaint();
    516614    }
    517615
     
    639737    }
    640738
    641739    public void paint(Graphics g, MapView mv) {
     740        if (!drawHelperLine && !drawTargetHighlight) return;
    642741
    643         // don't draw line if disabled in prefs
    644         if (!drawHelperLine) return;
    645 
    646742        // sanity checks
    647743        if (Main.map.mapView == null) return;
    648744        if (mousePos == null) return;
     
    651747        if (shift) return;
    652748
    653749        // don't draw line if we don't know where from or where to
    654         if (currentBaseNode == null) return;
    655         if (currentMouseEastNorth == null) return;
     750        if (currentBaseNode == null || currentMouseEastNorth == null) return;
    656751
    657752        // don't draw line if mouse is outside window
    658753        if (!Main.map.mapView.getBounds().contains(mousePos)) return;
     
    676771
    677772        g2.draw(b);
    678773        g2.setStroke(new BasicStroke(1));
    679 
    680774    }
    681775
    682776    @Override public String getModeHelpText() {
    683777        String rv;
    684778
    685779        if (currentBaseNode != null && !shift) {
    686             if (mouseOnExistingNode) {
     780            if (mouseOnExistingNode != null) {
    687781                if (alt && /* FIXME: way exists */true)
    688782                    rv = tr("Click to create a new way to the existing node.");
    689783                else
     
    703797        //rv.append(tr("Click to add a new node. Ctrl: no node re-use/auto-insert. Shift: no auto-connect. Alt: new way"));
    704798        return rv.toString();
    705799    }
    706    
     800
    707801    @Override public boolean layerIsSupported(Layer l) {
    708802        return l instanceof OsmDataLayer;
    709803    }
  • src/org/openstreetmap/josm/data/osm/OsmPrimitive.java

     
    122122     * If set to true, this object is currently selected.
    123123     */
    124124    public volatile boolean selected = false;
     125   
     126    /**
     127     * If set to true, this object is highlighted. Currently this is only used to
     128     * show which ways/nodes will connect
     129     */
     130    public volatile boolean highlighted = false;
    125131
    126132    /**
    127133     * Time of last modification to this object. This is not set by JOSM but
  • src/org/openstreetmap/josm/data/osm/visitor/MapPaintVisitor.java

     
    119119
    120120        if(osm.mappaintStyle == null && styles != null) {
    121121            osm.mappaintStyle = styles.get(osm);
    122             if(osm instanceof Way)
    123                 osm.isMappaintArea = styles.isArea(osm);
     122            osm.isMappaintArea = styles.isArea(osm);
    124123        }
    125124        return osm.isMappaintArea;
    126125    }
     
    150149
    151150        if (nodeStyle != null && isZoomOk(nodeStyle) && showIcons > dist)
    152151            drawNode(n, nodeStyle.icon, nodeStyle.annotate, n.selected);
     152        else if (n.highlighted)
     153            drawNode(n, highlightColor, selectedNodeSize, selectedNodeRadius, fillSelectedNode);
    153154        else if (n.selected)
    154155            drawNode(n, selectedColor, selectedNodeSize, selectedNodeRadius, fillSelectedNode);
    155156        else if (n.tagged)
     
    265266            int tmpWidth = (int) (100 /  (float) (circum / realWidth));
    266267            if (tmpWidth > width) width = tmpWidth;
    267268        }
    268         if(w.selected)
     269
     270        if(w.highlighted)
     271            color = highlightColor;
     272        else if(w.selected)
    269273            color = selectedColor;
    270274
    271275        // draw overlays under the way
     
    11351139                }
    11361140                g2d.draw(currentPath);
    11371141            }
    1138            
     1142
    11391143            if(useStrokes > dist)
    11401144                g2d.setStroke(new BasicStroke(1));
    11411145
  • src/org/openstreetmap/josm/data/osm/visitor/SimplePaintVisitor.java

     
    3636    public final static Color darkblue = new Color(0,0,128);
    3737    public final static Color darkgreen = new Color(0,128,0);
    3838    public final static Color teal = new Color(0,128,128);
     39    public final static Color lightteal= new Color(0, 255, 186);
    3940
    4041    /**
    4142     * The environment to paint to.
     
    6162    protected Color untaggedWayColor;
    6263    protected Color incompleteColor;
    6364    protected Color backgroundColor;
     65    protected Color highlightColor;
    6466    protected boolean showDirectionArrow;
    6567    protected boolean showRelevantDirectionsOnly;
    6668    protected boolean showHeadArrowOnly;
     
    9698        untaggedWayColor = Main.pref.getColor(marktr("untagged way"), darkgreen);
    9799        incompleteColor = Main.pref.getColor(marktr("incomplete way"), darkerblue);
    98100        backgroundColor = Main.pref.getColor(marktr("background"), Color.BLACK);
     101        highlightColor = Main.pref.getColor(marktr("highlight"), lightteal);
    99102    }
    100103
    101104    protected void getSettings(Boolean virtual) {
     
    131134            System.out.println("Simplepaint Profiler");
    132135
    133136        getSettings(virtual);
    134        
    135         if(profiler) 
     137
     138        if(profiler)
    136139        {
    137140            System.out.format("Prepare  : %4dms\n", (java.lang.System.currentTimeMillis()-profilerLast));
    138141            profilerLast = java.lang.System.currentTimeMillis();
    139142        }
    140        
     143
    141144        // draw tagged ways first, then untagged ways. takes
    142145        // time to iterate through list twice, OTOH does not
    143146        // require changing the colour while painting...
     
    244247
    245248        if (inactive)
    246249            drawNode(n, inactiveColor, unselectedNodeSize, unselectedNodeRadius, fillUnselectedNode);
     250        else if (n.highlighted)
     251            drawNode(n, highlightColor, selectedNodeSize, selectedNodeRadius, fillSelectedNode);
    247252        else if (n.selected)
    248253            drawNode(n, selectedColor, selectedNodeSize, selectedNodeRadius, fillSelectedNode);
    249254        else if(n.tagged)
     
    300305
    301306        if (inactive) {
    302307            wayColor = inactiveColor;
     308        } else if(w.highlighted) {
     309            wayColor = highlightColor;
     310        } else if(w.selected) {
     311            wayColor = selectedColor;
    303312        } else if (!w.tagged) {
    304313            wayColor = untaggedWayColor;
    305314        } else {
     
    311320            Point lastP = nc.getPoint(it.next().eastNorth);
    312321            for (int orderNumber = 1; it.hasNext(); orderNumber++) {
    313322                Point p = nc.getPoint(it.next().eastNorth);
    314                 drawSegment(lastP, p, w.selected && !inactive ? selectedColor : wayColor,
     323                drawSegment(lastP, p, wayColor,
    315324                    showOnlyHeadArrowOnly ? !it.hasNext() : showThisDirectionArrow);
    316325                if (showOrderNumber)
    317326                    drawOrderNumber(lastP, p, orderNumber);