blob: d71bae138f3f106d3327c266942046a31f68bcf8 [file] [log] [blame]
Akron9905e2a2016-05-10 16:06:44 +02001define({
2
3 /**
Akron6ed13992016-05-23 18:06:05 +02004 * Create new slider object.
5 * The slider will only be used by mouse - touch support
6 * shouldn't be necessary.
Akron9905e2a2016-05-10 16:06:44 +02007 */
Akron47c086c2016-05-18 21:22:06 +02008 create : function (menu) {
9 return Object.create(this)._init(menu);
Akron9905e2a2016-05-10 16:06:44 +020010 },
11
Akron6ed13992016-05-23 18:06:05 +020012 length : function (i) {
13 if (arguments.length === 0)
14 return this._length;
15 if (i == this._length)
16 return;
17 this._length = i;
18 this._initSize();
19 },
20
21 limit : function (i) {
22 if (arguments.length === 0)
23 return this._limit;
24 if (i == this._limit)
25 return;
26 this._limit = i;
27 this._initSize();
28 },
29
30 movetoRel : function (relativePos) {
Akron24b1eaa2016-05-18 16:00:25 +020031 var diffHeight = (this._rulerHeight - this._sliderHeight);
Akron47c086c2016-05-18 21:22:06 +020032 var relativeOffset = (relativePos / diffHeight);
33
34 var off = this.offset(parseInt(relativeOffset * this._screens));
35 if (off !== undefined) {
36 this._menu.screen(off);
37 };
Akron6b24b202016-05-17 23:04:36 +020038 },
39
Akron6ed13992016-05-23 18:06:05 +020040 movetoAbs : function (absPos) {
41 var absOffset = (absPos / this._rulerHeight);
42
43 var off = this.offset(parseInt(absOffset * (this._screens + 1)));
44 if (off !== undefined) {
45 this._menu.screen(off);
46 };
Akron6b24b202016-05-17 23:04:36 +020047 },
48
Akron6ed13992016-05-23 18:06:05 +020049 offset : function (off) {
50 if (arguments.length === 0)
51 return this._offset;
Akron6b24b202016-05-17 23:04:36 +020052
Akron6ed13992016-05-23 18:06:05 +020053 if (off > this._screens) {
54 off = this._screens;
55 }
56 else if (off < 0) {
57 off = 0;
58 };
Akron24b1eaa2016-05-18 16:00:25 +020059
Akron6ed13992016-05-23 18:06:05 +020060 if (off === this._offset)
61 return undefined;
Akron6b24b202016-05-17 23:04:36 +020062
Akron6ed13992016-05-23 18:06:05 +020063 this._offset = off;
64 this._slider.style.top = (this._step * off) + '%';
65 return off;
66 },
Akron6b24b202016-05-17 23:04:36 +020067
Akron6ed13992016-05-23 18:06:05 +020068 element : function () {
69 return this._element;
Akron6b24b202016-05-17 23:04:36 +020070 },
71
Akron9905e2a2016-05-10 16:06:44 +020072 // Initialize prefix object
Akron47c086c2016-05-18 21:22:06 +020073 _init : function (menu) {
74
75 this._menu = menu;
Akron9905e2a2016-05-10 16:06:44 +020076
Akronf86eaea2016-05-13 18:02:27 +020077 this._offset = 0;
Akron6b24b202016-05-17 23:04:36 +020078 this._event = {};
Akronf86eaea2016-05-13 18:02:27 +020079
Akron9905e2a2016-05-10 16:06:44 +020080 this._element = document.createElement('div');
81 this._element.setAttribute('class', 'ruler');
82
83 this._slider = this._element.appendChild(
84 document.createElement('span')
85 );
86
Akron6ed13992016-05-23 18:06:05 +020087 this._ruler = this._element.appendChild(document.createElement('div'));
Akron47c086c2016-05-18 21:22:06 +020088
Akron6ed13992016-05-23 18:06:05 +020089 // Do not mark the menu on mousedown
90 this._ruler.addEventListener('mousedown', function (e) {
91 e.halt()
92 }, false);
93
94 // Move the slider to the click position
95 this._ruler.addEventListener('click', this._mouseclick.bind(this), false);
96
Akron6b24b202016-05-17 23:04:36 +020097 this._slider.addEventListener('mousedown', this._mousedown.bind(this), false);
98
Akron9905e2a2016-05-10 16:06:44 +020099 return this;
100 },
101
Akronf86eaea2016-05-13 18:02:27 +0200102 _initSize : function () {
Akron6ed13992016-05-23 18:06:05 +0200103 if (this._length <= this._limit) {
104 this._element.style.display = 'none';
105 return;
106 }
107 else {
108 this._element.style.display = 'block';
109 };
110
Akronf86eaea2016-05-13 18:02:27 +0200111 this._height = ((this._limit / this._length) * 100);
Akron6b24b202016-05-17 23:04:36 +0200112 this._screens = this._length - this._limit;
113 this._step = (100 - this._height) / this._screens;
Akronf86eaea2016-05-13 18:02:27 +0200114 this._slider.style.height = this._height + '%';
Akron9905e2a2016-05-10 16:06:44 +0200115 },
116
Akron6ed13992016-05-23 18:06:05 +0200117 _initClientHeight : function () {
118 this._rulerHeight = this._element.clientHeight; // offsetHeight?
119 this._sliderHeight = this._slider.clientHeight; // offsetHeight?
Akron9905e2a2016-05-10 16:06:44 +0200120 },
121
Akron6ed13992016-05-23 18:06:05 +0200122 _mousemove : function (e) {
123 this.movetoRel(e.clientY - this._event.init);
124 e.halt();
125 // Support touch!
Akronf86eaea2016-05-13 18:02:27 +0200126 },
127
Akron6ed13992016-05-23 18:06:05 +0200128 _mouseup : function (e) {
129 this._element.classList.remove('active');
130 window.removeEventListener('mousemove', this._event.mov);
131 window.removeEventListener('mouseup', this._event.up);
132 this._menu.focus();
Akron9905e2a2016-05-10 16:06:44 +0200133 },
134
Akron6ed13992016-05-23 18:06:05 +0200135 _mousedown : function (e) {
136 // Bind drag handler
137 var ev = this._event;
138 ev.init = e.clientY - (this._step * this._offset);
139 ev.mov = this._mousemove.bind(this);
140 ev.up = this._mouseup.bind(this);
141
142 // TODO: This may not be necessary all the time
143 this._initClientHeight();
144
145 this._element.classList.add('active');
146
147 window.addEventListener('mousemove', ev.mov);
148 window.addEventListener('mouseup', ev.up);
149
150 e.halt();
151 },
152
153 _mouseclick : function (e) {
154 this._initClientHeight();
155
156 this.movetoAbs(
157 e.clientY - this._ruler.getClientRects()[0].top
158 );
159 e.halt();
Akron9905e2a2016-05-10 16:06:44 +0200160 }
161});