source: trunk/web/addons/job_monarch/lib/extjs/source/widgets/Slider.js @ 619

Last change on this file since 619 was 619, checked in by ramonb, 15 years ago

lib/:

  • added new AJAX dependancies: ExtJS, pChart, Lightbox2
File size: 13.5 KB
Line 
1/*
2 * Ext JS Library 2.2.1
3 * Copyright(c) 2006-2009, Ext JS, LLC.
4 * licensing@extjs.com
5 *
6 * http://extjs.com/license
7 */
8
9/**
10 * @class Ext.Slider
11 * @extends Ext.BoxComponent
12 * Slider which supports vertical or horizontal orientation, keyboard adjustments,
13 * configurable snapping, axis clicking and animation. Can be added as an item to
14 * any container. Example usage:
15<pre><code>
16new Ext.Slider({
17    renderTo: Ext.getBody(),
18    width: 200,
19    value: 50,
20    increment: 10,
21    minValue: 0,
22    maxValue: 100
23});
24</code></pre>
25 */
26Ext.Slider = Ext.extend(Ext.BoxComponent, {
27        /**
28         * @cfg {Number} value The value to initialize the slider with. Defaults to minValue.
29         */
30        /**
31         * @cfg {Boolean} vertical Orient the Slider vertically rather than horizontally, defaults to false.
32         */
33    vertical: false,
34        /**
35         * @cfg {Number} minValue The minimum value for the Slider. Defaults to 0.
36         */
37    minValue: 0,
38        /**
39         * @cfg {Number} maxValue The maximum value for the Slider. Defaults to 100.
40         */     
41    maxValue: 100,
42        /**
43         * @cfg {Number} keyIncrement How many units to change the Slider when adjusting with keyboard navigation. Defaults to 1. If the increment config is larger, it will be used instead.
44         */
45    keyIncrement: 1,
46        /**
47         * @cfg {Number} increment How many units to change the slider when adjusting by drag and drop. Use this option to enable 'snapping'.
48         */
49    increment: 0,
50        // private
51    clickRange: [5,15],
52        /**
53         * @cfg {Boolean} clickToChange Determines whether or not clicking on the Slider axis will change the slider. Defaults to true
54         */
55    clickToChange : true,
56        /**
57         * @cfg {Boolean} animate Turn on or off animation. Defaults to true
58         */
59    animate: true,
60
61    /**
62     * True while the thumb is in a drag operation
63     * @type boolean
64     */
65    dragging: false,
66
67    // private override
68    initComponent : function(){
69        if(this.value === undefined){
70            this.value = this.minValue;
71        }
72        Ext.Slider.superclass.initComponent.call(this);
73        this.keyIncrement = Math.max(this.increment, this.keyIncrement); 
74        this.addEvents(
75            /**
76             * @event beforechange
77             * Fires before the slider value is changed. By returning false from an event handler,
78             * you can cancel the event and prevent the slider from changing.
79                         * @param {Ext.Slider} slider The slider
80                         * @param {Number} newValue The new value which the slider is being changed to.
81                         * @param {Number} oldValue The old value which the slider was previously.
82             */         
83                        'beforechange', 
84                        /**
85                         * @event change
86                         * Fires when the slider value is changed.
87                         * @param {Ext.Slider} slider The slider
88                         * @param {Number} newValue The new value which the slider has been changed to.
89                         */
90                        'change',
91                        /**
92                         * @event changecomplete
93                         * Fires when the slider value is changed by the user and any drag operations have completed.
94                         * @param {Ext.Slider} slider The slider
95                         * @param {Number} newValue The new value which the slider has been changed to.
96                         */
97                        'changecomplete',
98                        /**
99                         * @event dragstart
100             * Fires after a drag operation has started.
101                         * @param {Ext.Slider} slider The slider
102                         * @param {Ext.EventObject} e The event fired from Ext.dd.DragTracker
103                         */
104                        'dragstart', 
105                        /**
106                         * @event drag
107             * Fires continuously during the drag operation while the mouse is moving.
108                         * @param {Ext.Slider} slider The slider
109                         * @param {Ext.EventObject} e The event fired from Ext.dd.DragTracker
110                         */
111                        'drag', 
112                        /**
113                         * @event dragend
114             * Fires after the drag operation has completed.
115                         * @param {Ext.Slider} slider The slider
116                         * @param {Ext.EventObject} e The event fired from Ext.dd.DragTracker
117                         */
118                        'dragend'
119                );
120
121        if(this.vertical){
122            Ext.apply(this, Ext.Slider.Vertical);
123        }
124    },
125
126        // private override
127    onRender : function(){
128        this.autoEl = {
129            cls: 'x-slider ' + (this.vertical ? 'x-slider-vert' : 'x-slider-horz'),
130            cn:{cls:'x-slider-end',cn:{cls:'x-slider-inner',cn:[{cls:'x-slider-thumb'},{tag:'a', cls:'x-slider-focus', href:"#", tabIndex: '-1', hidefocus:'on'}]}}
131        };
132        Ext.Slider.superclass.onRender.apply(this, arguments);
133        this.endEl = this.el.first();
134        this.innerEl = this.endEl.first();
135        this.thumb = this.innerEl.first();
136        this.halfThumb = (this.vertical ? this.thumb.getHeight() : this.thumb.getWidth())/2;
137        this.focusEl = this.thumb.next();
138        this.initEvents();
139    },
140
141        // private override
142    initEvents : function(){
143        this.thumb.addClassOnOver('x-slider-thumb-over');
144        this.mon(this.el, 'mousedown', this.onMouseDown, this);
145        this.mon(this.el, 'keydown', this.onKeyDown, this);
146
147        this.focusEl.swallowEvent("click", true);
148
149        this.tracker = new Ext.dd.DragTracker({
150            onBeforeStart: this.onBeforeDragStart.createDelegate(this),
151            onStart: this.onDragStart.createDelegate(this),
152            onDrag: this.onDrag.createDelegate(this),
153            onEnd: this.onDragEnd.createDelegate(this),
154            tolerance: 3,
155            autoStart: 300
156        });
157        this.tracker.initEl(this.thumb);
158        this.on('beforedestroy', this.tracker.destroy, this.tracker);
159    },
160
161        // private override
162    onMouseDown : function(e){
163        if(this.disabled) {return;}
164        if(this.clickToChange && e.target != this.thumb.dom){
165            var local = this.innerEl.translatePoints(e.getXY());
166            this.onClickChange(local);
167        }
168        this.focus();
169    },
170
171        // private
172    onClickChange : function(local){
173        if(local.top > this.clickRange[0] && local.top < this.clickRange[1]){
174            this.setValue(Math.round(this.reverseValue(local.left)), undefined, true);
175        }
176    },
177       
178        // private
179    onKeyDown : function(e){
180        if(this.disabled){e.preventDefault();return;}
181        var k = e.getKey();
182        switch(k){
183            case e.UP:
184            case e.RIGHT:
185                e.stopEvent();
186                if(e.ctrlKey){
187                    this.setValue(this.maxValue, undefined, true);
188                }else{
189                    this.setValue(this.value+this.keyIncrement, undefined, true);
190                }
191            break;
192            case e.DOWN:
193            case e.LEFT:
194                e.stopEvent();
195                if(e.ctrlKey){
196                    this.setValue(this.minValue, undefined, true);
197                }else{
198                    this.setValue(this.value-this.keyIncrement, undefined, true);
199                }
200            break;
201            default:
202                e.preventDefault();
203        }
204    },
205       
206        // private
207    doSnap : function(value){
208        if(!this.increment || this.increment == 1 || !value) {
209            return value;
210        }
211        var newValue = value, inc = this.increment;
212        var m = value % inc;
213        if(m > 0){
214            if(m > (inc/2)){
215                newValue = value + (inc-m);
216            }else{
217                newValue = value - m;
218            }
219        }
220        return newValue.constrain(this.minValue,  this.maxValue);
221    },
222       
223        // private
224    afterRender : function(){
225        Ext.Slider.superclass.afterRender.apply(this, arguments);
226        if(this.value !== undefined){
227            var v = this.normalizeValue(this.value);
228            if(v !== this.value){
229                delete this.value;
230                this.setValue(v, false);
231            }else{
232                this.moveThumb(this.translateValue(v), false);
233            }
234        }
235    },
236
237        // private
238    getRatio : function(){
239        var w = this.innerEl.getWidth();
240        var v = this.maxValue - this.minValue;
241        return v == 0 ? w : (w/v);
242    },
243
244        // private
245    normalizeValue : function(v){
246       if(typeof v != 'number'){
247            v = parseInt(v);
248        }
249        v = Math.round(v);
250        v = this.doSnap(v);
251        v = v.constrain(this.minValue, this.maxValue);
252        return v;
253    },
254
255        /**
256         * Programmatically sets the value of the Slider. Ensures that the value is constrained within
257         * the minValue and maxValue.
258         * @param {Number} value The value to set the slider to. (This will be constrained within minValue and maxValue)
259         * @param {Boolean} animate Turn on or off animation, defaults to true
260         */
261    setValue : function(v, animate, changeComplete){
262        v = this.normalizeValue(v);
263        if(v !== this.value && this.fireEvent('beforechange', this, v, this.value) !== false){
264            this.value = v;
265            this.moveThumb(this.translateValue(v), animate !== false);
266            this.fireEvent('change', this, v);
267            if(changeComplete){
268                this.fireEvent('changecomplete', this, v);
269            }
270        }
271    },
272
273        // private
274    translateValue : function(v){
275        var ratio = this.getRatio();
276        return (v * ratio)-(this.minValue * ratio)-this.halfThumb;
277    },
278
279        reverseValue : function(pos){
280        var ratio = this.getRatio();
281        return (pos+this.halfThumb+(this.minValue * ratio))/ratio;
282    },
283
284        // private
285    moveThumb: function(v, animate){
286        if(!animate || this.animate === false){
287            this.thumb.setLeft(v);
288        }else{
289            this.thumb.shift({left: v, stopFx: true, duration:.35});
290        }
291    },
292
293        // private
294    focus : function(){
295        this.focusEl.focus(10);
296    },
297
298        // private
299    onBeforeDragStart : function(e){
300        return !this.disabled;
301    },
302
303        // private
304    onDragStart: function(e){
305        this.thumb.addClass('x-slider-thumb-drag');
306        this.dragging = true;
307        this.dragStartValue = this.value;
308        this.fireEvent('dragstart', this, e);
309    },
310
311        // private
312    onDrag: function(e){
313        var pos = this.innerEl.translatePoints(this.tracker.getXY());
314        this.setValue(Math.round(this.reverseValue(pos.left)), false);
315        this.fireEvent('drag', this, e);
316    },
317       
318        // private
319    onDragEnd: function(e){
320        this.thumb.removeClass('x-slider-thumb-drag');
321        this.dragging = false;
322        this.fireEvent('dragend', this, e);
323        if(this.dragStartValue != this.value){
324            this.fireEvent('changecomplete', this, this.value);
325        }
326    },
327   
328    //private
329    onDisable: function(){
330        Ext.Slider.superclass.onDisable.call(this);
331        this.thumb.addClass(this.disabledClass);
332        if(Ext.isIE){
333            //IE breaks when using overflow visible and opacity other than 1.
334            //Create a place holder for the thumb and display it.
335            var xy = this.thumb.getXY();
336            this.thumb.hide();
337            this.innerEl.addClass(this.disabledClass).dom.disabled = true;
338            if (!this.thumbHolder){
339                this.thumbHolder = this.endEl.createChild({cls: 'x-slider-thumb ' + this.disabledClass});   
340            }
341            this.thumbHolder.show().setXY(xy);
342        }
343    },
344   
345    //private
346    onEnable: function(){
347        Ext.Slider.superclass.onEnable.call(this);
348        this.thumb.removeClass(this.disabledClass);
349        if(Ext.isIE){
350            this.innerEl.removeClass(this.disabledClass).dom.disabled = false;
351            if (this.thumbHolder){
352                this.thumbHolder.hide();
353            }
354            this.thumb.show();
355            this.syncThumb();
356        }
357    },
358
359    // private
360    onResize : function(w, h){
361        this.innerEl.setWidth(w - (this.el.getPadding('l') + this.endEl.getPadding('r')));
362        this.syncThumb();
363    },
364   
365    /**
366     * Synchronizes the thumb position to the proper proportion of the total component width based
367     * on the current slider {@link #value}.  This will be called automatically when the Slider
368     * is resized by a layout, but if it is rendered auto width, this method can be called from
369     * another resize handler to sync the Slider if necessary.
370     */
371    syncThumb : function(){
372        if(this.rendered){
373            this.moveThumb(this.translateValue(this.value));
374        }
375    },
376       
377        /**
378         * Returns the current value of the slider
379         * @return {Number} The current value of the slider
380         */
381    getValue : function(){
382        return this.value;
383    }
384});
385Ext.reg('slider', Ext.Slider);
386
387// private class to support vertical sliders
388Ext.Slider.Vertical = {
389    onResize : function(w, h){
390        this.innerEl.setHeight(h - (this.el.getPadding('t') + this.endEl.getPadding('b')));
391        this.syncThumb();
392    },
393
394    getRatio : function(){
395        var h = this.innerEl.getHeight();
396        var v = this.maxValue - this.minValue;
397        return h/v;
398    },
399
400    moveThumb: function(v, animate){
401        if(!animate || this.animate === false){
402            this.thumb.setBottom(v);
403        }else{
404            this.thumb.shift({bottom: v, stopFx: true, duration:.35});
405        }
406    },
407
408    onDrag: function(e){
409        var pos = this.innerEl.translatePoints(this.tracker.getXY());
410        var bottom = this.innerEl.getHeight()-pos.top;
411        this.setValue(this.minValue + Math.round(bottom/this.getRatio()), false);
412        this.fireEvent('drag', this, e);
413    },
414
415    onClickChange : function(local){
416        if(local.left > this.clickRange[0] && local.left < this.clickRange[1]){
417            var bottom = this.innerEl.getHeight()-local.top;
418            this.setValue(this.minValue + Math.round(bottom/this.getRatio()), undefined, true);
419        }
420    }
421};
Note: See TracBrowser for help on using the repository browser.