diff --git a/crates/egui/src/containers/area.rs b/crates/egui/src/containers/area.rs index 55cdb0755..f0cc8cab7 100644 --- a/crates/egui/src/containers/area.rs +++ b/crates/egui/src/containers/area.rs @@ -613,7 +613,9 @@ impl Prepared { .. } = self; - state.size = Some(content_ui.min_size()); + state.size = Some(content_ui.placer().min_item_size()); + + dbg!(state.size); // Make sure we report back the correct size. // Very important after the initial sizing pass, when the initial estimate of the size is way off. diff --git a/crates/egui/src/containers/popup.rs b/crates/egui/src/containers/popup.rs index 4a457bf03..9011b9f36 100644 --- a/crates/egui/src/containers/popup.rs +++ b/crates/egui/src/containers/popup.rs @@ -568,7 +568,8 @@ impl<'a> Popup<'a> { let mut response = area.show(&ctx, |ui| { style.apply(ui.style_mut()); - frame.show(ui, content).inner + // frame.show(ui, content).inner + content(ui) }); let closed_by_click = match close_behavior { diff --git a/crates/egui/src/layout.rs b/crates/egui/src/layout.rs index e967aaa6d..d18a342da 100644 --- a/crates/egui/src/layout.rs +++ b/crates/egui/src/layout.rs @@ -45,6 +45,8 @@ pub(crate) struct Region { /// If something has already been added, this will point to `style.spacing.item_spacing` beyond the latest child. /// The cursor can thus be `style.spacing.item_spacing` pixels outside of the `min_rect`. pub(crate) cursor: Rect, + + pub min_item_size: Vec2, } impl Region { @@ -426,6 +428,7 @@ impl Layout { min_rect: Rect::NOTHING, // temporary max_rect, cursor: self.initial_cursor(max_rect), + min_item_size: Vec2::default(), }; let seed = self.next_widget_position(®ion); region.min_rect = Rect::from_center_size(seed, Vec2::ZERO); @@ -529,6 +532,7 @@ impl Layout { mut cursor, mut max_rect, min_rect, + min_item_size, } = *region; match self.main_dir { @@ -590,6 +594,7 @@ impl Layout { min_rect, max_rect, cursor, + min_item_size, }; self.next_frame_ignore_wrap(®ion, child_size) diff --git a/crates/egui/src/placer.rs b/crates/egui/src/placer.rs index 2de822c03..f05ee9588 100644 --- a/crates/egui/src/placer.rs +++ b/crates/egui/src/placer.rs @@ -163,6 +163,7 @@ impl Placer { frame_rect: Rect, widget_rect: Rect, item_spacing: Vec2, + desired_size: Vec2, ) { debug_assert!(!frame_rect.any_nan()); debug_assert!(!widget_rect.any_nan()); @@ -179,11 +180,17 @@ impl Placer { ); } + self.region.min_item_size = self.region.min_item_size.max(desired_size); + self.expand_to_include_rect(frame_rect); // e.g. for centered layouts: pretend we used whole frame self.region.sanity_check(); } + pub(crate) fn min_item_size(&self) -> Vec2 { + self.region.min_item_size + } + /// Move to the next row in a grid layout or wrapping layout. /// Otherwise does nothing. pub(crate) fn end_row(&mut self, item_spacing: Vec2, painter: &Painter) { diff --git a/crates/egui/src/ui.rs b/crates/egui/src/ui.rs index 6da01d9be..94c9d0411 100644 --- a/crates/egui/src/ui.rs +++ b/crates/egui/src/ui.rs @@ -1403,7 +1403,7 @@ impl Ui { let widget_rect = self.placer.justify_and_align(frame_rect, desired_size); self.placer - .advance_after_rects(frame_rect, widget_rect, item_spacing); + .advance_after_rects(frame_rect, widget_rect, item_spacing, desired_size); register_rect(self, widget_rect); @@ -1426,7 +1426,8 @@ impl Ui { let rect = rect.round_ui(); let item_spacing = self.spacing().item_spacing; - self.placer.advance_after_rects(rect, rect, item_spacing); + self.placer + .advance_after_rects(rect, rect, item_spacing, rect.size()); register_rect(self, rect); let id = Id::new(self.next_auto_id_salt); @@ -2412,8 +2413,22 @@ impl Ui { let mut child_ui = self.new_child(ui_builder); self.next_auto_id_salt = next_auto_id_salt; // HACK: we want `scope` to only increment this once, so that `ui.scope` is equivalent to `ui.allocate_space`. let ret = add_contents(&mut child_ui); - let response = child_ui.remember_min_rect(); + let mut response = child_ui.remember_min_rect(); self.advance_cursor_after_rect(child_ui.min_rect()); + match self.layout().is_horizontal() { + true => { + response.intrinsic_size = Some(Vec2::new( + response.rect.width(), + self.placer.min_item_size().y, + )); + } + false => { + response.intrinsic_size = Some(Vec2::new( + self.placer.min_item_size().x, + response.rect.height(), + )); + } + } InnerResponse::new(ret, response) } diff --git a/crates/egui/src/widgets/checkbox.rs b/crates/egui/src/widgets/checkbox.rs index 7bdb6c86f..0b468478e 100644 --- a/crates/egui/src/widgets/checkbox.rs +++ b/crates/egui/src/widgets/checkbox.rs @@ -75,6 +75,7 @@ impl Widget for Checkbox<'_> { desired_size = desired_size.at_least(Vec2::splat(spacing.interact_size.y)); desired_size.y = desired_size.y.max(icon_width); + dbg!(desired_size); let (rect, mut response) = ui.allocate_exact_size(desired_size, Sense::click()); if response.clicked() { diff --git a/crates/egui_demo_lib/src/demo/popups.rs b/crates/egui_demo_lib/src/demo/popups.rs index 4cf689d3c..7f723158a 100644 --- a/crates/egui_demo_lib/src/demo/popups.rs +++ b/crates/egui_demo_lib/src/demo/popups.rs @@ -70,6 +70,18 @@ fn nested_menus(ui: &mut egui::Ui, checked: &mut bool) { } let _ = ui.button("Item"); ui.menu_button("Recursive", |ui| nested_menus(ui, checked)); + + // if ui.button(if *checked { "short" } else { "Very long text for this item that should be wrapped" }).clicked() { + // *checked = !*checked; + // } + ui.checkbox( + checked, + if *checked { + "short" + } else { + "Very long text for this item that should be wrapped" + }, + ); }); ui.menu_button("SubMenu", |ui| { if ui.button("Open…").clicked() { diff --git a/examples/hello_world_simple/src/main.rs b/examples/hello_world_simple/src/main.rs index 4fe49a89d..2a3006c22 100644 --- a/examples/hello_world_simple/src/main.rs +++ b/examples/hello_world_simple/src/main.rs @@ -2,6 +2,7 @@ #![allow(rustdoc::missing_crate_level_docs)] // it's an example use eframe::egui; +use eframe::egui::{Align, Button, Layout, Popup, TextWrapMode, Widget}; fn main() -> eframe::Result { env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`). @@ -15,19 +16,46 @@ fn main() -> eframe::Result { let mut name = "Arthur".to_owned(); let mut age = 42; + let mut checked = true; + eframe::run_simple_native("My egui App", options, move |ctx, _frame| { egui::CentralPanel::default().show(ctx, |ui| { - ui.heading("My egui Application"); - ui.horizontal(|ui| { - let name_label = ui.label("Your name: "); - ui.text_edit_singleline(&mut name) - .labelled_by(name_label.id); - }); - ui.add(egui::Slider::new(&mut age, 0..=120).text("age")); - if ui.button("Increment").clicked() { - age += 1; - } - ui.label(format!("Hello '{name}', age {age}")); + // ui.heading("My egui Application"); + // ui.horizontal(|ui| { + // let name_label = ui.label("Your name: "); + // ui.text_edit_singleline(&mut name) + // .labelled_by(name_label.id); + // }); + // ui.add(egui::Slider::new(&mut age, 0..=120).text("age")); + // if ui.button("Increment").clicked() { + // age += 1; + // } + // ui.label(format!("Hello '{name}', age {age}")); + + let response = ui.button("Hiiii"); + + let text = if checked { + "short" + } else { + "Very long text for this item that should be wrapped" + }; + Popup::from_response(&response) + .layout(Layout::top_down_justified(Align::Min)) + .show(|ui| { + // ui.checkbox(&mut checked, text); + + ui.button("Hiiii"); + + if Button::new(text) + .wrap_mode(TextWrapMode::Extend) + .ui(ui) + .clicked() + { + checked = !checked; + } + + ui.button("Some other button"); + }); }); }) }