]>
Commit | Line | Data |
---|---|---|
f0cfe83e AD |
1 | require({cache:{ |
2 | 'url:dijit/form/templates/HorizontalSlider.html':"<table class=\"dijit dijitReset dijitSlider dijitSliderH\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" rules=\"none\" data-dojo-attach-event=\"onkeypress:_onKeyPress,onkeyup:_onKeyUp\"\n\trole=\"presentation\"\n\t><tr class=\"dijitReset\"\n\t\t><td class=\"dijitReset\" colspan=\"2\"></td\n\t\t><td data-dojo-attach-point=\"topDecoration\" class=\"dijitReset dijitSliderDecoration dijitSliderDecorationT dijitSliderDecorationH\"></td\n\t\t><td class=\"dijitReset\" colspan=\"2\"></td\n\t></tr\n\t><tr class=\"dijitReset\"\n\t\t><td class=\"dijitReset dijitSliderButtonContainer dijitSliderButtonContainerH\"\n\t\t\t><div class=\"dijitSliderDecrementIconH\" style=\"display:none\" data-dojo-attach-point=\"decrementButton\"><span class=\"dijitSliderButtonInner\">-</span></div\n\t\t></td\n\t\t><td class=\"dijitReset\"\n\t\t\t><div class=\"dijitSliderBar dijitSliderBumper dijitSliderBumperH dijitSliderLeftBumper\" data-dojo-attach-event=\"press:_onClkDecBumper\"></div\n\t\t></td\n\t\t><td class=\"dijitReset\"\n\t\t\t><input data-dojo-attach-point=\"valueNode\" type=\"hidden\" ${!nameAttrSetting}\n\t\t\t/><div class=\"dijitReset dijitSliderBarContainerH\" role=\"presentation\" data-dojo-attach-point=\"sliderBarContainer\"\n\t\t\t\t><div role=\"presentation\" data-dojo-attach-point=\"progressBar\" class=\"dijitSliderBar dijitSliderBarH dijitSliderProgressBar dijitSliderProgressBarH\" data-dojo-attach-event=\"press:_onBarClick\"\n\t\t\t\t\t><div class=\"dijitSliderMoveable dijitSliderMoveableH\"\n\t\t\t\t\t\t><div data-dojo-attach-point=\"sliderHandle,focusNode\" class=\"dijitSliderImageHandle dijitSliderImageHandleH\" data-dojo-attach-event=\"press:_onHandleClick\" role=\"slider\"></div\n\t\t\t\t\t></div\n\t\t\t\t></div\n\t\t\t\t><div role=\"presentation\" data-dojo-attach-point=\"remainingBar\" class=\"dijitSliderBar dijitSliderBarH dijitSliderRemainingBar dijitSliderRemainingBarH\" data-dojo-attach-event=\"press:_onBarClick\"></div\n\t\t\t></div\n\t\t></td\n\t\t><td class=\"dijitReset\"\n\t\t\t><div class=\"dijitSliderBar dijitSliderBumper dijitSliderBumperH dijitSliderRightBumper\" data-dojo-attach-event=\"press:_onClkIncBumper\"></div\n\t\t></td\n\t\t><td class=\"dijitReset dijitSliderButtonContainer dijitSliderButtonContainerH\"\n\t\t\t><div class=\"dijitSliderIncrementIconH\" style=\"display:none\" data-dojo-attach-point=\"incrementButton\"><span class=\"dijitSliderButtonInner\">+</span></div\n\t\t></td\n\t></tr\n\t><tr class=\"dijitReset\"\n\t\t><td class=\"dijitReset\" colspan=\"2\"></td\n\t\t><td data-dojo-attach-point=\"containerNode,bottomDecoration\" class=\"dijitReset dijitSliderDecoration dijitSliderDecorationB dijitSliderDecorationH\"></td\n\t\t><td class=\"dijitReset\" colspan=\"2\"></td\n\t></tr\n></table>\n"}}); | |
3 | define("dijit/form/HorizontalSlider", [ | |
4 | "dojo/_base/array", // array.forEach | |
5 | "dojo/_base/declare", // declare | |
6 | "dojo/dnd/move", | |
7 | "dojo/_base/event", // event.stop | |
8 | "dojo/_base/fx", // fx.animateProperty | |
9 | "dojo/dom-geometry", // domGeometry.position | |
10 | "dojo/dom-style", // domStyle.getComputedStyle | |
11 | "dojo/keys", // keys.DOWN_ARROW keys.END keys.HOME keys.LEFT_ARROW keys.PAGE_DOWN keys.PAGE_UP keys.RIGHT_ARROW keys.UP_ARROW | |
12 | "dojo/_base/lang", // lang.hitch | |
13 | "dojo/sniff", // has("ie") has("mozilla") | |
14 | "dojo/dnd/Moveable", // Moveable | |
15 | "dojo/dnd/Mover", // Mover Mover.prototype.destroy.apply | |
16 | "dojo/query", // query | |
17 | "dojo/mouse", // mouse.wheel | |
18 | "../registry", // registry.findWidgets | |
19 | "../focus", // focus.focus() | |
20 | "../typematic", | |
21 | "./Button", | |
22 | "./_FormValueWidget", | |
23 | "../_Container", | |
24 | "dojo/text!./templates/HorizontalSlider.html" | |
25 | ], function(array, declare, move, event, fx, domGeometry, domStyle, keys, lang, has, Moveable, Mover, query, mouse, | |
26 | registry, focus, typematic, Button, _FormValueWidget, _Container, template){ | |
27 | ||
28 | // module: | |
29 | // dijit/form/HorizontalSlider | |
30 | ||
31 | ||
32 | var _SliderMover = declare("dijit.form._SliderMover", Mover, { | |
33 | onMouseMove: function(e){ | |
34 | var widget = this.widget; | |
35 | var abspos = widget._abspos; | |
36 | if(!abspos){ | |
37 | abspos = widget._abspos = domGeometry.position(widget.sliderBarContainer, true); | |
38 | widget._setPixelValue_ = lang.hitch(widget, "_setPixelValue"); | |
39 | widget._isReversed_ = widget._isReversed(); | |
40 | } | |
41 | var pixelValue = e[widget._mousePixelCoord] - abspos[widget._startingPixelCoord]; | |
42 | widget._setPixelValue_(widget._isReversed_ ? (abspos[widget._pixelCount]-pixelValue) : pixelValue, abspos[widget._pixelCount], false); | |
43 | }, | |
44 | ||
45 | destroy: function(e){ | |
46 | Mover.prototype.destroy.apply(this, arguments); | |
47 | var widget = this.widget; | |
48 | widget._abspos = null; | |
49 | widget._setValueAttr(widget.value, true); | |
50 | } | |
51 | }); | |
52 | ||
53 | var HorizontalSlider = declare("dijit.form.HorizontalSlider", [_FormValueWidget, _Container], { | |
54 | // summary: | |
55 | // A form widget that allows one to select a value with a horizontally draggable handle | |
56 | ||
57 | templateString: template, | |
58 | ||
59 | // Overrides FormValueWidget.value to indicate numeric value | |
60 | value: 0, | |
61 | ||
62 | // showButtons: [const] Boolean | |
63 | // Show increment/decrement buttons at the ends of the slider? | |
64 | showButtons: true, | |
65 | ||
66 | // minimum: [const] Integer | |
67 | // The minimum value the slider can be set to. | |
68 | minimum: 0, | |
69 | ||
70 | // maximum: [const] Integer | |
71 | // The maximum value the slider can be set to. | |
72 | maximum: 100, | |
73 | ||
74 | // discreteValues: Integer | |
75 | // If specified, indicates that the slider handle has only 'discreteValues' possible positions, | |
76 | // and that after dragging the handle, it will snap to the nearest possible position. | |
77 | // Thus, the slider has only 'discreteValues' possible values. | |
78 | // | |
79 | // For example, if minimum=10, maxiumum=30, and discreteValues=3, then the slider handle has | |
80 | // three possible positions, representing values 10, 20, or 30. | |
81 | // | |
82 | // If discreteValues is not specified or if it's value is higher than the number of pixels | |
83 | // in the slider bar, then the slider handle can be moved freely, and the slider's value will be | |
84 | // computed/reported based on pixel position (in this case it will likely be fractional, | |
85 | // such as 123.456789). | |
86 | discreteValues: Infinity, | |
87 | ||
88 | // pageIncrement: Integer | |
89 | // If discreteValues is also specified, this indicates the amount of clicks (ie, snap positions) | |
90 | // that the slider handle is moved via pageup/pagedown keys. | |
91 | // If discreteValues is not specified, it indicates the number of pixels. | |
92 | pageIncrement: 2, | |
93 | ||
94 | // clickSelect: Boolean | |
95 | // If clicking the slider bar changes the value or not | |
96 | clickSelect: true, | |
97 | ||
98 | // slideDuration: Number | |
99 | // The time in ms to take to animate the slider handle from 0% to 100%, | |
100 | // when clicking the slider bar to make the handle move. | |
101 | slideDuration: registry.defaultDuration, | |
102 | ||
103 | // Map widget attributes to DOMNode attributes. | |
104 | _setIdAttr: "", // Override _FormWidget which sends id to focusNode | |
105 | ||
106 | baseClass: "dijitSlider", | |
107 | ||
108 | // Apply CSS classes to up/down arrows and handle per mouse state | |
109 | cssStateNodes: { | |
110 | incrementButton: "dijitSliderIncrementButton", | |
111 | decrementButton: "dijitSliderDecrementButton", | |
112 | focusNode: "dijitSliderThumb" | |
113 | }, | |
114 | ||
115 | _mousePixelCoord: "pageX", | |
116 | _pixelCount: "w", | |
117 | _startingPixelCoord: "x", | |
118 | _handleOffsetCoord: "left", | |
119 | _progressPixelSize: "width", | |
120 | ||
121 | _onKeyUp: function(/*Event*/ e){ | |
122 | if(this.disabled || this.readOnly || e.altKey || e.ctrlKey || e.metaKey){ return; } | |
123 | this._setValueAttr(this.value, true); | |
124 | }, | |
125 | ||
126 | _onKeyPress: function(/*Event*/ e){ | |
127 | if(this.disabled || this.readOnly || e.altKey || e.ctrlKey || e.metaKey){ return; } | |
128 | switch(e.charOrCode){ | |
129 | case keys.HOME: | |
130 | this._setValueAttr(this.minimum, false); | |
131 | break; | |
132 | case keys.END: | |
133 | this._setValueAttr(this.maximum, false); | |
134 | break; | |
135 | // this._descending === false: if ascending vertical (min on top) | |
136 | // (this._descending || this.isLeftToRight()): if left-to-right horizontal or descending vertical | |
137 | case ((this._descending || this.isLeftToRight()) ? keys.RIGHT_ARROW : keys.LEFT_ARROW): | |
138 | case (this._descending === false ? keys.DOWN_ARROW : keys.UP_ARROW): | |
139 | case (this._descending === false ? keys.PAGE_DOWN : keys.PAGE_UP): | |
140 | this.increment(e); | |
141 | break; | |
142 | case ((this._descending || this.isLeftToRight()) ? keys.LEFT_ARROW : keys.RIGHT_ARROW): | |
143 | case (this._descending === false ? keys.UP_ARROW : keys.DOWN_ARROW): | |
144 | case (this._descending === false ? keys.PAGE_UP : keys.PAGE_DOWN): | |
145 | this.decrement(e); | |
146 | break; | |
147 | default: | |
148 | return; | |
149 | } | |
150 | event.stop(e); | |
151 | }, | |
152 | ||
153 | _onHandleClick: function(e){ | |
154 | if(this.disabled || this.readOnly){ return; } | |
155 | if(!has("ie")){ | |
156 | // make sure you get focus when dragging the handle | |
157 | // (but don't do on IE because it causes a flicker on mouse up (due to blur then focus) | |
158 | focus.focus(this.sliderHandle); | |
159 | } | |
160 | event.stop(e); | |
161 | }, | |
162 | ||
163 | _isReversed: function(){ | |
164 | // summary: | |
165 | // Returns true if direction is from right to left | |
166 | // tags: | |
167 | // protected extension | |
168 | return !this.isLeftToRight(); | |
169 | }, | |
170 | ||
171 | _onBarClick: function(e){ | |
172 | if(this.disabled || this.readOnly || !this.clickSelect){ return; } | |
173 | focus.focus(this.sliderHandle); | |
174 | event.stop(e); | |
175 | var abspos = domGeometry.position(this.sliderBarContainer, true); | |
176 | var pixelValue = e[this._mousePixelCoord] - abspos[this._startingPixelCoord]; | |
177 | this._setPixelValue(this._isReversed() ? (abspos[this._pixelCount] - pixelValue) : pixelValue, abspos[this._pixelCount], true); | |
178 | this._movable.onMouseDown(e); | |
179 | }, | |
180 | ||
181 | _setPixelValue: function(/*Number*/ pixelValue, /*Number*/ maxPixels, /*Boolean?*/ priorityChange){ | |
182 | if(this.disabled || this.readOnly){ return; } | |
183 | var count = this.discreteValues; | |
184 | if(count <= 1 || count == Infinity){ count = maxPixels; } | |
185 | count--; | |
186 | var pixelsPerValue = maxPixels / count; | |
187 | var wholeIncrements = Math.round(pixelValue / pixelsPerValue); | |
188 | this._setValueAttr(Math.max(Math.min((this.maximum-this.minimum)*wholeIncrements/count + this.minimum, this.maximum), this.minimum), priorityChange); | |
189 | }, | |
190 | ||
191 | _setValueAttr: function(/*Number*/ value, /*Boolean?*/ priorityChange){ | |
192 | // summary: | |
193 | // Hook so set('value', value) works. | |
194 | this._set("value", value); | |
195 | this.valueNode.value = value; | |
196 | this.focusNode.setAttribute("aria-valuenow", value); | |
197 | this.inherited(arguments); | |
198 | var percent = (value - this.minimum) / (this.maximum - this.minimum); | |
199 | var progressBar = (this._descending === false) ? this.remainingBar : this.progressBar; | |
200 | var remainingBar = (this._descending === false) ? this.progressBar : this.remainingBar; | |
201 | if(this._inProgressAnim && this._inProgressAnim.status != "stopped"){ | |
202 | this._inProgressAnim.stop(true); | |
203 | } | |
204 | if(priorityChange && this.slideDuration > 0 && progressBar.style[this._progressPixelSize]){ | |
205 | // animate the slider | |
206 | var _this = this; | |
207 | var props = {}; | |
208 | var start = parseFloat(progressBar.style[this._progressPixelSize]); | |
209 | var duration = this.slideDuration * (percent-start/100); | |
210 | if(duration == 0){ return; } | |
211 | if(duration < 0){ duration = 0 - duration; } | |
212 | props[this._progressPixelSize] = { start: start, end: percent*100, units:"%" }; | |
213 | this._inProgressAnim = fx.animateProperty({ node: progressBar, duration: duration, | |
214 | onAnimate: function(v){ | |
215 | remainingBar.style[_this._progressPixelSize] = (100 - parseFloat(v[_this._progressPixelSize])) + "%"; | |
216 | }, | |
217 | onEnd: function(){ | |
218 | delete _this._inProgressAnim; | |
219 | }, | |
220 | properties: props | |
221 | }); | |
222 | this._inProgressAnim.play(); | |
223 | }else{ | |
224 | progressBar.style[this._progressPixelSize] = (percent*100) + "%"; | |
225 | remainingBar.style[this._progressPixelSize] = ((1-percent)*100) + "%"; | |
226 | } | |
227 | }, | |
228 | ||
229 | _bumpValue: function(signedChange, /*Boolean?*/ priorityChange){ | |
230 | if(this.disabled || this.readOnly){ return; } | |
231 | var s = domStyle.getComputedStyle(this.sliderBarContainer); | |
232 | var c = domGeometry.getContentBox(this.sliderBarContainer, s); | |
233 | var count = this.discreteValues; | |
234 | if(count <= 1 || count == Infinity){ count = c[this._pixelCount]; } | |
235 | count--; | |
236 | var value = (this.value - this.minimum) * count / (this.maximum - this.minimum) + signedChange; | |
237 | if(value < 0){ value = 0; } | |
238 | if(value > count){ value = count; } | |
239 | value = value * (this.maximum - this.minimum) / count + this.minimum; | |
240 | this._setValueAttr(value, priorityChange); | |
241 | }, | |
242 | ||
243 | _onClkBumper: function(val){ | |
244 | if(this.disabled || this.readOnly || !this.clickSelect){ return; } | |
245 | this._setValueAttr(val, true); | |
246 | }, | |
247 | ||
248 | _onClkIncBumper: function(){ | |
249 | this._onClkBumper(this._descending === false ? this.minimum : this.maximum); | |
250 | }, | |
251 | ||
252 | _onClkDecBumper: function(){ | |
253 | this._onClkBumper(this._descending === false ? this.maximum : this.minimum); | |
254 | }, | |
255 | ||
256 | decrement: function(/*Event*/ e){ | |
257 | // summary: | |
258 | // Decrement slider | |
259 | // tags: | |
260 | // private | |
261 | this._bumpValue(e.charOrCode == keys.PAGE_DOWN ? -this.pageIncrement : -1); | |
262 | }, | |
263 | ||
264 | increment: function(/*Event*/ e){ | |
265 | // summary: | |
266 | // Increment slider | |
267 | // tags: | |
268 | // private | |
269 | this._bumpValue(e.charOrCode == keys.PAGE_UP ? this.pageIncrement : 1); | |
270 | }, | |
271 | ||
272 | _mouseWheeled: function(/*Event*/ evt){ | |
273 | // summary: | |
274 | // Event handler for mousewheel where supported | |
275 | event.stop(evt); | |
276 | this._bumpValue(evt.wheelDelta < 0 ? -1 : 1, true); // negative scroll acts like a decrement | |
277 | }, | |
278 | ||
279 | startup: function(){ | |
280 | if(this._started){ return; } | |
281 | ||
282 | array.forEach(this.getChildren(), function(child){ | |
283 | if(this[child.container] != this.containerNode){ | |
284 | this[child.container].appendChild(child.domNode); | |
285 | } | |
286 | }, this); | |
287 | ||
288 | this.inherited(arguments); | |
289 | }, | |
290 | ||
291 | _typematicCallback: function(/*Number*/ count, /*Object*/ button, /*Event*/ e){ | |
292 | if(count == -1){ | |
293 | this._setValueAttr(this.value, true); | |
294 | }else{ | |
295 | this[(button == (this._descending? this.incrementButton : this.decrementButton)) ? "decrement" : "increment"](e); | |
296 | } | |
297 | }, | |
298 | ||
299 | buildRendering: function(){ | |
300 | this.inherited(arguments); | |
301 | if(this.showButtons){ | |
302 | this.incrementButton.style.display=""; | |
303 | this.decrementButton.style.display=""; | |
304 | } | |
305 | ||
306 | // find any associated label element and add to slider focusnode. | |
307 | var label = query('label[for="'+this.id+'"]'); | |
308 | if(label.length){ | |
309 | if(!label[0].id){ label[0].id = this.id + "_label"; } | |
310 | this.focusNode.setAttribute("aria-labelledby", label[0].id); | |
311 | } | |
312 | ||
313 | this.focusNode.setAttribute("aria-valuemin", this.minimum); | |
314 | this.focusNode.setAttribute("aria-valuemax", this.maximum); | |
315 | }, | |
316 | ||
317 | postCreate: function(){ | |
318 | this.inherited(arguments); | |
319 | ||
320 | if(this.showButtons){ | |
321 | this.own( | |
322 | typematic.addMouseListener(this.decrementButton, this, "_typematicCallback", 25, 500), | |
323 | typematic.addMouseListener(this.incrementButton, this, "_typematicCallback", 25, 500) | |
324 | ); | |
325 | } | |
326 | this.connect(this.domNode, mouse.wheel, "_mouseWheeled"); | |
327 | ||
328 | // define a custom constructor for a SliderMover that points back to me | |
329 | var mover = declare(_SliderMover, { | |
330 | widget: this | |
331 | }); | |
332 | this._movable = new Moveable(this.sliderHandle, {mover: mover}); | |
333 | ||
334 | this._layoutHackIE7(); | |
335 | }, | |
336 | ||
337 | destroy: function(){ | |
338 | this._movable.destroy(); | |
339 | if(this._inProgressAnim && this._inProgressAnim.status != "stopped"){ | |
340 | this._inProgressAnim.stop(true); | |
341 | } | |
342 | this.inherited(arguments); | |
343 | } | |
344 | }); | |
345 | ||
346 | HorizontalSlider._Mover = _SliderMover; // for monkey patching | |
347 | ||
348 | return HorizontalSlider; | |
349 | }); |