GUI onChange and onFinishChange, addressing #81

This commit is contained in:
Monty Thibault 2017-09-30 17:53:07 -07:00
parent 2659494a80
commit bd4aca8e8b
13 changed files with 290 additions and 115 deletions

View File

@ -1055,6 +1055,12 @@ return /******/ (function(modules) { // webpackBootstrap
*/
this.property = property;
/**
* The containing GUI
* @type {GUI}
*/
this.parent = undefined;
/**
* The function to be called on change.
* @type {Function}
@ -1101,6 +1107,41 @@ return /******/ (function(modules) { // webpackBootstrap
return this;
};
/**
* Fires onFinishChange function if it exists and propagates message
* to parent.
*
* @param {Object} newValue The new value of <code>object[property]</code>
*/
Controller.prototype.__propagateFinishChange = function __propagateFinishChange(val) {
if (this.__onFinishChange) {
this.__onFinishChange.call(this, val);
}
if (this.parent) {
this.parent.__propagateFinishChange();
}
};
/**
* Fires onChange function if it exists and propagates message to parent.
*
* @param {Object} newValue The new value of <code>object[property]</code>
*/
Controller.prototype.__propagateChange = function __propagateChange(val) {
if (this.__onChange) {
this.__onChange.call(this, val);
}
if (this.parent) {
this.parent.__propagateChange();
}
};
/**
* Change the value of <code>object[property]</code>
*
@ -1110,11 +1151,9 @@ return /******/ (function(modules) { // webpackBootstrap
Controller.prototype.setValue = function setValue(newValue) {
this.object[this.property] = newValue;
if (this.__onChange) {
this.__onChange.call(this, newValue);
}
this.__propagateChange(newValue);
this.updateDisplay();
return this;
};
@ -1228,9 +1267,9 @@ return /******/ (function(modules) { // webpackBootstrap
BooleanController.prototype.setValue = function setValue(v) {
var toReturn = _Controller.prototype.setValue.call(this, v);
if (this.__onFinishChange) {
this.__onFinishChange.call(this, this.getValue());
}
this.__propagateFinishChange(this.getValue());
this.__prev = this.getValue();
return toReturn;
};
@ -1643,9 +1682,8 @@ return /******/ (function(modules) { // webpackBootstrap
OptionController.prototype.setValue = function setValue(v) {
var toReturn = _Controller.prototype.setValue.call(this, v);
if (this.__onFinishChange) {
this.__onFinishChange.call(this, this.getValue());
}
this.__propagateFinishChange(this.getValue());
return toReturn;
};
@ -1721,9 +1759,7 @@ return /******/ (function(modules) { // webpackBootstrap
}
function onBlur() {
if (_this.__onFinishChange) {
_this.__onFinishChange.call(_this, _this.getValue());
}
_this.__propagateFinishChange(_this.getValue());
}
_this2.__input = document.createElement('input');
@ -2003,9 +2039,7 @@ return /******/ (function(modules) { // webpackBootstrap
}
function onFinish() {
if (_this.__onFinishChange) {
_this.__onFinishChange.call(_this, _this.getValue());
}
_this.__propagateFinishChange(_this.getValue());
}
function onBlur() {
@ -2164,9 +2198,8 @@ return /******/ (function(modules) { // webpackBootstrap
function onMouseUp() {
_dom2.default.unbind(window, 'mousemove', onMouseDrag);
_dom2.default.unbind(window, 'mouseup', onMouseUp);
if (_this.__onFinishChange) {
_this.__onFinishChange.call(_this, _this.getValue());
}
_this.__propagateFinishChange(_this.getValue());
}
_this2.updateDisplay();
@ -2259,13 +2292,10 @@ return /******/ (function(modules) { // webpackBootstrap
}
FunctionController.prototype.fire = function fire() {
if (this.__onChange) {
this.__onChange.call(this);
}
this.__propagateChange(this.getValue());
this.getValue().call(this.object);
if (this.__onFinishChange) {
this.__onFinishChange.call(this, this.getValue());
}
this.__propagateFinishChange(this.getValue());
};
return FunctionController;
@ -2482,9 +2512,7 @@ return /******/ (function(modules) { // webpackBootstrap
}
function onFinish() {
if (_this.__onFinishChange) {
_this.__onFinishChange.call(_this, _this.__color.toOriginal());
}
_this.__propagateFinishChange(_this.__color.toOriginal());
}
_this2.__saturation_field.appendChild(valueField);
@ -2802,6 +2830,16 @@ return /******/ (function(modules) { // webpackBootstrap
*/
this.__rememberedObjectIndecesToControllers = [];
/*
* Called on change of child elements.
*/
this.__onChange = undefined;
/*
* Called on finish change of child elements.
*/
this.__onFinishChange = undefined;
this.__listening = [];
// Default parameters
@ -3203,6 +3241,36 @@ return /******/ (function(modules) { // webpackBootstrap
}
},
onChange: function onChange(f) {
this.__onChange = f;
return this;
},
onFinishChange: function onFinishChange(f) {
this.__onFinishChange = f;
return this;
},
__propagateChange: function __propagateChange() {
if (this.__onChange) {
this.__onChange.call(this);
}
if (this.parent) {
this.parent.__propagateChange();
}
},
__propagateFinishChange: function __propagateFinishChange() {
if (this.__onFinishChange) {
this.__onFinishChange.call(this);
}
if (this.parent) {
this.parent.__propagateFinishChange();
}
},
/**
* @param name
* @returns {dat.gui.GUI} The new folder.
@ -3398,9 +3466,7 @@ return /******/ (function(modules) { // webpackBootstrap
}
// fire onFinishChange callback
if (controller.__onFinishChange) {
controller.__onFinishChange.call(controller, controller.getValue());
}
controller.__propagateFinishChange(controller.getValue());
}, this);
_common2.default.each(this.__folders, function (folder) {
@ -3659,6 +3725,8 @@ return /******/ (function(modules) { // webpackBootstrap
params.before = params.before.__li;
}
controller.parent = gui;
recallSavedValue(gui, controller);
_dom2.default.addClass(controller.domElement, 'c');
@ -4233,56 +4301,56 @@ return /******/ (function(modules) { // webpackBootstrap
/* 24 */
/***/ function(module, exports) {
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
// css base code, injected by the css-loader
module.exports = function() {
var list = [];
// return the list of modules as css string
list.toString = function toString() {
var result = [];
for(var i = 0; i < this.length; i++) {
var item = this[i];
if(item[2]) {
result.push("@media " + item[2] + "{" + item[1] + "}");
} else {
result.push(item[1]);
}
}
return result.join("");
};
// import a list of modules into the list
list.i = function(modules, mediaQuery) {
if(typeof modules === "string")
modules = [[null, modules, ""]];
var alreadyImportedModules = {};
for(var i = 0; i < this.length; i++) {
var id = this[i][0];
if(typeof id === "number")
alreadyImportedModules[id] = true;
}
for(i = 0; i < modules.length; i++) {
var item = modules[i];
// skip already imported module
// this implementation is not 100% perfect for weird media query combinations
// when a module is imported multiple times with different media queries.
// I hope this will never occur (Hey this way we have smaller bundles)
if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) {
if(mediaQuery && !item[2]) {
item[2] = mediaQuery;
} else if(mediaQuery) {
item[2] = "(" + item[2] + ") and (" + mediaQuery + ")";
}
list.push(item);
}
}
};
return list;
};
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
// css base code, injected by the css-loader
module.exports = function() {
var list = [];
// return the list of modules as css string
list.toString = function toString() {
var result = [];
for(var i = 0; i < this.length; i++) {
var item = this[i];
if(item[2]) {
result.push("@media " + item[2] + "{" + item[1] + "}");
} else {
result.push(item[1]);
}
}
return result.join("");
};
// import a list of modules into the list
list.i = function(modules, mediaQuery) {
if(typeof modules === "string")
modules = [[null, modules, ""]];
var alreadyImportedModules = {};
for(var i = 0; i < this.length; i++) {
var id = this[i][0];
if(typeof id === "number")
alreadyImportedModules[id] = true;
}
for(i = 0; i < modules.length; i++) {
var item = modules[i];
// skip already imported module
// this implementation is not 100% perfect for weird media query combinations
// when a module is imported multiple times with different media queries.
// I hope this will never occur (Hey this way we have smaller bundles)
if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) {
if(mediaQuery && !item[2]) {
item[2] = mediaQuery;
} else if(mediaQuery) {
item[2] = "(" + item[2] + ") and (" + mediaQuery + ")";
}
list.push(item);
}
}
};
return list;
};
/***/ }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -47,9 +47,9 @@ class BooleanController extends Controller {
setValue(v) {
const toReturn = super.setValue(v);
if (this.__onFinishChange) {
this.__onFinishChange.call(this, this.getValue());
}
this.__propagateFinishChange(this.getValue());
this.__prev = this.getValue();
return toReturn;
}

View File

@ -175,9 +175,7 @@ class ColorController extends Controller {
}
function onFinish() {
if (_this.__onFinishChange) {
_this.__onFinishChange.call(_this, _this.__color.toOriginal());
}
_this.__propagateFinishChange(_this.__color.toOriginal());
}
this.__saturation_field.appendChild(valueField);

View File

@ -41,6 +41,13 @@ class Controller {
*/
this.property = property;
/**
* The containing GUI
* @type {GUI}
*/
this.parent = undefined;
/**
* The function to be called on change.
* @type {Function}
@ -83,6 +90,39 @@ class Controller {
return this;
}
/**
* Fires onFinishChange function if it exists and propagates message
* to parent.
*
* @param {Object} newValue The new value of <code>object[property]</code>
*/
__propagateFinishChange(val) {
if (this.__onFinishChange) {
this.__onFinishChange.call(this, val);
}
if (this.parent) {
this.parent.__propagateFinishChange();
}
}
/**
* Fires onChange function if it exists and propagates message to parent.
*
* @param {Object} newValue The new value of <code>object[property]</code>
*/
__propagateChange(val) {
if (this.__onChange) {
this.__onChange.call(this, val);
}
if (this.parent) {
this.parent.__propagateChange();
}
}
/**
* Change the value of <code>object[property]</code>
*
@ -90,11 +130,9 @@ class Controller {
*/
setValue(newValue) {
this.object[this.property] = newValue;
if (this.__onChange) {
this.__onChange.call(this, newValue);
}
this.__propagateChange(newValue);
this.updateDisplay();
return this;
}

View File

@ -45,13 +45,10 @@ class FunctionController extends Controller {
}
fire() {
if (this.__onChange) {
this.__onChange.call(this);
}
this.__propagateChange(this.getValue());
this.getValue().call(this.object);
if (this.__onFinishChange) {
this.__onFinishChange.call(this, this.getValue());
}
this.__propagateFinishChange(this.getValue());
}
}

View File

@ -58,9 +58,7 @@ class NumberControllerBox extends NumberController {
}
function onFinish() {
if (_this.__onFinishChange) {
_this.__onFinishChange.call(_this, _this.getValue());
}
_this.__propagateFinishChange(_this.getValue());
}
function onBlur() {

View File

@ -74,9 +74,8 @@ class NumberControllerSlider extends NumberController {
function onMouseUp() {
dom.unbind(window, 'mousemove', onMouseDrag);
dom.unbind(window, 'mouseup', onMouseUp);
if (_this.__onFinishChange) {
_this.__onFinishChange.call(_this, _this.getValue());
}
_this.__propagateFinishChange(_this.getValue());
}
this.updateDisplay();

View File

@ -71,9 +71,8 @@ class OptionController extends Controller {
setValue(v) {
const toReturn = super.setValue(v);
if (this.__onFinishChange) {
this.__onFinishChange.call(this, this.getValue());
}
this.__propagateFinishChange(this.getValue());
return toReturn;
}

View File

@ -35,9 +35,7 @@ class StringController extends Controller {
}
function onBlur() {
if (_this.__onFinishChange) {
_this.__onFinishChange.call(_this, _this.getValue());
}
_this.__propagateFinishChange(_this.getValue());
}
this.__input = document.createElement('input');

View File

@ -126,6 +126,18 @@ const GUI = function(pars) {
*/
this.__rememberedObjectIndecesToControllers = [];
/*
* Called on change of child elements.
*/
this.__onChange = undefined;
/*
* Called on finish change of child elements.
*/
this.__onFinishChange = undefined;
this.__listening = [];
// Default parameters
@ -542,6 +554,41 @@ common.extend(
}
},
onChange: function(f) {
this.__onChange = f;
return this;
},
onFinishChange: function(f) {
this.__onFinishChange = f;
return this;
},
__propagateChange: function() {
if (this.__onChange) {
this.__onChange.call(this);
}
if (this.parent) {
this.parent.__propagateChange();
}
},
__propagateFinishChange: function() {
if (this.__onFinishChange) {
this.__onFinishChange.call(this);
}
if (this.parent) {
this.parent.__propagateFinishChange();
}
},
/**
* @param name
* @returns {dat.gui.GUI} The new folder.
@ -736,9 +783,7 @@ common.extend(
}
// fire onFinishChange callback
if (controller.__onFinishChange) {
controller.__onFinishChange.call(controller, controller.getValue());
}
controller.__propagateFinishChange(controller.getValue());
}, this);
common.each(this.__folders, function(folder) {
@ -1014,6 +1059,8 @@ function add(gui, object, property, params) {
params.before = params.before.__li;
}
controller.parent = gui;
recallSavedValue(gui, controller);
dom.addClass(controller.domElement, 'c');

View File

@ -925,6 +925,39 @@ console.log(c2.__checkbox.getAttribute('checked'));
});
test("GUIOnChange", function() {
var gui = new dat.GUI({ autoPlace: false });
var f = gui.addFolder('f1');
var c = f.add({ x: 5 }, 'x');
var changed = false;
var finishChanged = false;
gui.onChange(function() {
changed = true;
});
gui.onFinishChange(function() {
finishChanged = true;
});
c.setValue(123);
c.__propagateFinishChange(123);
ok(changed, "GUI onChange fires as it should.");
ok(finishChanged, "GUI onFinishChange fires as is should.");
});
test("onFinishChange", function() {
var object = initObject();