Upgrade to ExtJS 4.0.0 - Released 04/26/2011
[extjs.git] / examples / ux / Spotlight.js
index ad8f28a..d822c76 100644 (file)
-/*!
- * Ext JS Library 3.1.0
- * Copyright(c) 2006-2009 Ext JS, LLC
- * licensing@extjs.com
- * http://www.extjs.com/license
+/**
+ * @class Ext.ux.Spotlight
+ * UX used to provide a spotlight around a specified component/element.
  */
-Ext.ux.Spotlight = function(config){\r
-    Ext.apply(this, config);\r
-}\r
-Ext.ux.Spotlight.prototype = {\r
-    active : false,\r
-    animate : true,\r
-    duration: .25,\r
-    easing:'easeNone',\r
-\r
-    // private\r
-    animated : false,\r
-\r
-    createElements : function(){\r
-        var bd = Ext.getBody();\r
-\r
-        this.right = bd.createChild({cls:'x-spotlight'});\r
-        this.left = bd.createChild({cls:'x-spotlight'});\r
-        this.top = bd.createChild({cls:'x-spotlight'});\r
-        this.bottom = bd.createChild({cls:'x-spotlight'});\r
-\r
-        this.all = new Ext.CompositeElement([this.right, this.left, this.top, this.bottom]);\r
-    },\r
-\r
-    show : function(el, callback, scope){\r
-        if(this.animated){\r
-            this.show.defer(50, this, [el, callback, scope]);\r
-            return;\r
-        }\r
-        this.el = Ext.get(el);\r
-        if(!this.right){\r
-            this.createElements();\r
-        }\r
-        if(!this.active){\r
-            this.all.setDisplayed('');\r
-            this.applyBounds(true, false);\r
-            this.active = true;\r
-            Ext.EventManager.onWindowResize(this.syncSize, this);\r
-            this.applyBounds(false, this.animate, false, callback, scope);\r
-        }else{\r
-            this.applyBounds(false, false, false, callback, scope); // all these booleans look hideous\r
-        }\r
-    },\r
-\r
-    hide : function(callback, scope){\r
-        if(this.animated){\r
-            this.hide.defer(50, this, [callback, scope]);\r
-            return;\r
-        }\r
-        Ext.EventManager.removeResizeListener(this.syncSize, this);\r
-        this.applyBounds(true, this.animate, true, callback, scope);\r
-    },\r
-\r
-    doHide : function(){\r
-        this.active = false;\r
-        this.all.setDisplayed(false);\r
-    },\r
-\r
-    syncSize : function(){\r
-        this.applyBounds(false, false);\r
-    },\r
-\r
-    applyBounds : function(basePts, anim, doHide, callback, scope){\r
-\r
-        var rg = this.el.getRegion();\r
-\r
-        var dw = Ext.lib.Dom.getViewWidth(true);\r
-        var dh = Ext.lib.Dom.getViewHeight(true);\r
-\r
-        var c = 0, cb = false;\r
-        if(anim){\r
-            cb = {\r
-                callback: function(){\r
-                    c++;\r
-                    if(c == 4){\r
-                        this.animated = false;\r
-                        if(doHide){\r
-                            this.doHide();\r
-                        }\r
-                        Ext.callback(callback, scope, [this]);\r
-                    }\r
-                },\r
-                scope: this,\r
-                duration: this.duration,\r
-                easing: this.easing\r
-            };\r
-            this.animated = true;\r
-        }\r
-\r
-        this.right.setBounds(\r
-                rg.right,\r
-                basePts ? dh : rg.top,\r
-                dw - rg.right,\r
-                basePts ? 0 : (dh - rg.top),\r
-                cb);\r
-\r
-        this.left.setBounds(\r
-                0,\r
-                0,\r
-                rg.left,\r
-                basePts ? 0 : rg.bottom,\r
-                cb);\r
-\r
-        this.top.setBounds(\r
-                basePts ? dw : rg.left,\r
-                0,\r
-                basePts ? 0 : dw - rg.left,\r
-                rg.top,\r
-                cb);\r
-\r
-        this.bottom.setBounds(\r
-                0,\r
-                rg.bottom,\r
-                basePts ? 0 : rg.right,\r
-                dh - rg.bottom,\r
-                cb);\r
-\r
-        if(!anim){\r
-            if(doHide){\r
-                this.doHide();\r
-            }\r
-            if(callback){\r
-                Ext.callback(callback, scope, [this]);\r
-            }\r
-        }\r
-    },\r
-\r
-    destroy : function(){\r
-        this.doHide();\r
-        Ext.destroy(\r
-            this.right,\r
-            this.left,\r
-            this.top,\r
-            this.bottom);\r
-        delete this.el;\r
-        delete this.all;\r
-    }\r
-};\r
-\r
-//backwards compat\r
-Ext.Spotlight = Ext.ux.Spotlight;
\ No newline at end of file
+Ext.define('Ext.ux.Spotlight', {
+    extend: 'Object',
+
+    /**
+     * @private
+     * The baseCls for the spotlight elements
+     */
+    baseCls: 'x-spotlight',
+
+    /**
+     * @cfg animate {Boolean} True to animate the spotlight change
+     * (defaults to true)
+     */
+    animate: true,
+
+    /**
+     * @cfg duration {Integer} The duration of the animation, in milliseconds
+     * (defaults to 250)
+     */
+    duration: 250,
+
+    /**
+     * @cfg easing {String} The type of easing for the spotlight animatation
+     * (defaults to null)
+     */
+    easing: null,
+
+    /**
+     * @private
+     * True if the spotlight is active on the element
+     */
+    active: false,
+
+    /**
+     * Create all the elements for the spotlight
+     */
+    createElements: function() {
+        var body = Ext.getBody();
+
+        this.right = body.createChild({
+            cls: this.baseCls
+        });
+        this.left = body.createChild({
+            cls: this.baseCls
+        });
+        this.top = body.createChild({
+            cls: this.baseCls
+        });
+        this.bottom = body.createChild({
+            cls: this.baseCls
+        });
+
+        this.all = Ext.create('Ext.CompositeElement', [this.right, this.left, this.top, this.bottom]);
+    },
+
+    /**
+     * Show the spotlight
+     */
+    show: function(el, callback, scope) {
+        //get the target element
+        this.el = Ext.get(el);
+
+        //create the elements if they don't already exist
+        if (!this.right) {
+            this.createElements();
+        }
+
+        if (!this.active) {
+            //if the spotlight is not active, show it
+            this.all.setDisplayed('');
+            this.active = true;
+            Ext.EventManager.onWindowResize(this.syncSize, this);
+            this.applyBounds(this.animate, false);
+        } else {
+            //if the spotlight is currently active, just move it
+            this.applyBounds(false, false);
+        }
+    },
+
+    /**
+     * Hide the spotlight
+     */
+    hide: function(callback, scope) {
+        Ext.EventManager.removeResizeListener(this.syncSize, this);
+
+        this.applyBounds(this.animate, true);
+    },
+
+    /**
+     * Resizes the spotlight with the window size.
+     */
+    syncSize: function() {
+        this.applyBounds(false, false);
+    },
+
+    /**
+     * Resizes the spotlight depending on the arguments
+     * @param {Boolean} animate True to animate the changing of the bounds
+     * @param {Boolean} animate True to reverse the animation
+     */
+    applyBounds: function(animate, reverse) {
+        var me = this,
+            box = me.el.getBox();
+
+        //get the current view width and height
+        var viewWidth = Ext.core.Element.getViewWidth(true);
+        var viewHeight = Ext.core.Element.getViewHeight(true);
+
+        var i = 0,
+            config = false,
+            from, to;
+
+        //where the element should start (if animation)
+        from = {
+            right: {
+                x: box.right,
+                y: viewHeight,
+                width: (viewWidth - box.right),
+                height: 0
+            },
+            left: {
+                x: 0,
+                y: 0,
+                width: box.x,
+                height: 0
+            },
+            top: {
+                x: viewWidth,
+                y: 0,
+                width: 0,
+                height: box.y
+            },
+            bottom: {
+                x: 0,
+                y: (box.y + box.height),
+                width: 0,
+                height: (viewHeight - (box.y + box.height)) + 'px'
+            }
+        };
+
+        //where the element needs to finish
+        to = {
+            right: {
+                x: box.right,
+                y: box.y,
+                width: (viewWidth - box.right) + 'px',
+                height: (viewHeight - box.y) + 'px'
+            },
+            left: {
+                x: 0,
+                y: 0,
+                width: box.x + 'px',
+                height: (box.y + box.height) + 'px'
+            },
+            top: {
+                x: box.x,
+                y: 0,
+                width: (viewWidth - box.x) + 'px',
+                height: box.y + 'px'
+            },
+            bottom: {
+                x: 0,
+                y: (box.y + box.height),
+                width: (box.x + box.width) + 'px',
+                height: (viewHeight - (box.y + box.height)) + 'px'
+            }
+        };
+
+        //reverse the objects
+        if (reverse) {
+            var clone = Ext.clone(from);
+            from = to;
+            to = clone;
+
+            delete clone;
+        }
+
+        if (animate) {
+            Ext.each(['right', 'left', 'top', 'bottom'], function(side) {
+                me[side].setBox(from[side]);
+                me[side].animate({
+                    duration: me.duration,
+                    easing: me.easing,
+                    to: to[side]
+                });
+            },
+            this);
+        } else {
+            Ext.each(['right', 'left', 'top', 'bottom'], function(side) {
+                me[side].setBox(Ext.apply(from[side], to[side]));
+            },
+            this);
+        }
+    },
+
+    /**
+     * Removes all the elements for the spotlight
+     */
+    destroy: function() {
+        Ext.destroy(this.right, this.left, this.top, this.bottom);
+        delete this.el;
+        delete this.all;
+    }
+});