- Author:
- David Nickerson <nickerso@users.sourceforge.net>
- Date:
- 2009-07-16 02:00:03+12:00
- Desc:
- the starting point for the HH tutorial example
- Permanent Source URI:
- https://models.fieldml.org/workspace/a1/rawfile/f6a8f90307388eb4b040ee3566b84d88b59247f7/dojo-presentation/js/dojo/dojox/form/RangeSlider.js
dojo.provide("dojox.form.RangeSlider");
dojo.require("dijit.form.Slider");
dojo.require("dojox.fx");
dojo.declare(
"dojox.form._RangeSliderMixin",
null,
{
value: [0,100],
postCreate: function(){
this.inherited(arguments);
// we sort the values!
// TODO: re-think, how to set the value
if(this._isReversed()){
this.value.sort(function(a, b){
return b-a;
});
}
else{
this.value.sort(function(a, b){
return a-b;
});
}
// define a custom constructor for a SliderMoverMax that points back to me
var _self = this;
var mover = function(){
dijit.form._SliderMoverMax.apply(this, arguments);
this.widget = _self;
};
dojo.extend(mover, dijit.form._SliderMoverMax.prototype);
this._movableMax = new dojo.dnd.Moveable(this.sliderHandleMax,{mover: mover});
dijit.setWaiState(this.focusNodeMax, "valuemin", this.minimum);
dijit.setWaiState(this.focusNodeMax, "valuemax", this.maximum);
// a dnd for the bar!
var barMover = function(){
dijit.form._SliderBarMover.apply(this, arguments);
this.widget = _self;
};
dojo.extend(barMover, dijit.form._SliderBarMover.prototype);
this._movableBar = new dojo.dnd.Moveable(this.progressBar,{mover: barMover});
},
destroy: function(){
this.inherited(arguments);
this._movableMax.destroy();
this._movableBar.destroy();
},
_onKeyPress: function(/*Event*/ e){
if(this.disabled || this.readOnly || e.altKey || e.ctrlKey){ return; }
var focusedEl = e.currentTarget;
var minSelected = false;
var maxSelected = false;
var signedChange;
if (focusedEl == this.sliderHandle){
minSelected = true;
}
else if(focusedEl == this.progressBar){
maxSelected = true;
minSelected = true;
}
else if(focusedEl == this.sliderHandleMax){
maxSelected = true;
}
switch(e.keyCode){
case dojo.keys.HOME:
this.setValue(this.minimum, true, maxSelected);
break;
case dojo.keys.END:
this.setValue(this.maximum, true, maxSelected);
break;
// this._descending === false: if ascending vertical (min on top)
// (this._descending || this.isLeftToRight()): if left-to-right horizontal or descending vertical
case ((this._descending || this.isLeftToRight()) ? dojo.keys.RIGHT_ARROW : dojo.keys.LEFT_ARROW):
case (this._descending === false ? dojo.keys.DOWN_ARROW : dojo.keys.UP_ARROW):
case (this._descending === false ? dojo.keys.PAGE_DOWN : dojo.keys.PAGE_UP):
if (minSelected && maxSelected){
signedChange = Array();
signedChange[0] = {'change': e.keyCode == dojo.keys.PAGE_UP ? this.pageIncrement : 1, 'useMaxValue': true};
signedChange[1] = {'change': e.keyCode == dojo.keys.PAGE_UP ? this.pageIncrement : 1, 'useMaxValue': false};
this._bumpValue(signedChange);
}
else if (minSelected){
this._bumpValue(e.keyCode == dojo.keys.PAGE_UP ? this.pageIncrement : 1, true);
}
else if (maxSelected){
this._bumpValue(e.keyCode == dojo.keys.PAGE_UP ? this.pageIncrement : 1);
}
break;
case ((this._descending || this.isLeftToRight()) ? dojo.keys.LEFT_ARROW : dojo.keys.RIGHT_ARROW):
case (this._descending === false ? dojo.keys.UP_ARROW : dojo.keys.DOWN_ARROW):
case (this._descending === false ? dojo.keys.PAGE_UP : dojo.keys.PAGE_DOWN):
if (minSelected && maxSelected){
signedChange = Array();
signedChange[0] = {'change': e.keyCode == dojo.keys.PAGE_DOWN ? -this.pageIncrement : -1, 'useMaxValue': false};
signedChange[1] = {'change': e.keyCode == dojo.keys.PAGE_DOWN ? -this.pageIncrement : -1, 'useMaxValue': true};
this._bumpValue(signedChange);
}
else if (minSelected){
this._bumpValue(e.keyCode == dojo.keys.PAGE_DOWN ? -this.pageIncrement : -1);
}
else if (maxSelected){
this._bumpValue(e.keyCode == dojo.keys.PAGE_DOWN ? -this.pageIncrement : -1, true);
}
break;
default:
dijit.form._FormValueWidget.prototype._onKeyPress.apply(this, arguments);
this.inherited(arguments);
return;
}
dojo.stopEvent(e);
},
_onHandleClickMax: function(e){
if(this.disabled || this.readOnly){ return; }
if(!dojo.isIE){
// make sure you get focus when dragging the handle
// (but don't do on IE because it causes a flicker on mouse up (due to blur then focus)
dijit.focus(this.sliderHandleMax);
}
dojo.stopEvent(e);
},
_onClkIncBumper: function(){
this.setValue(this._descending === false ? this.minimum : this.maximum, true, true);
},
_bumpValue: function(signedChange, useMaxValue){
// we pass an array to setValue when signedChange is an array
if(!dojo.isArray(signedChange)){
value = this._getBumpValue(signedChange, useMaxValue);
}
else{
value = Array();
value[0] = this._getBumpValue(signedChange[0]['change'], signedChange[0]['useMaxValue']);
value[1] = this._getBumpValue(signedChange[1]['change'], signedChange[1]['useMaxValue']);
}
this.setValue(value, true, !dojo.isArray(signedChange) && ((signedChange > 0 && !useMaxValue) || (useMaxValue && signedChange < 0)));
},
_getBumpValue: function(signedChange, useMaxValue){
var s = dojo.getComputedStyle(this.sliderBarContainer);
var c = dojo._getContentBox(this.sliderBarContainer, s);
var count = this.discreteValues;
if(count <= 1 || count == Infinity){ count = c[this._pixelCount]; }
count--;
var myValue = !useMaxValue ? this.value[0] : this.value[1];
if((this._isReversed() && signedChange < 0) || (signedChange > 0 && !this._isReversed())){
myValue = !useMaxValue ? this.value[1] : this.value[0];
}
var value = (myValue - this.minimum) * count / (this.maximum - this.minimum) + signedChange;
if(value < 0){ value = 0; }
if(value > count){ value = count; }
return value * (this.maximum - this.minimum) / count + this.minimum;
},
_onBarClick: function(e){
if(this.disabled || this.readOnly){ return; }
if(!dojo.isIE){
// make sure you get focus when dragging the handle
// (but don't do on IE because it causes a flicker on mouse up (due to blur then focus)
dijit.focus(this.progressBar);
}
dojo.stopEvent(e);
},
_onRemainingBarClick: function(e){
if(this.disabled || this.readOnly){ return; }
if(!dojo.isIE){
// make sure you get focus when dragging the handle
// (but don't do on IE because it causes a flicker on mouse up (due to blur then focus)
dijit.focus(this.progressBar);
}
// now we set the min/max-value of the slider!
var abspos = dojo.coords(this.sliderBarContainer, true);
var bar = dojo.coords(this.progressBar, true);
var relMousePos = e[this._mousePixelCoord] - abspos[this._startingPixelCoord];
var leftPos = bar[this._startingPixelCount];
var rightPos = bar[this._startingPixelCount] + bar[this._pixelCount];
var isMaxVal = this._isReversed() ? relMousePos <= leftPos : relMousePos >= rightPos;
this._setPixelValue(this._isReversed() ? (abspos[this._pixelCount]-relMousePos) : relMousePos, abspos[this._pixelCount], true, isMaxVal);
dojo.stopEvent(e);
},
_setPixelValue: function(/*Number*/ pixelValue, /*Number*/ maxPixels, /*Boolean*/ priorityChange, /*Boolean*/ isMaxVal){
if(this.disabled || this.readOnly){ return; }
var myValue = this._getValueByPixelValue(pixelValue, maxPixels);
this.setValue(myValue, priorityChange, isMaxVal);
},
_getValueByPixelValue: function(/*Number*/ pixelValue, /*Number*/ maxPixels){
pixelValue = pixelValue < 0 ? 0 : maxPixels < pixelValue ? maxPixels : pixelValue;
var count = this.discreteValues;
if(count <= 1 || count == Infinity){ count = maxPixels; }
count--;
var pixelsPerValue = maxPixels / count;
var wholeIncrements = Math.round(pixelValue / pixelsPerValue);
return (this.maximum-this.minimum)*wholeIncrements/count + this.minimum;
},
setValue: function(/*Array or Number*/ value, /*Boolean, optional*/ priorityChange, /*Boolean, optional*/ isMaxVal){
// we pass an array, when we move the slider with the bar
var actValue = this.value;
if(!dojo.isArray(value)){
if(isMaxVal){
if (this._isReversed()){
actValue[0] = value;
}
else{
actValue[1] = value;
}
}
else{
if(this._isReversed()){
actValue[1] = value;
}
else{
actValue[0] = value;
}
}
}
else{
actValue = value;
}
// we have to reset this values. don't know the reason for that
this._lastValueReported = "";
this.valueNode.value = this.value = value = actValue;
dijit.setWaiState(this.focusNode, "valuenow", actValue[0]);
dijit.setWaiState(this.focusNodeMax, "valuenow", actValue[1]);
if(this._isReversed()){
this.value.sort(function(a, b){
return b-a;
});
}
else{
this.value.sort(function(a, b){
return a-b;
});
}
// not calling the setValue-function of dijit.form.Slider, but the super-super-class (needed for the onchange-event!)
dijit.form._FormValueWidget.prototype.setValue.apply(this, arguments);
this._printSliderBar(priorityChange, isMaxVal);
},
_printSliderBar: function(priorityChange, isMaxVal){
var percentMin = (this.value[0] - this.minimum) / (this.maximum - this.minimum);
var percentMax = (this.value[1] - this.minimum) / (this.maximum - this.minimum);
var percentMinSave = percentMin;
if(percentMin > percentMax){
percentMin = percentMax;
percentMax = percentMinSave;
}
var sliderHandleVal = this._isReversed() ? ((1-percentMin)*100) : (percentMin * 100);
var sliderHandleMaxVal = this._isReversed() ? ((1-percentMax)*100) : (percentMax * 100);
var progressBarVal = this._isReversed() ? ((1-percentMax)*100) : (percentMin * 100);
if (priorityChange && this.slideDuration > 0 && this.progressBar.style[this._progressPixelSize]){
// animate the slider
var percent = isMaxVal ? percentMax : percentMin;
var _this = this;
var props = {};
var start = parseFloat(this.progressBar.style[this._handleOffsetCoord]);
var duration = this.slideDuration / 10; // * (percent-start/100);
if(duration === 0){ return; }
if(duration < 0){ duration = 0 - duration; }
var propsHandle = {};
var propsHandleMax = {};
var propsBar = {};
// hui, a lot of animations :-)
propsHandle[this._handleOffsetCoord] = { start: this.sliderHandle.style[this._handleOffsetCoord], end: sliderHandleVal, units:"%"};
propsHandleMax[this._handleOffsetCoord] = { start: this.sliderHandleMax.style[this._handleOffsetCoord], end: sliderHandleMaxVal, units:"%"};
propsBar[this._handleOffsetCoord] = { start: this.progressBar.style[this._handleOffsetCoord], end: progressBarVal, units:"%"};
propsBar[this._progressPixelSize] = { start: this.progressBar.style[this._progressPixelSize], end: (percentMax - percentMin) * 100, units:"%"};
var animHandle = dojo.animateProperty({node: this.sliderHandle,duration: duration, properties: propsHandle});
var animHandleMax = dojo.animateProperty({node: this.sliderHandleMax,duration: duration, properties: propsHandleMax});
var animBar = dojo.animateProperty({node: this.progressBar,duration: duration, properties: propsBar});
var animCombine = dojo.fx.combine([animHandle, animHandleMax, animBar]);
animCombine.play();
}
else{
this.sliderHandle.style[this._handleOffsetCoord] = sliderHandleVal + "%";
this.sliderHandleMax.style[this._handleOffsetCoord] = sliderHandleMaxVal + "%";
this.progressBar.style[this._handleOffsetCoord] = progressBarVal + "%";
this.progressBar.style[this._progressPixelSize] = ((percentMax - percentMin) * 100) + "%";
}
}
});
dojo.declare("dijit.form._SliderMoverMax",
dijit.form._SliderMover,
{
onMouseMove: function(e){
var widget = this.widget;
var abspos = widget._abspos;
if(!abspos){
abspos = widget._abspos = dojo.coords(widget.sliderBarContainer, true);
widget._setPixelValue_ = dojo.hitch(widget, "_setPixelValue");
widget._isReversed_ = widget._isReversed();
}
var pixelValue = e[widget._mousePixelCoord] - abspos[widget._startingPixelCoord];
widget._setPixelValue_(widget._isReversed_ ? (abspos[widget._pixelCount]-pixelValue) : pixelValue, abspos[widget._pixelCount], false, true);
},
destroy: function(e){
dojo.dnd.Mover.prototype.destroy.apply(this, arguments);
var widget = this.widget;
widget._abspos = null;
widget.setValue(widget.value, true);
}
});
dojo.declare("dijit.form._SliderBarMover",
dojo.dnd.Mover,
{
onMouseMove: function(e){
var widget = this.widget;
if(widget.disabled || widget.readOnly){ return; }
var abspos = widget._abspos;
var bar = widget._bar;
var mouseOffset = widget._mouseOffset;
if(!abspos){
abspos = widget._abspos = dojo.coords(widget.sliderBarContainer, true);
widget._setPixelValue_ = dojo.hitch(widget, "_setPixelValue");
widget._getValueByPixelValue_ = dojo.hitch(widget, "_getValueByPixelValue");
widget._isReversed_ = widget._isReversed();
}
if(!bar){
bar = widget._bar = dojo.coords(widget.progressBar, true);
}
if(!mouseOffset){
mouseOffset = widget._mouseOffset = e[widget._mousePixelCoord] - abspos[widget._startingPixelCoord] - bar[widget._startingPixelCount];
}
var pixelValueMin = e[widget._mousePixelCoord] - abspos[widget._startingPixelCoord] - mouseOffset;
var pixelValueMax = e[widget._mousePixelCoord] - abspos[widget._startingPixelCoord] - mouseOffset + bar[widget._pixelCount];
// we don't narrow the slider when it reaches the bumper!
// maybe there is a simpler way
var pixelValues = [pixelValueMin, pixelValueMax];
pixelValues.sort(function(a, b){
return a-b;
});
if(pixelValues[0] <= 0){
pixelValues[0] = 0;
pixelValues[1] = bar[widget._pixelCount];
}
if(pixelValues[1] >= abspos[widget._pixelCount]){
pixelValues[1] = abspos[widget._pixelCount];
pixelValues[0] = abspos[widget._pixelCount] - bar[widget._pixelCount];
}
// getting the real values by pixel
var myValues = [widget._getValueByPixelValue(widget._isReversed_ ? (abspos[widget._pixelCount] - pixelValues[0]) : pixelValues[0], abspos[widget._pixelCount]),
widget._getValueByPixelValue(widget._isReversed_ ? (abspos[widget._pixelCount] - pixelValues[1]) : pixelValues[1], abspos[widget._pixelCount])];
// and setting the value of the widget
widget.setValue(myValues, false, false);
},
destroy: function(e){
dojo.dnd.Mover.prototype.destroy.apply(this, arguments);
var widget = this.widget;
widget._abspos = null;
widget._bar = null;
widget._mouseOffset = null;
widget.setValue(widget.value, true);
}
});
dojo.declare(
"dojox.form.HorizontalRangeSlider",
[dijit.form.HorizontalSlider, dojox.form._RangeSliderMixin],
{
templatePath: dojo.moduleUrl('dojox.form','resources/HorizontalRangeSlider.html')
}
);
dojo.declare(
"dojox.form.VerticalRangeSlider",
[dijit.form.VerticalSlider, dojox.form._RangeSliderMixin],
{
// summary
// A form widget that allows one to select a range with two vertically draggable images
templatePath: dojo.moduleUrl('dojox.form','resources/VerticalRangeSlider.html')
}
);