Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement .add( controller ) & its use for custom Controllers. #243

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 91 additions & 42 deletions example.html
Original file line number Diff line number Diff line change
@@ -1,63 +1,112 @@
<!DOCTYPE html>
<html>

<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
</head>

<body>
<script type="text/javascript" src="build/dat.gui.js"></script>
<script type="text/javascript">
var obj = {
message: 'Hello World',
displayOutline: false,
<script type="text/javascript" src="build/dat.gui.js"></script>
<script type="text/javascript">
var obj = {
message: 'Hello World',
displayOutline: false,

maxSize: 6.0,
speed: 5,

height: 10,
noiseStrength: 10.2,
growthSpeed: 0.2,

maxSize: 6.0,
speed: 5,
type: 'three',

height: 10,
noiseStrength: 10.2,
growthSpeed: 0.2,
explode: function() {
alert('Bang!');
},

type: 'three',
color0: "#ffae23", // CSS string
color1: [0, 128, 255], // RGB array
color2: [0, 128, 255, 0.3], // RGB with alpha
color3: {
h: 350,
s: 0.9,
v: 0.3
} // Hue, saturation, value
};

explode: function () {
alert('Bang!');
},
var gui = new dat.gui.GUI();

color0: "#ffae23", // CSS string
color1: [ 0, 128, 255 ], // RGB array
color2: [ 0, 128, 255, 0.3 ], // RGB with alpha
color3: { h: 350, s: 0.9, v: 0.3 } // Hue, saturation, value
};
gui.remember(obj);

var gui = new dat.gui.GUI();
gui.add(obj, 'message');
gui.add(obj, 'displayOutline');
gui.add(obj, 'explode');

gui.remember(obj);
gui.add(obj, 'maxSize').min(-10).max(10).step(0.25);
gui.add(obj, 'height').step(5); // Increment amount

gui.add(obj, 'message');
gui.add(obj, 'displayOutline');
gui.add(obj, 'explode');
// Choose from accepted values
gui.add(obj, 'type', ['one', 'two', 'three']);

gui.add(obj, 'maxSize').min(-10).max(10).step(0.25);
gui.add(obj, 'height').step(5); // Increment amount
// Choose from named values
gui.add(obj, 'speed', {
Stopped: 0,
Slow: 0.1,
Fast: 5
});

// Choose from accepted values
gui.add(obj, 'type', [ 'one', 'two', 'three' ] );
var f1 = gui.addFolder('Colors');
f1.addColor(obj, 'color0');
f1.addColor(obj, 'color1');
f1.addColor(obj, 'color2');
f1.addColor(obj, 'color3');

// Choose from named values
gui.add(obj, 'speed', { Stopped: 0, Slow: 0.1, Fast: 5 } );
var f2 = gui.addFolder('Another Folder');
f2.add(obj, 'noiseStrength');

var f1 = gui.addFolder('Colors');
f1.addColor(obj, 'color0');
f1.addColor(obj, 'color1');
f1.addColor(obj, 'color2');
f1.addColor(obj, 'color3');
var f3 = f2.addFolder('Nested Folder');
f3.add(obj, 'growthSpeed');

var f2 = gui.addFolder('Another Folder');
f2.add(obj, 'noiseStrength');
// alternative StringController add
gui.add(new dat.controllers.StringController(obj, 'message'));

var f3 = f2.addFolder('Nested Folder');
f3.add(obj, 'growthSpeed');
// a custom controller
class KnobController extends dat.controllers.Controller {
constructor(object, property, a, b) {
super(object, property);
const _this = this;
this.__input = document.createElement('input');
this.__input.setAttribute('type', 'number');
this.__input.style.width = '40%';
this.updateDisplay();
this.domElement.appendChild(this.__input);
var button = document.createElement('input');
button.setAttribute('type', 'button');
button.value = 'Set ' + property;
button.style.width = '50%';
button.onclick = function(e) {
object[property] = a + b;
_this.updateDisplay();
};
this.domElement.appendChild(button);
}
updateDisplay() {
this.__input.value = this.getValue();
}
}

</script>
const api = {

color: '#ffffff',
value: 0.5,

};

gui.add(new KnobController(api, 'value', 0.5, 25), {
liClass: 'knobby'
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know if this is compatible with the augmentController method here?

dat.gui/src/dat/gui/GUI.js

Lines 922 to 990 in 096993e

function augmentController(gui, li, controller) {
controller.__li = li;
controller.__gui = gui;
common.extend(controller, /** @lends Controller.prototype */ {
/**
* @param {Array|Object} options
* @return {Controller}
*/
options: function(options) {
if (arguments.length > 1) {
const nextSibling = controller.__li.nextElementSibling;
controller.remove();
return add(
gui,
controller.object,
controller.property,
{
before: nextSibling,
factoryArgs: [common.toArray(arguments)]
}
);
}
if (common.isArray(options) || common.isObject(options)) {
const nextSibling = controller.__li.nextElementSibling;
controller.remove();
return add(
gui,
controller.object,
controller.property,
{
before: nextSibling,
factoryArgs: [options]
}
);
}
},
/**
* Sets the name of the controller.
* @param {string} name
* @return {Controller}
*/
name: function(name) {
controller.__li.firstElementChild.firstElementChild.innerHTML = name;
return controller;
},
/**
* Sets controller to listen for changes on its underlying object.
* @return {Controller}
*/
listen: function() {
controller.__gui.listen(controller);
return controller;
},
/**
* Removes the controller from its parent GUI.
* @return {Controller}
*/
remove: function() {
controller.__gui.remove(controller);
return controller;
}
});

... specifically — can you still remove(), listen(), and name() the KnobController normally? I don't suppose it's possible to override those methods in the subclass, which is unfortunate, but probably not this PR's problem to solve.

</script>
</body>
</html>

</html>
31 changes: 21 additions & 10 deletions src/dat/gui/GUI.js
Original file line number Diff line number Diff line change
Expand Up @@ -1131,23 +1131,30 @@ function recallSavedValue(gui, controller) {
}

function add(gui, object, property, params) {
if (object[property] === undefined) {
throw new Error(`Object "${object}" has no property "${property}"`);
}

let controller;

if (object instanceof Controller) {
controller = object;
params = property || { };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

params doesn't take a default value normally, so is it OK to omit the || {} here?

} else {

if (object[property] === undefined) {
throw new Error(`Object "${object}" has no property "${property}"`);
}

if (params.color) {
controller = new ColorController(object, property);
} else {
const factoryArgs = [object, property].concat(params.factoryArgs);
controller = ControllerFactory.apply(gui, factoryArgs);
}

if (params.color) {
controller = new ColorController(object, property);
} else {
const factoryArgs = [object, property].concat(params.factoryArgs);
controller = ControllerFactory.apply(gui, factoryArgs);
}

if (params.before instanceof Controller) {
params.before = params.before.__li;
}

recallSavedValue(gui, controller);

dom.addClass(controller.domElement, 'c');
Expand All @@ -1165,6 +1172,10 @@ function add(gui, object, property, params) {
dom.addClass(li, GUI.CLASS_CONTROLLER_ROW);
if (controller instanceof ColorController) {
dom.addClass(li, 'color');
} else if ( params.liClass ) {
dom.addClass(li, params.liClass);
} else if ( controller.liClass ) {
dom.addClass(li, controller.liClass);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are both of these (params.liClass and controller.liClass) needed? If this li will later be set as controller.__li, could the controller add the class itself?

} else {
dom.addClass(li, typeof controller.getValue());
}
Expand Down