From 9dc394dfc808e1eae8c94fc56e7e12444f20013e Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Sat, 3 Oct 2026 13:12:50 -0400 Subject: [PATCH] UI: wire Paint Bucket Fill dropdown (Foreground/Pattern) to the engine The options-bar Fill dropdown was decorative. It now persists in tool_options (bucket_fill_pattern) and the click sends contents=foreground|pattern, so Pattern actually flood-fills with the current pattern. ui tests + wasm green. Co-Authored-By: Claude Opus 4.8 --- crates/ui-egui/src/canvas.rs | 3 ++- crates/ui-egui/src/panels.rs | 6 ++++-- crates/ui-egui/src/state.rs | 3 +++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/crates/ui-egui/src/canvas.rs b/crates/ui-egui/src/canvas.rs index 221af085..3dd5f28c 100644 --- a/crates/ui-egui/src/canvas.rs +++ b/crates/ui-egui/src/canvas.rs @@ -1268,7 +1268,8 @@ pub fn tool_event(app: &mut PhotocraftApp, ev: ToolEvent, mods: egui::Modifiers) } Tool::PaintBucket => { let o = app.ui.tool_options.clone(); - let _ = app.run("paint.bucket", json!({"x": x.floor(), "y": y.floor(), "tolerance": o.tolerance, "contiguous": o.contiguous, "antiAlias": o.anti_alias, "opacity": o.fill_opacity, "target": paint_target(app)})); + let contents = if o.bucket_fill_pattern { "pattern" } else { "foreground" }; + let _ = app.run("paint.bucket", json!({"x": x.floor(), "y": y.floor(), "tolerance": o.tolerance, "contiguous": o.contiguous, "antiAlias": o.anti_alias, "opacity": o.fill_opacity, "contents": contents, "target": paint_target(app)})); return; } Tool::PolygonLasso => { diff --git a/crates/ui-egui/src/panels.rs b/crates/ui-egui/src/panels.rs index c0a9aa50..c293c03b 100644 --- a/crates/ui-egui/src/panels.rs +++ b/crates/ui-egui/src/panels.rs @@ -425,8 +425,10 @@ pub fn options_bar(app: &mut PhotocraftApp, ui: &mut egui::Ui) { } Tool::PaintBucket if t.pro => { opt_label(ui, "Fill"); - let mut src = 0u8; - widgets::dropdown(ui, "bucket-src", &mut src, &[(0u8, "Foreground"), (1, "Pattern")], 100.0); + let mut src = u8::from(app.ui.tool_options.bucket_fill_pattern); + if widgets::dropdown(ui, "bucket-src", &mut src, &[(0u8, "Foreground"), (1, "Pattern")], 100.0) { + app.ui.tool_options.bucket_fill_pattern = src == 1; + } opt_label(ui, "Opacity"); widgets::value_field(ui, &mut app.ui.tool_options.fill_opacity, 1.0..=100.0, "%", 62.0); opt_label(ui, "Tolerance"); diff --git a/crates/ui-egui/src/state.rs b/crates/ui-egui/src/state.rs index f2f87370..a6928032 100644 --- a/crates/ui-egui/src/state.rs +++ b/crates/ui-egui/src/state.rs @@ -276,6 +276,8 @@ pub struct ToolOptions { pub gradient_style: String, pub gradient_reverse: bool, pub fill_opacity: f32, + /// Paint Bucket fill source: false = Foreground colour, true = Pattern (Patterns panel selection). + pub bucket_fill_pattern: bool, /// Type tool: family, style name, size (pt), anti-aliasing and paragraph alignment. pub type_font: String, pub type_style: String, @@ -359,6 +361,7 @@ impl Default for ToolOptions { gradient_style: "linear".into(), gradient_reverse: false, fill_opacity: 100.0, + bucket_fill_pattern: false, type_font: "Inter".into(), type_style: "Regular".into(), type_size: 48.0,