From 14c2e5d3d5b1bce77b72e0c3367af0a2be9222d2 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Thu, 10 Jul 2025 10:48:14 +0200 Subject: [PATCH] Set intrinsic size for Label (#7328) Sets intrinsic size for labels --- crates/egui/src/response.rs | 4 +- crates/egui/src/widgets/label.rs | 4 +- tests/egui_tests/tests/test_atoms.rs | 59 ++++++++++++++++------------ 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/crates/egui/src/response.rs b/crates/egui/src/response.rs index d9dc61c3..85dc8a60 100644 --- a/crates/egui/src/response.rs +++ b/crates/egui/src/response.rs @@ -59,8 +59,8 @@ pub struct Response { /// The intrinsic / desired size of the widget. /// - /// For a button, this will be the size of the label + the frames padding, - /// even if the button is laid out in a justified layout and the actual size will be larger. + /// This is the size that a non-wrapped, non-truncated, non-justified version of the widget + /// would have. /// /// If this is `None`, use [`Self::rect`] instead. /// diff --git a/crates/egui/src/widgets/label.rs b/crates/egui/src/widgets/label.rs index b25cb908..1abac788 100644 --- a/crates/egui/src/widgets/label.rs +++ b/crates/egui/src/widgets/label.rs @@ -220,6 +220,7 @@ impl Label { .rect_without_leading_space() .translate(pos.to_vec2()); let mut response = ui.allocate_rect(rect, sense); + response.intrinsic_size = Some(galley.intrinsic_size()); for placed_row in galley.rows.iter().skip(1) { let rect = placed_row.rect().translate(pos.to_vec2()); response |= ui.allocate_rect(rect, sense); @@ -252,7 +253,8 @@ impl Label { }; let galley = ui.fonts(|fonts| fonts.layout_job(layout_job)); - let (rect, response) = ui.allocate_exact_size(galley.size(), sense); + let (rect, mut response) = ui.allocate_exact_size(galley.size(), sense); + response.intrinsic_size = Some(galley.intrinsic_size()); let galley_pos = match galley.job.halign { Align::LEFT => rect.left_top(), Align::Center => rect.center_top(), diff --git a/tests/egui_tests/tests/test_atoms.rs b/tests/egui_tests/tests/test_atoms.rs index 98e90c1c..cf2abbe1 100644 --- a/tests/egui_tests/tests/test_atoms.rs +++ b/tests/egui_tests/tests/test_atoms.rs @@ -72,32 +72,39 @@ fn single_test(name: &str, mut f: impl FnMut(&mut Ui)) -> SnapshotResult { #[test] fn test_intrinsic_size() { - let mut intrinsic_size = None; - for wrapping in [ - TextWrapMode::Extend, - TextWrapMode::Wrap, - TextWrapMode::Truncate, - ] { - _ = HarnessBuilder::default() - .with_size(Vec2::new(100.0, 100.0)) - .build_ui(|ui| { - ui.style_mut().wrap_mode = Some(wrapping); - let response = ui.add(Button::new( - "Hello world this is a long text that should be wrapped.", - )); - if let Some(current_intrinsic_size) = intrinsic_size { - assert_eq!( - Some(current_intrinsic_size), - response.intrinsic_size, - "For wrapping: {wrapping:?}" + let widgets = [Ui::button, Ui::label]; + + for widget in widgets { + let mut intrinsic_size = None; + for wrapping in [ + TextWrapMode::Extend, + TextWrapMode::Wrap, + TextWrapMode::Truncate, + ] { + _ = HarnessBuilder::default() + .with_size(Vec2::new(100.0, 100.0)) + .build_ui(|ui| { + ui.style_mut().wrap_mode = Some(wrapping); + let response = widget( + ui, + "Hello world this is a long text that should be wrapped.", ); - } - assert!( - response.intrinsic_size.is_some(), - "intrinsic_size should be set for `Button`" - ); - intrinsic_size = response.intrinsic_size; - }); + if let Some(current_intrinsic_size) = intrinsic_size { + assert_eq!( + Some(current_intrinsic_size), + response.intrinsic_size, + "For wrapping: {wrapping:?}" + ); + } + assert!( + response.intrinsic_size.is_some(), + "intrinsic_size should be set for `Button`" + ); + intrinsic_size = response.intrinsic_size; + if wrapping == TextWrapMode::Extend { + assert_eq!(Some(response.rect.size()), response.intrinsic_size); + } + }); + } } - assert_eq!(intrinsic_size.unwrap().round(), Vec2::new(305.0, 18.0)); }