1 package org.xpilot.jxpmap; 2 3 import java.awt.Color; 4 import java.awt.Dimension; 5 import java.awt.Graphics; 6 import java.awt.Graphics2D; 7 import java.awt.Point; 8 import java.awt.Rectangle; 9 import java.awt.Shape; 10 import java.awt.RenderingHints; 11 import java.awt.event.MouseEvent; 12 import java.awt.event.InputEvent; 13 import java.awt.geom.AffineTransform; 14 import java.math.BigDecimal; 15 import java.util.List; 16 import java.util.ArrayList; 17 import java.util.Iterator; 18 import java.util.Map; 19 20 import javax.swing.JComponent; 21 import javax.swing.undo.AbstractUndoableEdit; 22 import javax.swing.undo.CompoundEdit; 23 import javax.swing.undo.UndoManager; 24 import javax.swing.undo.UndoableEdit; 25 26 public class MapCanvas extends JComponent { 27 28 public static final int MODE_SELECT = 0; 29 public static final int MODE_EDIT = 1; 30 public static final int MODE_ERASE = 2; 31 public static final int MODE_COPY = 3; 32 33 private MapModel model; 34 private float scale; 35 private AffineTransform at, it; 36 private CanvasEventHandler eventHandler; 37 private CanvasEventHandler dragHandler, selectHandler; 38 private int mode; 39 private Point offset; 40 private UndoManager undoManager; 41 private MapEdit currentEdit; 42 private boolean fastRendering; 43 private List selected; 44 private int grid; 45 MapCanvas()46 public MapCanvas() { 47 48 setOpaque(true); 49 offset = new Point(0, 0); 50 AwtEventHandler handler = new AwtEventHandler(); 51 addMouseListener(handler); 52 addMouseMotionListener(handler); 53 undoManager = new UndoManager(); 54 dragHandler = new DragHandler(); 55 selectHandler = new SelectHandler(); 56 selected = new ArrayList(); 57 grid = -1; 58 mode = MODE_SELECT; 59 } 60 setCanvasEventHandler(CanvasEventHandler h)61 public void setCanvasEventHandler(CanvasEventHandler h) { 62 eventHandler = h; 63 } 64 getCanvasEventHandler()65 public CanvasEventHandler getCanvasEventHandler() { 66 return eventHandler; 67 } 68 getUndoManager()69 public UndoManager getUndoManager() { 70 return undoManager; 71 } 72 getModel()73 public MapModel getModel() { 74 return model; 75 } 76 setFastRendering(boolean value)77 public void setFastRendering(boolean value) { 78 this.fastRendering = value; 79 } 80 isFastRendering()81 public boolean isFastRendering() { 82 return this.fastRendering; 83 } 84 getSelectedObjects()85 public List getSelectedObjects() { 86 return selected; 87 } 88 setSelectedObject(MapObject object)89 public void setSelectedObject(MapObject object) { 90 if (!selected.isEmpty()) { 91 for (Iterator i = selected.iterator(); i.hasNext();) 92 ((MapObject)i.next()).setSelected(false); 93 } 94 selected.clear(); 95 if (object != null) { 96 object.setSelected(true); 97 selected.add(object); 98 } 99 } 100 addSelectedObject(MapObject object)101 public void addSelectedObject(MapObject object) { 102 object.setSelected(true); 103 selected.add(object); 104 } 105 setModel(MapModel m)106 public void setModel(MapModel m) { 107 this.model = m; 108 this.scale = m.getDefaultScale(); 109 this.at = null; 110 this.it = null; 111 eventHandler = null; 112 repaint(); 113 } 114 getScale()115 public float getScale() { 116 return scale; 117 } 118 setScale(float s)119 public void setScale(float s) { 120 this.offset.x = (int)(this.offset.x * s / this.scale); 121 this.offset.y = (int)(this.offset.y * s / this.scale); 122 this.scale = s; 123 this.at = null; 124 this.it = null; 125 eventHandler = null; 126 revalidate(); 127 } 128 setMode(int mode)129 public void setMode(int mode) { 130 this.mode = mode; 131 } 132 getMode()133 public int getMode() { 134 return mode; 135 } 136 setGrid(int grid)137 public void setGrid(int grid) { 138 this.grid = grid; 139 } 140 getGrid()141 public int getGrid() { 142 return grid; 143 } 144 paint(Graphics _g)145 public void paint(Graphics _g) { 146 147 if (model == null) 148 return; 149 150 Graphics2D g = (Graphics2D) _g; 151 if (fastRendering) 152 g.setRenderingHint(RenderingHints.KEY_RENDERING, 153 RenderingHints.VALUE_RENDER_SPEED); 154 Dimension mapSize = model.options.getSize(); 155 156 g.setColor(Color.black); 157 g.fill(g.getClipBounds()); 158 159 AffineTransform rootTx = new AffineTransform(g.getTransform()); 160 rootTx.concatenate(getTransform()); 161 g.setTransform(rootTx); 162 163 g.setColor(Color.red); 164 Rectangle world = new Rectangle(0, 0, mapSize.width, mapSize.height); 165 g.draw(world); 166 //drawShapeNoTx(g, world); 167 168 Rectangle view = g.getClipBounds(); 169 Point min = new Point(); 170 Point max = new Point(); 171 172 for (int i = model.objects.size() - 1; i >= 0; i--) { 173 MapObject o = (MapObject) model.objects.get(i); 174 computeBounds(min, max, view, o.getBounds(), mapSize); 175 176 for (int xoff = min.x; xoff <= max.x; xoff++) { 177 for (int yoff = min.y; yoff <= max.y; yoff++) { 178 179 AffineTransform tx = new AffineTransform(rootTx); 180 tx.translate(xoff * mapSize.width, yoff * mapSize.height); 181 g.setTransform(tx); 182 o.paint(g, scale); 183 } 184 } 185 } 186 g.setTransform(rootTx); 187 } 188 drawShape(Graphics2D g, Shape s)189 public void drawShape(Graphics2D g, Shape s) { 190 if (g.getClipBounds() == null) 191 g.setClip(getBounds()); 192 AffineTransform origTx = g.getTransform(); 193 AffineTransform rootTx = new AffineTransform(origTx); 194 rootTx.concatenate(getTransform()); 195 g.setTransform(rootTx); 196 drawShapeNoTx(g, s); 197 g.setTransform(origTx); 198 } 199 drawShapeNoTx(Graphics2D g, Shape s)200 private void drawShapeNoTx(Graphics2D g, Shape s) { 201 202 Rectangle view = g.getClipBounds(); 203 AffineTransform origTx = g.getTransform(); 204 Point min = new Point(); 205 Point max = new Point(); 206 Dimension mapSize = model.options.getSize(); 207 208 computeBounds(min, max, view, s.getBounds(), mapSize); 209 210 AffineTransform tx = new AffineTransform(); 211 for (int xoff = min.x; xoff <= max.x; xoff++) { 212 for (int yoff = min.y; yoff <= max.y; yoff++) { 213 tx.setTransform(origTx); 214 tx.translate(xoff * mapSize.width, yoff * mapSize.height); 215 g.setTransform(tx); 216 g.draw(s); 217 } 218 } 219 220 g.setTransform(origTx); 221 } 222 computeBounds( Point min, Point max, Rectangle view, Rectangle b, Dimension map)223 private void computeBounds( 224 Point min, 225 Point max, 226 Rectangle view, 227 Rectangle b, 228 Dimension map) { 229 if (model.options.isEdgeWrap()) { 230 min.x = (view.x - (b.x + b.width)) / map.width; 231 if (view.x > b.x + b.width) 232 min.x++; 233 max.x = (view.x + view.width - b.x) / map.width; 234 if (view.x + view.width < b.x) 235 max.x--; 236 min.y = (view.y - (b.y + b.height)) / map.height; 237 if (view.y > b.y + b.height) 238 min.y++; 239 max.y = (view.y + view.height - b.y) / map.height; 240 if (view.y + view.height < b.y) 241 max.y--; 242 } else { 243 min.x = min.y = max.x = min.y = 0; 244 } 245 } 246 computeWraps(Rectangle r, Point p)247 public Point[] computeWraps(Rectangle r, Point p) { 248 Dimension mapSize = model.options.getSize(); 249 Point min = new Point(); 250 Point max = new Point(); 251 Rectangle b = new Rectangle(p.x, p.y, 0, 0); 252 253 computeBounds(min, max, r, b, mapSize); 254 Point[] wraps = new Point[(max.x - min.x + 1) * (max.y - min.y + 1)]; 255 int i = 0; 256 for (int xoff = min.x; xoff <= max.x; xoff++) { 257 for (int yoff = min.y; yoff <= max.y; yoff++) { 258 wraps[i++] = 259 new Point( 260 xoff * mapSize.width + p.x, 261 yoff * mapSize.height + p.y); 262 } 263 } 264 return wraps; 265 } 266 containsWrapped(Rectangle r, Point p)267 public boolean containsWrapped(Rectangle r, Point p) { 268 return computeWraps(r, p).length > 0; 269 } 270 containsWrapped(MapObject o, Point p)271 public boolean containsWrapped(MapObject o, Point p) { 272 Point[] wraps = computeWraps(o.getBounds(), p); 273 for (int i = 0; i < wraps.length; i++) 274 if (o.contains(wraps[i])) 275 return true; 276 return false; 277 } 278 getTransform()279 public AffineTransform getTransform() { 280 if (at == null) { 281 at = new AffineTransform(); 282 at.translate( 283 -scale * model.options.getSize().width / 2 284 + getSize().width / 2 285 - offset.x, 286 scale * model.options.getSize().height / 2 287 + getSize().height / 2 288 - offset.y); 289 at.scale(scale, -scale); 290 } 291 return at; 292 } 293 getInverse()294 public AffineTransform getInverse() { 295 try { 296 if (it == null) 297 it = getTransform().createInverse(); 298 return it; 299 } catch (Exception e) { 300 e.printStackTrace(); 301 return null; 302 } 303 } 304 305 beginEdit()306 public void beginEdit() { 307 currentEdit = new CompoundMapEdit(); 308 } 309 commitEdit()310 public void commitEdit() { 311 currentEdit.edit(); 312 getUndoManager().addEdit(currentEdit); 313 repaint(); 314 currentEdit = null; 315 } 316 cancelEdit()317 public void cancelEdit() { 318 currentEdit = null; 319 } 320 doEdit(MapEdit e)321 private void doEdit(MapEdit e) { 322 if (currentEdit != null) { 323 currentEdit.addEdit(e); 324 } else { 325 e.edit(); 326 getUndoManager().addEdit(e); 327 repaint(); 328 } 329 } 330 331 private interface MapEdit extends UndoableEdit { edit()332 public void edit(); unedit()333 public void unedit(); 334 } 335 336 private abstract class AbstractMapEdit 337 extends AbstractUndoableEdit implements MapEdit { redo()338 public void redo() { 339 super.redo(); 340 edit(); 341 } undo()342 public void undo() { 343 super.undo(); 344 unedit(); 345 } 346 } 347 348 private class CompoundMapEdit 349 extends CompoundEdit implements MapEdit { edit()350 public void edit() { 351 for (Iterator i = edits.iterator(); i.hasNext();) 352 ((MapEdit)i.next()).edit(); 353 } unedit()354 public void unedit() {} 355 } 356 setPolygonEdgeStyle( final MapPolygon p, final int edgeIndex, final LineStyle newStyle)357 public void setPolygonEdgeStyle( 358 final MapPolygon p, 359 final int edgeIndex, 360 final LineStyle newStyle) { 361 final LineStyle oldStyle = p.getEdgeStyle(edgeIndex); 362 doEdit(new AbstractMapEdit() { 363 public void unedit() { 364 p.setEdgeStyle(edgeIndex, oldStyle); 365 } 366 public void edit() { 367 p.setEdgeStyle(edgeIndex, newStyle); 368 } 369 }); 370 } 371 removePolygonPoint(final MapPolygon p, final int i)372 public void removePolygonPoint(final MapPolygon p, final int i) { 373 final Point point = p.getPoint(i); 374 doEdit(new AbstractMapEdit() { 375 public void unedit() { 376 p.insertPoint(i, point); 377 } 378 public void edit() { 379 p.removePoint(i); 380 } 381 }); 382 } 383 insertPolygonPoint( final MapPolygon p, final int i, final Point point)384 public void insertPolygonPoint( 385 final MapPolygon p, 386 final int i, 387 final Point point) { 388 doEdit(new AbstractMapEdit() { 389 public void unedit() { 390 p.removePoint(i); 391 } 392 public void edit() { 393 p.insertPoint(i, point); 394 } 395 }); 396 } 397 movePolygonPoint( final MapPolygon p, final int i, final int newX, final int newY)398 public void movePolygonPoint( 399 final MapPolygon p, 400 final int i, 401 final int newX, 402 final int newY) { 403 final Point oldPoint = p.getPoint(i); 404 doEdit(new AbstractMapEdit() { 405 public void unedit() { 406 p.setPoint(i, oldPoint.x, oldPoint.y); 407 } 408 public void edit() { 409 p.setPoint(i, newX, newY); 410 } 411 }); 412 } 413 setPolygonStyles( final MapPolygon p, final Map newStyles)414 public void setPolygonStyles( 415 final MapPolygon p, 416 final Map newStyles) { 417 doEdit(new AbstractMapEdit() { 418 Map oldStyles = p.getStyles(); 419 Map oldDefaultStyles = model.getDefaultPolygonStyles(); 420 public void unedit() { 421 p.setStyles(oldStyles); 422 model.setDefaultPolygonStyles(oldDefaultStyles); 423 } 424 public void edit() { 425 p.setStyles(newStyles); 426 model.setDefaultPolygonStyles(newStyles); 427 } 428 }); 429 } 430 rotatePolygon( final MapPolygon p, final double angle)431 public void rotatePolygon( 432 final MapPolygon p, 433 final double angle) { 434 final MapPolygon rotated = (MapPolygon)p.copy(); 435 rotated.rotate(angle); 436 doEdit(new AbstractMapEdit() { 437 public void unedit() { 438 getModel().replace(rotated, p); 439 } 440 public void edit() { 441 getModel().replace(p, rotated); 442 } 443 }); 444 } 445 setObjectTeam(final MapObject o, final int newTeam)446 public void setObjectTeam(final MapObject o, final int newTeam) { 447 final int oldTeam = o.getTeam(); 448 doEdit(new AbstractMapEdit() { 449 public void unedit() { 450 o.setTeam(oldTeam); 451 } 452 public void edit() { 453 o.setTeam(newTeam); 454 } 455 }); 456 } 457 setBaseProperties( final Base b, final int newTeam, final int newDir, final int newOrder)458 public void setBaseProperties( 459 final Base b, 460 final int newTeam, 461 final int newDir, 462 final int newOrder) { 463 final int oldTeam = b.getTeam(); 464 final int oldDir = b.getDir(); 465 final int oldOrder = b.getOrder(); 466 doEdit(new AbstractMapEdit() { 467 public void unedit() { 468 b.setTeam(oldTeam); 469 b.setDir(oldDir); 470 b.setOrder(oldOrder); 471 } 472 public void edit() { 473 b.setTeam(newTeam); 474 b.setDir(newDir); 475 b.setOrder(newOrder); 476 } 477 }); 478 } 479 setBallProperties( final Ball b, final int newTeam, final PolygonStyle newStyle)480 public void setBallProperties( 481 final Ball b, 482 final int newTeam, 483 final PolygonStyle newStyle) { 484 final int oldTeam = b.getTeam(); 485 final PolygonStyle oldStyle = b.getStyle(); 486 doEdit(new AbstractMapEdit() { 487 public void unedit() { 488 b.setTeam(oldTeam); 489 b.setStyle(oldStyle); 490 } 491 public void edit() { 492 b.setTeam(newTeam); 493 b.setStyle(newStyle); 494 } 495 }); 496 } 497 setGravProperties( final Grav grav, final int newType, final BigDecimal newForce)498 public void setGravProperties( 499 final Grav grav, 500 final int newType, 501 final BigDecimal newForce) { 502 final int oldType = grav.getType(); 503 final BigDecimal oldForce = grav.getForce(); 504 doEdit(new AbstractMapEdit() { 505 public void unedit() { 506 grav.setType(oldType); 507 grav.setForce(oldForce); 508 } 509 public void edit() { 510 grav.setType(newType); 511 grav.setForce(newForce); 512 } 513 }); 514 } 515 setWormholeType(final Wormhole o, final int newType)516 public void setWormholeType(final Wormhole o, final int newType) { 517 final int oldType = o.getType(); 518 doEdit(new AbstractMapEdit() { 519 public void unedit() { 520 o.setType(oldType); 521 } 522 public void edit() { 523 o.setType(newType); 524 } 525 }); 526 } 527 setWormholePoint(final Wormhole o, final int x, final int y)528 public void setWormholePoint(final Wormhole o, final int x, final int y) { 529 doEdit(new AbstractMapEdit() { 530 private Point oldPoint = o.getPoint(); 531 public void unedit() { 532 o.setPoint(oldPoint); 533 } 534 public void edit() { 535 o.setPoint(new Point(x, y)); 536 } 537 }); 538 } 539 setCannonDir(final Cannon c, final int newDir)540 public void setCannonDir(final Cannon c, final int newDir) { 541 final int oldDir = c.getDir(); 542 doEdit(new AbstractMapEdit() { 543 public void unedit() { 544 c.setDir(oldDir); 545 } 546 public void edit() { 547 c.setDir(newDir); 548 } 549 }); 550 } 551 setCannonPoint(final Cannon c, final int x, final int y)552 public void setCannonPoint(final Cannon c, final int x, final int y) { 553 final Point oldPoint = c.getPoint(); 554 doEdit(new AbstractMapEdit() { 555 public void unedit() { 556 c.setPoint(oldPoint); 557 } 558 public void edit() { 559 c.setPoint(new Point(x, y)); 560 } 561 }); 562 } 563 removeMapObject(final MapObject o)564 public void removeMapObject(final MapObject o) { 565 final int i = getModel().indexOf(o); 566 if (i == -1) 567 return; 568 doEdit(new AbstractMapEdit() { 569 public void unedit() { 570 getModel().addObject(i, o); 571 } 572 public void edit() { 573 getModel().removeObject(i); 574 } 575 }); 576 } 577 addMapObject(final MapObject o)578 public void addMapObject(final MapObject o) { 579 doEdit(new AbstractMapEdit() { 580 public void unedit() { 581 getModel().removeObject(o); 582 } 583 public void edit() { 584 getModel().addToFront(o); 585 } 586 }); 587 } 588 bringMapObject(final MapObject o, final boolean front)589 public void bringMapObject(final MapObject o, final boolean front) { 590 final int i = getModel().indexOf(o); 591 doEdit(new AbstractMapEdit() { 592 public void unedit() { 593 getModel().removeObject(o); 594 getModel().addObject(i, o); 595 } 596 public void edit() { 597 getModel().removeObject(o); 598 getModel().addObject(o, front); 599 } 600 }); 601 } 602 makeBallAreaFromSelected()603 public void makeBallAreaFromSelected() { 604 if (selected.isEmpty()) return; 605 makeGroup(new BallArea(selected)); 606 } 607 makeBallTargetFromSelected()608 public void makeBallTargetFromSelected() { 609 if (selected.isEmpty()) return; 610 makeGroup(new BallTarget(selected)); 611 } 612 makeCannonFromSelected()613 public void makeCannonFromSelected() { 614 if (selected.isEmpty()) return; 615 makeGroup(new Cannon(selected)); 616 } 617 makeDecorationFromSelected()618 public void makeDecorationFromSelected() { 619 if (selected.isEmpty()) return; 620 makeGroup(new Decoration(selected)); 621 } 622 makeFrictionAreaFromSelected()623 public void makeFrictionAreaFromSelected() { 624 if (selected.isEmpty()) return; 625 makeGroup(new FrictionArea(selected)); 626 } 627 makeGroupFromSelected()628 public void makeGroupFromSelected() { 629 if (selected.isEmpty()) return; 630 makeGroup(new Group(selected)); 631 } 632 makeTargetFromSelected()633 public void makeTargetFromSelected() { 634 if (selected.isEmpty()) return; 635 makeGroup(new Target(selected)); 636 } 637 makeWormholeFromSelected()638 public void makeWormholeFromSelected() { 639 if (selected.isEmpty()) return; 640 makeGroup(new Wormhole(selected)); 641 } 642 makeGroup(final Group g)643 private void makeGroup(final Group g) { 644 doEdit(new AbstractMapEdit() { 645 public void unedit() { 646 for (Iterator i = g.getMembers().iterator(); i.hasNext();) { 647 MapObject o = (MapObject)i.next(); 648 o.setParent(null); 649 getModel().addToFront(o); 650 } 651 } 652 public void edit() { 653 for (Iterator i = selected.iterator(); i.hasNext();) { 654 MapObject o = (MapObject)i.next(); 655 o.setParent(g); 656 getModel().removeObject(o); 657 } 658 getModel().addToFront(g); 659 setSelectedObject(g); 660 } 661 }); 662 } 663 ungroupSelected()664 public void ungroupSelected() { 665 if (selected.isEmpty() 666 || !(selected.get(0) instanceof Group)) 667 return; 668 doEdit(new AbstractMapEdit() { 669 Group g = (Group)selected.get(0); 670 public void unedit() { 671 getModel().addToFront(g); 672 for (Iterator i = g.getMembers().iterator(); i.hasNext();) 673 getModel().removeObject((MapObject)i.next()); 674 } 675 public void edit() { 676 getModel().removeObject(g); 677 setSelectedObject(null); 678 for (Iterator i = g.getMembers().iterator(); i.hasNext();) { 679 MapObject o = (MapObject)i.next(); 680 getModel().addToFront(o); 681 addSelectedObject(o); 682 } 683 } 684 }); 685 } 686 regroupSelected()687 public void regroupSelected() { 688 if (selected.isEmpty() 689 || ((MapObject)selected.get(0)).getParent() == null) 690 return; 691 doEdit(new AbstractMapEdit() { 692 Group g = ((MapObject)selected.get(0)).getParent(); 693 public void unedit() { 694 getModel().removeObject(g); 695 for (Iterator i = g.getMembers().iterator(); i.hasNext();) 696 getModel().addToFront((MapObject)i.next()); 697 } 698 public void edit() { 699 getModel().addToFront(g); 700 for (Iterator i = g.getMembers().iterator(); i.hasNext();) 701 getModel().removeObject((MapObject)i.next()); 702 setSelectedObject(g); 703 } 704 }); 705 } 706 moveMapObject( final MapObject o, final int newX, final int newY)707 public void moveMapObject( 708 final MapObject o, 709 final int newX, 710 final int newY) { 711 final int oldX = o.getBounds().x; 712 final int oldY = o.getBounds().y; 713 doEdit(new AbstractMapEdit() { 714 public void unedit() { 715 o.moveTo(oldX, oldY); 716 } 717 public void edit() { 718 o.moveTo(newX, newY); 719 } 720 }); 721 } 722 addEdgeStyle(final LineStyle style)723 public void addEdgeStyle(final LineStyle style) { 724 doEdit(new AbstractMapEdit() { 725 public void unedit() { 726 getModel().edgeStyles.remove(style); 727 } 728 public void edit() { 729 getModel().edgeStyles.add(style); 730 } 731 }); 732 } 733 removeEdgeStyle(final LineStyle style)734 public void removeEdgeStyle(final LineStyle style) { 735 final java.util.List oldStyles = getModel().edgeStyles; 736 doEdit(new AbstractMapEdit() { 737 public void unedit() { 738 getModel().edgeStyles = oldStyles; 739 } 740 public void edit() { 741 getModel().edgeStyles.remove(style); 742 } 743 }); 744 } 745 addPolygonStyle(final PolygonStyle style)746 public void addPolygonStyle(final PolygonStyle style) { 747 doEdit(new AbstractMapEdit() { 748 public void unedit() { 749 getModel().polyStyles.remove(style); 750 } 751 public void edit() { 752 getModel().polyStyles.add(style); 753 } 754 }); 755 } 756 removePolygonStyle(final PolygonStyle style)757 public void removePolygonStyle(final PolygonStyle style) { 758 final java.util.List oldStyles = new ArrayList(getModel().polyStyles); 759 doEdit(new AbstractMapEdit() { 760 public void unedit() { 761 getModel().polyStyles = oldStyles; 762 } 763 public void edit() { 764 getModel().polyStyles.remove(style); 765 } 766 }); 767 } 768 setEdgeStyleProperties( final LineStyle style, final String newId, final int newStyle, final int newWidth, final Color newColor)769 public void setEdgeStyleProperties( 770 final LineStyle style, 771 final String newId, 772 final int newStyle, 773 final int newWidth, 774 final Color newColor) { 775 final String oldId = style.getId(); 776 final int oldStyle = style.getStyle(); 777 final int oldWidth = style.getWidth(); 778 final Color oldColor = style.getColor(); 779 doEdit(new AbstractMapEdit() { 780 public void unedit() { 781 set(oldId, oldStyle, oldWidth, oldColor); 782 } 783 public void edit() { 784 set(newId, newStyle, newWidth, newColor); 785 } 786 private void set(String id, int s, int w, Color c) { 787 style.setId(id); 788 style.setStyle(s); 789 style.setWidth(w); 790 style.setColor(c); 791 } 792 }); 793 } 794 setPolygonStyleProperties( final PolygonStyle style, final String newId, final int newFillStyle, final Color newColor, final Pixmap newTexture, final LineStyle newDefEdgeStyle, final boolean newVisible, final boolean newVisInRadar)795 public void setPolygonStyleProperties( 796 final PolygonStyle style, 797 final String newId, 798 final int newFillStyle, 799 final Color newColor, 800 final Pixmap newTexture, 801 final LineStyle newDefEdgeStyle, 802 final boolean newVisible, 803 final boolean newVisInRadar) { 804 final String oldId = style.getId(); 805 final int oldFillStyle = style.getFillStyle(); 806 final Color oldColor = style.getColor(); 807 final Pixmap oldTexture = style.getTexture(); 808 final LineStyle oldDefEdgeStyle = style.getDefaultEdgeStyle(); 809 final boolean oldVisible = style.isVisible(); 810 final boolean oldVisInRadar = style.isVisibleInRadar(); 811 doEdit(new AbstractMapEdit() { 812 public void unedit() { 813 set( 814 oldId, 815 oldFillStyle, 816 oldColor, 817 oldTexture, 818 oldDefEdgeStyle, 819 oldVisible, 820 oldVisInRadar); 821 } 822 public void edit() { 823 set( 824 newId, 825 newFillStyle, 826 newColor, 827 newTexture, 828 newDefEdgeStyle, 829 newVisible, 830 newVisInRadar); 831 } 832 private void set( 833 String id, 834 int fs, 835 Color c, 836 Pixmap t, 837 LineStyle es, 838 boolean v, 839 boolean vr) { 840 style.setId(id); 841 style.setFillStyle(fs); 842 style.setColor(c); 843 style.setTexture(t); 844 style.setDefaultEdgeStyle(es); 845 model.setDefaultEdgeStyle(es); 846 style.setVisible(v); 847 style.setVisibleInRadar(vr); 848 } 849 }); 850 } 851 852 private class AwtEventHandler implements CanvasEventHandler { 853 mouseClicked(MouseEvent evt)854 public void mouseClicked(MouseEvent evt) { 855 if (model == null) 856 return; 857 transformEvent(evt, true); 858 if (eventHandler != null) { 859 eventHandler.mouseClicked(evt); 860 return; 861 } 862 for (Iterator iter = model.objects.iterator(); iter.hasNext();) { 863 MapObject o = (MapObject) iter.next(); 864 if (o.checkAwtEvent(MapCanvas.this, evt)) { 865 return; 866 } 867 } 868 } 869 mouseEntered(MouseEvent evt)870 public void mouseEntered(MouseEvent evt) { 871 if (model == null) 872 return; 873 if (eventHandler != null) { 874 transformEvent(evt, true); 875 eventHandler.mouseEntered(evt); 876 return; 877 } 878 } 879 mouseExited(MouseEvent evt)880 public void mouseExited(MouseEvent evt) { 881 if (model == null) 882 return; 883 if (eventHandler != null) { 884 transformEvent(evt, true); 885 eventHandler.mouseExited(evt); 886 return; 887 } 888 } 889 mousePressed(MouseEvent evt)890 public void mousePressed(MouseEvent evt) { 891 if (model == null) 892 return; 893 transformEvent(evt, true); 894 if (eventHandler != null) { 895 eventHandler.mousePressed(evt); 896 return; 897 } 898 for (Iterator iter = model.objects.iterator(); iter.hasNext();) { 899 MapObject o = (MapObject) iter.next(); 900 if (o.checkAwtEvent(MapCanvas.this, evt)) { 901 return; 902 } 903 } 904 if ((evt.getModifiers() & InputEvent.BUTTON1_MASK) != 0) { 905 if (evt.isControlDown()) { 906 setSelectedObject(null); 907 setCanvasEventHandler(selectHandler); 908 selectHandler.mousePressed(evt); 909 } else { 910 dragHandler.mousePressed(evt); 911 setCanvasEventHandler(dragHandler); 912 setSelectedObject(null); 913 } 914 } 915 } 916 mouseReleased(MouseEvent evt)917 public void mouseReleased(MouseEvent evt) { 918 if (model == null) 919 return; 920 transformEvent(evt, true); 921 if (eventHandler != null) { 922 eventHandler.mouseReleased(evt); 923 return; 924 } 925 for (Iterator iter = model.objects.iterator(); iter.hasNext();) { 926 MapObject o = (MapObject) iter.next(); 927 if (o.checkAwtEvent(MapCanvas.this, evt)) { 928 return; 929 } 930 } 931 } 932 mouseDragged(MouseEvent evt)933 public void mouseDragged(MouseEvent evt) { 934 if (model == null) 935 return; 936 transformEvent(evt, true); 937 if (eventHandler != null) { 938 eventHandler.mouseDragged(evt); 939 return; 940 } 941 } 942 mouseMoved(MouseEvent evt)943 public void mouseMoved(MouseEvent evt) { 944 if (model == null) 945 return; 946 if (eventHandler != null) { 947 transformEvent(evt, true); 948 eventHandler.mouseMoved(evt); 949 return; 950 } 951 } 952 transformEvent(MouseEvent evt, boolean snap)953 private void transformEvent(MouseEvent evt, boolean snap) { 954 int x = evt.getX(); 955 int y = evt.getY(); 956 int g = grid * 64; 957 Point mapp = new Point(x, y); 958 getInverse().transform(mapp, mapp); 959 if (snap && g > 0) { 960 mapp.x = (mapp.x / g) * g; 961 mapp.y = (mapp.y / g) * g; 962 } 963 evt.translatePoint(mapp.x - evt.getX(), mapp.y - evt.getY()); 964 } 965 } 966 967 private class DragHandler extends CanvasEventAdapter { 968 969 private Point dragStart; 970 private Point offsetStart; 971 private boolean wasFastRendering; 972 mousePressed(MouseEvent evt)973 public void mousePressed(MouseEvent evt) { 974 toScreen(evt); 975 dragStart = evt.getPoint(); 976 offsetStart = new Point(offset); 977 wasFastRendering = isFastRendering(); 978 setFastRendering(true); 979 } 980 mouseDragged(MouseEvent evt)981 public void mouseDragged(MouseEvent evt) { 982 toScreen(evt); 983 at = null; 984 it = null; 985 offset.x = offsetStart.x + (dragStart.x - evt.getX()); 986 offset.y = offsetStart.y + (dragStart.y - evt.getY()); 987 repaint(); 988 } 989 mouseReleased(MouseEvent evt)990 public void mouseReleased(MouseEvent evt) { 991 setFastRendering(wasFastRendering); 992 setCanvasEventHandler(null); 993 repaint(); 994 } 995 toScreen(MouseEvent evt)996 private void toScreen(MouseEvent evt) { 997 Point mapp = new Point(); 998 Point evtp = evt.getPoint(); 999 getTransform().transform(evtp, mapp); 1000 evt.translatePoint(mapp.x - evtp.x, mapp.y - evtp.y); 1001 } 1002 } 1003 1004 private class SelectHandler extends CanvasEventAdapter { 1005 1006 private Point selectStart; 1007 private Rectangle selectShape = new Rectangle(); 1008 mousePressed(MouseEvent evt)1009 public void mousePressed(MouseEvent evt) { 1010 if ((evt.getModifiers() 1011 & InputEvent.BUTTON1_MASK) != 0) { 1012 selectStart = evt.getPoint(); 1013 paintSelectArea(evt, false, true); 1014 } 1015 } 1016 mouseDragged(MouseEvent evt)1017 public void mouseDragged(MouseEvent evt) { 1018 if ((evt.getModifiers() 1019 & InputEvent.BUTTON1_MASK) != 0) 1020 paintSelectArea(evt, true, true); 1021 } 1022 mouseReleased(MouseEvent evt)1023 public void mouseReleased(MouseEvent evt) { 1024 if ((evt.getModifiers() 1025 & InputEvent.BUTTON1_MASK) != 0) { 1026 paintSelectArea(evt, true, false); 1027 setCanvasEventHandler(null); 1028 repaint(); 1029 } 1030 } 1031 paintSelectArea( MouseEvent evt, boolean erase, boolean paint)1032 private void paintSelectArea( 1033 MouseEvent evt, boolean erase, boolean paint) { 1034 Graphics2D g = (Graphics2D)getGraphics(); 1035 g.setXORMode(Color.black); 1036 g.setColor(Color.white); 1037 if (erase) drawShape(g, selectShape); 1038 selectShape.setBounds( 1039 Math.min(selectStart.x, evt.getX()), 1040 Math.min(selectStart.y, evt.getY()), 1041 Math.abs(selectStart.x - evt.getX()), 1042 Math.abs(selectStart.y - evt.getY())); 1043 if (paint) drawShape(g, selectShape); 1044 } 1045 } 1046 } 1047