Ticket #6323: create_new_mode_6323.patch

File create_new_mode_6323.patch, 8.6 KB (added by Hojoe, 11 years ago)

Here's my proposal. With the Alt modifier and a double click nodes can be added. Alt and mouse drag creates a new rectangle. This patch uses code from the first patch.

  • src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java

    ### Eclipse Workspace Patch 1.0
    #P JOSM
     
    44import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
    55import static org.openstreetmap.josm.tools.I18n.tr;
    66
     7import java.awt.AWTEvent;
    78import java.awt.BasicStroke;
    89import java.awt.Color;
    910import java.awt.Cursor;
    1011import java.awt.Graphics2D;
    1112import java.awt.Point;
    1213import java.awt.Rectangle;
     14import java.awt.Toolkit;
     15import java.awt.event.AWTEventListener;
    1316import java.awt.event.ActionEvent;
     17import java.awt.event.InputEvent;
    1418import java.awt.event.KeyEvent;
    1519import java.awt.event.MouseEvent;
    1620import java.awt.geom.AffineTransform;
     
    5054 */
    5155public class ExtrudeAction extends MapMode implements MapViewPaintable {
    5256
    53     enum Mode { extrude, translate, select }
     57    enum Mode { extrude, translate, select, create_new }
    5458
    5559    private Mode mode = Mode.select;
    5660
     
    97101     */
    98102    private MoveCommand moveCommand;
    99103
     104    /** The cursor for the 'create_new' mode. */
     105    private final Cursor cursorCreateNew;
     106
    100107    /**
     108     * This listener is used to indicate the 'create_new' mode, if the Alt modifier is pressed.
     109     */
     110    private final AWTEventListener altKeyListener = new AWTEventListener() {
     111        @Override
     112        public void eventDispatched(AWTEvent e) {
     113            if(Main.map == null || Main.map.mapView == null || !Main.map.mapView.isActiveLayerDrawable())
     114                return;
     115            InputEvent ie = (InputEvent) e;
     116            boolean alt = (ie.getModifiers() & (ActionEvent.ALT_MASK|InputEvent.ALT_GRAPH_MASK)) != 0;
     117            if(mode == Mode.select) {
     118                Main.map.mapView.setNewCursor(alt ? cursorCreateNew : cursor, this);
     119            }
     120        }
     121    };
     122
     123    /**
    101124     * Create a new SelectAction
    102125     * @param mapFrame The MapFrame this action belongs to.
    103126     */
     
    109132        putValue("help", ht("/Action/Extrude"));
    110133        initialMoveDelay = Main.pref.getInteger("edit.initial-move-delay",200);
    111134        selectedColor = PaintColors.SELECTED.get();
     135        cursorCreateNew = ImageProvider.getCursor("normal", "rectangle_plus");
    112136    }
    113137
    114138    @Override public String getModeHelpText() {
     
    116140            return tr("Move a segment along its normal, then release the mouse button.");
    117141        else if (mode == Mode.extrude)
    118142            return tr("Draw a rectangle of the desired size, then release the mouse button.");
     143        else if (mode == Mode.create_new)
     144            return tr("Draw a rectangle of the desired size, then release the mouse button.");
    119145        else
    120             return tr("Drag a way segment to make a rectangle. Ctrl-drag to move a segment along its normal.");
     146            return tr("Drag a way segment to make a rectangle. Ctrl-drag to move a segment along its normal, " +
     147            "Alt-drag to create a new rectangle, Alt-double click to add a new node.");
    121148    }
    122149
    123150    @Override public boolean layerIsSupported(Layer l) {
     
    128155        super.enterMode();
    129156        Main.map.mapView.addMouseListener(this);
    130157        Main.map.mapView.addMouseMotionListener(this);
     158        try {
     159            Toolkit.getDefaultToolkit().addAWTEventListener(altKeyListener, AWTEvent.KEY_EVENT_MASK);
     160        } catch (SecurityException ex) {
     161        }
    131162    }
    132163
    133164    @Override public void exitMode() {
    134165        Main.map.mapView.removeMouseListener(this);
    135166        Main.map.mapView.removeMouseMotionListener(this);
    136167        Main.map.mapView.removeTemporaryLayer(this);
     168        try {
     169            Toolkit.getDefaultToolkit().removeAWTEventListener(altKeyListener);
     170        } catch (SecurityException ex) {
     171        }
    137172        super.exitMode();
    138173    }
    139174
    140175    /**
    141176     * If the left mouse button is pressed over a segment, switch
    142      * to either extrude or translate mode depending on whether Ctrl is held.
     177     * to either extrude, translate or create_new mode depending on whether Ctrl or Alt is held.
    143178     */
    144179    @Override public void mousePressed(MouseEvent e) {
    145180        if(!Main.map.mapView.isActiveLayerVisible())
     
    158193
    159194            if ((e.getModifiers() & ActionEvent.CTRL_MASK) != 0) {
    160195                mode = Mode.translate;
     196            } else if ((e.getModifiers() & ActionEvent.ALT_MASK) != 0) {
     197                mode = Mode.create_new;
     198                // create a new segment and then select and extrude the new segment
     199                getCurrentDataSet().setSelected(selectedSegment.way);
     200                alwaysCreateNodes = true;
    161201            } else {
    162202                mode = Mode.extrude;
    163203                getCurrentDataSet().setSelected(selectedSegment.way);
     
    224264        if (mode == Mode.select) {
    225265            // Just sit tight and wait for mouse to be released.
    226266        } else {
    227             //move and extrude mode - move the selected segment
     267            //move, create new and extrude mode - move the selected segment
    228268
    229269            EastNorth initialMouseEn = Main.map.mapView.getEastNorth(initialMousePos.x, initialMousePos.y);
    230270            EastNorth mouseEn = Main.map.mapView.getEastNorth(e.getPoint().x, e.getPoint().y);
     
    260300
    261301            Main.map.mapView.setNewCursor(Cursor.MOVE_CURSOR, this);
    262302
    263             if (mode == Mode.extrude) {
     303            if (mode == Mode.extrude || mode == Mode.create_new) {
    264304                //nothing here
    265305            } else if (mode == Mode.translate) {
    266306                //move nodes to new position
     
    292332        if (mode == Mode.select) {
    293333            // Nothing to be done
    294334        } else {
    295             if (mode == Mode.extrude) {
     335            if (mode == Mode.create_new) {
     336                if( e.getClickCount() == 2 && e.getPoint().equals(initialMousePos) ) {
     337                    // alt + double click add a new node
     338                    // Should maybe do the same as in DrawAction and fetch all nearby segments?
     339                    WaySegment ws = Main.map.mapView.getNearestWaySegment(e.getPoint(), OsmPrimitive.isSelectablePredicate);
     340                    if (ws != null) {
     341                        Node n = new Node(Main.map.mapView.getLatLon(e.getX(), e.getY()));
     342                        EastNorth A = ws.getFirstNode().getEastNorth();
     343                        EastNorth B = ws.getSecondNode().getEastNorth();
     344                        n.setEastNorth(Geometry.closestPointToSegment(A, B, n.getEastNorth()));
     345                        Way wnew = new Way(ws.way);
     346                        wnew.addNode(ws.lowerIndex+1, n);
     347                        SequenceCommand cmds = new SequenceCommand(tr("Add a new node to an existing way"),
     348                                new AddCommand(n), new ChangeCommand(ws.way, wnew));
     349                        Main.main.undoRedo.add(cmds);
     350                    }
     351                }
     352                else if (e.getPoint().distance(initialMousePos) > 10 && newN1en != null) {
     353                    // crete a new rectangle
     354                    Collection<Command> cmds = new LinkedList<Command>();
     355                    Node third = new Node(newN2en);
     356                    Node fourth = new Node(newN1en);
     357                    Way wnew = new Way();
     358                    wnew.addNode(selectedSegment.getFirstNode());
     359                    wnew.addNode(selectedSegment.getSecondNode());
     360                    wnew.addNode(third);
     361                    wnew.addNode(fourth);
     362                    // ... and close the way
     363                    wnew.addNode(selectedSegment.getFirstNode());
     364                    // undo support
     365                    cmds.add(new AddCommand(third));
     366                    cmds.add(new AddCommand(fourth));
     367                    cmds.add(new AddCommand(wnew));
     368                    Command c = new SequenceCommand(tr("Extrude Way"), cmds);
     369                    Main.main.undoRedo.add(c);
     370                    getCurrentDataSet().setSelected(wnew);
     371                }
     372            } else if (mode == Mode.extrude) {
    296373                if (e.getPoint().distance(initialMousePos) > 10 && newN1en != null) {
    297374                    // create extrusion
    298375
     
    438515                Point p3 = mv.getPoint(newN1en);
    439516                Point p4 = mv.getPoint(newN2en);
    440517
    441                 if (mode == Mode.extrude) {
     518                if (mode == Mode.extrude || mode == Mode.create_new) {
    442519                    // Draw rectangle around new area.
    443520                    GeneralPath b = new GeneralPath();
    444521                    b.moveTo(p1.x, p1.y); b.lineTo(p3.x, p3.y);