mirror of
https://github.com/emilk/egui.git
synced 2026-08-29 04:40:03 -04:00
Fix horizontal_wrapping row height after using text_edit_multiline (#8000)
* [x] I have followed the instructions in the PR template This PR have two commits: * **First commit** - introduction of tests and their canonization image. Expected behaviour is that `horizontal_wrapped_multiline_row_height` would match `horizontal_wrapped_multiline_row_height_reference`, but it doesn't. There is a bug in `horizontal_wrapped` that breaks line height after using `text_edit_multiline`. * **Second commit** - fix. You can see that `horizontal_wrapped_multiline_row_height` now looks like `horizontal_wrapped_multiline_row_height_reference` (although it's not a perfect match, upd: found, this is because of this issue: https://github.com/emilk/egui/issues/4921). I have used LLM to help me with this PR (codex + claude code). BTW, I'm using horizontal_wrapped with end_row instead of vertical + horizontal alternation, because I automatically generate my UI through some complex interactions between elements in my code, and it's can be that my `horizontal` starts in one function, and ends in another. Something like `begin_horizontal`/`end_horizontal`/`get_current_layout` would be very handy, related to https://github.com/emilk/egui/issues/1004. Also, I would like indent to be supported in `horizontal_wrapped`, or also, to have `indent_start`/`indent_end`. This is why I used `monospace("| ")` in my example, it simulates my use-case.
This commit is contained in:
@@ -623,12 +623,24 @@ impl Layout {
|
|||||||
if (self.is_vertical() && self.horizontal_align() == Align::Center)
|
if (self.is_vertical() && self.horizontal_align() == Align::Center)
|
||||||
|| self.horizontal_justify()
|
|| self.horizontal_justify()
|
||||||
{
|
{
|
||||||
frame_size.x = frame_size.x.max(available_rect.width()); // fill full width
|
// For wrapping layouts, fill the current column width, not the entire layout width.
|
||||||
|
let width = if self.main_wrap {
|
||||||
|
region.cursor.width()
|
||||||
|
} else {
|
||||||
|
available_rect.width()
|
||||||
|
};
|
||||||
|
frame_size.x = frame_size.x.max(width); // fill full width
|
||||||
}
|
}
|
||||||
if (self.is_horizontal() && self.vertical_align() == Align::Center)
|
if (self.is_horizontal() && self.vertical_align() == Align::Center)
|
||||||
|| self.vertical_justify()
|
|| self.vertical_justify()
|
||||||
{
|
{
|
||||||
frame_size.y = frame_size.y.max(available_rect.height()); // fill full height
|
// For wrapping layouts, fill the current row height, not the entire layout height.
|
||||||
|
let height = if self.main_wrap {
|
||||||
|
region.cursor.height()
|
||||||
|
} else {
|
||||||
|
available_rect.height()
|
||||||
|
};
|
||||||
|
frame_size.y = frame_size.y.max(height); // fill full height
|
||||||
}
|
}
|
||||||
|
|
||||||
let align2 = match self.main_dir {
|
let align2 = match self.main_dir {
|
||||||
@@ -791,14 +803,14 @@ impl Layout {
|
|||||||
let new_top = region.cursor.bottom() + spacing.y;
|
let new_top = region.cursor.bottom() + spacing.y;
|
||||||
region.cursor = Rect::from_min_max(
|
region.cursor = Rect::from_min_max(
|
||||||
pos2(region.max_rect.left(), new_top),
|
pos2(region.max_rect.left(), new_top),
|
||||||
pos2(INFINITY, new_top + region.cursor.height()),
|
pos2(INFINITY, new_top),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Direction::RightToLeft => {
|
Direction::RightToLeft => {
|
||||||
let new_top = region.cursor.bottom() + spacing.y;
|
let new_top = region.cursor.bottom() + spacing.y;
|
||||||
region.cursor = Rect::from_min_max(
|
region.cursor = Rect::from_min_max(
|
||||||
pos2(-INFINITY, new_top),
|
pos2(-INFINITY, new_top),
|
||||||
pos2(region.max_rect.right(), new_top + region.cursor.height()),
|
pos2(region.max_rect.right(), new_top),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Direction::TopDown | Direction::BottomUp => {}
|
Direction::TopDown | Direction::BottomUp => {}
|
||||||
|
|||||||
@@ -279,3 +279,88 @@ fn warn_if_rect_changes_id() {
|
|||||||
"Should warn when a widget rect changes Id between passes"
|
"Should warn when a widget rect changes Id between passes"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn horizontal_wrapped_multiline_row_height() {
|
||||||
|
let mut harness = Harness::builder().with_size((350.0, 300.0)).build_ui(|ui| {
|
||||||
|
ui.style_mut().interaction.tooltip_delay = 0.0;
|
||||||
|
ui.style_mut().interaction.show_tooltips_only_when_still = false;
|
||||||
|
|
||||||
|
let mut string = String::new();
|
||||||
|
|
||||||
|
ui.horizontal_wrapped(|ui| {
|
||||||
|
ui.monospace("| ");
|
||||||
|
let _ = ui.button("A");
|
||||||
|
let _ = ui.button("B");
|
||||||
|
ui.end_row();
|
||||||
|
|
||||||
|
ui.monospace("| ");
|
||||||
|
let _ = ui.button("C");
|
||||||
|
let _ = ui.button("D");
|
||||||
|
let _ = ui.button("E");
|
||||||
|
ui.end_row();
|
||||||
|
|
||||||
|
ui.monospace("| ");
|
||||||
|
ui.text_edit_multiline(&mut string);
|
||||||
|
ui.end_row();
|
||||||
|
|
||||||
|
ui.monospace("| ");
|
||||||
|
let _ = ui.button("F");
|
||||||
|
let _ = ui.button("G");
|
||||||
|
ui.end_row();
|
||||||
|
|
||||||
|
ui.monospace("| ");
|
||||||
|
let _ = ui.button("H");
|
||||||
|
let _ = ui.button("I");
|
||||||
|
let _ = ui.button("K");
|
||||||
|
ui.end_row();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
harness.snapshot("horizontal_wrapped_multiline_row_height");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn horizontal_wrapped_multiline_row_height_reference() {
|
||||||
|
let mut harness = Harness::builder().with_size((350.0, 300.0)).build_ui(|ui| {
|
||||||
|
ui.style_mut().interaction.tooltip_delay = 0.0;
|
||||||
|
ui.style_mut().interaction.show_tooltips_only_when_still = false;
|
||||||
|
|
||||||
|
let mut string = String::new();
|
||||||
|
|
||||||
|
ui.vertical(|ui| {
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.monospace("| ");
|
||||||
|
let _ = ui.button("A");
|
||||||
|
let _ = ui.button("B");
|
||||||
|
});
|
||||||
|
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.monospace("| ");
|
||||||
|
let _ = ui.button("C");
|
||||||
|
let _ = ui.button("D");
|
||||||
|
let _ = ui.button("E");
|
||||||
|
});
|
||||||
|
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.monospace("| ");
|
||||||
|
ui.text_edit_multiline(&mut string);
|
||||||
|
});
|
||||||
|
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.monospace("| ");
|
||||||
|
let _ = ui.button("F");
|
||||||
|
let _ = ui.button("G");
|
||||||
|
});
|
||||||
|
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.monospace("| ");
|
||||||
|
let _ = ui.button("H");
|
||||||
|
let _ = ui.button("I");
|
||||||
|
let _ = ui.button("K");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
harness.snapshot("horizontal_wrapped_multiline_row_height_reference");
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:ef21b42f90401f6b85685e1cc37d07970b38d2b40394f53bbde5bd4f0d54fb95
|
||||||
|
size 5340
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:5025f4cb528ae5edc387149f1d14523ab4b93058f0862e775a1c2276a3e77af6
|
||||||
|
size 5377
|
||||||
Reference in New Issue
Block a user