/[colormatch]/trunk/slider.js
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /trunk/slider.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Sat Oct 2 23:24:01 2004 UTC (19 years, 6 months ago) by dpavlin
File MIME type: application/javascript
File size: 15965 byte(s)
imported original ColorMatch

1 dpavlin 1 /*----------------------------------------------------------------------------\
2     | Slider 1.0 |
3     |-----------------------------------------------------------------------------|
4     | Created by Erik Arvidsson |
5     | (http://webfx.eae.net/contact.html#erik) |
6     | For WebFX (http://webfx.eae.net/) |
7     |-----------------------------------------------------------------------------|
8     | A slider control that degrades to an input control for non supported |
9     | browsers. |
10     |-----------------------------------------------------------------------------|
11     | Copyright (c) 1999 - 2002 Erik Arvidsson |
12     |-----------------------------------------------------------------------------|
13     | This software is provided "as is", without warranty of any kind, express or |
14     | implied, including but not limited to the warranties of merchantability, |
15     | fitness for a particular purpose and noninfringement. In no event shall the |
16     | authors or copyright holders be liable for any claim, damages or other |
17     | liability, whether in an action of contract, tort or otherwise, arising |
18     | from, out of or in connection with the software or the use or other |
19     | dealings in the software. |
20     | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
21     | This software is available under the three different licenses mentioned |
22     | below. To use this software you must chose, and qualify, for one of those. |
23     | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
24     | The WebFX Non-Commercial License http://webfx.eae.net/license.html |
25     | Permits anyone the right to use the software in a non-commercial context |
26     | free of charge. |
27     | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
28     | The WebFX Commercial license http://webfx.eae.net/commercial.html |
29     | Permits the license holder the right to use the software in a commercial |
30     | context. Such license must be specifically obtained, however it's valid for |
31     | any number of implementations of the licensed software. |
32     | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
33     | GPL - The GNU General Public License http://www.gnu.org/licenses/gpl.txt |
34     | Permits anyone the right to use and modify the software without limitations |
35     | as long as proper credits are given and the original and modified source |
36     | code are included. Requires that the final product, software derivate from |
37     | the original source or any software utilizing a GPL component, such as |
38     | this, is also licensed under the GPL license. |
39     |-----------------------------------------------------------------------------|
40     | 2002-10-14 | Original version released |
41     |-----------------------------------------------------------------------------|
42     | Dependencies: timer.js - an OO abstraction of timers |
43     | range.js - provides the data model for the slider |
44     | winclassic.css or any other css file describing the look |
45     |-----------------------------------------------------------------------------|
46     | Created 2002-10-14 | All changes are in the log above. | Updated 2002-10-14 |
47     \----------------------------------------------------------------------------*/
48    
49    
50     Slider.isSupported = typeof document.createElement != "undefined" &&
51     typeof document.documentElement != "undefined" &&
52     typeof document.documentElement.offsetWidth == "number";
53    
54    
55     function Slider(oElement, oInput, sOrientation) {
56    
57     this._orientation = sOrientation || "horizontal";
58     this._range = new Range();
59     this._range.setExtent(0);
60     this._blockIncrement = 10;
61     this._unitIncrement = 1;
62     this._timer = new Timer(100);
63    
64    
65     if (Slider.isSupported && oElement) {
66    
67     this.document = oElement.ownerDocument || oElement.document;
68    
69     this.element = oElement;
70     this.element.slider = this;
71     this.element.unselectable = "on";
72    
73     // add class name tag to class name
74     this.element.className = this._orientation + " " + this.classNameTag + " " + this.element.className;
75    
76     // create line
77     this.line = this.document.createElement("DIV");
78     this.line.className = "line";
79     this.line.unselectable = "on";
80     this.line.appendChild(this.document.createElement("DIV"));
81     this.element.appendChild(this.line);
82    
83     // create handle
84     this.handle = this.document.createElement("DIV");
85     this.handle.className = "handle";
86     this.handle.unselectable = "on";
87     this.handle.appendChild(this.document.createElement("DIV"));
88     this.handle.firstChild.appendChild(
89     this.document.createTextNode(String.fromCharCode(160)));
90     this.element.appendChild(this.handle);
91     }
92    
93     this.input = oInput;
94    
95     // events
96     var oThis = this;
97     this._range.onchange = function () {
98     oThis.recalculate();
99     if (typeof oThis.onchange == "function")
100     oThis.onchange();
101     };
102    
103     if (Slider.isSupported && oElement) {
104     this.element.onfocus = Slider.eventHandlers.onfocus;
105     this.element.onblur = Slider.eventHandlers.onblur;
106     this.element.onmousedown = Slider.eventHandlers.onmousedown;
107     this.element.onmouseover = Slider.eventHandlers.onmouseover;
108     this.element.onmouseout = Slider.eventHandlers.onmouseout;
109     this.element.onkeydown = Slider.eventHandlers.onkeydown;
110     this.element.onkeypress = Slider.eventHandlers.onkeypress;
111     this.element.onmousewheel = Slider.eventHandlers.onmousewheel;
112     this.handle.onselectstart =
113     this.element.onselectstart = function () { return false; };
114    
115     this._timer.ontimer = function () {
116     oThis.ontimer();
117     };
118    
119     // extra recalculate for ie
120     window.setTimeout(function() {
121     oThis.recalculate();
122     }, 1);
123     }
124     else {
125     this.input.onchange = function (e) {
126     oThis.setValue(oThis.input.value);
127     };
128     }
129     }
130    
131     Slider.eventHandlers = {
132    
133     // helpers to make events a bit easier
134     getEvent: function (e, el) {
135     if (!e) {
136     if (el)
137     e = el.document.parentWindow.event;
138     else
139     e = window.event;
140     }
141     if (!e.srcElement) {
142     var el = e.target;
143     while (el != null && el.nodeType != 1)
144     el = el.parentNode;
145     e.srcElement = el;
146     }
147     if (typeof e.offsetX == "undefined") {
148     e.offsetX = e.layerX;
149     e.offsetY = e.layerY;
150     }
151    
152     return e;
153     },
154    
155     getDocument: function (e) {
156     if (e.target)
157     return e.target.ownerDocument;
158     return e.srcElement.document;
159     },
160    
161     getSlider: function (e) {
162     var el = e.target || e.srcElement;
163     while (el != null && el.slider == null) {
164     el = el.parentNode;
165     }
166     if (el)
167     return el.slider;
168     return null;
169     },
170    
171     getLine: function (e) {
172     var el = e.target || e.srcElement;
173     while (el != null && el.className != "line") {
174     el = el.parentNode;
175     }
176     return el;
177     },
178    
179     getHandle: function (e) {
180     var el = e.target || e.srcElement;
181     var re = /handle/;
182     while (el != null && !re.test(el.className)) {
183     el = el.parentNode;
184     }
185     return el;
186     },
187     // end helpers
188    
189     onfocus: function (e) {
190     var s = this.slider;
191     s._focused = true;
192     s.handle.className = "handle hover";
193     },
194    
195     onblur: function (e) {
196     var s = this.slider
197     s._focused = false;
198     s.handle.className = "handle";
199     },
200    
201     onmouseover: function (e) {
202     e = Slider.eventHandlers.getEvent(e, this);
203     var s = this.slider;
204     if (e.srcElement == s.handle)
205     s.handle.className = "handle hover";
206     },
207    
208     onmouseout: function (e) {
209     e = Slider.eventHandlers.getEvent(e, this);
210     var s = this.slider;
211     if (e.srcElement == s.handle && !s._focused)
212     s.handle.className = "handle";
213     },
214    
215     onmousedown: function (e) {
216     e = Slider.eventHandlers.getEvent(e, this);
217     var s = this.slider;
218     if (s.element.focus)
219     s.element.focus();
220    
221     Slider._currentInstance = s;
222     var doc = s.document;
223    
224     if (doc.addEventListener) {
225     doc.addEventListener("mousemove", Slider.eventHandlers.onmousemove, true);
226     doc.addEventListener("mouseup", Slider.eventHandlers.onmouseup, true);
227     }
228     else if (doc.attachEvent) {
229     doc.attachEvent("onmousemove", Slider.eventHandlers.onmousemove);
230     doc.attachEvent("onmouseup", Slider.eventHandlers.onmouseup);
231     doc.attachEvent("onlosecapture", Slider.eventHandlers.onmouseup);
232     s.element.setCapture();
233     }
234    
235     if (Slider.eventHandlers.getHandle(e)) { // start drag
236     Slider._sliderDragData = {
237     screenX: e.screenX,
238     screenY: e.screenY,
239     dx: e.screenX - s.handle.offsetLeft,
240     dy: e.screenY - s.handle.offsetTop,
241     startValue: s.getValue(),
242     slider: s
243     };
244     }
245     else {
246     var lineEl = Slider.eventHandlers.getLine(e);
247     s._mouseX = e.offsetX + (lineEl ? s.line.offsetLeft : 0);
248     s._mouseY = e.offsetY + (lineEl ? s.line.offsetTop : 0);
249     s._increasing = null;
250     s.ontimer();
251     }
252     },
253    
254     onmousemove: function (e) {
255     e = Slider.eventHandlers.getEvent(e, this);
256    
257     if (Slider._sliderDragData) { // drag
258     var s = Slider._sliderDragData.slider;
259    
260     var boundSize = s.getMaximum() - s.getMinimum();
261     var size, pos, reset;
262    
263     if (s._orientation == "horizontal") {
264     size = s.element.offsetWidth - s.handle.offsetWidth;
265     pos = e.screenX - Slider._sliderDragData.dx;
266     reset = Math.abs(e.screenY - Slider._sliderDragData.screenY) > 100;
267     }
268     else {
269     size = s.element.offsetHeight - s.handle.offsetHeight;
270     pos = s.element.offsetHeight - s.handle.offsetHeight -
271     (e.screenY - Slider._sliderDragData.dy);
272     reset = Math.abs(e.screenX - Slider._sliderDragData.screenX) > 100;
273     }
274     s.setValue(reset ? Slider._sliderDragData.startValue :
275     s.getMinimum() + boundSize * pos / size);
276     return false;
277     }
278     else {
279     var s = Slider._currentInstance;
280     if (s != null) {
281     var lineEl = Slider.eventHandlers.getLine(e);
282     s._mouseX = e.offsetX + (lineEl ? s.line.offsetLeft : 0);
283     s._mouseY = e.offsetY + (lineEl ? s.line.offsetTop : 0);
284     }
285     }
286    
287     },
288    
289     onmouseup: function (e) {
290     e = Slider.eventHandlers.getEvent(e, this);
291     var s = Slider._currentInstance;
292     var doc = s.document;
293     if (doc.removeEventListener) {
294     doc.removeEventListener("mousemove", Slider.eventHandlers.onmousemove, true);
295     doc.removeEventListener("mouseup", Slider.eventHandlers.onmouseup, true);
296     }
297     else if (doc.detachEvent) {
298     doc.detachEvent("onmousemove", Slider.eventHandlers.onmousemove);
299     doc.detachEvent("onmouseup", Slider.eventHandlers.onmouseup);
300     doc.detachEvent("onlosecapture", Slider.eventHandlers.onmouseup);
301     s.element.releaseCapture();
302     }
303    
304     if (Slider._sliderDragData) { // end drag
305     Slider._sliderDragData = null;
306     }
307     else {
308     s._timer.stop();
309     s._increasing = null;
310     }
311     Slider._currentInstance = null;
312     },
313    
314     onkeydown: function (e) {
315     e = Slider.eventHandlers.getEvent(e, this);
316     //var s = Slider.eventHandlers.getSlider(e);
317     var s = this.slider;
318     var kc = e.keyCode;
319     switch (kc) {
320     case 33: // page up
321     s.setValue(s.getValue() + s.getBlockIncrement());
322     break;
323     case 34: // page down
324     s.setValue(s.getValue() - s.getBlockIncrement());
325     break;
326     case 35: // end
327     s.setValue(s.getOrientation() == "horizontal" ?
328     s.getMaximum() :
329     s.getMinimum());
330     break;
331     case 36: // home
332     s.setValue(s.getOrientation() == "horizontal" ?
333     s.getMinimum() :
334     s.getMaximum());
335     break;
336     case 38: // up
337     case 39: // right
338     s.setValue(s.getValue() + s.getUnitIncrement());
339     break;
340    
341     case 37: // left
342     case 40: // down
343     s.setValue(s.getValue() - s.getUnitIncrement());
344     break;
345     }
346    
347     if (kc >= 33 && kc <= 40) {
348     return false;
349     }
350     },
351    
352     onkeypress: function (e) {
353     e = Slider.eventHandlers.getEvent(e, this);
354     var kc = e.keyCode;
355     if (kc >= 33 && kc <= 40) {
356     return false;
357     }
358     },
359    
360     onmousewheel: function (e) {
361     e = Slider.eventHandlers.getEvent(e, this);
362     var s = this.slider;
363     s.setValue(s.getValue() + e.wheelDelta / 120 * s.getUnitIncrement());
364     // windows inverts this on horizontal sliders. That does not
365     // make sense to me
366     return false;
367     }
368     };
369    
370    
371    
372     Slider.prototype.classNameTag = "dynamic-slider-control",
373    
374     Slider.prototype.setValue = function (v) {
375     this._range.setValue(v);
376     this.input.value = this.getValue();
377     };
378    
379     Slider.prototype.getValue = function () {
380     return this._range.getValue();
381     };
382    
383     Slider.prototype.setMinimum = function (v) {
384     this._range.setMinimum(v);
385     this.input.value = this.getValue();
386     };
387    
388     Slider.prototype.getMinimum = function () {
389     return this._range.getMinimum();
390     };
391    
392     Slider.prototype.setMaximum = function (v) {
393     this._range.setMaximum(v);
394     this.input.value = this.getValue();
395     };
396    
397     Slider.prototype.getMaximum = function () {
398     return this._range.getMaximum();
399     };
400    
401     Slider.prototype.setUnitIncrement = function (v) {
402     this._unitIncrement = v;
403     };
404    
405     Slider.prototype.getUnitIncrement = function () {
406     return this._unitIncrement;
407     };
408    
409     Slider.prototype.setBlockIncrement = function (v) {
410     this._blockIncrement = v;
411     };
412    
413     Slider.prototype.getBlockIncrement = function () {
414     return this._blockIncrement;
415     };
416    
417     Slider.prototype.getOrientation = function () {
418     return this._orientation;
419     };
420    
421     Slider.prototype.setOrientation = function (sOrientation) {
422     if (sOrientation != this._orientation) {
423     if (Slider.isSupported && this.element) {
424     // add class name tag to class name
425     this.element.className = this.element.className.replace(this._orientation,
426     sOrientation);
427     }
428     this._orientation = sOrientation;
429     this.recalculate();
430    
431     }
432     };
433    
434     Slider.prototype.recalculate = function() {
435     if (!Slider.isSupported || !this.element) return;
436    
437     var w = this.element.offsetWidth;
438     var h = this.element.offsetHeight;
439     var hw = this.handle.offsetWidth;
440     var hh = this.handle.offsetHeight;
441     var lw = this.line.offsetWidth;
442     var lh = this.line.offsetHeight;
443    
444     // this assumes a border-box layout
445    
446     if (this._orientation == "horizontal") {
447     this.handle.style.left = (w - hw) * (this.getValue() - this.getMinimum()) /
448     (this.getMaximum() - this.getMinimum()) + "px";
449     this.handle.style.top = (h - hh) / 2 + "px";
450    
451     this.line.style.top = (h - lh) / 2 + "px";
452     this.line.style.left = hw / 2 + "px";
453     //this.line.style.right = hw / 2 + "px";
454     this.line.style.width = Math.max(0, w - hw - 2)+ "px";
455     this.line.firstChild.style.width = Math.max(0, w - hw - 4)+ "px";
456     }
457     else {
458     this.handle.style.left = (w - hw) / 2 + "px";
459     this.handle.style.top = h - hh - (h - hh) * (this.getValue() - this.getMinimum()) /
460     (this.getMaximum() - this.getMinimum()) + "px";
461    
462     this.line.style.left = (w - lw) / 2 + "px";
463     this.line.style.top = hh / 2 + "px";
464     this.line.style.height = Math.max(0, h - hh - 2) + "px"; //hard coded border width
465     //this.line.style.bottom = hh / 2 + "px";
466     this.line.firstChild.style.height = Math.max(0, h - hh - 4) + "px"; //hard coded border width
467     }
468     };
469    
470     Slider.prototype.ontimer = function () {
471     var hw = this.handle.offsetWidth;
472     var hh = this.handle.offsetHeight;
473     var hl = this.handle.offsetLeft;
474     var ht = this.handle.offsetTop;
475    
476     if (this._orientation == "horizontal") {
477     if (this._mouseX > hl + hw &&
478     (this._increasing == null || this._increasing)) {
479     this.setValue(this.getValue() + this.getBlockIncrement());
480     this._increasing = true;
481     }
482     else if (this._mouseX < hl &&
483     (this._increasing == null || !this._increasing)) {
484     this.setValue(this.getValue() - this.getBlockIncrement());
485     this._increasing = false;
486     }
487     }
488     else {
489     if (this._mouseY > ht + hh &&
490     (this._increasing == null || !this._increasing)) {
491     this.setValue(this.getValue() - this.getBlockIncrement());
492     this._increasing = false;
493     }
494     else if (this._mouseY < ht &&
495     (this._increasing == null || this._increasing)) {
496     this.setValue(this.getValue() + this.getBlockIncrement());
497     this._increasing = true;
498     }
499     }
500    
501     this._timer.start();
502     };

  ViewVC Help
Powered by ViewVC 1.1.26