diff --git a/src/views/list_view.rs b/src/views/list_view.rs index bfe9746..f7af360 100644 --- a/src/views/list_view.rs +++ b/src/views/list_view.rs @@ -1,9 +1,11 @@ +use Cursive; use Printer; use With; use direction; -use event::{Event, EventResult, Key}; +use event::{Callback, Event, EventResult, Key}; use std::any::Any; +use std::rc::Rc; use vec::Vec2; use view::ScrollBase; use view::Selector; @@ -35,6 +37,8 @@ pub struct ListView { children: Vec, scrollbase: ScrollBase, focus: usize, + // This callback is called when the selection is changed. + on_select: Option>, } new_default!(ListView); @@ -46,6 +50,7 @@ impl ListView { children: Vec::new(), scrollbase: ScrollBase::new(), focus: 0, + on_select: None, } } @@ -80,6 +85,29 @@ impl ListView { self.with(Self::add_delimiter) } + /// Sets a callback to be used when an item is selected. + pub fn set_on_select(&mut self, cb: F) + where F: Fn(&mut Cursive, &String) + 'static + { + self.on_select = Some(Rc::new(cb)); + } + + /// Sets a callback to be used when an item is selected. + /// + /// Chainable variant. + pub fn on_select(self, cb: F) -> Self + where F: Fn(&mut Cursive, &String) + 'static + { + self.with(|s| s.set_on_select(cb)) + } + + /// Returns the index of the currently focused item. + /// + /// Panics if the list is empty. + pub fn focus(&self) -> usize { + self.focus + } + fn iter_mut<'a>(&'a mut self, from_focus: bool, source: direction::Relative) -> Box + 'a> { @@ -121,7 +149,11 @@ impl ListView { self.focus = i; self.scrollbase.scroll_to(self.focus); - EventResult::Consumed(None) + EventResult::Consumed(self.on_select.clone().map(|cb| { + let i = self.focus(); + let focused_string = String::from(self.children[i].label()); + Callback::from_fn(move |s| cb(s, &focused_string)) + })) } } diff --git a/src/views/select_view.rs b/src/views/select_view.rs index ac7a5fa..e9ce58e 100644 --- a/src/views/select_view.rs +++ b/src/views/select_view.rs @@ -1,5 +1,3 @@ - - use Cursive; use Printer; use With;