Ref UITableView API: https://developer.apple.com/documentation/uikit/uitableviewdatasource ## Changes - Added some section related API to `ListDelegeate` and `DropdownDelegate` with default implement, so if you don't need section that you can just keep the default. - Added `sections_count` method to get the number of sections, default is 1. - Added `render_section_header` for special the section header by if needed, default return None. - Added `render_section_footer` for special the section footer by if needed, default return None. ## Break Changes - The `DropdownState` have change new method to use IndexPath type: ```diff - DropdownState::new(vec![], Some(1), window, cx); + DropdownState::new(vec![], Some(IndexPath::new(1)), window, cx); ``` - The `ListDelegeate`, `DropdownDelegate` has changed API: - The `ix` are change from `usize` to `IndexPath`. ```diff - fn render_item(&self, ix: usize, window: &mut Window, cx: &mut Context<List<Self>>) -> Option<Self::Item> + fn render_item(&self, ix: IndexPath, window: &mut Window, cx: &mut Context<List<Self>>) -> Option<Self::Item> - fn set_selected_index(&mut self, ix: Option<usize>, window: &mut Window, cx: &mut Context<List<Self>>) + fn set_selected_index(&mut self, ix: Option<IndexPath>, window: &mut Window, cx: &mut Context<List<Self>>) ``` - The `items_count` method have added `section` argument to support list section. ```diff - fn items_count(&self, cx: &App) -> usize + fn items_count(&self, section: usize, cx: &App) -> usize ``` - The `can_load_more` method has renamed to `is_eof` in `ListDelegate` and `TableDelegate`. ```diff - fn can_load_more(&self, cx: &App) -> bool + fn is_eof(&self, cx: &App) -> bool ``` - The `can_search` method has renamed to `searchable` in `ListDelegate`. ```diff - fn can_search(&self) -> bool + fn searchable(&self) -> bool ``` ## Showcase <img width="1196" height="925" alt="image" src="https://github.com/user-attachments/assets/22750abe-cc3f-427e-903b-51758bd4e027" /> <img width="1214" height="934" alt="image" src="https://github.com/user-attachments/assets/52d42546-e6e7-4448-9c0f-43cd659fb630" /> --------- Co-authored-by: Floyd Wang <gassnake999@gmail.com>
102 lines
2.7 KiB
Rust
102 lines
2.7 KiB
Rust
use std::fmt::{Debug, Display};
|
|
|
|
use gpui::ElementId;
|
|
|
|
/// Represents an index path in a list, which consists of a section index,
|
|
///
|
|
/// The default values for section, row, and column are all set to 0.
|
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
|
pub struct IndexPath {
|
|
/// The section index.
|
|
pub section: usize,
|
|
/// The item index in the section.
|
|
pub row: usize,
|
|
/// The column index.
|
|
pub column: usize,
|
|
}
|
|
|
|
impl From<IndexPath> for ElementId {
|
|
fn from(path: IndexPath) -> Self {
|
|
ElementId::Name(format!("index-path({},{},{})", path.section, path.row, path.column).into())
|
|
}
|
|
}
|
|
|
|
impl Display for IndexPath {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
write!(
|
|
f,
|
|
"IndexPath(section: {}, row: {}, column: {})",
|
|
self.section, self.row, self.column
|
|
)
|
|
}
|
|
}
|
|
|
|
impl IndexPath {
|
|
/// Create a new index path with the specified section and row.
|
|
///
|
|
/// The `section` is set to 0 by default.
|
|
/// The `column` is set to 0 by default.
|
|
pub fn new(row: usize) -> Self {
|
|
IndexPath {
|
|
section: 0,
|
|
row,
|
|
..Default::default()
|
|
}
|
|
}
|
|
|
|
/// Set the section for the index path.
|
|
pub fn section(mut self, section: usize) -> Self {
|
|
self.section = section;
|
|
self
|
|
}
|
|
|
|
/// Set the row for the index path.
|
|
pub fn row(mut self, row: usize) -> Self {
|
|
self.row = row;
|
|
self
|
|
}
|
|
|
|
/// Set the column for the index path.
|
|
pub fn column(mut self, column: usize) -> Self {
|
|
self.column = column;
|
|
self
|
|
}
|
|
|
|
/// Check if the self is equal to the given index path (Same section and row).
|
|
pub fn eq_row(&self, index: IndexPath) -> bool {
|
|
self.section == index.section && self.row == index.row
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_into_element_id() {
|
|
let index_path = IndexPath::new(2).section(1).column(3);
|
|
let element_id: ElementId = index_path.into();
|
|
assert_eq!(element_id.to_string(), "index-path(1,2,3)");
|
|
}
|
|
|
|
#[test]
|
|
fn test_display() {
|
|
assert_eq!(
|
|
format!("{}", IndexPath::new(2).section(1).column(3)),
|
|
"IndexPath(section: 1, row: 2, column: 3)"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_index_path() {
|
|
let mut index_path = IndexPath::default();
|
|
assert_eq!(index_path.section, 0);
|
|
assert_eq!(index_path.row, 0);
|
|
assert_eq!(index_path.column, 0);
|
|
|
|
index_path = index_path.section(1).row(2).column(3);
|
|
assert_eq!(index_path.section, 1);
|
|
assert_eq!(index_path.row, 2);
|
|
assert_eq!(index_path.column, 3);
|
|
}
|
|
}
|