[grid] Fix the last corner cases and bugs
This commit is contained in:
parent
07f1b074ca
commit
2b48f9723b
2 changed files with 63 additions and 25 deletions
|
@ -50,7 +50,7 @@ pub(crate) struct GridLayout {
|
||||||
|
|
||||||
striped: bool,
|
striped: bool,
|
||||||
initial_x: f32,
|
initial_x: f32,
|
||||||
min_row_height: f32,
|
min_cell_size: Vec2,
|
||||||
col: usize,
|
col: usize,
|
||||||
row: usize,
|
row: usize,
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ impl GridLayout {
|
||||||
spacing: ui.style().spacing.item_spacing,
|
spacing: ui.style().spacing.item_spacing,
|
||||||
striped: false,
|
striped: false,
|
||||||
initial_x: ui.cursor().x,
|
initial_x: ui.cursor().x,
|
||||||
min_row_height: ui.style().spacing.interact_size.y,
|
min_cell_size: ui.style().spacing.interact_size,
|
||||||
col: 0,
|
col: 0,
|
||||||
row: 0,
|
row: 0,
|
||||||
}
|
}
|
||||||
|
@ -75,31 +75,36 @@ impl GridLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GridLayout {
|
impl GridLayout {
|
||||||
|
fn prev_col_width(&self, col: usize) -> f32 {
|
||||||
|
self.prev_state
|
||||||
|
.col_width(col)
|
||||||
|
.unwrap_or(self.min_cell_size.x)
|
||||||
|
}
|
||||||
fn prev_row_height(&self, row: usize) -> f32 {
|
fn prev_row_height(&self, row: usize) -> f32 {
|
||||||
self.prev_state
|
self.prev_state
|
||||||
.row_height(row)
|
.row_height(row)
|
||||||
.unwrap_or(self.min_row_height)
|
.unwrap_or(self.min_cell_size.y)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn available_rect(&self, region: &Region) -> Rect {
|
pub(crate) fn available_rect(&self, region: &Region) -> Rect {
|
||||||
// let mut rect = Rect::from_min_max(region.cursor, region.max_rect.max);
|
// let mut rect = Rect::from_min_max(region.cursor, region.max_rect.max);
|
||||||
// rect.set_height(rect.height().at_least(self.min_row_height));
|
// rect.set_height(rect.height().at_least(self.min_cell_size.y));
|
||||||
// rect
|
// rect
|
||||||
|
|
||||||
|
// required for putting CollapsingHeader in anything but the last column:
|
||||||
self.available_rect_finite(region)
|
self.available_rect_finite(region)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn available_rect_finite(&self, region: &Region) -> Rect {
|
pub(crate) fn available_rect_finite(&self, region: &Region) -> Rect {
|
||||||
// If we want to allow width-filling widgets like `Separator` in one of the first cells
|
// If we want to allow width-filling widgets like `Separator` in one of the first cells
|
||||||
// then we need to make sure they don't spill out of the first cell:
|
// then we need to make sure they don't spill out of the first cell:
|
||||||
let width = self
|
let width = self.prev_state.col_width(self.col);
|
||||||
.prev_state
|
let width = width.or_else(|| self.curr_state.col_width(self.col));
|
||||||
.col_width(self.col)
|
let width = width.unwrap_or_default().at_least(self.min_cell_size.x);
|
||||||
.or_else(|| self.curr_state.col_width(self.col))
|
|
||||||
.unwrap_or_default();
|
let height = region.max_rect_finite().max.y - region.cursor.y;
|
||||||
let height = region
|
let height = height.at_least(self.min_cell_size.y);
|
||||||
.max_rect_finite()
|
|
||||||
.height()
|
|
||||||
.at_least(self.min_row_height);
|
|
||||||
Rect::from_min_size(region.cursor, vec2(width, height))
|
Rect::from_min_size(region.cursor, vec2(width, height))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,10 +125,35 @@ impl GridLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn advance(&mut self, cursor: &mut Pos2, frame_rect: Rect, widget_rect: Rect) {
|
pub(crate) fn advance(&mut self, cursor: &mut Pos2, frame_rect: Rect, widget_rect: Rect) {
|
||||||
|
let debug_expand_width = self.ctx.style().visuals.debug_expand_width;
|
||||||
|
let debug_expand_height = self.ctx.style().visuals.debug_expand_height;
|
||||||
|
if debug_expand_width || debug_expand_height {
|
||||||
|
let rect = widget_rect;
|
||||||
|
let too_wide = rect.width() > self.prev_col_width(self.col);
|
||||||
|
let too_high = rect.height() > self.prev_row_height(self.row);
|
||||||
|
|
||||||
|
if (debug_expand_width && too_wide) || (debug_expand_height && too_high) {
|
||||||
|
let painter = self.ctx.debug_painter();
|
||||||
|
painter.rect_stroke(rect, 0.0, (1.0, Color32::LIGHT_BLUE));
|
||||||
|
|
||||||
|
let stroke = Stroke::new(2.5, Color32::from_rgb(200, 0, 0));
|
||||||
|
let paint_line_seg = |a, b| painter.line_segment([a, b], stroke);
|
||||||
|
|
||||||
|
if debug_expand_width && too_wide {
|
||||||
|
paint_line_seg(rect.left_top(), rect.left_bottom());
|
||||||
|
paint_line_seg(rect.left_center(), rect.right_center());
|
||||||
|
paint_line_seg(rect.right_top(), rect.right_bottom());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.curr_state
|
self.curr_state
|
||||||
.set_min_col_width(self.col, widget_rect.width());
|
.set_min_col_width(self.col, widget_rect.width().at_least(self.min_cell_size.x));
|
||||||
self.curr_state
|
self.curr_state.set_min_row_height(
|
||||||
.set_min_row_height(self.row, widget_rect.height().at_least(self.min_row_height));
|
self.row,
|
||||||
|
widget_rect.height().at_least(self.min_cell_size.y),
|
||||||
|
);
|
||||||
|
|
||||||
self.col += 1;
|
self.col += 1;
|
||||||
cursor.x += frame_rect.width() + self.spacing.x;
|
cursor.x += frame_rect.width() + self.spacing.x;
|
||||||
}
|
}
|
||||||
|
@ -184,6 +214,7 @@ impl GridLayout {
|
||||||
pub struct Grid {
|
pub struct Grid {
|
||||||
id_source: Id,
|
id_source: Id,
|
||||||
striped: bool,
|
striped: bool,
|
||||||
|
min_col_width: Option<f32>,
|
||||||
min_row_height: Option<f32>,
|
min_row_height: Option<f32>,
|
||||||
spacing: Option<Vec2>,
|
spacing: Option<Vec2>,
|
||||||
}
|
}
|
||||||
|
@ -193,6 +224,7 @@ impl Grid {
|
||||||
Self {
|
Self {
|
||||||
id_source: Id::new(id_source),
|
id_source: Id::new(id_source),
|
||||||
striped: false,
|
striped: false,
|
||||||
|
min_col_width: None,
|
||||||
min_row_height: None,
|
min_row_height: None,
|
||||||
spacing: None,
|
spacing: None,
|
||||||
}
|
}
|
||||||
|
@ -207,6 +239,12 @@ impl Grid {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set minimum width of each column. Default: [`Spacing::interact_size.x`].
|
||||||
|
pub fn min_col_width(mut self, min_col_width: f32) -> Self {
|
||||||
|
self.min_col_width = Some(min_col_width);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Set minimum height of each row. Default: [`Spacing::interact_size.y`].
|
/// Set minimum height of each row. Default: [`Spacing::interact_size.y`].
|
||||||
pub fn min_row_height(mut self, min_row_height: f32) -> Self {
|
pub fn min_row_height(mut self, min_row_height: f32) -> Self {
|
||||||
self.min_row_height = Some(min_row_height);
|
self.min_row_height = Some(min_row_height);
|
||||||
|
@ -226,9 +264,11 @@ impl Grid {
|
||||||
let Self {
|
let Self {
|
||||||
id_source,
|
id_source,
|
||||||
striped,
|
striped,
|
||||||
|
min_col_width,
|
||||||
min_row_height,
|
min_row_height,
|
||||||
spacing,
|
spacing,
|
||||||
} = self;
|
} = self;
|
||||||
|
let min_col_width = min_col_width.unwrap_or_else(|| ui.style().spacing.interact_size.x);
|
||||||
let min_row_height = min_row_height.unwrap_or_else(|| ui.style().spacing.interact_size.y);
|
let min_row_height = min_row_height.unwrap_or_else(|| ui.style().spacing.interact_size.y);
|
||||||
let spacing = spacing.unwrap_or_else(|| ui.style().spacing.item_spacing);
|
let spacing = spacing.unwrap_or_else(|| ui.style().spacing.item_spacing);
|
||||||
|
|
||||||
|
@ -240,10 +280,11 @@ impl Grid {
|
||||||
let id = ui.make_persistent_id(id_source);
|
let id = ui.make_persistent_id(id_source);
|
||||||
let grid = GridLayout {
|
let grid = GridLayout {
|
||||||
striped,
|
striped,
|
||||||
min_row_height,
|
|
||||||
spacing,
|
spacing,
|
||||||
|
min_cell_size: vec2(min_col_width, min_row_height),
|
||||||
..GridLayout::new(ui, id)
|
..GridLayout::new(ui, id)
|
||||||
};
|
};
|
||||||
|
|
||||||
ui.set_grid(grid);
|
ui.set_grid(grid);
|
||||||
let r = add_contents(ui);
|
let r = add_contents(ui);
|
||||||
ui.save_grid();
|
ui.save_grid();
|
||||||
|
|
|
@ -203,8 +203,7 @@ impl Ui {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is like `max_rect()`, but will never be infinite.
|
/// This is like `max_rect()`, but will never be infinite.
|
||||||
/// If the desired rect is infinite ("be as big as you want")
|
/// This can be useful for widgets that expand to fit the available space.
|
||||||
/// this will be bounded by `min_rect` instead.
|
|
||||||
pub fn max_rect_finite(&self) -> Rect {
|
pub fn max_rect_finite(&self) -> Rect {
|
||||||
self.placer.max_rect_finite()
|
self.placer.max_rect_finite()
|
||||||
}
|
}
|
||||||
|
@ -310,7 +309,7 @@ impl Ui {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is like `available_size_before_wrap()`, but will never be infinite.
|
/// This is like `available_size_before_wrap()`, but will never be infinite.
|
||||||
/// Use this for components that want to grow without bounds (but shouldn't).
|
/// This can be useful for widgets that expand to fit the available space.
|
||||||
/// In most layouts the next widget will be put in the top left corner of this `Rect`.
|
/// In most layouts the next widget will be put in the top left corner of this `Rect`.
|
||||||
pub fn available_size_before_wrap_finite(&self) -> Vec2 {
|
pub fn available_size_before_wrap_finite(&self) -> Vec2 {
|
||||||
self.placer.available_rect_before_wrap_finite().size()
|
self.placer.available_rect_before_wrap_finite().size()
|
||||||
|
@ -321,7 +320,7 @@ impl Ui {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is like `available_rect_before_wrap()`, but will never be infinite.
|
/// This is like `available_rect_before_wrap()`, but will never be infinite.
|
||||||
/// Use this for components that want to grow without bounds (but shouldn't).
|
/// This can be useful for widgets that expand to fit the available space.
|
||||||
/// In most layouts the next widget will be put in the top left corner of this `Rect`.
|
/// In most layouts the next widget will be put in the top left corner of this `Rect`.
|
||||||
pub fn available_rect_before_wrap_finite(&self) -> Rect {
|
pub fn available_rect_before_wrap_finite(&self) -> Rect {
|
||||||
self.placer.available_rect_before_wrap_finite()
|
self.placer.available_rect_before_wrap_finite()
|
||||||
|
@ -475,10 +474,8 @@ impl Ui {
|
||||||
self.painter
|
self.painter
|
||||||
.rect_stroke(rect, 0.0, (1.0, Color32::LIGHT_BLUE));
|
.rect_stroke(rect, 0.0, (1.0, Color32::LIGHT_BLUE));
|
||||||
|
|
||||||
let color = color::Color32::from_rgb(200, 0, 0);
|
let stroke = Stroke::new(2.5, Color32::from_rgb(200, 0, 0));
|
||||||
let width = 2.5;
|
let paint_line_seg = |a, b| self.painter().line_segment([a, b], stroke);
|
||||||
|
|
||||||
let paint_line_seg = |a, b| self.painter().line_segment([a, b], (width, color));
|
|
||||||
|
|
||||||
if debug_expand_width && too_wide {
|
if debug_expand_width && too_wide {
|
||||||
paint_line_seg(rect.left_top(), rect.left_bottom());
|
paint_line_seg(rect.left_top(), rect.left_bottom());
|
||||||
|
|
Loading…
Reference in a new issue