~mortenoh/+junk/dhis2-detailed-import-export

« back to all changes in this revision

Viewing changes to gis/dhis-gis-geostat/mfbase/ext/source/core/Fx.js

  • Committer: larshelge at gmail
  • Date: 2009-03-03 16:46:36 UTC
  • Revision ID: larshelge@gmail.com-20090303164636-2sjlrquo7ib1gf7r
Initial check-in

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Ext JS Library 2.2
 
3
 * Copyright(c) 2006-2008, Ext JS, LLC.
 
4
 * licensing@extjs.com
 
5
 * 
 
6
 * http://extjs.com/license
 
7
 */
 
8
 
 
9
 
 
10
//Notifies Element that fx methods are available
 
11
Ext.enableFx = true;
 
12
 
 
13
/**
 
14
 * @class Ext.Fx
 
15
 * <p>A class to provide basic animation and visual effects support.  <b>Note:</b> This class is automatically applied
 
16
 * to the {@link Ext.Element} interface when included, so all effects calls should be performed via Element.
 
17
 * Conversely, since the effects are not actually defined in Element, Ext.Fx <b>must</b> be included in order for the 
 
18
 * Element effects to work.</p><br/>
 
19
 *
 
20
 * <p>It is important to note that although the Fx methods and many non-Fx Element methods support "method chaining" in that
 
21
 * they return the Element object itself as the method return value, it is not always possible to mix the two in a single
 
22
 * method chain.  The Fx methods use an internal effects queue so that each effect can be properly timed and sequenced.
 
23
 * Non-Fx methods, on the other hand, have no such internal queueing and will always execute immediately.  For this reason,
 
24
 * while it may be possible to mix certain Fx and non-Fx method calls in a single chain, it may not always provide the
 
25
 * expected results and should be done with care.</p><br/>
 
26
 *
 
27
 * <p>Motion effects support 8-way anchoring, meaning that you can choose one of 8 different anchor points on the Element
 
28
 * that will serve as either the start or end point of the animation.  Following are all of the supported anchor positions:</p>
 
29
<pre>
 
30
Value  Description
 
31
-----  -----------------------------
 
32
tl     The top left corner
 
33
t      The center of the top edge
 
34
tr     The top right corner
 
35
l      The center of the left edge
 
36
r      The center of the right edge
 
37
bl     The bottom left corner
 
38
b      The center of the bottom edge
 
39
br     The bottom right corner
 
40
</pre>
 
41
 * <b>Although some Fx methods accept specific custom config parameters, the ones shown in the Config Options section
 
42
 * below are common options that can be passed to any Fx method.</b>
 
43
 * 
 
44
 * @cfg {Function} callback A function called when the effect is finished.  Note that effects are queued internally by the
 
45
 * Fx class, so do not need to use the callback parameter to specify another effect -- effects can simply be chained together
 
46
 * and called in sequence (e.g., el.slideIn().highlight();).  The callback is intended for any additional code that should
 
47
 * run once a particular effect has completed. The Element being operated upon is passed as the first parameter.
 
48
 * @cfg {Object} scope The scope of the effect function
 
49
 * @cfg {String} easing A valid Easing value for the effect
 
50
 * @cfg {String} afterCls A css class to apply after the effect
 
51
 * @cfg {Number} duration The length of time (in seconds) that the effect should last
 
52
 * @cfg {Boolean} remove Whether the Element should be removed from the DOM and destroyed after the effect finishes
 
53
 * @cfg {Boolean} useDisplay Whether to use the <i>display</i> CSS property instead of <i>visibility</i> when hiding Elements (only applies to 
 
54
 * effects that end with the element being visually hidden, ignored otherwise)
 
55
 * @cfg {String/Object/Function} afterStyle A style specification string, e.g. "width:100px", or an object in the form {width:"100px"}, or
 
56
 * a function which returns such a specification that will be applied to the Element after the effect finishes
 
57
 * @cfg {Boolean} block Whether the effect should block other effects from queueing while it runs
 
58
 * @cfg {Boolean} concurrent Whether to allow subsequently-queued effects to run at the same time as the current effect, or to ensure that they run in sequence
 
59
 * @cfg {Boolean} stopFx Whether subsequent effects should be stopped and removed after the current effect finishes
 
60
 */
 
61
Ext.Fx = {
 
62
        /**
 
63
         * Slides the element into view.  An anchor point can be optionally passed to set the point of
 
64
         * origin for the slide effect.  This function automatically handles wrapping the element with
 
65
         * a fixed-size container if needed.  See the Fx class overview for valid anchor point options.
 
66
         * Usage:
 
67
         *<pre><code>
 
68
// default: slide the element in from the top
 
69
el.slideIn();
 
70
 
 
71
// custom: slide the element in from the right with a 2-second duration
 
72
el.slideIn('r', { duration: 2 });
 
73
 
 
74
// common config options shown with default values
 
75
el.slideIn('t', {
 
76
    easing: 'easeOut',
 
77
    duration: .5
 
78
});
 
79
</code></pre>
 
80
         * @param {String} anchor (optional) One of the valid Fx anchor positions (defaults to top: 't')
 
81
         * @param {Object} options (optional) Object literal with any of the Fx config options
 
82
         * @return {Ext.Element} The Element
 
83
         */
 
84
    slideIn : function(anchor, o){
 
85
        var el = this.getFxEl();
 
86
        o = o || {};
 
87
 
 
88
        el.queueFx(o, function(){
 
89
 
 
90
            anchor = anchor || "t";
 
91
 
 
92
            // fix display to visibility
 
93
            this.fixDisplay();
 
94
 
 
95
            // restore values after effect
 
96
            var r = this.getFxRestore();
 
97
            var b = this.getBox();
 
98
            // fixed size for slide
 
99
            this.setSize(b);
 
100
 
 
101
            // wrap if needed
 
102
            var wrap = this.fxWrap(r.pos, o, "hidden");
 
103
 
 
104
            var st = this.dom.style;
 
105
            st.visibility = "visible";
 
106
            st.position = "absolute";
 
107
 
 
108
            // clear out temp styles after slide and unwrap
 
109
            var after = function(){
 
110
                el.fxUnwrap(wrap, r.pos, o);
 
111
                st.width = r.width;
 
112
                st.height = r.height;
 
113
                el.afterFx(o);
 
114
            };
 
115
            // time to calc the positions
 
116
            var a, pt = {to: [b.x, b.y]}, bw = {to: b.width}, bh = {to: b.height};
 
117
 
 
118
            switch(anchor.toLowerCase()){
 
119
                case "t":
 
120
                    wrap.setSize(b.width, 0);
 
121
                    st.left = st.bottom = "0";
 
122
                    a = {height: bh};
 
123
                break;
 
124
                case "l":
 
125
                    wrap.setSize(0, b.height);
 
126
                    st.right = st.top = "0";
 
127
                    a = {width: bw};
 
128
                break;
 
129
                case "r":
 
130
                    wrap.setSize(0, b.height);
 
131
                    wrap.setX(b.right);
 
132
                    st.left = st.top = "0";
 
133
                    a = {width: bw, points: pt};
 
134
                break;
 
135
                case "b":
 
136
                    wrap.setSize(b.width, 0);
 
137
                    wrap.setY(b.bottom);
 
138
                    st.left = st.top = "0";
 
139
                    a = {height: bh, points: pt};
 
140
                break;
 
141
                case "tl":
 
142
                    wrap.setSize(0, 0);
 
143
                    st.right = st.bottom = "0";
 
144
                    a = {width: bw, height: bh};
 
145
                break;
 
146
                case "bl":
 
147
                    wrap.setSize(0, 0);
 
148
                    wrap.setY(b.y+b.height);
 
149
                    st.right = st.top = "0";
 
150
                    a = {width: bw, height: bh, points: pt};
 
151
                break;
 
152
                case "br":
 
153
                    wrap.setSize(0, 0);
 
154
                    wrap.setXY([b.right, b.bottom]);
 
155
                    st.left = st.top = "0";
 
156
                    a = {width: bw, height: bh, points: pt};
 
157
                break;
 
158
                case "tr":
 
159
                    wrap.setSize(0, 0);
 
160
                    wrap.setX(b.x+b.width);
 
161
                    st.left = st.bottom = "0";
 
162
                    a = {width: bw, height: bh, points: pt};
 
163
                break;
 
164
            }
 
165
            this.dom.style.visibility = "visible";
 
166
            wrap.show();
 
167
 
 
168
            arguments.callee.anim = wrap.fxanim(a,
 
169
                o,
 
170
                'motion',
 
171
                .5,
 
172
                'easeOut', after);
 
173
        });
 
174
        return this;
 
175
    },
 
176
    
 
177
        /**
 
178
         * Slides the element out of view.  An anchor point can be optionally passed to set the end point
 
179
         * for the slide effect.  When the effect is completed, the element will be hidden (visibility = 
 
180
         * 'hidden') but block elements will still take up space in the document.  The element must be removed
 
181
         * from the DOM using the 'remove' config option if desired.  This function automatically handles 
 
182
         * wrapping the element with a fixed-size container if needed.  See the Fx class overview for valid anchor point options.
 
183
         * Usage:
 
184
         *<pre><code>
 
185
// default: slide the element out to the top
 
186
el.slideOut();
 
187
 
 
188
// custom: slide the element out to the right with a 2-second duration
 
189
el.slideOut('r', { duration: 2 });
 
190
 
 
191
// common config options shown with default values
 
192
el.slideOut('t', {
 
193
    easing: 'easeOut',
 
194
    duration: .5,
 
195
    remove: false,
 
196
    useDisplay: false
 
197
});
 
198
</code></pre>
 
199
         * @param {String} anchor (optional) One of the valid Fx anchor positions (defaults to top: 't')
 
200
         * @param {Object} options (optional) Object literal with any of the Fx config options
 
201
         * @return {Ext.Element} The Element
 
202
         */
 
203
    slideOut : function(anchor, o){
 
204
        var el = this.getFxEl();
 
205
        o = o || {};
 
206
 
 
207
        el.queueFx(o, function(){
 
208
 
 
209
            anchor = anchor || "t";
 
210
 
 
211
            // restore values after effect
 
212
            var r = this.getFxRestore();
 
213
            
 
214
            var b = this.getBox();
 
215
            // fixed size for slide
 
216
            this.setSize(b);
 
217
 
 
218
            // wrap if needed
 
219
            var wrap = this.fxWrap(r.pos, o, "visible");
 
220
 
 
221
            var st = this.dom.style;
 
222
            st.visibility = "visible";
 
223
            st.position = "absolute";
 
224
 
 
225
            wrap.setSize(b);
 
226
 
 
227
            var after = function(){
 
228
                if(o.useDisplay){
 
229
                    el.setDisplayed(false);
 
230
                }else{
 
231
                    el.hide();
 
232
                }
 
233
 
 
234
                el.fxUnwrap(wrap, r.pos, o);
 
235
 
 
236
                st.width = r.width;
 
237
                st.height = r.height;
 
238
 
 
239
                el.afterFx(o);
 
240
            };
 
241
 
 
242
            var a, zero = {to: 0};
 
243
            switch(anchor.toLowerCase()){
 
244
                case "t":
 
245
                    st.left = st.bottom = "0";
 
246
                    a = {height: zero};
 
247
                break;
 
248
                case "l":
 
249
                    st.right = st.top = "0";
 
250
                    a = {width: zero};
 
251
                break;
 
252
                case "r":
 
253
                    st.left = st.top = "0";
 
254
                    a = {width: zero, points: {to:[b.right, b.y]}};
 
255
                break;
 
256
                case "b":
 
257
                    st.left = st.top = "0";
 
258
                    a = {height: zero, points: {to:[b.x, b.bottom]}};
 
259
                break;
 
260
                case "tl":
 
261
                    st.right = st.bottom = "0";
 
262
                    a = {width: zero, height: zero};
 
263
                break;
 
264
                case "bl":
 
265
                    st.right = st.top = "0";
 
266
                    a = {width: zero, height: zero, points: {to:[b.x, b.bottom]}};
 
267
                break;
 
268
                case "br":
 
269
                    st.left = st.top = "0";
 
270
                    a = {width: zero, height: zero, points: {to:[b.x+b.width, b.bottom]}};
 
271
                break;
 
272
                case "tr":
 
273
                    st.left = st.bottom = "0";
 
274
                    a = {width: zero, height: zero, points: {to:[b.right, b.y]}};
 
275
                break;
 
276
            }
 
277
 
 
278
            arguments.callee.anim = wrap.fxanim(a,
 
279
                o,
 
280
                'motion',
 
281
                .5,
 
282
                "easeOut", after);
 
283
        });
 
284
        return this;
 
285
    },
 
286
 
 
287
        /**
 
288
         * Fades the element out while slowly expanding it in all directions.  When the effect is completed, the 
 
289
         * element will be hidden (visibility = 'hidden') but block elements will still take up space in the document. 
 
290
         * The element must be removed from the DOM using the 'remove' config option if desired.
 
291
         * Usage:
 
292
         *<pre><code>
 
293
// default
 
294
el.puff();
 
295
 
 
296
// common config options shown with default values
 
297
el.puff({
 
298
    easing: 'easeOut',
 
299
    duration: .5,
 
300
    remove: false,
 
301
    useDisplay: false
 
302
});
 
303
</code></pre>
 
304
         * @param {Object} options (optional) Object literal with any of the Fx config options
 
305
         * @return {Ext.Element} The Element
 
306
         */
 
307
    puff : function(o){
 
308
        var el = this.getFxEl();
 
309
        o = o || {};
 
310
 
 
311
        el.queueFx(o, function(){
 
312
            this.clearOpacity();
 
313
            this.show();
 
314
 
 
315
            // restore values after effect
 
316
            var r = this.getFxRestore();
 
317
            var st = this.dom.style;
 
318
 
 
319
            var after = function(){
 
320
                if(o.useDisplay){
 
321
                    el.setDisplayed(false);
 
322
                }else{
 
323
                    el.hide();
 
324
                }
 
325
 
 
326
                el.clearOpacity();
 
327
 
 
328
                el.setPositioning(r.pos);
 
329
                st.width = r.width;
 
330
                st.height = r.height;
 
331
                st.fontSize = '';
 
332
                el.afterFx(o);
 
333
            };
 
334
 
 
335
            var width = this.getWidth();
 
336
            var height = this.getHeight();
 
337
 
 
338
            arguments.callee.anim = this.fxanim({
 
339
                    width : {to: this.adjustWidth(width * 2)},
 
340
                    height : {to: this.adjustHeight(height * 2)},
 
341
                    points : {by: [-(width * .5), -(height * .5)]},
 
342
                    opacity : {to: 0},
 
343
                    fontSize: {to:200, unit: "%"}
 
344
                },
 
345
                o,
 
346
                'motion',
 
347
                .5,
 
348
                "easeOut", after);
 
349
        });
 
350
        return this;
 
351
    },
 
352
 
 
353
        /**
 
354
         * Blinks the element as if it was clicked and then collapses on its center (similar to switching off a television).
 
355
         * When the effect is completed, the element will be hidden (visibility = 'hidden') but block elements will still 
 
356
         * take up space in the document. The element must be removed from the DOM using the 'remove' config option if desired.
 
357
         * Usage:
 
358
         *<pre><code>
 
359
// default
 
360
el.switchOff();
 
361
 
 
362
// all config options shown with default values
 
363
el.switchOff({
 
364
    easing: 'easeIn',
 
365
    duration: .3,
 
366
    remove: false,
 
367
    useDisplay: false
 
368
});
 
369
</code></pre>
 
370
         * @param {Object} options (optional) Object literal with any of the Fx config options
 
371
         * @return {Ext.Element} The Element
 
372
         */
 
373
    switchOff : function(o){
 
374
        var el = this.getFxEl();
 
375
        o = o || {};
 
376
 
 
377
        el.queueFx(o, function(){
 
378
            this.clearOpacity();
 
379
            this.clip();
 
380
 
 
381
            // restore values after effect
 
382
            var r = this.getFxRestore();
 
383
            var st = this.dom.style;
 
384
 
 
385
            var after = function(){
 
386
                if(o.useDisplay){
 
387
                    el.setDisplayed(false);
 
388
                }else{
 
389
                    el.hide();
 
390
                }
 
391
 
 
392
                el.clearOpacity();
 
393
                el.setPositioning(r.pos);
 
394
                st.width = r.width;
 
395
                st.height = r.height;
 
396
 
 
397
                el.afterFx(o);
 
398
            };
 
399
 
 
400
            this.fxanim({opacity:{to:0.3}}, null, null, .1, null, function(){
 
401
                this.clearOpacity();
 
402
                (function(){
 
403
                    this.fxanim({
 
404
                        height:{to:1},
 
405
                        points:{by:[0, this.getHeight() * .5]}
 
406
                    }, o, 'motion', 0.3, 'easeIn', after);
 
407
                }).defer(100, this);
 
408
            });
 
409
        });
 
410
        return this;
 
411
    },
 
412
 
 
413
    /**
 
414
     * Highlights the Element by setting a color (applies to the background-color by default, but can be
 
415
     * changed using the "attr" config option) and then fading back to the original color. If no original
 
416
     * color is available, you should provide the "endColor" config option which will be cleared after the animation.
 
417
     * Usage:
 
418
<pre><code>
 
419
// default: highlight background to yellow
 
420
el.highlight();
 
421
 
 
422
// custom: highlight foreground text to blue for 2 seconds
 
423
el.highlight("0000ff", { attr: 'color', duration: 2 });
 
424
 
 
425
// common config options shown with default values
 
426
el.highlight("ffff9c", {
 
427
    attr: "background-color", //can be any valid CSS property (attribute) that supports a color value
 
428
    endColor: (current color) or "ffffff",
 
429
    easing: 'easeIn',
 
430
    duration: 1
 
431
});
 
432
</code></pre>
 
433
     * @param {String} color (optional) The highlight color. Should be a 6 char hex color without the leading # (defaults to yellow: 'ffff9c')
 
434
     * @param {Object} options (optional) Object literal with any of the Fx config options
 
435
     * @return {Ext.Element} The Element
 
436
     */ 
 
437
    highlight : function(color, o){
 
438
        var el = this.getFxEl();
 
439
        o = o || {};
 
440
 
 
441
        el.queueFx(o, function(){
 
442
            color = color || "ffff9c";
 
443
            var attr = o.attr || "backgroundColor";
 
444
 
 
445
            this.clearOpacity();
 
446
            this.show();
 
447
 
 
448
            var origColor = this.getColor(attr);
 
449
            var restoreColor = this.dom.style[attr];
 
450
            var endColor = (o.endColor || origColor) || "ffffff";
 
451
 
 
452
            var after = function(){
 
453
                el.dom.style[attr] = restoreColor;
 
454
                el.afterFx(o);
 
455
            };
 
456
 
 
457
            var a = {};
 
458
            a[attr] = {from: color, to: endColor};
 
459
            arguments.callee.anim = this.fxanim(a,
 
460
                o,
 
461
                'color',
 
462
                1,
 
463
                'easeIn', after);
 
464
        });
 
465
        return this;
 
466
    },
 
467
 
 
468
   /**
 
469
    * Shows a ripple of exploding, attenuating borders to draw attention to an Element.
 
470
    * Usage:
 
471
<pre><code>
 
472
// default: a single light blue ripple
 
473
el.frame();
 
474
 
 
475
// custom: 3 red ripples lasting 3 seconds total
 
476
el.frame("ff0000", 3, { duration: 3 });
 
477
 
 
478
// common config options shown with default values
 
479
el.frame("C3DAF9", 1, {
 
480
    duration: 1 //duration of entire animation (not each individual ripple)
 
481
    // Note: Easing is not configurable and will be ignored if included
 
482
});
 
483
</code></pre>
 
484
    * @param {String} color (optional) The color of the border.  Should be a 6 char hex color without the leading # (defaults to light blue: 'C3DAF9').
 
485
    * @param {Number} count (optional) The number of ripples to display (defaults to 1)
 
486
    * @param {Object} options (optional) Object literal with any of the Fx config options
 
487
    * @return {Ext.Element} The Element
 
488
    */
 
489
    frame : function(color, count, o){
 
490
        var el = this.getFxEl();
 
491
        o = o || {};
 
492
 
 
493
        el.queueFx(o, function(){
 
494
            color = color || "#C3DAF9";
 
495
            if(color.length == 6){
 
496
                color = "#" + color;
 
497
            }
 
498
            count = count || 1;
 
499
            var duration = o.duration || 1;
 
500
            this.show();
 
501
 
 
502
            var b = this.getBox();
 
503
            var animFn = function(){
 
504
                var proxy = Ext.getBody().createChild({
 
505
                     style:{
 
506
                        visbility:"hidden",
 
507
                        position:"absolute",
 
508
                        "z-index":"35000", // yee haw
 
509
                        border:"0px solid " + color
 
510
                     }
 
511
                  });
 
512
                var scale = Ext.isBorderBox ? 2 : 1;
 
513
                proxy.animate({
 
514
                    top:{from:b.y, to:b.y - 20},
 
515
                    left:{from:b.x, to:b.x - 20},
 
516
                    borderWidth:{from:0, to:10},
 
517
                    opacity:{from:1, to:0},
 
518
                    height:{from:b.height, to:(b.height + (20*scale))},
 
519
                    width:{from:b.width, to:(b.width + (20*scale))}
 
520
                }, duration, function(){
 
521
                    proxy.remove();
 
522
                    if(--count > 0){
 
523
                         animFn();
 
524
                    }else{
 
525
                        el.afterFx(o);
 
526
                    }
 
527
                });
 
528
            };
 
529
            animFn.call(this);
 
530
        });
 
531
        return this;
 
532
    },
 
533
 
 
534
   /**
 
535
    * Creates a pause before any subsequent queued effects begin.  If there are
 
536
    * no effects queued after the pause it will have no effect.
 
537
    * Usage:
 
538
<pre><code>
 
539
el.pause(1);
 
540
</code></pre>
 
541
    * @param {Number} seconds The length of time to pause (in seconds)
 
542
    * @return {Ext.Element} The Element
 
543
    */
 
544
    pause : function(seconds){
 
545
        var el = this.getFxEl();
 
546
        var o = {};
 
547
 
 
548
        el.queueFx(o, function(){
 
549
            setTimeout(function(){
 
550
                el.afterFx(o);
 
551
            }, seconds * 1000);
 
552
        });
 
553
        return this;
 
554
    },
 
555
 
 
556
   /**
 
557
    * Fade an element in (from transparent to opaque).  The ending opacity can be specified
 
558
    * using the "endOpacity" config option.
 
559
    * Usage:
 
560
<pre><code>
 
561
// default: fade in from opacity 0 to 100%
 
562
el.fadeIn();
 
563
 
 
564
// custom: fade in from opacity 0 to 75% over 2 seconds
 
565
el.fadeIn({ endOpacity: .75, duration: 2});
 
566
 
 
567
// common config options shown with default values
 
568
el.fadeIn({
 
569
    endOpacity: 1, //can be any value between 0 and 1 (e.g. .5)
 
570
    easing: 'easeOut',
 
571
    duration: .5
 
572
});
 
573
</code></pre>
 
574
    * @param {Object} options (optional) Object literal with any of the Fx config options
 
575
    * @return {Ext.Element} The Element
 
576
    */
 
577
    fadeIn : function(o){
 
578
        var el = this.getFxEl();
 
579
        o = o || {};
 
580
        el.queueFx(o, function(){
 
581
            this.setOpacity(0);
 
582
            this.fixDisplay();
 
583
            this.dom.style.visibility = 'visible';
 
584
            var to = o.endOpacity || 1;
 
585
            arguments.callee.anim = this.fxanim({opacity:{to:to}},
 
586
                o, null, .5, "easeOut", function(){
 
587
                if(to == 1){
 
588
                    this.clearOpacity();
 
589
                }
 
590
                el.afterFx(o);
 
591
            });
 
592
        });
 
593
        return this;
 
594
    },
 
595
 
 
596
   /**
 
597
    * Fade an element out (from opaque to transparent).  The ending opacity can be specified
 
598
    * using the "endOpacity" config option.  Note that IE may require useDisplay:true in order
 
599
    * to redisplay correctly.
 
600
    * Usage:
 
601
<pre><code>
 
602
// default: fade out from the element's current opacity to 0
 
603
el.fadeOut();
 
604
 
 
605
// custom: fade out from the element's current opacity to 25% over 2 seconds
 
606
el.fadeOut({ endOpacity: .25, duration: 2});
 
607
 
 
608
// common config options shown with default values
 
609
el.fadeOut({
 
610
    endOpacity: 0, //can be any value between 0 and 1 (e.g. .5)
 
611
    easing: 'easeOut',
 
612
    duration: .5,
 
613
    remove: false,
 
614
    useDisplay: false
 
615
});
 
616
</code></pre>
 
617
    * @param {Object} options (optional) Object literal with any of the Fx config options
 
618
    * @return {Ext.Element} The Element
 
619
    */
 
620
    fadeOut : function(o){
 
621
        var el = this.getFxEl();
 
622
        o = o || {};
 
623
        el.queueFx(o, function(){
 
624
            arguments.callee.anim = this.fxanim({opacity:{to:o.endOpacity || 0}},
 
625
                o, null, .5, "easeOut", function(){
 
626
                if(this.visibilityMode == Ext.Element.DISPLAY || o.useDisplay){
 
627
                     this.dom.style.display = "none";
 
628
                }else{
 
629
                     this.dom.style.visibility = "hidden";
 
630
                }
 
631
                this.clearOpacity();
 
632
                el.afterFx(o);
 
633
            });
 
634
        });
 
635
        return this;
 
636
    },
 
637
 
 
638
   /**
 
639
    * Animates the transition of an element's dimensions from a starting height/width
 
640
    * to an ending height/width.
 
641
    * Usage:
 
642
<pre><code>
 
643
// change height and width to 100x100 pixels
 
644
el.scale(100, 100);
 
645
 
 
646
// common config options shown with default values.  The height and width will default to
 
647
// the element's existing values if passed as null.
 
648
el.scale(
 
649
    [element's width],
 
650
    [element's height], {
 
651
            easing: 'easeOut',
 
652
            duration: .35
 
653
        }
 
654
);
 
655
</code></pre>
 
656
    * @param {Number} width  The new width (pass undefined to keep the original width)
 
657
    * @param {Number} height  The new height (pass undefined to keep the original height)
 
658
    * @param {Object} options (optional) Object literal with any of the Fx config options
 
659
    * @return {Ext.Element} The Element
 
660
    */
 
661
    scale : function(w, h, o){
 
662
        this.shift(Ext.apply({}, o, {
 
663
            width: w,
 
664
            height: h
 
665
        }));
 
666
        return this;
 
667
    },
 
668
 
 
669
   /**
 
670
    * Animates the transition of any combination of an element's dimensions, xy position and/or opacity.
 
671
    * Any of these properties not specified in the config object will not be changed.  This effect 
 
672
    * requires that at least one new dimension, position or opacity setting must be passed in on
 
673
    * the config object in order for the function to have any effect.
 
674
    * Usage:
 
675
<pre><code>
 
676
// slide the element horizontally to x position 200 while changing the height and opacity
 
677
el.shift({ x: 200, height: 50, opacity: .8 });
 
678
 
 
679
// common config options shown with default values.
 
680
el.shift({
 
681
    width: [element's width],
 
682
    height: [element's height],
 
683
    x: [element's x position],
 
684
    y: [element's y position],
 
685
    opacity: [element's opacity],
 
686
    easing: 'easeOut',
 
687
    duration: .35
 
688
});
 
689
</code></pre>
 
690
    * @param {Object} options  Object literal with any of the Fx config options
 
691
    * @return {Ext.Element} The Element
 
692
    */
 
693
    shift : function(o){
 
694
        var el = this.getFxEl();
 
695
        o = o || {};
 
696
        el.queueFx(o, function(){
 
697
            var a = {}, w = o.width, h = o.height, x = o.x, y = o.y,  op = o.opacity;
 
698
            if(w !== undefined){
 
699
                a.width = {to: this.adjustWidth(w)};
 
700
            }
 
701
            if(h !== undefined){
 
702
                a.height = {to: this.adjustHeight(h)};
 
703
            }
 
704
            if(o.left !== undefined){
 
705
                a.left = {to: o.left};
 
706
            }
 
707
            if(o.top !== undefined){
 
708
                a.top = {to: o.top};
 
709
            }
 
710
            if(o.right !== undefined){
 
711
                a.right = {to: o.right};
 
712
            }
 
713
            if(o.bottom !== undefined){
 
714
                a.bottom = {to: o.bottom};
 
715
            }
 
716
            if(x !== undefined || y !== undefined){
 
717
                a.points = {to: [
 
718
                    x !== undefined ? x : this.getX(),
 
719
                    y !== undefined ? y : this.getY()
 
720
                ]};
 
721
            }
 
722
            if(op !== undefined){
 
723
                a.opacity = {to: op};
 
724
            }
 
725
            if(o.xy !== undefined){
 
726
                a.points = {to: o.xy};
 
727
            }
 
728
            arguments.callee.anim = this.fxanim(a,
 
729
                o, 'motion', .35, "easeOut", function(){
 
730
                el.afterFx(o);
 
731
            });
 
732
        });
 
733
        return this;
 
734
    },
 
735
 
 
736
        /**
 
737
         * Slides the element while fading it out of view.  An anchor point can be optionally passed to set the 
 
738
         * ending point of the effect.
 
739
         * Usage:
 
740
         *<pre><code>
 
741
// default: slide the element downward while fading out
 
742
el.ghost();
 
743
 
 
744
// custom: slide the element out to the right with a 2-second duration
 
745
el.ghost('r', { duration: 2 });
 
746
 
 
747
// common config options shown with default values
 
748
el.ghost('b', {
 
749
    easing: 'easeOut',
 
750
    duration: .5,
 
751
    remove: false,
 
752
    useDisplay: false
 
753
});
 
754
</code></pre>
 
755
         * @param {String} anchor (optional) One of the valid Fx anchor positions (defaults to bottom: 'b')
 
756
         * @param {Object} options (optional) Object literal with any of the Fx config options
 
757
         * @return {Ext.Element} The Element
 
758
         */
 
759
    ghost : function(anchor, o){
 
760
        var el = this.getFxEl();
 
761
        o = o || {};
 
762
 
 
763
        el.queueFx(o, function(){
 
764
            anchor = anchor || "b";
 
765
 
 
766
            // restore values after effect
 
767
            var r = this.getFxRestore();
 
768
            var w = this.getWidth(),
 
769
                h = this.getHeight();
 
770
 
 
771
            var st = this.dom.style;
 
772
 
 
773
            var after = function(){
 
774
                if(o.useDisplay){
 
775
                    el.setDisplayed(false);
 
776
                }else{
 
777
                    el.hide();
 
778
                }
 
779
 
 
780
                el.clearOpacity();
 
781
                el.setPositioning(r.pos);
 
782
                st.width = r.width;
 
783
                st.height = r.height;
 
784
 
 
785
                el.afterFx(o);
 
786
            };
 
787
 
 
788
            var a = {opacity: {to: 0}, points: {}}, pt = a.points;
 
789
            switch(anchor.toLowerCase()){
 
790
                case "t":
 
791
                    pt.by = [0, -h];
 
792
                break;
 
793
                case "l":
 
794
                    pt.by = [-w, 0];
 
795
                break;
 
796
                case "r":
 
797
                    pt.by = [w, 0];
 
798
                break;
 
799
                case "b":
 
800
                    pt.by = [0, h];
 
801
                break;
 
802
                case "tl":
 
803
                    pt.by = [-w, -h];
 
804
                break;
 
805
                case "bl":
 
806
                    pt.by = [-w, h];
 
807
                break;
 
808
                case "br":
 
809
                    pt.by = [w, h];
 
810
                break;
 
811
                case "tr":
 
812
                    pt.by = [w, -h];
 
813
                break;
 
814
            }
 
815
 
 
816
            arguments.callee.anim = this.fxanim(a,
 
817
                o,
 
818
                'motion',
 
819
                .5,
 
820
                "easeOut", after);
 
821
        });
 
822
        return this;
 
823
    },
 
824
 
 
825
        /**
 
826
         * Ensures that all effects queued after syncFx is called on the element are
 
827
         * run concurrently.  This is the opposite of {@link #sequenceFx}.
 
828
         * @return {Ext.Element} The Element
 
829
         */
 
830
    syncFx : function(){
 
831
        this.fxDefaults = Ext.apply(this.fxDefaults || {}, {
 
832
            block : false,
 
833
            concurrent : true,
 
834
            stopFx : false
 
835
        });
 
836
        return this;
 
837
    },
 
838
 
 
839
        /**
 
840
         * Ensures that all effects queued after sequenceFx is called on the element are
 
841
         * run in sequence.  This is the opposite of {@link #syncFx}.
 
842
         * @return {Ext.Element} The Element
 
843
         */
 
844
    sequenceFx : function(){
 
845
        this.fxDefaults = Ext.apply(this.fxDefaults || {}, {
 
846
            block : false,
 
847
            concurrent : false,
 
848
            stopFx : false
 
849
        });
 
850
        return this;
 
851
    },
 
852
 
 
853
        /* @private */
 
854
    nextFx : function(){
 
855
        var ef = this.fxQueue[0];
 
856
        if(ef){
 
857
            ef.call(this);
 
858
        }
 
859
    },
 
860
 
 
861
        /**
 
862
         * Returns true if the element has any effects actively running or queued, else returns false.
 
863
         * @return {Boolean} True if element has active effects, else false
 
864
         */
 
865
    hasActiveFx : function(){
 
866
        return this.fxQueue && this.fxQueue[0];
 
867
    },
 
868
 
 
869
        /**
 
870
         * Stops any running effects and clears the element's internal effects queue if it contains
 
871
         * any additional effects that haven't started yet.
 
872
         * @return {Ext.Element} The Element
 
873
         */
 
874
    stopFx : function(){
 
875
        if(this.hasActiveFx()){
 
876
            var cur = this.fxQueue[0];
 
877
            if(cur && cur.anim && cur.anim.isAnimated()){
 
878
                this.fxQueue = [cur]; // clear out others
 
879
                cur.anim.stop(true);
 
880
            }
 
881
        }
 
882
        return this;
 
883
    },
 
884
 
 
885
        /* @private */
 
886
    beforeFx : function(o){
 
887
        if(this.hasActiveFx() && !o.concurrent){
 
888
           if(o.stopFx){
 
889
               this.stopFx();
 
890
               return true;
 
891
           }
 
892
           return false;
 
893
        }
 
894
        return true;
 
895
    },
 
896
 
 
897
        /**
 
898
         * Returns true if the element is currently blocking so that no other effect can be queued
 
899
         * until this effect is finished, else returns false if blocking is not set.  This is commonly
 
900
         * used to ensure that an effect initiated by a user action runs to completion prior to the
 
901
         * same effect being restarted (e.g., firing only one effect even if the user clicks several times).
 
902
         * @return {Boolean} True if blocking, else false
 
903
         */
 
904
    hasFxBlock : function(){
 
905
        var q = this.fxQueue;
 
906
        return q && q[0] && q[0].block;
 
907
    },
 
908
 
 
909
        /* @private */
 
910
    queueFx : function(o, fn){
 
911
        if(!this.fxQueue){
 
912
            this.fxQueue = [];
 
913
        }
 
914
        if(!this.hasFxBlock()){
 
915
            Ext.applyIf(o, this.fxDefaults);
 
916
            if(!o.concurrent){
 
917
                var run = this.beforeFx(o);
 
918
                fn.block = o.block;
 
919
                this.fxQueue.push(fn);
 
920
                if(run){
 
921
                    this.nextFx();
 
922
                }
 
923
            }else{
 
924
                fn.call(this);
 
925
            }
 
926
        }
 
927
        return this;
 
928
    },
 
929
 
 
930
        /* @private */
 
931
    fxWrap : function(pos, o, vis){
 
932
        var wrap;
 
933
        if(!o.wrap || !(wrap = Ext.get(o.wrap))){
 
934
            var wrapXY;
 
935
            if(o.fixPosition){
 
936
                wrapXY = this.getXY();
 
937
            }
 
938
            var div = document.createElement("div");
 
939
            div.style.visibility = vis;
 
940
            wrap = Ext.get(this.dom.parentNode.insertBefore(div, this.dom));
 
941
            wrap.setPositioning(pos);
 
942
            if(wrap.getStyle("position") == "static"){
 
943
                wrap.position("relative");
 
944
            }
 
945
            this.clearPositioning('auto');
 
946
            wrap.clip();
 
947
            wrap.dom.appendChild(this.dom);
 
948
            if(wrapXY){
 
949
                wrap.setXY(wrapXY);
 
950
            }
 
951
        }
 
952
        return wrap;
 
953
    },
 
954
 
 
955
        /* @private */
 
956
    fxUnwrap : function(wrap, pos, o){
 
957
        this.clearPositioning();
 
958
        this.setPositioning(pos);
 
959
        if(!o.wrap){
 
960
            wrap.dom.parentNode.insertBefore(this.dom, wrap.dom);
 
961
            wrap.remove();
 
962
        }
 
963
    },
 
964
 
 
965
        /* @private */
 
966
    getFxRestore : function(){
 
967
        var st = this.dom.style;
 
968
        return {pos: this.getPositioning(), width: st.width, height : st.height};
 
969
    },
 
970
 
 
971
        /* @private */
 
972
    afterFx : function(o){
 
973
        if(o.afterStyle){
 
974
            this.applyStyles(o.afterStyle);
 
975
        }
 
976
        if(o.afterCls){
 
977
            this.addClass(o.afterCls);
 
978
        }
 
979
        if(o.remove === true){
 
980
            this.remove();
 
981
        }
 
982
        Ext.callback(o.callback, o.scope, [this]);
 
983
        if(!o.concurrent){
 
984
            this.fxQueue.shift();
 
985
            this.nextFx();
 
986
        }
 
987
    },
 
988
 
 
989
        /* @private */
 
990
    getFxEl : function(){ // support for composite element fx
 
991
        return Ext.get(this.dom);
 
992
    },
 
993
 
 
994
        /* @private */
 
995
    fxanim : function(args, opt, animType, defaultDur, defaultEase, cb){
 
996
        animType = animType || 'run';
 
997
        opt = opt || {};
 
998
        var anim = Ext.lib.Anim[animType](
 
999
            this.dom, args,
 
1000
            (opt.duration || defaultDur) || .35,
 
1001
            (opt.easing || defaultEase) || 'easeOut',
 
1002
            function(){
 
1003
                Ext.callback(cb, this);
 
1004
            },
 
1005
            this
 
1006
        );
 
1007
        opt.anim = anim;
 
1008
        return anim;
 
1009
    }
 
1010
};
 
1011
 
 
1012
// backwords compat
 
1013
Ext.Fx.resize = Ext.Fx.scale;
 
1014
 
 
1015
//When included, Ext.Fx is automatically applied to Element so that all basic
 
1016
//effects are available directly via the Element API
 
1017
Ext.apply(Ext.Element.prototype, Ext.Fx);