georgealways / lil-gui

Makes a floating panel for controllers on the web. Works as a drop-in replacement for dat.gui in most projects.
https://lil-gui.georgealways.com/
MIT License
1.08k stars 43 forks source link

Controller Extensions #12

Open awelles opened 2 years ago

awelles commented 2 years ago

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

georgealways commented 2 years ago

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.

awelles commented 2 years ago

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 commented 2 years ago

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

georgealways commented 2 years ago

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' ;)

awelles commented 2 years ago

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!

amatyulkov commented 2 years ago

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

georgealways commented 2 years ago

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.

araid commented 1 year ago

@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!

georgealways commented 1 year ago

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

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!