Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / examples / ux / Spotlight.js
1 /*
2
3 This file is part of Ext JS 4
4
5 Copyright (c) 2011 Sencha Inc
6
7 Contact:  http://www.sencha.com/contact
8
9 GNU General Public License Usage
10 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.
11
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
13
14 */
15 /**
16  * @class Ext.ux.Spotlight
17  * UX used to provide a spotlight around a specified component/element.
18  */
19 Ext.define('Ext.ux.Spotlight', {
20     extend: 'Object',
21
22     /**
23      * @private
24      * The baseCls for the spotlight elements
25      */
26     baseCls: 'x-spotlight',
27
28     /**
29      * @cfg animate {Boolean} True to animate the spotlight change
30      * (defaults to true)
31      */
32     animate: true,
33
34     /**
35      * @cfg duration {Integer} The duration of the animation, in milliseconds
36      * (defaults to 250)
37      */
38     duration: 250,
39
40     /**
41      * @cfg easing {String} The type of easing for the spotlight animatation
42      * (defaults to null)
43      */
44     easing: null,
45
46     /**
47      * @private
48      * True if the spotlight is active on the element
49      */
50     active: false,
51
52     /**
53      * Create all the elements for the spotlight
54      */
55     createElements: function() {
56         var body = Ext.getBody();
57
58         this.right = body.createChild({
59             cls: this.baseCls
60         });
61         this.left = body.createChild({
62             cls: this.baseCls
63         });
64         this.top = body.createChild({
65             cls: this.baseCls
66         });
67         this.bottom = body.createChild({
68             cls: this.baseCls
69         });
70
71         this.all = Ext.create('Ext.CompositeElement', [this.right, this.left, this.top, this.bottom]);
72     },
73
74     /**
75      * Show the spotlight
76      */
77     show: function(el, callback, scope) {
78         //get the target element
79         this.el = Ext.get(el);
80
81         //create the elements if they don't already exist
82         if (!this.right) {
83             this.createElements();
84         }
85
86         if (!this.active) {
87             //if the spotlight is not active, show it
88             this.all.setDisplayed('');
89             this.active = true;
90             Ext.EventManager.onWindowResize(this.syncSize, this);
91             this.applyBounds(this.animate, false);
92         } else {
93             //if the spotlight is currently active, just move it
94             this.applyBounds(false, false);
95         }
96     },
97
98     /**
99      * Hide the spotlight
100      */
101     hide: function(callback, scope) {
102         Ext.EventManager.removeResizeListener(this.syncSize, this);
103
104         this.applyBounds(this.animate, true);
105     },
106
107     /**
108      * Resizes the spotlight with the window size.
109      */
110     syncSize: function() {
111         this.applyBounds(false, false);
112     },
113
114     /**
115      * Resizes the spotlight depending on the arguments
116      * @param {Boolean} animate True to animate the changing of the bounds
117      * @param {Boolean} animate True to reverse the animation
118      */
119     applyBounds: function(animate, reverse) {
120         var me = this,
121             box = me.el.getBox();
122
123         //get the current view width and height
124         var viewWidth = Ext.Element.getViewWidth(true);
125         var viewHeight = Ext.Element.getViewHeight(true);
126
127         var i = 0,
128             config = false,
129             from, to;
130
131         //where the element should start (if animation)
132         from = {
133             right: {
134                 x: box.right,
135                 y: viewHeight,
136                 width: (viewWidth - box.right),
137                 height: 0
138             },
139             left: {
140                 x: 0,
141                 y: 0,
142                 width: box.x,
143                 height: 0
144             },
145             top: {
146                 x: viewWidth,
147                 y: 0,
148                 width: 0,
149                 height: box.y
150             },
151             bottom: {
152                 x: 0,
153                 y: (box.y + box.height),
154                 width: 0,
155                 height: (viewHeight - (box.y + box.height)) + 'px'
156             }
157         };
158
159         //where the element needs to finish
160         to = {
161             right: {
162                 x: box.right,
163                 y: box.y,
164                 width: (viewWidth - box.right) + 'px',
165                 height: (viewHeight - box.y) + 'px'
166             },
167             left: {
168                 x: 0,
169                 y: 0,
170                 width: box.x + 'px',
171                 height: (box.y + box.height) + 'px'
172             },
173             top: {
174                 x: box.x,
175                 y: 0,
176                 width: (viewWidth - box.x) + 'px',
177                 height: box.y + 'px'
178             },
179             bottom: {
180                 x: 0,
181                 y: (box.y + box.height),
182                 width: (box.x + box.width) + 'px',
183                 height: (viewHeight - (box.y + box.height)) + 'px'
184             }
185         };
186
187         //reverse the objects
188         if (reverse) {
189             var clone = Ext.clone(from);
190             from = to;
191             to = clone;
192
193             delete clone;
194         }
195
196         if (animate) {
197             Ext.each(['right', 'left', 'top', 'bottom'], function(side) {
198                 me[side].setBox(from[side]);
199                 me[side].animate({
200                     duration: me.duration,
201                     easing: me.easing,
202                     to: to[side]
203                 });
204             },
205             this);
206         } else {
207             Ext.each(['right', 'left', 'top', 'bottom'], function(side) {
208                 me[side].setBox(Ext.apply(from[side], to[side]));
209             },
210             this);
211         }
212     },
213
214     /**
215      * Removes all the elements for the spotlight
216      */
217     destroy: function() {
218         Ext.destroy(this.right, this.left, this.top, this.bottom);
219         delete this.el;
220         delete this.all;
221     }
222 });
223