diff --git a/crates/ui-egui/src/prepare.rs b/crates/ui-egui/src/prepare.rs index 07597c87a3..75ad8972ff 100644 --- a/crates/ui-egui/src/prepare.rs +++ b/crates/ui-egui/src/prepare.rs @@ -997,16 +997,20 @@ pub(crate) fn body(ui: &mut egui::Ui, d: &mut FieldDraft, t: &crate::theme::Toke if let Some(l) = d.look.as_mut() { widgets::section_title(ui, tl!("Borders and Colors")); egui::Grid::new("field-borders").num_columns(2).spacing([12.0, 8.0]).show(ui, |ui| { - for (label, slot) in [(tl!("Border Color:"), &mut l.border), (tl!("Fill Color:"), &mut l.fill)] { + for (index, (label, slot)) in + [(tl!("Border Color:"), &mut l.border), (tl!("Fill Color:"), &mut l.fill)].into_iter().enumerate() + { ui.label(label); - ui.horizontal(|ui| { - let mut none = slot.is_none(); - if ui.checkbox(&mut none, tl!("No color")).changed() { - *slot = if none { None } else { Some([0.0; 3]) }; - } - if let Some(c) = crate::comments::swatch_grid(ui, *slot) { - *slot = Some(c); - } + ui.push_id(("field-color", index), |ui| { + ui.horizontal(|ui| { + let mut none = slot.is_none(); + if ui.checkbox(&mut none, tl!("No color")).changed() { + *slot = if none { None } else { Some([0.0; 3]) }; + } + if let Some(c) = crate::comments::swatch_grid(ui, *slot) { + *slot = Some(c); + } + }); }); ui.end_row(); } diff --git a/crates/ui-egui/tests/prepare.rs b/crates/ui-egui/tests/prepare.rs index cd6e013244..b23f1a9f8f 100644 --- a/crates/ui-egui/tests/prepare.rs +++ b/crates/ui-egui/tests/prepare.rs @@ -7,7 +7,8 @@ use egui_kittest::kittest::Queryable; use pdfcraft_ui_egui::{PdfCraftApp, QuickTool}; fn harness() -> Harness<'static, PdfCraftApp> { - let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(|_cc| { + let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(|cc| { + cc.egui_ctx.options_mut(|options| options.warn_on_id_clash = true); let mut app = PdfCraftApp::new(); app.set_option("language", "en").unwrap(); app.open_bytes("form.pdf", None, include_bytes!("data/form.pdf").to_vec()).unwrap(); @@ -157,6 +158,27 @@ fn appearance_tab_restyles_the_field() { h.get_by_label("Appearance").click(); h.run_steps(2); h.get_by_label("Line Style:"); + fn no_grid_id_warning(shape: &egui::Shape) -> bool { + match shape { + egui::Shape::Vec(shapes) => shapes.iter().all(no_grid_id_warning), + egui::Shape::Text(text) => !text.galley.job.text.contains("Grid ID"), + _ => true, + } + } + // Check egui's actual painted diagnostics, rather than reproducing the ID formula. + assert!(h.output().shapes.iter().all(|shape| no_grid_id_warning(&shape.shape)), "palette grids must not share an ID"); + let before = h.state().field_props.as_ref().unwrap().look.unwrap(); + assert_eq!(h.get_all_by_label("No color").count(), 2); + h.get_all_by_label("No color").next().unwrap().click(); + h.run_steps(2); + let border = h.state().field_props.as_ref().unwrap().look.as_ref().unwrap().border; + assert_eq!(border, if before.border.is_some() { None } else { Some([0.0; 3]) }); + assert_eq!(h.state().field_props.as_ref().unwrap().look.as_ref().unwrap().fill, before.fill); + h.get_all_by_label("No color").nth(1).unwrap().click(); + h.run_steps(2); + let look = h.state().field_props.as_ref().unwrap().look.as_ref().unwrap(); + assert_eq!(look.border, border); + assert_eq!(look.fill, if before.fill.is_some() { None } else { Some([0.0; 3]) }); { let d = h.state_mut().field_props.as_mut().unwrap(); let l = d.look.as_mut().expect("a look");