1 26 27 package org.nightlabs.editor2d.impl; 28 29 import java.awt.Point ; 30 import java.awt.Rectangle ; 31 import java.awt.geom.AffineTransform ; 32 import java.beans.PropertyChangeListener ; 33 import java.beans.PropertyChangeSupport ; 34 import java.util.Iterator ; 35 36 import org.nightlabs.editor2d.DrawComponent; 37 import org.nightlabs.editor2d.DrawComponentContainer; 38 import org.nightlabs.editor2d.EditorGuide; 39 import org.nightlabs.editor2d.MultiLayerDrawComponent; 40 import org.nightlabs.editor2d.render.RenderModeManager; 41 import org.nightlabs.editor2d.render.Renderer; 42 import org.nightlabs.editor2d.util.EditorModelUtil; 43 import org.nightlabs.i18n.I18nText; 44 import org.nightlabs.i18n.I18nTextBuffer; 45 46 51 public class DrawComponentImpl 52 implements DrawComponent 53 { 54 protected long id = ID_EDEFAULT; 55 protected I18nText name = new I18nTextBuffer(); 56 protected int x = X_EDEFAULT; 57 protected int y = Y_EDEFAULT; 58 protected int width = WIDTH_EDEFAULT; 59 protected int height = HEIGHT_EDEFAULT; 60 protected double rotation = ROTATION_EDEFAULT; 61 protected EditorGuide horizontalGuide = null; 62 protected EditorGuide verticalGuide = null; 63 protected int rotationX = ROTATION_X_DEFAULT; 64 protected int rotationY = ROTATION_Y_DEFAULT; 65 protected transient Rectangle bounds = BOUNDS_EDEFAULT; 66 protected AffineTransform affineTransform = new AffineTransform (); 67 protected int tmpRotationX = TMP_ROTATION_X_EDEFAULT; 68 protected int tmpRotationY = TMP_ROTATION_Y_EDEFAULT; 69 70 protected transient PropertyChangeSupport listeners = null; 71 protected PropertyChangeSupport getPropertyChangeSupport() 72 { 73 if (listeners == null) 74 listeners = new PropertyChangeSupport (this); 75 return listeners; 76 } 77 public void addPropertyChangeListener(PropertyChangeListener l){ 78 getPropertyChangeSupport().addPropertyChangeListener(l); 79 } 80 public void removePropertyChangeListener(PropertyChangeListener l){ 81 getPropertyChangeSupport().removePropertyChangeListener(l); 82 } 83 protected void firePropertyChange(String prop, Object oldValue, Object newValue){ 84 getPropertyChangeSupport().firePropertyChange(prop, oldValue, newValue); 85 } 86 protected void firePropertyChange(String prop, int oldValue, int newValue){ 87 getPropertyChangeSupport().firePropertyChange(prop, oldValue, newValue); 88 } 89 protected void firePropertyChange(String prop, double oldValue, double newValue){ 90 getPropertyChangeSupport().firePropertyChange(prop, new Double (oldValue), new Double (newValue)); 91 } 92 protected void firePropertyChange(String prop, boolean oldValue, boolean newValue){ 93 getPropertyChangeSupport().firePropertyChange(prop, oldValue, newValue); 94 } 95 96 public DrawComponentImpl() { 97 super(); 98 } 99 100 104 public long getId() { 105 return id; 106 } 107 108 112 public void setId(long newId) { 113 long oldId = id; 114 id = newId; 115 firePropertyChange(PROP_ID, new Long (oldId), new Long (newId)); 116 } 117 118 122 public String getName() { 123 return name.getText(getLanguageId()); 124 } 125 126 131 public void setName(String newName) { 132 String oldName = name.getText(getLanguageId()); 133 name.setText(getLanguageId(), newName); 134 firePropertyChange(PROP_NAME, oldName, newName); 135 } 136 137 140 protected transient String languageId = DEFAULT_LANGUAGE_ID; 141 142 147 public String getLanguageId() { 148 return languageId; 149 } 150 151 158 public void setLanguageId(String newLanguageId) { 159 String oldLanguageId = languageId; 160 primSetLanguageId(newLanguageId); 161 firePropertyChange(PROP_LANGUAGE_ID, oldLanguageId, languageId); 162 } 163 164 168 protected void primSetLanguageId(String newLanguageId) { 169 languageId = newLanguageId; 170 } 171 172 176 public I18nText getI18nText() { 177 return name; 178 } 179 180 187 public void setI18nText(I18nText text) { 188 this.name = text; 189 firePropertyChange(PROP_NAME, null, name); 190 } 191 192 197 public int getX() { 198 return getBounds().x; 199 } 200 201 207 public void setX(int newX) 208 { 209 int oldX = x; 210 x = newX; 211 primSetX(x); 212 firePropertyChange(PROP_X, oldX, x); 213 } 214 215 219 protected void primSetX(int x) 220 { 221 if (x == getBounds().x) 222 return; 223 setLocation(x, getY()); 224 } 225 226 231 public int getY() { 232 return getBounds().y; 233 } 234 235 240 public void setY(int newY) 241 { 242 int oldY = y; 243 y = newY; 244 primSetY(y); 245 firePropertyChange(PROP_Y, oldY, y); 246 } 247 248 252 protected void primSetY(int y) 253 { 254 if (y == getBounds().y) 255 return; 256 setLocation(getX(), y); 257 } 258 259 264 public int getWidth() { 265 return getBounds().width; 266 } 267 268 273 public void setWidth(int newWidth) 274 { 275 int oldWidth = width; 276 width = newWidth; 277 primSetWidth(width); 278 firePropertyChange(PROP_Y, oldWidth, width); 279 } 280 281 285 protected void primSetWidth(float width) 286 { 287 if (width == getBounds().width) 288 return; 289 setSize((int)width, getHeight()); 290 } 291 292 297 public int getHeight() { 298 return getBounds().height; 299 } 300 301 306 public void setHeight(int newHeight) 307 { 308 int oldHeight = height; 309 height = newHeight; 310 primSetHeight(height); 311 firePropertyChange(PROP_Y, oldHeight, height); 312 } 313 314 318 protected void primSetHeight(float height) 319 { 320 if (height == getBounds().height) 321 return; 322 setSize(getWidth(), (int)height); 323 } 324 325 329 public double getRotation() { 330 return rotation; 331 } 332 333 340 public void setRotation(double newRotation) 341 { 342 double oldRotation = rotation; 343 primSetRotation(newRotation); 344 firePropertyChange(PROP_Y, oldRotation, rotation); 345 } 346 347 351 protected static transient double rotationLimit = 360.0d; 352 353 357 protected void primSetRotation(double newRotation) 358 { 359 double oldRotation = rotation; 360 rotation = EditorModelUtil.getConstrainedValue(newRotation, rotationLimit); 361 362 if (oldRotation == newRotation) 363 return; 364 365 double degreesToRotateInRadians; 366 double degreesToRotate = EditorModelUtil.calcDiffRotation(rotation, oldRotation); 367 degreesToRotateInRadians = Math.toRadians(degreesToRotate); 368 369 if (degreesToRotate != 0) 370 { 371 atUtil.setToIdentity(); 372 if (tmpRotationX != TMP_ROTATION_X_EDEFAULT && tmpRotationY != TMP_ROTATION_Y_EDEFAULT) 373 atUtil.rotate(degreesToRotateInRadians, getTmpRotationX(), getTmpRotationY()); 374 else 375 atUtil.rotate(degreesToRotateInRadians, getRotationX(), getRotationY()); 376 transform(atUtil); 377 } 378 } 379 380 383 public EditorGuide getHorizontalGuide() { 384 return horizontalGuide; 385 } 386 387 393 public void setHorizontalGuide(EditorGuide newHorizontalGuide) 394 { 395 EditorGuide old = horizontalGuide; 396 horizontalGuide = newHorizontalGuide; 397 firePropertyChange(PROP_HORIZONTAL_GUIDE, old, horizontalGuide); 398 } 399 400 403 public EditorGuide getVerticalGuide() { 404 return verticalGuide; 405 } 406 407 413 public void setVerticalGuide(EditorGuide newVerticalGuide) 414 { 415 EditorGuide old = verticalGuide; 416 verticalGuide = newVerticalGuide; 417 firePropertyChange(PROP_VERTICAL_GUIDE, old, verticalGuide); 418 } 419 420 427 public int getRotationX() 428 { 429 if (rotationX == ROTATION_X_DEFAULT) 430 return (int) getBounds().getCenterX(); 431 432 return rotationX; 433 } 434 435 441 public void setRotationX(int newRotationX) 442 { 443 int oldRotationX = rotationX; 444 primSetRotationX(newRotationX); 445 firePropertyChange(PROP_ROTATION_X, oldRotationX, rotationX); 446 } 447 448 453 protected void primSetRotationX(int newRotationX) { 454 rotationX = newRotationX; 455 } 456 457 464 public int getRotationY() 465 { 466 if (rotationY == ROTATION_Y_DEFAULT) 467 return (int) getBounds().getCenterY(); 468 469 return rotationY; 470 } 471 472 478 public void setRotationY(int newRotationY) 479 { 480 int oldRotationY = rotationY; 481 primSetRotationY(newRotationY); 482 firePropertyChange(PROP_ROTATION_X, oldRotationY, rotationY); 483 } 484 485 490 protected void primSetRotationY(int newRotationY) { 491 rotationY = newRotationY; 492 } 493 494 501 public Rectangle getBounds() 502 { 503 if (bounds == null) { 504 bounds = new Rectangle (x, y, width, height); 505 } 506 return bounds; 507 } 508 509 514 public void setBounds(Rectangle newBounds) 515 { 516 Rectangle oldBounds = bounds; 517 primSetBounds(newBounds); 518 519 bounds = newBounds; 520 x = bounds.x; 521 y = bounds.y; 522 width = bounds.width; 523 height = bounds.height; 524 525 firePropertyChange(PROP_BOUNDS, oldBounds, bounds); 526 } 527 528 532 protected void primSetBounds(Rectangle newBounds) 533 { 534 if (getBounds().equals(newBounds)) 535 return; 536 537 if (newBounds.x == getX() && newBounds.y == getY()) { 538 setSize(newBounds.width, newBounds.height); 539 return; 540 } 541 542 if (newBounds.width == getWidth() && newBounds.height == getHeight()) { 543 setLocation(newBounds.x, newBounds.y); 544 return; 545 } 546 547 setSize(newBounds.width, newBounds.height); 548 setLocation(newBounds.x, newBounds.y); 549 } 550 551 558 public AffineTransform getAffineTransform() { 559 return affineTransform; 560 } 561 562 565 public void setAffineTransform(AffineTransform newAffineTransform) 566 { 567 AffineTransform oldAffineTransform = affineTransform; 568 affineTransform = newAffineTransform; 569 firePropertyChange(PROP_AFFINE_TRANSFORM, oldAffineTransform, affineTransform); 570 } 571 572 575 public int getTmpRotationX() { 576 return tmpRotationX; 577 } 578 579 589 public void setTmpRotationX(int newTmpRotationX) { 590 int oldTmpRotationX = tmpRotationX; 591 tmpRotationX = newTmpRotationX; 592 firePropertyChange(PROP_TMP_ROTATION_X, oldTmpRotationX, tmpRotationX); 593 } 594 595 598 public int getTmpRotationY() { 599 return tmpRotationY; 600 } 601 602 612 public void setTmpRotationY(int newTmpRotationY) { 613 int oldTmpRotationY = tmpRotationY; 614 tmpRotationY = newTmpRotationY; 615 firePropertyChange(PROP_TMP_ROTATION_Y, oldTmpRotationY, tmpRotationY); 616 } 617 618 626 public void setLocation(int newX, int newY) 627 { 628 atUtil.setToIdentity(); 629 atUtil.translate((float)newX - (float)getX(), (float)newY - (float)getY()); 630 631 transformRotationCenter(atUtil); 632 transform(atUtil); 633 } 634 635 642 protected void setSize(int newWidth, int newHeight) 643 { 644 atUtil.setToIdentity(); 645 float ratioY = (float)newHeight / (float)getHeight(); 646 ratioY = EditorModelUtil.checkFactor(ratioY); 647 float ratioX = (float)newWidth / (float)getWidth(); 648 ratioX = EditorModelUtil.checkFactor(ratioX); 649 float distanceX = (float)getX() - ((float)getX()*ratioX); 650 float distanceY = (float)getY() - ((float)getY()*ratioY); 651 atUtil.translate(distanceX, distanceY); 652 atUtil.scale(ratioX, ratioY); 653 654 transformRotationCenter(atUtil); 655 transform(atUtil); 656 } 657 658 664 protected void transformRotationCenter(AffineTransform at) 665 { 666 if (rotationX != ROTATION_X_DEFAULT || rotationY != ROTATION_Y_DEFAULT) { 667 Point rotationCenter = new Point (getRotationX(), getRotationY()); 668 Point newRotationCenter = new Point (); 669 at.transform(rotationCenter, newRotationCenter); 670 rotationX = newRotationCenter.x; 671 rotationY = newRotationCenter.y; 672 } 673 } 674 675 679 protected static transient final AffineTransform atUtil = new AffineTransform (); 680 681 684 public String toString() 685 { 686 StringBuffer result = new StringBuffer (super.toString()); 687 result.append(" (id: "); 688 result.append(id); 689 result.append(", name: "); 690 result.append(name); 691 result.append(", x: "); 692 result.append(x); 693 result.append(", y: "); 694 result.append(y); 695 result.append(", width: "); 696 result.append(width); 697 result.append(", height: "); 698 result.append(height); 699 result.append(", rotation: "); 700 result.append(rotation); 701 result.append(", rotationX: "); 702 result.append(rotationX); 703 result.append(", rotationY: "); 704 result.append(rotationY); 705 result.append(", bounds: "); 706 result.append(bounds); 707 result.append(", affineTransform: "); 708 result.append(affineTransform); 709 result.append(", tmpRotationX: "); 710 result.append(tmpRotationX); 711 result.append(", tmpRotationY: "); 712 result.append(tmpRotationY); 713 result.append(", renderMode: "); 714 result.append(renderMode); 715 result.append(')'); 716 return result.toString(); 717 } 718 719 722 protected DrawComponentContainer parent = null; 723 724 729 public DrawComponentContainer getParent() { 730 return parent; 731 } 732 733 740 public void setParent(DrawComponentContainer newParent) 741 { 742 DrawComponentContainer oldParent = parent; 743 primSetParent(newParent); 744 firePropertyChange(PROP_PARENT, oldParent, parent); 745 } 746 747 753 protected void primSetParent(DrawComponentContainer newParent) { 754 parent = newParent; 755 } 756 757 760 protected int renderMode = RENDER_MODE_EDEFAULT; 761 762 767 public int getRenderMode() { 768 return renderMode; 769 } 770 771 777 public void setRenderMode(int mode) 778 { 779 primSetRenderMode(mode); 781 firePropertyChange(PROP_RENDER_MODE, -1, renderMode); 782 } 783 784 789 protected void primSetRenderMode(int mode) 790 { 791 renderMode = mode; 792 if (getRenderModeManager() != null) 793 renderer = getRenderModeManager().getRenderer(renderMode, getRenderModeClass()); 794 } 795 796 protected transient Renderer renderer; 797 798 806 public Renderer getRenderer() 807 { 808 if (renderer == null) 809 renderer = getRenderModeManager().getRenderer(getRenderMode(), getRenderModeClass()); 810 811 return renderer; 812 } 813 814 protected transient Class renderModeClass = this.getClass(); 815 816 823 public Class getRenderModeClass() { 824 return renderModeClass; 825 } 826 827 protected transient RenderModeManager renderModeManager = null; 828 829 836 public void setRenderModeManager(RenderModeManager man) { 837 renderModeManager = man; 838 } 839 840 845 public RenderModeManager getRenderModeManager() 846 { 847 if (renderModeManager == null && getRoot() != null) { 848 renderModeManager = getRoot().getRenderModeManager(); 849 } 850 return renderModeManager; 851 } 852 853 857 public String getTypeName() { 858 return "DrawComponent"; 859 } 860 861 869 public MultiLayerDrawComponent getRoot() 870 { 871 if (getParent() != null) 872 return getParent().getRoot(); 873 return null; 874 } 875 876 879 public void setRotationMember(double value) { 880 this.rotation = value; 881 } 882 883 890 public void transform(AffineTransform newAT) 891 { 892 transform(newAT, false); 893 } 895 896 915 public void transform(AffineTransform newAT, boolean fromParent) 916 { 917 affineTransform.preConcatenate(newAT); 920 bounds = null; 921 } 922 923 927 public void clearBounds() 928 { 929 bounds = null; 930 bounds = getBounds(); 931 firePropertyChange(PROP_BOUNDS, null, bounds); 932 } 933 934 963 public Object clone(DrawComponentContainer parent) 964 { 965 try { 966 DrawComponentImpl dc = (DrawComponentImpl) super.clone(); 967 dc.affineTransform = (AffineTransform )affineTransform.clone(); 968 dc.bounds = new Rectangle (getBounds()); 969 dc.name = new I18nTextBuffer(); 970 dc.id = DrawComponent.ID_EDEFAULT; 971 name.copyTo(dc.name); 972 dc.languageId = new String (languageId); 973 dc.horizontalGuide = null; 974 dc.verticalGuide = null; 975 976 dc.renderer = renderer; 977 dc.renderMode = renderMode; 978 dc.renderModeClass = renderModeClass; 979 dc.renderModeManager = renderModeManager; 980 dc.rotation = rotation; 981 dc.rotationX = rotationX; 982 dc.rotationY = rotationY; 983 dc.tmpRotationX = tmpRotationX; 984 dc.tmpRotationY = tmpRotationY; 985 dc.height = height; 986 dc.width = width; 987 dc.x = x; 988 dc.y = y; 989 990 dc.listeners = new PropertyChangeSupport (dc); 992 PropertyChangeListener [] propertyChangeListeners = listeners.getPropertyChangeListeners(); 993 for (int i = 0; i < propertyChangeListeners.length - 1; i++) { 994 dc.listeners.addPropertyChangeListener(propertyChangeListeners[i]); 995 } 996 997 parent.addDrawComponent(dc); 999 return dc; 1000 } catch (CloneNotSupportedException e) { 1001 throw new IllegalStateException ("How the hell can clone fail?! I implemented it!", e); 1002 } 1003 } 1004 1005 public Object clone() 1006 { 1007 return clone(getParent()); 1008 } 1009 1010 1039} | Popular Tags |