Changeset 169
- Timestamp:
- 07/28/08 16:52:25 (16 years ago)
- Location:
- trunk/src/org/expeditee/items
- Files:
-
- 1 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/expeditee/items/HeavyDutyInteractiveWidget.java
r139 r169 7 7 import java.awt.Rectangle; 8 8 import java.awt.geom.Rectangle2D; 9 import java.util.LinkedList; 9 10 10 11 import javax.swing.JComponent; 11 12 import javax.swing.SwingUtilities; 12 13 14 import org.expeditee.gui.DisplayIO; 13 15 import org.expeditee.gui.FrameGraphics; 16 import org.expeditee.gui.FreeItems; 14 17 import org.expeditee.taskmanagement.EntityLoadManager; 15 18 import org.expeditee.taskmanagement.EntitySaveManager; … … 34 37 * if the widget still belongs to a frame (i.e. is not removed) and is anchored. 35 38 * 39 * Heavey duty widgets can also have an expiry on how long they should stay cached for. If they do have an 40 * expiry then it they unload once expired, and will re-load once in view again. Must take care for 41 * unloadable widgets because you must check your unloadable elements to whether they are unloaded or not 42 * every time your widget accessess them. 43 * 36 44 * @author Brook Novak 37 45 * … … 42 50 public static final float LOAD_STATE_COMPLETED = 2.0f; 43 51 44 /** waiting to load */52 /** waiting to load. Could have been loaded previously but expired. */ 45 53 public static final float LOAD_STATE_PENDING = 3.0f; 46 54 … … 51 59 public static final float LOAD_STATE_INCOMPLETED = 5.0f; 52 60 61 // GUI Stuff 53 62 private static final String DEFAULT_LOAD_MESSAGE = "Loading"; 54 63 private static final String PENDING_MESSAGE = "Pending"; 55 64 56 private static final Color LOAD_SCREEN_COLOR = new Color(150,150,250);57 private static final Color LOAD_SCREEN_COLOR_FREESPACE = new Color(50,50,180, 128);65 private static final Color LOAD_SCREEN_COLOR = Color.LIGHT_GRAY; 66 private static final Color LOAD_SCREEN_COLOR_FREESPACE = FREESPACE_BACKCOLOR; 58 67 59 68 private static final Font LOAD_NORMAL_FONT = new Font("Arial", Font.BOLD, 12); … … 62 71 private static final int BAR_HOROZONTIAL_MARGIN = 20; 63 72 private static final int BAR_HEIGHT = 40; 64 65 private float loadState = LOAD_STATE_PENDING; 73 74 /** Unifies state transitions to a single thread. */ 75 private LoadStateManager stateProccessor = null; 76 private LinkedList<HDWTask> queuedTasks = new LinkedList<HDWTask>(); 77 78 // Model data 79 private float loadState; // handled by constructors and stateProccessor 66 80 private String screenMessage = DEFAULT_LOAD_MESSAGE; 67 81 private boolean hasCancelledBeenRequested; 82 private boolean isExpired = false; 83 private int cacheDepth = -1; 68 84 69 85 /** 70 86 * Constructor. 87 * 88 * @param source 89 * 90 * @param component 91 * 92 * @param minWidth 93 * 94 * @param maxWidth 95 * 96 * @param minHeight 97 * 98 * @param maxHeight 99 * 100 * @param cacheDepth 101 * Less or equal to zero for no cache management - i.e. use expeditees frame caching. 102 * Positive to limit cache; where the widget will be explicity unloaded 103 * ({@link HeavyDutyInteractiveWidget#unloadWidgetData()}) once the user has traversed 104 * cacheDepth frames without seeing this instance. 105 * The general rule is: the more memory your widget may take, the smaller the cache depth. 106 * 107 * @param skipLoad 108 * If true, the load state will be set to completed and the widget will not go through 109 * the loading proccess. Otherwise if true then the widget will go the loading phase. 110 */ 111 protected HeavyDutyInteractiveWidget(Text source, JComponent component, 112 int minWidth, int maxWidth, int minHeight, int maxHeight, int cacheDepth, boolean skipLoad) { 113 super(source, component, minWidth, maxWidth, minHeight, maxHeight); 114 115 this.cacheDepth = cacheDepth; 116 117 if (skipLoad) { 118 loadState = LOAD_STATE_COMPLETED; 119 } else { 120 loadState = LOAD_STATE_PENDING; 121 component.setVisible(false); // not allowed to interact with it yet 122 component.setEnabled(false); 123 } 124 } 125 126 /** 127 * Chained constructor. 71 128 * 72 129 * @param source … … 76 133 * @param minHeight 77 134 * @param maxHeight 78 *79 * @param skipLoad80 * If true, the load state will be set to completed and the widget will not go through81 * the loading proccess. Otherwise if true then the widget will go the loading phase.82 135 */ 83 136 protected HeavyDutyInteractiveWidget(Text source, JComponent component, 84 int minWidth, int maxWidth, int minHeight, int maxHeight, boolean skipLoad) { 85 super(source, component, minWidth, maxWidth, minHeight, maxHeight); 86 87 if (skipLoad) { 88 loadState = LOAD_STATE_COMPLETED; 89 } else { 90 component.setVisible(false); // not allowed to interact with it yet 91 component.setEnabled(false); 92 } 93 } 94 95 /** 96 * Chained constructor. 97 * 98 * @param source 99 * @param component 100 * @param minWidth 101 * @param maxWidth 102 * @param minHeight 103 * @param maxHeight 104 */ 105 protected HeavyDutyInteractiveWidget(Text source, JComponent component, 106 int minWidth, int maxWidth, int minHeight, int maxHeight) { 107 this(source, component, minWidth, maxWidth, minHeight, maxHeight, false); 137 int minWidth, int maxWidth, int minHeight, int maxHeight, int cacheDepth) { 138 this(source, component, minWidth, maxWidth, minHeight, maxHeight, cacheDepth, false); 108 139 } 109 140 … … 122 153 */ 123 154 protected final void updateLoadPercentage(float percent) { 124 if (percent > 1.0f) throw new IllegalArgumentException("loadState is larger than 1.0"); 125 else if (!isInLoadProgress()) throw new IllegalStateException("Load is not in progress"); 126 setLoadState(percent); 127 } 128 129 /** 130 * @param loadState 131 * Can be any of the following values. 132 * <ul> 133 * <li>PENDING_STATE if pending. 134 * <li>COMPLETED_STATE if loaded. 135 * <li>between 0.0f and 1.0f inclusive if loading: represents progress percent complete. 136 * <li>FAILED_STATE if failed. 137 * <li>INCOMPLETED_STATE if load was unable to complete. 138 * <li>negative if loading but indeterminant. 139 * </ul> 140 * 141 */ 142 private final void setLoadState(float loadState) { 143 assert (loadState == LOAD_STATE_FAILED || loadState != LOAD_STATE_INCOMPLETED || 144 loadState != LOAD_STATE_PENDING || loadState != LOAD_STATE_COMPLETED || 145 loadState < 1.0f) ; 146 147 this.loadState = loadState; 148 149 if (this.loadState == LOAD_STATE_COMPLETED) { 150 // Never use invoke and wait 151 SwingUtilities.invokeLater(new Runnable() { 152 public void run() { 153 _swingComponent.setVisible(true); 154 _swingComponent.setEnabled(true); 155 } 156 }); 157 } 158 159 // Re-render loading state 160 FrameGraphics.invalidateArea(new Rectangle(getX(), getY(), getWidth(), getHeight())); 161 FrameGraphics.requestRefresh(true); 162 } 155 if (percent > 1.0f) 156 throw new IllegalArgumentException("loadState is larger than 1.0"); 157 158 else if (!isInLoadProgress() || 159 stateProccessor == null || 160 !stateProccessor.isAlive()) 161 throw new IllegalStateException("Load is not in progress"); 162 163 // Assuming that this is called from stateProccessor. 164 stateProccessor.setLoadState(percent, false); 165 } 166 163 167 164 168 /** … … 274 278 } 275 279 280 281 276 282 /** 277 283 * Invoked by the load queue manager only. … … 279 285 public final void performLoad() { 280 286 281 // Check that not already loaded.282 if (loadState == LOAD_STATE_COMPLETED ||283 loadState == LOAD_STATE_FAILED) return;284 285 // Reset flag.286 hasCancelledBeenRequested = false;287 288 // Set the load state as loading... 0%289 setLoadState(0.0f);290 291 float finalState = LOAD_STATE_FAILED;292 293 287 try { 294 finalState = loadWidgetData(); 295 } catch (Exception e) { 288 doTaskAndWait(HDWTask.Load); 289 } catch (InterruptedException e) { 290 loadState = LOAD_STATE_INCOMPLETED; // safety 296 291 e.printStackTrace(); 297 292 } 298 299 // Safety check for return state 300 try { 301 if (finalState != LOAD_STATE_COMPLETED 302 && finalState != LOAD_STATE_FAILED 303 && finalState != LOAD_STATE_INCOMPLETED) { 304 throw new Exception("ERROR: Bad return state: " + finalState); 305 } 306 } catch (Exception e) { 307 e.printStackTrace(); 308 finalState = LOAD_STATE_COMPLETED; 309 } 310 311 // Set the final state 312 setLoadState(finalState); 313 314 } 315 293 } 294 295 /** 296 * Invoked by load manager 297 */ 316 298 public final void cancelLoadRequested() { 317 299 hasCancelledBeenRequested = true; … … 325 307 protected boolean hasCancelBeenRequested() { 326 308 return hasCancelledBeenRequested; 309 } 310 311 /** 312 * 313 * @return 314 * True if this widget is in an expired state 315 */ 316 protected boolean isExpired() { 317 return isExpired; 318 } 319 320 protected boolean isLoaded() { 321 return this.loadState == LOAD_STATE_COMPLETED; 327 322 } 328 323 … … 364 359 case ItemParentStateChangedEvent.EVENT_TYPE_SHOWN: 365 360 case ItemParentStateChangedEvent.EVENT_TYPE_SHOWN_VIA_OVERLAY: 361 366 362 // When anchored to the window, then requeue for loading iff load state 367 363 // is currently pending or incomplete … … 371 367 EntityLoadManager.getInstance().queue(this, getLoadDelayTime()); 372 368 } 369 373 370 // Ensure that registered for saving at next save point 374 371 EntitySaveManager.getInstance().register(this); 372 373 // Ensure is cached 374 WidgetCacheManager.cacheWidget(this); 375 375 376 break; 376 377 … … 379 380 case ItemParentStateChangedEvent.EVENT_TYPE_REMOVED_VIA_OVERLAY: 380 381 case ItemParentStateChangedEvent.EVENT_TYPE_HIDDEN: 382 381 383 // Whenever the widget is not longer in view then cancel current loading proccess 382 384 // if currently loading. This must be performed later because this event occurs … … 386 388 // Always unregister from save point. 387 389 EntitySaveManager.getInstance().unregister(this); 390 391 // If the widget has been removed then unregister from caching 392 // So that if deleted then won't hang around in cache 393 if (e.getEventType() == ItemParentStateChangedEvent.EVENT_TYPE_REMOVED) { 394 WidgetCacheManager.uncacheWidget(this); 395 // If removed via overlay, then cached frames may still contain overlay with the widget... 396 } 388 397 break; 389 398 } … … 392 401 private class DoCancelLoad implements Runnable { 393 402 public void run() { 394 if (!isFloating()) { 395 EntityLoadManager.getInstance().cancel(HeavyDutyInteractiveWidget.this); 396 } 403 404 for (Item i : getItems()) { // Only cancel if the widget is not floating. Allow loading while in free space 405 if (FreeItems.getInstance().contains(i)) 406 return; 407 } 408 409 // TODO: One problem with loading in free space is that there is no way of cancelling 410 // if the heavy duty widget is deleted in free space while loading. 411 // This is just an inefficiency. 412 EntityLoadManager.getInstance().cancel(HeavyDutyInteractiveWidget.this); 413 397 414 } 398 415 } … … 403 420 public abstract int getLoadDelayTime(); 404 421 422 /** 423 * Invoked by save manager 424 */ 405 425 public final void performSave() { 406 // Only save if still belongs to a frame 407 if (!isFloating() && getParentFrame() != null) { 408 saveWidgetData(); 409 } 410 } 411 426 try { 427 doTaskAndWait(HDWTask.Save); 428 } catch (InterruptedException e) { 429 e.printStackTrace(); 430 } 431 } 432 412 433 /** 413 434 * Called by dedicated thread to save data at a save point. … … 419 440 protected abstract void saveWidgetData(); 420 441 442 /** 443 * Only invoked if has cache expiry and has expired. Only if this is no longer visible. 444 */ 445 void expire() { 446 doTaskLater(HDWTask.Unload); 447 } 448 449 /** 450 * Invoked if this widget has a cache expiry and has been expired. 451 * The protocol is that you should unload anything in memory... 452 * This should be quick, e.g. setting references to null / disposing. 453 * Pupose is to free memory. 454 * 455 * Important note: 456 * It is possible for a widget to expire before it had a chance to be saved, 457 * or even when saving. Thus must be careful. 458 * A simple approach would be to check the saving flag 459 * 460 * 461 */ 462 protected abstract void unloadWidgetData(); 463 464 /** 465 * The cache depth is measured by how many frames the user can traverse through until 466 * the widget should expire. 467 * 468 * This is immutable. 469 * 470 * @return 471 * The cache depth for this interactive widget. less or equal to zero for no cache expiry. 472 */ 473 public final int getCacheDepth() { 474 return cacheDepth; 475 } 476 477 private synchronized void doTaskAndWait(HDWTask task) throws InterruptedException { 478 queueTask(task); 479 stateProccessor.join(); 480 } 481 482 private void doTaskLater(HDWTask task) { 483 queueTask(task); 484 } 485 486 private void queueTask(HDWTask task) { 487 488 synchronized(queuedTasks) { 489 490 if (!queuedTasks.contains(task)) 491 queuedTasks.add(task); 492 493 494 if (stateProccessor == null || !stateProccessor.isAlive()) { 495 stateProccessor = new LoadStateManager(); 496 stateProccessor.start(); 497 } 498 499 } 500 501 } 502 503 504 /** 505 * Unified state management. Load states are handled by one thread always. 506 * Only has one instance - per widget instance, of this at any given time, 507 * 508 * @author Brook 509 * 510 */ 511 private class LoadStateManager extends Thread { 512 513 /** 514 * @param loadState 515 * Can be any of the following values. 516 * <ul> 517 * <li>PENDING_STATE if pending. 518 * <li>COMPLETED_STATE if loaded. 519 * <li>between 0.0f and 1.0f inclusive if loading: represents progress percent complete. 520 * <li>FAILED_STATE if failed. 521 * <li>INCOMPLETED_STATE if load was unable to complete. 522 * <li>negative if loading but indeterminant. 523 * </ul> 524 * 525 */ 526 private void setLoadState(float state, boolean expired) { 527 assert (state == LOAD_STATE_FAILED || state != LOAD_STATE_INCOMPLETED || 528 state != LOAD_STATE_PENDING || state != LOAD_STATE_COMPLETED || 529 state < 1.0f) ; 530 531 assert (!expired || 532 (expired && state == LOAD_STATE_PENDING)); 533 534 535 isExpired = expired; 536 loadState = state; 537 538 if (loadState == LOAD_STATE_COMPLETED) { // set enabled state - show the swing components 539 SwingUtilities.invokeLater(new Runnable() { 540 public void run() { 541 _swingComponent.setVisible(true); 542 _swingComponent.setEnabled(true); 543 } 544 }); 545 546 } else if(expired) { // disable/hide swing GUI when expires, like a reset 547 548 SwingUtilities.invokeLater(new Runnable() { 549 public void run() { 550 _swingComponent.setVisible(false); 551 _swingComponent.setEnabled(false); 552 } 553 }); 554 } 555 556 // Re-render loading state - if not expired 557 if (!expired) { 558 FrameGraphics.invalidateArea(new Rectangle(getX(), getY(), getWidth(), getHeight())); 559 FrameGraphics.requestRefresh(true); 560 } 561 } 562 563 /** 564 * All state transitions performed by one thread. 565 */ 566 public void run() { 567 568 while (true) { // keep proccessing tasks 569 570 HDWTask task = null; 571 572 synchronized(queuedTasks) { 573 if (queuedTasks.isEmpty()) return; 574 task = queuedTasks.remove(); 575 } 576 577 if (task == HDWTask.Load) { 578 doLoad(); 579 } else if (task == HDWTask.Save) { 580 doSave(); // does not change state 581 } else { 582 assert(task == HDWTask.Unload); 583 doUnload(); 584 } 585 } 586 } 587 588 private void doLoad() { 589 590 // Check that not already loaded. 591 if (loadState == LOAD_STATE_COMPLETED || 592 loadState == LOAD_STATE_FAILED) return; 593 594 // Only load if in view 595 if (!isFloating() && getParentFrame() != DisplayIO.getCurrentFrame()) 596 return; 597 598 // Reset flag. 599 hasCancelledBeenRequested = false; 600 601 // Set the load state as loading... 0% 602 setLoadState(0.0f, false); 603 604 float finalState = LOAD_STATE_FAILED; 605 606 try { 607 finalState = loadWidgetData(); 608 } catch (Exception e) { 609 e.printStackTrace(); 610 } 611 612 // Safety check for return state 613 try { 614 if (finalState != LOAD_STATE_COMPLETED 615 && finalState != LOAD_STATE_FAILED 616 && finalState != LOAD_STATE_INCOMPLETED) { 617 throw new Exception("ERROR: Bad return state: " + finalState); 618 } 619 } catch (Exception e) { 620 e.printStackTrace(); 621 finalState = LOAD_STATE_COMPLETED; 622 } 623 624 // Set the final state 625 setLoadState(finalState, false); 626 627 } 628 629 private void doSave() { 630 631 // Only save if still belongs to a frame 632 if (!isFloating() && getParentFrame() != null) { 633 saveWidgetData(); 634 } 635 636 } 637 638 private void doUnload() { 639 640 // Reset the load state 641 setLoadState(LOAD_STATE_PENDING, true); 642 643 // Get rid of memory 644 unloadWidgetData(); 645 646 } 647 648 649 650 } 651 652 private enum HDWTask { 653 Save, 654 Load, 655 Unload 656 } 657 658 421 659 } -
trunk/src/org/expeditee/items/InteractiveWidget.java
r142 r169 7 7 import java.awt.Graphics; 8 8 import java.awt.Point; 9 import java.awt.Rectangle; 9 10 import java.lang.reflect.Constructor; 10 11 import java.util.ArrayList; … … 39 40 40 41 /* 41 * GUIDE: l1 d1-------d2 | | l4 | X | 12 | | d4-------d3 13 42 * GUIDE: l1 d1-------d2 | 43 * | l4 | X | 12 | | d4-------d3 13 42 44 */ 43 45 private List<Item> _expediteeItems; // used for quickly returning item list … … 56 58 private Text _textRepresentation; 57 59 58 private final static Color FREESPACE_BACKCOLOR = new Color(100,100,100,128); 60 //private final static Color FREESPACE_BACKCOLOR = new Color(100,100,100,128); 61 protected final static Color FREESPACE_BACKCOLOR = new Color(100,100,100); 59 62 60 63 // A flag for signifying whether the swing components are ready to paint. … … 131 134 + TAG + ":\""); 132 135 133 int width = -1, height = -1;136 float width = -1, height = -1; 134 137 135 138 if (tokens.length < 2) … … 369 372 int x = source.getX(); 370 373 int y = source.getY(); 371 int width = ( _minWidth < 0) ? 10 : _minWidth;372 int height = ( _minHeight < 0) ? 10 : _minHeight;374 int width = (int)((_minWidth < 0) ? 10 : _minWidth); 375 int height = (int)((_minHeight < 0) ? 10 : _minHeight); 373 376 374 377 Frame idAllocator = _textRepresentation.getParent(); … … 382 385 383 386 // create WidgetEdges 384 _l1 = new WidgetEdge(_d1, _d2, idAllocator.getNextItemID() );385 _l2 = new WidgetEdge(_d2, _d3, idAllocator.getNextItemID() );386 _l3 = new WidgetEdge(_d3, _d4, idAllocator.getNextItemID() );387 _l4 = new WidgetEdge(_d4, _d1, idAllocator.getNextItemID() );387 _l1 = new WidgetEdge(_d1, _d2, idAllocator.getNextItemID(), this); 388 _l2 = new WidgetEdge(_d2, _d3, idAllocator.getNextItemID(), this); 389 _l3 = new WidgetEdge(_d3, _d4, idAllocator.getNextItemID(), this); 390 _l4 = new WidgetEdge(_d4, _d1, idAllocator.getNextItemID(), this); 388 391 389 392 Collection<Item> enclist = new ArrayList<Item>(4); … … 407 410 _expediteeItems.add(_l4); 408 411 } 409 412 410 413 /** 411 414 * This can be overrided for creating custom copies. The default implementation … … 481 484 * @param height 482 485 */ 483 public void setSize( int width, int height) {486 public void setSize(float width, float height) { 484 487 485 488 // Clamp … … 502 505 _d4.setFloating(true); 503 506 504 int x = _d1.getX() + width; 505 int y = _d1.getY() + height; 507 float x = _d1.getX() + width; 508 float y = _d1.getY() + height; 509 506 510 _d2.setX(x); 507 511 _d3.setX(x); … … 538 542 _d3.setFloating(vfloating[2]); 539 543 _d4.setFloating(vfloating[3]); 544 545 onMoved(); 540 546 541 547 } … … 551 557 * @return False if need to call super.setPosition 552 558 */ 553 boolean setPositions(WidgetCorner src, int x, int y) {559 boolean setPositions(WidgetCorner src, float x, float y) { 554 560 555 561 if (_settingPositionFlag) … … 560 566 boolean isAllPickedUp = (_d1.isFloating() && _d2.isFloating() 561 567 && _d3.isFloating() && _d4.isFloating()); 562 563 int newX = x; 564 565 // X Positions 566 if (src == _d1 || src == _d4) { 567 568 if (src == _d1 && isAllPickedUp) 569 _d1.setX(newX); 570 else if (src == _d4 && isAllPickedUp) 571 _d4.setX(newX); 572 else { 568 569 // If so, then this will be called one by one .. 570 if (isAllPickedUp) { 571 src.setPosition(x, y); 572 } else { 573 574 float newX = x; 575 576 // Reference: 577 // D1 D2 578 // D3 D4 579 580 // 581 // GUIDE: 582 // l1 583 // d1-------d2 584 // | | 585 // l4 | X | 12 586 // | | 587 // d4-------d3 588 // 13 589 // 590 591 // X Positions 592 if (src == _d1 || src == _d4) { 593 573 594 // Check min X constraint 574 595 if (_minWidth >= 0) { … … 583 604 } 584 605 } 585 606 586 607 if (!(src == _d4 && _d1.isFloating() && _d4.isFloating())) 587 608 _d1.setX(newX); 588 609 if (!(src == _d1 && _d4.isFloating() && _d1.isFloating())) 589 610 _d4.setX(newX); 590 } 591 592 } else if (src == _d2 || src == _d3) { 593 594 if (src == _d2 && isAllPickedUp) 595 _d2.setX(newX); 596 else if (src == _d3 && isAllPickedUp) 597 _d3.setX(newX); 598 else { 611 612 } else if (src == _d2 || src == _d3) { 613 614 599 615 // Check min X constraint 600 616 if (_minWidth >= 0) { … … 609 625 } 610 626 } 611 627 612 628 if (!(src == _d3 && _d2.isFloating() && _d3.isFloating())) 613 629 _d2.setX(newX); … … 615 631 _d3.setX(newX); 616 632 } 617 618 } 619 620 int newY = y; 621 622 // Y Positions 623 if (src == _d1 || src == _d2) { 624 625 if (src == _d1 && isAllPickedUp) 626 _d1.setY(newY); 627 else if (src == _d2 && isAllPickedUp) 628 _d2.setY(newY); 629 else { 633 634 float newY = y; 635 636 // Y Positions 637 if (src == _d1 || src == _d2) { 638 630 639 // Check min Y constraint 631 640 if (_minHeight >= 0) { … … 640 649 } 641 650 } 642 651 643 652 if (!(src == _d2 && _d1.isFloating() && _d2.isFloating())) 644 653 _d1.setY(newY); 645 654 if (!(src == _d1 && _d2.isFloating() && _d1.isFloating())) 646 655 _d2.setY(newY); 647 648 } 649 650 } else if (src == _d3 || src == _d4) { 651 652 if (src == _d3 && isAllPickedUp) 653 _d3.setY(newY); 654 else if (src == _d4 && isAllPickedUp) 655 _d4.setY(newY); 656 else { 656 657 } else if (src == _d3 || src == _d4) { 658 659 657 660 // Check min Y constraint 658 661 if (_minHeight >= 0) { … … 667 670 } 668 671 } 669 672 670 673 if (!(src == _d4 && _d3.isFloating() && _d4.isFloating())) 671 674 _d3.setY(newY); … … 674 677 } 675 678 } 676 679 677 680 // Update source text position so position is remembered from loading 678 int newTextX = getX();679 int newTextY = getY();681 float newTextX = getX(); 682 float newTextY = getY(); 680 683 if (_textRepresentation.getX() != newTextX || _textRepresentation.getY() != newTextY) 681 684 _textRepresentation.setPosition(newTextX, newTextY); 682 685 683 686 _settingPositionFlag = false; 687 688 onMoved(); 689 684 690 return true; 685 691 } … … 694 700 695 701 public int getWidth() { 702 696 703 return Math.abs(_d2.getX() - _d1.getX()); 697 704 } … … 832 839 } 833 840 834 publicvoid onBoundsChanged() {841 final void onBoundsChanged() { 835 842 if (isFixedSize()) _swingComponent.setBounds(getX(), getY(), _maxWidth, _maxHeight); 836 843 else _swingComponent.setBounds(getX(), getY(), getWidth(), getHeight()); … … 978 985 } 979 986 987 protected void invalidateSelf() { 988 Rectangle dirty = new Rectangle((int)getX(), (int)getY(), (int)getWidth(), (int)getHeight()); 989 FrameGraphics.invalidateArea(dirty); 990 FrameGraphics.refresh(true); 991 } 992 993 /** 994 * @see ItemUtils#isVisible(Item) 995 * 996 * @return 997 * True if this widget is visible from the current frame. 998 * Considers overlays and vectors. 999 * 1000 */ 1001 public boolean isVisible() { 1002 return ItemUtils.isVisible(_d1); 1003 } 1004 1005 /** 1006 * Invoked whenever the widget have moved. 1007 * 1008 */ 1009 protected void onMoved() { } 1010 980 1011 } -
trunk/src/org/expeditee/items/Item.java
r156 r169 1739 1739 public void onParentStateChanged(ItemParentStateChangedEvent e) { 1740 1740 } 1741 1741 1742 1742 public void setHighlightMode(HighlightMode mode, Color color) { 1743 1743 setHighlightColor(color); -
trunk/src/org/expeditee/items/ItemParentStateChangedEvent.java
r108 r169 6 6 * Raised whenever the items parent (Frame) changes - when the frame is no longer in view 7 7 * or becomes in view, or if the item has no parent / has a new parent. 8 * 8 9 * @author Brook Novak 9 10 * … … 22 23 public static final int EVENT_TYPE_REMOVED = 6; 23 24 public static final int EVENT_TYPE_REMOVED_VIA_OVERLAY = 7; 25 24 26 25 27 public ItemParentStateChangedEvent(Frame src, int eventType) { -
trunk/src/org/expeditee/items/WidgetCorner.java
r128 r169 29 29 @Override 30 30 public void setPosition(float x, float y) { 31 31 32 invalidateFill(); 32 33 if (_widgetSource != null) { // _widgetSource == null on construction 33 if (!_widgetSource.setPositions(this, (int)(x+0.5),(int)(y+0.5))) {34 if (!_widgetSource.setPositions(this, x, y)) { 34 35 super.setPosition(x, y); 35 36 } … … 42 43 invalidateFill(); 43 44 if (_widgetSource != null) { // _widgetSource == null on construction 44 if (!_widgetSource.setPositions(this, (int)(x+0.5),(int)(y+0.5))) {45 if (!_widgetSource.setPositions(this, x, y)) { 45 46 super.setXY(x, y); 46 47 } -
trunk/src/org/expeditee/items/WidgetEdge.java
r139 r169 9 9 */ 10 10 public class WidgetEdge extends Line { 11 12 private InteractiveWidget _widgetSource; 11 13 12 WidgetEdge(WidgetCorner start, WidgetCorner end, int id ) {14 WidgetEdge(WidgetCorner start, WidgetCorner end, int id, InteractiveWidget widgetSource) { 13 15 super(start, end, id); 14 16 super.setThickness(2.0f); 15 17 super.setColor(Color.black); 18 19 if (widgetSource == null) throw new NullPointerException("widgetSource"); 20 _widgetSource = widgetSource; 16 21 } 17 22 23 public InteractiveWidget getWidgetSource() { 24 return _widgetSource; 25 } 26 18 27 @Override 19 28 public Item forceMerge(Item merger, int mouseX, int mouseY) {
Note:
See TracChangeset
for help on using the changeset viewer.