gpui_component/table/
delegate.rs

1use std::ops::Range;
2
3use gpui::{
4    div, App, Context, Div, InteractiveElement as _, IntoElement, ParentElement as _, Stateful,
5    Styled as _, Window,
6};
7
8use crate::{
9    h_flex,
10    menu::PopupMenu,
11    table::{loading::Loading, Column, ColumnSort, TableState},
12    ActiveTheme as _, Icon, IconName, Size,
13};
14
15/// A delegate trait for providing data and rendering for a table.
16#[allow(unused)]
17pub trait TableDelegate: Sized + 'static {
18    /// Return the number of columns in the table.
19    fn columns_count(&self, cx: &App) -> usize;
20
21    /// Return the number of rows in the table.
22    fn rows_count(&self, cx: &App) -> usize;
23
24    /// Returns the table column at the given index.
25    ///
26    /// This only call on Table prepare or refresh.
27    fn column(&self, col_ix: usize, cx: &App) -> &Column;
28
29    /// Perform sort on the column at the given index.
30    fn perform_sort(
31        &mut self,
32        col_ix: usize,
33        sort: ColumnSort,
34        window: &mut Window,
35        cx: &mut Context<TableState<Self>>,
36    ) {
37    }
38
39    /// Render the header cell at the given column index, default to the column name.
40    fn render_th(&self, col_ix: usize, window: &mut Window, cx: &mut App) -> impl IntoElement {
41        div()
42            .size_full()
43            .child(self.column(col_ix, cx).name.clone())
44    }
45
46    /// Render the row at the given row and column.
47    fn render_tr(&self, row_ix: usize, window: &mut Window, cx: &mut App) -> Stateful<Div> {
48        h_flex().id(("row", row_ix))
49    }
50
51    /// Render the context menu for the row at the given row index.
52    fn context_menu(
53        &self,
54        row_ix: usize,
55        menu: PopupMenu,
56        window: &mut Window,
57        cx: &mut App,
58    ) -> PopupMenu {
59        menu
60    }
61
62    /// Render cell at the given row and column.
63    fn render_td(
64        &self,
65        row_ix: usize,
66        col_ix: usize,
67        window: &mut Window,
68        cx: &mut App,
69    ) -> impl IntoElement;
70
71    /// Move the column at the given `col_ix` to insert before the column at the given `to_ix`.
72    fn move_column(
73        &mut self,
74        col_ix: usize,
75        to_ix: usize,
76        window: &mut Window,
77        cx: &mut Context<TableState<Self>>,
78    ) {
79    }
80
81    /// Return a Element to show when table is empty.
82    fn render_empty(&self, window: &mut Window, cx: &mut App) -> impl IntoElement {
83        h_flex()
84            .size_full()
85            .justify_center()
86            .text_color(cx.theme().muted_foreground.opacity(0.6))
87            .child(Icon::new(IconName::Inbox).size_12())
88            .into_any_element()
89    }
90
91    /// Return true to show the loading view.
92    fn loading(&self, cx: &App) -> bool {
93        false
94    }
95
96    /// Return a Element to show when table is loading, default is built-in Skeleton loading view.
97    ///
98    /// The size is the size of the Table.
99    fn render_loading(&self, size: Size, window: &mut Window, cx: &mut App) -> impl IntoElement {
100        Loading::new().size(size)
101    }
102
103    /// Return true to enable load more data when scrolling to the bottom.
104    ///
105    /// Default: true
106    fn is_eof(&self, cx: &App) -> bool {
107        true
108    }
109
110    /// Returns a threshold value (n rows), of course, when scrolling to the bottom,
111    /// the remaining number of rows triggers `load_more`.
112    /// This should smaller than the total number of first load rows.
113    ///
114    /// Default: 20 rows
115    fn load_more_threshold(&self) -> usize {
116        20
117    }
118
119    /// Load more data when the table is scrolled to the bottom.
120    ///
121    /// This will performed in a background task.
122    ///
123    /// This is always called when the table is near the bottom,
124    /// so you must check if there is more data to load or lock the loading state.
125    fn load_more(&mut self, window: &mut Window, cx: &mut Context<TableState<Self>>) {}
126
127    /// Render the last empty column, default to empty.
128    fn render_last_empty_col(&self, window: &mut Window, cx: &mut App) -> impl IntoElement {
129        h_flex().w_3().h_full().flex_shrink_0()
130    }
131
132    /// Called when the visible range of the rows changed.
133    ///
134    /// NOTE: Make sure this method is fast, because it will be called frequently.
135    ///
136    /// This can used to handle some data update, to only update the visible rows.
137    /// Please ensure that the data is updated in the background task.
138    fn visible_rows_changed(
139        &mut self,
140        visible_range: Range<usize>,
141        window: &mut Window,
142        cx: &mut Context<TableState<Self>>,
143    ) {
144    }
145
146    /// Called when the visible range of the columns changed.
147    ///
148    /// NOTE: Make sure this method is fast, because it will be called frequently.
149    ///
150    /// This can used to handle some data update, to only update the visible rows.
151    /// Please ensure that the data is updated in the background task.
152    fn visible_columns_changed(
153        &mut self,
154        visible_range: Range<usize>,
155        window: &mut Window,
156        cx: &mut Context<TableState<Self>>,
157    ) {
158    }
159}