table: Refactor TableDelegate to easy to access delegate. (#1712)
Closes #1610, #1583 Closes https://github.com/longbridge/gpui-component/discussions/1707 ## Description This change to improve the `TableDelegate` to have `&mut self` and `Context<TableState<Self>>` to easy access delegate. ## Break Changes - The argument types of `render_tr`, `render_td`, `render_th`, `context_menu`, `render_loading`, `render_empty`, `render_last_empty_col` in `TableDelegate` has been changed. ```diff - fn render_th(&self, col_ix: usize, _: &mut Window, _: &mut App) -> impl IntoElement + fn render_th(&mut self, col_ix: usize, _: &mut Window, _: &mut Context<TableState<Self>>) -> impl IntoElement ```
This commit is contained in:
parent
0126f1b036
commit
001b1795f1
3 changed files with 71 additions and 30 deletions
|
|
@ -189,6 +189,7 @@ struct StockTableDelegate {
|
|||
loading: bool,
|
||||
lazy_load: bool,
|
||||
full_loading: bool,
|
||||
clicked_row: Option<usize>,
|
||||
eof: bool,
|
||||
visible_rows: Range<usize>,
|
||||
visible_cols: Range<usize>,
|
||||
|
|
@ -202,6 +203,7 @@ impl StockTableDelegate {
|
|||
size: Size::default(),
|
||||
stocks: random_stocks(size),
|
||||
lazy_load: false,
|
||||
clicked_row: None,
|
||||
columns: vec![
|
||||
Column::new("id", "ID")
|
||||
.width(60.)
|
||||
|
|
@ -354,7 +356,12 @@ impl TableDelegate for StockTableDelegate {
|
|||
&self.columns[col_ix]
|
||||
}
|
||||
|
||||
fn render_th(&self, col_ix: usize, _: &mut Window, _: &mut App) -> impl IntoElement {
|
||||
fn render_th(
|
||||
&mut self,
|
||||
col_ix: usize,
|
||||
_: &mut Window,
|
||||
_: &mut Context<TableState<Self>>,
|
||||
) -> impl IntoElement {
|
||||
let col = self.columns.get(col_ix).unwrap();
|
||||
|
||||
div()
|
||||
|
|
@ -368,11 +375,11 @@ impl TableDelegate for StockTableDelegate {
|
|||
}
|
||||
|
||||
fn context_menu(
|
||||
&self,
|
||||
&mut self,
|
||||
row_ix: usize,
|
||||
menu: PopupMenu,
|
||||
_window: &mut Window,
|
||||
_cx: &mut App,
|
||||
_: &mut Context<TableState<Self>>,
|
||||
) -> PopupMenu {
|
||||
menu.menu(
|
||||
format!("Selected Row: {}", row_ix),
|
||||
|
|
@ -385,13 +392,23 @@ impl TableDelegate for StockTableDelegate {
|
|||
.menu("Size XSmall", Box::new(ChangeSize(Size::XSmall)))
|
||||
}
|
||||
|
||||
fn render_tr(&self, row_ix: usize, _: &mut Window, _: &mut App) -> Stateful<Div> {
|
||||
div().id(row_ix).on_click(|ev: &ClickEvent, _, _| {
|
||||
println!(
|
||||
"You have clicked row with secondary: {}",
|
||||
ev.modifiers().secondary()
|
||||
)
|
||||
})
|
||||
fn render_tr(
|
||||
&mut self,
|
||||
row_ix: usize,
|
||||
_: &mut Window,
|
||||
cx: &mut Context<TableState<Self>>,
|
||||
) -> Stateful<Div> {
|
||||
div()
|
||||
.id(row_ix)
|
||||
.on_click(cx.listener(move |table, ev: &ClickEvent, _window, cx| {
|
||||
println!(
|
||||
"You have clicked row with secondary: {}",
|
||||
ev.modifiers().secondary()
|
||||
);
|
||||
|
||||
table.delegate_mut().clicked_row = Some(row_ix);
|
||||
cx.notify();
|
||||
}))
|
||||
}
|
||||
|
||||
/// NOTE: Performance metrics
|
||||
|
|
@ -403,11 +420,11 @@ impl TableDelegate for StockTableDelegate {
|
|||
///
|
||||
/// If we improve the td rendering, we can reduce the time to render the full table cells.
|
||||
fn render_td(
|
||||
&self,
|
||||
&mut self,
|
||||
row_ix: usize,
|
||||
col_ix: usize,
|
||||
_: &mut Window,
|
||||
cx: &mut App,
|
||||
cx: &mut Context<TableState<Self>>,
|
||||
) -> impl IntoElement {
|
||||
let stock = self.stocks.get(row_ix).unwrap();
|
||||
let col = self.columns.get(col_ix).unwrap();
|
||||
|
|
|
|||
|
|
@ -1,15 +1,14 @@
|
|||
use std::ops::Range;
|
||||
|
||||
use gpui::{
|
||||
div, App, Context, Div, InteractiveElement as _, IntoElement, ParentElement as _, Stateful,
|
||||
Styled as _, Window,
|
||||
App, Context, Div, InteractiveElement as _, IntoElement, ParentElement as _, Stateful,
|
||||
Styled as _, Window, div,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
h_flex,
|
||||
ActiveTheme as _, Icon, IconName, Size, h_flex,
|
||||
menu::PopupMenu,
|
||||
table::{loading::Loading, Column, ColumnSort, TableState},
|
||||
ActiveTheme as _, Icon, IconName, Size,
|
||||
table::{Column, ColumnSort, TableState, loading::Loading},
|
||||
};
|
||||
|
||||
/// A delegate trait for providing data and rendering for a table.
|
||||
|
|
@ -37,35 +36,45 @@ pub trait TableDelegate: Sized + 'static {
|
|||
}
|
||||
|
||||
/// Render the header cell at the given column index, default to the column name.
|
||||
fn render_th(&self, col_ix: usize, window: &mut Window, cx: &mut App) -> impl IntoElement {
|
||||
fn render_th(
|
||||
&mut self,
|
||||
col_ix: usize,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<TableState<Self>>,
|
||||
) -> impl IntoElement {
|
||||
div()
|
||||
.size_full()
|
||||
.child(self.column(col_ix, cx).name.clone())
|
||||
}
|
||||
|
||||
/// Render the row at the given row and column.
|
||||
fn render_tr(&self, row_ix: usize, window: &mut Window, cx: &mut App) -> Stateful<Div> {
|
||||
fn render_tr(
|
||||
&mut self,
|
||||
row_ix: usize,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<TableState<Self>>,
|
||||
) -> Stateful<Div> {
|
||||
h_flex().id(("row", row_ix))
|
||||
}
|
||||
|
||||
/// Render the context menu for the row at the given row index.
|
||||
fn context_menu(
|
||||
&self,
|
||||
&mut self,
|
||||
row_ix: usize,
|
||||
menu: PopupMenu,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
cx: &mut Context<TableState<Self>>,
|
||||
) -> PopupMenu {
|
||||
menu
|
||||
}
|
||||
|
||||
/// Render cell at the given row and column.
|
||||
fn render_td(
|
||||
&self,
|
||||
&mut self,
|
||||
row_ix: usize,
|
||||
col_ix: usize,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
cx: &mut Context<TableState<Self>>,
|
||||
) -> impl IntoElement;
|
||||
|
||||
/// Move the column at the given `col_ix` to insert before the column at the given `to_ix`.
|
||||
|
|
@ -79,7 +88,11 @@ pub trait TableDelegate: Sized + 'static {
|
|||
}
|
||||
|
||||
/// Return a Element to show when table is empty.
|
||||
fn render_empty(&self, window: &mut Window, cx: &mut App) -> impl IntoElement {
|
||||
fn render_empty(
|
||||
&mut self,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<TableState<Self>>,
|
||||
) -> impl IntoElement {
|
||||
h_flex()
|
||||
.size_full()
|
||||
.justify_center()
|
||||
|
|
@ -96,7 +109,12 @@ pub trait TableDelegate: Sized + 'static {
|
|||
/// Return a Element to show when table is loading, default is built-in Skeleton loading view.
|
||||
///
|
||||
/// The size is the size of the Table.
|
||||
fn render_loading(&self, size: Size, window: &mut Window, cx: &mut App) -> impl IntoElement {
|
||||
fn render_loading(
|
||||
&mut self,
|
||||
size: Size,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<TableState<Self>>,
|
||||
) -> impl IntoElement {
|
||||
Loading::new().size(size)
|
||||
}
|
||||
|
||||
|
|
@ -125,7 +143,11 @@ pub trait TableDelegate: Sized + 'static {
|
|||
fn load_more(&mut self, window: &mut Window, cx: &mut Context<TableState<Self>>) {}
|
||||
|
||||
/// Render the last empty column, default to empty.
|
||||
fn render_last_empty_col(&self, window: &mut Window, cx: &mut App) -> impl IntoElement {
|
||||
fn render_last_empty_col(
|
||||
&mut self,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<TableState<Self>>,
|
||||
) -> impl IntoElement {
|
||||
h_flex().w_3().h_full().flex_shrink_0()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -788,7 +788,7 @@ where
|
|||
/// The children must be one by one items.
|
||||
/// Because the horizontal scroll handle will use the child_item_bounds to
|
||||
/// calculate the item position for itself's `scroll_to_item` method.
|
||||
fn render_th(&self, col_ix: usize, window: &mut Window, cx: &mut Context<Self>) -> Div {
|
||||
fn render_th(&mut self, col_ix: usize, window: &mut Window, cx: &mut Context<Self>) -> Div {
|
||||
let entity_id = cx.entity_id();
|
||||
let col_group = self.col_groups.get(col_ix).expect("BUG: invalid col index");
|
||||
|
||||
|
|
@ -896,7 +896,8 @@ where
|
|||
.bg(cx.theme().table_head)
|
||||
.children(
|
||||
self.col_groups
|
||||
.iter()
|
||||
.clone()
|
||||
.into_iter()
|
||||
.filter(|col| col.column.fixed == Some(ColumnFixed::Left))
|
||||
.enumerate()
|
||||
.map(|(col_ix, _)| self.render_th(col_ix, window, cx)),
|
||||
|
|
@ -939,7 +940,8 @@ where
|
|||
.relative()
|
||||
.children(
|
||||
self.col_groups
|
||||
.iter()
|
||||
.clone()
|
||||
.into_iter()
|
||||
.skip(left_columns_count)
|
||||
.enumerate()
|
||||
.map(|(col_ix, _)| {
|
||||
|
|
@ -1302,7 +1304,7 @@ where
|
|||
move |this, window: &mut Window, cx: &mut Context<PopupMenu>| {
|
||||
if let Some(row_ix) = view.read(cx).right_clicked_row {
|
||||
view.update(cx, |menu, cx| {
|
||||
menu.delegate().context_menu(row_ix, this, window, cx)
|
||||
menu.delegate_mut().context_menu(row_ix, this, window, cx)
|
||||
})
|
||||
} else {
|
||||
this
|
||||
|
|
|
|||
Loading…
Reference in a new issue