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, ListState},
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<ListState<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(&self, ix: IndexPath, window: &mut Window, cx: &mut App) -> Option<Self::Item>;
39
40 /// Render the section header at the given index, default is None.
41 ///
42 /// NOTE: Every header should have same height.
43 fn render_section_header(
44 &self,
45 section: usize,
46 window: &mut Window,
47 cx: &mut App,
48 ) -> Option<impl IntoElement> {
49 None::<AnyElement>
50 }
51
52 /// Render the section footer at the given index, default is None.
53 ///
54 /// NOTE: Every footer should have same height.
55 fn render_section_footer(
56 &self,
57 section: usize,
58 window: &mut Window,
59 cx: &mut App,
60 ) -> Option<impl IntoElement> {
61 None::<AnyElement>
62 }
63
64 /// Return a Element to show when list is empty.
65 fn render_empty(&self, window: &mut Window, cx: &mut App) -> impl IntoElement {
66 h_flex()
67 .size_full()
68 .justify_center()
69 .text_color(cx.theme().muted_foreground.opacity(0.6))
70 .child(Icon::new(IconName::Inbox).size_12())
71 .into_any_element()
72 }
73
74 /// Returns Some(AnyElement) to render the initial state of the list.
75 ///
76 /// This can be used to show a view for the list before the user has
77 /// interacted with it.
78 ///
79 /// For example: The last search results, or the last selected item.
80 ///
81 /// Default is None, that means no initial state.
82 fn render_initial(&self, window: &mut Window, cx: &mut App) -> Option<AnyElement> {
83 None
84 }
85
86 /// Returns the loading state to show the loading view.
87 fn loading(&self, cx: &App) -> bool {
88 false
89 }
90
91 /// Returns a Element to show when loading, default is built-in Skeleton
92 /// loading view.
93 fn render_loading(&self, window: &mut Window, cx: &mut App) -> impl IntoElement {
94 Loading
95 }
96
97 /// Set the selected index, just store the ix, don't confirm.
98 fn set_selected_index(
99 &mut self,
100 ix: Option<IndexPath>,
101 window: &mut Window,
102 cx: &mut Context<ListState<Self>>,
103 );
104
105 /// Set the confirm and give the selected index,
106 /// this is means user have clicked the item or pressed Enter.
107 ///
108 /// This will always to `set_selected_index` before confirm.
109 fn confirm(&mut self, secondary: bool, window: &mut Window, cx: &mut Context<ListState<Self>>) {
110 }
111
112 /// Cancel the selection, e.g.: Pressed ESC.
113 fn cancel(&mut self, window: &mut Window, cx: &mut Context<ListState<Self>>) {}
114
115 /// Return true to enable load more data when scrolling to the bottom.
116 ///
117 /// Default: true
118 fn is_eof(&self, cx: &App) -> bool {
119 true
120 }
121
122 /// Returns a threshold value (n entities), of course,
123 /// when scrolling to the bottom, the remaining number of rows
124 /// triggers `load_more`.
125 ///
126 /// This should smaller than the total number of first load rows.
127 ///
128 /// Default: 20 entities (section header, footer and row)
129 fn load_more_threshold(&self) -> usize {
130 20
131 }
132
133 /// Load more data when the table is scrolled to the bottom.
134 ///
135 /// This will performed in a background task.
136 ///
137 /// This is always called when the table is near the bottom,
138 /// so you must check if there is more data to load or lock
139 /// the loading state.
140 fn load_more(&mut self, window: &mut Window, cx: &mut Context<ListState<Self>>) {}
141}