Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / examples / ux / Spotlight.js
index f25db34..e76ed17 100644 (file)
-/*!
- * Ext JS Library 3.2.0
- * Copyright(c) 2006-2010 Ext JS, Inc.
- * licensing@extjs.com
- * http://www.extjs.com/license
+/*
+
+This file is part of Ext JS 4
+
+Copyright (c) 2011 Sencha Inc
+
+Contact:  http://www.sencha.com/contact
+
+GNU General Public License Usage
+This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file.  Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+
+If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
+
+*/
+/**
+ * @class Ext.ux.Spotlight
+ * UX used to provide a spotlight around a specified component/element.
  */
-Ext.ux.Spotlight = function(config){
-    Ext.apply(this, config);
-}
-Ext.ux.Spotlight.prototype = {
-    active : false,
-    animate : true,
-    duration: .25,
-    easing:'easeNone',
-
-    // private
-    animated : false,
-
-    createElements : function(){
-        var bd = Ext.getBody();
-
-        this.right = bd.createChild({cls:'x-spotlight'});
-        this.left = bd.createChild({cls:'x-spotlight'});
-        this.top = bd.createChild({cls:'x-spotlight'});
-        this.bottom = bd.createChild({cls:'x-spotlight'});
-
-        this.all = new Ext.CompositeElement([this.right, this.left, this.top, this.bottom]);
+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 : function(el, callback, scope){
-        if(this.animated){
-            this.show.defer(50, this, [el, callback, scope]);
-            return;
-        }
+    /**
+     * Show the spotlight
+     */
+    show: function(el, callback, scope) {
+        //get the target element
         this.el = Ext.get(el);
-        if(!this.right){
+
+        //create the elements if they don't already exist
+        if (!this.right) {
             this.createElements();
         }
-        if(!this.active){
+
+        if (!this.active) {
+            //if the spotlight is not active, show it
             this.all.setDisplayed('');
-            this.applyBounds(true, false);
             this.active = true;
             Ext.EventManager.onWindowResize(this.syncSize, this);
-            this.applyBounds(false, this.animate, false, callback, scope);
-        }else{
-            this.applyBounds(false, false, false, callback, scope); // all these booleans look hideous
+            this.applyBounds(this.animate, false);
+        } else {
+            //if the spotlight is currently active, just move it
+            this.applyBounds(false, false);
         }
     },
 
-    hide : function(callback, scope){
-        if(this.animated){
-            this.hide.defer(50, this, [callback, scope]);
-            return;
-        }
+    /**
+     * Hide the spotlight
+     */
+    hide: function(callback, scope) {
         Ext.EventManager.removeResizeListener(this.syncSize, this);
-        this.applyBounds(true, this.animate, true, callback, scope);
-    },
 
-    doHide : function(){
-        this.active = false;
-        this.all.setDisplayed(false);
+        this.applyBounds(this.animate, true);
     },
 
-    syncSize : function(){
+    /**
+     * Resizes the spotlight with the window size.
+     */
+    syncSize: function() {
         this.applyBounds(false, false);
     },
 
-    applyBounds : function(basePts, anim, doHide, callback, scope){
-
-        var rg = this.el.getRegion();
-
-        var dw = Ext.lib.Dom.getViewWidth(true);
-        var dh = Ext.lib.Dom.getViewHeight(true);
-
-        var c = 0, cb = false;
-        if(anim){
-            cb = {
-                callback: function(){
-                    c++;
-                    if(c == 4){
-                        this.animated = false;
-                        if(doHide){
-                            this.doHide();
-                        }
-                        Ext.callback(callback, scope, [this]);
-                    }
-                },
-                scope: this,
-                duration: this.duration,
-                easing: this.easing
-            };
-            this.animated = true;
-        }
-
-        this.right.setBounds(
-                rg.right,
-                basePts ? dh : rg.top,
-                dw - rg.right,
-                basePts ? 0 : (dh - rg.top),
-                cb);
-
-        this.left.setBounds(
-                0,
-                0,
-                rg.left,
-                basePts ? 0 : rg.bottom,
-                cb);
-
-        this.top.setBounds(
-                basePts ? dw : rg.left,
-                0,
-                basePts ? 0 : dw - rg.left,
-                rg.top,
-                cb);
-
-        this.bottom.setBounds(
-                0,
-                rg.bottom,
-                basePts ? 0 : rg.right,
-                dh - rg.bottom,
-                cb);
-
-        if(!anim){
-            if(doHide){
-                this.doHide();
+    /**
+     * 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.Element.getViewWidth(true);
+        var viewHeight = Ext.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'
             }
-            if(callback){
-                Ext.callback(callback, scope, [this]);
+        };
+
+        //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);
         }
     },
 
-    destroy : function(){
-        this.doHide();
-        Ext.destroy(
-            this.right,
-            this.left,
-            this.top,
-            this.bottom);
+    /**
+     * 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;
     }
-};
+});
 
-//backwards compat
-Ext.Spotlight = Ext.ux.Spotlight;
\ No newline at end of file