table: Add visible_rows_changed, visible_cols_changed method to table delegate. (#543)
Co-authored-by: Jason Lee <huacnlee@gmail.com>
This commit is contained in:
parent
205a499bc9
commit
eb10186463
2 changed files with 121 additions and 1 deletions
|
|
@ -1,4 +1,7 @@
|
||||||
use std::time::{self, Duration};
|
use std::{
|
||||||
|
ops::Range,
|
||||||
|
time::{self, Duration},
|
||||||
|
};
|
||||||
|
|
||||||
use fake::{Fake, Faker};
|
use fake::{Fake, Faker};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
|
|
@ -181,6 +184,8 @@ struct StockTableDelegate {
|
||||||
loading: bool,
|
loading: bool,
|
||||||
fixed_cols: bool,
|
fixed_cols: bool,
|
||||||
is_eof: bool,
|
is_eof: bool,
|
||||||
|
visible_rows: Range<usize>,
|
||||||
|
visible_cols: Range<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StockTableDelegate {
|
impl StockTableDelegate {
|
||||||
|
|
@ -250,6 +255,8 @@ impl StockTableDelegate {
|
||||||
fixed_cols: false,
|
fixed_cols: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
is_eof: false,
|
is_eof: false,
|
||||||
|
visible_cols: Range::default(),
|
||||||
|
visible_rows: Range::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -490,6 +497,22 @@ impl TableDelegate for StockTableDelegate {
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visible_rows_changed(
|
||||||
|
&mut self,
|
||||||
|
visible_range: Range<usize>,
|
||||||
|
_: &mut ViewContext<Table<Self>>,
|
||||||
|
) {
|
||||||
|
self.visible_rows = visible_range;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visible_cols_changed(
|
||||||
|
&mut self,
|
||||||
|
visible_range: Range<usize>,
|
||||||
|
_: &mut ViewContext<Table<Self>>,
|
||||||
|
) {
|
||||||
|
self.visible_cols = visible_range;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TableStory {
|
pub struct TableStory {
|
||||||
|
|
@ -842,6 +865,8 @@ impl Render for TableStory {
|
||||||
this.child(h_flex().gap_1().child(Indicator::new()).child("Loading..."))
|
this.child(h_flex().gap_1().child(Indicator::new()).child("Loading..."))
|
||||||
})
|
})
|
||||||
.child(format!("Total Rows: {}", rows_count))
|
.child(format!("Total Rows: {}", rows_count))
|
||||||
|
.child(format!("Visible Rows: {:?}", delegate.visible_rows))
|
||||||
|
.child(format!("Visible Cols: {:?}", delegate.visible_cols))
|
||||||
.when(delegate.is_eof, |this| this.child("All data loaded.")),
|
.when(delegate.is_eof, |this| this.child("All data loaded.")),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,27 @@ struct FixedCols {
|
||||||
left: usize,
|
left: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The visible range of the rows and columns.
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct VisibleRangeState {
|
||||||
|
/// The visible range of the rows.
|
||||||
|
rows: Range<usize>,
|
||||||
|
/// The visible range of the columns.
|
||||||
|
cols: Range<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VisibleRangeState {
|
||||||
|
/// Returns the visible range of the rows.
|
||||||
|
pub fn rows(&self) -> Range<usize> {
|
||||||
|
self.rows.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the visible range of the columns.
|
||||||
|
pub fn cols(&self) -> Range<usize> {
|
||||||
|
self.cols.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Table<D: TableDelegate> {
|
pub struct Table<D: TableDelegate> {
|
||||||
focus_handle: FocusHandle,
|
focus_handle: FocusHandle,
|
||||||
delegate: D,
|
delegate: D,
|
||||||
|
|
@ -148,6 +169,8 @@ pub struct Table<D: TableDelegate> {
|
||||||
border: bool,
|
border: bool,
|
||||||
/// The cell size of the table.
|
/// The cell size of the table.
|
||||||
size: Size,
|
size: Size,
|
||||||
|
/// The visible range of the rows and columns.
|
||||||
|
visible_range: VisibleRangeState,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
|
|
@ -280,6 +303,32 @@ pub trait TableDelegate: Sized + 'static {
|
||||||
fn render_last_empty_col(&mut self, cx: &mut ViewContext<Table<Self>>) -> Div {
|
fn render_last_empty_col(&mut self, cx: &mut ViewContext<Table<Self>>) -> Div {
|
||||||
h_flex().w_5().h_full().flex_shrink_0()
|
h_flex().w_5().h_full().flex_shrink_0()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Called when the visible range of the rows changed.
|
||||||
|
///
|
||||||
|
/// NOTE: Make sure this method is fast, because it will be called frequently.
|
||||||
|
///
|
||||||
|
/// This can used to handle some data update, to only update the visible rows.
|
||||||
|
/// Please ensure that the data is updated in the background task.
|
||||||
|
fn visible_rows_changed(
|
||||||
|
&mut self,
|
||||||
|
visible_range: Range<usize>,
|
||||||
|
cx: &mut ViewContext<Table<Self>>,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Called when the visible range of the columns changed.
|
||||||
|
///
|
||||||
|
/// NOTE: Make sure this method is fast, because it will be called frequently.
|
||||||
|
///
|
||||||
|
/// This can used to handle some data update, to only update the visible rows.
|
||||||
|
/// Please ensure that the data is updated in the background task.
|
||||||
|
fn visible_cols_changed(
|
||||||
|
&mut self,
|
||||||
|
visible_range: Range<usize>,
|
||||||
|
cx: &mut ViewContext<Table<Self>>,
|
||||||
|
) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D> Table<D>
|
impl<D> Table<D>
|
||||||
|
|
@ -307,6 +356,7 @@ where
|
||||||
stripe: false,
|
stripe: false,
|
||||||
border: true,
|
border: true,
|
||||||
size: Size::default(),
|
size: Size::default(),
|
||||||
|
visible_range: VisibleRangeState::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
this.prepare_col_groups(cx);
|
this.prepare_col_groups(cx);
|
||||||
|
|
@ -436,6 +486,11 @@ where
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the visible range of the rows and columns.
|
||||||
|
pub fn visible_range(&self) -> &VisibleRangeState {
|
||||||
|
&self.visible_range
|
||||||
|
}
|
||||||
|
|
||||||
fn on_row_click(&mut self, ev: &MouseDownEvent, row_ix: usize, cx: &mut ViewContext<Self>) {
|
fn on_row_click(&mut self, ev: &MouseDownEvent, row_ix: usize, cx: &mut ViewContext<Self>) {
|
||||||
if ev.button == MouseButton::Right {
|
if ev.button == MouseButton::Right {
|
||||||
self.right_clicked_row = Some(row_ix);
|
self.right_clicked_row = Some(row_ix);
|
||||||
|
|
@ -630,6 +685,35 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_visible_range_if_need(
|
||||||
|
&mut self,
|
||||||
|
visible_range: Range<usize>,
|
||||||
|
axis: Axis,
|
||||||
|
cx: &mut ViewContext<Self>,
|
||||||
|
) {
|
||||||
|
// Skip when visible range is only 1 item.
|
||||||
|
// The visual_list will use first item to measure.
|
||||||
|
if visible_range.len() <= 1 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if axis == Axis::Vertical {
|
||||||
|
if self.visible_range.rows == visible_range {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.delegate_mut()
|
||||||
|
.visible_rows_changed(visible_range.clone(), cx);
|
||||||
|
self.visible_range.rows = visible_range;
|
||||||
|
} else {
|
||||||
|
if self.visible_range.cols == visible_range {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.delegate_mut()
|
||||||
|
.visible_cols_changed(visible_range.clone(), cx);
|
||||||
|
self.visible_range.cols = visible_range;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the size of the content area.
|
/// Returns the size of the content area.
|
||||||
fn head_content_bounds(&self) -> gpui::Bounds<Pixels> {
|
fn head_content_bounds(&self) -> gpui::Bounds<Pixels> {
|
||||||
let has_fixed_cols = self.fixed_head_cols_bounds.size.width > px(0.0);
|
let has_fixed_cols = self.fixed_head_cols_bounds.size.width > px(0.0);
|
||||||
|
|
@ -1054,6 +1138,12 @@ where
|
||||||
.child(
|
.child(
|
||||||
virtual_list(view, row_ix, Axis::Horizontal, col_sizes, {
|
virtual_list(view, row_ix, Axis::Horizontal, col_sizes, {
|
||||||
move |table, visible_range: Range<usize>, _, cx| {
|
move |table, visible_range: Range<usize>, _, cx| {
|
||||||
|
table.update_visible_range_if_need(
|
||||||
|
visible_range.clone(),
|
||||||
|
Axis::Horizontal,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
|
||||||
visible_range
|
visible_range
|
||||||
.map(|col_ix| {
|
.map(|col_ix| {
|
||||||
let col_ix = col_ix + left_cols_count;
|
let col_ix = col_ix + left_cols_count;
|
||||||
|
|
@ -1227,6 +1317,11 @@ where
|
||||||
{
|
{
|
||||||
move |table, visible_range, cx| {
|
move |table, visible_range, cx| {
|
||||||
table.load_more_if_need(visible_range.clone(), cx);
|
table.load_more_if_need(visible_range.clone(), cx);
|
||||||
|
table.update_visible_range_if_need(
|
||||||
|
visible_range.clone(),
|
||||||
|
Axis::Vertical,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
|
||||||
if visible_range.end > rows_count {
|
if visible_range.end > rows_count {
|
||||||
table.scroll_to_row(
|
table.scroll_to_row(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue