Merge #976: fix(ui): keep the style picker open while editing a style's colour (@kollakek1)

This commit is contained in:
bflatastic
2026-10-24 09:23:29 +07:00
3 changed files with 38 additions and 1 deletions
+9
View File
@@ -435,6 +435,12 @@ fn alpha_slider(ui: &mut Ui, rect: Rect, color: Color) -> Option<(f32, bool)> {
slider_knob(ui, rect, color.a, Id::new("cp_alpha"))
}
/// The colour picker window's area id. A fixed id (not `Window::new`'s, which egui keys by
/// `Id::new(Some(title))`) so the style picker can tell a click inside the picker from one outside.
pub fn window_id() -> Id {
Id::new("color_picker")
}
pub fn show(app: &mut FigApp, ctx: &egui::Context) {
let Some(target) = app.ui.picker.clone() else {
// A colour sampled for a picker that has closed has no paint to go to.
@@ -470,6 +476,9 @@ pub fn show(app: &mut FigApp, ctx: &egui::Context) {
let mut open = true;
let mut close_now = false;
egui::Window::new("color_picker")
// A fixed area id so the style picker can tell a click in here from a click outside
// (`Window::new` alone would key the area by `Id::new(Some(title))`).
.id(window_id())
.title_bar(false)
.fixed_pos(pos)
.fixed_size(vec2(240.0, 0.0))
+1 -1
View File
@@ -909,7 +909,7 @@ pub fn show(app: &mut FigApp, ctx: &egui::Context) {
// Clicks in the colour picker editing this picker's style, or in a menu the editor opened,
// keep it open.
let picker_rect =
app.ui.picker.as_ref().filter(|t| matches!(t, PickerTarget::Style { .. })).and(ctx.memory(|m| m.area_rect(Id::new("color_picker"))));
app.ui.picker.as_ref().filter(|t| matches!(t, PickerTarget::Style { .. })).and(ctx.memory(|m| m.area_rect(crate::colorpicker::window_id())));
// So do clicks in the variable picker binding one of its fields (Escape closes that first).
let variables = crate::variable_ui::picker_rect(ctx);
let in_popup = egui::Popup::is_any_open(ctx) || variables.is_some();
+28
View File
@@ -164,6 +164,34 @@ fn chars_linked_to_several_styles_show_mixed() {
assert_eq!(text_link(&app, &doc, &[t]), None);
}
#[test]
fn a_click_in_the_colour_picker_keeps_the_style_editor_open() {
use crate::layers_drag_tests::Ui;
let mut s = Session::new();
s.execute("style.create", &json!({"type": "paint", "name": "Brand", "value": [{"type": "solid", "color": "#0D99FF"}]})).unwrap();
let mut u = Ui::new(s);
open_for_selection(&mut u.app, StyleSlot::Fill, Some("Brand"));
for _ in 0..3 {
u.frame(vec![]);
}
let id = u.app.session.doc().unwrap().style("Brand").unwrap().id.clone();
u.app.ui.picker = Some(crate::colorpicker::PickerTarget::Style { id, index: 0 });
for _ in 0..3 {
u.frame(vec![]);
}
let cp = u.ctx.memory(|m| m.area_rect(crate::colorpicker::window_id())).expect("colour picker shows");
let p = cp.center();
u.button(p, true);
u.button(p, false);
u.frame(vec![]);
assert!(u.app.ui.style_picker.is_some(), "the style editor stays open while the colour picker is used");
assert!(
matches!(u.app.ui.picker, Some(crate::colorpicker::PickerTarget::Style { .. })),
"the colour picker stays open too: {:?}",
u.app.ui.picker
);
}
#[test]
fn local_style_drops_move_into_the_folder_above() {
let st = |id: &str, name: &str| Style {