Changeset 169


Ignore:
Timestamp:
07/28/08 16:52:25 (16 years ago)
Author:
bjn8
Message:

Improvements for widgets and popups

Location:
trunk/src/org/expeditee/items
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/expeditee/items/HeavyDutyInteractiveWidget.java

    r139 r169  
    77import java.awt.Rectangle;
    88import java.awt.geom.Rectangle2D;
     9import java.util.LinkedList;
    910
    1011import javax.swing.JComponent;
    1112import javax.swing.SwingUtilities;
    1213
     14import org.expeditee.gui.DisplayIO;
    1315import org.expeditee.gui.FrameGraphics;
     16import org.expeditee.gui.FreeItems;
    1417import org.expeditee.taskmanagement.EntityLoadManager;
    1518import org.expeditee.taskmanagement.EntitySaveManager;
     
    3437 * if the widget still belongs to a frame (i.e. is not removed) and is anchored.
    3538 *
     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 *
    3644 * @author Brook Novak
    3745 *
     
    4250        public static final float LOAD_STATE_COMPLETED = 2.0f;
    4351       
    44         /** waiting to load */
     52        /** waiting to load. Could have been loaded previously but expired. */
    4553        public static final float LOAD_STATE_PENDING = 3.0f;
    4654       
     
    5159        public static final float LOAD_STATE_INCOMPLETED = 5.0f;
    5260       
     61        // GUI Stuff
    5362        private static final String DEFAULT_LOAD_MESSAGE = "Loading";
    5463        private static final String PENDING_MESSAGE = "Pending";
    5564       
    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;
    5867       
    5968        private static final Font LOAD_NORMAL_FONT = new Font("Arial", Font.BOLD, 12);
     
    6271        private static final int BAR_HOROZONTIAL_MARGIN = 20;
    6372        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
    6680        private String screenMessage = DEFAULT_LOAD_MESSAGE;
    6781        private boolean hasCancelledBeenRequested;
     82        private boolean isExpired = false;
     83        private int cacheDepth = -1;
    6884
    6985        /**
    7086         * 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.
    71128         *
    72129         * @param source
     
    76133         * @param minHeight
    77134         * @param maxHeight
    78          *
    79          * @param skipLoad
    80          *              If true, the load state will be set to completed and the widget will not go through
    81          *              the loading proccess. Otherwise if true then the widget will go the loading phase.
    82135         */
    83136        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);
    108139        }
    109140       
     
    122153         */
    123154        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       
    163167       
    164168        /**
     
    274278        }
    275279       
     280       
     281       
    276282        /**
    277283         * Invoked by the load queue manager only.
     
    279285        public final void performLoad() {
    280286               
    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                
    293287                try {
    294                         finalState = loadWidgetData();
    295                 } catch (Exception e) {
     288                        doTaskAndWait(HDWTask.Load);
     289                } catch (InterruptedException e) {
     290                        loadState = LOAD_STATE_INCOMPLETED; // safety
    296291                        e.printStackTrace();
    297292                }
    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         */
    316298        public final void cancelLoadRequested() {
    317299                hasCancelledBeenRequested = true;
     
    325307        protected boolean hasCancelBeenRequested() {
    326308                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;
    327322        }
    328323
     
    364359                        case ItemParentStateChangedEvent.EVENT_TYPE_SHOWN:
    365360                        case ItemParentStateChangedEvent.EVENT_TYPE_SHOWN_VIA_OVERLAY:
     361                               
    366362                                // When anchored to the window, then requeue for loading iff load state
    367363                                // is currently pending or incomplete
     
    371367                                        EntityLoadManager.getInstance().queue(this, getLoadDelayTime());
    372368                                }
     369                               
    373370                                // Ensure that registered for saving at next save point
    374371                                EntitySaveManager.getInstance().register(this);
     372                               
     373                                // Ensure is cached
     374                                WidgetCacheManager.cacheWidget(this);
     375                               
    375376                        break;
    376377                       
     
    379380                        case ItemParentStateChangedEvent.EVENT_TYPE_REMOVED_VIA_OVERLAY:
    380381                        case ItemParentStateChangedEvent.EVENT_TYPE_HIDDEN:
     382
    381383                                // Whenever the widget is not longer in view then cancel current loading proccess
    382384                                // if currently loading. This must be performed later because this event occurs
     
    386388                                // Always unregister from save point.
    387389                                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                                }
    388397                                break;
    389398                }
     
    392401        private class DoCancelLoad implements Runnable {
    393402                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                       
    397414                }
    398415        }
     
    403420        public abstract int getLoadDelayTime();
    404421
     422        /**
     423         * Invoked by save manager
     424         */
    405425        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       
    412433        /**
    413434         * Called by dedicated thread to save data at a save point.
     
    419440        protected abstract void saveWidgetData();
    420441       
     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       
    421659}
  • trunk/src/org/expeditee/items/InteractiveWidget.java

    r142 r169  
    77import java.awt.Graphics;
    88import java.awt.Point;
     9import java.awt.Rectangle;
    910import java.lang.reflect.Constructor;
    1011import java.util.ArrayList;
     
    3940
    4041        /*
    41          * GUIDE: l1 d1-------d2 | | l4 | X | 12 | | d4-------d3 13
     42         * GUIDE: l1 d1-------d2 |
     43         * | l4 | X | 12 | | d4-------d3 13
    4244         */
    4345        private List<Item> _expediteeItems; // used for quickly returning item list
     
    5658        private Text _textRepresentation;
    5759       
    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);
    5962
    6063        // A flag for signifying whether the swing components are ready to paint.
     
    131134                                        + TAG + ":\"");
    132135
    133                 int width = -1, height = -1;
     136                float width = -1, height = -1;
    134137
    135138                if (tokens.length < 2)
     
    369372                int x = source.getX();
    370373                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);
    373376
    374377                Frame idAllocator = _textRepresentation.getParent();
     
    382385
    383386                // 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);
    388391               
    389392                Collection<Item> enclist = new ArrayList<Item>(4);
     
    407410                _expediteeItems.add(_l4);
    408411        }
    409 
     412       
    410413        /**
    411414         * This can be overrided for creating custom copies. The default implementation
     
    481484         * @param height
    482485         */
    483         public void setSize(int width, int height) {
     486        public void setSize(float width, float height) {
    484487
    485488                // Clamp
     
    502505                _d4.setFloating(true);
    503506
    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               
    506510                _d2.setX(x);
    507511                _d3.setX(x);
     
    538542                _d3.setFloating(vfloating[2]);
    539543                _d4.setFloating(vfloating[3]);
     544               
     545                onMoved();
    540546
    541547        }
     
    551557         * @return False if need to call super.setPosition
    552558         */
    553         boolean setPositions(WidgetCorner src, int x, int y) {
     559        boolean setPositions(WidgetCorner src, float x, float y) {
    554560
    555561                if (_settingPositionFlag)
     
    560566                boolean isAllPickedUp = (_d1.isFloating() && _d2.isFloating()
    561567                                && _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       
    573594                                // Check min X constraint
    574595                                if (_minWidth >= 0) {
     
    583604                                        }
    584605                                }
    585 
     606       
    586607                                if (!(src == _d4 && _d1.isFloating() && _d4.isFloating()))
    587608                                        _d1.setX(newX);
    588609                                if (!(src == _d1 && _d4.isFloating() && _d1.isFloating()))
    589610                                        _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       
    599615                                // Check min X constraint
    600616                                if (_minWidth >= 0) {
     
    609625                                        }
    610626                                }
    611 
     627       
    612628                                if (!(src == _d3 && _d2.isFloating() && _d3.isFloating()))
    613629                                        _d2.setX(newX);
     
    615631                                        _d3.setX(newX);
    616632                        }
    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       
    630639                                // Check min Y constraint
    631640                                if (_minHeight >= 0) {
     
    640649                                        }
    641650                                }
    642 
     651       
    643652                                if (!(src == _d2 && _d1.isFloating() && _d2.isFloating()))
    644653                                        _d1.setY(newY);
    645654                                if (!(src == _d1 && _d2.isFloating() && _d1.isFloating()))
    646655                                        _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       
    657660                                // Check min Y constraint
    658661                                if (_minHeight >= 0) {
     
    667670                                        }
    668671                                }
    669 
     672       
    670673                                if (!(src == _d4 && _d3.isFloating() && _d4.isFloating()))
    671674                                        _d3.setY(newY);
     
    674677                        }
    675678                }
    676 
     679               
    677680                // 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();
    680683                if (_textRepresentation.getX() != newTextX || _textRepresentation.getY() != newTextY)
    681684                        _textRepresentation.setPosition(newTextX, newTextY);
    682685
    683686                _settingPositionFlag = false;
     687               
     688                onMoved();
     689               
    684690                return true;
    685691        }
     
    694700
    695701        public int getWidth() {
     702               
    696703                return Math.abs(_d2.getX() - _d1.getX());
    697704        }
     
    832839        }
    833840       
    834         public void onBoundsChanged() {
     841        final void onBoundsChanged() {
    835842                if (isFixedSize()) _swingComponent.setBounds(getX(), getY(), _maxWidth, _maxHeight);
    836843                else _swingComponent.setBounds(getX(), getY(), getWidth(), getHeight());
     
    978985        }
    979986       
     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       
    9801011}
  • trunk/src/org/expeditee/items/Item.java

    r156 r169  
    17391739        public void onParentStateChanged(ItemParentStateChangedEvent e) {
    17401740        }
    1741 
     1741       
    17421742        public void setHighlightMode(HighlightMode mode, Color color) {
    17431743                setHighlightColor(color);
  • trunk/src/org/expeditee/items/ItemParentStateChangedEvent.java

    r108 r169  
    66 * Raised whenever the items parent (Frame) changes - when the frame is no longer in view
    77 * or becomes in view, or if the item has no parent / has a new parent.
     8 *
    89 * @author Brook Novak
    910 *
     
    2223        public static final int EVENT_TYPE_REMOVED = 6;
    2324        public static final int EVENT_TYPE_REMOVED_VIA_OVERLAY = 7;
     25       
    2426       
    2527        public ItemParentStateChangedEvent(Frame src, int eventType) {
  • trunk/src/org/expeditee/items/WidgetCorner.java

    r128 r169  
    2929        @Override
    3030        public void setPosition(float x, float y) {
     31               
    3132                invalidateFill();
    3233                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)) {
    3435                                super.setPosition(x, y);
    3536                        }
     
    4243                invalidateFill();
    4344                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)) {
    4546                                super.setXY(x, y);
    4647                        }
  • trunk/src/org/expeditee/items/WidgetEdge.java

    r139 r169  
    99 */
    1010public class WidgetEdge extends Line {
     11       
     12        private InteractiveWidget _widgetSource;
    1113         
    12         WidgetEdge(WidgetCorner start, WidgetCorner end, int id) {
     14        WidgetEdge(WidgetCorner start, WidgetCorner end, int id, InteractiveWidget widgetSource) {
    1315                super(start, end, id);
    1416                super.setThickness(2.0f);
    1517                super.setColor(Color.black);
     18               
     19                if (widgetSource == null) throw new NullPointerException("widgetSource");
     20                _widgetSource = widgetSource;
    1621        }
    1722
     23        public InteractiveWidget getWidgetSource() {
     24                return _widgetSource;
     25        }
     26       
    1827        @Override
    1928        public Item forceMerge(Item merger, int mouseX, int mouseY) {
Note: See TracChangeset for help on using the changeset viewer.