213 lines
6.8 KiB
JavaScript
213 lines
6.8 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
|
|
*/
|
|
|
|
/**
|
|
* The <code>useraction</code> event is emitted when a widget gets modified by user interaction.
|
|
* The event is emitted for the option <code>value</code>.
|
|
*
|
|
* @event TK.Knob#useraction
|
|
*
|
|
* @param {string} name - The name of the option which was changed due to the users action
|
|
* @param {mixed} value - The new value of the option
|
|
*/
|
|
|
|
"use strict";
|
|
(function(w, TK){
|
|
var format_viewbox = TK.FORMAT("0 0 %d %d");
|
|
function dblclick() {
|
|
this.userset("value", this.options.reset);
|
|
/**
|
|
* Is fired when the knob receives a double click in order to reset to initial value.
|
|
*
|
|
* @event TK.Knob#doubleclick
|
|
*
|
|
* @param {number} value - The value of the widget.
|
|
*/
|
|
this.fire_event("doubleclick", this.options.value);
|
|
}
|
|
function module_range() {
|
|
return this.parent.circular;
|
|
}
|
|
/**
|
|
* TK.Knob is a {@link TK.Circular} inside of an SVG which can be
|
|
* modified both by dragging and scrolling utilizing {@link TK.DragValue}
|
|
* and {@link TK.ScrollValue}.
|
|
* It inherits all options of {@link TK.Circular} and {@link TK.DragValue}.
|
|
* The options listed below consist of options from the contained widgets,
|
|
* only showing the default values.
|
|
*
|
|
* @class TK.Knob
|
|
*
|
|
* @extends TK.Widget
|
|
*
|
|
* @param {Object} [options={ }] - An object containing initial options.
|
|
*
|
|
* @property {Object} [options.hand={width: 1, length: 12, margin: 24}]
|
|
* @property {Number} [options.margin=13]
|
|
* @property {Number} [options.thickness=6]
|
|
* @property {Number} [options.step=1]
|
|
* @property {Number} [options.shift_up=4]
|
|
* @property {Number} [options.shift_down=0.25]
|
|
* @property {Object} [options.dot={length: 6, margin: 13, width: 2}]
|
|
* @property {Object} [options.marker={thickness: 6, margin: 13}]
|
|
* @property {Object} [options.label={margin: 10, align: "outer", format: function(val){return val;}}]
|
|
* @property {Number} [options.basis=300] - Distance to drag between <code>min</code> and <code>max</code>.
|
|
|
|
*/
|
|
TK.Knob = TK.class({
|
|
_class: "Knob",
|
|
Extends: TK.Widget,
|
|
_options: Object.assign(Object.create(TK.Widget.prototype._options), TK.Circular.prototype._options,
|
|
TK.DragValue.prototype._options, {
|
|
size: "number",
|
|
reset: "number",
|
|
}),
|
|
options: Object.assign({}, TK.Circular.prototype.options, {
|
|
size: 100,
|
|
hand: {width: 1, length: 12, margin: 24},
|
|
margin: 13,
|
|
thickness: 6,
|
|
step: 1,
|
|
shift_up: 4,
|
|
shift_down: 0.25,
|
|
dot: {length: 6, margin: 13, width: 2},
|
|
marker: {thickness: 6, margin: 13},
|
|
label: {margin: 12, align: "outer", format: function(val){return val;}},
|
|
direction: "polar",
|
|
rotation: 45,
|
|
blind_angle: 20,
|
|
basis: 300,
|
|
}),
|
|
static_events: {
|
|
dblclick: dblclick,
|
|
},
|
|
initialize: function (options) {
|
|
TK.Widget.prototype.initialize.call(this, options);
|
|
options = this.options;
|
|
var E, S;
|
|
/**
|
|
* @member {HTMLDivElement} TK.Knob#element - The main DIV container.
|
|
* Has class <code>toolkit-knob</code>.
|
|
*/
|
|
if (!(E = this.element)) this.element = E = TK.element("div")
|
|
TK.add_class(E, "toolkit-knob");
|
|
|
|
/**
|
|
* @member {SVGImage} TK.Knob#svg - The main SVG image.
|
|
*/
|
|
this.svg = S = TK.make_svg("svg");
|
|
|
|
var co = TK.object_and(options, TK.Circular.prototype._options);
|
|
co = TK.object_sub(co, TK.Widget.prototype._options);
|
|
co.container = S;
|
|
|
|
/**
|
|
* @member {TK.Circular} TK.Knob#circular - The {@link TK.Circular} module.
|
|
*/
|
|
this.circular = new TK.Circular(co);
|
|
|
|
this.widgetize(E, true, true, true);
|
|
|
|
/**
|
|
* @member {TK.DragValue} TK.Knob#drag - Instance of {@link TK.DragValue} used for the
|
|
* interaction.
|
|
*/
|
|
this.drag = new TK.DragValue(this, {
|
|
node: S,
|
|
range: module_range,
|
|
direction: options.direction,
|
|
rotation: options.rotation,
|
|
blind_angle: options.blind_angle,
|
|
limit: true,
|
|
});
|
|
/**
|
|
* @member {TK.ScrollValue} TK.Knob#scroll - Instance of {@link TK.ScrollValue} used for the
|
|
* interaction.
|
|
*/
|
|
this.scroll = new TK.ScrollValue(this, {
|
|
node: S,
|
|
range: module_range,
|
|
limit: true,
|
|
});
|
|
|
|
E.appendChild(S);
|
|
this.set("base", options.base);
|
|
if (options.reset === void(0))
|
|
options.reset = options.value;
|
|
this.add_child(this.circular);
|
|
},
|
|
|
|
get_range: function() {
|
|
return this.circular;
|
|
},
|
|
|
|
destroy: function () {
|
|
this.drag.destroy();
|
|
this.scroll.destroy();
|
|
this.circular.destroy();
|
|
TK.Widget.prototype.destroy.call(this);
|
|
},
|
|
|
|
redraw: function() {
|
|
var I = this.invalid;
|
|
var O = this.options;
|
|
|
|
if (I.size) {
|
|
I.size = false;
|
|
this.svg.setAttribute("viewBox", format_viewbox(O.size, O.size));
|
|
}
|
|
|
|
TK.Widget.prototype.redraw.call(this);
|
|
},
|
|
/**
|
|
* This is an alias for {@link TK.Circular#add_label} of the internal
|
|
* circular instance.
|
|
*
|
|
* @method TK.Knob#add_label
|
|
*/
|
|
add_label: function(x) {
|
|
return this.circular.add_label(x);
|
|
},
|
|
|
|
/**
|
|
* This is an alias for {@link TK.Circular#remove_label} of the internal
|
|
* circular instance.
|
|
*
|
|
* @method TK.Knob#remove_label
|
|
*/
|
|
remove_label: function(x) {
|
|
this.circular.remove_label(x);
|
|
},
|
|
|
|
set: function(key, value) {
|
|
if (key === "base") {
|
|
if (value === false) value = this.options.min;
|
|
}
|
|
// TK.Circular does the snapping
|
|
if (!TK.Widget.prototype._options[key]) {
|
|
if (TK.Circular.prototype._options[key])
|
|
value = this.circular.set(key, value);
|
|
if (TK.DragValue.prototype._options[key])
|
|
this.drag.set(key, value);
|
|
}
|
|
return TK.Widget.prototype.set.call(this, key, value);
|
|
},
|
|
});
|
|
})(this, this.TK);
|