Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ src/
`text_button`, `link`, `badge`, `menu_button`, `menu_item`, `list_row`,
`text_input`, `search_field`, `secret_input`, `toggle`, `modal`,
`page_header`, `section_header`, `nav_item`, `checkbox`, `segmented`,
`select`, `select_option`, `banner`, `collapsing`, `cad_tool_button`,
`data_table` (+ `SortState`, `sortable_header`), `toast_overlay`
(+ `ToastStack`), `chip`, `content_card`, `inspector_row`,
`list_section_label`, `empty_state`.
`select`, `select_option`, `banner`, `collapsing`, `cad_tool_button`
(+ `paint_phosphor_glyph`), `data_table` (+ `SortState`,
`sortable_header`), `toast_overlay` (+ `ToastStack`), `chip`,
`content_card`, `inspector_row`, `list_section_label`, `empty_state`.

## Rules — keep these true

Expand Down
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,13 @@ It is `#[non_exhaustive]` — new fields can be added without breaking you.
Groups: surfaces (`bg`, `bg_chrome`, `card`, `card_hover`), borders
(`border`, `border_soft`, `border_strong`), text (`text`, `text_2`, `text_3`,
`text_disabled`), accents (`accent`, `accent_ink`, `accent_soft`, `accent_2`,
`accent_2_soft`), status (`danger`, `warning`, `success`), and metrics
(`radius_*`, `space_1..5`).
`accent_2_soft`), status (`danger`, `warning`, `success`), metrics
(`radius_*`, `space_1..5`), and a **schematic palette** for CAD canvas use
(`canvas_bg`, `canvas_grid_minor`, `canvas_grid_major`, `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`).
Non-canvas consumers can ignore the schematic fields.

## Components

Expand Down Expand Up @@ -119,7 +124,7 @@ All live in `tokito_ui::components` (aliased `c` above). Each takes
| `select_option` | `select_option(ui, t, label, selected) -> bool` | One option row inside a `select` popup. |
| `banner` | `banner(ui, t, kind, glyph, title, body) -> Response` | A status callout — `BannerKind::Success` / `Danger` / `Warning` / `Info`. |
| `collapsing` | `collapsing(ui, t, id_source, label, \|ui\| …)` | A collapsible "Advanced options" disclosure section. |
| `cad_tool_button` | `cad_tool_button(ui, t, glyph, side, selected, tooltip) -> Response` | A square, toggleable CAD tool-rail button — accent border + soft fill when selected. |
| `cad_tool_button` + `paint_phosphor_glyph` | `cad_tool_button(ui, t, side, selected, tooltip, \|p, r, ink\| …)` | A square, toggleable CAD tool-rail button. Caller paints the icon via the closure — pass `paint_phosphor_glyph(GLYPH)` for Phosphor, or paint hand-drawn schematic strokes. |
| `data_table` + `sortable_header` | `data_table(ui, t, id, headers, cols, &mut SortState, n, h, \|row, i\| …)` | A scrollable [`egui_extras::TableBuilder`] table with click-to-sort column headers. |
| `toast_overlay` + `ToastStack` | `toast_overlay(ctx, t, &mut ToastStack)` | Transient bottom-right notifications. `ToastStack` is the owned queue; push from anywhere, paint once per frame. |
| `chip` | `chip(ui, t, label, selected) -> bool` | A small toggleable pill — filter chip / tag. Returns `true` on click. |
Expand Down
54 changes: 38 additions & 16 deletions src/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1055,20 +1055,28 @@ fn lighten(c: Color32, amount: f32) -> Color32 {
/// A square, toggleable CAD-tool-rail button.
///
/// Used for the left-side tool rail in a schematic / PCB editor (select,
/// wire, label, bus, etc.). `glyph` is a Phosphor constant; `side` is the
/// width and height; `selected` paints the active state (accent border +
/// soft accent fill); `tooltip` shows on hover.
/// wire, label, bus, etc.). `side` is the width and height; `selected` paints
/// the active state (accent border + soft accent fill); `tooltip` shows on
/// hover.
///
/// Hover eases an underlay fill in; the icon ink is `accent` when selected,
/// `text` otherwise.
pub fn cad_tool_button(
/// `paint_icon` is invoked with the button's `Painter`, the inner `Rect`, and
/// the current ink colour — the caller decides what symbol to draw (Phosphor
/// glyph, hand-drawn schematic strokes, an image, whatever). For the common
/// Phosphor case, use [`paint_phosphor_glyph`] as the closure.
///
/// Hover eases an underlay fill in; the ink is `accent` when selected,
/// `text` otherwise (interpolated with `text_2` on hover).
pub fn cad_tool_button<F>(
ui: &mut Ui,
t: &Tokens,
glyph: &str,
side: f32,
selected: bool,
tooltip: &str,
) -> Response {
paint_icon: F,
) -> Response
where
F: FnOnce(&egui::Painter, Rect, Color32),
{
let (rect, mut response) = ui.allocate_exact_size(Vec2::splat(side), Sense::click());

let factor = hover_t(ui, response.id, response.hovered());
Expand All @@ -1093,21 +1101,35 @@ pub fn cad_tool_button(
} else {
lerp_color(t.text_2, t.text, factor)
};
let glyph_size = (side * 0.5).clamp(14.0, 24.0);
painter.text(
rect.center(),
egui::Align2::CENTER_CENTER,
glyph,
icons::font(glyph_size),
ink,
);
paint_icon(painter, rect, ink);

if !tooltip.is_empty() {
response = response.on_hover_text(tooltip);
}
response
}

/// Helper closure for [`cad_tool_button`] that paints a centred Phosphor
/// glyph at a sensible size for the button.
///
/// Usage:
/// ```ignore
/// cad_tool_button(ui, &t, 38.0, selected, "Wire", paint_phosphor_glyph(icons::ph::PEN_NIB))
/// ```
pub fn paint_phosphor_glyph(glyph: &'static str) -> impl FnOnce(&egui::Painter, Rect, Color32) {
move |painter, rect, ink| {
let side = rect.width().min(rect.height());
let glyph_size = (side * 0.5).clamp(14.0, 24.0);
painter.text(
rect.center(),
egui::Align2::CENTER_CENTER,
glyph,
icons::font(glyph_size),
ink,
);
}
}

// ---------------------------------------------------------------------------
// table
// ---------------------------------------------------------------------------
Expand Down
95 changes: 95 additions & 0 deletions src/tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,59 @@ pub struct Tokens {
pub space_3: f32,
pub space_4: f32,
pub space_5: f32,

// -----------------------------------------------------------------------
// Schematic palette
// -----------------------------------------------------------------------
//
// These describe colours for a schematic / CAD-style canvas. They live
// here (in the shared design layer) so a consumer's editor canvas pulls
// from the same `Tokens` value that drives its chrome — one token source.
//
// A non-canvas consumer can ignore these fields; the presets below pick
// reasonable defaults.
/// Schematic sheet background.
pub canvas_bg: Color32,
/// Minor grid line — quiet, for the dense grid step.
pub canvas_grid_minor: Color32,
/// Major grid line — stronger, every Nth grid step.
pub canvas_grid_major: Color32,
/// Sheet frame border / title block strokes.
pub canvas_frame: Color32,

/// Symbol body ink — schematic outlines at rest.
pub sym_ink: Color32,
/// Symbol body fill — pale KiCad-style component body.
pub sym_body_fill: Color32,
/// Symbol body ink when hovered.
pub sym_ink_hover: Color32,
/// Symbol body ink when selected.
pub sym_ink_selected: Color32,
/// Subtle outline ring (anti-aliasing halo, soft separators).
pub sym_outline: Color32,
/// Selection ring around the symbol bounding box.
pub sym_sel_ring: Color32,

/// Wire — default ink.
pub wire: Color32,
/// Wire — highlighted (same net under cursor / search match).
pub wire_highlight: Color32,
/// Wire — selected.
pub wire_selected: Color32,

/// Net label ink.
pub label_ink: Color32,
/// Reference designator ink.
pub refdes_ink: Color32,
/// Pin name / number ink.
pub pin_ink: Color32,
/// Pin "hot" ink — active connection point, current drag.
pub pin_hot: Color32,

/// Marquee / multi-select fill.
pub selection: Color32,
/// Preview backdrop (place-tool ghost, drag preview).
pub preview_bg: Color32,
}

impl Tokens {
Expand Down Expand Up @@ -116,6 +169,27 @@ impl Tokens {
space_3: 12.0,
space_4: 16.0,
space_5: 24.0,
// Schematic palette — dark variant. Cool teal-ink schematic
// against a deep slate sheet, warm orange selection ring.
canvas_bg: Color32::from_rgb(0x14, 0x16, 0x1c),
canvas_grid_minor: Color32::from_rgba_unmultiplied(0x60, 0x64, 0x70, 0x1c),
canvas_grid_major: Color32::from_rgba_unmultiplied(0x7a, 0x80, 0x8c, 0x34),
canvas_frame: Color32::from_rgb(0x4a, 0x4f, 0x5a),
sym_ink: Color32::from_rgb(0xe6, 0xe8, 0xec),
sym_body_fill: Color32::from_rgb(0x22, 0x24, 0x2a),
sym_ink_hover: Color32::from_rgb(0x2d, 0xd4, 0xbf),
sym_ink_selected: Color32::from_rgb(0xff, 0xff, 0xff),
sym_outline: Color32::from_rgb(0x2a, 0x2c, 0x32),
sym_sel_ring: Color32::from_rgb(0xe0, 0x78, 0x20),
wire: Color32::from_rgb(0x9d, 0xc7, 0xff),
wire_highlight: Color32::from_rgb(0x2d, 0xd4, 0xbf),
wire_selected: Color32::from_rgb(0xe0, 0x78, 0x20),
label_ink: Color32::from_rgb(0xb9, 0xc7, 0xdc),
refdes_ink: Color32::from_rgb(0x9a, 0x9d, 0xa7),
pin_ink: Color32::from_rgb(0xa8, 0xb0, 0xbe),
pin_hot: Color32::from_rgb(0xe0, 0x78, 0x20),
selection: Color32::from_rgba_unmultiplied(0xe0, 0x78, 0x20, 0x33),
preview_bg: Color32::from_rgb(0x1a, 0x1c, 0x22),
}
}

Expand Down Expand Up @@ -151,6 +225,27 @@ impl Tokens {
space_3: 12.0,
space_4: 16.0,
space_5: 24.0,
// Schematic palette — light variant. Schematic-ink (near-black)
// on a soft slate sheet; same warm orange selection.
canvas_bg: Color32::from_rgb(0xf4, 0xf7, 0xfa),
canvas_grid_minor: Color32::from_rgba_unmultiplied(0x8c, 0x94, 0x9e, 0x1c),
canvas_grid_major: Color32::from_rgba_unmultiplied(0x78, 0x80, 0x8c, 0x34),
canvas_frame: Color32::from_rgb(0xa8, 0xae, 0xb8),
sym_ink: Color32::from_rgb(0x1c, 0x20, 0x26),
sym_body_fill: Color32::from_rgb(0xff, 0xfb, 0xde),
sym_ink_hover: Color32::from_rgb(0x14, 0x34, 0x5c),
sym_ink_selected: Color32::from_rgb(0x10, 0x14, 0x1a),
sym_outline: Color32::from_rgb(0xfa, 0xfb, 0xfc),
sym_sel_ring: Color32::from_rgb(0xe0, 0x78, 0x20),
wire: Color32::from_rgb(0x30, 0x5e, 0x84),
wire_highlight: Color32::from_rgb(0x14, 0x84, 0x76),
wire_selected: Color32::from_rgb(0xe0, 0x78, 0x20),
label_ink: Color32::from_rgb(0x28, 0x48, 0x6c),
refdes_ink: Color32::from_rgb(0x30, 0x36, 0x3e),
pin_ink: Color32::from_rgb(0x48, 0x58, 0x6c),
pin_hot: Color32::from_rgb(0xe0, 0x78, 0x20),
selection: Color32::from_rgba_unmultiplied(0xe0, 0x78, 0x20, 0x33),
preview_bg: Color32::from_rgb(0xf4, 0xf5, 0xf7),
}
}

Expand Down
Loading