UI Toolbox logoUI Toolbox

Write a custom theme

  1. Create a USS file in Assets/UIToolbox/Runtime/Resources/UIToolbox/Themes/, for example ocean.uss.
  2. Add a :root, .tb-workspace rule. The theme sheet is on the workspace element, and :root matches only the panel root, so .tb-workspace is the selector that applies. Keep :root too, so the sheet also works when you add it to a panel root.
  3. Override only the --tb-* variables that you want to change. Do not add new selectors to a theme.
  4. Select the theme with theme-name="ocean" in UXML, or with workspace.SetTheme("ocean") in code.
  5. Make sure auto-load-styles is true. If it is false, the theme sheet is not loaded.

Example Assets/UIToolbox/Runtime/Resources/UIToolbox/Themes/ocean.uss:

/* Ocean theme: overrides variables only. */
:root, .tb-workspace {
    --tb-color-background: #0b1d2a;
    --tb-color-surface: #112b3c;
    --tb-color-surface-alt: #16384d;
    --tb-color-surface-hover: #1d4a66;
    --tb-color-border: #2a6f97;
    --tb-color-text: #e0f2ff;
    --tb-color-text-muted: #9cc5e0;
    --tb-color-accent: #01a9b4;
    --tb-color-accent-text: #001018;

    --tb-radius-md: 10px;
    --tb-size-title-bar: 30px;
}

To keep a sheet outside Resources/UIToolbox/Themes, reference it as a StyleSheet asset and add it with AddUserStyleSheet. Themes/game-custom.uss is an example of such a sheet. The Theming sample loads it this way.

To change a control, not only a color, put the rule in a user sheet. Use the canonical classes below.

Restyle the chrome with images

A theme changes colors. To change the whole look, use a user sheet that restyles the canonical classes. Assets/UIToolbox/Examples/Kingdom/Kingdom.uss makes the stock chrome medieval: wood frames, parchment content, stone buttons and the Cinzel font. Rules to follow:

Assets/UIToolbox/Examples/Firefight/Firefight.uss does the same for a shooter HUD. Translucent colors in the --tb-* variables and a 9-slice PNG with alpha make glass panels. A small image with background-repeat: repeat lays tick marks over the meter fills.

The images and the sounds of the two samples are generated (Kingdom/Art, Firefight/Art, and the Audio folders). Assets/UIToolbox/Examples/Audio has two more sound sets for the other samples: DefaultSounds (generated) and KenneySounds (Kenney "Interface Sounds", CC0, with its license file). The fonts are in Assets/UIToolbox/Examples/Fonts with their SIL Open Font License files.

Style families and style scopes

A theme styles the whole workspace. A style family styles one part of it. A family is a class that sets the --tb-* variables. Every Toolbox control reads only these variables, so the controls in an element with the class take the family:

.style--neon {
    --tb-color-background: #0b0f1f;
    --tb-color-surface: #121a33;
    --tb-color-border: #00e5ff;
    --tb-color-text: #d9fbff;
    --tb-color-accent: #ff2bd6;
    --tb-radius-sm: 0;
    --tb-radius-md: 0;
}

A popup (the search list, the calendar, the color popup) and a MessageBox show in the workspace or the top element of the document, not in the control. So they are outside the element with the family class. Add the class tb-style-scope (AnchoredPopup.STYLE_SCOPE_CLASS) to that element. While a popup or a box is open, it copies the classes of the nearest style scope above its anchor. When it closes, it removes them again.

<ui:VisualElement class="tb-style-scope style--neon">
    <tb:DatePicker label="Launch" />
</ui:VisualElement>

The rules of a family class apply also to the popup. Put the layout rules of the scope element on a child selector (.cells > *), not on the family class, so the popup does not take them.

The Styles example (Assets/UIToolbox/Examples/Scenes/Styles.unity) shows each Toolbox control four times: in the workspace theme and in the Neon, Paper and Terminal families of Styles.uss. Each cell also sets other attributes, for example a donut PieChart, a bar Graph or a Rating with 10 items. Use the families as a start for your own.