Write a custom theme
- Create a USS file in
Assets/UIToolbox/Runtime/Resources/UIToolbox/Themes/, for exampleocean.uss. - Add a
:root, .tb-workspacerule. The theme sheet is on the workspace element, and:rootmatches only the panel root, so.tb-workspaceis the selector that applies. Keep:roottoo, so the sheet also works when you add it to a panel root. - Override only the
--tb-*variables that you want to change. Do not add new selectors to a theme. - Select the theme with
theme-name="ocean"in UXML, or withworkspace.SetTheme("ocean")in code. - Make sure
auto-load-stylesis 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:
- Scope every rule with a class on an ancestor, for example
.kingdom. The sample puts the class on the element that holds the workspace. The extra class also makes the rule win overWindowStyles.uss. - Set the
--tb-*variables on.kingdom .tb-workspace, not on.kingdom. The theme rule:root, .tb-workspacematches the workspace element itself, so a value set on an ancestor does not reach it. - Set the drag hint colors too:
--tb-color-previewand--tb-color-preview-border(snap and tear-off preview, resize handle),--tb-color-drop-target(merge border) and--tb-color-dock-target(dock border). Without them the hints keep the colors of the theme, such as the blue of the dark theme. - Use 9-slice images for frames:
background-image, then-unity-slice-left,-right,-topand-bottomin pixels of the image. Setbackground-colorto transparent and give the window apaddingequal to the frame width. - Set a font with
-unity-font-definition: url("Fonts/Name.ttf"). A TTF file works. - A type selector matches the exact type only.
.kingdom Buttondoes not matchWorkspaceToolbarButton, so add.kingdom .tb-toolbar-button. - A rule with more classes wins over a preset step. For example, add
.kingdom .tb-toolbar Label.tb-anim-flash--1to set the flash color of a toolbar label.
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.