mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Add on_select callback for SelectView
And updated the select example to use that instead of an OK button. This also removes the need for an ID selector.
This commit is contained in:
parent
a30a77f39b
commit
b64a6b8c34
@ -4,7 +4,7 @@ use std::fs::File;
|
|||||||
use std::io::{BufReader,BufRead};
|
use std::io::{BufReader,BufRead};
|
||||||
|
|
||||||
use cursive::Cursive;
|
use cursive::Cursive;
|
||||||
use cursive::view::{Dialog,SelectView,TextView,Selector,BoxView};
|
use cursive::view::{Dialog,SelectView,TextView,BoxView};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// To keep things simple, little error management is done here.
|
// To keep things simple, little error management is done here.
|
||||||
@ -22,17 +22,15 @@ fn main() {
|
|||||||
let mut siv = Cursive::new();
|
let mut siv = Cursive::new();
|
||||||
|
|
||||||
// Let's add a BoxView to keep the list at a reasonable size - it can scroll anyway.
|
// Let's add a BoxView to keep the list at a reasonable size - it can scroll anyway.
|
||||||
siv.add_layer(Dialog::new(BoxView::new((20,10), select.with_id("city")))
|
siv.add_layer(Dialog::new(BoxView::new((20,10), select.on_select(|s,city| show_next_window(s,city))))
|
||||||
.title("Where are you from?")
|
.title("Where are you from?"));
|
||||||
.button("Ok", |s| {
|
|
||||||
// Find the SelectView, gets its selection.
|
|
||||||
let city = s.find::<SelectView>(&Selector::Id("city")).unwrap().selection().to_string();
|
|
||||||
// And show the next window.
|
|
||||||
s.pop_layer();
|
|
||||||
s.add_layer(Dialog::new(TextView::new(&format!("{} is a great city!", city)))
|
|
||||||
.button("Quit", |s| s.quit()));
|
|
||||||
}));
|
|
||||||
|
|
||||||
siv.run();
|
siv.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Let's put the callback in a separate function to keep it clean, but it's not required.
|
||||||
|
fn show_next_window(siv: &mut Cursive, city: &str) {
|
||||||
|
siv.pop_layer();
|
||||||
|
siv.add_layer(Dialog::new(TextView::new(&format!("{} is a great city!", city)))
|
||||||
|
.button("Quit", |s| s.quit()));
|
||||||
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use color;
|
use color;
|
||||||
|
use ::Cursive;
|
||||||
use view::{View,IdView,SizeRequest,DimensionRequest};
|
use view::{View,IdView,SizeRequest,DimensionRequest};
|
||||||
use event::{Event,EventResult,Key};
|
use event::{Event,EventResult,Key};
|
||||||
use vec::Vec2;
|
use vec::Vec2;
|
||||||
@ -9,14 +11,14 @@ use super::scroll::ScrollBase;
|
|||||||
|
|
||||||
struct Item<T> {
|
struct Item<T> {
|
||||||
label: String,
|
label: String,
|
||||||
value: T,
|
value: Rc<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <T> Item<T> {
|
impl <T> Item<T> {
|
||||||
fn new(label: &str, value: T) -> Self {
|
fn new(label: &str, value: T) -> Self {
|
||||||
Item {
|
Item {
|
||||||
label: label.to_string(),
|
label: label.to_string(),
|
||||||
value: value,
|
value: Rc::new(value),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -28,21 +30,32 @@ pub struct SelectView<T=String> {
|
|||||||
items: Vec<Item<T>>,
|
items: Vec<Item<T>>,
|
||||||
focus: usize,
|
focus: usize,
|
||||||
scrollbase: ScrollBase,
|
scrollbase: ScrollBase,
|
||||||
|
select_cb: Option<Rc<Box<Fn(&mut Cursive,&T)>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <T> SelectView<T> {
|
impl <T: 'static> SelectView<T> {
|
||||||
/// Creates a new empty SelectView.
|
/// Creates a new empty SelectView.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
SelectView {
|
SelectView {
|
||||||
items: Vec::new(),
|
items: Vec::new(),
|
||||||
focus: 0,
|
focus: 0,
|
||||||
scrollbase: ScrollBase::new(),
|
scrollbase: ScrollBase::new(),
|
||||||
|
select_cb: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets a function to be called when an item is selected (when ENTER is pressed).
|
||||||
|
pub fn on_select<F>(mut self, cb: F) -> Self
|
||||||
|
where F: Fn(&mut Cursive,&T) + 'static
|
||||||
|
{
|
||||||
|
self.select_cb = Some(Rc::new(Box::new(cb)));
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the value of the currently selected item. Panics if the list is empty.
|
/// Returns the value of the currently selected item. Panics if the list is empty.
|
||||||
pub fn selection(&self) -> &T {
|
pub fn selection(&self) -> Rc<T> {
|
||||||
&self.items[self.focus].value
|
self.items[self.focus].value.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a item to the list, with given label and value.
|
/// Adds a item to the list, with given label and value.
|
||||||
@ -76,7 +89,7 @@ impl SelectView<String> {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <T> View for SelectView<T> {
|
impl <T: 'static> View for SelectView<T> {
|
||||||
fn draw(&mut self, printer: &Printer) {
|
fn draw(&mut self, printer: &Printer) {
|
||||||
|
|
||||||
self.scrollbase.draw(printer, |printer,i| {
|
self.scrollbase.draw(printer, |printer,i| {
|
||||||
@ -115,6 +128,13 @@ impl <T> View for SelectView<T> {
|
|||||||
Event::KeyEvent(Key::PageDown) => self.focus = min(self.focus+10,self.items.len()-1),
|
Event::KeyEvent(Key::PageDown) => self.focus = min(self.focus+10,self.items.len()-1),
|
||||||
Event::KeyEvent(Key::Home) => self.focus = 0,
|
Event::KeyEvent(Key::Home) => self.focus = 0,
|
||||||
Event::KeyEvent(Key::End) => self.focus = self.items.len()-1,
|
Event::KeyEvent(Key::End) => self.focus = self.items.len()-1,
|
||||||
|
Event::KeyEvent(Key::Enter) if self.select_cb.is_some() => {
|
||||||
|
if let Some(ref cb) = self.select_cb {
|
||||||
|
let cb = cb.clone();
|
||||||
|
let v = self.selection();
|
||||||
|
return EventResult::Consumed(Some(Rc::new(Box::new(move |s| cb(s, &*v)))));
|
||||||
|
}
|
||||||
|
},
|
||||||
Event::CharEvent(c) => {
|
Event::CharEvent(c) => {
|
||||||
// Starting from the current focus, find the first item that match the char.
|
// Starting from the current focus, find the first item that match the char.
|
||||||
// Cycle back to the beginning of the list when we reach the end.
|
// Cycle back to the beginning of the list when we reach the end.
|
||||||
|
Loading…
Reference in New Issue
Block a user