X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/7a654f8d43fdb43d78b63d90528bed6e86b608cc..6746dc89c47ed01b165cc1152533605f97eb8e8d:/docs/source/Manager2.html diff --git a/docs/source/Manager2.html b/docs/source/Manager2.html index 0399f383..f1139470 100644 --- a/docs/source/Manager2.html +++ b/docs/source/Manager2.html @@ -1,250 +1,325 @@ -
+ +/** - * @class Ext.direct.Manager - * <p><b><u>Overview</u></b></p> - * - * <p>Ext.Direct aims to streamline communication between the client and server - * by providing a single interface that reduces the amount of common code - * typically required to validate data and handle returned data packets - * (reading data, error conditions, etc).</p> - * - * <p>The Ext.direct namespace includes several classes for a closer integration - * with the server-side. The Ext.data namespace also includes classes for working - * with Ext.data.Stores which are backed by data from an Ext.Direct method.</p> - * - * <p><b><u>Specification</u></b></p> - * - * <p>For additional information consult the - * <a href="http://sencha.com/products/extjs/extdirect">Ext.Direct Specification</a>.</p> - * - * <p><b><u>Providers</u></b></p> - * - * <p>Ext.Direct uses a provider architecture, where one or more providers are - * used to transport data to and from the server. There are several providers - * that exist in the core at the moment:</p><div class="mdetail-params"><ul> - * - * <li>{@link Ext.direct.JsonProvider JsonProvider} for simple JSON operations</li> - * <li>{@link Ext.direct.PollingProvider PollingProvider} for repeated requests</li> - * <li>{@link Ext.direct.RemotingProvider RemotingProvider} exposes server side - * on the client.</li> - * </ul></div> - * - * <p>A provider does not need to be invoked directly, providers are added via - * {@link Ext.direct.Manager}.{@link Ext.direct.Manager#add add}.</p> - * - * <p><b><u>Router</u></b></p> - * - * <p>Ext.Direct utilizes a "router" on the server to direct requests from the client - * to the appropriate server-side method. Because the Ext.Direct API is completely - * platform-agnostic, you could completely swap out a Java based server solution - * and replace it with one that uses C# without changing the client side JavaScript - * at all.</p> - * - * <p><b><u>Server side events</u></b></p> - * - * <p>Custom events from the server may be handled by the client by adding - * listeners, for example:</p> - * <pre><code> -{"type":"event","name":"message","data":"Successfully polled at: 11:19:30 am"} - -// add a handler for a 'message' event sent by the server -Ext.direct.Manager.on('message', function(e){ - out.append(String.format('<p><i>{0}</i></p>', e.data)); - out.el.scrollTo('t', 100000, true); -}); - * </code></pre> + + + + +\ No newline at end of file +The source code + + + + + + +/** + * @class Ext.fx.Manager + * Animation Manager which keeps track of all current animations and manages them on a frame by frame basis. + * @private * @singleton */ -Ext.define('Ext.direct.Manager', { - +Ext.define('Ext.fx.Manager', { + /* Begin Definitions */ + singleton: true, - + + 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: { - observable: 'Ext.util.Observable' - }, - - requires: ['Ext.util.MixedCollection'], - - statics: { - exceptions: { - TRANSPORT: 'xhr', - PARSE: 'parse', - LOGIN: 'login', - SERVER: 'exception' - } + queue: 'Ext.fx.Queue' }, - + /* End Definitions */ - - constructor: function(){ - var me = this; - - me.addEvents( - /** - * @event event - * Fires after an event. - * @param {event} e The Ext.direct.Event type that occurred. - * @param {Ext.direct.Provider} provider The {@link Ext.direct.Provider Provider}. - */ - 'event', - /** - * @event exception - * Fires after an event exception. - * @param {event} e The Ext.direct.Event type that occurred. - */ - 'exception' - ); - me.transactions = Ext.create('Ext.util.MixedCollection'); - me.providers = Ext.create('Ext.util.MixedCollection'); - - me.mixins.observable.constructor.call(me); - }, - - /** - * Adds an Ext.Direct Provider and creates the proxy or stub methods to execute server-side methods. - * If the provider is not already connected, it will auto-connect. - * <pre><code> -var pollProv = new Ext.direct.PollingProvider({ - url: 'php/poll2.php' -}); -Ext.direct.Manager.addProvider({ - "type":"remoting", // create a {@link Ext.direct.RemotingProvider} - "url":"php\/router.php", // url to connect to the Ext.Direct server-side router. - "actions":{ // each property within the actions object represents a Class - "TestAction":[ // array of methods within each server side Class - { - "name":"doEcho", // name of method - "len":1 - },{ - "name":"multiply", - "len":1 - },{ - "name":"doForm", - "formHandler":true, // handle form on server with Ext.Direct.Transaction - "len":1 - }] + constructor: function() { + 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); + // }; + // } + // })(); }, - "namespace":"myApplication",// namespace to create the Remoting Provider in -},{ - type: 'polling', // create a {@link Ext.direct.PollingProvider} - url: 'php/poll.php' -}, pollProv); // reference to previously created instance - * </code></pre> - * @param {Object/Array} provider Accepts either an Array of Provider descriptions (an instance - * or config object for a Provider) or any number of Provider descriptions as arguments. Each - * Provider description instructs Ext.Direct how to create client-side stub methods. + + /** + * @cfg {Number} interval Default interval in miliseconds to calculate each frame. Defaults to 16ms (~60fps) + */ + interval: 16, + + /** + * @cfg {Boolean} forceJS Turn off to not use CSS3 transitions when they are available */ - addProvider : function(provider){ + forceJS: true, + + // @private Target factory + createTarget: function(target) { var me = this, - args = arguments, - i = 0, - len; - - if (args.length > 1) { - for (len = args.length; i < len; ++i) { - me.addProvider(args[i]); + useCSS3 = !me.forceJS && Ext.supports.Transitions, + targetObj; + + me.useCSS3 = useCSS3; + + // dom id + if (Ext.isString(target)) { + target = Ext.get(target); + } + // dom element + if (target && 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); } - return; + // 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; } - - // if provider has not already been instantiated - if (!provider.isProvider) { - provider = Ext.create('direct.' + provider.type + 'provider', provider); + else { + return null; } - me.providers.add(provider); - provider.on('data', me.onProviderData, me); + }, + + /** + * Add an Anim to the manager. This is done automatically when an Anim instance is created. + * @param {Ext.fx.Anim} anim + */ + 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); - if (!provider.isConnected()) { - provider.connect(); + // Start the timer if not already running + if (!task && items.length) { + task = this.task = { + run: this.runner, + interval: this.interval, + scope: this + }; + Ext.TaskManager.start(task); } - return provider; + // //Start the timer if not already running + // if (!me.task && items.length) { + // me.requestAnimFrame(cb); + // } }, - - /** - * Retrieve a {@link Ext.direct.Provider provider} by the - * <b><tt>{@link Ext.direct.Provider#id id}</tt></b> specified when the provider is - * {@link #addProvider added}. - * @param {String/Ext.data.Provider} id The id of the provider, or the provider instance. + + /** + * Remove an Anim from the manager. This is done automatically when an Anim ends. + * @param {Ext.fx.Anim} anim */ - getProvider : function(id){ - return id.isProvider ? id : this.providers.get(id); + 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 && !items.length) { + Ext.TaskManager.stop(task); + delete this.task; + } }, - - /** - * Removes the provider. - * @param {String/Ext.direct.Provider} provider The provider instance or the id of the provider. - * @return {Ext.direct.Provider} The provider, null if not found. + + /** + * @private + * Filter function to determine which animations need to be started */ - removeProvider : function(provider){ - var me = this, - providers = me.providers, - provider = provider.isProvider ? provider : providers.get(provider); - - if (provider) { - provider.un('data', me.onProviderData, me); - providers.remove(provider); - return provider; - } - return null; + startingFilter: function(o) { + return o.paused === false && o.running === false && o.iterations > 0; }, - - /** - * Add a transaction to the manager. - * @private - * @param {Ext.direct.Transaction} transaction The transaction to add - * @return {Ext.direct.Transaction} transaction + + /** + * @private + * Filter function to determine which animations are still running */ - addTransaction: function(transaction){ - this.transactions.add(transaction); - return transaction; + runningFilter: function(o) { + return o.paused === false && o.running === true && o.isAnimator !== true; }, - /** - * Remove a transaction from the manager. - * @private - * @param {String/Ext.direct.Transaction} transaction The transaction/id of transaction to remove - * @return {Ext.direct.Transaction} transaction + /** + * @private + * Runner function being called each frame */ - removeTransaction: function(transaction){ - transaction = this.getTransaction(transaction); - this.transactions.remove(transaction); - return transaction; + 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(); }, - /** - * Gets a transaction - * @private - * @param {String/Ext.direct.Transaction} transaction The transaction/id of transaction to get - * @return {Ext.direct.Transaction} + /** + * @private + * Start the individual animation (initialization) */ - getTransaction: function(transaction){ - return transaction.isTransaction ? transaction : this.transactions.get(transaction); + startAnim: function(anim) { + anim.start(this.timestamp); }, - - onProviderData : function(provider, event){ + + /** + * @private + * Run the individual animation for this frame + */ + runAnim: function(anim) { + if (!anim) { + return; + } var me = this, - i = 0, - len; - - if (Ext.isArray(event)) { - for (len = event.length; i < len; ++i) { - me.onProviderData(provider, event[i]); + targetId = anim.target.getId(), + useCSS3 = me.useCSS3 && 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(); } - return; + + // 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 >= anim.duration) { + me.applyPendingAttrs(true); + delete me.targetData[targetId]; + delete me.targetArr[targetId]; + anim.lastFrame(); + } + }, + + /** + * 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; } - if (event.name && event.name != 'event' && event.name != 'exception') { - me.fireEvent(event.name, event); - } else if (event.type == 'exception') { - me.fireEvent('exception', event); + + data = { + duration: anim.duration, + easing: (useCSS3 && anim.reverse) ? anim.easingFn.reverse().toCSS3() : anim.easing, + attrs: {} + }; + Ext.apply(data.attrs, anim.runAnim(elapsedTime)); + targetData.push(data); + }, + + /** + * @private + * Apply all pending attribute changes to their targets + */ + 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); + } } - me.fireEvent('event', event, provider); } -}, function(){ - // Backwards compatibility - Ext.Direct = Ext.direct.Manager; }); -