From ccadeef41a95eb4d641ef80361070339c0a3728d Mon Sep 17 00:00:00 2001 From: BFlat Date: Fri, 9 Oct 2026 08:08:06 +0700 Subject: [PATCH] Fix #1357: every Layer Style effect row shows its checkbox (#1422) * Fix #1357: every Layer Style effect row shows its checkbox An effect not on the layer yet was drawn as a greyed label with no checkbox, so the box only appeared after the effect had been turned on and off once. Those rows now draw an empty checkbox too, as in Photoshop; a click on the row still adds the effect turned on. The checkbox drawing is shared by both kinds of row. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01UHgFEHEsefoQoBParH47JA * Layer Style test: count the effect list's checkboxes, not the pane's Main's Blending Options pane now draws checkboxes of its own, so the test counts the leftmost column only. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01UHgFEHEsefoQoBParH47JA --------- Co-authored-by: Claude --- crates/ui-egui/src/layer_style.rs | 65 ++++++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 9 deletions(-) diff --git a/crates/ui-egui/src/layer_style.rs b/crates/ui-egui/src/layer_style.rs index 5e50c736e1..acba9a3eb4 100644 --- a/crates/ui-egui/src/layer_style.rs +++ b/crates/ui-egui/src/layer_style.rs @@ -678,6 +678,22 @@ fn save_new_style(app: &mut PhotocraftApp, f: &Map) { } /// Dialog body (left list, right parameters). +/// The enable checkbox of an effect row. +fn fx_checkbox_rect(row: egui::Rect) -> egui::Rect { + egui::Rect::from_min_size(row.min + vec2(6.0, 6.0), vec2(14.0, 14.0)) +} + +/// An effect row's checkbox: an accent box with a tick when on, an outline when off. +fn fx_checkbox(p: &egui::Painter, cb: egui::Rect, on: bool, t: &Tokens) { + if on { + p.rect_filled(cb, 2.0, t.accent); + p.line_segment([cb.left_center() + vec2(3.0, 0.5), cb.center_bottom() + vec2(-1.0, -3.5)], Stroke::new(1.8, Color32::WHITE)); + p.line_segment([cb.center_bottom() + vec2(-1.0, -3.5), cb.right_top() + vec2(-3.0, 3.5)], Stroke::new(1.8, Color32::WHITE)); + } else { + p.rect_stroke(cb, 2.0, Stroke::new(1.5, t.text_faint), StrokeKind::Inside); + } +} + pub fn body(app: &mut PhotocraftApp, ui: &mut egui::Ui, f: &mut Map) { let t = Tokens::get(ui.ctx()); let selected = f.get("selected").and_then(Value::as_str).unwrap_or("dropShadow").to_string(); @@ -716,11 +732,13 @@ pub fn body(app: &mut PhotocraftApp, ui: &mut egui::Ui, f: &mut Map = h + .output() + .shapes + .iter() + .filter_map(|c| match &c.shape { + egui::Shape::Rect(r) if r.rect.size() == vec2(14.0, 14.0) && r.stroke.width > 0.0 => Some(r.rect), + _ => None, + }) + .collect(); + // The effect list is the leftmost column; the selected pane draws checkboxes of its own. + let column = boxes.iter().map(|r| r.min.x).fold(f32::INFINITY, f32::min); + let rows = boxes.iter().filter(|r| (r.min.x - column).abs() < 0.5).count(); + assert_eq!(rows, KINDS.len(), "one empty checkbox per effect row"); + } + #[test] fn every_kind_has_spec_and_defaults() { for &(kind, _) in KINDS {