Changeset 5506 in josm for trunk/src/org/openstreetmap/josm/actions/mapmode
- Timestamp:
- 2012-09-08T15:08:25+02:00 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java ¶
r4982 r5506 3 3 4 4 import static org.openstreetmap.josm.gui.help.HelpUtil.ht; 5 import static org.openstreetmap.josm.tools.I18n.marktr; 5 6 import static org.openstreetmap.josm.tools.I18n.tr; 6 7 … … 63 64 */ 64 65 private boolean alwaysCreateNodes = false; 66 65 67 private long mouseDownTime = 0; 66 68 private WaySegment selectedSegment = null; … … 68 70 69 71 /** 72 * drawing settings for helper lines 73 */ 74 private Color helperColor; 75 private BasicStroke helperStrokeDash; 76 private BasicStroke helperStrokeRA; 77 78 /** 70 79 * Possible directions to move to. 71 80 */ 72 private List< EastNorth> possibleMoveDirections;81 private List<ReferenceSegment> possibleMoveDirections; 73 82 74 83 /** 75 84 * The direction that is currently active. 76 85 */ 77 private EastNorthactiveMoveDirection;86 private ReferenceSegment activeMoveDirection; 78 87 79 88 /** … … 104 113 /** The cursor for the 'create_new' mode. */ 105 114 private final Cursor cursorCreateNew; 115 116 /** The cursor for the 'translate' mode. */ 117 private final Cursor cursorTranslate; 118 119 /** The cursor for the 'alwaysCreateNodes' submode. */ 120 private final Cursor cursorCreateNodes; 121 122 private class ReferenceSegment { 123 public final EastNorth en; 124 public final WaySegment ws; 125 public final boolean perpendicular; 126 127 public ReferenceSegment(EastNorth en, WaySegment ws, boolean perpendicular) { 128 this.en = en; 129 this.ws = ws; 130 this.perpendicular = perpendicular; 131 } 132 } 106 133 107 134 /** … … 115 142 InputEvent ie = (InputEvent) e; 116 143 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); 144 boolean ctrl = (ie.getModifiers() & (ActionEvent.CTRL_MASK)) != 0; 145 boolean shift = (ie.getModifiers() & (ActionEvent.SHIFT_MASK)) != 0; 146 if (mode == Mode.select) { 147 Main.map.mapView.setNewCursor(ctrl ? cursorTranslate : alt ? cursorCreateNew : shift ? cursorCreateNodes : cursor, this); 119 148 } 120 149 } … … 134 163 selectedColor = PaintColors.SELECTED.get(); 135 164 cursorCreateNew = ImageProvider.getCursor("normal", "rectangle_plus"); 165 cursorTranslate = ImageProvider.getCursor("normal", "rectangle_move"); 166 cursorCreateNodes = ImageProvider.getCursor("normal", "rectangle_plussmall"); 167 helperColor = Main.pref.getColor(marktr("Extrude: helper line"), Color.ORANGE); 168 float dash1[] = { 4.0f }; 169 helperStrokeDash = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, 170 BasicStroke.JOIN_MITER, 10.0f, dash1, 0.0f); 171 helperStrokeRA = new BasicStroke(1); 136 172 } 137 173 … … 212 248 213 249 //gather possible move directions - perpendicular to the selected segment and parallel to neighbor segments 214 possibleMoveDirections = new ArrayList< EastNorth>();215 possibleMoveDirections.add(new EastNorth( 250 possibleMoveDirections = new ArrayList<ReferenceSegment>(); 251 possibleMoveDirections.add(new ReferenceSegment(new EastNorth( 216 252 initialN1en.getY() - initialN2en.getY(), 217 initialN2en.getX() - initialN1en.getX())); 253 initialN2en.getX() - initialN1en.getX() 254 ), selectedSegment, true)); 218 255 219 256 //add directions parallel to neighbor segments … … 222 259 if (prevNode != null) { 223 260 EastNorth en = prevNode.getEastNorth(); 224 possibleMoveDirections.add(new EastNorth( 261 possibleMoveDirections.add(new ReferenceSegment(new EastNorth( 225 262 initialN1en.getX() - en.getX(), 226 initialN1en.getY() - en.getY())); 263 initialN1en.getY() - en.getY() 264 ), new WaySegment(selectedSegment.way, getPreviousNodeIndex(selectedSegment.lowerIndex)), false)); 227 265 } 228 266 … … 230 268 if (nextNode != null) { 231 269 EastNorth en = nextNode.getEastNorth(); 232 possibleMoveDirections.add(new EastNorth( 270 possibleMoveDirections.add(new ReferenceSegment(new EastNorth( 233 271 initialN2en.getX() - en.getX(), 234 initialN2en.getY() - en.getY())); 272 initialN2en.getY() - en.getY() 273 ), new WaySegment(selectedSegment.way, getPreviousNodeIndex(getNextNodeIndex(getNextNodeIndex(selectedSegment.lowerIndex)))), false)); 235 274 } 236 275 … … 278 317 279 318 //find the best movement direction and vector 280 for ( EastNorthdirection: possibleMoveDirections) {281 EastNorth movement = calculateSegmentOffset(initialN1en, initialN2en, direction 319 for (ReferenceSegment direction : possibleMoveDirections) { 320 EastNorth movement = calculateSegmentOffset(initialN1en, initialN2en, direction.en, mouseEn); 282 321 if (movement == null) { 283 322 //if direction parallel to segment. … … 429 468 430 469 boolean alt = (e.getModifiers() & (ActionEvent.ALT_MASK|InputEvent.ALT_GRAPH_MASK)) != 0; 470 boolean ctrl = (e.getModifiers() & (ActionEvent.CTRL_MASK)) != 0; 471 boolean shift = (e.getModifiers() & (ActionEvent.SHIFT_MASK)) != 0; 431 472 // Switch back into select mode 432 Main.map.mapView.setNewCursor(alt ? cursorCreateNew : cursor, this); 473 Main.map.mapView.setNewCursor(ctrl ? cursorTranslate : alt ? cursorCreateNew : shift ? cursorCreateNodes : cursor, this); 433 474 Main.map.mapView.removeTemporaryLayer(this); 434 475 selectedSegment = null; … … 475 516 } 476 517 518 /** 519 * Gets a node from selected way before given index. 520 * @param index index of current node 521 * @return index of previous node or -1 if there are no nodes there. 522 */ 523 private int getPreviousNodeIndex(int index) { 524 if (index > 0) 525 return index - 1; 526 else if (selectedSegment.way.isClosed()) 527 return selectedSegment.way.getNodesCount() - 2; 528 else 529 return -1; 530 } 477 531 478 532 /** … … 482 536 */ 483 537 private Node getPreviousNode(int index) { 484 if (index > 0) 485 return selectedSegment.way.getNode(index - 1); 486 else if (selectedSegment.way.isClosed()) 487 return selectedSegment.way.getNode(selectedSegment.way.getNodesCount() - 2); 538 int indexPrev = getPreviousNodeIndex(index); 539 if (indexPrev >= 0) 540 return selectedSegment.way.getNode(indexPrev); 488 541 else 489 542 return null; 490 543 } 491 544 492 /** 493 * Gets a node from selected way before given index. 545 546 /** 547 * Gets a node from selected way after given index. 548 * @param index index of current node 549 * @return index of next node or -1 if there are no nodes there. 550 */ 551 private int getNextNodeIndex(int index) { 552 int count = selectedSegment.way.getNodesCount(); 553 if (index < count - 1) 554 return index + 1; 555 else if (selectedSegment.way.isClosed()) 556 return 1; 557 else 558 return -1; 559 } 560 561 /** 562 * Gets a node from selected way after given index. 494 563 * @param index index of current node 495 564 * @return next node or null if there are no nodes there. 496 565 */ 497 566 private Node getNextNode(int index) { 498 int count = selectedSegment.way.getNodesCount(); 499 if (index < count - 1) 500 return selectedSegment.way.getNode(index + 1); 501 else if (selectedSegment.way.isClosed()) 502 return selectedSegment.way.getNode(1); 567 int indexNext = getNextNodeIndex(index); 568 if (indexNext >= 0) 569 return selectedSegment.way.getNode(indexNext); 503 570 else 504 571 return null; … … 519 586 Point p4 = mv.getPoint(newN2en); 520 587 588 double fac = 1.0 / activeMoveDirection.en.distance(0,0); 589 // mult by factor to get unit vector. 590 EastNorth normalUnitVector = new EastNorth(activeMoveDirection.en.getX() * fac, activeMoveDirection.en.getY() * fac); 591 592 // Check to see if our new N1 is in a positive direction with respect to the normalUnitVector. 593 // Even if the x component is zero, we should still be able to discern using +0.0 and -0.0 594 if (newN1en != null && ((newN1en.getX() > initialN1en.getX()) != (normalUnitVector.getX() > -0.0))) { 595 // If not, use a sign-flipped version of the normalUnitVector. 596 normalUnitVector = new EastNorth(-normalUnitVector.getX(), -normalUnitVector.getY()); 597 } 598 599 //HACK: swap Y, because the target pixels are top down, but EastNorth is bottom-up. 600 //This is normally done by MapView.getPoint, but it does not work on vectors. 601 normalUnitVector.setLocation(normalUnitVector.getX(), -normalUnitVector.getY()); 602 521 603 if (mode == Mode.extrude || mode == Mode.create_new) { 522 604 // Draw rectangle around new area. … … 526 608 b.lineTo(p1.x, p1.y); 527 609 g2.draw(b); 528 g2.setStroke(new BasicStroke(1)); 610 611 if (activeMoveDirection != null) { 612 // Draw reference way 613 Point pr1 = mv.getPoint(activeMoveDirection.ws.getFirstNode().getEastNorth()); 614 Point pr2 = mv.getPoint(activeMoveDirection.ws.getSecondNode().getEastNorth()); 615 b = new GeneralPath(); 616 b.moveTo(pr1.x, pr1.y); 617 b.lineTo(pr2.x, pr2.y); 618 g2.setColor(helperColor); 619 g2.setStroke(helperStrokeDash); 620 g2.draw(b); 621 622 // Draw right angle marker on first node position, only when moving at right angle 623 if (activeMoveDirection.perpendicular) { 624 // mirror RightAngle marker, so it is inside the extrude 625 double headingRefWS = activeMoveDirection.ws.getFirstNode().getEastNorth().heading(activeMoveDirection.ws.getSecondNode().getEastNorth()); 626 double headingMoveDir = Math.atan2(normalUnitVector.getY(), normalUnitVector.getX()); 627 double headingDiff = headingRefWS - headingMoveDir; 628 if (headingDiff < 0) headingDiff += 2 * Math.PI; 629 boolean mirrorRA = Math.abs(headingDiff - Math.PI) > 1e-5; 630 631 // EastNorth units per pixel 632 double factor = 1.0/g2.getTransform().getScaleX(); 633 double raoffsetx = 8.0*factor*normalUnitVector.getX(); 634 double raoffsety = 8.0*factor*normalUnitVector.getY(); 635 636 Point2D ra1 = new Point2D.Double(pr1.x + raoffsetx, pr1.y+raoffsety); 637 Point2D ra3 = new Point2D.Double(pr1.x - raoffsety*(mirrorRA ? -1 : 1), pr1.y + raoffsetx*(mirrorRA ? -1 : 1)); 638 Point2D ra2 = new Point2D.Double(ra1.getX() - raoffsety*(mirrorRA ? -1 : 1), ra1.getY() + raoffsetx*(mirrorRA ? -1 : 1)); 639 GeneralPath ra = new GeneralPath(); 640 ra.moveTo((float)ra1.getX(), (float)ra1.getY()); 641 ra.lineTo((float)ra2.getX(), (float)ra2.getY()); 642 ra.lineTo((float)ra3.getX(), (float)ra3.getY()); 643 g2.setStroke(helperStrokeRA); 644 g2.draw(ra); 645 } 646 } 529 647 } else if (mode == Mode.translate) { 530 648 // Highlight the new and old segments. … … 537 655 if (activeMoveDirection != null) { 538 656 539 double fac = 1.0 / activeMoveDirection.distance(0,0);540 // mult by factor to get unit vector.541 EastNorth normalUnitVector = new EastNorth(activeMoveDirection.getX() * fac, activeMoveDirection.getY() * fac);542 543 // Check to see if our new N1 is in a positive direction with respect to the normalUnitVector.544 // Even if the x component is zero, we should still be able to discern using +0.0 and -0.0545 if (newN1en != null && (newN1en.getX() > initialN1en.getX() != normalUnitVector.getX() > -0.0)) {546 // If not, use a sign-flipped version of the normalUnitVector.547 normalUnitVector = new EastNorth(-normalUnitVector.getX(), -normalUnitVector.getY());548 }549 550 //HACK: swap Y, because the target pixels are top down, but EastNorth is bottom-up.551 //This is normally done by MapView.getPoint, but it does not work on vectors.552 normalUnitVector.setLocation(normalUnitVector.getX(), -normalUnitVector.getY());553 554 657 // Draw a guideline along the normal. 555 658 Line2D normline; … … 559 662 560 663 // Draw right angle marker on initial position, only when moving at right angle 561 if (activeMoveDirection == possibleMoveDirections.get(0)) {664 if (activeMoveDirection.perpendicular) { 562 665 // EastNorth units per pixel 563 666 double factor = 1.0/g2.getTransform().getScaleX();
Note:
See TracChangeset
for help on using the changeset viewer.