Unity-style GUI thoughts


#1

A couple of years ago I was working with Unity.

 Unity allows a very succinct GUI pattern:

void OnGUI() {
    if (GUI.Button(myRect, "ClickMe")) {
        :
    }
}

 This allows for super clean code as GUI objects don't exist outside of the OnGUI event.

 Contrast that with a standard approach -- where you would need to place code in at least four separate places:

  •  define the button as a class member
  •  initialise it in the constructor
  •  handle user interaction
  •  position it in the refresh event

The Unity style is excellent for rapid prototyping.

I'm not quite sure how it is implemented internally. I think that OnGUI executes once per frame in order to render, and also any mouse or keyboard event also invokes it.

Has anyone considered doing something similar with JUCE?

π


#2

It's called immediate mode GUI. For some things, it's nice, but for more complex stuff (anything that carries state or multi-frame stuff) it's bad.


#3

In Unity I was able to create my own persistent settings variables.

Something like:

class PrefsBool {
    bool value;
public:
    PrefsBool(string key, bool valueIfNoneFound) {
        // load from prefs file
    }
    void setValue(bool v) {
       value = v;
       //!!! save to prefs file
    }
    void render(Rect R, string text) {
        if( GUI.Toggle(R,text) != value )
            setValue(!value);
    }
}

   ... so then my settings code could just do something like this:

class settings : Component {
    PrefsBool isPortrait("isPortrait", false);
    :
    void OnGUI() {
        :
        isPortrait.render(someRect, "Check for portrait mode");
        
    }
    :
    void someMethod() {
        if (isPortrait.didChangeValue()) {
            print( isPortrait.getValue() ); 
            // ^ or just `isPortrait` & write a custom bool type conversion in prefsBool

didChangeValue() would return true if the value had changed since the last time it was called.

With suitable type conversions, I could use these variables as simple bools floats etc. But every time their value is set they would save to file. And .render(...) could be invoked on them to position a GUI control that would let the user change the value.

This was for highly experimental work; it gave a decent plastic workflow.

Just posting in case anyone has any interesting angles on GUI dev.

π


#4

I've been working with React Native and Redux. Its quite a new way for me to work with UI development. Redux allows you to keep a global state which represents all the data in your application. You cannot mutate the state. Each state change is a new state. The makes things very predictable, and allows things like stepping back in time. React Native makes it possible to listen to that state and re-render the UI when necessary, with an XML-like abstraction called JSX for declaring layouts, and flexbox type stylesheets. And, love it or hate it, its all in javascript! Although I must say ES6/ES7 makes it better. 

 


#5

If using JUCE's OpenGLRenderer, https://github.com/ocornut/imgui works well for prototyping and does what you want... (Whoops, meant to reply to Pi!)