Grid: special-treat first frame to fix bug causing expanding grids (#2384)
This commit is contained in:
parent
4e59296cbb
commit
0b2d56cff0
1 changed files with 22 additions and 5 deletions
|
@ -51,6 +51,9 @@ pub(crate) struct GridLayout {
|
||||||
style: std::sync::Arc<Style>,
|
style: std::sync::Arc<Style>,
|
||||||
id: Id,
|
id: Id,
|
||||||
|
|
||||||
|
/// First frame (no previous know state).
|
||||||
|
is_first_frame: bool,
|
||||||
|
|
||||||
/// State previous frame (if any).
|
/// State previous frame (if any).
|
||||||
/// This can be used to predict future sizes of cells.
|
/// This can be used to predict future sizes of cells.
|
||||||
prev_state: State,
|
prev_state: State,
|
||||||
|
@ -71,8 +74,9 @@ pub(crate) struct GridLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GridLayout {
|
impl GridLayout {
|
||||||
pub(crate) fn new(ui: &Ui, id: Id) -> Self {
|
pub(crate) fn new(ui: &Ui, id: Id, prev_state: Option<State>) -> Self {
|
||||||
let prev_state = State::load(ui.ctx(), id).unwrap_or_default();
|
let is_first_frame = prev_state.is_none();
|
||||||
|
let prev_state = prev_state.unwrap_or_default();
|
||||||
|
|
||||||
// TODO(emilk): respect current layout
|
// TODO(emilk): respect current layout
|
||||||
|
|
||||||
|
@ -88,6 +92,7 @@ impl GridLayout {
|
||||||
ctx: ui.ctx().clone(),
|
ctx: ui.ctx().clone(),
|
||||||
style: ui.style().clone(),
|
style: ui.style().clone(),
|
||||||
id,
|
id,
|
||||||
|
is_first_frame,
|
||||||
prev_state,
|
prev_state,
|
||||||
curr_state: State::default(),
|
curr_state: State::default(),
|
||||||
initial_available,
|
initial_available,
|
||||||
|
@ -125,7 +130,16 @@ impl GridLayout {
|
||||||
let is_last_column = Some(self.col + 1) == self.num_columns;
|
let is_last_column = Some(self.col + 1) == self.num_columns;
|
||||||
|
|
||||||
let width = if is_last_column {
|
let width = if is_last_column {
|
||||||
(self.initial_available.right() - region.cursor.left()).at_most(self.max_cell_size.x)
|
// The first frame we don't really know the widths of the previous columns,
|
||||||
|
// so returning a big available width here can cause trouble.
|
||||||
|
if self.is_first_frame {
|
||||||
|
self.curr_state
|
||||||
|
.col_width(self.col)
|
||||||
|
.unwrap_or(self.min_cell_size.x)
|
||||||
|
} else {
|
||||||
|
(self.initial_available.right() - region.cursor.left())
|
||||||
|
.at_most(self.max_cell_size.x)
|
||||||
|
}
|
||||||
} else if self.max_cell_size.x.is_finite() {
|
} else if self.max_cell_size.x.is_finite() {
|
||||||
// TODO(emilk): should probably heed `prev_state` here too
|
// TODO(emilk): should probably heed `prev_state` here too
|
||||||
self.max_cell_size.x
|
self.max_cell_size.x
|
||||||
|
@ -361,14 +375,17 @@ impl Grid {
|
||||||
let min_row_height = min_row_height.unwrap_or_else(|| ui.spacing().interact_size.y);
|
let min_row_height = min_row_height.unwrap_or_else(|| ui.spacing().interact_size.y);
|
||||||
let spacing = spacing.unwrap_or_else(|| ui.spacing().item_spacing);
|
let spacing = spacing.unwrap_or_else(|| ui.spacing().item_spacing);
|
||||||
|
|
||||||
|
let id = ui.make_persistent_id(id_source);
|
||||||
|
let prev_state = State::load(ui.ctx(), id);
|
||||||
|
|
||||||
// Each grid cell is aligned LEFT_CENTER.
|
// Each grid cell is aligned LEFT_CENTER.
|
||||||
// If somebody wants to wrap more things inside a cell,
|
// If somebody wants to wrap more things inside a cell,
|
||||||
// then we should pick a default layout that matches that alignment,
|
// then we should pick a default layout that matches that alignment,
|
||||||
// which we do here:
|
// which we do here:
|
||||||
let max_rect = ui.cursor().intersect(ui.max_rect());
|
let max_rect = ui.cursor().intersect(ui.max_rect());
|
||||||
ui.allocate_ui_at_rect(max_rect, |ui| {
|
ui.allocate_ui_at_rect(max_rect, |ui| {
|
||||||
|
ui.set_visible(prev_state.is_some()); // Avoid visible first-frame jitter
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
let id = ui.make_persistent_id(id_source);
|
|
||||||
let grid = GridLayout {
|
let grid = GridLayout {
|
||||||
num_columns,
|
num_columns,
|
||||||
striped,
|
striped,
|
||||||
|
@ -376,7 +393,7 @@ impl Grid {
|
||||||
max_cell_size,
|
max_cell_size,
|
||||||
spacing,
|
spacing,
|
||||||
row: start_row,
|
row: start_row,
|
||||||
..GridLayout::new(ui, id)
|
..GridLayout::new(ui, id, prev_state)
|
||||||
};
|
};
|
||||||
|
|
||||||
ui.set_grid(grid);
|
ui.set_grid(grid);
|
||||||
|
|
Loading…
Reference in a new issue