Rename grid to strip.
Easier documentation/naming of cell direction. Add doc comments for public structs.
This commit is contained in:
parent
42b6ed6100
commit
6d4e10cf91
10 changed files with 135 additions and 136 deletions
|
@ -23,13 +23,13 @@ impl Default for Demos {
|
|||
Box::new(super::dancing_strings::DancingStrings::default()),
|
||||
Box::new(super::drag_and_drop::DragAndDropDemo::default()),
|
||||
Box::new(super::font_book::FontBook::default()),
|
||||
Box::new(super::grid_demo::GridDemo::default()),
|
||||
Box::new(super::MiscDemoWindow::default()),
|
||||
Box::new(super::multi_touch::MultiTouch::default()),
|
||||
Box::new(super::painting::Painting::default()),
|
||||
Box::new(super::plot_demo::PlotDemo::default()),
|
||||
Box::new(super::scrolling::Scrolling::default()),
|
||||
Box::new(super::sliders::Sliders::default()),
|
||||
Box::new(super::strip_demo::StripDemo::default()),
|
||||
Box::new(super::table_demo::TableDemo::default()),
|
||||
Box::new(super::text_edit::TextEdit::default()),
|
||||
Box::new(super::widget_gallery::WidgetGallery::default()),
|
||||
|
|
|
@ -12,7 +12,6 @@ pub mod dancing_strings;
|
|||
pub mod demo_app_windows;
|
||||
pub mod drag_and_drop;
|
||||
pub mod font_book;
|
||||
pub mod grid_demo;
|
||||
pub mod layout_test;
|
||||
pub mod misc_demo_window;
|
||||
pub mod multi_touch;
|
||||
|
@ -22,6 +21,7 @@ pub mod password;
|
|||
pub mod plot_demo;
|
||||
pub mod scrolling;
|
||||
pub mod sliders;
|
||||
pub mod strip_demo;
|
||||
pub mod table_demo;
|
||||
pub mod tests;
|
||||
pub mod text_edit;
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
use egui::Color32;
|
||||
use egui_extras::{GridBuilder, Size};
|
||||
use egui_extras::{Size, StripBuilder};
|
||||
|
||||
/// Shows off a table with dynamic layout
|
||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||
#[derive(Default)]
|
||||
pub struct GridDemo {}
|
||||
pub struct StripDemo {}
|
||||
|
||||
impl super::Demo for GridDemo {
|
||||
impl super::Demo for StripDemo {
|
||||
fn name(&self) -> &'static str {
|
||||
"▣ Grid Demo"
|
||||
"▣ Strip Demo"
|
||||
}
|
||||
|
||||
fn show(&mut self, ctx: &egui::Context, open: &mut bool) {
|
||||
|
@ -23,9 +23,9 @@ impl super::Demo for GridDemo {
|
|||
}
|
||||
}
|
||||
|
||||
impl super::View for GridDemo {
|
||||
impl super::View for StripDemo {
|
||||
fn ui(&mut self, ui: &mut egui::Ui) {
|
||||
GridBuilder::new(ui)
|
||||
StripBuilder::new(ui)
|
||||
.size(Size::Absolute(50.0))
|
||||
.size(Size::Remainder)
|
||||
.size(Size::RelativeMinimum {
|
||||
|
@ -33,15 +33,15 @@ impl super::View for GridDemo {
|
|||
minimum: 60.0,
|
||||
})
|
||||
.size(Size::Absolute(10.0))
|
||||
.vertical(|mut grid| {
|
||||
grid.cell(|ui| {
|
||||
.vertical(|mut strip| {
|
||||
strip.cell(|ui| {
|
||||
ui.painter()
|
||||
.rect_filled(ui.available_rect_before_wrap(), 0.0, Color32::BLUE);
|
||||
ui.label("Full width and 50px height");
|
||||
});
|
||||
grid.grid(|builder| {
|
||||
builder.sizes(Size::Remainder, 2).horizontal(|mut grid| {
|
||||
grid.cell(|ui| {
|
||||
strip.strip(|builder| {
|
||||
builder.sizes(Size::Remainder, 2).horizontal(|mut strip| {
|
||||
strip.cell(|ui| {
|
||||
ui.painter().rect_filled(
|
||||
ui.available_rect_before_wrap(),
|
||||
0.0,
|
||||
|
@ -49,10 +49,10 @@ impl super::View for GridDemo {
|
|||
);
|
||||
ui.label("remaining height and 50% of the width");
|
||||
});
|
||||
grid.grid(|builder| {
|
||||
builder.sizes(Size::Remainder, 3).vertical(|mut grid| {
|
||||
grid.empty();
|
||||
grid.cell(|ui| {
|
||||
strip.strip(|builder| {
|
||||
builder.sizes(Size::Remainder, 3).vertical(|mut strip| {
|
||||
strip.empty();
|
||||
strip.cell(|ui| {
|
||||
ui.painter().rect_filled(
|
||||
ui.available_rect_before_wrap(),
|
||||
0.0,
|
||||
|
@ -64,22 +64,22 @@ impl super::View for GridDemo {
|
|||
});
|
||||
});
|
||||
});
|
||||
grid.grid(|builder| {
|
||||
strip.strip(|builder| {
|
||||
builder
|
||||
.size(Size::Remainder)
|
||||
.size(Size::Absolute(60.0))
|
||||
.size(Size::Remainder)
|
||||
.size(Size::Absolute(70.0))
|
||||
.horizontal(|mut grid| {
|
||||
grid.empty();
|
||||
grid.grid(|builder| {
|
||||
.horizontal(|mut strip| {
|
||||
strip.empty();
|
||||
strip.strip(|builder| {
|
||||
builder
|
||||
.size(Size::Remainder)
|
||||
.size(Size::Absolute(60.0))
|
||||
.size(Size::Remainder)
|
||||
.vertical(|mut grid| {
|
||||
grid.empty();
|
||||
grid.cell(|ui| {
|
||||
.vertical(|mut strip| {
|
||||
strip.empty();
|
||||
strip.cell(|ui| {
|
||||
ui.painter().rect_filled(
|
||||
ui.available_rect_before_wrap(),
|
||||
0.0,
|
||||
|
@ -89,8 +89,8 @@ impl super::View for GridDemo {
|
|||
});
|
||||
});
|
||||
});
|
||||
grid.empty();
|
||||
grid.cell(|ui| {
|
||||
strip.empty();
|
||||
strip.cell(|ui| {
|
||||
ui.painter().rect_filled(
|
||||
ui.available_rect_before_wrap(),
|
||||
0.0,
|
||||
|
@ -100,7 +100,7 @@ impl super::View for GridDemo {
|
|||
});
|
||||
});
|
||||
});
|
||||
grid.cell(|ui| {
|
||||
strip.cell(|ui| {
|
||||
ui.vertical_centered(|ui| {
|
||||
ui.add(crate::__egui_github_link_file!());
|
||||
});
|
|
@ -1,5 +1,5 @@
|
|||
use egui::{Label, Vec2};
|
||||
use egui_extras::{GridBuilder, Size, TableBuilder};
|
||||
use egui_extras::{Size, StripBuilder, TableBuilder};
|
||||
|
||||
/// Shows off a table with dynamic layout
|
||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||
|
@ -31,7 +31,7 @@ impl super::View for TableDemo {
|
|||
|
||||
// The table is inside a grid as its container would otherwise grow slowly as it takes all available height
|
||||
ui.spacing_mut().item_spacing = Vec2::splat(4.0);
|
||||
GridBuilder::new(ui)
|
||||
StripBuilder::new(ui)
|
||||
.size(Size::Remainder)
|
||||
.size(Size::Absolute(10.0))
|
||||
.vertical(|mut grid| {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use super::{button::DatePickerButtonState, month_data};
|
||||
use crate::{GridBuilder, Size, TableBuilder};
|
||||
use crate::{Size, StripBuilder, TableBuilder};
|
||||
use chrono::{Date, Datelike, NaiveDate, Utc, Weekday};
|
||||
use egui::{Align, Button, Color32, ComboBox, Direction, Id, Label, Layout, RichText, Ui, Vec2};
|
||||
|
||||
|
@ -54,7 +54,7 @@ impl<'a> DatePickerPopup<'a> {
|
|||
let height = 20.0;
|
||||
let spacing = 2.0;
|
||||
ui.spacing_mut().item_spacing = Vec2::splat(spacing);
|
||||
GridBuilder::new(ui)
|
||||
StripBuilder::new(ui)
|
||||
.sizes(
|
||||
Size::Absolute(height),
|
||||
match (self.combo_boxes, self.arrows) {
|
||||
|
@ -68,11 +68,11 @@ impl<'a> DatePickerPopup<'a> {
|
|||
if self.calendar { 1 } else { 0 },
|
||||
)
|
||||
.size(Size::Absolute(height))
|
||||
.vertical(|mut grid| {
|
||||
.vertical(|mut strip| {
|
||||
if self.combo_boxes {
|
||||
grid.grid_noclip(|builder| {
|
||||
builder.sizes(Size::Remainder, 3).horizontal(|mut grid| {
|
||||
grid.cell(|ui| {
|
||||
strip.strip_noclip(|builder| {
|
||||
builder.sizes(Size::Remainder, 3).horizontal(|mut strip| {
|
||||
strip.cell(|ui| {
|
||||
ComboBox::from_id_source("date_picker_year")
|
||||
.selected_text(popup_state.year.to_string())
|
||||
.show_ui(ui, |ui| {
|
||||
|
@ -92,7 +92,7 @@ impl<'a> DatePickerPopup<'a> {
|
|||
}
|
||||
});
|
||||
});
|
||||
grid.cell(|ui| {
|
||||
strip.cell(|ui| {
|
||||
ComboBox::from_id_source("date_picker_month")
|
||||
.selected_text(popup_state.month.to_string())
|
||||
.show_ui(ui, |ui| {
|
||||
|
@ -112,7 +112,7 @@ impl<'a> DatePickerPopup<'a> {
|
|||
}
|
||||
});
|
||||
});
|
||||
grid.cell(|ui| {
|
||||
strip.cell(|ui| {
|
||||
ComboBox::from_id_source("date_picker_day")
|
||||
.selected_text(popup_state.day.to_string())
|
||||
.show_ui(ui, |ui| {
|
||||
|
@ -137,9 +137,9 @@ impl<'a> DatePickerPopup<'a> {
|
|||
}
|
||||
|
||||
if self.arrows {
|
||||
grid.grid(|builder| {
|
||||
builder.sizes(Size::Remainder, 6).horizontal(|mut grid| {
|
||||
grid.cell(|ui| {
|
||||
strip.strip(|builder| {
|
||||
builder.sizes(Size::Remainder, 6).horizontal(|mut strip| {
|
||||
strip.cell(|ui| {
|
||||
ui.with_layout(Layout::top_down_justified(Align::Center), |ui| {
|
||||
if ui
|
||||
.button("<<<")
|
||||
|
@ -153,7 +153,7 @@ impl<'a> DatePickerPopup<'a> {
|
|||
}
|
||||
});
|
||||
});
|
||||
grid.cell(|ui| {
|
||||
strip.cell(|ui| {
|
||||
ui.with_layout(Layout::top_down_justified(Align::Center), |ui| {
|
||||
if ui
|
||||
.button("<<")
|
||||
|
@ -171,7 +171,7 @@ impl<'a> DatePickerPopup<'a> {
|
|||
}
|
||||
});
|
||||
});
|
||||
grid.cell(|ui| {
|
||||
strip.cell(|ui| {
|
||||
ui.with_layout(Layout::top_down_justified(Align::Center), |ui| {
|
||||
if ui.button("<").on_hover_text("substract one day").clicked() {
|
||||
popup_state.day -= 1;
|
||||
|
@ -187,7 +187,7 @@ impl<'a> DatePickerPopup<'a> {
|
|||
}
|
||||
});
|
||||
});
|
||||
grid.cell(|ui| {
|
||||
strip.cell(|ui| {
|
||||
ui.with_layout(Layout::top_down_justified(Align::Center), |ui| {
|
||||
if ui.button(">").on_hover_text("add one day").clicked() {
|
||||
popup_state.day += 1;
|
||||
|
@ -203,7 +203,7 @@ impl<'a> DatePickerPopup<'a> {
|
|||
}
|
||||
});
|
||||
});
|
||||
grid.cell(|ui| {
|
||||
strip.cell(|ui| {
|
||||
ui.with_layout(Layout::top_down_justified(Align::Center), |ui| {
|
||||
if ui.button(">>").on_hover_text("add one month").clicked() {
|
||||
popup_state.month += 1;
|
||||
|
@ -217,7 +217,7 @@ impl<'a> DatePickerPopup<'a> {
|
|||
}
|
||||
});
|
||||
});
|
||||
grid.cell(|ui| {
|
||||
strip.cell(|ui| {
|
||||
ui.with_layout(Layout::top_down_justified(Align::Center), |ui| {
|
||||
if ui.button(">>>").on_hover_text("add one year").clicked() {
|
||||
popup_state.year += 1;
|
||||
|
@ -232,7 +232,7 @@ impl<'a> DatePickerPopup<'a> {
|
|||
}
|
||||
|
||||
if self.calendar {
|
||||
grid.cell(|ui| {
|
||||
strip.cell(|ui| {
|
||||
ui.spacing_mut().item_spacing = Vec2::new(1.0, 2.0);
|
||||
TableBuilder::new(ui)
|
||||
.scroll(false)
|
||||
|
@ -321,17 +321,17 @@ impl<'a> DatePickerPopup<'a> {
|
|||
});
|
||||
}
|
||||
|
||||
grid.grid(|builder| {
|
||||
builder.sizes(Size::Remainder, 3).horizontal(|mut grid| {
|
||||
grid.empty();
|
||||
grid.cell(|ui| {
|
||||
strip.strip(|builder| {
|
||||
builder.sizes(Size::Remainder, 3).horizontal(|mut strip| {
|
||||
strip.empty();
|
||||
strip.cell(|ui| {
|
||||
ui.with_layout(Layout::top_down_justified(Align::Center), |ui| {
|
||||
if ui.button("Cancel").clicked() {
|
||||
close = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
grid.cell(|ui| {
|
||||
strip.cell(|ui| {
|
||||
ui.with_layout(Layout::top_down_justified(Align::Center), |ui| {
|
||||
if ui.button("Save").clicked() {
|
||||
*self.selection = Date::from_utc(
|
||||
|
|
|
@ -8,35 +8,33 @@ pub(crate) enum CellSize {
|
|||
Remainder,
|
||||
}
|
||||
|
||||
/// Cells are positioned in two dimensions
|
||||
/// Cells are positioned in two dimensions, cells go in one direction and form lines.
|
||||
///
|
||||
/// In a grid there's only one line which goes into the orthogonal direction of the grid:
|
||||
/// In a strip there's only one line which goes in the direction of the strip:
|
||||
///
|
||||
/// In a horizontal grid, a `[Layout]` with vertical `[LineDirection]` is used.
|
||||
/// In a horizontal strip, a `[Layout]` with horizontal `[CellDirection]` is used.
|
||||
/// Its cells go from left to right inside this `[Layout]`.
|
||||
///
|
||||
/// In a table there's a `[Layout]` for each table row with a horizontal `[LineDirection]`.
|
||||
/// Its cells go from left to right.
|
||||
pub(crate) enum LineDirection {
|
||||
/// Cells go from top to bottom on each line
|
||||
/// Lines go from left to right
|
||||
Horizontal,
|
||||
/// In a table there's a `[Layout]` for each table row with a horizonal `[CellDirection]`.
|
||||
/// Its cells go from left to right. And the lines go from top to bottom.
|
||||
pub(crate) enum CellDirection {
|
||||
/// Cells go from left to right
|
||||
/// Lines go from top to bottom
|
||||
Horizontal,
|
||||
/// Cells go fromtop to bottom
|
||||
Vertical,
|
||||
}
|
||||
|
||||
/// Positions cells in `[LineDirection]` and starts a new line on `[Layout::end_line]`
|
||||
/// Positions cells in `[CellDirection]` and starts a new line on `[Layout::end_line]`
|
||||
pub struct Layout<'l> {
|
||||
ui: &'l mut Ui,
|
||||
direction: LineDirection,
|
||||
direction: CellDirection,
|
||||
rect: Rect,
|
||||
pos: Pos2,
|
||||
max: Pos2,
|
||||
}
|
||||
|
||||
impl<'l> Layout<'l> {
|
||||
pub(crate) fn new(ui: &'l mut Ui, direction: LineDirection) -> Self {
|
||||
pub(crate) fn new(ui: &'l mut Ui, direction: CellDirection) -> Self {
|
||||
let rect = ui.available_rect_before_wrap();
|
||||
let pos = rect.left_top();
|
||||
|
||||
|
@ -71,12 +69,12 @@ impl<'l> Layout<'l> {
|
|||
|
||||
fn set_pos(&mut self, rect: Rect) {
|
||||
match self.direction {
|
||||
LineDirection::Horizontal => {
|
||||
self.pos.y = rect.bottom() + self.ui.spacing().item_spacing.y;
|
||||
}
|
||||
LineDirection::Vertical => {
|
||||
CellDirection::Horizontal => {
|
||||
self.pos.x = rect.right() + self.ui.spacing().item_spacing.x;
|
||||
}
|
||||
CellDirection::Vertical => {
|
||||
self.pos.y = rect.bottom() + self.ui.spacing().item_spacing.y;
|
||||
}
|
||||
}
|
||||
|
||||
self.max.x = self
|
||||
|
@ -130,14 +128,14 @@ impl<'l> Layout<'l> {
|
|||
/// only needed for layouts with multiple lines, like Table
|
||||
pub fn end_line(&mut self) {
|
||||
match self.direction {
|
||||
LineDirection::Horizontal => {
|
||||
self.pos.x = self.max.x;
|
||||
self.pos.y = self.rect.top();
|
||||
}
|
||||
LineDirection::Vertical => {
|
||||
CellDirection::Horizontal => {
|
||||
self.pos.y = self.max.y;
|
||||
self.pos.x = self.rect.left();
|
||||
}
|
||||
CellDirection::Vertical => {
|
||||
self.pos.x = self.max.x;
|
||||
self.pos.y = self.rect.top();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -85,17 +85,17 @@
|
|||
#[cfg(feature = "chrono")]
|
||||
mod datepicker;
|
||||
|
||||
mod grid;
|
||||
pub mod image;
|
||||
mod layout;
|
||||
mod sizing;
|
||||
mod strip;
|
||||
mod table;
|
||||
|
||||
#[cfg(feature = "chrono")]
|
||||
pub use crate::datepicker::DatePickerButton;
|
||||
|
||||
pub use crate::grid::*;
|
||||
pub use crate::image::RetainedImage;
|
||||
pub(crate) use crate::layout::Layout;
|
||||
pub use crate::sizing::Size;
|
||||
pub use crate::strip::*;
|
||||
pub use crate::table::*;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/// Size hint for table column/grid cell
|
||||
/// Size hint for table column/strip cell
|
||||
#[derive(Clone, Debug, Copy)]
|
||||
pub enum Size {
|
||||
/// Absolute size in points
|
||||
|
|
|
@ -1,50 +1,42 @@
|
|||
use crate::{
|
||||
layout::{CellSize, Layout, LineDirection},
|
||||
layout::{CellDirection, CellSize, Layout},
|
||||
sizing::Sizing,
|
||||
Size,
|
||||
};
|
||||
use egui::{Response, Ui};
|
||||
|
||||
/// The direction in which cells are positioned in the grid.
|
||||
///
|
||||
/// In a horizontal grid cells are positions from left to right.
|
||||
/// In a vertical grid cells are positions from top to bottom.
|
||||
enum GridDirection {
|
||||
Horizontal,
|
||||
Vertical,
|
||||
}
|
||||
|
||||
pub struct GridBuilder<'a> {
|
||||
/// Builder for creating a new [`Strip`].
|
||||
pub struct StripBuilder<'a> {
|
||||
ui: &'a mut Ui,
|
||||
sizing: Sizing,
|
||||
}
|
||||
|
||||
impl<'a> GridBuilder<'a> {
|
||||
/// Create new grid builder.
|
||||
impl<'a> StripBuilder<'a> {
|
||||
/// Create new strip builder.
|
||||
///
|
||||
/// In contrast to normal egui behavior, cells do *not* grow with its children!
|
||||
/// In contrast to normal egui behavior, strip cells do *not* grow with its children!
|
||||
///
|
||||
/// After adding size hints with `[Self::column]`/`[Self::columns]` the grid can be build with `[Self::horizontal]`/`[Self::vertical]`.
|
||||
/// After adding size hints with `[Self::column]`/`[Self::columns]` the strip can be build with `[Self::horizontal]`/`[Self::vertical]`.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// use egui_extras::{GridBuilder, Size};
|
||||
/// GridBuilder::new(ui)
|
||||
/// use egui_extras::{StripBuilder, Size};
|
||||
/// StripBuilder::new(ui)
|
||||
/// .size(Size::RemainderMinimum(100.0))
|
||||
/// .size(Size::Absolute(40.0))
|
||||
/// .vertical(|mut grid| {
|
||||
/// grid.grid(|builder| {
|
||||
/// builder.sizes(Size::Remainder, 2).horizontal(|mut grid| {
|
||||
/// grid.cell(|ui| {
|
||||
/// .vertical(|mut strip| {
|
||||
/// strip.strip(|builder| {
|
||||
/// builder.sizes(Size::Remainder, 2).horizontal(|mut strip| {
|
||||
/// strip.cell(|ui| {
|
||||
/// ui.label("Top Left");
|
||||
/// });
|
||||
/// grid.cell(|ui| {
|
||||
/// strip.cell(|ui| {
|
||||
/// ui.label("Top Right");
|
||||
/// });
|
||||
/// });
|
||||
/// });
|
||||
/// grid.cell(|ui| {
|
||||
/// strip.cell(|ui| {
|
||||
/// ui.label("Fixed");
|
||||
/// });
|
||||
/// });
|
||||
|
@ -62,7 +54,7 @@ impl<'a> GridBuilder<'a> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Add size hint for columns/rows [count] times
|
||||
/// Add size hint for columns/rows `count` times
|
||||
pub fn sizes(mut self, size: Size, count: usize) -> Self {
|
||||
for _ in 0..count {
|
||||
self.sizing.add(size);
|
||||
|
@ -70,63 +62,65 @@ impl<'a> GridBuilder<'a> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Build horizontal grid: Cells are positions from left to right.
|
||||
/// Takes the available horizontal width, so there can't be anything right of the grid or the container will grow slowly!
|
||||
/// Build horizontal strip: Cells are positions from left to right.
|
||||
/// Takes the available horizontal width, so there can't be anything right of the strip or the container will grow slowly!
|
||||
///
|
||||
/// Returns a `[egui::Response]` for hover events.
|
||||
pub fn horizontal<F>(self, grid: F) -> Response
|
||||
pub fn horizontal<F>(self, strip: F) -> Response
|
||||
where
|
||||
F: for<'b> FnOnce(Grid<'a, 'b>),
|
||||
F: for<'b> FnOnce(Strip<'a, 'b>),
|
||||
{
|
||||
let widths = self.sizing.into_lengths(
|
||||
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, LineDirection::Vertical);
|
||||
grid(Grid {
|
||||
let mut layout = Layout::new(self.ui, CellDirection::Horizontal);
|
||||
strip(Strip {
|
||||
layout: &mut layout,
|
||||
direction: GridDirection::Horizontal,
|
||||
direction: CellDirection::Horizontal,
|
||||
sizes: widths,
|
||||
});
|
||||
layout.set_rect()
|
||||
}
|
||||
|
||||
/// Build vertical grid: Cells are positions from top to bottom.
|
||||
/// Takes the full available vertical height, so there can't be anything below of the grid or the container will grow slowly!
|
||||
/// Build vertical strip: Cells are positions from top to bottom.
|
||||
/// Takes the full available vertical height, so there can't be anything below of the strip or the container will grow slowly!
|
||||
///
|
||||
/// Returns a `[egui::Response]` for hover events.
|
||||
pub fn vertical<F>(self, grid: F) -> Response
|
||||
pub fn vertical<F>(self, strip: F) -> Response
|
||||
where
|
||||
F: for<'b> FnOnce(Grid<'a, 'b>),
|
||||
F: for<'b> FnOnce(Strip<'a, 'b>),
|
||||
{
|
||||
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, LineDirection::Horizontal);
|
||||
grid(Grid {
|
||||
let mut layout = Layout::new(self.ui, CellDirection::Vertical);
|
||||
strip(Strip {
|
||||
layout: &mut layout,
|
||||
direction: GridDirection::Vertical,
|
||||
direction: CellDirection::Vertical,
|
||||
sizes: heights,
|
||||
});
|
||||
layout.set_rect()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Grid<'a, 'b> {
|
||||
/// A Strip of cells which go in one direction. Each cell has a fixed size.
|
||||
/// In contrast to normal egui behavior, strip cells do *not* grow with its children!
|
||||
pub struct Strip<'a, 'b> {
|
||||
layout: &'b mut Layout<'a>,
|
||||
direction: GridDirection,
|
||||
direction: CellDirection,
|
||||
sizes: Vec<f32>,
|
||||
}
|
||||
|
||||
impl<'a, 'b> Grid<'a, 'b> {
|
||||
impl<'a, 'b> Strip<'a, 'b> {
|
||||
fn next_cell_size(&mut self) -> (CellSize, CellSize) {
|
||||
match self.direction {
|
||||
GridDirection::Horizontal => (
|
||||
CellDirection::Horizontal => (
|
||||
CellSize::Absolute(self.sizes.remove(0)),
|
||||
CellSize::Remainder,
|
||||
),
|
||||
GridDirection::Vertical => (
|
||||
CellDirection::Vertical => (
|
||||
CellSize::Remainder,
|
||||
CellSize::Absolute(self.sizes.remove(0)),
|
||||
),
|
||||
|
@ -137,7 +131,7 @@ impl<'a, 'b> Grid<'a, 'b> {
|
|||
pub fn empty(&mut self) {
|
||||
assert!(
|
||||
!self.sizes.is_empty(),
|
||||
"Tried using more grid cells then available."
|
||||
"Tried using more strip cells then available."
|
||||
);
|
||||
|
||||
let (width, height) = self.next_cell_size();
|
||||
|
@ -147,7 +141,7 @@ impl<'a, 'b> Grid<'a, 'b> {
|
|||
fn _cell(&mut self, clip: bool, add_contents: impl FnOnce(&mut Ui)) {
|
||||
assert!(
|
||||
!self.sizes.is_empty(),
|
||||
"Tried using more grid cells then available."
|
||||
"Tried using more strip cells then available."
|
||||
);
|
||||
|
||||
let (width, height) = self.next_cell_size();
|
||||
|
@ -164,23 +158,23 @@ impl<'a, 'b> Grid<'a, 'b> {
|
|||
self._cell(true, add_contents);
|
||||
}
|
||||
|
||||
fn _grid(&mut self, clip: bool, grid_builder: impl FnOnce(GridBuilder<'_>)) {
|
||||
fn _strip(&mut self, clip: bool, strip_builder: impl FnOnce(StripBuilder<'_>)) {
|
||||
self._cell(clip, |ui| {
|
||||
grid_builder(GridBuilder::new(ui));
|
||||
strip_builder(StripBuilder::new(ui));
|
||||
});
|
||||
}
|
||||
/// Add grid as cell
|
||||
pub fn grid(&mut self, grid_builder: impl FnOnce(GridBuilder<'_>)) {
|
||||
self._grid(false, grid_builder);
|
||||
/// Add strip as cell
|
||||
pub fn strip(&mut self, strip_builder: impl FnOnce(StripBuilder<'_>)) {
|
||||
self._strip(false, strip_builder);
|
||||
}
|
||||
|
||||
/// Add grid as cell, content is clipped
|
||||
pub fn grid_noclip(&mut self, grid_builder: impl FnOnce(GridBuilder<'_>)) {
|
||||
self._grid(true, grid_builder);
|
||||
/// Add strip as cell, content is clipped
|
||||
pub fn strip_noclip(&mut self, strip_builder: impl FnOnce(StripBuilder<'_>)) {
|
||||
self._strip(true, strip_builder);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> Drop for Grid<'a, 'b> {
|
||||
impl<'a, 'b> Drop for Strip<'a, 'b> {
|
||||
fn drop(&mut self) {
|
||||
while !self.sizes.is_empty() {
|
||||
self.empty();
|
|
@ -1,10 +1,10 @@
|
|||
//! Table view with (optional) fixed header and scrolling body.
|
||||
//! Cell widths are precalculated with given size hints so we can have tables like this:
|
||||
//! | fixed size | all available space/minimum | 30% of available width | fixed size |
|
||||
//! Takes all available height, so if you want something below the table, put it in a grid.
|
||||
//! Takes all available height, so if you want something below the table, put it in a strip.
|
||||
|
||||
use crate::{
|
||||
layout::{CellSize, LineDirection},
|
||||
layout::{CellDirection, CellSize},
|
||||
sizing::Sizing,
|
||||
Layout, Size,
|
||||
};
|
||||
|
@ -12,6 +12,7 @@ use crate::{
|
|||
use egui::{Response, Ui};
|
||||
use std::cmp;
|
||||
|
||||
/// Builder for creating a new [`Table`].
|
||||
pub struct TableBuilder<'a> {
|
||||
ui: &'a mut Ui,
|
||||
sizing: Sizing,
|
||||
|
@ -27,7 +28,7 @@ impl<'a> TableBuilder<'a> {
|
|||
/// | fixed size | all available space/minimum | 30% of available width | fixed size |
|
||||
///
|
||||
/// In contrast to normal egui behavior, columns/rows do *not* grow with its children!
|
||||
/// Takes all available height, so if you want something below the table, put it in a grid.
|
||||
/// Takes all available height, so if you want something below the table, put it in a strip.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```
|
||||
|
@ -85,7 +86,7 @@ impl<'a> TableBuilder<'a> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Add size hint for column [count] times
|
||||
/// Add size hint for column `count` times
|
||||
pub fn columns(mut self, size: Size, count: usize) -> Self {
|
||||
for _ in 0..count {
|
||||
self.sizing.add(size);
|
||||
|
@ -107,7 +108,7 @@ impl<'a> TableBuilder<'a> {
|
|||
);
|
||||
let ui = self.ui;
|
||||
{
|
||||
let mut layout = Layout::new(ui, LineDirection::Vertical);
|
||||
let mut layout = Layout::new(ui, CellDirection::Horizontal);
|
||||
{
|
||||
let row = TableRow {
|
||||
layout: &mut layout,
|
||||
|
@ -149,6 +150,8 @@ impl<'a> TableBuilder<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Table struct which can construct a [`TableBody`].
|
||||
/// Is created by [`TableBuilder`] by either calling `body` or after creating a header row with `header`.
|
||||
pub struct Table<'a> {
|
||||
ui: &'a mut Ui,
|
||||
widths: Vec<f32>,
|
||||
|
@ -169,7 +172,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, LineDirection::Vertical);
|
||||
let layout = Layout::new(ui, CellDirection::Horizontal);
|
||||
|
||||
body(TableBody {
|
||||
layout,
|
||||
|
@ -183,6 +186,8 @@ impl<'a> Table<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// The body of a table.
|
||||
/// Is created by calling `body` on a [`Table`] (after adding a header row) or [`TableBuilder`] (without a header row).
|
||||
pub struct TableBody<'a> {
|
||||
layout: Layout<'a>,
|
||||
widths: Vec<f32>,
|
||||
|
@ -265,6 +270,8 @@ impl<'a> Drop for TableBody<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// The row of a table.
|
||||
/// Is created by [`TableRow`] for each created [`TableBody::row`] or each visible row in rows created by calling [`TableBody::rows`].
|
||||
pub struct TableRow<'a, 'b> {
|
||||
layout: &'b mut Layout<'a>,
|
||||
widths: Vec<f32>,
|
||||
|
|
Loading…
Reference in a new issue