gpui_component/list/delegate.rs
1use gpui::{AnyElement, App, Context, IntoElement, ParentElement as _, Styled as _, Task, Window};
2
3use crate::{
4 h_flex,
5 list::{loading::Loading, List},
6 ActiveTheme as _, Icon, IconName, IndexPath, Selectable,
7};
8
9/// A delegate for the List.
10#[allow(unused)]
11pub trait ListDelegate: Sized + 'static {
12 type Item: Selectable + IntoElement;
13
14 /// When Query Input change, this method will be called.
15 /// You can perform search here.
16 fn perform_search(
17 &mut self,
18 query: &str,
19 window: &mut Window,
20 cx: &mut Context<List<Self>>,
21 ) -> Task<()> {
22 Task::ready(())
23 }
24
25 /// Return the number of sections in the list, default is 1.
26 fn sections_count(&self, cx: &App) -> usize {
27 1
28 }
29
30 /// Return the number of items in the section at the given index.
31 fn items_count(&self, section: usize, cx: &App) -> usize;
32
33 /// Render the item at the given index.
34 ///
35 /// Return None will skip the item.
36 ///
37 /// NOTE: Every item should have same height.
38 fn render_item(
39 &self,
40 ix: IndexPath,
41 window: &mut Window,
42 cx: &mut Context<List<Self>>,
43 ) -> Option<Self::Item>;
44
45 /// Render the section header at the given index, default is None.
46 ///
47 /// NOTE: Every header should have same height.
48 fn render_section_header(
49 &self,
50 section: usize,
51 window: &mut Window,
52 cx: &mut Context<List<Self>>,
53 ) -> Option<impl IntoElement> {
54 None::<AnyElement>
55 }
56
57 /// Render the section footer at the given index, default is None.
58 ///
59 /// NOTE: Every footer should have same height.
60 fn render_section_footer(
61 &self,
62 section: usize,
63 window: &mut Window,
64 cx: &mut Context<List<Self>>,
65 ) -> Option<impl IntoElement> {
66 None::<AnyElement>
67 }
68
69 /// Return a Element to show when list is empty.
70 fn render_empty(&self, window: &mut Window, cx: &mut Context<List<Self>>) -> impl IntoElement {
71 h_flex()
72 .size_full()
73 .justify_center()
74 .text_color(cx.theme().muted_foreground.opacity(0.6))
75 .child(Icon::new(IconName::Inbox).size_12())
76 .into_any_element()
77 }
78
79 /// Returns Some(AnyElement) to render the initial state of the list.
80 ///
81 /// This can be used to show a view for the list before the user has
82 /// interacted with it.
83 ///
84 /// For example: The last search results, or the last selected item.
85 ///
86 /// Default is None, that means no initial state.
87 fn render_initial(
88 &self,
89 window: &mut Window,
90 cx: &mut Context<List<Self>>,
91 ) -> Option<AnyElement> {
92 None
93 }
94
95 /// Returns the loading state to show the loading view.
96 fn loading(&self, cx: &App) -> bool {
97 false
98 }
99
100 /// Returns a Element to show when loading, default is built-in Skeleton
101 /// loading view.
102 fn render_loading(
103 &self,
104 window: &mut Window,
105 cx: &mut Context<List<Self>>,
106 ) -> impl IntoElement {
107 Loading
108 }
109
110 /// Set the selected index, just store the ix, don't confirm.
111 fn set_selected_index(
112 &mut self,
113 ix: Option<IndexPath>,
114 window: &mut Window,
115 cx: &mut Context<List<Self>>,
116 );
117
118 /// Set the confirm and give the selected index,
119 /// this is means user have clicked the item or pressed Enter.
120 ///
121 /// This will always to `set_selected_index` before confirm.
122 fn confirm(&mut self, secondary: bool, window: &mut Window, cx: &mut Context<List<Self>>) {}
123
124 /// Cancel the selection, e.g.: Pressed ESC.
125 fn cancel(&mut self, window: &mut Window, cx: &mut Context<List<Self>>) {}
126
127 /// Return true to enable load more data when scrolling to the bottom.
128 ///
129 /// Default: true
130 fn is_eof(&self, cx: &App) -> bool {
131 true
132 }
133
134 /// Returns a threshold value (n entities), of course,
135 /// when scrolling to the bottom, the remaining number of rows
136 /// triggers `load_more`.
137 ///
138 /// This should smaller than the total number of first load rows.
139 ///
140 /// Default: 20 entities (section header, footer and row)
141 fn load_more_threshold(&self) -> usize {
142 20
143 }
144
145 /// Load more data when the table is scrolled to the bottom.
146 ///
147 /// This will performed in a background task.
148 ///
149 /// This is always called when the table is near the bottom,
150 /// so you must check if there is more data to load or lock
151 /// the loading state.
152 fn load_more(&mut self, window: &mut Window, cx: &mut Context<List<Self>>) {}
153}