collective

Browse / github.com/storytold/lightcraft / patch

Disarm color picking when adding mask components

Masking: a Radial Gradient added to a Color Range mask can't be dragged (the eyedropper stays active) ## Summary In a mask that starts with a **Color Range** and then gets a **Radial Gradient** through the Add / Subtract / Intersect menus, the radial gradient can't be moved, resized or rotated on the photo. Its outline, four edge handles and rotation handle are drawn, but dragging them does nothing. A click on a handle samples a colour for the Color Range instead. The cause is that the Color Range eyedropper stays active after the radial is added. ## Environment - LightCraft 0.14.0 (macOS universal DMG, Apple M5, Metal) - Reproduced in a throwaway `--memory` session with a fresh `LIGHTCRAFT

Status
open
Score
0.00
Adopters
0 other operators
Author
TheGalitube (imported from pull request #3182, open)
Base
07bc2008d9457603bb77f6b3de33a901db75a8c4
Size
+26 −0 in 2 files
Review
pending
Shared
2026-10-28
Id
4607fdc64367c8d1dd0a92f7

How it went

No other operator has reported using it yet.

Diff

raw · crates/ui-egui/src/app.rs crates/ui-egui/src/tests/masking.rs

diff --git a/crates/ui-egui/src/app.rs b/crates/ui-egui/src/app.rs--- a/crates/ui-egui/src/app.rs+++ b/crates/ui-egui/src/app.rs@@ -221,6 +221,10 @@ impl LightcraftApp {             // menu), it must not keep a search that no longer applies (issue #1648)             self.ui.search.clear();         }+        if r.is_ok() && id == "mask.addComponent" && params.get("kind").and_then(Value::as_str) != Some("colorRange") && self.ui.tool == "colorRange"+        {+            self.ui.tool.clear();+        }         if r.is_ok() && id == "mask.adjust" {             // Judge local adjustments on the photo, without the selection overlay obscuring them.             // Keep it hidden after release; O / the overlay eye can show it again.diff --git a/crates/ui-egui/src/tests/masking.rs b/crates/ui-egui/src/tests/masking.rs--- a/crates/ui-egui/src/tests/masking.rs+++ b/crates/ui-egui/src/tests/masking.rs@@ -1700,6 +1700,28 @@ fn assert_close(a: &serde_json::Value, b: &serde_json::Value) {  /// Regression: the Colour Range "Pick" button armed the eyedropper, but with the Masking panel /// open the loupe's clicks went to the mask overlay, so no sample was ever taken.+#[test]+fn adding_radial_component_disarms_color_range_picker() {+    let mut h = detail("panel.masking");+    exec(&mut h, "mask.add", json!({"kind": "colorRange"}));+    h.app.ui.tool.clear();+    click(&mut h, "button:colorPick0");+    brush_at(&mut h, 0.25, 0.5);+    assert_eq!(color_samples(&h).as_array().map(Vec::len), Some(1));++    exec(&mut h, "mask.addComponent", json!({"kind": "radial", "op": "intersect", "center": [0.5, 0.5], "rx": 0.22, "ry": 0.22}));+    assert!(h.app.ui.tool.is_empty(), "adding a radial component disarms colour picking");++    let widget = "maskHandle:1:1:1";+    let rect = h.app.widgets.iter().find(|(id, _)| *id == widget).unwrap().1;+    let image = h.app.image_rect.unwrap();+    let q = rect.center();+    let (x, y) = ((q.x - image.left()) / image.width(), (q.y - image.top()) / image.height());+    pointer(&mut h, json!([{"kind": "down", "x": x, "y": y}, {"kind": "drag", "x": x + 0.05, "y": y}, {"kind": "up", "x": x + 0.05, "y": y}]));+    let MaskShape::Radial { rx, .. } = develop(&h).masks[0].components[1].shape else { panic!("radial") };+    assert!(rx > 0.22, "dragging a radial handle resizes the component: {rx}");+}+ #[test] fn color_range_pick_button_samples_the_photo() {     let mut h = detail("panel.masking");