Skip to content

Commit

Permalink
More realistic demo with various fixes and tweaks (#6)
Browse files Browse the repository at this point in the history
It's starting to get ready for production!
  • Loading branch information
emilk authored Sep 5, 2024
1 parent a03f30b commit 2a630db
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 45 deletions.
16 changes: 8 additions & 8 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53"
[[package]]
name = "ecolor"
version = "0.28.1"
source = "git+https://github.com/emilk/egui?rev=2be93aca5d0db973ab163267fb4162363786ffba#2be93aca5d0db973ab163267fb4162363786ffba"
source = "git+https://github.com/emilk/egui?rev=7cb61f8031d2d7ccfa8cfb2442a52a2a31ec923c#7cb61f8031d2d7ccfa8cfb2442a52a2a31ec923c"
dependencies = [
"bytemuck",
"emath",
Expand All @@ -407,7 +407,7 @@ dependencies = [
[[package]]
name = "eframe"
version = "0.28.1"
source = "git+https://github.com/emilk/egui?rev=2be93aca5d0db973ab163267fb4162363786ffba#2be93aca5d0db973ab163267fb4162363786ffba"
source = "git+https://github.com/emilk/egui?rev=7cb61f8031d2d7ccfa8cfb2442a52a2a31ec923c#7cb61f8031d2d7ccfa8cfb2442a52a2a31ec923c"
dependencies = [
"ahash",
"bytemuck",
Expand Down Expand Up @@ -443,7 +443,7 @@ dependencies = [
[[package]]
name = "egui"
version = "0.28.1"
source = "git+https://github.com/emilk/egui?rev=2be93aca5d0db973ab163267fb4162363786ffba#2be93aca5d0db973ab163267fb4162363786ffba"
source = "git+https://github.com/emilk/egui?rev=7cb61f8031d2d7ccfa8cfb2442a52a2a31ec923c#7cb61f8031d2d7ccfa8cfb2442a52a2a31ec923c"
dependencies = [
"accesskit",
"ahash",
Expand All @@ -458,7 +458,7 @@ dependencies = [
[[package]]
name = "egui-winit"
version = "0.28.1"
source = "git+https://github.com/emilk/egui?rev=2be93aca5d0db973ab163267fb4162363786ffba#2be93aca5d0db973ab163267fb4162363786ffba"
source = "git+https://github.com/emilk/egui?rev=7cb61f8031d2d7ccfa8cfb2442a52a2a31ec923c#7cb61f8031d2d7ccfa8cfb2442a52a2a31ec923c"
dependencies = [
"ahash",
"arboard",
Expand All @@ -475,7 +475,7 @@ dependencies = [
[[package]]
name = "egui_glow"
version = "0.28.1"
source = "git+https://github.com/emilk/egui?rev=2be93aca5d0db973ab163267fb4162363786ffba#2be93aca5d0db973ab163267fb4162363786ffba"
source = "git+https://github.com/emilk/egui?rev=7cb61f8031d2d7ccfa8cfb2442a52a2a31ec923c#7cb61f8031d2d7ccfa8cfb2442a52a2a31ec923c"
dependencies = [
"ahash",
"bytemuck",
Expand All @@ -499,7 +499,7 @@ dependencies = [
[[package]]
name = "emath"
version = "0.28.1"
source = "git+https://github.com/emilk/egui?rev=2be93aca5d0db973ab163267fb4162363786ffba#2be93aca5d0db973ab163267fb4162363786ffba"
source = "git+https://github.com/emilk/egui?rev=7cb61f8031d2d7ccfa8cfb2442a52a2a31ec923c#7cb61f8031d2d7ccfa8cfb2442a52a2a31ec923c"
dependencies = [
"bytemuck",
"serde",
Expand Down Expand Up @@ -532,7 +532,7 @@ dependencies = [
[[package]]
name = "epaint"
version = "0.28.1"
source = "git+https://github.com/emilk/egui?rev=2be93aca5d0db973ab163267fb4162363786ffba#2be93aca5d0db973ab163267fb4162363786ffba"
source = "git+https://github.com/emilk/egui?rev=7cb61f8031d2d7ccfa8cfb2442a52a2a31ec923c#7cb61f8031d2d7ccfa8cfb2442a52a2a31ec923c"
dependencies = [
"ab_glyph",
"ahash",
Expand All @@ -549,7 +549,7 @@ dependencies = [
[[package]]
name = "epaint_default_fonts"
version = "0.28.1"
source = "git+https://github.com/emilk/egui?rev=2be93aca5d0db973ab163267fb4162363786ffba#2be93aca5d0db973ab163267fb4162363786ffba"
source = "git+https://github.com/emilk/egui?rev=7cb61f8031d2d7ccfa8cfb2442a52a2a31ec923c#7cb61f8031d2d7ccfa8cfb2442a52a2a31ec923c"

[[package]]
name = "equivalent"
Expand Down
8 changes: 2 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ version = "0.28.1"
[profile.release]
opt-level = 2 # fast and small wasm

[profile.dev.package."*"]
# Optimize all dependencies even in debug builds (does not affect workspace packages):
opt-level = 2


[workspace.dependencies]
egui_table = { version = "0.28.1", path = "egui_table", default-features = false }
Expand All @@ -31,8 +27,8 @@ vec1 = { version = "1.12.1", default-features = false }

[patch.crates-io]
# If you want to use the bleeding edge version of egui and eframe:
eframe = { git = "https://github.com/emilk/egui", rev = "2be93aca5d0db973ab163267fb4162363786ffba" } # egui master 2024-09-05
egui = { git = "https://github.com/emilk/egui", rev = "2be93aca5d0db973ab163267fb4162363786ffba" } # egui master 2024-09-05
eframe = { git = "https://github.com/emilk/egui", rev = "7cb61f8031d2d7ccfa8cfb2442a52a2a31ec923c" } # egui master 2024-09-05
egui = { git = "https://github.com/emilk/egui", rev = "7cb61f8031d2d7ccfa8cfb2442a52a2a31ec923c" } # egui master 2024-09-05

# If you fork https://github.com/emilk/egui you can test with:
# egui = { path = "../../egui/crates/egui" }
Expand Down
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ Work-in-progress. Pre-release.
### TODO/Bugs
* Hierarchical headers
* Fix auto-sizing on parent resize
* Test with `egui::Sides`
* Test with truncating content
* Go through TODOs


Expand Down
85 changes: 63 additions & 22 deletions demo/src/table_demo.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::ops::Range;

use egui::Margin;
use egui_table::{AutoSizeMode, CellInfo, Column, Table, TableDelegate, TableState};

#[derive(serde::Deserialize, serde::Serialize)]
Expand All @@ -9,17 +10,21 @@ pub struct TableDemo {
num_sticky_cols: usize,
default_column: Column,
auto_size_mode: AutoSizeMode,
top_row_height: f32,
row_height: f32,
prefetched_row_ranges: Vec<Range<u64>>,
}

impl Default for TableDemo {
fn default() -> Self {
Self {
num_columns: 10,
num_rows: 100,
num_columns: 20,
num_rows: 10_000,
num_sticky_cols: 1,
default_column: Column::new(100.0, 10.0..=500.0),
auto_size_mode: AutoSizeMode::default(),
top_row_height: 24.0,
row_height: 20.0,
prefetched_row_ranges: vec![],
}
}
Expand All @@ -41,27 +46,55 @@ impl TableDelegate for TableDemo {
fn cell_ui(&mut self, ui: &mut egui::Ui, cell: &CellInfo) {
let CellInfo { row_nr, col_nr, .. } = *cell;

ui.add_space(4.0);

if !self.was_prefetched(row_nr) {
if row_nr % 2 == 1 {
ui.painter()
.rect_filled(ui.max_rect(), 0.0, ui.visuals().error_fg_color);
ui.label("ERROR: row not prefetched");
log::warn!("Was asked to show row {row_nr} which was not prefetched! This is a bug.");
return;
.rect_filled(ui.max_rect(), 0.0, ui.visuals().faint_bg_color);
}

if row_nr == 0 {
ui.heading(format!("Column {col_nr}"));
} else {
if row_nr % 2 == 1 {
ui.painter()
.rect_filled(ui.max_rect(), 0.0, ui.visuals().faint_bg_color);
}
ui.label(format!("({row_nr}, {col_nr})"));
}

ui.add_space(4.0);
egui::Frame::none()
.inner_margin(Margin::symmetric(4.0, 0.0))
.show(ui, |ui| {
if !self.was_prefetched(row_nr) {
ui.painter()
.rect_filled(ui.max_rect(), 0.0, ui.visuals().error_fg_color);
ui.label("ERROR: row not prefetched");
log::warn!(
"Was asked to show row {row_nr} which was not prefetched! This is a bug."
);
return;
}

#[allow(clippy::collapsible_else_if)]
if row_nr == 0 {
if col_nr == 0 {
egui::Sides::new().height(ui.available_height()).show(
ui,
|ui| {
ui.heading("Row");
},
|ui| {
ui.label("⬇");
},
);
} else {
ui.heading(format!("Column {col_nr}"));
}
} else {
if col_nr == 0 {
ui.label(row_nr.to_string());
} else {
ui.label(format!("({row_nr}, {col_nr})"));

if (row_nr + col_nr as u64) % 27 == 0 {
if !ui.is_sizing_pass() {
// During a sizing pass we don't truncate!
ui.style_mut().wrap_mode = Some(egui::TextWrapMode::Truncate);
}
ui.label("Extra long cell!");
}
}
}
});
}
}

Expand All @@ -84,6 +117,14 @@ impl TableDemo {
});
ui.end_row();

ui.label("Height of top row");
ui.add(egui::DragValue::new(&mut self.top_row_height).range(0.0..=100.0));
ui.end_row();

ui.label("Height of other rows");
ui.add(egui::DragValue::new(&mut self.row_height).range(0.0..=100.0));
ui.end_row();

ui.label("Sticky columns");
ui.add(egui::DragValue::new(&mut self.num_sticky_cols));
ui.end_row();
Expand Down Expand Up @@ -146,8 +187,8 @@ impl TableDemo {
columns: vec![self.default_column; self.num_columns],
id_salt,
num_sticky_cols: self.num_sticky_cols,
sticky_row_heights: vec![20.0; 1],
row_height: 16.0,
sticky_row_heights: vec![self.top_row_height; 1],
row_height: self.row_height,
num_rows: self.num_rows,
auto_size_mode: self.auto_size_mode,
}
Expand Down
33 changes: 26 additions & 7 deletions egui_table/src/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ impl TableState {
///
/// ## Batteries not included
/// * You need to specify its size beforehand
/// * Does not add any margins to cells. Add it yourself.
/// * Does not add any margins to cells. Add it yourself with [`egui::Frame`].
/// * Does not clip cells, or wrap them in scroll areas. Do that yourself.
/// * Doesn't paint any guide-lines for the rows. Paint them yourself.
/// * There is not special header rows. Use sticky rows for that.
Expand Down Expand Up @@ -128,14 +128,21 @@ impl Table {
let num_scroll_rows = self.num_rows - self.sticky_row_heights.len() as u64;

let id = TableState::id(ui, self.id_salt);
let mut state: TableState = TableState::load(ui.ctx(), id).unwrap_or_default();
let state = TableState::load(ui.ctx(), id);
let is_new = state.is_none();
let do_full_sizing_pass = is_new;
let mut state = state.unwrap_or_default();

for (i, column) in self.columns.iter_mut().enumerate() {
let column_id = column.id(i);
if let Some(existing_width) = state.col_widths.get(&column_id) {
column.current = *existing_width;
}
column.current = column.range.clamp(column.current);

if do_full_sizing_pass {
column.auto_size_this_frame = true;
}
}

let parent_width = ui.available_width();
Expand Down Expand Up @@ -177,7 +184,11 @@ impl Table {
self.sticky_row_heights.iter().sum(),
);

ui.scope(|ui| {
let mut ui_builder = UiBuilder::new();
if do_full_sizing_pass {
ui_builder = ui_builder.sizing_pass().invisible();
}
ui.scope_builder(ui_builder, |ui| {
// Don't wrap text in the table cells.
ui.style_mut().wrap_mode = Some(egui::TextWrapMode::Extend); // TODO: I think this is default for horizontal layouts anyway?

Expand Down Expand Up @@ -319,6 +330,7 @@ impl<'a> TableSplitScrollDelegate<'a> {
};

let mut cell_rect = self.cell_rect(col_nr, row_nr).translate(-offset);
let clip_rect = cell_rect; // Note: we shrink the cell rect when auto-sizing, but not the clip rect! This is to avoid flicker.
if column.auto_size_this_frame {
cell_rect.max.x = cell_rect.min.x + column.range.min;
}
Expand All @@ -331,7 +343,7 @@ impl<'a> TableSplitScrollDelegate<'a> {
ui_builder = ui_builder.sizing_pass();
}
let mut cell_ui = ui.new_child(ui_builder);
cell_ui.shrink_clip_rect(cell_rect);
cell_ui.shrink_clip_rect(clip_rect);

self.table_delegate
.cell_ui(&mut cell_ui, &CellInfo { col_nr, row_nr });
Expand Down Expand Up @@ -420,18 +432,25 @@ impl<'a> SplitScrollDelegate for TableSplitScrollDelegate<'a> {

if resize_response.dragged() {
if let Some(pointer) = ui.ctx().pointer_latest_pos() {
let mut new_width = *column_width + pointer.x - x;
let desired_new_width = *column_width + pointer.x - x;
let desired_new_width = column.range.clamp(desired_new_width);

// We don't want to shrink below the size that was actually used.
// However, we still want to allow content that shrinks when you try
// to make the column less wide, so we allow some small shrinkage each frame:
// big enough to allow shrinking over time, small enough not to look ugly when
// shrinking fails. This is a bit of a HACK around immediate mode.
// TODO: do something smarter by remembering success/failure to resize from one frame to the next.
let max_shrinkage_per_frame = 8.0;
new_width = new_width.at_least(used_width - max_shrinkage_per_frame);
new_width = column.range.clamp(new_width);
let new_width =
desired_new_width.at_least(used_width - max_shrinkage_per_frame);
let new_width = column.range.clamp(new_width);
x += new_width - *column_width;
*column_width = new_width;

if new_width != desired_new_width {
ui.ctx().request_repaint(); // Get there faster
}
}
}

Expand Down

0 comments on commit 2a630db

Please sign in to comment.