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}