blob: 9b5b0adbdd89eeb70941dcd0b5cdc0db38735612 [file] [log] [blame]
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.widget.Slider");
// load dependencies
dojo.require("dojo.event.*");
dojo.require("dojo.dnd.*");
// dojo.dnd.* doesn't include this package, because it's not in __package__.js
dojo.require("dojo.dnd.HtmlDragMove");
dojo.require("dojo.widget.*");
dojo.require("dojo.html.layout");
dojo.widget.defineWidget (
"dojo.widget.Slider",
dojo.widget.HtmlWidget,
{
// summary
// Slider Widget.
//
// The slider widget comes in three forms:
// 1. Base Slider widget which supports movement in x and y dimensions
// 2. Vertical Slider (SliderVertical) widget which supports movement
// only in the y dimension.
// 3. Horizontal Slider (SliderHorizontal) widget which supports movement
// only in the x dimension.
//
// The key objects in the widget are:
// - a container div which displays a bar in the background (Slider object)
// - a handle inside the container div, which represents the value
// (sliderHandle DOM node)
// - the object which moves the handle (_handleMove is of type
// SliderDragMoveSource)
//
// The values for the slider are calculated by grouping pixels together,
// based on the number of values to be represented by the slider.
// The number of pixels in a group is called the _valueSize
// e.g. if slider is 150 pixels long, and is representing the values
// 0,1,...10 then pixels are grouped into lots of 15 (_valueSize), where:
// value 0 maps to pixels 0 - 7
// 1 8 - 22
// 2 23 - 37 etc.
// The accuracy of the slider is limited to the number of pixels
// (i.e tiles > pixels will result in the slider not being able to
// represent some values).
// minimumX: Number
// minimum value to be represented by slider in the horizontal direction
minimumX: 0,
// minimumY: Number
// minimum value to be represented by slider in the vertical direction
minimumY: 0,
// maximumX: Number
// maximum value to be represented by slider in the horizontal direction
maximumX: 10,
// maximumY: Number
// maximum value to be represented by slider in the vertical direction
maximumY: 10,
// snapValuesX: Number
// number of values to be represented by slider in the horizontal direction
// =0 means no snapping
snapValuesX: 0,
// snapValuesY: Number
// number of values to be represented by slider in the vertical direction
// =0 means no snapping
snapValuesY: 0,
// should the handle snap to the grid or remain where it was dragged to?
// FIXME: snapToGrid=false is logically in conflict with setting snapValuesX and snapValuesY
_snapToGrid: true,
// isEnableX: Boolean
// enables (disables) sliding in the horizontal direction
isEnableX: true,
// isEnableY: Boolean
// enables (disables) sliding in the vertical direction
isEnableY: true,
// value size (pixels) in the x dimension
_valueSizeX: 0.0,
// value size (pixels) in the y dimension
_valueSizeY: 0.0,
// left most edge of constraining container (pixels) in the X dimension
_minX: 0,
// top most edge of constraining container (pixels) in the Y dimension
_minY: 0,
// constrained slider size (pixels) in the x dimension
_constraintWidth: 0,
// constrained slider size (pixels) in the y dimension
_constraintHeight: 0,
// progress image right clip value (pixels) in the X dimension
_clipLeft: 0,
// progress image left clip value (pixels) in the X dimension
_clipRight: 0,
// progress image top clip value (pixels) in the Y dimension
_clipTop: 0,
// progress image bottom clip value (pixels) in the Y dimension
_clipBottom: 0,
// half the size of the slider handle (pixels) in the X dimension
_clipXdelta: 0,
// half the size of the slider handle (pixels) in the Y dimension
_clipYdelta: 0,
// initialValueX: Number
// initial value in the x dimension
initialValueX: 0,
// initialValueY: Number
// initial value in the y dimension
initialValueY: 0,
// flipX: Boolean
// values decrease in the X dimension
flipX: false,
// flipY: Boolean
// values decrease in the Y dimension
flipY: false,
// clickSelect: Boolean
// enables (disables) the user to click on the slider to set the position
clickSelect: true,
// activeDrag: Boolean
// disables (enables) the value to change while you are dragging, or just after drag finishes
activeDrag: false,
templateCssPath: dojo.uri.dojoUri ("src/widget/templates/Slider.css"),
templatePath: dojo.uri.dojoUri ("src/widget/templates/Slider.html"),
// This is set to true when a drag is started, so that it is not confused
// with a click
_isDragInProgress: false,
// default user style attributes
// bottomButtonSrc: String
// down arrow graphic URL
bottomButtonSrc: dojo.uri.dojoUri("src/widget/templates/images/slider_down_arrow.png"),
// topButtonSrc: String
// up arrow graphic URL
topButtonSrc: dojo.uri.dojoUri("src/widget/templates/images/slider_up_arrow.png"),
// leftButtonSrc: String
// left arrow graphic URL
leftButtonSrc: dojo.uri.dojoUri("src/widget/templates/images/slider_left_arrow.png"),
// rightButtonSrc: String
// right arrow graphic URL
rightButtonSrc: dojo.uri.dojoUri("src/widget/templates/images/slider_right_arrow.png"),
// backgroundSrc: String
// slider background graphic URL
backgroundSrc: dojo.uri.dojoUri("src/widget/templates/images/blank.gif"),
// progressBackgroundSrc: String
// slider background graphic URL to overlay the normal background to show progress
progressBackgroundSrc: dojo.uri.dojoUri("src/widget/templates/images/blank.gif"),
// backgroundSize: String
// sizing style attributes for the background image
backgroundSize: "width:200px;height:200px;",
// backgroundStyle: String
// style attributes (other than sizing) for the background image
backgroundStyle: "",
// buttonStyleX: String
// style attributes for the left and right arrow images
buttonStyleX: "",
// buttonStyleY: String
// style attributes for the up and down arrow images
buttonStyleY: "",
// handleStyle: String
// style attributes for the moveable slider image
handleStyle: "",
// handleSrc: String
// moveable slider graphic URL
handleSrc: dojo.uri.dojoUri("src/widget/templates/images/slider-button.png"),
// showButtons: Boolean
// show (don't show) the arrow buttons
showButtons: true,
_eventCount: 0,
_typamaticTimer: null,
_typamaticFunction: null,
// defaultTimeout: Number
// number of milliseconds before a held key or button becomes typematic
defaultTimeout: 500,
// timeoutChangeRate: Number
// fraction of time used to change the typematic timer between events
// 1.0 means that each typematic event fires at defaultTimeout intervals
// < 1.0 means that each typematic event fires at an increasing faster rate
timeoutChangeRate: 0.90,
_currentTimeout: this.defaultTimeout,
// does the keyboard related stuff
_handleKeyEvents: function(/*Event*/ evt){
if(!evt.key){ return; }
if(!evt.ctrlKey && !evt.altKey){
switch(evt.key){
case evt.KEY_LEFT_ARROW:
dojo.event.browser.stopEvent(evt);
this._leftButtonPressed(evt);
return;
case evt.KEY_RIGHT_ARROW:
dojo.event.browser.stopEvent(evt);
this._rightButtonPressed(evt);
return;
case evt.KEY_DOWN_ARROW:
dojo.event.browser.stopEvent(evt);
this._bottomButtonPressed(evt);
return;
case evt.KEY_UP_ARROW:
dojo.event.browser.stopEvent(evt);
this._topButtonPressed(evt);
return;
}
}
this._eventCount++;
},
_pressButton: function(/*DomNode*/ buttonNode){
buttonNode.className = buttonNode.className.replace("Outset","Inset");
},
_releaseButton: function(/*DomNode*/ buttonNode){
buttonNode.className = buttonNode.className.replace("Inset","Outset");
},
_buttonPressed: function(/*Event*/ evt, /*DomNode*/ buttonNode){
this._setFocus();
if(typeof evt == "object"){
if(this._typamaticTimer != null){
if(this._typamaticNode == buttonNode){
return;
}
clearTimeout(this._typamaticTimer);
}
this._buttonReleased(null);
this._eventCount++;
this._typamaticTimer = null;
this._currentTimeout = this.defaultTimeout;
dojo.event.browser.stopEvent(evt);
}else if (evt != this._eventCount){
this._buttonReleased(null);
return false;
}
if (buttonNode == this.leftButtonNode && this.isEnableX){
this._snapX(dojo.html.getPixelValue (this.sliderHandleNode,"left") - this._valueSizeX);
}
else if (buttonNode == this.rightButtonNode && this.isEnableX){
this._snapX(dojo.html.getPixelValue (this.sliderHandleNode,"left") + this._valueSizeX);
}
else if (buttonNode == this.topButtonNode && this.isEnableY){
this._snapY(dojo.html.getPixelValue (this.sliderHandleNode,"top") - this._valueSizeY);
}
else if (buttonNode == this.bottomButtonNode && this.isEnableY){
this._snapY(dojo.html.getPixelValue (this.sliderHandleNode,"top") + this._valueSizeY);
}
else {
return false;
}
this._pressButton(buttonNode);
this.notifyListeners();
this._typamaticNode = buttonNode;
this._typamaticTimer = dojo.lang.setTimeout(this, "_buttonPressed", this._currentTimeout, this._eventCount, buttonNode);
this._currentTimeout = Math.round(this._currentTimeout * this.timeoutChangeRate);
return false;
},
_bottomButtonPressed: function(/*Event*/ evt){
return this._buttonPressed(evt,this.bottomButtonNode);
},
// IE sends these events when rapid clicking, mimic an extra single click
_bottomButtonDoubleClicked: function(/*Event*/ evt){
var rc = this._bottomButtonPressed(evt);
dojo.lang.setTimeout( this, "_buttonReleased", 50, null);
return rc;
},
_topButtonPressed: function(/*Event*/ evt){
return this._buttonPressed(evt,this.topButtonNode);
},
// IE sends these events when rapid clicking, mimic an extra single click
_topButtonDoubleClicked: function(/*Event*/ evt){
var rc = this._topButtonPressed(evt);
dojo.lang.setTimeout( this, "_buttonReleased", 50, null);
return rc;
},
_leftButtonPressed: function(/*Event*/ evt){
return this._buttonPressed(evt,this.leftButtonNode);
},
// IE sends these events when rapid clicking, mimic an extra single click
_leftButtonDoubleClicked: function(/*Event*/ evt){
var rc = this._leftButtonPressed(evt);
dojo.lang.setTimeout( this, "_buttonReleased", 50, null);
return rc;
},
_rightButtonPressed: function(/*Event*/ evt){
return this._buttonPressed(evt,this.rightButtonNode);
},
// IE sends these events when rapid clicking, mimic an extra single click
_rightButtonDoubleClicked: function(/*Event*/ evt){
var rc = this._rightButtonPressed(evt);
dojo.lang.setTimeout( this, "_buttonReleased", 50, null);
return rc;
},
_buttonReleased: function(/*Event*/ evt){
if(typeof evt == "object" && evt != null && typeof evt.keyCode != "undefined" && evt.keyCode != null){
var keyCode = evt.keyCode;
switch(keyCode){
case evt.KEY_LEFT_ARROW:
case evt.KEY_RIGHT_ARROW:
case evt.KEY_DOWN_ARROW:
case evt.KEY_UP_ARROW:
dojo.event.browser.stopEvent(evt);
break;
}
}
this._releaseButton(this.topButtonNode);
this._releaseButton(this.bottomButtonNode);
this._releaseButton(this.leftButtonNode);
this._releaseButton(this.rightButtonNode);
this._eventCount++;
if(this._typamaticTimer != null){
clearTimeout(this._typamaticTimer);
}
this._typamaticTimer = null;
this._currentTimeout = this.defaultTimeout;
},
_mouseWheeled: function(/*Event*/ evt){
var scrollAmount = 0;
if(typeof evt.wheelDelta == 'number'){ // IE
scrollAmount = evt.wheelDelta;
}else if (typeof evt.detail == 'number'){ // Mozilla+Firefox
scrollAmount = -evt.detail;
}
if (this.isEnableY){
if(scrollAmount > 0){
this._topButtonPressed(evt);
this._buttonReleased(evt);
}else if (scrollAmount < 0){
this._bottomButtonPressed(evt);
this._buttonReleased(evt);
}
} else if (this.isEnableX){
if(scrollAmount > 0){
this._rightButtonPressed(evt);
this._buttonReleased(evt);
}else if (scrollAmount < 0){
this._leftButtonPressed(evt);
this._buttonReleased(evt);
}
}
},
_discardEvent: function(/*Event*/ evt){
dojo.event.browser.stopEvent(evt);
},
_setFocus: function(){
if (this.focusNode.focus){
this.focusNode.focus();
}
},
// This function is called when the template is loaded
fillInTemplate: function (/*Object*/ args, /*Object*/ frag)
{
var source = this.getFragNodeRef(frag);
dojo.html.copyStyle(this.domNode, source);
// the user's style for the widget might include border and padding
// unfortunately, border isn't supported for inline elements
// so I get to fake everyone out by setting the border and padding
// of the outer table cells
var padding = this.domNode.style.padding;
if (dojo.lang.isString(padding) && padding != "" && padding != "0px" && padding != "0px 0px 0px 0px"){
this.topBorderNode.style.padding =
this.bottomBorderNode.style.padding = padding;
this.topBorderNode.style.paddingBottom = "0px";
this.bottomBorderNode.style.paddingTop = "0px";
this.rightBorderNode.style.paddingRight = this.domNode.style.paddingRight;
this.leftBorderNode.style.paddingLeft= this.domNode.style.paddingLeft;
this.domNode.style.padding = "0px 0px 0px 0px";
}
var borderWidth = this.domNode.style.borderWidth;
if (dojo.lang.isString(borderWidth) && borderWidth != "" && borderWidth != "0px" && borderWidth != "0px 0px 0px 0px"){
this.topBorderNode.style.borderStyle =
this.rightBorderNode.style.borderStyle =
this.bottomBorderNode.style.borderStyle =
this.leftBorderNode.style.borderStyle =
this.domNode.style.borderStyle;
this.topBorderNode.style.borderColor =
this.rightBorderNode.style.borderColor =
this.bottomBorderNode.style.borderColor =
this.leftBorderNode.style.borderColor =
this.domNode.style.borderColor;
this.topBorderNode.style.borderWidth =
this.bottomBorderNode.style.borderWidth = borderWidth;
this.topBorderNode.style.borderBottomWidth = "0px";
this.bottomBorderNode.style.borderTopWidth = "0px";
this.rightBorderNode.style.borderRightWidth = this.domNode.style.borderRightWidth;
this.leftBorderNode.style.borderLeftWidth = this.domNode.style.borderLeftWidth;
this.domNode.style.borderWidth = "0px 0px 0px 0px";
}
// dojo.debug ("fillInTemplate - className = " + this.domNode.className);
// setup drag-n-drop for the sliderHandle
this._handleMove = new dojo.widget._SliderDragMoveSource (this.sliderHandleNode);
this._handleMove.setParent (this);
if (this.clickSelect){
dojo.event.connect (this.constrainingContainerNode, "onmousedown", this, "_onClick");
}
if (this.isEnableX){
this.setValueX (!isNaN(this.initialValueX) ? this.initialValueX : (!isNaN(this.minimumX) ? this.minimumX : 0));
}
if (!this.isEnableX || !this.showButtons){
this.rightButtonNode.style.width = "1px"; // allow the border to show
this.rightButtonNode.style.visibility = "hidden";
this.leftButtonNode.style.width = "1px"; // allow the border to show
this.leftButtonNode.style.visibility = "hidden";
}
if (this.isEnableY){
this.setValueY (!isNaN(this.initialValueY) ? this.initialValueY : (!isNaN(this.minimumY) ? this.minimumY : 0));
}
if (!this.isEnableY || !this.showButtons){
this.bottomButtonNode.style.width = "1px"; // allow the border to show
this.bottomButtonNode.style.visibility = "hidden";
this.topButtonNode.style.width = "1px"; // allow the border to show
this.topButtonNode.style.visibility = "hidden";
}
if(this.focusNode.addEventListener){
// dojo.event.connect() doesn't seem to work with DOMMouseScroll
this.focusNode.addEventListener('DOMMouseScroll', dojo.lang.hitch(this, "_mouseWheeled"), false); // Mozilla + Firefox + Netscape
}
},
// move the X value to the closest allowable value
_snapX: function(/*Number*/ x){
if (x < 0){ x = 0; }
else if (x > this._constraintWidth){ x = this._constraintWidth; }
else {
var selectedValue = Math.round (x / this._valueSizeX);
x = Math.round (selectedValue * this._valueSizeX);
}
this.sliderHandleNode.style.left = x + "px";
if (this.flipX){
this._clipLeft = x + this._clipXdelta;
} else {
this._clipRight = x + this._clipXdelta;
}
this.progressBackgroundNode.style.clip = "rect("+this._clipTop+"px,"+this._clipRight+"px,"+this._clipBottom+"px,"+this._clipLeft+"px)";
},
// compute _valueSizeX & _constraintWidth & default snapValuesX
_calc_valueSizeX: function (){
var constrainingCtrBox = dojo.html.getContentBox(this.constrainingContainerNode);
var sliderHandleBox = dojo.html.getContentBox(this.sliderHandleNode);
if (isNaN(constrainingCtrBox.width) || isNaN(sliderHandleBox.width) || constrainingCtrBox.width <= 0 || sliderHandleBox.width <= 0){
return false;
}
this._constraintWidth = constrainingCtrBox.width
+ dojo.html.getPadding(this.constrainingContainerNode).width
- sliderHandleBox.width;
if (this.flipX){
this._clipLeft = this._clipRight = constrainingCtrBox.width;
} else {
this._clipLeft = this._clipRight = 0;
}
this._clipXdelta = sliderHandleBox.width >> 1;
if (!this.isEnableY){
this._clipTop = 0;
this._clipBottom = constrainingCtrBox.height;
}
if (this._constraintWidth <= 0){ return false; }
if (this.snapValuesX == 0){
this.snapValuesX = this._constraintWidth + 1;
}
this._valueSizeX = this._constraintWidth / (this.snapValuesX - 1);
return true;
},
// summary
// move the handle horizontally to the specified value
setValueX: function (/*Number*/ value){
if (0.0 == this._valueSizeX){
if (this._calc_valueSizeX () == false){
dojo.lang.setTimeout(this, "setValueX", 100, value);
return;
}
}
if (isNaN(value)){
value = 0;
}
if (value > this.maximumX){
value = this.maximumX;
}
else if (value < this.minimumX){
value = this.minimumX;
}
var pixelPercent = (value-this.minimumX) / (this.maximumX-this.minimumX);
if (this.flipX){
pixelPercent = 1.0 - pixelPercent;
}
this._snapX (pixelPercent * this._constraintWidth);
this.notifyListeners();
},
// summary
// return the X value that the matches the position of the handle
getValueX: function (){
var pixelPercent = dojo.html.getPixelValue (this.sliderHandleNode,"left") / this._constraintWidth;
if (this.flipX){
pixelPercent = 1.0 - pixelPercent;
}
return Math.round (pixelPercent * (this.snapValuesX-1)) * ((this.maximumX-this.minimumX) / (this.snapValuesX-1)) + this.minimumX;
},
// move the Y value to the closest allowable value
_snapY: function (/*Number*/ y){
if (y < 0){ y = 0; }
else if (y > this._constraintHeight){ y = this._constraintHeight; }
else {
var selectedValue = Math.round (y / this._valueSizeY);
y = Math.round (selectedValue * this._valueSizeY);
}
this.sliderHandleNode.style.top = y + "px";
if (this.flipY){
this._clipTop = y + this._clipYdelta;
} else {
this._clipBottom = y + this._clipYdelta;
}
this.progressBackgroundNode.style.clip = "rect("+this._clipTop+"px,"+this._clipRight+"px,"+this._clipBottom+"px,"+this._clipLeft+"px)";
},
// compute _valueSizeY & _constraintHeight & default snapValuesY
_calc_valueSizeY: function (){
var constrainingCtrBox = dojo.html.getContentBox(this.constrainingContainerNode);
var sliderHandleBox = dojo.html.getContentBox(this.sliderHandleNode);
if (isNaN(constrainingCtrBox.height) || isNaN(sliderHandleBox.height) || constrainingCtrBox.height <= 0 || sliderHandleBox.height <= 0){
return false;
}
this._constraintHeight = constrainingCtrBox.height
+ dojo.html.getPadding(this.constrainingContainerNode).height
- sliderHandleBox.height;
if (this.flipY){
this._clipTop = this._clipBottom = constrainingCtrBox.height;
} else {
this._clipTop = this._clipBottom = 0;
}
this._clipYdelta = sliderHandleBox.height >> 1;
if (!this.isEnableX){
this._clipLeft = 0;
this._clipRight = constrainingCtrBox.width;
}
if (this._constraintHeight <= 0){ return false; }
if (this.snapValuesY == 0){
this.snapValuesY = this._constraintHeight + 1;
}
this._valueSizeY = this._constraintHeight / (this.snapValuesY - 1);
return true;
},
// summary
// move the handle vertically to the specified value
setValueY: function (/*Number*/ value){
if (0.0 == this._valueSizeY){
if (this._calc_valueSizeY () == false){
dojo.lang.setTimeout(this, "setValueY", 100, value);
return;
}
}
if (isNaN(value)){
value = 0;
}
if (value > this.maximumY){
value = this.maximumY;
}
else if (value < this.minimumY){
value = this.minimumY;
}
var pixelPercent = (value-this.minimumY) / (this.maximumY-this.minimumY);
if (this.flipY){
pixelPercent = 1.0 - pixelPercent;
}
this._snapY (pixelPercent * this._constraintHeight);
this.notifyListeners();
},
// summary
// return the Y value that the matches the position of the handle
getValueY: function (){
var pixelPercent = dojo.html.getPixelValue (this.sliderHandleNode,"top") / this._constraintHeight;
if (this.flipY){
pixelPercent = 1.0 - pixelPercent;
}
return Math.round (pixelPercent * (this.snapValuesY-1)) * ((this.maximumY-this.minimumY) / (this.snapValuesY-1)) + this.minimumY;
},
// set the position of the handle
_onClick: function(/*Event*/ evt){
if (this._isDragInProgress){
return;
}
var parent = dojo.html.getAbsolutePosition(this.constrainingContainerNode, true, dojo.html.boxSizing.MARGIN_BOX);
var content = dojo.html.getContentBox(this._handleMove.domNode);
if (this.isEnableX){
var x = evt.pageX - parent.x - (content.width >> 1);
this._snapX(x);
}
if (this.isEnableY){
var y = evt.pageY - parent.y - (content.height >> 1);
this._snapY(y);
}
this.notifyListeners();
},
// summary
// method to invoke user's onValueChanged method
notifyListeners: function(){
this.onValueChanged(this.getValueX(), this.getValueY());
},
// summary
// empty method to be overridden by user
onValueChanged: function(/*Number*/ x, /*Number*/ y){
}
}
);
dojo.widget.defineWidget (
"dojo.widget.SliderHorizontal",
dojo.widget.Slider,
{
// summary
// the horizontal slider widget subclass
isEnableX: true,
isEnableY: false,
// initialValue: Number
// sets initialValueX.
// TODO: should be called "value". Also, common attributes between SliderHorizontal/SliderVertical
// should be consolidated to Slider1D base class
initialValue: "",
// snapValues: Number
// sets snapValuesX
snapValues: "",
// minimum: Number
// sets minimumX
minimum: "",
// maximum: Number
// sets maximumX
maximum: "",
// buttonStyle: String
// sets buttonStyleX
buttonStyle: "",
backgroundSize: "height:10px;width:200px;",
backgroundSrc: dojo.uri.dojoUri("src/widget/templates/images/slider-bg.gif"),
// flip: Boolean
// sets flipX
flip: false,
postMixInProperties: function(){
dojo.widget.SliderHorizontal.superclass.postMixInProperties.apply(this, arguments);
if (!isNaN(parseFloat(this.initialValue))){
this.initialValueX = parseFloat(this.initialValue);
}
if (!isNaN(parseFloat(this.minimum))){
this.minimumX = parseFloat(this.minimum);
}
if (!isNaN(parseFloat(this.maximum))){
this.maximumX = parseFloat(this.maximum);
}
if (!isNaN(parseInt(this.snapValues))){
this.snapValuesX = parseInt(this.snapValues);
}
if (dojo.lang.isString(this.buttonStyle) && this.buttonStyle != ""){
this.buttonStyleX = this.buttonStyle;
}
if (dojo.lang.isBoolean(this.flip)){
this.flipX = this.flip;
}
},
notifyListeners: function(){
this.onValueChanged(this.getValueX());
},
// summary
// wrapper for getValueX()
getValue: function (){
return this.getValueX ();
},
// summary
// wrapper for setValueX()
setValue: function (/*Number*/ value){
this.setValueX (value);
},
onValueChanged: function(/*Number*/ value){
}
}
);
/* ------------------------------------------------------------------------- */
dojo.widget.defineWidget (
"dojo.widget.SliderVertical",
dojo.widget.Slider,
{
// summary
// the vertical slider widget subclass
isEnableX: false,
isEnableY: true,
// initialValue: Number
// sets initialValueY
initialValue: "",
// snapValues: Number
// sets snapValuesY
snapValues: "",
// minimum: Number
// sets minimumY
minimum: "",
// Number
// maximum: sets maximumY
maximum: "",
// buttonStyle: String
// sets buttonStyleY
buttonStyle: "",
backgroundSize: "width:10px;height:200px;",
backgroundSrc: dojo.uri.dojoUri("src/widget/templates/images/slider-bg-vert.gif"),
// flip: Boolean
// sets flipY
flip: false,
postMixInProperties: function(){
dojo.widget.SliderVertical.superclass.postMixInProperties.apply(this, arguments);
if (!isNaN(parseFloat(this.initialValue))){
this.initialValueY = parseFloat(this.initialValue);
}
if (!isNaN(parseFloat(this.minimum))){
this.minimumY = parseFloat(this.minimum);
}
if (!isNaN(parseFloat(this.maximum))){
this.maximumY = parseFloat(this.maximum);
}
if (!isNaN(parseInt(this.snapValues))){
this.snapValuesY = parseInt(this.snapValues);
}
if (dojo.lang.isString(this.buttonStyle) && this.buttonStyle != ""){
this.buttonStyleY = this.buttonStyle;
}
if (dojo.lang.isBoolean(this.flip)){
this.flipY = this.flip;
}
},
notifyListeners: function(){
this.onValueChanged(this.getValueY());
},
// summary
// wrapper for getValueY()
getValue: function (){
return this.getValueY ();
},
// summary
// wrapper for setValueY()
setValue: function (/*Number*/ value){
this.setValueY (value);
},
onValueChanged: function(/*Number*/ value){
}
}
);
/* ------------------------------------------------------------------------- */
/**
* This class extends the HtmlDragMoveSource class to provide
* features for the slider handle.
*/
dojo.declare (
"dojo.widget._SliderDragMoveSource",
dojo.dnd.HtmlDragMoveSource,
{
slider: null,
/** Setup the handle for drag
* Extends dojo.dnd.HtmlDragMoveSource by creating a SliderDragMoveSource */
onDragStart: function(/*Event*/ evt){
this.slider._isDragInProgress = true;
var dragObj = this.createDragMoveObject ();
this.slider.notifyListeners();
return dragObj;
},
onDragEnd: function(/*Event*/ evt){
this.slider._isDragInProgress = false;
this.slider.notifyListeners();
},
createDragMoveObject: function (){
//dojo.debug ("SliderDragMoveSource#createDragMoveObject - " + this.slider);
var dragObj = new dojo.widget._SliderDragMoveObject (this.dragObject, this.type);
dragObj.slider = this.slider;
// this code copied from dojo.dnd.HtmlDragSource#onDragStart
if (this.dragClass){
dragObj.dragClass = this.dragClass;
}
return dragObj;
},
setParent: function (/*Widget*/ slider){
this.slider = slider;
}
});
/* ------------------------------------------------------------------------- */
/**
* This class extends the HtmlDragMoveObject class to provide
* features for the slider handle.
*/
dojo.declare (
"dojo.widget._SliderDragMoveObject",
dojo.dnd.HtmlDragMoveObject,
{
// reference to dojo.widget.Slider
slider: null,
/** Moves the node to follow the mouse.
* Extends functon HtmlDragObject by adding functionality to snap handle
* to a discrete value */
onDragMove: function(/*Event*/ evt){
this.updateDragOffset ();
if (this.slider.isEnableX){
var x = this.dragOffset.x + evt.pageX;
this.slider._snapX(x);
}
if (this.slider.isEnableY){
var y = this.dragOffset.y + evt.pageY;
this.slider._snapY(y);
}
if(this.slider.activeDrag){
this.slider.notifyListeners();
}
}
});