Skip to content

Commit dfd09c7

Browse files
authored
Fix scroll_to_row not taking the header into account (#44)
Title. Also update the demo to test/verify scrolling to specific rows/columns.
1 parent 35abc9b commit dfd09c7

File tree

3 files changed

+33
-26
lines changed

3 files changed

+33
-26
lines changed

demo/src/table_demo.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,17 +301,23 @@ impl TableDemo {
301301
self.prefetched.clear();
302302
});
303303

304+
let first_scrollable_col = self.num_sticky_cols;
305+
let last_col = self.num_columns.saturating_sub(1);
306+
let mid_col = (first_scrollable_col + last_col) / 2;
304307
let mut scroll_to_column = None;
305308
ui.horizontal(|ui| {
306309
ui.label("Scroll horizontally to…");
307310
if ui.button("left").clicked() {
308-
scroll_to_column = Some(0);
311+
scroll_to_column = Some(first_scrollable_col);
309312
}
310313
if ui.button("middle").clicked() {
311-
scroll_to_column = Some(self.num_columns / 2);
314+
scroll_to_column = Some(mid_col);
312315
}
313316
if ui.button("right").clicked() {
314-
scroll_to_column = Some(self.num_columns.saturating_sub(1));
317+
scroll_to_column = Some(last_col);
318+
}
319+
if ui.button(format!("column {mid_col}")).clicked() {
320+
scroll_to_column = Some(mid_col);
315321
}
316322
});
317323

@@ -327,6 +333,10 @@ impl TableDemo {
327333
if ui.button("bottom").clicked() {
328334
scroll_to_row = Some(self.num_rows.saturating_sub(1));
329335
}
336+
let mid_row = self.num_rows / 2;
337+
if ui.button(format!("row {mid_row}")).clicked() {
338+
scroll_to_row = Some(mid_row);
339+
}
330340
});
331341

332342
ui.separator();
Lines changed: 2 additions & 2 deletions
Loading

egui_table/src/table.rs

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -759,37 +759,34 @@ impl SplitScrollDelegate for TableSplitScrollDelegate<'_> {
759759
let mut target_align = None;
760760

761761
if let Some((column_range, align)) = &self.table.scroll_to_columns {
762+
// Use the first scrollable column as the base, so that offsets start
763+
// at 0 for the first non-sticky column — mirroring how row_top_offset
764+
// starts at 0 for the first data row.
765+
let scrollable_col_x_base = self.col_x[self.table.num_sticky_cols];
762766
let x_from_column_nr = |col_nr: usize| -> f32 {
763-
let mut x = self.col_x[col_nr];
764-
765-
let sitcky_width = self.col_x[self.table.num_sticky_cols] - self.col_x.first();
766-
if x < sitcky_width {
767-
// We need to do some shenanigans here because how the `SplitScroll` works:
768-
x -= sitcky_width;
769-
}
770-
771-
ui.min_rect().left() + x
767+
ui.min_rect().left() + (self.col_x[col_nr] - scrollable_col_x_base)
772768
};
773769

774-
target_rect.min.x = x_from_column_nr(*column_range.start());
770+
let sticky_width = scrollable_col_x_base - self.col_x.first();
771+
772+
// Subtract sticky_width from the left of the target rect so that when
773+
// scroll_to_rect aligns the left of the target to the viewport left, the
774+
// actual column lands just right of the sticky columns (not behind them).
775+
target_rect.min.x = x_from_column_nr(*column_range.start()) - sticky_width;
775776
target_rect.max.x = x_from_column_nr(*column_range.end() + 1);
776777
target_align = target_align.or(*align);
777778
}
778779

779780
if let Some((row_range, align)) = &self.table.scroll_to_rows {
780-
let y_from_row_nr = |row_nr: u64| -> f32 {
781-
let mut y = self.get_row_top_offset(row_nr);
781+
let y_from_row_nr =
782+
|row_nr: u64| -> f32 { ui.min_rect().top() + self.get_row_top_offset(row_nr) };
782783

783-
let sticky_height = self.header_row_y.last() - self.header_row_y.first();
784-
if y < sticky_height {
785-
// We need to do some shenanigans here because how the `SplitScroll` works:
786-
y -= sticky_height;
787-
}
788-
789-
ui.min_rect().top() + y
790-
};
784+
let sticky_height = self.header_row_y.last() - self.header_row_y.first();
791785

792-
target_rect.min.y = y_from_row_nr(*row_range.start());
786+
// Subtract sticky_height from the top of the target rect so that when
787+
// scroll_to_rect aligns the top of the target to the viewport top, the
788+
// actual row lands just below the sticky header (not behind it).
789+
target_rect.min.y = y_from_row_nr(*row_range.start()) - sticky_height;
793790
target_rect.max.y = y_from_row_nr(*row_range.end() + 1);
794791
target_align = target_align.or(*align);
795792
}

0 commit comments

Comments
 (0)