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