lil-gui icon indicating copy to clipboard operation
lil-gui copied to clipboard

Controller Extensions

Open awelles opened this issue 3 years ago • 9 comments

Providing a standard entry point to provide custom controllers would be lovely.

Something on a GUI class instance would work. like:

const gui = new GUI(); gui.add_custom_controller( 'addDate', DateController ); ... const folder = gui.addFolder( 'Folder' ); folder.addDate( folderParams, 'date' );

Where DateController extends Controllers. Though perhaps you could come up with something you find more elegant.

However it's done, a method to provide custom controllers could harness community creativity. DateTime, RealTimeGraph, Point, 3DPoint, etc..

Edit: While keeping the core minimal

awelles avatar Nov 14 '21 03:11 awelles

Ha, yes—while keeping the core minimal ;)

I'm planning on writing an example that shows what it's like to extend the Controller class. I'm imagining something like this right now for "registering" it with the GUI:

GUI.prototype.addDate = function() {
  return new MyDateController(this, ...arguments);
};

I like that because it's terse and wouldn't require anything be added to core.

georgealways avatar Nov 14 '21 13:11 georgealways

I like it.

PS: thanks for this project. Ive long loved datgui but it's been in desperate need of a reboot. It's legacy seems in good hands here. Carry on Good sir.

awelles avatar Nov 14 '21 15:11 awelles

I wanted to do a simple proof of concept and ended up doing this: https://github.com/awelles/lil-gui-inputcontroller

It's a generic InputController class with passable 'type' attribute using your suggested method. Creates out of the box vanilla input elements. Rough draft. Use at your own risk. Browser results may vary.

Mostly functional types: color, date, datetime-local, email, file, month, number, password, range, search, tel, text, time, url, week

Live-demo: https://awelles.github.io/lil-gui-inputcontroller/example.html

awelles avatar Nov 15 '21 05:11 awelles

Neat -- you've got the idea.

The main reason I've held off on an example like this is just to be sure the API for the "internals" of Controller are stable. For example, 0.13 is going to re-enable onFinishChange, so Controller has to make another call to invoke that. There are also some special considerations to make for Controllers that target object types (look at ColorController). Since lil-gui handles all the relevant primitives, I imagine these would be the focus of custom controller creation.

I know it's a proof of concept, but just be careful with that number controller: typeof input.value === 'string' ;)

georgealways avatar Nov 15 '21 11:11 georgealways

Yeah, what I made does zero type logic and comes with all the quirks of html inputs. It will murder any attached objects. Numbers to strings, dates and colors to it's preferred format, etc.

Maybe I'll make it something useful with onFinishChange later

Thanks for the feedback!

awelles avatar Nov 15 '21 17:11 awelles

This looks a bit stale, what's the latest?

As long as the Controller class is exported from the package, it looks like custom controllers could be supported with an API like this:

class MyController extends Controller { /* my impl */}
const gui = new GUI();

gui.addCustom(context, 'prop', MyController);

If that's acceptable and doable in your opinion -- I could look into this with a ColorWithAlphaController

amatyulkov avatar May 25 '22 13:05 amatyulkov

It is a bit stale—I actually wrote a custom controller API and set of guides last year, but the requests sort of died out, so I put it down. A color picker with alpha would be a perfect test case though—would you be willing to implement it with this experimental API?

Those custom controller guides live here, and the source is in this repo under a branch named 'custom-controller'. The API isn't far off from what you've written above (extending the controller class) but it makes it easier to write controllers that support library features like saving, loading, change events, etc.

Let me know if that's something you're interested in. Would be great to get feedback on if the guides and API make sense in general.

georgealways avatar May 25 '22 21:05 georgealways

@georgealways I ran across this looking for a way to make multiline text inputs, but I can't find the 'custom-controller' branch. Would love support for either of those things (custom controllers or just a multiline option).

Thanks for the great work on this!

araid avatar Mar 30 '23 22:03 araid

Hi! No plans for custom controller support at the moment. I had plans for a custom controller API / boilerplate at one point, but ultimately I decided it would expose me to more support requests than I could field.

That said, a multiline controller is actually a great starting place for custom controllers. I put together an example for those brave enough to extend the Controller class without the helper API I had in mind.

To future readers: consider this "unsupported" i.e. EXTEND AT YOUR OWN RISK. I don't have the bandwidth to help debug custom controllers :)

Custom Multiline Controller example

  • It does not fire onChange / finishChange events
  • It does not respect .disable()
  • It does not support screen readers
  • It does not incorporate the library's CSS vars
  • Extending this pattern beyond primitive object types will break gui.save/load() and controller.listen()

The built-in string controller is a more complete example for reference:

https://github.com/georgealways/lil-gui/blob/master/src/StringController.js

In general, if you need more complex custom controllers, I would recommend Tweakpane: https://cocopon.github.io/tweakpane/plugins/

Hope that helps!

georgealways avatar Mar 31 '23 13:03 georgealways