Skip to content

Commit

Permalink
Add ListView::try_remove and some other missing functions
Browse files Browse the repository at this point in the history
  • Loading branch information
gyscos committed Aug 28, 2024
1 parent 30389f3 commit fbcc967
Showing 1 changed file with 57 additions and 1 deletion.
58 changes: 57 additions & 1 deletion cursive-core/src/views/list_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,16 @@ type ListCallback = dyn Fn(&mut Cursive, &String) + Send + Sync;
/// Displays a list of elements.
pub struct ListView {
children: Vec<ListChild>,

// Height for each child.
// This should have the same size as the `children` list.
children_heights: Vec<usize>,

// Which child is focused? Should index into the `children` list.
//
// This is `0` when `children` is empty.
focus: usize,

// This callback is called when the selection is changed.
on_select: Option<Arc<ListCallback>>,
}
Expand Down Expand Up @@ -80,6 +85,10 @@ impl ListView {
}

/// Returns a reference to the child at the given position.
///
/// # Panics
///
/// If `id >= self.len()`.
pub fn get_row(&self, id: usize) -> &ListChild {
&self.children[id]
}
Expand All @@ -93,6 +102,20 @@ impl ListView {
&mut self.children[id]
}

/// Gives mutable access to the child at the given position.
///
/// Returns `None` if `id >= self.len()`.
pub fn try_row_mut(&mut self, id: usize) -> Option<&mut ListChild> {
self.children.get_mut(id)
}

/// Gives access to the child at the given position.
///
/// Returns `None` if `id >= self.len()`.
pub fn try_row(&self, id: usize) -> Option<&ListChild> {
self.children.get(id)
}

/// Sets the children for this view.
pub fn set_children(&mut self, children: Vec<ListChild>) {
self.children_heights.resize(children.len(), 0);
Expand All @@ -109,10 +132,30 @@ impl ListView {
self.children_heights.push(0);
}

/// Attempts to set the focus to the given position.
///
/// Returns `None` if `if >= self.len()` or if the child at this location is not focusable.
pub fn set_focus(&mut self, id: usize) -> Option<EventResult> {
if id >= self.len() {
return None;
}

let ListChild::Row(_, ref mut view) = self.children[id] else {
return None;
};

let Ok(res) = view.take_focus(direction::Direction::none()) else {
return None;
};

Some(self.set_focus_unchecked(id).and(res))
}

/// Removes all children from this view.
pub fn clear(&mut self) {
self.children.clear();
self.children_heights.clear();
self.focus = 0;
}

/// Adds a view to the end of the list.
Expand Down Expand Up @@ -143,10 +186,23 @@ impl ListView {
///
/// If `index >= self.len()`.
pub fn remove_child(&mut self, index: usize) -> ListChild {
// TODO: fix the focus if it's > index.
// Drop the EventResult that would come from that?
self.children_heights.remove(index);
self.children.remove(index)
}

/// Removes a child from the view.
///
/// Returns `None` if `index >= self.len()`.
pub fn try_remove(&mut self, index: usize) -> Option<ListChild> {
if index >= self.len() {
None
} else {
Some(self.remove_child(index))
}
}

/// Sets a callback to be used when an item is selected.
#[crate::callback_helpers]
pub fn set_on_select<F>(&mut self, cb: F)
Expand All @@ -169,7 +225,7 @@ impl ListView {

/// Returns the index of the currently focused item.
///
/// Panics if the list is empty.
/// Returns `0` if the list is empty.
pub fn focus(&self) -> usize {
self.focus
}
Expand Down

0 comments on commit fbcc967

Please sign in to comment.