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}