Three readable line type icons in the Sketch Palette, with construction orange moved to a caller contract (#747)
The Sketch Palette's line types are three drawn icons (solid, one gap, gap with a dot) instead of text glyphs, and the construction orange is now chosen by the caller (`fixed_accent` on the toolbar) rather than hardcoded in the icons.
This commit is contained in:
1 parent
aae70053ee
commit
4a989f6e2d
5 files changed
+308
-33
No files matched your search
@@ -21,6 +21,28 @@ fn panel_accent(t: Tokens, tab: &str, panel: &str) -> Color32 {
|
||||
}
|
||||
}
|
||||
|
||||
/// The accent stroke colour a command's icon keeps on every surface that draws it, where the
|
||||
/// command's own meaning fixes it. Construction geometry carries one fixed meaning across the
|
||||
/// whole app. `sketch.construction` and `sketch.centerline` therefore draw their icon in the
|
||||
/// theme's construction orange on the ribbon, in a panel's drop-down and under the pointer while
|
||||
/// being dragged. The Sketch Palette's own line type buttons pass that same orange. `icons::paint`
|
||||
/// draws both of these icon names in the accent its caller hands it, never in a colour of its own.
|
||||
/// The caller is the only place the rule can live. Every other command has no fixed colour. It
|
||||
/// keeps the accent of whichever surface draws it.
|
||||
fn fixed_accent(t: Tokens, id: &str) -> Option<Color32> {
|
||||
match id {
|
||||
"sketch.construction" | "sketch.centerline" => Some(t.construction_geom),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// The accent stroke colour for one command's icon on the ribbon. It covers the command's own
|
||||
/// button and a collapsed panel's single button. A command with a `fixed_accent` keeps that.
|
||||
/// Every other command takes its `panel_accent`.
|
||||
fn command_accent(t: Tokens, tab: &str, panel: &str, id: &str) -> Color32 {
|
||||
fixed_accent(t, id).unwrap_or_else(|| panel_accent(t, tab, panel))
|
||||
}
|
||||
|
||||
/// 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) {
|
||||
@@ -605,7 +627,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 = panel_accent(t, &tab, panel);
|
||||
let acc = command_accent(t, &tab, panel, c.id);
|
||||
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);
|
||||
@@ -655,8 +677,11 @@ 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, panel_accent(t, &tab, panel)) } else { (t.border, t.panel_header, t.border) };
|
||||
let (ink, fill, acc) = if info.enabled {
|
||||
(t.icon, t.icon_fill, command_accent(t, &tab, panel, selected.id))
|
||||
} else {
|
||||
(t.border, t.panel_header, t.border)
|
||||
};
|
||||
let icon = match selected.id {
|
||||
"sketch.finish" => "finish",
|
||||
"config.table" => "configuration_table",
|
||||
@@ -941,10 +966,11 @@ 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());
|
||||
}
|
||||
// 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.
|
||||
// Every other row keeps the plain accent it always has. A constraint command's row switches
|
||||
// to the constraint red, to match its button on the ribbon. A command with a `fixed_accent`
|
||||
// keeps that colour ahead of either.
|
||||
let (ink, fill, acc, text) = if info.enabled {
|
||||
let acc = if c.panel == "CONSTRAINTS" { t.glyph_text } else { t.accent };
|
||||
let acc = fixed_accent(t, c.id).unwrap_or(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)
|
||||
@@ -1078,7 +1104,7 @@ fn drag_ghost(ctx: &egui::Context, id: &str, at: egui::Pos2, removing: bool) {
|
||||
let p = ctx.layer_painter(egui::LayerId::new(egui::Order::Tooltip, egui::Id::new("sc_toolbar_drag")));
|
||||
let r = Rect::from_center_size(at + vec2(14.0, 16.0), vec2(30.0, 30.0));
|
||||
p.rect(r, 4.0, t.toolbar.gamma_multiply(0.92), Stroke::new(1.0, if removing { t.error } else { t.accent }), egui::StrokeKind::Inside);
|
||||
icons::paint(&p, r.shrink(5.0), c.icon, t.icon, t.icon_fill, t.accent);
|
||||
icons::paint(&p, r.shrink(5.0), c.icon, t.icon, t.icon_fill, fixed_accent(t, c.id).unwrap_or(t.accent));
|
||||
if removing {
|
||||
let s = Stroke::new(2.0, t.error);
|
||||
let x = Rect::from_center_size(r.right_top(), vec2(9.0, 9.0));
|
||||
@@ -1523,3 +1549,66 @@ mod panel_drop_tests {
|
||||
h.step(&json!({"expect":{"handle_order":["button:solid.scale","button:solid.extrude"]}})).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod icon_accent_tests {
|
||||
use super::*;
|
||||
|
||||
/// `icons.rs` pins one half of the construction icon contract. `construction` and
|
||||
/// `centerline` take their colour from whatever accent their caller hands over. That half
|
||||
/// stays green when the caller hands over the wrong colour. That is exactly what the toolbar
|
||||
/// did. This pins the other half: the colour the toolbar actually passes for those two
|
||||
/// commands, on every surface the toolbar draws them on.
|
||||
#[test]
|
||||
fn the_toolbar_passes_construction_orange_for_both_line_type_commands() {
|
||||
for t in [Tokens::light(), Tokens::dark()] {
|
||||
// The regression itself: the SKETCH tab's accent is green. These two icons drew in
|
||||
// it. Construction orange has to be a colour no panel accent can supply.
|
||||
assert_ne!(t.construction_geom, t.sketch_accent, "construction orange must differ from the sketch accent");
|
||||
assert_ne!(t.construction_geom, t.accent, "construction orange must differ from the plain accent");
|
||||
assert_ne!(t.construction_geom, t.glyph_text, "construction orange must differ from the constraint red");
|
||||
for id in ["sketch.construction", "sketch.centerline"] {
|
||||
assert_eq!(fixed_accent(t, id), Some(t.construction_geom), "{id} must have a fixed accent");
|
||||
// Its ribbon button, a collapsed panel's single button, and a drop-down row.
|
||||
assert_eq!(command_accent(t, "SKETCH", "CREATE", id), t.construction_geom, "{id} on the SKETCH ribbon");
|
||||
assert_eq!(command_accent(t, "SOLID", "CREATE", id), t.construction_geom, "{id} on the SOLID ribbon");
|
||||
assert_eq!(fixed_accent(t, id).unwrap_or(t.accent), t.construction_geom, "{id} in a drop-down row");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Those two and no others. Every other command's icon keeps the accent of the panel it sits
|
||||
/// on, so the constraint red and the sketch green both survive the exception above.
|
||||
#[test]
|
||||
fn no_other_command_overrides_the_accent_of_its_own_panel() {
|
||||
let t = Tokens::light();
|
||||
let specs = solidcraft_engine::command_specs();
|
||||
let mut fixed: Vec<&str> = specs.iter().map(|c| c.id).filter(|id| fixed_accent(t, id).is_some()).collect();
|
||||
fixed.sort_unstable();
|
||||
assert_eq!(fixed, ["sketch.centerline", "sketch.construction"], "only the two line type commands fix their own accent");
|
||||
for c in &specs {
|
||||
if fixed.contains(&c.id) {
|
||||
continue;
|
||||
}
|
||||
let want = panel_accent(t, c.tab, c.panel);
|
||||
assert_eq!(command_accent(t, c.tab, c.panel, c.id), want, "{} must keep the accent of its own panel", c.id);
|
||||
}
|
||||
// The fix did not flatten every icon to one colour. A sketch tool is still green, a
|
||||
// constraint still red, a solid tool still blue. A missing id fails this as well.
|
||||
let accent_of = |id: &str| solidcraft_engine::find_command(id).map(|c| command_accent(t, c.tab, c.panel, c.id));
|
||||
assert_eq!(accent_of("sketch.text"), Some(t.sketch_accent));
|
||||
assert_eq!(accent_of("sketch.constraint.polygon"), Some(t.glyph_text));
|
||||
assert_eq!(accent_of("solid.extrude"), Some(t.accent));
|
||||
}
|
||||
|
||||
/// Both line type commands sit on the SKETCH tab's CREATE panel. The accent above is
|
||||
/// therefore a colour a person can actually see. Their icons are the two `icons.rs` draws
|
||||
/// from the caller's accent.
|
||||
#[test]
|
||||
fn both_line_type_commands_are_create_panel_commands_with_their_own_icons() {
|
||||
for (id, icon) in [("sketch.construction", "construction"), ("sketch.centerline", "centerline")] {
|
||||
let seen = solidcraft_engine::find_command(id).map(|c| (c.tab, c.panel, c.icon));
|
||||
assert_eq!(seen, Some(("SKETCH", "CREATE", icon)), "{id} must be on the SKETCH CREATE panel");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user