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}