Skip to content

Commit c88a3fd

Browse files
RobWaltJohannesProgrammiert
authored andcommitted
feat(combobox): implement text wrap for selected text (emilk#2272)
* feat(combobox): implement text wrap for selected text * chore(changelog): add line to changelog * feat(combobox-text-wrap): make wrap boolean - specifying a wrap width didn't really make sense so now it's boolean - the selected text will now use the maximum available width while still respecting the spacing and icon coming after it * feat(combobox-text-wrap): update changelog
1 parent 5bce301 commit c88a3fd

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ NOTE: [`epaint`](crates/epaint/CHANGELOG.md), [`eframe`](crates/eframe/CHANGELOG
2323
* Implemented `Debug` for `egui::Context` ([#2248](https://github.com/emilk/egui/pull/2248)).
2424
* 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)).
2525
* Added `ui.centered`.
26+
* Added possibility to enable text wrap for the selected text of `egui::ComboBox` ([#2272](https://github.com/emilk/egui/pull/2244))
2627
* Added `Area::constrain` and `Window::constrain` which constrains area to the screen bounds. ([#2270](https://github.com/emilk/egui/pull/2270)).
2728
* Added `Area::pivot` and `Window::pivot` which controls what part of the window to position. ([#2303](https://github.com/emilk/egui/pull/2303)).
2829

crates/egui/src/containers/combo_box.rs

+28-3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pub struct ComboBox {
3636
selected_text: WidgetText,
3737
width: Option<f32>,
3838
icon: Option<IconPainter>,
39+
wrap_enabled: bool,
3940
}
4041

4142
impl ComboBox {
@@ -47,6 +48,7 @@ impl ComboBox {
4748
selected_text: Default::default(),
4849
width: None,
4950
icon: None,
51+
wrap_enabled: false,
5052
}
5153
}
5254

@@ -59,6 +61,7 @@ impl ComboBox {
5961
selected_text: Default::default(),
6062
width: None,
6163
icon: None,
64+
wrap_enabled: false,
6265
}
6366
}
6467

@@ -70,6 +73,7 @@ impl ComboBox {
7073
selected_text: Default::default(),
7174
width: None,
7275
icon: None,
76+
wrap_enabled: false,
7377
}
7478
}
7579

@@ -124,6 +128,12 @@ impl ComboBox {
124128
self
125129
}
126130

131+
/// Controls whether text wrap is used for the selected text
132+
pub fn wrap(mut self, wrap: bool) -> Self {
133+
self.wrap_enabled = wrap;
134+
self
135+
}
136+
127137
/// Show the combo box, with the given ui code for the menu contents.
128138
///
129139
/// Returns `InnerResponse { inner: None }` if the combo box is closed.
@@ -146,6 +156,7 @@ impl ComboBox {
146156
selected_text,
147157
width,
148158
icon,
159+
wrap_enabled,
149160
} = self;
150161

151162
let button_id = ui.make_persistent_id(id_source);
@@ -154,7 +165,14 @@ impl ComboBox {
154165
if let Some(width) = width {
155166
ui.spacing_mut().slider_width = width; // yes, this is ugly. Will remove later.
156167
}
157-
let mut ir = combo_box_dyn(ui, button_id, selected_text, menu_contents, icon);
168+
let mut ir = combo_box_dyn(
169+
ui,
170+
button_id,
171+
selected_text,
172+
menu_contents,
173+
icon,
174+
wrap_enabled,
175+
);
158176
if let Some(label) = label {
159177
ir.response
160178
.widget_info(|| WidgetInfo::labeled(WidgetType::ComboBox, label.text()));
@@ -221,6 +239,7 @@ fn combo_box_dyn<'c, R>(
221239
selected_text: WidgetText,
222240
menu_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
223241
icon: Option<IconPainter>,
242+
wrap_enabled: bool,
224243
) -> InnerResponse<Option<R>> {
225244
let popup_id = button_id.with("popup");
226245

@@ -244,10 +263,16 @@ fn combo_box_dyn<'c, R>(
244263

245264
let button_response = button_frame(ui, button_id, is_popup_open, Sense::click(), |ui| {
246265
// We don't want to change width when user selects something new
247-
let full_minimum_width = ui.spacing().slider_width;
266+
let full_minimum_width = wrap_enabled
267+
.then(|| ui.available_width() - ui.spacing().item_spacing.x * 2.0)
268+
.unwrap_or_else(|| ui.spacing().slider_width);
248269
let icon_size = Vec2::splat(ui.spacing().icon_width);
270+
let wrap_width = wrap_enabled
271+
.then(|| ui.available_width() - ui.spacing().item_spacing.x - icon_size.x)
272+
.unwrap_or(f32::INFINITY);
249273

250-
let galley = selected_text.into_galley(ui, Some(false), f32::INFINITY, TextStyle::Button);
274+
let galley =
275+
selected_text.into_galley(ui, Some(wrap_enabled), wrap_width, TextStyle::Button);
251276

252277
let width = galley.size().x + ui.spacing().item_spacing.x + icon_size.x;
253278
let width = width.at_least(full_minimum_width);

0 commit comments

Comments
 (0)