From 72c5d974b83dc9c46b3f008becb0851f063a6da8 Mon Sep 17 00:00:00 2001 From: William Dunn Date: Mon, 12 Oct 2026 21:37:42 -0400 Subject: [PATCH] fix(ui): draw sketch constraint glyphs in red (#414) * fix(ui): draw sketch constraint glyphs in red Traditional CAD convention marks constraint glyphs in red. glyph_edge and glyph_text in both themes now use red values. glyph_bg is unchanged. The same glyph box switches to the error colour when a constraint fails. The new reds are chosen to stay distinct from that error colour. They are also distinct from the blue used for selection and hover. See the pull request body for the before and after RGB values and the contrast reasoning. * fix(ui): match constraint toolbar icons to the red glyph colour The CONSTRAINTS panel buttons and their drop-down rows drew their accent strokes in the normal sketch tool green. They now use glyph_text, the same red the matching constraint glyph box uses in the sketch view. A new panel_accent helper in toolbar.rs picks the colour: the constraint red for the CONSTRAINTS panel, the existing sketch green for every other sketch tool, and the plain accent everywhere else. No other toolbar styling changed. --- crates/ui-egui/src/theme.rs | 8 ++++---- crates/ui-egui/src/toolbar.rs | 32 ++++++++++++++++++++++++-------- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/crates/ui-egui/src/theme.rs b/crates/ui-egui/src/theme.rs index c6ce9017..d971f739 100644 --- a/crates/ui-egui/src/theme.rs +++ b/crates/ui-egui/src/theme.rs @@ -191,8 +191,8 @@ impl Tokens { subheading_bg: Color32::from_rgb(234, 237, 242), profile_fill: Color32::from_rgba_unmultiplied_const(255, 196, 120, 70), glyph_bg: Color32::WHITE, - glyph_edge: Color32::from_rgb(90, 150, 90), - glyph_text: Color32::from_rgb(40, 110, 40), + glyph_edge: Color32::from_rgb(190, 110, 100), + glyph_text: Color32::from_rgb(150, 40, 35), overlay: Color32::from_rgba_unmultiplied_const(255, 255, 255, 235), rubber_band: Color32::from_rgb(30, 120, 230), app_bar_text: Color32::from_rgb(230, 234, 242), @@ -247,8 +247,8 @@ impl Tokens { t.heading_bg = Color32::from_rgb(38, 44, 55); t.subheading_bg = Color32::from_rgb(48, 55, 68); t.glyph_bg = Color32::from_rgb(44, 50, 60); - t.glyph_edge = Color32::from_rgb(96, 170, 110); - t.glyph_text = Color32::from_rgb(150, 220, 160); + t.glyph_edge = Color32::from_rgb(200, 130, 120); + t.glyph_text = Color32::from_rgb(240, 165, 155); t.overlay = Color32::from_rgba_unmultiplied_const(34, 38, 46, 240); t.rubber_band = Color32::from_rgb(92, 160, 255); t.timeline_item = Color32::from_rgb(52, 58, 70); diff --git a/crates/ui-egui/src/toolbar.rs b/crates/ui-egui/src/toolbar.rs index 9d6e0570..768ef994 100644 --- a/crates/ui-egui/src/toolbar.rs +++ b/crates/ui-egui/src/toolbar.rs @@ -8,6 +8,19 @@ use crate::{SolveApp, icons}; pub const TABS: &[&str] = &["SOLID", "SURFACE", "MESH", "SHEET METAL", "PLASTIC", "UTILITIES"]; +/// The accent stroke colour for a panel's icons: constraint commands use the same red as the +/// constraint glyphs they draw in the sketch (`glyph_text`), sketch tools otherwise keep +/// `sketch_accent`, and every other tab keeps the plain `accent`. +fn panel_accent(t: Tokens, tab: &str, panel: &str) -> Color32 { + if panel == "CONSTRAINTS" { + t.glyph_text + } else if tab == "SKETCH" { + t.sketch_accent + } else { + t.accent + } +} + /// Panels shown on each tab (in order). Commands come from the registry by (tab, panel). pub fn panels(tab: &str) -> &'static [&'static str] { if let Some(p) = crate::workspace::panels(tab) { @@ -582,7 +595,7 @@ pub fn toolbar(app: &mut SolveApp, ui: &mut egui::Ui) { painter.rect_filled(br, 4.0, t.hover); } if let Some(c) = shown.first().or(cmds.first()) { - let acc = if tab == "SKETCH" { t.sketch_accent } else { t.accent }; + let acc = panel_accent(t, &tab, panel); icons::paint(&painter, Rect::from_center_size(br.center() - vec2(0.0, 3.0), vec2(26.0, 26.0)), c.icon, t.icon, t.icon_fill, acc); } caret(&painter, pos2(br.center().x, br.bottom() - 3.0), t.text_dim); @@ -621,11 +634,8 @@ pub fn toolbar(app: &mut SolveApp, ui: &mut egui::Ui) { } else if resp.hovered() && info.enabled { painter.rect_filled(br, 4.0, t.hover); } - let (ink, fill, acc) = if info.enabled { - (t.icon, t.icon_fill, if tab == "SKETCH" { t.sketch_accent } else { t.accent }) - } else { - (t.border, t.panel_header, t.border) - }; + let (ink, fill, acc) = + if info.enabled { (t.icon, t.icon_fill, panel_accent(t, &tab, panel)) } else { (t.border, t.panel_header, t.border) }; let icon = match c.id { "sketch.finish" => "finish", "config.table" => "configuration_table", @@ -876,8 +886,14 @@ fn dropdown_row(app: &SolveApp, ui: &mut egui::Ui, c: &'static solidcraft_engine p.rect_filled(rect, 3.0, t.hover); crate::scenario::publish_handle(&format!("dropdown_hot:{}", c.id), rect.center()); } - let (ink, fill, acc, text) = - if info.enabled { (t.icon, t.icon_fill, t.accent, t.text) } else { (t.border, t.panel_header, t.border, t.text_dim) }; + // Every other row keeps the plain accent it always has; only a constraint command's row + // switches to the constraint red, to match its button on the ribbon. + let (ink, fill, acc, text) = if info.enabled { + let acc = if c.panel == "CONSTRAINTS" { t.glyph_text } else { t.accent }; + (t.icon, t.icon_fill, acc, t.text) + } else { + (t.border, t.panel_header, t.border, t.text_dim) + }; let ir = Rect::from_center_size(pos2(rect.left() + 6.0 + 9.0, rect.center().y), vec2(18.0, 18.0)); icons::paint(p, ir, c.icon, ink, fill, acc); p.text(pos2(ir.right() + 8.0, rect.center().y), Align2::LEFT_CENTER, &label, FontId::proportional(13.0), text);