175 lines
6.0 KiB
JavaScript
175 lines
6.0 KiB
JavaScript
|
/*
|
||
|
* This file is part of Toolkit.
|
||
|
*
|
||
|
* Toolkit is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU General Public
|
||
|
* License as published by the Free Software Foundation; either
|
||
|
* version 3 of the License, or (at your option) any later version.
|
||
|
*
|
||
|
* Toolkit is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
* Lesser General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General
|
||
|
* Public License along with this program; if not, write to the
|
||
|
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||
|
* Boston, MA 02110-1301 USA
|
||
|
*/
|
||
|
"use strict";
|
||
|
(function(w, TK) {
|
||
|
function scroll_timeout() {
|
||
|
/**
|
||
|
* Is fired when scrolling ended.
|
||
|
*
|
||
|
* @event TK.ScrollValue#scrollended
|
||
|
*/
|
||
|
fire_event.call(this, "scrollended");
|
||
|
this._wheel = false;
|
||
|
this.__sto = false;
|
||
|
this.set("scrolling", false);
|
||
|
TK.remove_class(this.options.classes, "toolkit-scrolling");
|
||
|
}
|
||
|
function scrollwheel(e) {
|
||
|
var O = this.options;
|
||
|
if (!O.active) return;
|
||
|
e.preventDefault();
|
||
|
var DIR = O.scroll_direction;
|
||
|
var d = e.deltaX * DIR[0] + e.deltaY * DIR[1] + e.deltaZ * DIR[2];
|
||
|
var direction = d > 0 ? 1 : -1;
|
||
|
var range = O.range.call(this);
|
||
|
var RO = range.options;
|
||
|
|
||
|
var v;
|
||
|
|
||
|
// timeout for resetting the class
|
||
|
if (this._wheel) {
|
||
|
v = this._raw_value;
|
||
|
window.clearTimeout(this.__sto);
|
||
|
} else {
|
||
|
this._raw_value = v = O.get.call(this);
|
||
|
TK.add_class(O.classes, "toolkit-scrolling");
|
||
|
/**
|
||
|
* Is fired when scrolling starts.
|
||
|
*
|
||
|
* @event TK.ScrollValue#scrollstarted
|
||
|
*
|
||
|
* @param {DOMEvent} event - The native DOM event.
|
||
|
*/
|
||
|
fire_event.call(this, "scrollstarted", e);
|
||
|
this._wheel = true;
|
||
|
}
|
||
|
this.__sto = window.setTimeout(scroll_timeout.bind(this), 200);
|
||
|
|
||
|
// calc step depending on options.step, .shift up and .shift down
|
||
|
var step = (RO.step || 1) * direction;
|
||
|
if (e.ctrlKey || e.altKey) {
|
||
|
step *= RO.shift_down;
|
||
|
} else if (e.shiftKey) {
|
||
|
step *= RO.shift_up;
|
||
|
}
|
||
|
|
||
|
var pos = range.val2px(v);
|
||
|
|
||
|
pos += step;
|
||
|
|
||
|
v = range.px2val(pos);
|
||
|
|
||
|
if (O.limit)
|
||
|
O.set.call(this, Math.min(RO.max, Math.max(RO.min, v)));
|
||
|
else
|
||
|
O.set.call(this, v);
|
||
|
|
||
|
/**
|
||
|
* Is fired while scrolling happens.
|
||
|
*
|
||
|
* @event TK.ScrollValue#scrolling
|
||
|
*
|
||
|
* @param {DOMEvent} event - The native DOM event.
|
||
|
*/
|
||
|
fire_event.call(this, "scrolling", e);
|
||
|
|
||
|
/* do not remember out of range values */
|
||
|
if (v > RO.min && v < RO.max)
|
||
|
this._raw_value = v;
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
function fire_event(title, event) {
|
||
|
var O = this.options;
|
||
|
// fire an event on this drag object and one with more
|
||
|
// information on the draggified element
|
||
|
this.fire_event(title, this, event);
|
||
|
var e = O.events.call(this);
|
||
|
if (e) e.fire_event(title, event, O.get.call(this), O.node, this, O.range.call(this));
|
||
|
}
|
||
|
/**
|
||
|
* TK.ScrollValue enables the scroll wheel for setting a value of an
|
||
|
* object. For instance, it is used by {@link TK.Knob} to allow turning
|
||
|
* the knob using the scroll wheel.
|
||
|
*
|
||
|
* @class TK.ScrollValue
|
||
|
*
|
||
|
* @extends TK.Module
|
||
|
*
|
||
|
* @param {Object} [options={ }] - An object containing initial options.
|
||
|
*
|
||
|
* @property {HTMLElement} options.node - The element receiving the scroll event.
|
||
|
* @property {Function} [options.get=function () { return this.parent.options.value; }] - Callback returning the value.
|
||
|
* @property {Function} [options.set=function (v) { return this.parent.userset("value", v); }] - Callback setting the value.
|
||
|
* @property {Function} [options.range=function () { return this.parent; }] - A function returning a {@link TK.Range} instance or options for a new one.
|
||
|
* @property {Function|Boolean} [options.events=false] - A function returning
|
||
|
* an element receiving events or <code>false</code> to fire events on the main element.
|
||
|
* @property {HTMLElement|Boolean} [options.classes=false] - Element receiving
|
||
|
* classes or <code>false</code> to set classes on the main element.
|
||
|
* @property {Boolean} [options.active=true] - Disable the scroll event.
|
||
|
* @property {Array<Number>} [options.scroll_direction=[0, -1, 0]] - An array
|
||
|
* containing values for x, y and z defining the direction of scrolling.
|
||
|
* @property {Boolean} [options.limit=false] - Limit the returned value to min and max of the range.
|
||
|
*/
|
||
|
TK.ScrollValue = TK.class({
|
||
|
_class: "ScrollValue",
|
||
|
Extends: TK.Module,
|
||
|
_options: {
|
||
|
get: "function",
|
||
|
set: "function",
|
||
|
range: "function",
|
||
|
events: "function",
|
||
|
classes: "object|boolean",
|
||
|
node: "object|boolean",
|
||
|
active: "boolean",
|
||
|
scroll_direction: "array",
|
||
|
limit: "boolean",
|
||
|
},
|
||
|
options: {
|
||
|
range: function () { return this.parent; },
|
||
|
events: function () { return this.parent; },
|
||
|
classes: false,
|
||
|
get: function () { return this.parent.options.value; },
|
||
|
set: function (v) { return this.parent.userset("value", v); },
|
||
|
active: true,
|
||
|
scroll_direction: [0, -1, 0],
|
||
|
limit: false,
|
||
|
},
|
||
|
initialize: function (widget, options) {
|
||
|
TK.Module.prototype.initialize.call(this, widget, options);
|
||
|
this._wheel = false;
|
||
|
this._raw_value = 0.0;
|
||
|
this.set("node", this.options.node);
|
||
|
this.set("events", this.options.events);
|
||
|
this.set("classes", this.options.classes);
|
||
|
},
|
||
|
static_events: {
|
||
|
set_node: function(value) {
|
||
|
this.delegate_events(value);
|
||
|
if (value && !this.options.classes) this.set("classes", value);
|
||
|
},
|
||
|
wheel: scrollwheel,
|
||
|
},
|
||
|
set: function (key, value) {
|
||
|
if ((key === "classes") && !value) value = this.options.node;
|
||
|
return TK.Module.prototype.set.call(this, key, value);
|
||
|
}
|
||
|
})
|
||
|
})(this, this.TK);
|