Changeset 8550 in josm
- Timestamp:
- 2015-07-01T20:20:33+02:00 (9 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java
r8540 r8550 586 586 587 587 if (mode == Mode.SELECT) { 588 if (e.getButton() != MouseEvent.BUTTON1) { 589 return; 590 } 591 selectionManager.endSelecting(e); 588 592 selectionManager.unregister(mv); 589 593 -
trunk/src/org/openstreetmap/josm/gui/SelectionManager.java
r8512 r8550 2 2 package org.openstreetmap.josm.gui; 3 3 4 import java.awt.Component; 4 import java.awt.Color; 5 import java.awt.Graphics2D; 5 6 import java.awt.Point; 6 7 import java.awt.Polygon; … … 17 18 import org.openstreetmap.josm.Main; 18 19 import org.openstreetmap.josm.actions.SelectByInternalPointAction; 20 import org.openstreetmap.josm.data.Bounds; 19 21 import org.openstreetmap.josm.data.osm.Node; 20 22 import org.openstreetmap.josm.data.osm.OsmPrimitive; 21 23 import org.openstreetmap.josm.data.osm.Way; 24 import org.openstreetmap.josm.data.osm.visitor.paint.PaintColors; 25 import org.openstreetmap.josm.gui.layer.MapViewPaintable; 26 import org.openstreetmap.josm.tools.Utils; 22 27 23 28 /** 24 * Manages the selection of a rectangle . Listening to left and right mouse button29 * Manages the selection of a rectangle or a lasso loop. Listening to left and right mouse button 25 30 * presses and to mouse motions and draw the rectangle accordingly. 26 31 * 27 32 * Left mouse button selects a rectangle from the press until release. Pressing 28 * right mouse button while left is still pressed enable the rectangleto move33 * right mouse button while left is still pressed enable the selection area to move 29 34 * around. Releasing the left button fires an action event to the listener given 30 35 * at constructor, except if the right is still pressed, which just remove the 31 36 * selection rectangle and does nothing. 32 37 * 38 * It is possible to switch between lasso selection and rectangle selection by using {@link #setLassoMode(boolean)}. 39 * 33 40 * The point where the left mouse button was pressed and the current mouse 34 41 * position are two opposite corners of the selection rectangle. 35 42 * 36 * It is possible to specify an aspect ratio (width per height) which the43 * For rectangle mode, it is possible to specify an aspect ratio (width per height) which the 37 44 * selection rectangle always must have. In this case, the selection rectangle 38 45 * will be the largest window with this aspect ratio, where the position the left … … 56 63 /** 57 64 * Called, when the left mouse button was released. 58 * @param r The rectangle that is currently theselection.65 * @param r The rectangle that encloses the current selection. 59 66 * @param e The mouse event. 60 67 * @see InputEvent#getModifiersEx() 68 * @see SelectionManager#getSelectedObjects(boolean) 61 69 */ 62 70 void selectionEnded(Rectangle r, MouseEvent e); … … 75 83 void removePropertyChangeListener(PropertyChangeListener listener); 76 84 } 85 86 /** 87 * This draws the selection hint (rectangle or lasso polygon) on the screen. 88 * 89 * @author Michael Zangl 90 */ 91 private class SelectionHintLayer implements MapViewPaintable { 92 @Override 93 public void paint(Graphics2D g, MapView mv, Bounds bbox) { 94 if (mousePos == null || mousePosStart == null || mousePos == mousePosStart) 95 return; 96 Color color = Utils.complement(PaintColors.getBackgroundColor()); 97 g.setColor(color); 98 if (lassoMode) { 99 g.drawPolygon(lasso); 100 101 g.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha() / 8)); 102 g.fillPolygon(lasso); 103 } else { 104 Rectangle paintRect = getSelectionRectangle(); 105 g.drawRect(paintRect.x, paintRect.y, paintRect.width, paintRect.height); 106 } 107 } 108 } 109 77 110 /** 78 111 * The listener that receives the events after left mouse button is released. … … 81 114 /** 82 115 * Position of the map when the mouse button was pressed. 83 * If this is not <code>null</code>, a rectangle is drawn on screen. 116 * If this is not <code>null</code>, a rectangle/lasso line is drawn on screen. 117 * If this is <code>null</code>, no selection is active. 84 118 */ 85 119 private Point mousePosStart; 86 120 /** 87 * Position of the map when the selection rectangle was last drawn.121 * The last position of the mouse while the mouse button was pressed. 88 122 */ 89 123 private Point mousePos; 90 124 /** 91 * The Component , the selection rectangle is drawn onto.125 * The Component that provides us with OSM data and the aspect is taken from. 92 126 */ 93 127 private final NavigatableComponent nc; … … 98 132 private boolean aspectRatio; 99 133 134 /** 135 * <code>true</code> if we should paint a lasso instead of a rectangle. 136 */ 100 137 private boolean lassoMode; 138 /** 139 * The polygon to store the selection outline if {@link #lassoMode} is used. 140 */ 101 141 private Polygon lasso = new Polygon(); 142 143 /** 144 * The result of the last selection. 145 */ 146 private Polygon selectionResult = new Polygon(); 147 148 private final SelectionHintLayer selectionHintLayer = new SelectionHintLayer(); 102 149 103 150 /** … … 108 155 * @param aspectRatio If true, the selection window must obtain the aspect 109 156 * ratio of the drawComponent. 110 * @param navComp The component , the rectangle is drawn onto.157 * @param navComp The component that provides us with OSM data and the aspect is taken from. 111 158 */ 112 159 public SelectionManager(SelectionEnded selectionEndedListener, boolean aspectRatio, NavigatableComponent navComp) { … … 117 164 118 165 /** 119 * Register itself at the given event source .166 * Register itself at the given event source and add a hint layer. 120 167 * @param eventSource The emitter of the mouse events. 121 168 * @param lassoMode {@code true} to enable lasso mode, {@code false} to disable it. 122 169 */ 123 public void register( NavigatableComponenteventSource, boolean lassoMode) {170 public void register(MapView eventSource, boolean lassoMode) { 124 171 this.lassoMode = lassoMode; 125 172 eventSource.addMouseListener(this); … … 129 176 @Override 130 177 public void propertyChange(PropertyChangeEvent evt) { 131 if (mousePosStart != null) { 132 paintRect(); 133 mousePos = mousePosStart = null; 134 } 178 abortSelecting(); 135 179 } 136 180 }); 137 }138 /**139 * Unregister itself from the given event source. If a selection rectangle is140 * shown, hide it first.181 eventSource.addTemporaryLayer(selectionHintLayer); 182 } 183 /** 184 * Unregister itself from the given event source and hide the selection hint layer. 141 185 * 142 186 * @param eventSource The emitter of the mouse events. 143 187 */ 144 public void unregister(Component eventSource) { 188 public void unregister(MapView eventSource) { 189 abortSelecting(); 190 eventSource.removeTemporaryLayer(selectionHintLayer); 145 191 eventSource.removeMouseListener(this); 146 192 eventSource.removeMouseMotionListener(this); … … 176 222 mousePosStart = mousePos = e.getPoint(); 177 223 } 178 if (!lassoMode) { 179 paintRect(); 180 } 224 selectionAreaChanged(); 181 225 } 182 226 183 227 if (buttonPressed == MouseEvent.BUTTON1_DOWN_MASK) { 184 228 mousePos = e.getPoint(); 185 if (lassoMode) { 186 paintLasso(); 187 } else { 188 paintRect(); 189 } 229 addLassoPoint(e.getPoint()); 230 selectionAreaChanged(); 190 231 } else if (buttonPressed == (MouseEvent.BUTTON1_DOWN_MASK | MouseEvent.BUTTON3_DOWN_MASK)) { 191 mousePosStart.x += e.getX()-mousePos.x; 192 mousePosStart.y += e.getY()-mousePos.y; 232 moveSelection(e.getX()-mousePos.x, e.getY()-mousePos.y); 193 233 mousePos = e.getPoint(); 194 paintRect(); 195 } 234 selectionAreaChanged(); 235 } 236 } 237 238 /** 239 * Moves the current selection by some pixels. 240 * @param dx How much to move it in x direction. 241 * @param dy How much to move it in y direction. 242 */ 243 private void moveSelection(int dx, int dy) { 244 mousePosStart.x += dx; 245 mousePosStart.y += dy; 246 lasso.translate(dx, dy); 196 247 } 197 248 … … 201 252 @Override 202 253 public void mouseReleased(MouseEvent e) { 203 if (e.getButton() != MouseEvent.BUTTON1) 254 if (e.getButton() == MouseEvent.BUTTON1) { 255 endSelecting(e); 256 } 257 } 258 259 /** 260 * Ends the selection of the current area. This simulates a release of mouse button 1. 261 * @param e A mouse event that caused this. Needed for backward compatibility. 262 */ 263 public void endSelecting(MouseEvent e) { 264 mousePos = e.getPoint(); 265 if (lassoMode) { 266 addLassoPoint(e.getPoint()); 267 } 268 269 // Left mouse was released while right is still pressed. 270 boolean rightMouseStillPressed = (e.getModifiersEx() & MouseEvent.BUTTON3_DOWN_MASK) != 0; 271 272 if (!rightMouseStillPressed) { 273 selectingDone(e); 274 } 275 abortSelecting(); 276 } 277 278 private void addLassoPoint(Point point) { 279 if (isNoSelection()) { 204 280 return; 205 if (mousePos == null || mousePosStart == null) 206 return; // injected release from outside 207 // disable the selection rect 208 Rectangle r; 209 if (!lassoMode) { 210 nc.requestClearRect(); 211 r = getSelectionRectangle(); 212 213 lasso = rectToPolygon(r); 214 } else { 215 nc.requestClearPoly(); 216 lasso.addPoint(mousePos.x, mousePos.y); 217 r = lasso.getBounds(); 218 } 219 mousePosStart = null; 220 mousePos = null; 221 222 if ((e.getModifiersEx() & MouseEvent.BUTTON3_DOWN_MASK) == 0) { 223 selectionEndedListener.selectionEnded(r, e); 224 } 225 } 226 227 /** 228 * Draws a selection rectangle on screen. 229 */ 230 private void paintRect() { 231 if (mousePos == null || mousePosStart == null || mousePos == mousePosStart) 232 return; 233 nc.requestPaintRect(getSelectionRectangle()); 234 } 235 236 private void paintLasso() { 237 if (mousePos == null || mousePosStart == null || mousePos == mousePosStart) { 238 return; 239 } 240 lasso.addPoint(mousePos.x, mousePos.y); 241 nc.requestPaintPoly(lasso); 281 } 282 lasso.addPoint(point.x, point.y); 283 } 284 285 private boolean isNoSelection() { 286 return mousePos == null || mousePosStart == null || mousePos == mousePosStart; 242 287 } 243 288 … … 287 332 @Override 288 333 public void propertyChange(PropertyChangeEvent evt) { 289 if ("active".equals(evt.getPropertyName()) && !(Boolean) evt.getNewValue() && mousePosStart != null) { 290 paintRect(); 291 mousePosStart = null; 292 mousePos = null; 293 } 294 } 295 296 /** 297 * Return a list of all objects in the selection, respecting the different 334 if ("active".equals(evt.getPropertyName()) && !(Boolean)evt.getNewValue()) { 335 abortSelecting(); 336 } 337 } 338 339 /** 340 * Stores the current selection and stores the result in {@link #selectionResult} to be retrieved by {@link #getSelectedObjects(boolean)} later. 341 * @param e The mouse event that caused the selection to be finished. 342 */ 343 private void selectingDone(MouseEvent e) { 344 if (isNoSelection()) { 345 // Nothing selected. 346 return; 347 } 348 Rectangle r; 349 if (lassoMode) { 350 r = lasso.getBounds(); 351 352 selectionResult = new Polygon(lasso.xpoints, lasso.ypoints, lasso.npoints); 353 } else { 354 r = getSelectionRectangle(); 355 356 selectionResult = rectToPolygon(r); 357 } 358 selectionEndedListener.selectionEnded(r, e); 359 } 360 361 private void abortSelecting() { 362 if (mousePosStart != null) { 363 mousePos = mousePosStart = null; 364 lasso.reset(); 365 selectionAreaChanged(); 366 } 367 } 368 369 private void selectionAreaChanged() { 370 // Trigger a redraw of the map view. 371 // A nicer way would be to provide change events for the temporary layer. 372 Main.map.mapView.repaint(); 373 } 374 375 /** 376 * Return a list of all objects in the active/last selection, respecting the different 298 377 * modifier. 299 378 * … … 308 387 // whether user only clicked, not dragged. 309 388 boolean clicked = false; 310 Rectangle bounding = lasso.getBounds();389 Rectangle bounding = selectionResult.getBounds(); 311 390 if (bounding.height <= 2 && bounding.width <= 2) { 312 391 clicked = true; … … 314 393 315 394 if (clicked) { 316 Point center = new Point( lasso.xpoints[0], lasso.ypoints[0]);395 Point center = new Point(selectionResult.xpoints[0], selectionResult.ypoints[0]); 317 396 OsmPrimitive osm = nc.getNearestNodeOrWay(center, OsmPrimitive.isSelectablePredicate, false); 318 397 if (osm != null) { … … 322 401 // nodes 323 402 for (Node n : nc.getCurrentDataSet().getNodes()) { 324 if (n.isSelectable() && lasso.contains(nc.getPoint2D(n))) {403 if (n.isSelectable() && selectionResult.contains(nc.getPoint2D(n))) { 325 404 selection.add(n); 326 405 } … … 334 413 if (alt) { 335 414 for (Node n : w.getNodes()) { 336 if (!n.isIncomplete() && lasso.contains(nc.getPoint2D(n))) {415 if (!n.isIncomplete() && selectionResult.contains(nc.getPoint2D(n))) { 337 416 selection.add(w); 338 417 break; … … 342 421 boolean allIn = true; 343 422 for (Node n : w.getNodes()) { 344 if (!n.isIncomplete() && ! lasso.contains(nc.getPoint(n))) {423 if (!n.isIncomplete() && !selectionResult.contains(nc.getPoint(n))) { 345 424 allIn = false; 346 425 break;
Note:
See TracChangeset
for help on using the changeset viewer.