Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / docs / source / Manager3.html
index 24a69a7..bc878f2 100644 (file)
@@ -3,8 +3,8 @@
 <head>
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
   <title>The source code</title>
-  <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
-  <script type="text/javascript" src="../prettify/prettify.js"></script>
+  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
+  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
   <style type="text/css">
     .highlight { display: block; background-color: #ddd; }
   </style>
   </script>
 </head>
 <body onload="prettyPrint(); highlight();">
-  <pre class="prettyprint lang-js"><span id='Ext-state-Manager'>/**
-</span> * @class Ext.state.Manager
- * This is the global state manager. By default all components that are &quot;state aware&quot; check this class
- * for state information if you don't pass them a custom state provider. In order for this class
- * to be useful, it must be initialized with a provider when your application initializes. Example usage:
- &lt;pre&gt;&lt;code&gt;
-// in your initialization function
-init : function(){
-   Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
-   var win = new Window(...);
-   win.restoreState();
-}
- &lt;/code&gt;&lt;/pre&gt;
- * This class passes on calls from components to the underlying {@link Ext.state.Provider} so that
- * there is a common interface that can be used without needing to refer to a specific provider instance
- * in every component.
+  <pre class="prettyprint lang-js"><span id='Ext-fx-Manager'>/**
+</span> * @class Ext.fx.Manager
+ * Animation Manager which keeps track of all current animations and manages them on a frame by frame basis.
+ * @private
  * @singleton
- * @docauthor Evan Trimboli &lt;evan@sencha.com&gt;
  */
-Ext.define('Ext.state.Manager', {
+
+Ext.define('Ext.fx.Manager', {
+
+    /* Begin Definitions */
+
     singleton: true,
-    requires: ['Ext.state.Provider'],
+
+    requires: ['Ext.util.MixedCollection',
+               'Ext.fx.target.Element',
+               'Ext.fx.target.CompositeElement',
+               'Ext.fx.target.Sprite',
+               'Ext.fx.target.CompositeSprite',
+               'Ext.fx.target.Component'],
+
+    mixins: {
+        queue: 'Ext.fx.Queue'
+    },
+
+    /* End Definitions */
+
     constructor: function() {
-        this.provider = Ext.create('Ext.state.Provider');
+        this.items = Ext.create('Ext.util.MixedCollection');
+        this.mixins.queue.constructor.call(this);
+
+        // this.requestAnimFrame = (function() {
+        //     var raf = window.requestAnimationFrame ||
+        //               window.webkitRequestAnimationFrame ||
+        //               window.mozRequestAnimationFrame ||
+        //               window.oRequestAnimationFrame ||
+        //               window.msRequestAnimationFrame;
+        //     if (raf) {
+        //         return function(callback, element) {
+        //             raf(callback);
+        //         };
+        //     }
+        //     else {
+        //         return function(callback, element) {
+        //             window.setTimeout(callback, Ext.fx.Manager.interval);
+        //         };
+        //     }
+        // })();
     },
-    
-    
-<span id='Ext-state-Manager-method-setProvider'>    /**
-</span>     * Configures the default state provider for your application
-     * @param {Provider} stateProvider The state provider to set
+
+<span id='Ext-fx-Manager-cfg-interval'>    /**
+</span>     * @cfg {Number} interval Default interval in miliseconds to calculate each frame.  Defaults to 16ms (~60fps)
+     */
+    interval: 16,
+
+<span id='Ext-fx-Manager-cfg-forceJS'>    /**
+</span>     * @cfg {Boolean} forceJS Turn off to not use CSS3 transitions when they are available
      */
-    setProvider : function(stateProvider){
-        this.provider = stateProvider;
+    forceJS: true,
+
+    // @private Target factory
+    createTarget: function(target) {
+        var me = this,
+            useCSS3 = !me.forceJS &amp;&amp; Ext.supports.Transitions,
+            targetObj;
+
+        me.useCSS3 = useCSS3;
+
+        // dom id
+        if (Ext.isString(target)) {
+            target = Ext.get(target);
+        }
+        // dom element
+        if (target &amp;&amp; target.tagName) {
+            target = Ext.get(target);
+            targetObj = Ext.create('Ext.fx.target.' + 'Element' + (useCSS3 ? 'CSS' : ''), target);
+            me.targets.add(targetObj);
+            return targetObj;
+        }
+        if (Ext.isObject(target)) {
+            // Element
+            if (target.dom) {
+                targetObj = Ext.create('Ext.fx.target.' + 'Element' + (useCSS3 ? 'CSS' : ''), target);
+            }
+            // Element Composite
+            else if (target.isComposite) {
+                targetObj = Ext.create('Ext.fx.target.' + 'CompositeElement' + (useCSS3 ? 'CSS' : ''), target);
+            }
+            // Draw Sprite
+            else if (target.isSprite) {
+                targetObj = Ext.create('Ext.fx.target.Sprite', target);
+            }
+            // Draw Sprite Composite
+            else if (target.isCompositeSprite) {
+                targetObj = Ext.create('Ext.fx.target.CompositeSprite', target);
+            }
+            // Component
+            else if (target.isComponent) {
+                targetObj = Ext.create('Ext.fx.target.Component', target);
+            }
+            else if (target.isAnimTarget) {
+                return target;
+            }
+            else {
+                return null;
+            }
+            me.targets.add(targetObj);
+            return targetObj;
+        }
+        else {
+            return null;
+        }
     },
 
-<span id='Ext-state-Manager-method-get'>    /**
-</span>     * Returns the current value for a key
-     * @param {String} name The key name
-     * @param {Mixed} defaultValue The default value to return if the key lookup does not match
-     * @return {Mixed} The state data
+<span id='Ext-fx-Manager-method-addAnim'>    /**
+</span>     * Add an Anim to the manager. This is done automatically when an Anim instance is created.
+     * @param {Ext.fx.Anim} anim
      */
-    get : function(key, defaultValue){
-        return this.provider.get(key, defaultValue);
+    addAnim: function(anim) {
+        var items = this.items,
+            task = this.task;
+        // var me = this,
+        //     items = me.items,
+        //     cb = function() {
+        //         if (items.length) {
+        //             me.task = true;
+        //             me.runner();
+        //             me.requestAnimFrame(cb);
+        //         }
+        //         else {
+        //             me.task = false;
+        //         }
+        //     };
+
+        items.add(anim);
+
+        // Start the timer if not already running
+        if (!task &amp;&amp; items.length) {
+            task = this.task = {
+                run: this.runner,
+                interval: this.interval,
+                scope: this
+            };
+            Ext.TaskManager.start(task);
+        }
+
+        // //Start the timer if not already running
+        // if (!me.task &amp;&amp; items.length) {
+        //     me.requestAnimFrame(cb);
+        // }
     },
 
-<span id='Ext-state-Manager-method-set'>    /**
-</span>     * Sets the value for a key
-     * @param {String} name The key name
-     * @param {Mixed} value The state data
+<span id='Ext-fx-Manager-method-removeAnim'>    /**
+</span>     * Remove an Anim from the manager. This is done automatically when an Anim ends.
+     * @param {Ext.fx.Anim} anim
      */
-     set : function(key, value){
-        this.provider.set(key, value);
+    removeAnim: function(anim) {
+        // this.items.remove(anim);
+        var items = this.items,
+            task = this.task;
+        items.remove(anim);
+        // Stop the timer if there are no more managed Anims
+        if (task &amp;&amp; !items.length) {
+            Ext.TaskManager.stop(task);
+            delete this.task;
+        }
     },
 
-<span id='Ext-state-Manager-method-clear'>    /**
-</span>     * Clears a value from the state
-     * @param {String} name The key name
+<span id='Ext-fx-Manager-method-startingFilter'>    /**
+</span>     * @private
+     * Filter function to determine which animations need to be started
      */
-    clear : function(key){
-        this.provider.clear(key);
+    startingFilter: function(o) {
+        return o.paused === false &amp;&amp; o.running === false &amp;&amp; o.iterations &gt; 0;
+    },
+
+<span id='Ext-fx-Manager-method-runningFilter'>    /**
+</span>     * @private
+     * Filter function to determine which animations are still running
+     */
+    runningFilter: function(o) {
+        return o.paused === false &amp;&amp; o.running === true &amp;&amp; o.isAnimator !== true;
+    },
+
+<span id='Ext-fx-Manager-method-runner'>    /**
+</span>     * @private
+     * Runner function being called each frame
+     */
+    runner: function() {
+        var me = this,
+            items = me.items;
+
+        me.targetData = {};
+        me.targetArr = {};
+
+        // Single timestamp for all animations this interval
+        me.timestamp = new Date();
+
+        // Start any items not current running
+        items.filterBy(me.startingFilter).each(me.startAnim, me);
+
+        // Build the new attributes to be applied for all targets in this frame
+        items.filterBy(me.runningFilter).each(me.runAnim, me);
+
+        // Apply all the pending changes to their targets
+        me.applyPendingAttrs();
+    },
+
+<span id='Ext-fx-Manager-method-startAnim'>    /**
+</span>     * @private
+     * Start the individual animation (initialization)
+     */
+    startAnim: function(anim) {
+        anim.start(this.timestamp);
+    },
+
+<span id='Ext-fx-Manager-method-runAnim'>    /**
+</span>     * @private
+     * Run the individual animation for this frame
+     */
+    runAnim: function(anim) {
+        if (!anim) {
+            return;
+        }
+        var me = this,
+            targetId = anim.target.getId(),
+            useCSS3 = me.useCSS3 &amp;&amp; anim.target.type == 'element',
+            elapsedTime = me.timestamp - anim.startTime,
+            target, o;
+
+        this.collectTargetData(anim, elapsedTime, useCSS3);
+
+        // For CSS3 animation, we need to immediately set the first frame's attributes without any transition
+        // to get a good initial state, then add the transition properties and set the final attributes.
+        if (useCSS3) {
+            // Flush the collected attributes, without transition
+            anim.target.setAttr(me.targetData[targetId], true);
+
+            // Add the end frame data
+            me.targetData[targetId] = [];
+            me.collectTargetData(anim, anim.duration, useCSS3);
+
+            // Pause the animation so runAnim doesn't keep getting called
+            anim.paused = true;
+
+            target = anim.target.target;
+            // We only want to attach an event on the last element in a composite
+            if (anim.target.isComposite) {
+                target = anim.target.target.last();
+            }
+
+            // Listen for the transitionend event
+            o = {};
+            o[Ext.supports.CSS3TransitionEnd] = anim.lastFrame;
+            o.scope = anim;
+            o.single = true;
+            target.on(o);
+        }
+        // For JS animation, trigger the lastFrame handler if this is the final frame
+        else if (elapsedTime &gt;= anim.duration) {
+            me.applyPendingAttrs(true);
+            delete me.targetData[targetId];
+            delete me.targetArr[targetId];
+            anim.lastFrame();
+        }
+    },
+
+<span id='Ext-fx-Manager-method-collectTargetData'>    /**
+</span>     * Collect target attributes for the given Anim object at the given timestamp
+     * @param {Ext.fx.Anim} anim The Anim instance
+     * @param {Number} timestamp Time after the anim's start time
+     */
+    collectTargetData: function(anim, elapsedTime, useCSS3) {
+        var targetId = anim.target.getId(),
+            targetData = this.targetData[targetId],
+            data;
+        
+        if (!targetData) {
+            targetData = this.targetData[targetId] = [];
+            this.targetArr[targetId] = anim.target;
+        }
+
+        data = {
+            duration: anim.duration,
+            easing: (useCSS3 &amp;&amp; anim.reverse) ? anim.easingFn.reverse().toCSS3() : anim.easing,
+            attrs: {}
+        };
+        Ext.apply(data.attrs, anim.runAnim(elapsedTime));
+        targetData.push(data);
     },
 
-<span id='Ext-state-Manager-method-getProvider'>    /**
-</span>     * Gets the currently configured state provider
-     * @return {Provider} The state provider
+<span id='Ext-fx-Manager-method-applyPendingAttrs'>    /**
+</span>     * @private
+     * Apply all pending attribute changes to their targets
      */
-    getProvider : function(){
-        return this.provider;
+    applyPendingAttrs: function(isLastFrame) {
+        var targetData = this.targetData,
+            targetArr = this.targetArr,
+            targetId;
+        for (targetId in targetData) {
+            if (targetData.hasOwnProperty(targetId)) {
+                targetArr[targetId].setAttr(targetData[targetId], false, isLastFrame);
+            }
+        }
     }
-});</pre>
+});
+</pre>
 </body>
 </html>