From faf104220be18cda878e9864bab3760caa4901d8 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 2 Jul 2021 09:55:57 +0200 Subject: [PATCH] Grid::num_columns: allow the last column to take up the rest of the space This allows for resizaeable grids, where the last column will be given the remainder of the width. To demonstrate, the widget gallery window is now resizeable. --- CHANGELOG.md | 3 ++ egui/src/grid.rs | 41 ++++++++++++++----- egui_demo_lib/src/apps/demo/widget_gallery.rs | 6 ++- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37cda03cc19..3c617deab34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,10 @@ NOTE: [`eframe`](eframe/CHANGELOG.md), [`egui_web`](egui_web/CHANGELOG.md) and [ ## Unreleased + +### Added ⭐ * [Progress bar](https://github.com/emilk/egui/pull/519) +* `Grid::num_columns`: allow the last column to take up the rest of the space of the parent `Ui`. ## 0.13.1 - 2021-06-28 - Plot fixes diff --git a/egui/src/grid.rs b/egui/src/grid.rs index 210d05490ef..cbef8c865ae 100644 --- a/egui/src/grid.rs +++ b/egui/src/grid.rs @@ -46,13 +46,16 @@ pub(crate) struct GridLayout { prev_state: State, /// State accumulated during the current frame. curr_state: State, + initial_available: Rect, + // Options: + num_columns: Option, spacing: Vec2, - - striped: bool, - initial_x: f32, min_cell_size: Vec2, max_cell_size: Vec2, + striped: bool, + + // Cursor: col: usize, row: usize, } @@ -63,10 +66,9 @@ impl GridLayout { // TODO: respect current layout - let available = ui.placer().max_rect().intersect(ui.cursor()); - let initial_x = available.min.x; + let initial_available = ui.placer().max_rect().intersect(ui.cursor()); assert!( - initial_x.is_finite(), + initial_available.min.x.is_finite(), "Grid not yet available for right-to-left layouts" ); @@ -76,11 +78,14 @@ impl GridLayout { id, prev_state, curr_state: State::default(), + initial_available, + + num_columns: None, spacing: ui.spacing().item_spacing, - striped: false, - initial_x, min_cell_size: ui.spacing().interact_size, max_cell_size: Vec2::INFINITY, + striped: false, + col: 0, row: 0, } @@ -109,7 +114,11 @@ impl GridLayout { } pub(crate) fn available_rect_finite(&self, region: &Region) -> Rect { - let width = if self.max_cell_size.x.is_finite() { + let is_last_column = Some(self.col + 1) == self.num_columns; + + let width = if is_last_column { + (self.initial_available.right() - region.cursor.left()).at_most(self.max_cell_size.x) + } else if self.max_cell_size.x.is_finite() { // TODO: should probably heed `prev_state` here too self.max_cell_size.x } else { @@ -183,7 +192,7 @@ impl GridLayout { } pub(crate) fn end_row(&mut self, cursor: &mut Rect, painter: &Painter) { - cursor.min.x = self.initial_x; + cursor.min.x = self.initial_available.min.x; cursor.min.y += self.spacing.y; cursor.min.y += self .curr_state @@ -247,6 +256,7 @@ impl GridLayout { #[must_use = "You should call .show()"] pub struct Grid { id_source: Id, + num_columns: Option, striped: bool, min_col_width: Option, min_row_height: Option, @@ -260,6 +270,7 @@ impl Grid { pub fn new(id_source: impl std::hash::Hash) -> Self { Self { id_source: Id::new(id_source), + num_columns: None, striped: false, min_col_width: None, min_row_height: None, @@ -269,6 +280,12 @@ impl Grid { } } + /// Setting this will allow the last column to expand to take up the rest of the space of the parent [`Ui`]. + pub fn num_columns(mut self, num_columns: usize) -> Self { + self.num_columns = Some(num_columns); + self + } + /// If `true`, add a subtle background color to every other row. /// /// This can make a table easier to read. @@ -317,6 +334,7 @@ impl Grid { pub fn show(self, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) -> InnerResponse { let Self { id_source, + num_columns, striped, min_col_width, min_row_height, @@ -336,10 +354,11 @@ impl Grid { ui.horizontal(|ui| { let id = ui.make_persistent_id(id_source); let grid = GridLayout { + num_columns, striped, - spacing, min_cell_size: vec2(min_col_width, min_row_height), max_cell_size, + spacing, row: start_row, ..GridLayout::new(ui, id) }; diff --git a/egui_demo_lib/src/apps/demo/widget_gallery.rs b/egui_demo_lib/src/apps/demo/widget_gallery.rs index 19527000a8b..34475a34da9 100644 --- a/egui_demo_lib/src/apps/demo/widget_gallery.rs +++ b/egui_demo_lib/src/apps/demo/widget_gallery.rs @@ -42,7 +42,8 @@ impl super::Demo for WidgetGallery { fn show(&mut self, ctx: &egui::CtxRef, open: &mut bool) { egui::Window::new(self.name()) .open(open) - .resizable(false) + .resizable(true) + .default_width(300.0) .show(ctx, |ui| { use super::View; self.ui(ui); @@ -57,8 +58,9 @@ impl super::View for WidgetGallery { ui.set_enabled(self.enabled); egui::Grid::new("my_grid") - .striped(true) + .num_columns(2) .spacing([40.0, 4.0]) + .striped(true) .show(ui, |ui| { self.gallery_grid_contents(ui); });