Skip to content

Commit

Permalink
ComboBox: fix justified layout of popup if wider than parent button (
Browse files Browse the repository at this point in the history
…emilk#4570)

* Closes emilk#4452

The `ComboBox` popup has a justified layout to make selection of items
easier.

Thanks to [the new sizing pass
logic](emilk#4535) we don't have to know
the final width in advance:


![image](https://github.com/emilk/egui/assets/1148717/53b0dda7-14c9-43be-a073-ad49865e69a6)
  • Loading branch information
emilk authored and hacknus committed Oct 30, 2024
1 parent d46cb35 commit 6a3c752
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 6 deletions.
11 changes: 7 additions & 4 deletions crates/egui/src/containers/popup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ pub fn popup_below_widget<R>(
///
/// Useful for drop-down menus (combo boxes) or suggestion menus under text fields.
///
/// The opened popup will have the same width as the parent.
/// The opened popup will have a minimum width matching its parent.
///
/// You must open the popup with [`Memory::open_popup`] or [`Memory::toggle_popup`].
///
Expand Down Expand Up @@ -341,18 +341,21 @@ pub fn popup_above_or_below_widget<R>(
AboveOrBelow::Below => (widget_response.rect.left_bottom(), Align2::LEFT_TOP),
};

let frame = Frame::popup(parent_ui.style());
let frame_margin = frame.total_margin();
let inner_width = widget_response.rect.width() - frame_margin.sum().x;

let inner = Area::new(popup_id)
.order(Order::Foreground)
.constrain(true)
.fixed_pos(pos)
.default_width(inner_width)
.pivot(pivot)
.show(parent_ui.ctx(), |ui| {
let frame = Frame::popup(parent_ui.style());
let frame_margin = frame.total_margin();
frame
.show(ui, |ui| {
ui.with_layout(Layout::top_down_justified(Align::LEFT), |ui| {
ui.set_width(widget_response.rect.width() - frame_margin.sum().x);
ui.set_min_width(inner_width);
add_contents(ui)
})
.inner
Expand Down
2 changes: 0 additions & 2 deletions crates/egui_demo_lib/src/demo/widget_gallery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,6 @@ impl WidgetGallery {
egui::ComboBox::from_label("Take your pick")
.selected_text(format!("{radio:?}"))
.show_ui(ui, |ui| {
ui.style_mut().wrap_mode = Some(egui::TextWrapMode::Extend);
ui.set_min_width(60.0);
ui.selectable_value(radio, Enum::First, "First");
ui.selectable_value(radio, Enum::Second, "Second");
ui.selectable_value(radio, Enum::Third, "Third");
Expand Down
23 changes: 23 additions & 0 deletions tests/test_size_pass/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ fn main() -> eframe::Result<()> {
let options = eframe::NativeOptions::default();
eframe::run_simple_native("My egui App", options, move |ctx, _frame| {
egui::CentralPanel::default().show(ctx, |ui| {
if ui.button("Reset egui memory").clicked() {
ctx.memory_mut(|mem| *mem = Default::default());
}

ui.separator();

ui.label("The menu should be as wide as the widest button");
ui.menu_button("Click for menu", |ui| {
let _ = ui.button("Narrow").clicked();
Expand All @@ -20,6 +26,23 @@ fn main() -> eframe::Result<()> {
ui.label("A separator:");
ui.separator();
});

ui.separator();

let alternatives = [
"Short",
"Min",
"Very very long text that will extend",
"Short",
];
let mut selected = 1;

egui::ComboBox::from_label("ComboBox").show_index(
ui,
&mut selected,
alternatives.len(),
|i| alternatives[i],
);
});
})
}

0 comments on commit 6a3c752

Please sign in to comment.