From 4675c4d9a7b2edf410dd94a84a25c8d0ef5fb3ca Mon Sep 17 00:00:00 2001 From: lucasmerlin Date: Tue, 18 Mar 2025 15:58:15 +0100 Subject: [PATCH] Fix labels, propagate preferred size in scrollareas and add more examples from the issue --- crates/egui/src/containers/scroll_area.rs | 2 +- crates/egui/src/widgets/label.rs | 4 +- examples/hello_world_simple/src/main.rs | 114 ++++++++++++++-------- 3 files changed, 80 insertions(+), 40 deletions(-) diff --git a/crates/egui/src/containers/scroll_area.rs b/crates/egui/src/containers/scroll_area.rs index d88c9c2f3..dd6c69447 100644 --- a/crates/egui/src/containers/scroll_area.rs +++ b/crates/egui/src/containers/scroll_area.rs @@ -1245,7 +1245,7 @@ impl Prepared { } } - ui.advance_cursor_after_rect(outer_rect, Vec2::ZERO); // TODO + ui.advance_cursor_after_rect(outer_rect, content_ui.placer().intrinsic_size()); if show_scroll_this_frame != state.show_scroll { ui.ctx().request_repaint(); diff --git a/crates/egui/src/widgets/label.rs b/crates/egui/src/widgets/label.rs index 1a4c49c78..8eaf9d944 100644 --- a/crates/egui/src/widgets/label.rs +++ b/crates/egui/src/widgets/label.rs @@ -214,6 +214,7 @@ impl Label { assert!(!galley.rows.is_empty(), "Galleys are never empty"); // collect a response from many rows: let rect = galley.rows[0].rect.translate(vec2(pos.x, pos.y)); + dbg!(galley.desired_size()); let mut response = ui.allocate_rect(rect, sense, galley.desired_size()); for row in galley.rows.iter().skip(1) { let rect = row.rect.translate(vec2(pos.x, pos.y)); @@ -247,7 +248,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, response) = + ui.allocate_at_least(galley.size(), sense, galley.desired_size()); // TODO: Change back to allocate_exact_size let galley_pos = match galley.job.halign { Align::LEFT => rect.left_top(), Align::Center => rect.center_top(), diff --git a/examples/hello_world_simple/src/main.rs b/examples/hello_world_simple/src/main.rs index 4e2fcd8c3..db2f2ac40 100644 --- a/examples/hello_world_simple/src/main.rs +++ b/examples/hello_world_simple/src/main.rs @@ -2,7 +2,8 @@ #![allow(rustdoc::missing_crate_level_docs)] // it's an example use eframe::egui; -use eframe::egui::{Align, Button, Layout, Popup, TextWrapMode, Widget}; +use eframe::egui::containers::menu::{MenuButton, MenuConfig}; +use eframe::egui::{Align, Button, Layout, Popup, PopupCloseBehavior, TextWrapMode, Widget}; fn main() -> eframe::Result { env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`). @@ -18,52 +19,89 @@ fn main() -> eframe::Result { let mut checked = true; + let mut flag = false; + let mut row_count = 5; + eframe::run_simple_native("My egui App", options, move |ctx, _frame| { ctx.options_mut(|o| o.max_passes = 1.try_into().unwrap()); 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}")); + // std::thread::sleep(std::time::Duration::from_millis(100)); + // 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"); + // + // ui.horizontal(|ui| { + // ui.vertical(|ui| { + // if Button::new(text) + // // .wrap_mode(TextWrapMode::Extend) + // .ui(ui) + // .clicked() + // { + // checked = !checked; + // } + // ui.button("Button1"); + // }); + // + // ui.button("Button2") + // }); + // + // ui.button("Some other button"); + // }); - std::thread::sleep(std::time::Duration::from_millis(100)); - let response = ui.button("Hiiii"); + // Antoines example - 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.label(format!("Showing {} rows", row_count)); + // if MenuButton::new("BTN") + // .config(MenuConfig::new().close_behavior(PopupCloseBehavior::CloseOnClickOutside)) + // .ui(ui, |ui| { + // ui.radio_value(&mut flag, false, "False"); + // ui.radio_value(&mut flag, true, "True"); + // + // if flag { + // egui::ScrollArea::vertical().show(ui, |ui| { + // for _ in 0..row_count { + // ui.add_space(30.0); + // ui.label("Veeeeeeeeeeeery long text."); + // } + // }); + // } + // }) + // .0 + // .clicked() + // { + // if row_count % 2 == 1 { + // row_count -= 3; + // } else { + // row_count += 5; + // } + // } - ui.button("Hiiii"); - - ui.horizontal(|ui| { - ui.vertical(|ui| { - if Button::new(text) - // .wrap_mode(TextWrapMode::Extend) - .ui(ui) - .clicked() - { - checked = !checked; + MenuButton::new("Menu") + .config(MenuConfig::new().close_behavior(PopupCloseBehavior::CloseOnClickOutside)) + .ui(ui, |ui| { + if ui.button("Close menu").clicked() { + ui.close_menu(); + } + ui.collapsing("Collapsing", |ui| { + egui::ScrollArea::both().show(ui, |ui| { + for _ in 0..10 { + ui.label( + "This is a long text label containing \ + a lot of words and spans many lines", + ); } - ui.button("Button1"); }); - - ui.button("Button2") }); - - ui.button("Some other button"); }); }); })