Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / src / ProgressBar.js
index 6c793b6..1dcb515 100644 (file)
@@ -13,39 +13,34 @@ If you are unsure which license is appropriate for your use, please contact the
 
 */
 /**
- * @class Ext.ProgressBar
- * @extends Ext.Component
- * <p>An updateable progress bar component.  The progress bar supports two different modes: manual and automatic.</p>
- * <p>In manual mode, you are responsible for showing, updating (via {@link #updateProgress}) and clearing the
- * progress bar as needed from your own code.  This method is most appropriate when you want to show progress
- * throughout an operation that has predictable points of interest at which you can update the control.</p>
- * <p>In automatic mode, you simply call {@link #wait} and let the progress bar run indefinitely, only clearing it
- * once the operation is complete.  You can optionally have the progress bar wait for a specific amount of time
- * and then clear itself.  Automatic mode is most appropriate for timed operations or asynchronous operations in
- * which you have no need for indicating intermediate progress.</p>
- * {@img Ext.ProgressBar/Ext.ProgressBar.png Ext.ProgressBar component}
- * Example Usage:
-     var p = Ext.create('Ext.ProgressBar', {
-       renderTo: Ext.getBody(),
-       width: 300
-    });
-
-    //Wait for 5 seconds, then update the status el (progress bar will auto-reset)
-    p.wait({
-       interval: 500, //bar will move fast!
-       duration: 50000,
-       increment: 15,
-       text: 'Updating...',
-       scope: this,
-       fn: function(){
-          p.updateText('Done!');
-       }
-    });
- * @cfg {Float} value A floating point value between 0 and 1 (e.g., .5, defaults to 0)
- * @cfg {String} text The progress bar text (defaults to '')
- * @cfg {Mixed} textEl The element to render the progress text to (defaults to the progress
- * bar's internal text element)
- * @cfg {String} id The progress bar element's id (defaults to an auto-generated id)
+ * An updateable progress bar component. The progress bar supports two different modes: manual and automatic.
+ *
+ * In manual mode, you are responsible for showing, updating (via {@link #updateProgress}) and clearing the progress bar
+ * as needed from your own code. This method is most appropriate when you want to show progress throughout an operation
+ * that has predictable points of interest at which you can update the control.
+ *
+ * In automatic mode, you simply call {@link #wait} and let the progress bar run indefinitely, only clearing it once the
+ * operation is complete. You can optionally have the progress bar wait for a specific amount of time and then clear
+ * itself. Automatic mode is most appropriate for timed operations or asynchronous operations in which you have no need
+ * for indicating intermediate progress.
+ *
+ *     @example
+ *     var p = Ext.create('Ext.ProgressBar', {
+ *        renderTo: Ext.getBody(),
+ *        width: 300
+ *     });
+ *
+ *     // Wait for 5 seconds, then update the status el (progress bar will auto-reset)
+ *     p.wait({
+ *         interval: 500, //bar will move fast!
+ *         duration: 50000,
+ *         increment: 15,
+ *         text: 'Updating...',
+ *         scope: this,
+ *         fn: function(){
+ *             p.updateText('Done!');
+ *         }
+ *     });
  */
 Ext.define('Ext.ProgressBar', {
     extend: 'Ext.Component',
@@ -59,21 +54,43 @@ Ext.define('Ext.ProgressBar', {
     ],
 
     uses: ['Ext.fx.Anim'],
+
+   /**
+    * @cfg {Number} [value=0]
+    * A floating point value between 0 and 1 (e.g., .5)
+    */
+
+   /**
+    * @cfg {String} [text='']
+    * The progress bar text (defaults to '')
+    */
+
+   /**
+    * @cfg {String/HTMLElement/Ext.Element} textEl
+    * The element to render the progress text to (defaults to the progress bar's internal text element)
+    */
+
+   /**
+    * @cfg {String} id
+    * The progress bar element's id (defaults to an auto-generated id)
+    */
+
    /**
-    * @cfg {String} baseCls
-    * The base CSS class to apply to the progress bar's wrapper element (defaults to 'x-progress')
+    * @cfg {String} [baseCls='x-progress']
+    * The base CSS class to apply to the progress bar's wrapper element.
     */
     baseCls: Ext.baseCSSPrefix + 'progress',
 
     config: {
         /**
         * @cfg {Boolean} animate
-        * True to animate the progress bar during transitions (defaults to false)
+        * True to animate the progress bar during transitions
         */
         animate: false,
 
         /**
-         * @cfg {String} text The text shown in the progress bar (defaults to '')
+         * @cfg {String} text
+         * The text shown in the progress bar
          */
         text: ''
     },
@@ -85,7 +102,7 @@ Ext.define('Ext.ProgressBar', {
         '<div class="{baseCls}-text {baseCls}-text-back">',
             '<div>&#160;</div>',
         '</div>',
-        '<div class="{baseCls}-bar">',
+        '<div id="{id}-bar" class="{baseCls}-bar">',
             '<div class="{baseCls}-text">',
                 '<div>&#160;</div>',
             '</div>',
@@ -98,19 +115,15 @@ Ext.define('Ext.ProgressBar', {
     initComponent: function() {
         this.callParent();
 
-        this.renderSelectors = Ext.apply(this.renderSelectors || {}, {
-            textTopEl: '.' + this.baseCls + '-text',
-            textBackEl: '.' + this.baseCls + '-text-back',
-            bar: '.' + this.baseCls + '-bar'
-        });
+        this.addChildEls('bar');
 
         this.addEvents(
             /**
              * @event update
              * Fires after each update interval
              * @param {Ext.ProgressBar} this
-             * @param {Number} The current progress value
-             * @param {String} The current progress text
+             * @param {Number} value The current progress value
+             * @param {String} text The current progress text
              */
             "update"
         );
@@ -119,9 +132,11 @@ Ext.define('Ext.ProgressBar', {
     afterRender : function() {
         var me = this;
 
+        // This produces a composite w/2 el's (which is why we cannot use childEls or
+        // renderSelectors):
         me.textEl = me.textEl ? Ext.get(me.textEl) : me.el.select('.' + me.baseCls + '-text');
 
-        this.callParent(arguments);
+        me.callParent(arguments);
 
         if (me.value) {
             me.updateProgress(me.value, me.text);
@@ -132,54 +147,63 @@ Ext.define('Ext.ProgressBar', {
     },
 
     /**
-     * Updates the progress bar value, and optionally its text.  If the text argument is not specified,
-     * any existing text value will be unchanged.  To blank out existing text, pass ''.  Note that even
-     * if the progress bar value exceeds 1, it will never automatically reset -- you are responsible for
-     * determining when the progress is complete and calling {@link #reset} to clear and/or hide the control.
-     * @param {Float} value (optional) A floating point value between 0 and 1 (e.g., .5, defaults to 0)
-     * @param {String} text (optional) The string to display in the progress text element (defaults to '')
-     * @param {Boolean} animate (optional) Whether to animate the transition of the progress bar. If this value is
-     * not specified, the default for the class is used (default to false)
+     * Updates the progress bar value, and optionally its text. If the text argument is not specified, any existing text
+     * value will be unchanged. To blank out existing text, pass ''. Note that even if the progress bar value exceeds 1,
+     * it will never automatically reset -- you are responsible for determining when the progress is complete and
+     * calling {@link #reset} to clear and/or hide the control.
+     * @param {Number} [value=0] A floating point value between 0 and 1 (e.g., .5)
+     * @param {String} [text=''] The string to display in the progress text element
+     * @param {Boolean} [animate=false] Whether to animate the transition of the progress bar. If this value is not
+     * specified, the default for the class is used
      * @return {Ext.ProgressBar} this
      */
     updateProgress: function(value, text, animate) {
-        var newWidth;
-        this.value = value || 0;
+        var me = this,
+            newWidth;
+            
+        me.value = value || 0;
         if (text) {
-            this.updateText(text);
+            me.updateText(text);
         }
-        if (this.rendered && !this.isDestroyed) {
-            newWidth = Math.floor(this.value * this.el.getWidth(true));
-            if (Ext.isForcedBorderBox) {
-                newWidth += this.bar.getBorderWidth("lr");
-            }
-            if (animate === true || (animate !== false && this.animate)) {
-                this.bar.stopAnimation();
-                this.bar.animate(Ext.apply({
-                    to: {
-                        width: newWidth + 'px'
-                    }
-                }, this.animate));
+        if (me.rendered && !me.isDestroyed) {
+            if (me.isVisible(true)) {
+                newWidth = Math.floor(me.value * me.el.getWidth(true));
+                if (Ext.isForcedBorderBox) {
+                    newWidth += me.bar.getBorderWidth("lr");
+                }
+                if (animate === true || (animate !== false && me.animate)) {
+                    me.bar.stopAnimation();
+                    me.bar.animate(Ext.apply({
+                        to: {
+                            width: newWidth + 'px'
+                        }
+                    }, me.animate));
+                } else {
+                    me.bar.setWidth(newWidth);
+                }
             } else {
-                this.bar.setWidth(newWidth);
+                // force a layout when we're visible again
+                me.doComponentLayout();
             }
         }
-        this.fireEvent('update', this, this.value, text);
-        return this;
+        me.fireEvent('update', me, me.value, text);
+        return me;
     },
 
     /**
-     * Updates the progress bar text.  If specified, textEl will be updated, otherwise the progress
-     * bar itself will display the updated text.
-     * @param {String} text (optional) The string to display in the progress text element (defaults to '')
+     * Updates the progress bar text. If specified, textEl will be updated, otherwise the progress bar itself will
+     * display the updated text.
+     * @param {String} [text=''] The string to display in the progress text element
      * @return {Ext.ProgressBar} this
      */
     updateText: function(text) {
-        this.text = text;
-        if (this.rendered) {
-            this.textEl.update(this.text);
+        var me = this;
+        
+        me.text = text;
+        if (me.rendered) {
+            me.textEl.update(me.text);
         }
-        return this;
+        return me;
     },
 
     applyText : function(text) {
@@ -187,91 +211,87 @@ Ext.define('Ext.ProgressBar', {
     },
 
     /**
-         * Initiates an auto-updating progress bar.  A duration can be specified, in which case the progress
-         * bar will automatically reset after a fixed amount of time and optionally call a callback function
-         * if specified.  If no duration is passed in, then the progress bar will run indefinitely and must
-         * be manually cleared by calling {@link #reset}.  The wait method accepts a config object with
-         * the following properties:
-         * <pre>
-    Property   Type          Description
-    ---------- ------------  ----------------------------------------------------------------------
-    duration   Number        The length of time in milliseconds that the progress bar should
-                             run before resetting itself (defaults to undefined, in which case it
-                             will run indefinitely until reset is called)
-    interval   Number        The length of time in milliseconds between each progress update
-                             (defaults to 1000 ms)
-    animate    Boolean       Whether to animate the transition of the progress bar. If this value is
-                             not specified, the default for the class is used.
-    increment  Number        The number of progress update segments to display within the progress
-                             bar (defaults to 10).  If the bar reaches the end and is still
-                             updating, it will automatically wrap back to the beginning.
-    text       String        Optional text to display in the progress bar element (defaults to '').
-    fn         Function      A callback function to execute after the progress bar finishes auto-
-                             updating.  The function will be called with no arguments.  This function
-                             will be ignored if duration is not specified since in that case the
-                             progress bar can only be stopped programmatically, so any required function
-                             should be called by the same code after it resets the progress bar.
-    scope      Object        The scope that is passed to the callback function (only applies when
-                             duration and fn are both passed).
-    </pre>
-             *
-             * Example usage:
-             * <pre><code>
-    var p = new Ext.ProgressBar({
-       renderTo: 'my-el'
-    });
-
-    //Wait for 5 seconds, then update the status el (progress bar will auto-reset)
-    var p = Ext.create('Ext.ProgressBar', {
-       renderTo: Ext.getBody(),
-       width: 300
-    });
-
-    //Wait for 5 seconds, then update the status el (progress bar will auto-reset)
-    p.wait({
-       interval: 500, //bar will move fast!
-       duration: 50000,
-       increment: 15,
-       text: 'Updating...',
-       scope: this,
-       fn: function(){
-          p.updateText('Done!');
-       }
-    });
-
-    //Or update indefinitely until some async action completes, then reset manually
-    p.wait();
-    myAction.on('complete', function(){
-        p.reset();
-        p.updateText('Done!');
-    });
-    </code></pre>
-         * @param {Object} config (optional) Configuration options
-         * @return {Ext.ProgressBar} this
-         */
+     * Initiates an auto-updating progress bar. A duration can be specified, in which case the progress bar will
+     * automatically reset after a fixed amount of time and optionally call a callback function if specified. If no
+     * duration is passed in, then the progress bar will run indefinitely and must be manually cleared by calling
+     * {@link #reset}.
+     *
+     * Example usage:
+     *
+     *     var p = new Ext.ProgressBar({
+     *        renderTo: 'my-el'
+     *     });
+     *
+     *     //Wait for 5 seconds, then update the status el (progress bar will auto-reset)
+     *     var p = Ext.create('Ext.ProgressBar', {
+     *        renderTo: Ext.getBody(),
+     *        width: 300
+     *     });
+     *
+     *     //Wait for 5 seconds, then update the status el (progress bar will auto-reset)
+     *     p.wait({
+     *        interval: 500, //bar will move fast!
+     *        duration: 50000,
+     *        increment: 15,
+     *        text: 'Updating...',
+     *        scope: this,
+     *        fn: function(){
+     *           p.updateText('Done!');
+     *        }
+     *     });
+     *
+     *     //Or update indefinitely until some async action completes, then reset manually
+     *     p.wait();
+     *     myAction.on('complete', function(){
+     *         p.reset();
+     *         p.updateText('Done!');
+     *     });
+     *
+     * @param {Object} config (optional) Configuration options
+     * @param {Number} config.duration The length of time in milliseconds that the progress bar should
+     * run before resetting itself (defaults to undefined, in which case it will run indefinitely
+     * until reset is called)
+     * @param {Number} config.interval The length of time in milliseconds between each progress update
+     * (defaults to 1000 ms)
+     * @param {Boolean} config.animate Whether to animate the transition of the progress bar. If this
+     * value is not specified, the default for the class is used.
+     * @param {Number} config.increment The number of progress update segments to display within the
+     * progress bar (defaults to 10).  If the bar reaches the end and is still updating, it will
+     * automatically wrap back to the beginning.
+     * @param {String} config.text Optional text to display in the progress bar element (defaults to '').
+     * @param {Function} config.fn A callback function to execute after the progress bar finishes auto-
+     * updating.  The function will be called with no arguments.  This function will be ignored if
+     * duration is not specified since in that case the progress bar can only be stopped programmatically,
+     * so any required function should be called by the same code after it resets the progress bar.
+     * @param {Object} config.scope The scope that is passed to the callback function (only applies when
+     * duration and fn are both passed).
+     * @return {Ext.ProgressBar} this
+     */
     wait: function(o) {
-        if (!this.waitTimer) {
-            var scope = this;
+        var me = this;
+            
+        if (!me.waitTimer) {
+            scope = me;
             o = o || {};
-            this.updateText(o.text);
-            this.waitTimer = Ext.TaskManager.start({
+            me.updateText(o.text);
+            me.waitTimer = Ext.TaskManager.start({
                 run: function(i){
                     var inc = o.increment || 10;
                     i -= 1;
-                    this.updateProgress(((((i+inc)%inc)+1)*(100/inc))*0.01, null, o.animate);
+                    me.updateProgress(((((i+inc)%inc)+1)*(100/inc))*0.01, null, o.animate);
                 },
                 interval: o.interval || 1000,
                 duration: o.duration,
                 onStop: function(){
                     if (o.fn) {
-                        o.fn.apply(o.scope || this);
+                        o.fn.apply(o.scope || me);
                     }
-                    this.reset();
+                    me.reset();
                 },
                 scope: scope
             });
         }
-        return this;
+        return me;
     },
 
     /**
@@ -283,38 +303,44 @@ Ext.define('Ext.ProgressBar', {
     },
 
     /**
-     * Resets the progress bar value to 0 and text to empty string.  If hide = true, the progress
-     * bar will also be hidden (using the {@link #hideMode} property internally).
-     * @param {Boolean} hide (optional) True to hide the progress bar (defaults to false)
+     * Resets the progress bar value to 0 and text to empty string. If hide = true, the progress bar will also be hidden
+     * (using the {@link #hideMode} property internally).
+     * @param {Boolean} [hide=false] True to hide the progress bar.
      * @return {Ext.ProgressBar} this
      */
     reset: function(hide){
-        this.updateProgress(0);
-        this.clearTimer();
+        var me = this;
+        
+        me.updateProgress(0);
+        me.clearTimer();
         if (hide === true) {
-            this.hide();
+            me.hide();
         }
-        return this;
+        return me;
     },
 
     // private
     clearTimer: function(){
-        if (this.waitTimer) {
-            this.waitTimer.onStop = null; //prevent recursion
-            Ext.TaskManager.stop(this.waitTimer);
-            this.waitTimer = null;
+        var me = this;
+        
+        if (me.waitTimer) {
+            me.waitTimer.onStop = null; //prevent recursion
+            Ext.TaskManager.stop(me.waitTimer);
+            me.waitTimer = null;
         }
     },
 
     onDestroy: function(){
-        this.clearTimer();
-        if (this.rendered) {
-            if (this.textEl.isComposite) {
-                this.textEl.clear();
+        var me = this;
+        
+        me.clearTimer();
+        if (me.rendered) {
+            if (me.textEl.isComposite) {
+                me.textEl.clear();
             }
-            Ext.destroyMembers(this, 'textEl', 'progressBar', 'textTopEl');
+            Ext.destroyMembers(me, 'textEl', 'progressBar');
         }
-        this.callParent();
+        me.callParent();
     }
 });