From 63a70ab00d5447c6a0fa53f54675335ce4301dbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20R=C3=B6ssler?= Date: Wed, 9 Feb 2022 16:00:25 +0100 Subject: [PATCH] remove padding, use egui item spacing --- egui_demo_lib/src/apps/demo/grid_demo.rs | 6 +-- egui_demo_lib/src/apps/demo/table_demo.rs | 20 ++++----- egui_extras/src/datepicker/popup.rs | 19 +++++---- egui_extras/src/grid.rs | 49 +++++++++-------------- egui_extras/src/layout.rs | 42 +++++++++---------- egui_extras/src/lib.rs | 2 - egui_extras/src/padding.rs | 29 -------------- egui_extras/src/sizing.rs | 4 +- egui_extras/src/table.rs | 28 ++++++------- 9 files changed, 81 insertions(+), 118 deletions(-) delete mode 100644 egui_extras/src/padding.rs diff --git a/egui_demo_lib/src/apps/demo/grid_demo.rs b/egui_demo_lib/src/apps/demo/grid_demo.rs index 85154209..8f6df706 100644 --- a/egui_demo_lib/src/apps/demo/grid_demo.rs +++ b/egui_demo_lib/src/apps/demo/grid_demo.rs @@ -1,5 +1,5 @@ use egui::Color32; -use egui_extras::{GridBuilder, Padding, Size}; +use egui_extras::{GridBuilder, Size}; /// Shows off a table with dynamic layout #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] @@ -25,14 +25,14 @@ impl super::Demo for GridDemo { impl super::View for GridDemo { fn ui(&mut self, ui: &mut egui::Ui) { - GridBuilder::new(ui, Padding::new(0.0, 0.0)) + GridBuilder::new(ui) .size(Size::Absolute(50.0)) .size(Size::Remainder) .size(Size::RelativeMinimum { relative: 0.5, minimum: 60.0, }) - .size(Size::Absolute(14.0)) + .size(Size::Absolute(10.0)) .vertical(|mut grid| { grid.cell(|ui| { ui.painter() diff --git a/egui_demo_lib/src/apps/demo/table_demo.rs b/egui_demo_lib/src/apps/demo/table_demo.rs index d6c47d77..a005399b 100644 --- a/egui_demo_lib/src/apps/demo/table_demo.rs +++ b/egui_demo_lib/src/apps/demo/table_demo.rs @@ -1,5 +1,5 @@ -use egui::Label; -use egui_extras::{GridBuilder, Padding, Size, TableBuilder}; +use egui::{Label, Vec2}; +use egui_extras::{GridBuilder, Size, TableBuilder}; /// Shows off a table with dynamic layout #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] @@ -30,13 +30,15 @@ impl super::View for TableDemo { ui.checkbox(&mut self.virtual_scrool, "Virtual scroll demo"); // The table is inside a grid as its container would otherwise grow slowly as it takes all available height - GridBuilder::new(ui, Padding::new(0.0, 0.0)) + ui.spacing_mut().item_spacing = Vec2::splat(4.0); + GridBuilder::new(ui) .size(Size::Remainder) - .size(Size::Absolute(14.0)) + .size(Size::Absolute(10.0)) .vertical(|mut grid| { - grid.cell(|ui| { - // TODO: Fix table as a padding smaller than 16 grows the window - TableBuilder::new(ui, Padding::new(3.0, 16.0)) + grid.cell_clip(|ui| { + ui.spacing_mut().item_spacing = Vec2::splat(3.0); + + TableBuilder::new(ui) .striped(true) .column(Size::Absolute(120.0)) .column(Size::RemainderMinimum(180.0)) @@ -58,7 +60,7 @@ impl super::View for TableDemo { row.col(|ui| { ui.label(index.to_string()); }); - row.col(|ui| { + row.col_clip(|ui| { ui.add( Label::new("virtual scroll, easily with thousands of rows!") .wrap(false), @@ -79,7 +81,7 @@ impl super::View for TableDemo { row.col(|ui| { ui.label(i.to_string()); }); - row.col(|ui| { + row.col_clip(|ui| { ui.add( Label::new( format!("Normal scroll, each row can have a different height. Height: {}", height), diff --git a/egui_extras/src/datepicker/popup.rs b/egui_extras/src/datepicker/popup.rs index 11c9aaa4..759dee98 100644 --- a/egui_extras/src/datepicker/popup.rs +++ b/egui_extras/src/datepicker/popup.rs @@ -1,7 +1,7 @@ use super::{button::DatePickerButtonState, month_data}; -use crate::{GridBuilder, Padding, Size, TableBuilder}; +use crate::{GridBuilder, Size, TableBuilder}; use chrono::{Date, Datelike, NaiveDate, Utc, Weekday}; -use egui::{Align, Button, Color32, ComboBox, Direction, Id, Label, Layout, RichText, Ui}; +use egui::{Align, Button, Color32, ComboBox, Direction, Id, Label, Layout, RichText, Ui, Vec2}; #[derive(Default, Clone)] #[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))] @@ -52,7 +52,9 @@ impl<'a> DatePickerPopup<'a> { let weeks = month_data(popup_state.year, popup_state.month); let mut close = false; let height = 20.0; - GridBuilder::new(ui, Padding::new(2.0, 0.0)) + let spacing = 2.0; + ui.spacing_mut().item_spacing = Vec2::splat(spacing); + GridBuilder::new(ui) .sizes( Size::Absolute(height), match (self.combo_boxes, self.arrows) { @@ -62,7 +64,7 @@ impl<'a> DatePickerPopup<'a> { }, ) .sizes( - Size::Absolute(2.0 + (height + 2.0) * weeks.len() as f32), + Size::Absolute((spacing + height) * (weeks.len() + 1) as f32), if self.calendar { 1 } else { 0 }, ) .size(Size::Absolute(height)) @@ -70,7 +72,7 @@ impl<'a> DatePickerPopup<'a> { if self.combo_boxes { grid.grid_noclip(|builder| { builder.sizes(Size::Remainder, 3).horizontal(|mut grid| { - grid.cell_noclip(|ui| { + grid.cell(|ui| { ComboBox::from_id_source("date_picker_year") .selected_text(popup_state.year.to_string()) .show_ui(ui, |ui| { @@ -90,7 +92,7 @@ impl<'a> DatePickerPopup<'a> { } }); }); - grid.cell_noclip(|ui| { + grid.cell(|ui| { ComboBox::from_id_source("date_picker_month") .selected_text(popup_state.month.to_string()) .show_ui(ui, |ui| { @@ -110,7 +112,7 @@ impl<'a> DatePickerPopup<'a> { } }); }); - grid.cell_noclip(|ui| { + grid.cell(|ui| { ComboBox::from_id_source("date_picker_day") .selected_text(popup_state.day.to_string()) .show_ui(ui, |ui| { @@ -231,7 +233,8 @@ impl<'a> DatePickerPopup<'a> { if self.calendar { grid.cell(|ui| { - TableBuilder::new(ui, Padding::new(2.0, 0.0)) + ui.spacing_mut().item_spacing = Vec2::new(1.0, 2.0); + TableBuilder::new(ui) .scroll(false) .columns(Size::Remainder, if self.calendar_week { 8 } else { 7 }) .header(height, |mut header| { diff --git a/egui_extras/src/grid.rs b/egui_extras/src/grid.rs index 2744aae2..cc317c24 100644 --- a/egui_extras/src/grid.rs +++ b/egui_extras/src/grid.rs @@ -1,7 +1,7 @@ use crate::{ layout::{CellSize, Layout, LineDirection}, sizing::Sizing, - Padding, Size, + Size, }; use egui::Ui; @@ -13,20 +13,15 @@ enum GridDirection { pub struct GridBuilder<'a> { ui: &'a mut Ui, sizing: Sizing, - padding: Padding, } impl<'a> GridBuilder<'a> { /// Create new grid builder /// After adding size hints with `[Self::column]`/`[Self::columns]` the grid can be build with `[Self::horizontal]`/`[Self::vertical]` - pub fn new(ui: &'a mut Ui, padding: Padding) -> Self { + pub fn new(ui: &'a mut Ui) -> Self { let sizing = Sizing::new(); - Self { - ui, - sizing, - padding, - } + Self { ui, sizing } } /// Add size hint for column/row @@ -50,15 +45,14 @@ impl<'a> GridBuilder<'a> { F: for<'b> FnOnce(Grid<'a, 'b>), { let widths = self.sizing.into_lengths( - self.ui.available_rect_before_wrap().width() - 2.0 * self.padding.outer, - self.padding.inner, + self.ui.available_rect_before_wrap().width() - self.ui.spacing().item_spacing.x, + self.ui.spacing().item_spacing.x, ); - let mut layout = Layout::new(self.ui, self.padding.clone(), LineDirection::Vertical); + let mut layout = Layout::new(self.ui, LineDirection::Vertical); grid(Grid { layout: &mut layout, direction: GridDirection::Horizontal, - padding: self.padding.clone(), - widths, + sizes: widths, }); } @@ -68,16 +62,15 @@ impl<'a> GridBuilder<'a> { where F: for<'b> FnOnce(Grid<'a, 'b>), { - let widths = self.sizing.into_lengths( - self.ui.available_rect_before_wrap().height() - 2.0 * self.padding.outer, - self.padding.inner, + let heights = self.sizing.into_lengths( + self.ui.available_rect_before_wrap().height() - self.ui.spacing().item_spacing.y, + self.ui.spacing().item_spacing.y, ); - let mut layout = Layout::new(self.ui, self.padding.clone(), LineDirection::Horizontal); + let mut layout = Layout::new(self.ui, LineDirection::Horizontal); grid(Grid { layout: &mut layout, direction: GridDirection::Vertical, - padding: self.padding.clone(), - widths, + sizes: heights, }); } } @@ -85,20 +78,19 @@ impl<'a> GridBuilder<'a> { pub struct Grid<'a, 'b> { layout: &'b mut Layout<'a>, direction: GridDirection, - padding: Padding, - widths: Vec, + sizes: Vec, } impl<'a, 'b> Grid<'a, 'b> { fn size(&mut self) -> (CellSize, CellSize) { match self.direction { GridDirection::Horizontal => ( - CellSize::Absolute(self.widths.remove(0)), + CellSize::Absolute(self.sizes.remove(0)), CellSize::Remainder, ), GridDirection::Vertical => ( CellSize::Remainder, - CellSize::Absolute(self.widths.remove(0)), + CellSize::Absolute(self.sizes.remove(0)), ), } } @@ -106,7 +98,7 @@ impl<'a, 'b> Grid<'a, 'b> { /// Add empty cell pub fn empty(&mut self) { assert!( - !self.widths.is_empty(), + !self.sizes.is_empty(), "Tried using more grid cells then available." ); @@ -116,7 +108,7 @@ impl<'a, 'b> Grid<'a, 'b> { fn _cell(&mut self, clip: bool, add_contents: impl FnOnce(&mut Ui)) { assert!( - !self.widths.is_empty(), + !self.sizes.is_empty(), "Tried using more grid cells then available." ); @@ -130,14 +122,13 @@ impl<'a, 'b> Grid<'a, 'b> { } /// Add cell, content is clipped - pub fn cell_noclip(&mut self, add_contents: impl FnOnce(&mut Ui)) { + pub fn cell_clip(&mut self, add_contents: impl FnOnce(&mut Ui)) { self._cell(true, add_contents); } fn _grid(&mut self, clip: bool, grid_builder: impl FnOnce(GridBuilder<'_>)) { - let padding = self.padding.clone(); self._cell(clip, |ui| { - grid_builder(GridBuilder::new(ui, padding)); + grid_builder(GridBuilder::new(ui)); }); } /// Add grid as cell @@ -153,7 +144,7 @@ impl<'a, 'b> Grid<'a, 'b> { impl<'a, 'b> Drop for Grid<'a, 'b> { fn drop(&mut self) { - while !self.widths.is_empty() { + while !self.sizes.is_empty() { self.empty(); } } diff --git a/egui_extras/src/layout.rs b/egui_extras/src/layout.rs index abca17b2..7e1dad01 100644 --- a/egui_extras/src/layout.rs +++ b/egui_extras/src/layout.rs @@ -1,5 +1,4 @@ -use crate::Padding; -use egui::{Pos2, Rect, Response, Rgba, Sense, Ui, Vec2}; +use egui::{Pos2, Rect, Response, Rgba, Sense, Ui}; #[derive(Clone, Copy)] pub(crate) enum CellSize { @@ -30,7 +29,6 @@ pub(crate) enum LineDirection { /// Positions cells in `[LineDirection]` and starts a new line on `[Layout::end_line]` pub struct Layout<'l> { ui: &'l mut Ui, - padding: Padding, direction: LineDirection, rect: Rect, pos: Pos2, @@ -38,15 +36,12 @@ pub struct Layout<'l> { } impl<'l> Layout<'l> { - pub(crate) fn new(ui: &'l mut Ui, padding: Padding, direction: LineDirection) -> Self { - let rect = ui - .available_rect_before_wrap() - .shrink(padding.inner + padding.outer); + pub(crate) fn new(ui: &'l mut Ui, direction: LineDirection) -> Self { + let rect = ui.available_rect_before_wrap(); let pos = rect.left_top(); Self { ui, - padding, rect, pos, max: pos, @@ -64,11 +59,11 @@ impl<'l> Layout<'l> { max: Pos2 { x: match width { CellSize::Absolute(width) => self.pos.x + width, - CellSize::Remainder => self.rect.right(), + CellSize::Remainder => self.rect.right() - self.ui.spacing().item_spacing.x, }, y: match height { CellSize::Absolute(height) => self.pos.y + height, - CellSize::Remainder => self.rect.bottom(), + CellSize::Remainder => self.rect.bottom() - self.ui.spacing().item_spacing.y, }, }, } @@ -77,15 +72,21 @@ impl<'l> Layout<'l> { fn set_pos(&mut self, rect: Rect) { match self.direction { LineDirection::Horizontal => { - self.pos.y = rect.bottom() + self.padding.inner; + self.pos.y = rect.bottom() + self.ui.spacing().item_spacing.y; } LineDirection::Vertical => { - self.pos.x = rect.right() + self.padding.inner; + self.pos.x = rect.right() + self.ui.spacing().item_spacing.x; } } - self.max.x = self.max.x.max(rect.right() + self.padding.inner); - self.max.y = self.max.y.max(rect.bottom() + self.padding.inner); + self.max.x = self + .max + .x + .max(rect.right() + self.ui.spacing().item_spacing.x); + self.max.y = self + .max + .y + .max(rect.bottom() + self.ui.spacing().item_spacing.y); } pub(crate) fn empty(&mut self, width: CellSize, height: CellSize) { @@ -114,8 +115,9 @@ impl<'l> Layout<'l> { add_contents: impl FnOnce(&mut Ui), ) -> Response { let mut rect = self.cell_rect(&width, &height); - *rect.top_mut() -= self.padding.inner; - *rect.left_mut() -= self.padding.inner; + // Make sure we don't have a gap in the stripe background + *rect.top_mut() -= self.ui.spacing().item_spacing.y; + *rect.left_mut() -= self.ui.spacing().item_spacing.x; let text_color: Rgba = self.ui.visuals().text_color().into(); self.ui @@ -154,12 +156,8 @@ impl<'l> Layout<'l> { if clip { let mut clip_rect = child_ui.clip_rect(); - clip_rect.min = clip_rect - .min - .max(rect.min - Vec2::new(self.padding.inner, self.padding.inner)); - clip_rect.max = clip_rect - .max - .min(rect.max + Vec2::new(self.padding.inner, self.padding.inner)); + clip_rect.min = clip_rect.min.max(rect.min); + clip_rect.max = clip_rect.max.min(rect.max); child_ui.set_clip_rect(clip_rect); } diff --git a/egui_extras/src/lib.rs b/egui_extras/src/lib.rs index 99ed7483..9b718ee2 100644 --- a/egui_extras/src/lib.rs +++ b/egui_extras/src/lib.rs @@ -85,7 +85,6 @@ mod datepicker; mod grid; mod layout; -mod padding; mod sizing; mod table; @@ -94,6 +93,5 @@ pub use datepicker::DatePickerButton; pub use grid::*; pub(crate) use layout::Layout; -pub use padding::Padding; pub use sizing::Size; pub use table::*; diff --git a/egui_extras/src/padding.rs b/egui_extras/src/padding.rs deleted file mode 100644 index 23de3592..00000000 --- a/egui_extras/src/padding.rs +++ /dev/null @@ -1,29 +0,0 @@ -/// Configure padding of grid or table -/// TODO: Use padding settings of egui/should we extend egui padding settings for table? -#[derive(Clone, Debug)] -pub struct Padding { - pub(crate) inner: f32, - pub(crate) outer: f32, -} - -impl Padding { - pub fn new(inner: f32, outer: f32) -> Self { - Self { inner, outer } - } - - pub fn inner(mut self, inner: f32) -> Self { - self.inner = inner; - self - } - - pub fn outer(mut self, outer: f32) -> Self { - self.outer = outer; - self - } -} - -impl Default for Padding { - fn default() -> Self { - Self::new(5.0, 10.0) - } -} diff --git a/egui_extras/src/sizing.rs b/egui_extras/src/sizing.rs index e8fa7379..c9cf261c 100644 --- a/egui_extras/src/sizing.rs +++ b/egui_extras/src/sizing.rs @@ -32,7 +32,7 @@ impl Sizing { self.sizes.push(size); } - pub fn into_lengths(self, length: f32, inner_padding: f32) -> Vec { + pub fn into_lengths(self, length: f32, spacing: f32) -> Vec { let mut remainders = 0; let sum_non_remainder = self .sizes @@ -55,7 +55,7 @@ impl Sizing { } }) .sum::() - + inner_padding * (self.sizes.len() + 1) as f32; + + spacing * (self.sizes.len() - 1) as f32; let avg_remainder_length = if remainders == 0 { 0.0 diff --git a/egui_extras/src/table.rs b/egui_extras/src/table.rs index 50f23b54..244d91f1 100644 --- a/egui_extras/src/table.rs +++ b/egui_extras/src/table.rs @@ -5,7 +5,7 @@ use crate::{ layout::{CellSize, LineDirection}, sizing::Sizing, - Layout, Padding, Size, + Layout, Size, }; use egui::{Response, Ui}; @@ -13,19 +13,17 @@ use std::cmp; pub struct TableBuilder<'a> { ui: &'a mut Ui, - padding: Padding, sizing: Sizing, scroll: bool, striped: bool, } impl<'a> TableBuilder<'a> { - pub fn new(ui: &'a mut Ui, padding: Padding) -> Self { + pub fn new(ui: &'a mut Ui) -> Self { let sizing = Sizing::new(); Self { ui, - padding, sizing, scroll: true, striped: false, @@ -61,12 +59,18 @@ impl<'a> TableBuilder<'a> { /// Create a header row which always stays visible and at the top pub fn header(self, height: f32, header: impl FnOnce(TableRow<'_, '_>)) -> Table<'a> { let widths = self.sizing.into_lengths( - self.ui.available_rect_before_wrap().width() - 2.0 * self.padding.outer, - self.padding.inner, + self.ui.available_rect_before_wrap().width() + - self.ui.spacing().item_spacing.x + - if self.scroll { + self.ui.spacing().scroll_bar_width + } else { + 0.0 + }, + self.ui.spacing().item_spacing.x, ); let ui = self.ui; { - let mut layout = Layout::new(ui, self.padding.clone(), LineDirection::Vertical); + let mut layout = Layout::new(ui, LineDirection::Vertical); { let row = TableRow { layout: &mut layout, @@ -81,7 +85,6 @@ impl<'a> TableBuilder<'a> { Table { ui, - padding: self.padding, widths, scroll: self.scroll, striped: self.striped, @@ -94,13 +97,12 @@ impl<'a> TableBuilder<'a> { F: for<'b> FnOnce(TableBody<'b>), { let widths = self.sizing.into_lengths( - self.ui.available_rect_before_wrap().width() - 2.0 * self.padding.outer, - self.padding.inner, + self.ui.available_rect_before_wrap().width(), + self.ui.spacing().item_spacing.x, ); Table { ui: self.ui, - padding: self.padding, widths, scroll: self.scroll, striped: self.striped, @@ -111,7 +113,6 @@ impl<'a> TableBuilder<'a> { pub struct Table<'a> { ui: &'a mut Ui, - padding: Padding, widths: Vec, scroll: bool, striped: bool, @@ -123,7 +124,6 @@ impl<'a> Table<'a> { where F: for<'b> FnOnce(TableBody<'b>), { - let padding = self.padding; let ui = self.ui; let widths = self.widths; let striped = self.striped; @@ -131,7 +131,7 @@ impl<'a> Table<'a> { let end_y = ui.available_rect_before_wrap().bottom(); egui::ScrollArea::new([false, self.scroll]).show(ui, move |ui| { - let layout = Layout::new(ui, padding, LineDirection::Vertical); + let layout = Layout::new(ui, LineDirection::Vertical); body(TableBody { layout,