natinusala / borealis

Hardware accelerated, controller and TV oriented UI library for PC and Nintendo Switch (libnx)
Apache License 2.0
266 stars 83 forks source link

Rework style / theme #132

Open natinusala opened 3 years ago

natinusala commented 3 years ago

Having to add styles and themes entries programmatically is bad. They need to be loaded externally from XML files, called "stylesheets". Every built-in view should have its own stylesheet for clarity.

A "theme" is now the result of loading all "stylesheet" files.

The need is for users to:

At first, it should be a 1:1 of what we have in the code, aka:

  1. Declare a theme (for now there is only one "brls/switch" one)
  2. For each variant, declare colors and metrics
  3. By default, all apps use the "brls/switch" theme unless specified otherwise by the user
  4. The API should stay roughly the same to quickly load theme values in the code and in XML files

So for instance, each built-in view's stylesheet can look like this:

<brls:Stylesheet theme="brls/switch" prefix="brls/sidebar">
    <brls:ThemeVariant name="dark">
        <brls:Color name="background" value="#323232" />
        <brls:Color name="active_item" value="#00ffcc" />
        <brls:Color name="separator" value="#515151" />
        <brls:Color name="some_other_color" value="rgb(255, 255, 255)" />

        <brls:Metric name="border_height" value="16px" />
        <brls:Metric name="padding_top" value="32px" />

        <!-- And so on... -->
    </brls:ThemeVariant>
</brls:Theme>

Which would be equivalent to the current C++ theme and style:

// Theme
{ "brls/sidebar/background", nvgRGB(50, 50, 50) },
{ "brls/sidebar/active_item", nvgRGB(0, 255, 204) },
{ "brls/sidebar/separator", nvgRGB(81, 81, 81) },

// Style
{ "brls/sidebar/border_height", 16.0f },
{ "brls/sidebar/padding_top", 32.0f },

Users can redefine the style by overriding values for the "brls/switch" theme. The final "theme" is the aggregation of all stylesheets, first the built-in ones then the user ones on top of it.

So one challenge is how to build a full theme in one go when the app inits, while having multiple stylesheet files on both the filesystem AND scaterred around the code (for built-in views, I don't want them in XML files and I don't want one big theme file either as we currently have).

Rough summary:

And THEN we can imagine more features like inheritance between themes... but that can be kept for later.

EmmmaTech commented 2 years ago

I think instead of calling the default theme brls/switch, it should be renamed to brls/default since GLFW still uses themes, just default to the light theme.