gpui_component/table/
delegate.rs

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