129 lines
4.9 KiB
Markdown
129 lines
4.9 KiB
Markdown
|
|
# theming
|
|
|
|
A small Makepad example that demonstrates **runtime theme and language
|
|
swapping** using the new `script_mod!` / Splash DSL (Makepad 2.0).
|
|
|
|
Click **Toggle theme** to cycle light/dark; click **Language** to cycle
|
|
English/Kiswahili. The whole UI re-skins and re-localizes at runtime by
|
|
swapping the *active* design token set and reloading the script tree — no
|
|
per-widget edits required.
|
|
|
|
---
|
|
|
|
## Token architecture (3 tiers)
|
|
|
|
This example follows a layered design-token system so that a single change
|
|
propagates predictably across the whole UI:
|
|
|
|
```
|
|
Tier 1 — Primitives Tier 2 — Semantic Tier 3 — Widgets
|
|
(raw values, no meaning) (roles bound per theme) (read active theme)
|
|
|
|
mod.streem_design.palette → mod.streem_theme.light → draw_bg.color: color_bg
|
|
mod.streem_design.shapes → mod.streem_theme.dark ↘ draw_text.text_style: h1
|
|
mod.streem_design.typography mod.streem_theme.s_themes ← (the active theme)
|
|
```
|
|
|
|
* **Tier 1 — `streem_design/`**
|
|
* `palette.rs` — the *only* place raw hex colors live (`amber_600`, `gray_900`…).
|
|
* `shapes.rs` — radii, control heights, a spacing scale, border widths.
|
|
* `typography.rs` — named text styles (`h1`, `body1`, `overline`…).
|
|
* **Tier 2 — `streem_theme/`**
|
|
* `mod.rs` — `light` / `dark` themes that map *roles* (`color_bg`,
|
|
`color_primary`, `color_text`, status colors…) onto palette primitives.
|
|
Widgets read everything through `mod.streem_theme.s_themes.*`.
|
|
* **Localization — `streem_i18n/`**
|
|
* `mod.rs` — `en` / `sw` string tables; the active language is
|
|
`mod.streem_i18n.s_i18n` (same swap pattern as themes).
|
|
* **Host — `src/main.rs`**
|
|
* Tracks the selected theme/language indices, points `s_themes` / `s_i18n`
|
|
at the selection, reloads the script tree, and drives a live status label.
|
|
|
|
Why this matters: because semantic themes reference palette tokens, you can
|
|
re-brand the entire app by editing one entry in `palette.rs`. Because widgets
|
|
only ever read `s_themes`/`s_i18n`, the host can re-skin/re-localize the tree
|
|
generically.
|
|
|
|
---
|
|
|
|
## Project layout
|
|
|
|
```
|
|
theming/
|
|
├── Cargo.toml
|
|
└── src/
|
|
├── main.rs # host App: toggles + reload path
|
|
├── streem_design/
|
|
│ ├── mod.rs # registers tier-1 modules
|
|
│ ├── palette.rs # tier 1: raw colors
|
|
│ ├── shapes.rs # tier 1: radii / spacing / sizes
|
|
│ └── typography.rs # tier 1: text styles
|
|
├── streem_theme/
|
|
│ └── mod.rs # tier 2: semantic light/dark themes
|
|
└── streem_i18n/
|
|
└── mod.rs # localized strings (en/sw)
|
|
```
|
|
|
|
---
|
|
|
|
## Building & running
|
|
|
|
> **Studio-first workflow.** Per the project runbook, UI programs should be
|
|
> launched and inspected through the Makepad Studio remote protocol via a
|
|
> runnable item, **not** via raw `cargo run`. Use the shell only for non-UI
|
|
> tasks (`cargo check`, `cargo test`, file/search ops), and prefer `--release`
|
|
> for any performance-sensitive run.
|
|
|
|
### Dependency setup
|
|
|
|
`Cargo.toml` uses a **local path** dependency on `makepad-widgets`, which
|
|
assumes this crate sits as a sibling of your Makepad checkout:
|
|
|
|
```
|
|
makepad/ # your makepad checkout (the new DSL lives on `dev`)
|
|
widgets/
|
|
<projects>/
|
|
theming/ # this crate → path = "../../../../makepad/widgets"
|
|
```
|
|
|
|
Adjust the number of `../` segments in `Cargo.toml` to match where you place
|
|
this crate. If you are **not** inside a Makepad checkout, uncomment the git
|
|
dependency in `Cargo.toml` instead (pinned to `branch = "dev"`).
|
|
|
|
### Non-UI checks (shell is fine)
|
|
|
|
```bash
|
|
cargo check # type-check
|
|
cargo test # runs the unit tests in src/main.rs
|
|
cargo build --release
|
|
```
|
|
|
|
### Running the UI (via Studio)
|
|
|
|
1. Start the Studio remote bridge once.
|
|
2. Add `theming` to the Cargo workspace and `makepad.splash` so Studio exposes
|
|
it as a runnable item.
|
|
3. Launch it with `RunItem` (the runnable item name shown in Studio).
|
|
4. After editing UI/runtime code, `ClearBuild` the old build and re-run before
|
|
trusting screenshots or widget dumps.
|
|
|
|
---
|
|
|
|
## What changed vs. the original
|
|
|
|
See [`CHANGES.md`](./CHANGES.md) for the full list. Highlights:
|
|
|
|
* Introduced the 3-tier token system and an app-owned `mod.streem_design.*`
|
|
namespace (was `mod.widgets.*`, which collides conceptually with the
|
|
framework's own widget namespace).
|
|
* Themes now reference palette primitives instead of inlining hex.
|
|
* Fixed the unused `color_text` role and removed dead/duplicated token files.
|
|
* Status text is now driven entirely by live Rust state (no baked-in
|
|
"light | reapply: 0" string in the DSL).
|
|
* Added a generic, index-based theme/language cycle (replacing the rigid
|
|
2-state enum) plus runtime language switching wired through one reload path.
|
|
* Hardened `Event::LiveEdit` so a hot-reload re-applies the active selection
|
|
instead of silently reverting to script defaults.
|
|
|
|
|