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}