Close a layer's colour picker when the selection changes

Fixes #396

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
NetterSilver
2026-10-15 14:15:35 +02:00
co-authored by Claude Haiku 5.5
parent 102404e8c3
commit 908906f3f4
3 changed files with 65 additions and 1 deletions
+9 -1
View File
@@ -400,7 +400,15 @@ fn alpha_slider(ui: &mut Ui, rect: Rect, color: Color) -> Option<(f32, bool)> {
pub fn show(app: &mut FigApp, ctx: &egui::Context) {
let Some(target) = app.ui.picker.clone() else { return };
let Some(mut paint) = current_paint(app, &target) else {
// A layer's picker belongs to the selection it was opened for: once that changes, close it
// rather than keep editing layers that are no longer selected.
let stale = match &target {
PickerTarget::Paint { ids, .. } | PickerTarget::Effect { ids, .. } => *ids != app.session.selection(),
PickerTarget::TextRange { id, .. } => !app.session.selection().contains(id),
_ => false,
};
let current = if stale { None } else { current_paint(app, &target) };
let Some(mut paint) = current else {
app.ui.picker = None;
return;
};
@@ -0,0 +1,54 @@
//! The colour picker of a layer's paint or effect closes when that layer is no longer the
//! selection, so it never keeps editing a layer that was deselected (#396).
use figcraft_doc::NodeId;
use figcraft_engine::Session;
use serde_json::json;
use crate::colorpicker::PickerTarget;
use crate::layers_drag_tests::Ui;
fn rect(s: &mut Session, x: f64) -> NodeId {
let v = s.execute("shape.rectangle", &json!({"x": x, "y": 0, "width": 20, "height": 20})).unwrap();
NodeId(v["id"].as_u64().unwrap())
}
fn two() -> (Ui, NodeId, NodeId) {
let mut s = Session::new();
let a = rect(&mut s, 0.0);
let b = rect(&mut s, 40.0);
s.execute("select.set", &json!({"ids": [a]})).unwrap();
(Ui::new(s), a, b)
}
#[test]
fn picker_closes_when_its_layer_is_deselected() {
for effect in [false, true] {
let (mut u, a, _) = two();
let target = if effect {
u.app.run("effect.add", json!({"ids": [a], "type": "dropShadow"}));
PickerTarget::Effect { ids: vec![a], index: 0, secondary: false }
} else {
PickerTarget::Paint { fills: true, index: 0, ids: vec![a] }
};
u.app.ui.picker = Some(target.clone());
u.frame(vec![]);
u.frame(vec![]);
assert_eq!(u.app.ui.picker, Some(target.clone()), "the picker opens while its layer is selected");
u.app.run("select.none", json!({}));
u.frame(vec![]);
u.frame(vec![]);
assert!(u.app.ui.picker.is_none(), "deselecting closes {target:?}");
}
}
#[test]
fn picker_closes_when_another_layer_is_selected() {
let (mut u, a, b) = two();
u.app.ui.picker = Some(PickerTarget::Paint { fills: true, index: 0, ids: vec![a] });
u.frame(vec![]);
u.app.run("select.set", json!({"ids": [b]}));
u.frame(vec![]);
u.frame(vec![]);
assert!(u.app.ui.picker.is_none(), "selecting another layer closes the picker: {:?}", u.app.ui.picker);
}
+2
View File
@@ -75,6 +75,8 @@ mod canvas_drag_tests;
#[cfg(test)]
mod canvas_fixes_tests;
#[cfg(test)]
mod colorpicker_selection_tests;
#[cfg(test)]
mod comments_tests;
#[cfg(test)]
mod cursors_tests;