diff --git a/crates/egui/src/containers/combo_box.rs b/crates/egui/src/containers/combo_box.rs index 3d2bdd50b53..55157294b79 100644 --- a/crates/egui/src/containers/combo_box.rs +++ b/crates/egui/src/containers/combo_box.rs @@ -45,6 +45,7 @@ pub struct ComboBox { height: Option, icon: Option, wrap_mode: Option, + close_behavior: Option, } impl ComboBox { @@ -58,6 +59,7 @@ impl ComboBox { height: None, icon: None, wrap_mode: None, + close_behavior: None, } } @@ -72,6 +74,7 @@ impl ComboBox { height: None, icon: None, wrap_mode: None, + close_behavior: None, } } @@ -85,6 +88,7 @@ impl ComboBox { height: None, icon: None, wrap_mode: None, + close_behavior: None, } } @@ -173,7 +177,6 @@ impl ComboBox { #[inline] pub fn wrap(mut self) -> Self { self.wrap_mode = Some(TextWrapMode::Wrap); - self } @@ -184,6 +187,15 @@ impl ComboBox { self } + /// Controls the close behavior for the popup. + /// + /// By default, `PopupCloseBehavior::CloseOnClick` will be used. + #[inline] + pub fn close_behavior(mut self, close_behavior: PopupCloseBehavior) -> Self { + self.close_behavior = Some(close_behavior); + self + } + /// Show the combo box, with the given ui code for the menu contents. /// /// Returns `InnerResponse { inner: None }` if the combo box is closed. @@ -208,6 +220,7 @@ impl ComboBox { height, icon, wrap_mode, + close_behavior, } = self; let button_id = ui.make_persistent_id(id_salt); @@ -220,6 +233,7 @@ impl ComboBox { menu_contents, icon, wrap_mode, + close_behavior, (width, height), ); if let Some(label) = label { @@ -301,6 +315,7 @@ fn combo_box_dyn<'c, R>( menu_contents: Box R + 'c>, icon: Option, wrap_mode: Option, + close_behavior: Option, (width, height): (Option, Option), ) -> InnerResponse> { let popup_id = ComboBox::widget_to_popup_id(button_id); @@ -325,6 +340,8 @@ fn combo_box_dyn<'c, R>( let wrap_mode = wrap_mode.unwrap_or_else(|| ui.wrap_mode()); + let close_behavior = close_behavior.unwrap_or(PopupCloseBehavior::CloseOnClick); + let margin = ui.spacing().button_padding; let button_response = button_frame(ui, button_id, is_popup_open, Sense::click(), |ui| { let icon_spacing = ui.spacing().icon_spacing; @@ -396,7 +413,7 @@ fn combo_box_dyn<'c, R>( popup_id, &button_response, above_or_below, - PopupCloseBehavior::CloseOnClick, + close_behavior, |ui| { ScrollArea::vertical() .max_height(height) diff --git a/examples/popups/src/main.rs b/examples/popups/src/main.rs index 46762d667c0..baed12c2a26 100644 --- a/examples/popups/src/main.rs +++ b/examples/popups/src/main.rs @@ -14,12 +14,33 @@ fn main() -> Result<(), eframe::Error> { struct MyApp { checkbox: bool, number: u8, + numbers: [bool; 10], } impl eframe::App for MyApp { fn update(&mut self, ctx: &eframe::egui::Context, _frame: &mut eframe::Frame) { CentralPanel::default().show(ctx, |ui| { - ui.label("PopupCloseBehavior::CloseOnClickAway popup"); + ui.label("PopupCloseBehavior::CloseOnClick popup"); + ComboBox::from_label("ComboBox") + .selected_text(format!("{}", self.number)) + .show_ui(ui, |ui| { + for num in 0..10 { + ui.selectable_value(&mut self.number, num, format!("{num}")); + } + }); + + ui.label("PopupCloseBehavior::CloseOnClickOutside popup"); + ComboBox::from_label("Ignore Clicks") + .close_behavior(PopupCloseBehavior::CloseOnClickOutside) + .selected_text("Select Numbers") + .show_ui(ui, |ui| { + ui.label("This popup will be open even if you click the checkboxes"); + for (i, num) in self.numbers.iter_mut().enumerate() { + ui.checkbox(num, format!("Checkbox {}", i + 1)); + } + }); + + ui.label("PopupCloseBehavior::IgnoreClicks popup"); let response = ui.button("Open"); let popup_id = Id::new("popup_id"); @@ -31,22 +52,13 @@ impl eframe::App for MyApp { ui, popup_id, &response, - PopupCloseBehavior::CloseOnClickOutside, + PopupCloseBehavior::IgnoreClicks, |ui| { - ui.set_min_width(300.0); - ui.label("This popup will be open even if you click the checkbox"); + ui.set_min_width(310.0); + ui.label("This popup will be open until you press the button again"); ui.checkbox(&mut self.checkbox, "Checkbox"); }, ); - - ui.label("PopupCloseBehavior::CloseOnClick popup"); - ComboBox::from_label("ComboBox") - .selected_text(format!("{}", self.number)) - .show_ui(ui, |ui| { - for num in 0..10 { - ui.selectable_value(&mut self.number, num, format!("{num}")); - } - }); }); } }