mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-24 01:46:31 +00:00
Add some doc to the menu
module
This commit is contained in:
parent
7a466e254f
commit
2065be3e88
@ -94,6 +94,7 @@ mod backend;
|
|||||||
pub use xy::XY;
|
pub use xy::XY;
|
||||||
pub use with::With;
|
pub use with::With;
|
||||||
pub use printer::Printer;
|
pub use printer::Printer;
|
||||||
|
pub use menubar::Menubar;
|
||||||
|
|
||||||
use backend::{Backend, NcursesBackend};
|
use backend::{Backend, NcursesBackend};
|
||||||
|
|
||||||
|
12
src/menu.rs
12
src/menu.rs
@ -1,4 +1,16 @@
|
|||||||
//! Module to build menus.
|
//! Module to build menus.
|
||||||
|
//!
|
||||||
|
//! Menus are a way to arrange many actions in groups of more manageable size.
|
||||||
|
//!
|
||||||
|
//! A menu can be seen as a `MenuTree`. It has a list of children:
|
||||||
|
//!
|
||||||
|
//! * Leaf nodes are made of a label and a callback
|
||||||
|
//! * Sub-trees are made of a label, and another `MenuTree`.
|
||||||
|
//! * Delimiters are just there to separate groups of related children.
|
||||||
|
//!
|
||||||
|
//! The [menubar] is the main way to show menus.
|
||||||
|
//!
|
||||||
|
//! [menubar]: ../struct.Cursive.html#method.menubar
|
||||||
|
|
||||||
use With;
|
use With;
|
||||||
use Cursive;
|
use Cursive;
|
||||||
|
@ -27,16 +27,26 @@ enum State {
|
|||||||
Submenu,
|
Submenu,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Shows a single-line list of items, with pop-up menus when one is selected.
|
||||||
|
///
|
||||||
|
/// The [`Cursive`] root already includes a menubar that you just needs to configure.
|
||||||
|
///
|
||||||
|
/// [`Cursive`]: struct.Cursive.html#method.menubar
|
||||||
pub struct Menubar {
|
pub struct Menubar {
|
||||||
|
/// Menu items in this menubar.
|
||||||
pub menus: Vec<(String, Rc<MenuTree>)>,
|
pub menus: Vec<(String, Rc<MenuTree>)>,
|
||||||
|
/// TODO: move this out of this view.
|
||||||
pub autohide: bool,
|
pub autohide: bool,
|
||||||
pub focus: usize,
|
focus: usize,
|
||||||
|
|
||||||
|
// TODO: make Menubar impl View and take out the State management
|
||||||
state: State,
|
state: State,
|
||||||
}
|
}
|
||||||
|
|
||||||
new_default!(Menubar);
|
new_default!(Menubar);
|
||||||
|
|
||||||
impl Menubar {
|
impl Menubar {
|
||||||
|
/// Creates a new, empty menubar.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Menubar {
|
Menubar {
|
||||||
menus: Vec::new(),
|
menus: Vec::new(),
|
||||||
@ -46,28 +56,41 @@ impl Menubar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Hides the menubar.
|
||||||
fn hide(&mut self) {
|
fn hide(&mut self) {
|
||||||
self.state = State::Inactive;
|
self.state = State::Inactive;
|
||||||
::B::clear();
|
::B::clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Takes the focus.
|
||||||
|
///
|
||||||
|
/// TODO: impl View
|
||||||
pub fn take_focus(&mut self) {
|
pub fn take_focus(&mut self) {
|
||||||
self.state = State::Selected;
|
self.state = State::Selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// True if we should be receiving events.
|
||||||
pub fn receive_events(&self) -> bool {
|
pub fn receive_events(&self) -> bool {
|
||||||
self.state == State::Selected
|
self.state == State::Selected
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if we should be drawn.
|
||||||
pub fn visible(&self) -> bool {
|
pub fn visible(&self) -> bool {
|
||||||
!self.autohide || self.state != State::Inactive
|
!self.autohide || self.state != State::Inactive
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adds a new item to the menubar.
|
||||||
|
///
|
||||||
|
/// The item will use the given title, and on selection, will open a
|
||||||
|
/// popup-menu with the given menu tree.
|
||||||
pub fn add(&mut self, title: &str, menu: MenuTree) -> &mut Self {
|
pub fn add(&mut self, title: &str, menu: MenuTree) -> &mut Self {
|
||||||
self.menus.push((title.to_string(), Rc::new(menu)));
|
self.menus.push((title.to_string(), Rc::new(menu)));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Draws the view.
|
||||||
|
///
|
||||||
|
/// TODO: impl View
|
||||||
pub fn draw(&mut self, printer: &Printer) {
|
pub fn draw(&mut self, printer: &Printer) {
|
||||||
// Draw the bar at the top
|
// Draw the bar at the top
|
||||||
printer.with_color(ColorStyle::Primary, |printer| {
|
printer.with_color(ColorStyle::Primary, |printer| {
|
||||||
@ -88,6 +111,9 @@ impl Menubar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reacts to event.
|
||||||
|
///
|
||||||
|
/// TODO: impl View
|
||||||
pub fn on_event(&mut self, event: Event) -> Option<Callback> {
|
pub fn on_event(&mut self, event: Event) -> Option<Callback> {
|
||||||
match event {
|
match event {
|
||||||
Event::Key(Key::Esc) => self.hide(),
|
Event::Key(Key::Esc) => self.hide(),
|
||||||
@ -133,6 +159,12 @@ impl Menubar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn show_child(s: &mut Cursive, offset: (usize, usize), menu: Rc<MenuTree>) {
|
fn show_child(s: &mut Cursive, offset: (usize, usize), menu: Rc<MenuTree>) {
|
||||||
|
// Adds a new layer located near the item title with the menu popup.
|
||||||
|
// Also adds two key callbacks on this new view, to handle `left` and
|
||||||
|
// `right` key presses.
|
||||||
|
// (If the view itself listens for a `left` or `right` press, it will
|
||||||
|
// consume it before our KeyEventView. This means sub-menus can properly
|
||||||
|
// 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)
|
KeyEventView::new(MenuPopup::new(menu)
|
||||||
@ -142,8 +174,8 @@ fn show_child(s: &mut Cursive, offset: (usize, usize), menu: Rc<MenuTree>) {
|
|||||||
}))
|
}))
|
||||||
.register(Key::Right, |s| {
|
.register(Key::Right, |s| {
|
||||||
s.pop_layer();
|
s.pop_layer();
|
||||||
// Act as if we sent "Left" then "Enter"
|
|
||||||
s.select_menubar();
|
s.select_menubar();
|
||||||
|
// Act as if we sent "Right" then "Down"
|
||||||
s.menubar().on_event(Event::Key(Key::Right));
|
s.menubar().on_event(Event::Key(Key::Right));
|
||||||
if let Some(cb) = s.menubar()
|
if let Some(cb) = s.menubar()
|
||||||
.on_event(Event::Key(Key::Down)) {
|
.on_event(Event::Key(Key::Down)) {
|
||||||
@ -152,8 +184,8 @@ fn show_child(s: &mut Cursive, offset: (usize, usize), menu: Rc<MenuTree>) {
|
|||||||
})
|
})
|
||||||
.register(Key::Left, |s| {
|
.register(Key::Left, |s| {
|
||||||
s.pop_layer();
|
s.pop_layer();
|
||||||
// Act as if we sent "Left" then "Enter"
|
|
||||||
s.select_menubar();
|
s.select_menubar();
|
||||||
|
// Act as if we sent "Left" then "Down"
|
||||||
s.menubar().on_event(Event::Key(Key::Left));
|
s.menubar().on_event(Event::Key(Key::Left));
|
||||||
if let Some(cb) = s.menubar()
|
if let Some(cb) = s.menubar()
|
||||||
.on_event(Event::Key(Key::Down)) {
|
.on_event(Event::Key(Key::Down)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user