diff --git a/CHANGELOG.md b/CHANGELOG.md index dc4785b35b5..c937bf010b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ NOTE: [`epaint`](crates/epaint/CHANGELOG.md), [`eframe`](crates/eframe/CHANGELOG * Added `egui::gui_zoom` module with helpers for scaling the whole GUI of an app ([#2239](https://github.com/emilk/egui/pull/2239)). * You can now put one interactive widget on top of another, and only one will get interaction at a time ([#2244](https://github.com/emilk/egui/pull/2244)). * Added `ui.centered`. +* Added possibility to enable text wrap for the selected text of `egui::ComboBox` ([#2272](https://github.com/emilk/egui/pull/2244)) * Added `Area::constrain` and `Window::constrain` which constrains area to the screen bounds. ([#2270](https://github.com/emilk/egui/pull/2270)). * Added `Area::pivot` and `Window::pivot` which controls what part of the window to position. ([#2303](https://github.com/emilk/egui/pull/2303)). diff --git a/crates/egui/src/containers/combo_box.rs b/crates/egui/src/containers/combo_box.rs index 9c33002f780..cb2665d5ede 100644 --- a/crates/egui/src/containers/combo_box.rs +++ b/crates/egui/src/containers/combo_box.rs @@ -36,6 +36,7 @@ pub struct ComboBox { selected_text: WidgetText, width: Option, icon: Option, + wrap_enabled: bool, } impl ComboBox { @@ -47,6 +48,7 @@ impl ComboBox { selected_text: Default::default(), width: None, icon: None, + wrap_enabled: false, } } @@ -59,6 +61,7 @@ impl ComboBox { selected_text: Default::default(), width: None, icon: None, + wrap_enabled: false, } } @@ -70,6 +73,7 @@ impl ComboBox { selected_text: Default::default(), width: None, icon: None, + wrap_enabled: false, } } @@ -124,6 +128,12 @@ impl ComboBox { self } + /// Controls whether text wrap is used for the selected text + pub fn wrap(mut self, wrap: bool) -> Self { + self.wrap_enabled = wrap; + self + } + /// Show the combo box, with the given ui code for the menu contents. /// /// Returns `InnerResponse { inner: None }` if the combo box is closed. @@ -146,6 +156,7 @@ impl ComboBox { selected_text, width, icon, + wrap_enabled, } = self; let button_id = ui.make_persistent_id(id_source); @@ -154,7 +165,14 @@ impl ComboBox { if let Some(width) = width { ui.spacing_mut().slider_width = width; // yes, this is ugly. Will remove later. } - let mut ir = combo_box_dyn(ui, button_id, selected_text, menu_contents, icon); + let mut ir = combo_box_dyn( + ui, + button_id, + selected_text, + menu_contents, + icon, + wrap_enabled, + ); if let Some(label) = label { ir.response .widget_info(|| WidgetInfo::labeled(WidgetType::ComboBox, label.text())); @@ -221,6 +239,7 @@ fn combo_box_dyn<'c, R>( selected_text: WidgetText, menu_contents: Box R + 'c>, icon: Option, + wrap_enabled: bool, ) -> InnerResponse> { let popup_id = button_id.with("popup"); @@ -244,10 +263,16 @@ fn combo_box_dyn<'c, R>( let button_response = button_frame(ui, button_id, is_popup_open, Sense::click(), |ui| { // We don't want to change width when user selects something new - let full_minimum_width = ui.spacing().slider_width; + let full_minimum_width = wrap_enabled + .then(|| ui.available_width() - ui.spacing().item_spacing.x * 2.0) + .unwrap_or_else(|| ui.spacing().slider_width); let icon_size = Vec2::splat(ui.spacing().icon_width); + let wrap_width = wrap_enabled + .then(|| ui.available_width() - ui.spacing().item_spacing.x - icon_size.x) + .unwrap_or(f32::INFINITY); - let galley = selected_text.into_galley(ui, Some(false), f32::INFINITY, TextStyle::Button); + let galley = + selected_text.into_galley(ui, Some(wrap_enabled), wrap_width, TextStyle::Button); let width = galley.size().x + ui.spacing().item_spacing.x + icon_size.x; let width = width.at_least(full_minimum_width);