|
|
|
|
@ -170,34 +170,70 @@ define([
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
handleTextChange: function() {
|
|
|
|
|
// this handles the entry of text into the contentEditable label
|
|
|
|
|
// first, the value is checked if it contains a parseable number
|
|
|
|
|
// (or pair of numbers, for the _range case)
|
|
|
|
|
// then it is clamped within the min-max range of the slider
|
|
|
|
|
// finally, the model is updated if the value is to be changed
|
|
|
|
|
//
|
|
|
|
|
// if any of these conditions are not met, the text is reset
|
|
|
|
|
//
|
|
|
|
|
// the step size is not enforced
|
|
|
|
|
|
|
|
|
|
var text = this.$readout.text();
|
|
|
|
|
var value = this._validate_text_input(text);
|
|
|
|
|
if (isNaN(value)) {
|
|
|
|
|
this.$readout.text(this.model.get('value'));
|
|
|
|
|
var vmin = this.model.get('min');
|
|
|
|
|
var vmax = this.model.get('max');
|
|
|
|
|
if (this.model.get("_range")) {
|
|
|
|
|
// range case
|
|
|
|
|
// ranges can be expressed either "val-val" or "val:val" (+spaces)
|
|
|
|
|
var match = this._range_regex.exec(text);
|
|
|
|
|
if (match) {
|
|
|
|
|
var values = [this._parse_text_input(match[1]),
|
|
|
|
|
this._parse_text_input(match[2])];
|
|
|
|
|
// reject input where NaN or lower > upper
|
|
|
|
|
if (isNaN(values[0]) ||
|
|
|
|
|
isNaN(values[1]) ||
|
|
|
|
|
(values[0] > values[1])) {
|
|
|
|
|
this.$readout.text(this.model.get('value').join('-'));
|
|
|
|
|
} else {
|
|
|
|
|
// clamp to range
|
|
|
|
|
values = [Math.max(Math.min(values[0], vmax), vmin),
|
|
|
|
|
Math.max(Math.min(values[1], vmax), vmin)];
|
|
|
|
|
|
|
|
|
|
if ((values[0] != this.model.get('value')[0]) ||
|
|
|
|
|
(values[1] != this.model.get('value')[1])) {
|
|
|
|
|
this.$readout.text(values.join('-'));
|
|
|
|
|
this.model.set('value', values, {updated_view: this});
|
|
|
|
|
this.touch();
|
|
|
|
|
} else {
|
|
|
|
|
this.$readout.text(this.model.get('value').join('-'));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
this.$readout.text(this.model.get('value').join('-'));
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
//check for outside range
|
|
|
|
|
if (value > this.model.get('max')) value = this.model.get('max');
|
|
|
|
|
if (value < this.model.get('min')) value = this.model.get('min');
|
|
|
|
|
|
|
|
|
|
//update the readout unconditionally
|
|
|
|
|
//this covers eg, entering a float value which rounds to the
|
|
|
|
|
//existing int value, which will not trigger an update since the model
|
|
|
|
|
//doesn't change, but we should update the text to reflect that
|
|
|
|
|
//a float value isn't being used
|
|
|
|
|
this.$readout.text(value);
|
|
|
|
|
|
|
|
|
|
//note that the step size currently isn't enforced, so if an
|
|
|
|
|
//off-step value is input it will be retained
|
|
|
|
|
|
|
|
|
|
//update the model
|
|
|
|
|
this.model.set('value', value, {updated_view: this});
|
|
|
|
|
this.touch();
|
|
|
|
|
// single value case
|
|
|
|
|
var value = this._parse_text_input(text);
|
|
|
|
|
if (isNaN(value)) {
|
|
|
|
|
this.$readout.text(this.model.get('value'));
|
|
|
|
|
} else {
|
|
|
|
|
value = Math.max(Math.min(value, vmax), vmin);
|
|
|
|
|
|
|
|
|
|
if (value != this.model.get('value')) {
|
|
|
|
|
this.$readout.text(value);
|
|
|
|
|
this.model.set('value', value, {updated_view: this});
|
|
|
|
|
this.touch();
|
|
|
|
|
} else {
|
|
|
|
|
this.$readout.text(this.model.get('value'));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
_validate_text_input: function(x) {
|
|
|
|
|
return parseInt(x);
|
|
|
|
|
},
|
|
|
|
|
_parse_text_input: parseInt,
|
|
|
|
|
|
|
|
|
|
_range_regex: /^\s*([+-]?\d+)\s*[-:]\s*([+-]?\d+)/,
|
|
|
|
|
|
|
|
|
|
handleSliderChange: function(e, ui) {
|
|
|
|
|
// Called when the slider value is changed.
|
|
|
|
|
|