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

View File

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

View File

@ -41,6 +41,13 @@ class Controller {
*/ */
this.property = property; this.property = property;
/**
* The containing GUI
* @type {GUI}
*/
this.parent = undefined;
/** /**
* The function to be called on change. * The function to be called on change.
* @type {Function} * @type {Function}
@ -83,6 +90,39 @@ class Controller {
return this; 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> * Change the value of <code>object[property]</code>
* *
@ -90,11 +130,9 @@ class Controller {
*/ */
setValue(newValue) { setValue(newValue) {
this.object[this.property] = newValue; this.object[this.property] = newValue;
if (this.__onChange) { this.__propagateChange(newValue);
this.__onChange.call(this, newValue);
}
this.updateDisplay(); this.updateDisplay();
return this; return this;
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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