External definition and configuration of UI - nselikoff/Cinder-MinimalUI GitHub Wiki

Warning: work in progress :)

I've started a branch, glNext_json_config, to refactor MinimalUI to allow external definition and configuration of the UI via JSON.

Here's an example JSON file (still playing with how this is structured):

{
  "UIControllers": [
    {
      "params": {
        "id": "params",
        "panelColor": "0x440000FF"
      },
      "UIElements": [
        {
          "id": "foo",
          "type": "Button",
          "params": {
            "label": "Foo"
          },
          "EventHandlers": [
            "testButton"
          ]
        },
        {
          "id": "bar",
          "type": "Button",
          "params": {
            "label": "Bar"
          },
          "EventHandlers": [
            "testButton"
          ]
        },
        {
          "id": "baz",
          "type": "Slider",
          "params": {
            "label": "Baz"
          },
          "linkedValue": "sliderValue"
        }
      ]
    }
  ]
}

And here's how it would look in the app:

MinimalUI::UIControllerRef mUI;

// load one or more UIControllers from a file, each of which will be a child of mUI
mUI = MinimalUI::ControllerManager::create( loadAsset( "ui.json" ) );

// now you can do...
mUI->draw();
mUI->update();
mUI->resize();
mUI->show();
mUI->hide();

// and to get to the internal bits, something like this (not implemented yet)...
MinimalUI::SliderRef mSlider = static_cast<MinimalUI::SliderRef>(mUI->getUIElement("Slider1"));
// then mSlider->getValue(), mButton->addEventHandler(), etc

A few things to note:

  • everything is created under a root UIController, to remove the need for having a bunch of UIControllerRefs in your main app and looping through them for update, draw, etc. To support this I have added the ability for UIControllers to contain other UIControllers as children. This will require some additional thought in terms of drawing but should open up some good possibilities for enhancing performance as well.
  • Take a look at the new ControllerManager class, which is the one responsible for parsing the JSON and creating everything
  • I haven't done any of the dynamic stuff yet (linked values for sliders, callbacks for buttons)
  • I also needed a Button constructor that didn't require an eventHandler immediately, so I refactored that class a little bit. That may change or be imitated in the other derived UIElement classes.
  • incidentally I changed the UIElement class' mParent variable from a pointer to a shared pointer (I don't think I knew how to use shared_from_this when I first coded this).
  • internally I changed the constructors to take JSON directly instead of a string that's converted to JSON. The convenience methods (e.g. UIController::addButton(...)) still take a string as of now.