From aec3a22fdfa764b431fa0caa24f9c980456e5cb6 Mon Sep 17 00:00:00 2001 From: Ahmed5Emad Date: Sun, 18 Oct 2026 20:24:12 +0300 Subject: [PATCH] M2: shut padding pair fields edit their own axis The closed Spacing row paired each icon with the other axis: the side-bars field wrote top/bottom and the top/bottom-bars field wrote left/right. The H field now binds paddingHorizontal (left+right) and the V field paddingVertical (top+bottom); the PaddingH/PaddingV paintings were swapped to match so every icon is pixel-identical. (shut_pair_fields_edit_their_own_axis). --- crates/ui-egui/src/icons.rs | 14 ++++---- crates/ui-egui/src/layout_panel.rs | 30 ++++++++--------- .../ui-egui/src/padding_individual_tests.rs | 32 +++++++++++++++++++ 3 files changed, 54 insertions(+), 22 deletions(-) diff --git a/crates/ui-egui/src/icons.rs b/crates/ui-egui/src/icons.rs index f4f2f31b..d9cb32cc 100644 --- a/crates/ui-egui/src/icons.rs +++ b/crates/ui-egui/src/icons.rs @@ -938,17 +938,17 @@ fn draw(p: &P, icon: Icon) { p.line(3.0, 7.5, 13.0, 7.5); } PaddingH => { - // The horizontal axis: bars across the top and bottom in their frame. - p.rect(2.5, 2.5, 13.5, 13.5, 1.0); - p.fill_rect(2.5, 2.5, 13.5, 5.5, 1.0); - p.fill_rect(2.5, 10.5, 13.5, 13.5, 1.0); - } - PaddingV => { - // The vertical axis: bars down the left and right in their frame. + // Horizontal padding: bars down the padded left and right sides in their frame. p.rect(2.5, 2.5, 13.5, 13.5, 1.0); p.fill_rect(2.5, 2.5, 5.5, 13.5, 1.0); p.fill_rect(10.5, 2.5, 13.5, 13.5, 1.0); } + PaddingV => { + // Vertical padding: bars across the padded top and bottom in their frame. + p.rect(2.5, 2.5, 13.5, 13.5, 1.0); + p.fill_rect(2.5, 2.5, 13.5, 5.5, 1.0); + p.fill_rect(2.5, 10.5, 13.5, 13.5, 1.0); + } PaddingTop => { p.rect(2.5, 2.5, 13.5, 13.5, 1.0); p.fill_rect(2.5, 2.5, 13.5, 5.5, 1.0); diff --git a/crates/ui-egui/src/layout_panel.rs b/crates/ui-egui/src/layout_panel.rs index 72d44b9a..9f69c6c4 100644 --- a/crates/ui-egui/src/layout_panel.rs +++ b/crates/ui-egui/src/layout_panel.rs @@ -456,21 +456,6 @@ fn spacing(app: &mut FigApp, ui: &mut Ui, ids: &[NodeId], l: &AutoLayout) { } row(ui, 32.0, |ui| { // Sides that disagree show both values ("16,54") instead of "Mixed". - let v_pair = format!("{},{}", widgets::fmt_num(pt), widgets::fmt_num(pb)); - let v_empty = if pt == pb { tr("Mixed") } else { v_pair.as_str() }; - let e = crate::variable_ui::number_field_or( - app, - ui, - ids, - "paddingVertical", - Id::new("al_padv"), - (pt == pb).then_some(pt), - col, - v_empty, - Lead::Icon(Icon::PaddingV, tr("Vertical padding")), - "", - ); - app.field(ids, "paddingVertical", e, |v| json!(v.max(0.0))); let h_pair = format!("{},{}", widgets::fmt_num(pl), widgets::fmt_num(pr)); let h_empty = if pl == pr { tr("Mixed") } else { h_pair.as_str() }; let e = crate::variable_ui::number_field_or( @@ -486,6 +471,21 @@ fn spacing(app: &mut FigApp, ui: &mut Ui, ids: &[NodeId], l: &AutoLayout) { "", ); app.field(ids, "paddingHorizontal", e, |v| json!(v.max(0.0))); + let v_pair = format!("{},{}", widgets::fmt_num(pt), widgets::fmt_num(pb)); + let v_empty = if pt == pb { tr("Mixed") } else { v_pair.as_str() }; + let e = crate::variable_ui::number_field_or( + app, + ui, + ids, + "paddingVertical", + Id::new("al_padv"), + (pt == pb).then_some(pt), + col, + v_empty, + Lead::Icon(Icon::PaddingV, tr("Vertical padding")), + "", + ); + app.field(ids, "paddingVertical", e, |v| json!(v.max(0.0))); if icons::button(ui, Icon::IndependentPadding, 24.0, false, tr("Individual padding")).clicked() { ui.data_mut(|d| d.insert_temp(Id::new("indep_padding"), true)); } diff --git a/crates/ui-egui/src/padding_individual_tests.rs b/crates/ui-egui/src/padding_individual_tests.rs index e6397033..8fdb3192 100644 --- a/crates/ui-egui/src/padding_individual_tests.rs +++ b/crates/ui-egui/src/padding_individual_tests.rs @@ -73,3 +73,35 @@ fn side_fields_show_only_once_the_toggle_opens_and_set_one_side() { u.app.run("edit.undo", json!({})); assert_eq!(padding(&u, f), [10.0; 4]); } + +/// The middle of the shut pair field with accessible name `label`. +fn named_field(u: &mut Ui, label: &str) -> Pos2 { + u.ctx.enable_accesskit(); + u.frame(vec![]); + let out = u.frame_output(vec![]); + let nodes = out.platform_output.accesskit_update.expect("an AccessKit update").nodes; + let n = nodes.iter().map(|(_, n)| n).find(|n| n.role() != Role::Button && n.label() == Some(label)).expect(label); + let b = n.bounds().expect("bounds"); + pos2(((b.x0 + b.x1) / 2.0) as f32, ((b.y0 + b.y1) / 2.0) as f32) +} + +/// The shut pair fields edit their own axis: horizontal touches left and right +/// only, vertical touches top and bottom only. +#[test] +fn shut_pair_fields_edit_their_own_axis() { + let (mut u, f) = scene(); + u.app.run("node.set", json!({"ids": [f], "props": {"paddingLeft": 16.0, "paddingRight": 54.0}})); + assert_eq!(padding(&u, f), [10.0, 54.0, 10.0, 16.0]); + let h = named_field(&mut u, "Horizontal padding"); + click(&mut u, h); + u.frame(vec![Event::Text("20".into())]); + enter(&mut u); + u.frame(vec![]); + assert_eq!(padding(&u, f), [10.0, 20.0, 10.0, 20.0]); + let v = named_field(&mut u, "Vertical padding"); + click(&mut u, v); + u.frame(vec![Event::Text("7".into())]); + enter(&mut u); + u.frame(vec![]); + assert_eq!(padding(&u, f), [7.0, 20.0, 7.0, 20.0]); +}