feat(tokens+cad): schematic palette in Tokens + cad_tool_button paint-closure#8
Merged
Merged
Conversation
Round 3 of the Tokito editor migration foundation. Two changes that let the editor delete `crate::ui::tokens::UiTokens` entirely and rebuild its hand-drawn CAD tool rail on the shared `cad_tool_button` primitive. ## Schematic palette in Tokens Adds 19 schematic-canvas colour fields to `Tokens` (canvas_bg, grid_*, canvas_frame, sym_ink, sym_body_fill, sym_ink_hover, sym_ink_selected, sym_outline, sym_sel_ring, wire, wire_highlight, wire_selected, label_ink, refdes_ink, pin_ink, pin_hot, selection, preview_bg) with sensible defaults in both `dark()` and `light()` presets. Cool teal-ink schematic on a deep slate sheet in dark, near-black ink on pale slate in light; warm orange selection ring in both. Effect: a consumer's editor canvas pulls from the same Tokens value that drives its chrome — one token source. Non-canvas consumers can ignore the schematic fields. ## cad_tool_button paint-closure Replaces the hardcoded `glyph: &str` parameter with a closure `FnOnce(&Painter, Rect, Color32)`. The caller decides what to draw: - Phosphor case: `cad_tool_button(ui, &t, 38.0, sel, "Wire", paint_phosphor_glyph(icons::ph::PEN_NIB))` - Hand-drawn schematic glyphs: pass a closure that runs line_segment / rect_stroke / circle_filled directly. Used by the Tokito schematic editor for wire-bend, GND-triangle, net-label, junction icons that aren't in Phosphor. `paint_phosphor_glyph(glyph)` is the convenience helper for the common case; it centres a glyph at a sensible size for the button. This is a breaking signature change vs the previous cad_tool_button — no production callers yet (no shipped consumers), so the simpler explicit-closure shape wins over backwards-compatible enum variants. ## Docs - README — Tokens groups now name the schematic palette; cad_tool_button table row shows the new signature. - AGENTS.md — paint_phosphor_glyph noted next to cad_tool_button. ## CI gates locally clean - `cargo fmt --all -- --check` - `cargo clippy --all-targets -- -D warnings` - `cargo build` - `RUSTDOCFLAGS="-D warnings" cargo doc --no-deps` Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
kakarot-dev
added a commit
to VtronTokito/tokito
that referenced
this pull request
Jun 12, 2026
…alette unified Round 4 of the editor migration. Real type-level migration this time: the custom UiTokens struct is gone; UiTokens is now a thin type alias for tokito_ui::Tokens, which carries both chrome and schematic palettes. ## What changed - ui/tokens.rs — replaced with `pub use tokito_ui::Tokens as UiTokens;` The 40+ schematic colour fields the editor used (canvas, wire, sym, label_ink, refdes_ink, pin_ink, selection, preview_bg, …) now live in tokito_ui::Tokens (via VtronTokito/ui#8). - theme.rs — tokens_for() returns the tokito_ui preset (dark/light) for the theme; no more hand-rolled UiTokens literal. Visuals wiring uses Stroke::new(1.0, t.border) where it previously read t.stroke_subtle, and t.rounding_*() for the Rounding-typed visual fields. - Every editor consumer file (app/studio/*, editor/*, mcad_viewer/*, viewer3d.rs, app/mod.rs, app/impl_eframe.rs, theme.rs, base_symbols.rs) was field-renamed from the legacy UiTokens names to the tokito_ui ones: text_primary → text text_secondary → text_2 text_muted → text_3 bg_app → bg bg_panel → bg_chrome bg_elevated → card bg_canvas → canvas_bg bg_hover → card_hover bg_chip_selected → accent_soft accent_dim → accent_soft spacing_xs..lg → space_1, space_2, space_4, space_5 .stroke_subtle → Stroke::new(1.0, .border) .stroke_focus → Stroke::new(1.4, .border_strong) .margin_panel → Margin::symmetric(.space_4, .space_3) - editor/tool_icons.rs — new module holding the hand-drawn schematic glyphs (Select, Place, Wire, NetLabel, Power, Junction, NoConnect, Bus, Text, Pan, Focus, ZoomFit, Grid, Snap). Designed as the closure body the new tokito_ui::components::cad_tool_button takes: c::cad_tool_button(ui, &t, 38.0, sel, "Wire", |p, r, ink| { paint(p, r, ToolIcon::Wire, ink) }); - ui/widgets.rs, ui/layout.rs, ui/toast.rs — still in place as thin wrappers; bodies now pass `tokens` directly (no more .tk() conversion). The wrappers will fold away in a final cleanup slice once consumer call sites switch to tokito_ui::components::* directly. Today they're a 1:1 trivial mapping. ## Visual + behavioural effect - Every chrome surface, button, list row, card, search field, toast in the editor now renders through tokito_ui::components. - The schematic canvas reads its palette from the same Tokens value the chrome reads — one token source. - Mesh (mcad_viewer + viewer3d.rs) was migrated too (no carve-out). ## Local CI clean - cargo fmt --all -- --check - cargo clippy --workspace --all-targets -- -D warnings - cargo test -p tokito-native: 56 passed, 0 failed ## Still ahead in this PR - Migrate consumer call sites to import tokito_ui::components directly (today they go through `crate::ui::widgets::secondary_button` etc., which is a 1-line wrapper around `tokito_ui::components::text_button`). - Delete legacy crate::ui::{widgets, layout, table, toast, typography}. Both are mechanical organisational cleanup; the visual look is final. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
kakarot-dev
added a commit
to VtronTokito/tokito
that referenced
this pull request
Jun 12, 2026
…gation) (#52) * deps(tokito_ui): bump rev to 5fc4542 — cad_tool_button + data_table + toast_overlay Bumps the tokito_ui rev to pick up the three new primitives shipped in [VtronTokito/ui#6][1]: - cad_tool_button — square toggleable CAD tool-rail button (replaces legacy `crate::ui::widgets::cad_tool_button`) - data_table + SortState + sortable_header — egui_extras-backed sortable table (replaces legacy `crate::ui::table`) - toast_overlay + ToastStack — transient bottom-right notifications (replaces legacy `crate::ui::toast`) This is the foundation slice for the editor migration — every studio file we port next (slices #37–#43 under epic #26) consumes at least one of these. [1]: VtronTokito/ui#6 cargo fmt --all -- --check: clean cargo clippy --workspace --all-targets -- -D warnings: clean cargo test -p tokito-native: 56 passed, 0 failed Closes #36 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(ui): legacy primitives delegate to tokito_ui The legacy crate::ui::{widgets, layout, toast} modules now render through tokito_ui::components under the hood. The editor's call sites (`secondary_button(ui, chrome.tokens, label)`, `filter_chip(...)`, `content_card(...)`, etc.) stay unchanged — they keep taking &UiTokens and returning the same shapes — but the actual painting goes through the shared design layer. Effect: the whole editor (chrome panels, side bars, lists, buttons, toasts) immediately picks up the new tokito_ui look without touching the 20+ files that consume these primitives. ## What changed - tokens.rs: `UiTokens::tk()` produces a `tokito_ui::Tokens` from the chrome palette. The schematic-specific colours (canvas grid, wire default/highlight/selected, ERC markers, symbol body fill) stay editor-local because they don't have a tokito_ui counterpart. - widgets.rs: `list_row`, `primary_button`, `primary_button_full`, `secondary_button` delegate to tokito_ui::components::{list_row, text_button(ButtonKind::{Primary, Secondary})}. The CAD tool rail (`cad_tool_button` + `paint_tool_icon`) stays manual because the schematic tool glyphs (wire bend, GND triangle, net label) aren't Phosphor — tokito_ui::cad_tool_button takes a glyph string. - layout.rs: `section_header`, `subsection`, `empty_state`, `content_card`, `inspector_row`, `filter_chip`, `list_section_label` delegate. The panel chrome (`panel_frame`, `dock_tab_shell`, `toolbar_actions`, `search_field`) stays editor-local — dock-specific behaviour. - toast.rs: `ToastStack` wraps `tokito_ui::components::ToastStack`; `ToastKind` mirrors the shared enum 1:1 via `From`. table.rs is unchanged — its `SortState` has a `sort_strings` convenience the tokito_ui version doesn't, and `sortable_header` doesn't take tokens. mcad_viewer/* and viewer3d.rs stay legacy as well — explicitly out of scope for this migration ("don't touch the mesh"). ## Verified locally - `cargo fmt --all -- --check`: clean - `cargo clippy --workspace --all-targets -- -D warnings`: clean - `cargo test -p tokito-native`: 56 passed, 0 failed ## Follow-up (separate PR) The slice #44 "delete legacy crate::ui::{widgets, layout, toast}" remains open. The legacy modules are now thin wrappers — when we rewrite the editor call sites to call tokito_ui directly, the modules drop. Closes #36 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(ui): real migration to tokito_ui — UiTokens deleted, schematic palette unified Round 4 of the editor migration. Real type-level migration this time: the custom UiTokens struct is gone; UiTokens is now a thin type alias for tokito_ui::Tokens, which carries both chrome and schematic palettes. ## What changed - ui/tokens.rs — replaced with `pub use tokito_ui::Tokens as UiTokens;` The 40+ schematic colour fields the editor used (canvas, wire, sym, label_ink, refdes_ink, pin_ink, selection, preview_bg, …) now live in tokito_ui::Tokens (via VtronTokito/ui#8). - theme.rs — tokens_for() returns the tokito_ui preset (dark/light) for the theme; no more hand-rolled UiTokens literal. Visuals wiring uses Stroke::new(1.0, t.border) where it previously read t.stroke_subtle, and t.rounding_*() for the Rounding-typed visual fields. - Every editor consumer file (app/studio/*, editor/*, mcad_viewer/*, viewer3d.rs, app/mod.rs, app/impl_eframe.rs, theme.rs, base_symbols.rs) was field-renamed from the legacy UiTokens names to the tokito_ui ones: text_primary → text text_secondary → text_2 text_muted → text_3 bg_app → bg bg_panel → bg_chrome bg_elevated → card bg_canvas → canvas_bg bg_hover → card_hover bg_chip_selected → accent_soft accent_dim → accent_soft spacing_xs..lg → space_1, space_2, space_4, space_5 .stroke_subtle → Stroke::new(1.0, .border) .stroke_focus → Stroke::new(1.4, .border_strong) .margin_panel → Margin::symmetric(.space_4, .space_3) - editor/tool_icons.rs — new module holding the hand-drawn schematic glyphs (Select, Place, Wire, NetLabel, Power, Junction, NoConnect, Bus, Text, Pan, Focus, ZoomFit, Grid, Snap). Designed as the closure body the new tokito_ui::components::cad_tool_button takes: c::cad_tool_button(ui, &t, 38.0, sel, "Wire", |p, r, ink| { paint(p, r, ToolIcon::Wire, ink) }); - ui/widgets.rs, ui/layout.rs, ui/toast.rs — still in place as thin wrappers; bodies now pass `tokens` directly (no more .tk() conversion). The wrappers will fold away in a final cleanup slice once consumer call sites switch to tokito_ui::components::* directly. Today they're a 1:1 trivial mapping. ## Visual + behavioural effect - Every chrome surface, button, list row, card, search field, toast in the editor now renders through tokito_ui::components. - The schematic canvas reads its palette from the same Tokens value the chrome reads — one token source. - Mesh (mcad_viewer + viewer3d.rs) was migrated too (no carve-out). ## Local CI clean - cargo fmt --all -- --check - cargo clippy --workspace --all-targets -- -D warnings - cargo test -p tokito-native: 56 passed, 0 failed ## Still ahead in this PR - Migrate consumer call sites to import tokito_ui::components directly (today they go through `crate::ui::widgets::secondary_button` etc., which is a 1-line wrapper around `tokito_ui::components::text_button`). - Delete legacy crate::ui::{widgets, layout, table, toast, typography}. Both are mechanical organisational cleanup; the visual look is final. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(ui): finish migration — call tokito_ui::components directly, delete legacy modules Editor consumers now reach into `tokito_ui::components` and `tokito_ui::Tokens` without going through `crate::ui::{widgets,layout,table,toast,tokens,typography}`. Those modules are gone; only `crate::ui::icons` (Phosphor font binding) remains. - toast: `crate::ui::toast::{ToastStack,ToastKind}` → `tokito_ui::components::*`, `.show(ctx, tokens)` → `toast_overlay(ctx, tokens, stack)`. - table: `crate::ui::table::{SortState,SortDir,sortable_header}` → tokito_ui's variants; the editor-local `data_table`/`sort_strings` helpers are dropped. - typography: `TypeRamp::small_weak/body/section/title` calls inlined as `RichText::new(...).small().weak()` / `.heading().strong()` etc. — egui's named text styles already carry the same pixel sizes (theme.rs registers Small at 11.0, matching the ramp). - tokens: `crate::ui::UiTokens` → `tokito_ui::Tokens` throughout (editor, render, base_symbols, mcad_viewer, theme). - chrome: `dock_tab_shell`, `section_header`, `subsection`, `empty_state`, `toolbar_actions` inlined into `app/studio/chrome.rs::TabChrome`. - search field on the place panel built inline against `egui::TextEdit` to preserve Enter-to-submit semantics. Gates green locally: `cargo fmt --check`, `cargo clippy --workspace --all-targets -- -D warnings`, `cargo test --workspace --locked`. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * ci(coverage): drop TOKITO_RUN_DB_INTEGRATION — gate off the flaky pg-embed test pg-embed's PostgreSQL bootstrap flakes intermittently on the Actions runner (seen here as `put_and_get_schematic_document: embedded PostgreSQL failed after retries` — same fragility that already gates pg-embed off the Windows `test` job). The DB integration tests are still run by `test (ubuntu-latest)`; coverage just leaves the env var unset so the suite self-skips them via `tokito::test_support::database_integration_tests_enabled()`. Coverage delta on the affected DB paths is small (request handlers behind a thin axum layer) and we already accept Codecov upload failures with `fail_ci_if_error: false`, so trading coverage of that slice for a stable job is the right call. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Round 3 for the Tokito editor migration. Two changes that let the editor delete `crate::ui::tokens::UiTokens` entirely and put the hand-drawn CAD tool rail through the shared `cad_tool_button` primitive.
Schematic palette in `Tokens`
Adds 19 schematic-canvas colour fields with sensible defaults in both `dark()` and `light()`:
One token source for chrome + canvas. Non-canvas consumers can ignore the schematic fields.
`cad_tool_button` paint-closure
Replaces `glyph: &str` with `FnOnce(&Painter, Rect, Color32)`. Caller decides what to draw:
```rust
// Phosphor case
cad_tool_button(ui, &t, 38.0, sel, "Wire", paint_phosphor_glyph(icons::ph::PEN_NIB))
// Hand-drawn schematic glyph
cad_tool_button(ui, &t, 38.0, sel, "Junction", |p, rect, ink| {
let c = rect.center();
let stroke = Stroke::new(1.65, ink);
p.line_segment([c - vec2(8.0, 0.0), c + vec2(8.0, 0.0)], stroke);
p.line_segment([c - vec2(0.0, 8.0), c + vec2(0.0, 8.0)], stroke);
p.circle_filled(c, 4.0, ink);
})
```
`paint_phosphor_glyph(glyph)` is the convenience helper for the common case.
Breaking signature change — no shipped consumers yet, so the explicit-closure shape wins over backwards-compatible enum variants.
Local CI
Next
After this lands, tokito#52 absorbs: