Rename KeyEventView to OnEventView

This commit is contained in:
Alexandre Bury 2017-06-12 16:39:12 -07:00
parent 6fa062775b
commit 93b5421f53
5 changed files with 108 additions and 101 deletions

View File

@ -1,7 +1,7 @@
extern crate cursive; extern crate cursive;
use cursive::Cursive; use cursive::Cursive;
use cursive::views::{Dialog, KeyEventView, TextView}; use cursive::views::{Dialog, OnEventView, TextView};
use cursive::view::{Offset, Position}; use cursive::view::{Offset, Position};
use cursive::traits::*; use cursive::traits::*;
@ -33,8 +33,8 @@ fn main() {
// Let's wrap the view to give it a recognizable ID, so we can look for it. // Let's wrap the view to give it a recognizable ID, so we can look for it.
// We add the P callback on the textview only (and not globally), // We add the P callback on the textview only (and not globally),
// so that we can't call it when the popup is already visible. // so that we can't call it when the popup is already visible.
siv.add_layer(KeyEventView::new(TextView::new(content).with_id("text")) siv.add_layer(OnEventView::new(TextView::new(content).with_id("text"))
.register('p', |s| show_popup(s))); .on_event('p', |s| show_popup(s)));
siv.run(); siv.run();

View File

@ -12,7 +12,7 @@ use std::rc::Rc;
use unicode_width::UnicodeWidthStr; use unicode_width::UnicodeWidthStr;
use vec::Vec2; use vec::Vec2;
use view::{Position, ScrollBase, View}; use view::{Position, ScrollBase, View};
use views::KeyEventView; use views::OnEventView;
/// Popup that shows a list of items. /// Popup that shows a list of items.
pub struct MenuPopup { pub struct MenuPopup {
@ -153,7 +153,7 @@ impl MenuPopup {
let action_cb = action_cb.clone(); let action_cb = action_cb.clone();
s.screen_mut() s.screen_mut()
.add_layer_at(Position::parent(offset), .add_layer_at(Position::parent(offset),
KeyEventView::new(MenuPopup::new(tree.clone()) OnEventView::new(MenuPopup::new(tree.clone())
.on_action(move |s| { .on_action(move |s| {
// This will happen when the subtree popup // This will happen when the subtree popup
// activates something; // activates something;
@ -163,7 +163,7 @@ impl MenuPopup {
action_cb.clone()(s); action_cb.clone()(s);
} }
})) }))
.register(Key::Left, |s| s.pop_layer())); .on_event(Key::Left, |s| s.pop_layer()));
}) })
} }
} }
@ -297,7 +297,6 @@ impl View for MenuPopup {
} }
fn layout(&mut self, size: Vec2) { fn layout(&mut self, size: Vec2) {
self.scrollbase self.scrollbase.set_heights(size.y - 2, self.menu.children.len());
.set_heights(size.y - 2, self.menu.children.len());
} }
} }

View File

@ -10,7 +10,7 @@ use theme::ColorStyle;
use unicode_width::UnicodeWidthStr; use unicode_width::UnicodeWidthStr;
use vec::Vec2; use vec::Vec2;
use view::{Position, View}; use view::{Position, View};
use views::{KeyEventView, MenuPopup}; use views::{OnEventView, MenuPopup};
/// Current state of the menubar /// Current state of the menubar
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
@ -108,9 +108,7 @@ impl Menubar {
/// ///
/// Returns `None` if `i > self.len()` /// Returns `None` if `i > self.len()`
pub fn get_subtree(&mut self, i: usize) -> Option<&mut MenuTree> { pub fn get_subtree(&mut self, i: usize) -> Option<&mut MenuTree> {
self.menus self.menus.get_mut(i).map(|&mut (_, ref mut tree)| Rc::make_mut(tree))
.get_mut(i)
.map(|&mut (_, ref mut tree)| Rc::make_mut(tree))
} }
/// Looks for an item with the given label. /// Looks for an item with the given label.
@ -129,9 +127,7 @@ impl Menubar {
/// ///
/// Returns `None` if no such label was found. /// Returns `None` if no such label was found.
pub fn find_position(&mut self, label: &str) -> Option<usize> { pub fn find_position(&mut self, label: &str) -> Option<usize> {
self.menus self.menus.iter().position(|&(ref l, _)| l == label)
.iter()
.position(|&(ref l, _)| l == label)
} }
/// Remove the item at the given position. /// Remove the item at the given position.
@ -145,34 +141,35 @@ fn show_child(s: &mut Cursive, offset: (usize, usize), menu: Rc<MenuTree>) {
// Also adds two key callbacks on this new view, to handle `left` and // Also adds two key callbacks on this new view, to handle `left` and
// `right` key presses. // `right` key presses.
// (If the view itself listens for a `left` or `right` press, it will // (If the view itself listens for a `left` or `right` press, it will
// consume it before our KeyEventView. This means sub-menus can properly // consume it before our OnEventView. This means sub-menus can properly
// be entered.) // be entered.)
s.screen_mut() s.screen_mut()
.add_layer_at(Position::absolute(offset), .add_layer_at(Position::absolute(offset),
KeyEventView::new(MenuPopup::new(menu) OnEventView::new(MenuPopup::new(menu)
.on_dismiss(|s| s.select_menubar()) .on_dismiss(|s| {
s.select_menubar()
})
.on_action(|s| { .on_action(|s| {
s.menubar().state = State::Inactive s.menubar().state =
State::Inactive
})) }))
.register(Key::Right, |s| { .on_event(Key::Right, |s| {
s.pop_layer(); s.pop_layer();
s.select_menubar(); s.select_menubar();
// Act as if we sent "Right" then "Down" // Act as if we sent "Right" then "Down"
s.menubar().on_event(Event::Key(Key::Right)).process(s); s.menubar().on_event(Event::Key(Key::Right)).process(s);
if let EventResult::Consumed(Some(cb)) = if let EventResult::Consumed(Some(cb)) =
s.menubar() s.menubar().on_event(Event::Key(Key::Down)) {
.on_event(Event::Key(Key::Down)) {
cb(s); cb(s);
} }
}) })
.register(Key::Left, |s| { .on_event(Key::Left, |s| {
s.pop_layer(); s.pop_layer();
s.select_menubar(); s.select_menubar();
// Act as if we sent "Left" then "Down" // Act as if we sent "Left" then "Down"
s.menubar().on_event(Event::Key(Key::Left)).process(s); s.menubar().on_event(Event::Key(Key::Left)).process(s);
if let EventResult::Consumed(Some(cb)) = if let EventResult::Consumed(Some(cb)) =
s.menubar() s.menubar().on_event(Event::Key(Key::Down)) {
.on_event(Event::Key(Key::Down)) {
cb(s); cb(s);
} }
})); }));
@ -226,7 +223,8 @@ impl View for Menubar {
// since we don't know when it will be called. // since we don't know when it will be called.
let menu = self.menus[self.focus].1.clone(); let menu = self.menus[self.focus].1.clone();
self.state = State::Submenu; self.state = State::Submenu;
let offset = (self.menus[..self.focus] let offset =
(self.menus[..self.focus]
.iter() .iter()
.map(|&(ref title, _)| title.width() + 2) .map(|&(ref title, _)| title.width() + 2)
.fold(0, |a, b| a + b), .fold(0, |a, b| a + b),
@ -234,7 +232,9 @@ impl View for Menubar {
// Since the closure will be called multiple times, // Since the closure will be called multiple times,
// we also need a new Rc on every call. // we also need a new Rc on every call.
return EventResult::with_cb(move |s| { return EventResult::with_cb(move |s| {
show_child(s, offset, menu.clone()) show_child(s,
offset,
menu.clone())
}); });
} }
_ => return EventResult::Ignored, _ => return EventResult::Ignored,

View File

@ -43,7 +43,7 @@ mod dialog;
mod dummy; mod dummy;
mod edit_view; mod edit_view;
mod id_view; mod id_view;
mod key_event_view; mod on_event_view;
mod layer; mod layer;
mod linear_layout; mod linear_layout;
mod list_view; mod list_view;
@ -69,7 +69,7 @@ pub use self::dialog::Dialog;
pub use self::dummy::DummyView; pub use self::dummy::DummyView;
pub use self::edit_view::EditView; pub use self::edit_view::EditView;
pub use self::id_view::{IdView, ViewRef}; pub use self::id_view::{IdView, ViewRef};
pub use self::key_event_view::KeyEventView; pub use self::on_event_view::OnEventView;
pub use self::layer::Layer; pub use self::layer::Layer;
pub use self::linear_layout::LinearLayout; pub use self::linear_layout::LinearLayout;
pub use self::list_view::{ListChild, ListView}; pub use self::list_view::{ListChild, ListView};

View File

@ -4,6 +4,7 @@ use Cursive;
use event::{Callback, Event, EventResult}; use event::{Callback, Event, EventResult};
use std::collections::HashMap; use std::collections::HashMap;
use view::{View, ViewWrapper}; use view::{View, ViewWrapper};
use With;
/// A simple wrapper view that catches some ignored event from its child. /// A simple wrapper view that catches some ignored event from its child.
/// ///
@ -13,36 +14,43 @@ use view::{View, ViewWrapper};
/// ///
/// ``` /// ```
/// # use cursive::event;; /// # use cursive::event;;
/// # use cursive::views::{KeyEventView, TextView}; /// # use cursive::views::{OnEventView, TextView};
/// let view = KeyEventView::new(TextView::new("This view has an event!")) /// let view = OnEventView::new(TextView::new("This view has an event!"))
/// .register('q', |s| s.quit()) /// .on_event('q', |s| s.quit())
/// .register(event::Key::Esc, |s| s.quit()); /// .on_event(event::Key::Esc, |s| s.quit());
/// ``` /// ```
pub struct KeyEventView<T: View> { pub struct OnEventView<T: View> {
content: T, content: T,
callbacks: HashMap<Event, Callback>, callbacks: HashMap<Event, Callback>,
} }
impl<T: View> KeyEventView<T> { impl<T: View> OnEventView<T> {
/// Wraps the given view in a new KeyEventView. /// Wraps the given view in a new OnEventView.
pub fn new(view: T) -> Self { pub fn new(view: T) -> Self {
KeyEventView { OnEventView {
content: view, content: view,
callbacks: HashMap::new(), callbacks: HashMap::new(),
} }
} }
/// Registers a callback when the given key is ignored by the child. /// Registers a callback when the given event is ignored by the child.
pub fn register<F, E: Into<Event>>(mut self, event: E, cb: F) -> Self ///
/// Chainable variant.
pub fn on_event<F, E: Into<Event>>(self, event: E, cb: F) -> Self
where F: Fn(&mut Cursive) + 'static
{
self.with(|s| s.set_on_event(event, cb))
}
/// Registers a callback when the given event is ignored by the child.
pub fn set_on_event<F, E: Into<Event>>(&mut self, event: E, cb: F)
where F: Fn(&mut Cursive) + 'static where F: Fn(&mut Cursive) + 'static
{ {
self.callbacks.insert(event.into(), Callback::from_fn(cb)); self.callbacks.insert(event.into(), Callback::from_fn(cb));
self
} }
} }
impl<T: View> ViewWrapper for KeyEventView<T> { impl<T: View> ViewWrapper for OnEventView<T> {
wrap_impl!(self.content: T); wrap_impl!(self.content: T);
fn wrap_on_event(&mut self, event: Event) -> EventResult { fn wrap_on_event(&mut self, event: Event) -> EventResult {