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