mirror of
https://github.com/emilk/egui.git
synced 2026-09-02 06:40:06 -04:00
Layout fixes (#651)
* Fix incorrect max_width/height of panels * Fix set_width/set_min_width/set_height/set_min_height Closes https://github.com/emilk/egui/issues/647 Broke in https://github.com/emilk/egui/pull/629 * Fix expand_to_include_x/expand_to_include_y * Make minimum grid column width propagate properly * Expand cursor when max_rect expands * Add ui.expand_to_include_y * Only expand cursor in advance * demo: clean up font_book code * Fix: Make sure `TextEdit` contents expand to fill width if applicable * ProgressBar: minimum width and fix for having it in an infinite layout * clippy fix
This commit is contained in:
@@ -213,7 +213,7 @@ impl SidePanel {
|
||||
let frame = frame.unwrap_or_else(|| Frame::side_top_panel(ui.style()));
|
||||
let inner_response = frame.show(&mut panel_ui, |ui| {
|
||||
ui.set_min_height(ui.max_rect_finite().height()); // Make sure the frame fills the full height
|
||||
ui.set_width_range(width_range);
|
||||
ui.set_min_width(*width_range.start());
|
||||
add_contents(ui)
|
||||
});
|
||||
|
||||
@@ -474,7 +474,7 @@ impl TopBottomPanel {
|
||||
let frame = frame.unwrap_or_else(|| Frame::side_top_panel(ui.style()));
|
||||
let inner_response = frame.show(&mut panel_ui, |ui| {
|
||||
ui.set_min_width(ui.max_rect_finite().width()); // Make the frame fill full width
|
||||
ui.set_height_range(height_range);
|
||||
ui.set_min_height(*height_range.start());
|
||||
add_contents(ui)
|
||||
});
|
||||
|
||||
|
||||
@@ -130,6 +130,9 @@ impl GridLayout {
|
||||
.unwrap_or(self.min_cell_size.x)
|
||||
};
|
||||
|
||||
// If something above was wider, we can be wider:
|
||||
let width = width.max(self.curr_state.col_width(self.col).unwrap_or(0.0));
|
||||
|
||||
let available = region.max_rect.intersect(region.cursor);
|
||||
|
||||
let height = region.max_rect_finite().max.y - available.top();
|
||||
@@ -181,11 +184,9 @@ impl GridLayout {
|
||||
}
|
||||
|
||||
self.curr_state
|
||||
.set_min_col_width(self.col, widget_rect.width().at_least(self.min_cell_size.x));
|
||||
self.curr_state.set_min_row_height(
|
||||
self.row,
|
||||
widget_rect.height().at_least(self.min_cell_size.y),
|
||||
);
|
||||
.set_min_col_width(self.col, widget_rect.width().max(self.min_cell_size.x));
|
||||
self.curr_state
|
||||
.set_min_row_height(self.row, widget_rect.height().max(self.min_cell_size.y));
|
||||
|
||||
cursor.min.x += self.prev_col_width(self.col) + self.spacing.x;
|
||||
self.col += 1;
|
||||
|
||||
@@ -74,6 +74,7 @@ impl Region {
|
||||
pub fn expand_to_include_x(&mut self, x: f32) {
|
||||
self.min_rect.extend_with_x(x);
|
||||
self.max_rect.extend_with_x(x);
|
||||
self.cursor.extend_with_x(x);
|
||||
}
|
||||
|
||||
/// Ensure we are big enough to contain the given Y-coordinate.
|
||||
@@ -81,6 +82,7 @@ impl Region {
|
||||
pub fn expand_to_include_y(&mut self, y: f32) {
|
||||
self.min_rect.extend_with_y(y);
|
||||
self.max_rect.extend_with_y(y);
|
||||
self.cursor.extend_with_y(y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -680,6 +682,15 @@ impl Layout {
|
||||
}
|
||||
};
|
||||
}
|
||||
} else {
|
||||
// Make sure we also expand where we consider adding things (the cursor):
|
||||
if self.is_horizontal() {
|
||||
cursor.min.y = cursor.min.y.min(frame_rect.min.y);
|
||||
cursor.max.y = cursor.max.y.max(frame_rect.max.y);
|
||||
} else {
|
||||
cursor.min.x = cursor.min.x.min(frame_rect.min.x);
|
||||
cursor.max.x = cursor.max.x.max(frame_rect.max.x);
|
||||
}
|
||||
}
|
||||
|
||||
match self.main_dir {
|
||||
|
||||
@@ -180,7 +180,7 @@ impl Placer {
|
||||
)
|
||||
}
|
||||
|
||||
self.region.expand_to_include_rect(frame_rect); // e.g. for centered layouts: pretend we used whole frame
|
||||
self.expand_to_include_rect(frame_rect); // e.g. for centered layouts: pretend we used whole frame
|
||||
}
|
||||
|
||||
/// Move to the next row in a grid layout or wrapping layout.
|
||||
@@ -210,6 +210,11 @@ impl Placer {
|
||||
self.region.expand_to_include_x(x);
|
||||
}
|
||||
|
||||
/// Expand the `min_rect` and `max_rect` of this ui to include a child at the given y-coordinate.
|
||||
pub(crate) fn expand_to_include_y(&mut self, y: f32) {
|
||||
self.region.expand_to_include_y(y);
|
||||
}
|
||||
|
||||
fn next_widget_space_ignore_wrap_justify(&self, size: Vec2) -> Rect {
|
||||
self.layout
|
||||
.next_widget_space_ignore_wrap_justify(&self.region, size)
|
||||
@@ -223,6 +228,9 @@ impl Placer {
|
||||
region.max_rect.min.x = rect.min.x;
|
||||
region.max_rect.max.x = rect.max.x;
|
||||
region.max_rect = region.max_rect.union(region.min_rect); // make sure we didn't shrink too much
|
||||
|
||||
region.cursor.min.x = region.max_rect.min.x;
|
||||
region.cursor.max.x = region.max_rect.max.x;
|
||||
}
|
||||
|
||||
/// Set the maximum height of the ui.
|
||||
@@ -233,6 +241,9 @@ impl Placer {
|
||||
region.max_rect.min.y = rect.min.y;
|
||||
region.max_rect.max.y = rect.max.y;
|
||||
region.max_rect = region.max_rect.union(region.min_rect); // make sure we didn't shrink too much
|
||||
|
||||
region.cursor.min.y = region.max_rect.min.y;
|
||||
region.cursor.max.y = region.max_rect.max.y;
|
||||
}
|
||||
|
||||
/// Set the minimum width of the ui.
|
||||
|
||||
@@ -470,6 +470,12 @@ impl Ui {
|
||||
self.placer.expand_to_include_x(x);
|
||||
}
|
||||
|
||||
/// Ensure we are big enough to contain the given y-coordinate.
|
||||
/// This is sometimes useful to expand an ui to stretch to a certain place.
|
||||
pub fn expand_to_include_y(&mut self, y: f32) {
|
||||
self.placer.expand_to_include_y(y);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Layout related measures:
|
||||
|
||||
|
||||
@@ -67,7 +67,8 @@ impl Widget for ProgressBar {
|
||||
ui.ctx().request_repaint();
|
||||
}
|
||||
|
||||
let desired_width = desired_width.unwrap_or(ui.available_size_before_wrap().x);
|
||||
let desired_width = desired_width
|
||||
.unwrap_or_else(|| ui.available_size_before_wrap_finite().x.at_least(96.0));
|
||||
let height = ui.spacing().interact_size.y;
|
||||
let (outer_rect, response) =
|
||||
ui.allocate_exact_size(vec2(desired_width, height), Sense::hover());
|
||||
|
||||
@@ -461,12 +461,12 @@ impl<'t, S: TextBuffer> TextEdit<'t, S> {
|
||||
const MIN_WIDTH: f32 = 24.0; // Never make a `TextEdit` more narrow than this.
|
||||
let available_width = ui.available_width().at_least(MIN_WIDTH);
|
||||
let desired_width = desired_width.unwrap_or_else(|| ui.spacing().text_edit_width);
|
||||
let mut wrap_width = desired_width.min(available_width);
|
||||
|
||||
let make_galley = |ui: &Ui, text: &str| {
|
||||
let make_galley = |ui: &Ui, wrap_width: f32, text: &str| {
|
||||
let text = mask_if_password(text);
|
||||
if multiline {
|
||||
ui.fonts()
|
||||
.layout_multiline(text_style, text, desired_width.min(available_width))
|
||||
ui.fonts().layout_multiline(text_style, text, wrap_width)
|
||||
} else {
|
||||
ui.fonts().layout_single_line(text_style, text)
|
||||
}
|
||||
@@ -478,15 +478,18 @@ impl<'t, S: TextBuffer> TextEdit<'t, S> {
|
||||
}
|
||||
};
|
||||
|
||||
let mut galley = make_galley(ui, text.as_ref());
|
||||
let mut galley = make_galley(ui, wrap_width, text.as_ref());
|
||||
|
||||
let desired_height = (desired_height_rows.at_least(1) as f32) * line_spacing;
|
||||
let desired_size = vec2(
|
||||
desired_width.min(available_width),
|
||||
galley.size.y.max(desired_height),
|
||||
);
|
||||
let desired_size = vec2(wrap_width, galley.size.y.max(desired_height));
|
||||
let (auto_id, rect) = ui.allocate_space(desired_size);
|
||||
|
||||
if (rect.width() - desired_size.x).abs() > 0.5 {
|
||||
// We didn't get what we asked for. Likely we are in a justified layout, and got enlarged.
|
||||
wrap_width = rect.width();
|
||||
galley = make_galley(ui, wrap_width, text.as_ref())
|
||||
}
|
||||
|
||||
let id = id.unwrap_or_else(|| {
|
||||
if let Some(id_source) = id_source {
|
||||
ui.make_persistent_id(id_source)
|
||||
@@ -502,7 +505,7 @@ impl<'t, S: TextBuffer> TextEdit<'t, S> {
|
||||
Sense::hover()
|
||||
};
|
||||
let mut response = ui.interact(rect, id, sense);
|
||||
let painter = ui.painter_at(Rect::from_min_size(response.rect.min, desired_size));
|
||||
let painter = ui.painter_at(rect);
|
||||
|
||||
if enabled {
|
||||
if let Some(pointer_pos) = ui.input().pointer.interact_pos() {
|
||||
@@ -715,7 +718,7 @@ impl<'t, S: TextBuffer> TextEdit<'t, S> {
|
||||
response.mark_changed();
|
||||
|
||||
// Layout again to avoid frame delay, and to keep `text` and `galley` in sync.
|
||||
galley = make_galley(ui, text.as_ref());
|
||||
galley = make_galley(ui, wrap_width, text.as_ref());
|
||||
|
||||
// Set cursorp using new galley:
|
||||
cursorp = CursorPair {
|
||||
|
||||
Reference in New Issue
Block a user