From dbfaa4527b8d2912b465ed416427eeaaee0d1830 Mon Sep 17 00:00:00 2001 From: njust Date: Sun, 28 Aug 2022 09:37:23 +0200 Subject: [PATCH] egui_extras: Add Table::vertical_scroll_offset (#1946) * egui_extras: Add Table::vertical_scroll_offset * Added example for TableBuilder::vertical_scroll_offset * Format code * Add link to PR in the changelog Co-authored-by: Emil Ernerfeldt --- crates/egui_demo_lib/src/demo/table_demo.rs | 33 +++++++++++++++++++-- crates/egui_extras/CHANGELOG.md | 2 +- crates/egui_extras/src/table.rs | 20 ++++++++++++- 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/crates/egui_demo_lib/src/demo/table_demo.rs b/crates/egui_demo_lib/src/demo/table_demo.rs index c07cec4a..09b4cef4 100644 --- a/crates/egui_demo_lib/src/demo/table_demo.rs +++ b/crates/egui_demo_lib/src/demo/table_demo.rs @@ -12,6 +12,8 @@ pub struct TableDemo { demo: DemoType, resizable: bool, num_rows: usize, + row_to_scroll_to: i32, + vertical_scroll_offset: Option, } impl Default for TableDemo { @@ -20,6 +22,8 @@ impl Default for TableDemo { demo: DemoType::Manual, resizable: true, num_rows: 10_000, + row_to_scroll_to: 0, + vertical_scroll_offset: None, } } } @@ -41,6 +45,12 @@ impl super::Demo for TableDemo { } } +fn scroll_offset_for_row(ui: &egui::Ui, row: i32) -> f32 { + let text_height = egui::TextStyle::Body.resolve(ui.style()).size; + let row_item_spacing = ui.spacing().item_spacing.y; + row as f32 * (text_height + row_item_spacing) +} + impl super::View for TableDemo { fn ui(&mut self, ui: &mut egui::Ui) { ui.vertical(|ui| { @@ -66,6 +76,19 @@ impl super::View for TableDemo { .text("Num rows"), ); } + + if self.demo == DemoType::ManyHomogenous { + ui.add( + egui::Slider::new(&mut self.row_to_scroll_to, 0..=self.num_rows as i32) + .logarithmic(true) + .text("Row to scroll to"), + ); + + if ui.button("Scroll to row").clicked() { + self.vertical_scroll_offset + .replace(scroll_offset_for_row(ui, self.row_to_scroll_to)); + } + } }); ui.separator(); @@ -94,13 +117,19 @@ impl TableDemo { let text_height = egui::TextStyle::Body.resolve(ui.style()).size; - TableBuilder::new(ui) + let mut table = TableBuilder::new(ui) .striped(true) .cell_layout(egui::Layout::left_to_right(egui::Align::Center)) .column(Size::initial(60.0).at_least(40.0)) .column(Size::initial(60.0).at_least(40.0)) .column(Size::remainder().at_least(60.0)) - .resizable(self.resizable) + .resizable(self.resizable); + + if let Some(y_scroll) = self.vertical_scroll_offset.take() { + table = table.vertical_scroll_offset(y_scroll); + } + + table .header(20.0, |mut header| { header.col(|ui| { ui.heading("Row"); diff --git a/crates/egui_extras/CHANGELOG.md b/crates/egui_extras/CHANGELOG.md index 1f491dc5..311c37f4 100644 --- a/crates/egui_extras/CHANGELOG.md +++ b/crates/egui_extras/CHANGELOG.md @@ -3,7 +3,7 @@ All notable changes to the `egui_extras` integration will be noted in this file. ## Unreleased - +* Added `TableBuilder::vertical_scroll_offset`: method to set vertical scroll offset position for a table ([#1946](https://github.com/emilk/egui/pull/1946)). ## 0.19.0 - 2022-08-20 * MSRV (Minimum Supported Rust Version) is now `1.61.0` ([#1846](https://github.com/emilk/egui/pull/1846)). diff --git a/crates/egui_extras/src/table.rs b/crates/egui_extras/src/table.rs index a2a6ce5b..bdc11f00 100644 --- a/crates/egui_extras/src/table.rs +++ b/crates/egui_extras/src/table.rs @@ -57,6 +57,7 @@ pub struct TableBuilder<'a> { resizable: bool, clip: bool, stick_to_bottom: bool, + scroll_offset_y: Option, cell_layout: egui::Layout, } @@ -71,6 +72,7 @@ impl<'a> TableBuilder<'a> { resizable: false, clip: true, stick_to_bottom: false, + scroll_offset_y: None, cell_layout, } } @@ -115,6 +117,12 @@ impl<'a> TableBuilder<'a> { self } + /// Set the vertical scroll offset position. + pub fn vertical_scroll_offset(mut self, offset: f32) -> Self { + self.scroll_offset_y = Some(offset); + self + } + /// What layout should we use for the individual cells? pub fn cell_layout(mut self, cell_layout: egui::Layout) -> Self { self.cell_layout = cell_layout; @@ -156,6 +164,7 @@ impl<'a> TableBuilder<'a> { resizable, clip, stick_to_bottom, + scroll_offset_y, cell_layout, } = self; @@ -189,6 +198,7 @@ impl<'a> TableBuilder<'a> { striped, clip, stick_to_bottom, + scroll_offset_y, cell_layout, } } @@ -208,6 +218,7 @@ impl<'a> TableBuilder<'a> { resizable, clip, stick_to_bottom, + scroll_offset_y, cell_layout, } = self; @@ -229,6 +240,7 @@ impl<'a> TableBuilder<'a> { striped, clip, stick_to_bottom, + scroll_offset_y, cell_layout, } .body(body); @@ -268,6 +280,7 @@ pub struct Table<'a> { striped: bool, clip: bool, stick_to_bottom: bool, + scroll_offset_y: Option, cell_layout: egui::Layout, } @@ -288,6 +301,7 @@ impl<'a> Table<'a> { striped, clip, stick_to_bottom, + scroll_offset_y, cell_layout, } = self; @@ -295,10 +309,14 @@ impl<'a> Table<'a> { let mut new_widths = widths.clone(); - let scroll_area = egui::ScrollArea::new([false, scroll]) + let mut scroll_area = egui::ScrollArea::new([false, scroll]) .auto_shrink([true; 2]) .stick_to_bottom(stick_to_bottom); + if let Some(scroll_offset_y) = scroll_offset_y { + scroll_area = scroll_area.vertical_scroll_offset(scroll_offset_y); + } + scroll_area.show(ui, move |ui| { let layout = StripLayout::new(ui, CellDirection::Horizontal, clip, cell_layout);