979 lines
36 KiB
HTML
979 lines
36 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
<title>The source code</title>
|
|
<link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
|
|
<script type="text/javascript" src="../resources/prettify/prettify.js"></script>
|
|
<style type="text/css">
|
|
.highlight { display: block; background-color: #ddd; }
|
|
</style>
|
|
<script type="text/javascript">
|
|
function highlight() {
|
|
document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
|
|
}
|
|
</script>
|
|
</head>
|
|
<body onload="prettyPrint(); highlight();">
|
|
<pre class="prettyprint lang-js"><span id='Ext-slider-Thumb'>/**
|
|
</span> * @class Ext.slider.Thumb
|
|
* @extends Object
|
|
* Represents a single thumb element on a Slider. This would not usually be created manually and would instead
|
|
* be created internally by an {@link Ext.slider.MultiSlider Ext.Slider}.
|
|
*/
|
|
Ext.slider.Thumb = Ext.extend(Object, {
|
|
|
|
<span id='Ext-slider-Thumb-property-dragging'> /**
|
|
</span> * True while the thumb is in a drag operation
|
|
* @type Boolean
|
|
*/
|
|
dragging: false,
|
|
|
|
<span id='Ext-slider-Thumb-cfg-slider'> /**
|
|
</span> * @constructor
|
|
* @cfg {Ext.slider.MultiSlider} slider The Slider to render to (required)
|
|
*/
|
|
constructor: function(config) {
|
|
<span id='Ext-slider-Thumb-property-slider'> /**
|
|
</span> * @property slider
|
|
* @type Ext.slider.MultiSlider
|
|
* The slider this thumb is contained within
|
|
*/
|
|
Ext.apply(this, config || {}, {
|
|
cls: 'x-slider-thumb',
|
|
|
|
<span id='Ext-slider-Thumb-cfg-constrain'> /**
|
|
</span> * @cfg {Boolean} constrain True to constrain the thumb so that it cannot overlap its siblings
|
|
*/
|
|
constrain: false
|
|
});
|
|
|
|
Ext.slider.Thumb.superclass.constructor.call(this, config);
|
|
|
|
if (this.slider.vertical) {
|
|
Ext.apply(this, Ext.slider.Thumb.Vertical);
|
|
}
|
|
},
|
|
|
|
<span id='Ext-slider-Thumb-method-render'> /**
|
|
</span> * Renders the thumb into a slider
|
|
*/
|
|
render: function() {
|
|
this.el = this.slider.innerEl.insertFirst({cls: this.cls});
|
|
|
|
this.initEvents();
|
|
},
|
|
|
|
<span id='Ext-slider-Thumb-method-enable'> /**
|
|
</span> * Enables the thumb if it is currently disabled
|
|
*/
|
|
enable: function() {
|
|
this.disabled = false;
|
|
this.el.removeClass(this.slider.disabledClass);
|
|
},
|
|
|
|
<span id='Ext-slider-Thumb-method-disable'> /**
|
|
</span> * Disables the thumb if it is currently enabled
|
|
*/
|
|
disable: function() {
|
|
this.disabled = true;
|
|
this.el.addClass(this.slider.disabledClass);
|
|
},
|
|
|
|
<span id='Ext-slider-Thumb-method-initEvents'> /**
|
|
</span> * Sets up an Ext.dd.DragTracker for this thumb
|
|
*/
|
|
initEvents: function() {
|
|
var el = this.el;
|
|
|
|
el.addClassOnOver('x-slider-thumb-over');
|
|
|
|
this.tracker = new Ext.dd.DragTracker({
|
|
onBeforeStart: this.onBeforeDragStart.createDelegate(this),
|
|
onStart : this.onDragStart.createDelegate(this),
|
|
onDrag : this.onDrag.createDelegate(this),
|
|
onEnd : this.onDragEnd.createDelegate(this),
|
|
tolerance : 3,
|
|
autoStart : 300
|
|
});
|
|
|
|
this.tracker.initEl(el);
|
|
},
|
|
|
|
<span id='Ext-slider-Thumb-method-onBeforeDragStart'> /**
|
|
</span> * @private
|
|
* This is tied into the internal Ext.dd.DragTracker. If the slider is currently disabled,
|
|
* this returns false to disable the DragTracker too.
|
|
* @return {Boolean} False if the slider is currently disabled
|
|
*/
|
|
onBeforeDragStart : function(e) {
|
|
if (this.disabled) {
|
|
return false;
|
|
} else {
|
|
this.slider.promoteThumb(this);
|
|
return true;
|
|
}
|
|
},
|
|
|
|
<span id='Ext-slider-Thumb-method-onDragStart'> /**
|
|
</span> * @private
|
|
* This is tied into the internal Ext.dd.DragTracker's onStart template method. Adds the drag CSS class
|
|
* to the thumb and fires the 'dragstart' event
|
|
*/
|
|
onDragStart: function(e){
|
|
this.el.addClass('x-slider-thumb-drag');
|
|
this.dragging = true;
|
|
this.dragStartValue = this.value;
|
|
|
|
this.slider.fireEvent('dragstart', this.slider, e, this);
|
|
},
|
|
|
|
<span id='Ext-slider-Thumb-method-onDrag'> /**
|
|
</span> * @private
|
|
* This is tied into the internal Ext.dd.DragTracker's onDrag template method. This is called every time
|
|
* the DragTracker detects a drag movement. It updates the Slider's value using the position of the drag
|
|
*/
|
|
onDrag: function(e) {
|
|
var slider = this.slider,
|
|
index = this.index,
|
|
newValue = this.getNewValue();
|
|
|
|
if (this.constrain) {
|
|
var above = slider.thumbs[index + 1],
|
|
below = slider.thumbs[index - 1];
|
|
|
|
if (below != undefined && newValue <= below.value) newValue = below.value;
|
|
if (above != undefined && newValue >= above.value) newValue = above.value;
|
|
}
|
|
|
|
slider.setValue(index, newValue, false);
|
|
slider.fireEvent('drag', slider, e, this);
|
|
},
|
|
|
|
<span id='Ext-slider-Thumb-method-getNewValue'> getNewValue: function() {
|
|
</span> var slider = this.slider,
|
|
pos = slider.innerEl.translatePoints(this.tracker.getXY());
|
|
|
|
return Ext.util.Format.round(slider.reverseValue(pos.left), slider.decimalPrecision);
|
|
},
|
|
|
|
<span id='Ext-slider-Thumb-method-onDragEnd'> /**
|
|
</span> * @private
|
|
* This is tied to the internal Ext.dd.DragTracker's onEnd template method. Removes the drag CSS class and
|
|
* fires the 'changecomplete' event with the new value
|
|
*/
|
|
onDragEnd: function(e) {
|
|
var slider = this.slider,
|
|
value = this.value;
|
|
|
|
this.el.removeClass('x-slider-thumb-drag');
|
|
|
|
this.dragging = false;
|
|
slider.fireEvent('dragend', slider, e);
|
|
|
|
if (this.dragStartValue != value) {
|
|
slider.fireEvent('changecomplete', slider, value, this);
|
|
}
|
|
},
|
|
|
|
<span id='Ext-slider-Thumb-method-destroy'> /**
|
|
</span> * @private
|
|
* Destroys the thumb
|
|
*/
|
|
destroy: function(){
|
|
Ext.destroyMembers(this, 'tracker', 'el');
|
|
}
|
|
});
|
|
|
|
<span id='Ext-slider-MultiSlider'>/**
|
|
</span> * @class Ext.slider.MultiSlider
|
|
* @extends Ext.BoxComponent
|
|
* Slider which supports vertical or horizontal orientation, keyboard adjustments, configurable snapping, axis clicking and animation. Can be added as an item to any container. Example usage:
|
|
<pre>
|
|
new Ext.Slider({
|
|
renderTo: Ext.getBody(),
|
|
width: 200,
|
|
value: 50,
|
|
increment: 10,
|
|
minValue: 0,
|
|
maxValue: 100
|
|
});
|
|
</pre>
|
|
* Sliders can be created with more than one thumb handle by passing an array of values instead of a single one:
|
|
<pre>
|
|
new Ext.Slider({
|
|
renderTo: Ext.getBody(),
|
|
width: 200,
|
|
values: [25, 50, 75],
|
|
minValue: 0,
|
|
maxValue: 100,
|
|
|
|
//this defaults to true, setting to false allows the thumbs to pass each other
|
|
{@link #constrainThumbs}: false
|
|
});
|
|
</pre>
|
|
*/
|
|
Ext.slider.MultiSlider = Ext.extend(Ext.BoxComponent, {
|
|
<span id='Ext-slider-MultiSlider-cfg-value'> /**
|
|
</span> * @cfg {Number} value The value to initialize the slider with. Defaults to minValue.
|
|
*/
|
|
<span id='Ext-slider-MultiSlider-cfg-vertical'> /**
|
|
</span> * @cfg {Boolean} vertical Orient the Slider vertically rather than horizontally, defaults to false.
|
|
*/
|
|
vertical: false,
|
|
<span id='Ext-slider-MultiSlider-cfg-minValue'> /**
|
|
</span> * @cfg {Number} minValue The minimum value for the Slider. Defaults to 0.
|
|
*/
|
|
minValue: 0,
|
|
<span id='Ext-slider-MultiSlider-cfg-maxValue'> /**
|
|
</span> * @cfg {Number} maxValue The maximum value for the Slider. Defaults to 100.
|
|
*/
|
|
maxValue: 100,
|
|
<span id='Ext-slider-MultiSlider-cfg-decimalPrecision'> /**
|
|
</span> * @cfg {Number/Boolean} decimalPrecision.
|
|
* <p>The number of decimal places to which to round the Slider's value. Defaults to 0.</p>
|
|
* <p>To disable rounding, configure as <tt><b>false</b></tt>.</p>
|
|
*/
|
|
decimalPrecision: 0,
|
|
<span id='Ext-slider-MultiSlider-cfg-keyIncrement'> /**
|
|
</span> * @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.
|
|
*/
|
|
keyIncrement: 1,
|
|
<span id='Ext-slider-MultiSlider-cfg-increment'> /**
|
|
</span> * @cfg {Number} increment How many units to change the slider when adjusting by drag and drop. Use this option to enable 'snapping'.
|
|
*/
|
|
increment: 0,
|
|
|
|
<span id='Ext-slider-MultiSlider-property-clickRange'> /**
|
|
</span> * @private
|
|
* @property clickRange
|
|
* @type Array
|
|
* Determines whether or not a click to the slider component is considered to be a user request to change the value. Specified as an array of [top, bottom],
|
|
* the click event's 'top' property is compared to these numbers and the click only considered a change request if it falls within them. e.g. if the 'top'
|
|
* value of the click event is 4 or 16, the click is not considered a change request as it falls outside of the [5, 15] range
|
|
*/
|
|
clickRange: [5,15],
|
|
|
|
<span id='Ext-slider-MultiSlider-cfg-clickToChange'> /**
|
|
</span> * @cfg {Boolean} clickToChange Determines whether or not clicking on the Slider axis will change the slider. Defaults to true
|
|
*/
|
|
clickToChange : true,
|
|
<span id='Ext-slider-MultiSlider-cfg-animate'> /**
|
|
</span> * @cfg {Boolean} animate Turn on or off animation. Defaults to true
|
|
*/
|
|
animate: true,
|
|
<span id='Ext-slider-MultiSlider-cfg-constrainThumbs'> /**
|
|
</span> * @cfg {Boolean} constrainThumbs True to disallow thumbs from overlapping one another. Defaults to true
|
|
*/
|
|
constrainThumbs: true,
|
|
|
|
<span id='Ext-slider-MultiSlider-property-topThumbZIndex'> /**
|
|
</span> * @private
|
|
* @property topThumbZIndex
|
|
* @type Number
|
|
* The number used internally to set the z index of the top thumb (see promoteThumb for details)
|
|
*/
|
|
topThumbZIndex: 10000,
|
|
|
|
<span id='Ext-slider-MultiSlider-method-initComponent'> // private override
|
|
</span> initComponent : function(){
|
|
if(!Ext.isDefined(this.value)){
|
|
this.value = this.minValue;
|
|
}
|
|
|
|
<span id='Ext-slider-MultiSlider-property-thumbs'> /**
|
|
</span> * @property thumbs
|
|
* @type Array
|
|
* Array containing references to each thumb
|
|
*/
|
|
this.thumbs = [];
|
|
|
|
Ext.slider.MultiSlider.superclass.initComponent.call(this);
|
|
|
|
this.keyIncrement = Math.max(this.increment, this.keyIncrement);
|
|
this.addEvents(
|
|
<span id='Ext-slider-MultiSlider-event-beforechange'> /**
|
|
</span> * @event beforechange
|
|
* Fires before the slider value is changed. By returning false from an event handler,
|
|
* you can cancel the event and prevent the slider from changing.
|
|
* @param {Ext.slider.MultiSlider} slider The slider
|
|
* @param {Number} newValue The new value which the slider is being changed to.
|
|
* @param {Number} oldValue The old value which the slider was previously.
|
|
*/
|
|
'beforechange',
|
|
|
|
<span id='Ext-slider-MultiSlider-event-change'> /**
|
|
</span> * @event change
|
|
* Fires when the slider value is changed.
|
|
* @param {Ext.slider.MultiSlider} slider The slider
|
|
* @param {Number} newValue The new value which the slider has been changed to.
|
|
* @param {Ext.slider.Thumb} thumb The thumb that was changed
|
|
*/
|
|
'change',
|
|
|
|
<span id='Ext-slider-MultiSlider-event-changecomplete'> /**
|
|
</span> * @event changecomplete
|
|
* Fires when the slider value is changed by the user and any drag operations have completed.
|
|
* @param {Ext.slider.MultiSlider} slider The slider
|
|
* @param {Number} newValue The new value which the slider has been changed to.
|
|
* @param {Ext.slider.Thumb} thumb The thumb that was changed
|
|
*/
|
|
'changecomplete',
|
|
|
|
<span id='Ext-slider-MultiSlider-event-dragstart'> /**
|
|
</span> * @event dragstart
|
|
* Fires after a drag operation has started.
|
|
* @param {Ext.slider.MultiSlider} slider The slider
|
|
* @param {Ext.EventObject} e The event fired from Ext.dd.DragTracker
|
|
*/
|
|
'dragstart',
|
|
|
|
<span id='Ext-slider-MultiSlider-event-drag'> /**
|
|
</span> * @event drag
|
|
* Fires continuously during the drag operation while the mouse is moving.
|
|
* @param {Ext.slider.MultiSlider} slider The slider
|
|
* @param {Ext.EventObject} e The event fired from Ext.dd.DragTracker
|
|
*/
|
|
'drag',
|
|
|
|
<span id='Ext-slider-MultiSlider-event-dragend'> /**
|
|
</span> * @event dragend
|
|
* Fires after the drag operation has completed.
|
|
* @param {Ext.slider.MultiSlider} slider The slider
|
|
* @param {Ext.EventObject} e The event fired from Ext.dd.DragTracker
|
|
*/
|
|
'dragend'
|
|
);
|
|
|
|
<span id='Ext-slider-MultiSlider-property-values'> /**
|
|
</span> * @property values
|
|
* @type Array
|
|
* Array of values to initalize the thumbs with
|
|
*/
|
|
if (this.values == undefined || Ext.isEmpty(this.values)) this.values = [0];
|
|
|
|
var values = this.values;
|
|
|
|
for (var i=0; i < values.length; i++) {
|
|
this.addThumb(values[i]);
|
|
}
|
|
|
|
if(this.vertical){
|
|
Ext.apply(this, Ext.slider.Vertical);
|
|
}
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-addThumb'> /**
|
|
</span> * Creates a new thumb and adds it to the slider
|
|
* @param {Number} value The initial value to set on the thumb. Defaults to 0
|
|
*/
|
|
addThumb: function(value) {
|
|
var thumb = new Ext.slider.Thumb({
|
|
value : value,
|
|
slider : this,
|
|
index : this.thumbs.length,
|
|
constrain: this.constrainThumbs
|
|
});
|
|
this.thumbs.push(thumb);
|
|
|
|
//render the thumb now if needed
|
|
if (this.rendered) thumb.render();
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-promoteThumb'> /**
|
|
</span> * @private
|
|
* Moves the given thumb above all other by increasing its z-index. This is called when as drag
|
|
* any thumb, so that the thumb that was just dragged is always at the highest z-index. This is
|
|
* required when the thumbs are stacked on top of each other at one of the ends of the slider's
|
|
* range, which can result in the user not being able to move any of them.
|
|
* @param {Ext.slider.Thumb} topThumb The thumb to move to the top
|
|
*/
|
|
promoteThumb: function(topThumb) {
|
|
var thumbs = this.thumbs,
|
|
zIndex, thumb;
|
|
|
|
for (var i = 0, j = thumbs.length; i < j; i++) {
|
|
thumb = thumbs[i];
|
|
|
|
if (thumb == topThumb) {
|
|
zIndex = this.topThumbZIndex;
|
|
} else {
|
|
zIndex = '';
|
|
}
|
|
|
|
thumb.el.setStyle('zIndex', zIndex);
|
|
}
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-onRender'> // private override
|
|
</span> onRender : function() {
|
|
this.autoEl = {
|
|
cls: 'x-slider ' + (this.vertical ? 'x-slider-vert' : 'x-slider-horz'),
|
|
cn : {
|
|
cls: 'x-slider-end',
|
|
cn : {
|
|
cls:'x-slider-inner',
|
|
cn : [{tag:'a', cls:'x-slider-focus', href:"#", tabIndex: '-1', hidefocus:'on'}]
|
|
}
|
|
}
|
|
};
|
|
|
|
Ext.slider.MultiSlider.superclass.onRender.apply(this, arguments);
|
|
|
|
this.endEl = this.el.first();
|
|
this.innerEl = this.endEl.first();
|
|
this.focusEl = this.innerEl.child('.x-slider-focus');
|
|
|
|
//render each thumb
|
|
for (var i=0; i < this.thumbs.length; i++) {
|
|
this.thumbs[i].render();
|
|
}
|
|
|
|
//calculate the size of half a thumb
|
|
var thumb = this.innerEl.child('.x-slider-thumb');
|
|
this.halfThumb = (this.vertical ? thumb.getHeight() : thumb.getWidth()) / 2;
|
|
|
|
this.initEvents();
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-initEvents'> /**
|
|
</span> * @private
|
|
* Adds keyboard and mouse listeners on this.el. Ignores click events on the internal focus element.
|
|
* Creates a new DragTracker which is used to control what happens when the user drags the thumb around.
|
|
*/
|
|
initEvents : function(){
|
|
this.mon(this.el, {
|
|
scope : this,
|
|
mousedown: this.onMouseDown,
|
|
keydown : this.onKeyDown
|
|
});
|
|
|
|
this.focusEl.swallowEvent("click", true);
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-onMouseDown'> /**
|
|
</span> * @private
|
|
* Mousedown handler for the slider. If the clickToChange is enabled and the click was not on the draggable 'thumb',
|
|
* this calculates the new value of the slider and tells the implementation (Horizontal or Vertical) to move the thumb
|
|
* @param {Ext.EventObject} e The click event
|
|
*/
|
|
onMouseDown : function(e){
|
|
if(this.disabled){
|
|
return;
|
|
}
|
|
|
|
//see if the click was on any of the thumbs
|
|
var thumbClicked = false;
|
|
for (var i=0; i < this.thumbs.length; i++) {
|
|
thumbClicked = thumbClicked || e.target == this.thumbs[i].el.dom;
|
|
}
|
|
|
|
if (this.clickToChange && !thumbClicked) {
|
|
var local = this.innerEl.translatePoints(e.getXY());
|
|
this.onClickChange(local);
|
|
}
|
|
this.focus();
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-onClickChange'> /**
|
|
</span> * @private
|
|
* Moves the thumb to the indicated position. Note that a Vertical implementation is provided in Ext.slider.Vertical.
|
|
* Only changes the value if the click was within this.clickRange.
|
|
* @param {Object} local Object containing top and left values for the click event.
|
|
*/
|
|
onClickChange : function(local) {
|
|
if (local.top > this.clickRange[0] && local.top < this.clickRange[1]) {
|
|
//find the nearest thumb to the click event
|
|
var thumb = this.getNearest(local, 'left'),
|
|
index = thumb.index;
|
|
|
|
this.setValue(index, Ext.util.Format.round(this.reverseValue(local.left), this.decimalPrecision), undefined, true);
|
|
}
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-getNearest'> /**
|
|
</span> * @private
|
|
* Returns the nearest thumb to a click event, along with its distance
|
|
* @param {Object} local Object containing top and left values from a click event
|
|
* @param {String} prop The property of local to compare on. Use 'left' for horizontal sliders, 'top' for vertical ones
|
|
* @return {Object} The closest thumb object and its distance from the click event
|
|
*/
|
|
getNearest: function(local, prop) {
|
|
var localValue = prop == 'top' ? this.innerEl.getHeight() - local[prop] : local[prop],
|
|
clickValue = this.reverseValue(localValue),
|
|
nearestDistance = (this.maxValue - this.minValue) + 5, //add a small fudge for the end of the slider
|
|
index = 0,
|
|
nearest = null;
|
|
|
|
for (var i=0; i < this.thumbs.length; i++) {
|
|
var thumb = this.thumbs[i],
|
|
value = thumb.value,
|
|
dist = Math.abs(value - clickValue);
|
|
|
|
if (Math.abs(dist <= nearestDistance)) {
|
|
nearest = thumb;
|
|
index = i;
|
|
nearestDistance = dist;
|
|
}
|
|
}
|
|
return nearest;
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-onKeyDown'> /**
|
|
</span> * @private
|
|
* Handler for any keypresses captured by the slider. If the key is UP or RIGHT, the thumb is moved along to the right
|
|
* by this.keyIncrement. If DOWN or LEFT it is moved left. Pressing CTRL moves the slider to the end in either direction
|
|
* @param {Ext.EventObject} e The Event object
|
|
*/
|
|
onKeyDown : function(e){
|
|
/*
|
|
* The behaviour for keyboard handling with multiple thumbs is currently undefined.
|
|
* There's no real sane default for it, so leave it like this until we come up
|
|
* with a better way of doing it.
|
|
*/
|
|
if(this.disabled || this.thumbs.length !== 1){
|
|
e.preventDefault();
|
|
return;
|
|
}
|
|
var k = e.getKey(),
|
|
val;
|
|
switch(k){
|
|
case e.UP:
|
|
case e.RIGHT:
|
|
e.stopEvent();
|
|
val = e.ctrlKey ? this.maxValue : this.getValue(0) + this.keyIncrement;
|
|
this.setValue(0, val, undefined, true);
|
|
break;
|
|
case e.DOWN:
|
|
case e.LEFT:
|
|
e.stopEvent();
|
|
val = e.ctrlKey ? this.minValue : this.getValue(0) - this.keyIncrement;
|
|
this.setValue(0, val, undefined, true);
|
|
break;
|
|
default:
|
|
e.preventDefault();
|
|
}
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-doSnap'> /**
|
|
</span> * @private
|
|
* If using snapping, this takes a desired new value and returns the closest snapped
|
|
* value to it
|
|
* @param {Number} value The unsnapped value
|
|
* @return {Number} The value of the nearest snap target
|
|
*/
|
|
doSnap : function(value){
|
|
if (!(this.increment && value)) {
|
|
return value;
|
|
}
|
|
var newValue = value,
|
|
inc = this.increment,
|
|
m = value % inc;
|
|
if (m != 0) {
|
|
newValue -= m;
|
|
if (m * 2 >= inc) {
|
|
newValue += inc;
|
|
} else if (m * 2 < -inc) {
|
|
newValue -= inc;
|
|
}
|
|
}
|
|
return newValue.constrain(this.minValue, this.maxValue);
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-afterRender'> // private
|
|
</span> afterRender : function(){
|
|
Ext.slider.MultiSlider.superclass.afterRender.apply(this, arguments);
|
|
|
|
for (var i=0; i < this.thumbs.length; i++) {
|
|
var thumb = this.thumbs[i];
|
|
|
|
if (thumb.value !== undefined) {
|
|
var v = this.normalizeValue(thumb.value);
|
|
|
|
if (v !== thumb.value) {
|
|
// delete this.value;
|
|
this.setValue(i, v, false);
|
|
} else {
|
|
this.moveThumb(i, this.translateValue(v), false);
|
|
}
|
|
}
|
|
};
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-getRatio'> /**
|
|
</span> * @private
|
|
* Returns the ratio of pixels to mapped values. e.g. if the slider is 200px wide and maxValue - minValue is 100,
|
|
* the ratio is 2
|
|
* @return {Number} The ratio of pixels to mapped values
|
|
*/
|
|
getRatio : function(){
|
|
var w = this.innerEl.getWidth(),
|
|
v = this.maxValue - this.minValue;
|
|
return v == 0 ? w : (w/v);
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-normalizeValue'> /**
|
|
</span> * @private
|
|
* Returns a snapped, constrained value when given a desired value
|
|
* @param {Number} value Raw number value
|
|
* @return {Number} The raw value rounded to the correct d.p. and constrained within the set max and min values
|
|
*/
|
|
normalizeValue : function(v){
|
|
v = this.doSnap(v);
|
|
v = Ext.util.Format.round(v, this.decimalPrecision);
|
|
v = v.constrain(this.minValue, this.maxValue);
|
|
return v;
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-setMinValue'> /**
|
|
</span> * Sets the minimum value for the slider instance. If the current value is less than the
|
|
* minimum value, the current value will be changed.
|
|
* @param {Number} val The new minimum value
|
|
*/
|
|
setMinValue : function(val){
|
|
this.minValue = val;
|
|
var i = 0,
|
|
thumbs = this.thumbs,
|
|
len = thumbs.length,
|
|
t;
|
|
|
|
for(; i < len; ++i){
|
|
t = thumbs[i];
|
|
t.value = t.value < val ? val : t.value;
|
|
}
|
|
this.syncThumb();
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-setMaxValue'> /**
|
|
</span> * Sets the maximum value for the slider instance. If the current value is more than the
|
|
* maximum value, the current value will be changed.
|
|
* @param {Number} val The new maximum value
|
|
*/
|
|
setMaxValue : function(val){
|
|
this.maxValue = val;
|
|
var i = 0,
|
|
thumbs = this.thumbs,
|
|
len = thumbs.length,
|
|
t;
|
|
|
|
for(; i < len; ++i){
|
|
t = thumbs[i];
|
|
t.value = t.value > val ? val : t.value;
|
|
}
|
|
this.syncThumb();
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-setValue'> /**
|
|
</span> * Programmatically sets the value of the Slider. Ensures that the value is constrained within
|
|
* the minValue and maxValue.
|
|
* @param {Number} index Index of the thumb to move
|
|
* @param {Number} value The value to set the slider to. (This will be constrained within minValue and maxValue)
|
|
* @param {Boolean} animate Turn on or off animation, defaults to true
|
|
*/
|
|
setValue : function(index, v, animate, changeComplete) {
|
|
var thumb = this.thumbs[index],
|
|
el = thumb.el;
|
|
|
|
v = this.normalizeValue(v);
|
|
|
|
if (v !== thumb.value && this.fireEvent('beforechange', this, v, thumb.value, thumb) !== false) {
|
|
thumb.value = v;
|
|
if(this.rendered){
|
|
this.moveThumb(index, this.translateValue(v), animate !== false);
|
|
this.fireEvent('change', this, v, thumb);
|
|
if(changeComplete){
|
|
this.fireEvent('changecomplete', this, v, thumb);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-translateValue'> /**
|
|
</span> * @private
|
|
*/
|
|
translateValue : function(v) {
|
|
var ratio = this.getRatio();
|
|
return (v * ratio) - (this.minValue * ratio) - this.halfThumb;
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-reverseValue'> /**
|
|
</span> * @private
|
|
* Given a pixel location along the slider, returns the mapped slider value for that pixel.
|
|
* E.g. if we have a slider 200px wide with minValue = 100 and maxValue = 500, reverseValue(50)
|
|
* returns 200
|
|
* @param {Number} pos The position along the slider to return a mapped value for
|
|
* @return {Number} The mapped value for the given position
|
|
*/
|
|
reverseValue : function(pos){
|
|
var ratio = this.getRatio();
|
|
return (pos + (this.minValue * ratio)) / ratio;
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-moveThumb'> /**
|
|
</span> * @private
|
|
* @param {Number} index Index of the thumb to move
|
|
*/
|
|
moveThumb: function(index, v, animate){
|
|
var thumb = this.thumbs[index].el;
|
|
|
|
if(!animate || this.animate === false){
|
|
thumb.setLeft(v);
|
|
}else{
|
|
thumb.shift({left: v, stopFx: true, duration:.35});
|
|
}
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-focus'> // private
|
|
</span> focus : function(){
|
|
this.focusEl.focus(10);
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-onResize'> // private
|
|
</span> onResize : function(w, h){
|
|
var thumbs = this.thumbs,
|
|
len = thumbs.length,
|
|
i = 0;
|
|
|
|
/*
|
|
* If we happen to be animating during a resize, the position of the thumb will likely be off
|
|
* when the animation stops. As such, just stop any animations before syncing the thumbs.
|
|
*/
|
|
for(; i < len; ++i){
|
|
thumbs[i].el.stopFx();
|
|
}
|
|
// check to see if we're using an auto width
|
|
if(Ext.isNumber(w)){
|
|
this.innerEl.setWidth(w - (this.el.getPadding('l') + this.endEl.getPadding('r')));
|
|
}
|
|
this.syncThumb();
|
|
Ext.slider.MultiSlider.superclass.onResize.apply(this, arguments);
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-onDisable'> //private
|
|
</span> onDisable: function(){
|
|
Ext.slider.MultiSlider.superclass.onDisable.call(this);
|
|
|
|
for (var i=0; i < this.thumbs.length; i++) {
|
|
var thumb = this.thumbs[i],
|
|
el = thumb.el;
|
|
|
|
thumb.disable();
|
|
|
|
if(Ext.isIE){
|
|
//IE breaks when using overflow visible and opacity other than 1.
|
|
//Create a place holder for the thumb and display it.
|
|
var xy = el.getXY();
|
|
el.hide();
|
|
|
|
this.innerEl.addClass(this.disabledClass).dom.disabled = true;
|
|
|
|
if (!this.thumbHolder) {
|
|
this.thumbHolder = this.endEl.createChild({cls: 'x-slider-thumb ' + this.disabledClass});
|
|
}
|
|
|
|
this.thumbHolder.show().setXY(xy);
|
|
}
|
|
}
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-onEnable'> //private
|
|
</span> onEnable: function(){
|
|
Ext.slider.MultiSlider.superclass.onEnable.call(this);
|
|
|
|
for (var i=0; i < this.thumbs.length; i++) {
|
|
var thumb = this.thumbs[i],
|
|
el = thumb.el;
|
|
|
|
thumb.enable();
|
|
|
|
if (Ext.isIE) {
|
|
this.innerEl.removeClass(this.disabledClass).dom.disabled = false;
|
|
|
|
if (this.thumbHolder) this.thumbHolder.hide();
|
|
|
|
el.show();
|
|
this.syncThumb();
|
|
}
|
|
}
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-syncThumb'> /**
|
|
</span> * Synchronizes the thumb position to the proper proportion of the total component width based
|
|
* on the current slider {@link #value}. This will be called automatically when the Slider
|
|
* is resized by a layout, but if it is rendered auto width, this method can be called from
|
|
* another resize handler to sync the Slider if necessary.
|
|
*/
|
|
syncThumb : function() {
|
|
if (this.rendered) {
|
|
for (var i=0; i < this.thumbs.length; i++) {
|
|
this.moveThumb(i, this.translateValue(this.thumbs[i].value));
|
|
}
|
|
}
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-getValue'> /**
|
|
</span> * Returns the current value of the slider
|
|
* @param {Number} index The index of the thumb to return a value for
|
|
* @return {Number} The current value of the slider
|
|
*/
|
|
getValue : function(index) {
|
|
return this.thumbs[index].value;
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-getValues'> /**
|
|
</span> * Returns an array of values - one for the location of each thumb
|
|
* @return {Array} The set of thumb values
|
|
*/
|
|
getValues: function() {
|
|
var values = [];
|
|
|
|
for (var i=0; i < this.thumbs.length; i++) {
|
|
values.push(this.thumbs[i].value);
|
|
}
|
|
|
|
return values;
|
|
},
|
|
|
|
<span id='Ext-slider-MultiSlider-method-beforeDestroy'> // private
|
|
</span> beforeDestroy : function(){
|
|
var thumbs = this.thumbs;
|
|
for(var i = 0, len = thumbs.length; i < len; ++i){
|
|
thumbs[i].destroy();
|
|
thumbs[i] = null;
|
|
}
|
|
Ext.destroyMembers(this, 'endEl', 'innerEl', 'focusEl', 'thumbHolder');
|
|
Ext.slider.MultiSlider.superclass.beforeDestroy.call(this);
|
|
}
|
|
});
|
|
|
|
Ext.reg('multislider', Ext.slider.MultiSlider);
|
|
|
|
<span id='Ext-slider-SingleSlider'>/**
|
|
</span> * @class Ext.slider.SingleSlider
|
|
* @extends Ext.slider.MultiSlider
|
|
* Slider which supports vertical or horizontal orientation, keyboard adjustments,
|
|
* configurable snapping, axis clicking and animation. Can be added as an item to
|
|
* any container. Example usage:
|
|
<pre><code>
|
|
new Ext.slider.SingleSlider({
|
|
renderTo: Ext.getBody(),
|
|
width: 200,
|
|
value: 50,
|
|
increment: 10,
|
|
minValue: 0,
|
|
maxValue: 100
|
|
});
|
|
</code></pre>
|
|
* The class Ext.slider.SingleSlider is aliased to Ext.Slider for backwards compatibility.
|
|
*/
|
|
Ext.slider.SingleSlider = Ext.extend(Ext.slider.MultiSlider, {
|
|
<span id='Ext-slider-SingleSlider-method-constructor'> constructor: function(config) {
|
|
</span> config = config || {};
|
|
|
|
Ext.applyIf(config, {
|
|
values: [config.value || 0]
|
|
});
|
|
|
|
Ext.slider.SingleSlider.superclass.constructor.call(this, config);
|
|
},
|
|
|
|
<span id='Ext-slider-SingleSlider-method-getValue'> /**
|
|
</span> * Returns the current value of the slider
|
|
* @return {Number} The current value of the slider
|
|
*/
|
|
getValue: function() {
|
|
//just returns the value of the first thumb, which should be the only one in a single slider
|
|
return Ext.slider.SingleSlider.superclass.getValue.call(this, 0);
|
|
},
|
|
|
|
<span id='Ext-slider-SingleSlider-method-setValue'> /**
|
|
</span> * Programmatically sets the value of the Slider. Ensures that the value is constrained within
|
|
* the minValue and maxValue.
|
|
* @param {Number} value The value to set the slider to. (This will be constrained within minValue and maxValue)
|
|
* @param {Boolean} animate Turn on or off animation, defaults to true
|
|
*/
|
|
setValue: function(value, animate) {
|
|
var args = Ext.toArray(arguments),
|
|
len = args.length;
|
|
|
|
//this is to maintain backwards compatiblity for sliders with only one thunb. Usually you must pass the thumb
|
|
//index to setValue, but if we only have one thumb we inject the index here first if given the multi-slider
|
|
//signature without the required index. The index will always be 0 for a single slider
|
|
if (len == 1 || (len <= 3 && typeof arguments[1] != 'number')) {
|
|
args.unshift(0);
|
|
}
|
|
|
|
return Ext.slider.SingleSlider.superclass.setValue.apply(this, args);
|
|
},
|
|
|
|
<span id='Ext-slider-SingleSlider-method-syncThumb'> /**
|
|
</span> * Synchronizes the thumb position to the proper proportion of the total component width based
|
|
* on the current slider {@link #value}. This will be called automatically when the Slider
|
|
* is resized by a layout, but if it is rendered auto width, this method can be called from
|
|
* another resize handler to sync the Slider if necessary.
|
|
*/
|
|
syncThumb : function() {
|
|
return Ext.slider.SingleSlider.superclass.syncThumb.apply(this, [0].concat(arguments));
|
|
},
|
|
|
|
<span id='Ext-slider-SingleSlider-method-getNearest'> // private
|
|
</span> getNearest : function(){
|
|
// Since there's only 1 thumb, it's always the nearest
|
|
return this.thumbs[0];
|
|
}
|
|
});
|
|
|
|
//backwards compatibility
|
|
Ext.Slider = Ext.slider.SingleSlider;
|
|
|
|
Ext.reg('slider', Ext.slider.SingleSlider);
|
|
|
|
// private class to support vertical sliders
|
|
Ext.slider.Vertical = {
|
|
onResize : function(w, h){
|
|
this.innerEl.setHeight(h - (this.el.getPadding('t') + this.endEl.getPadding('b')));
|
|
this.syncThumb();
|
|
},
|
|
|
|
getRatio : function(){
|
|
var h = this.innerEl.getHeight(),
|
|
v = this.maxValue - this.minValue;
|
|
return h/v;
|
|
},
|
|
|
|
moveThumb: function(index, v, animate) {
|
|
var thumb = this.thumbs[index],
|
|
el = thumb.el;
|
|
|
|
if (!animate || this.animate === false) {
|
|
el.setBottom(v);
|
|
} else {
|
|
el.shift({bottom: v, stopFx: true, duration:.35});
|
|
}
|
|
},
|
|
|
|
onClickChange : function(local) {
|
|
if (local.left > this.clickRange[0] && local.left < this.clickRange[1]) {
|
|
var thumb = this.getNearest(local, 'top'),
|
|
index = thumb.index,
|
|
value = this.minValue + this.reverseValue(this.innerEl.getHeight() - local.top);
|
|
|
|
this.setValue(index, Ext.util.Format.round(value, this.decimalPrecision), undefined, true);
|
|
}
|
|
}
|
|
};
|
|
|
|
//private class to support vertical dragging of thumbs within a slider
|
|
Ext.slider.Thumb.Vertical = {
|
|
getNewValue: function() {
|
|
var slider = this.slider,
|
|
innerEl = slider.innerEl,
|
|
pos = innerEl.translatePoints(this.tracker.getXY()),
|
|
bottom = innerEl.getHeight() - pos.top;
|
|
|
|
return slider.minValue + Ext.util.Format.round(bottom / slider.getRatio(), slider.decimalPrecision);
|
|
}
|
|
};
|
|
</pre>
|
|
</body>
|
|
</html>
|