I’ve been working on a small set of classes that bridge juce::Component
with Facebook’s Yoga library to provide a declarative API for representing component heirarchies and layouts. It’s inspired by React.js, with which I have a long history and with which I vastly prefer writing my UIs, and so borrows a lot of its principles. Like with React, I’ve implemented my own rudimentary tree diffing algorithm for merging two component trees with minimal overhead so that you can declare your UI as a function of external state once and the framework will take care of merging subsequent changes.
A quick example component might look like this:
class Chrome : blueprint::Container
{
using blueprint::Container::Container;
void paint (Graphics& g) override
{
// You still get your standard juce::Component hooks so
// do whatever you like in here!
}
auto renderChildren()
{
namespace bp = blueprint;
return (
bp::make<bp::Container>(
{{"flex", 1.0},
{"padding", 10.0},
{"background-colour", props.getProperty("mouseOver") ? "ffa7a7ff" : "ff272727ff"}},
bp::make<bp::Container>(
{{"flex", 1.0},
{"justify-content", center},
{"align-items", center}},
std::move(children)))
);
}
}
The API is very much in flux, but hopefully this gets the rough direction across.
I have a github project up with a working example, showing a case of rendering a tree based on a parameter value from an AudioProcessorValueTreeState, and merging newly constructed trees with the existing: https://github.com/nick-thompson/blueprint
There are many open questions here and I am not exactly a cpp library author (pretty sure I have string copies everywhere), but I’d like to use this work to facilitate a conversation and build this into something much better if there’s enough interest. If you are interested, please look over the existing code and consider the open questions at the bottom of the README on Github. Open an issue on the repository if you have a strong opinion for any of those questions, or feel free to just get into the code and send a PR (i.e. the assignment of string properties to Yoga flex properties is probably garbage currently :P)
cc @tpoole and @ed95 – a lot of this is born out of the conversation at ADC around JUCE considering React Native (which I support for desktop apps) and trying to provide something similar/familiar that seamlessly works for plugin development. I’d love to get your input on this, and if, down the road, this ends up looking like something worth including in JUCE directly, I’m definitely open to it.
Let me know what you think!