mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-24 01:46:31 +00:00
Add base for menubar
Cursive now has a global menubar, with a `select_menubar()` method.
This commit is contained in:
parent
43230534ff
commit
042e631d9f
79
src/lib.rs
79
src/lib.rs
@ -31,6 +31,10 @@ pub mod vec;
|
|||||||
pub mod theme;
|
pub mod theme;
|
||||||
pub mod align;
|
pub mod align;
|
||||||
pub mod orientation;
|
pub mod orientation;
|
||||||
|
pub mod menu;
|
||||||
|
|
||||||
|
// This probably doesn't need to be public?
|
||||||
|
mod menubar;
|
||||||
|
|
||||||
mod div;
|
mod div;
|
||||||
mod utf8;
|
mod utf8;
|
||||||
@ -43,9 +47,9 @@ use std::path::Path;
|
|||||||
use vec::Vec2;
|
use vec::Vec2;
|
||||||
use printer::Printer;
|
use printer::Printer;
|
||||||
use view::View;
|
use view::View;
|
||||||
use view::{StackView, Selector};
|
use view::{Selector, StackView};
|
||||||
|
|
||||||
use event::{Event, ToEvent, Key, EventResult, Callback};
|
use event::{Callback, Event, EventResult, Key, ToEvent};
|
||||||
|
|
||||||
/// Identifies a screen in the cursive ROOT.
|
/// Identifies a screen in the cursive ROOT.
|
||||||
pub type ScreenId = usize;
|
pub type ScreenId = usize;
|
||||||
@ -58,15 +62,14 @@ pub type ScreenId = usize;
|
|||||||
///
|
///
|
||||||
/// It uses a list of screen, with one screen active at a time.
|
/// It uses a list of screen, with one screen active at a time.
|
||||||
pub struct Cursive {
|
pub struct Cursive {
|
||||||
|
theme: theme::Theme,
|
||||||
screens: Vec<StackView>,
|
screens: Vec<StackView>,
|
||||||
|
global_callbacks: HashMap<Event, Rc<Callback>>,
|
||||||
|
menu: menubar::Menubar,
|
||||||
|
|
||||||
active_screen: ScreenId,
|
active_screen: ScreenId,
|
||||||
|
|
||||||
running: bool,
|
running: bool,
|
||||||
|
|
||||||
global_callbacks: HashMap<Event, Rc<Callback>>,
|
|
||||||
|
|
||||||
theme: theme::Theme,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cursive {
|
impl Cursive {
|
||||||
@ -88,11 +91,12 @@ impl Cursive {
|
|||||||
ncurses::COLOR_PAIR(theme::ColorPair::Background.ncurses_id()));
|
ncurses::COLOR_PAIR(theme::ColorPair::Background.ncurses_id()));
|
||||||
|
|
||||||
let mut res = Cursive {
|
let mut res = Cursive {
|
||||||
|
theme: theme,
|
||||||
screens: Vec::new(),
|
screens: Vec::new(),
|
||||||
|
global_callbacks: HashMap::new(),
|
||||||
|
menu: menubar::Menubar::new(),
|
||||||
active_screen: 0,
|
active_screen: 0,
|
||||||
running: true,
|
running: true,
|
||||||
global_callbacks: HashMap::new(),
|
|
||||||
theme: theme,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
res.screens.push(StackView::new());
|
res.screens.push(StackView::new());
|
||||||
@ -100,6 +104,24 @@ impl Cursive {
|
|||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Selects the menubar
|
||||||
|
pub fn select_menu(&mut self) {
|
||||||
|
self.menu.selected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the menubar autohide_menubar feature.
|
||||||
|
///
|
||||||
|
/// * When enabled, the menu is only visible when selected.
|
||||||
|
/// * When disabled, the menu is always visible and reserves the top row.
|
||||||
|
pub fn set_autohide_menu(&mut self, autohide: bool) {
|
||||||
|
self.menu.autohide = autohide;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieve the menu tree used by the menubar.
|
||||||
|
pub fn menu(&mut self) -> &mut menu::MenuTree {
|
||||||
|
&mut self.menu.menu
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the currently used theme
|
/// Returns the currently used theme
|
||||||
pub fn current_theme(&self) -> &theme::Theme {
|
pub fn current_theme(&self) -> &theme::Theme {
|
||||||
&self.theme
|
&self.theme
|
||||||
@ -150,7 +172,8 @@ impl Cursive {
|
|||||||
/// Sets the active screen. Panics if no such screen exist.
|
/// Sets the active screen. Panics if no such screen exist.
|
||||||
pub fn set_screen(&mut self, screen_id: ScreenId) {
|
pub fn set_screen(&mut self, screen_id: ScreenId) {
|
||||||
if screen_id >= self.screens.len() {
|
if screen_id >= self.screens.len() {
|
||||||
panic!("Tried to set an invalid screen ID: {}, but only {} screens present.",
|
panic!("Tried to set an invalid screen ID: {}, but only {} \
|
||||||
|
screens present.",
|
||||||
screen_id,
|
screen_id,
|
||||||
self.screens.len());
|
self.screens.len());
|
||||||
}
|
}
|
||||||
@ -222,8 +245,28 @@ impl Cursive {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn draw(&mut self) {
|
fn draw(&mut self) {
|
||||||
|
// TODO: don't clone the theme
|
||||||
|
// Reference it or something
|
||||||
let printer = Printer::new(self.screen_size(), self.theme.clone());
|
let printer = Printer::new(self.screen_size(), self.theme.clone());
|
||||||
self.screen_mut().draw(&printer);
|
|
||||||
|
// Draw the currently active screen
|
||||||
|
// If the menubar is active, nothing else can be.
|
||||||
|
let offset = if self.menu.autohide {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
let selected = self.menu.selected;
|
||||||
|
self.screen_mut()
|
||||||
|
.draw(&printer.sub_printer(Vec2::new(0, offset),
|
||||||
|
printer.size,
|
||||||
|
!selected));
|
||||||
|
|
||||||
|
// Draw the menubar?
|
||||||
|
if self.menu.selected || !self.menu.autohide {
|
||||||
|
self.menu.draw(&printer);
|
||||||
|
}
|
||||||
|
|
||||||
ncurses::refresh();
|
ncurses::refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,13 +275,16 @@ impl Cursive {
|
|||||||
|
|
||||||
// Is it a UTF-8 starting point?
|
// Is it a UTF-8 starting point?
|
||||||
if 32 <= ch && ch < 0x100 && ch != 127 {
|
if 32 <= ch && ch < 0x100 && ch != 127 {
|
||||||
Event::CharEvent(utf8::read_char(ch as u8, || ncurses::getch() as u8).unwrap())
|
Event::CharEvent(utf8::read_char(ch as u8,
|
||||||
|
|| ncurses::getch() as u8)
|
||||||
|
.unwrap())
|
||||||
} else {
|
} else {
|
||||||
Event::KeyEvent(Key::from_ncurses(ch))
|
Event::KeyEvent(Key::from_ncurses(ch))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Runs the event loop.
|
/// Runs the event loop.
|
||||||
|
///
|
||||||
/// It will wait for user input (key presses) and trigger callbacks accordingly.
|
/// It will wait for user input (key presses) and trigger callbacks accordingly.
|
||||||
/// Blocks until quit() is called.
|
/// Blocks until quit() is called.
|
||||||
pub fn run(&mut self) {
|
pub fn run(&mut self) {
|
||||||
@ -259,6 +305,16 @@ impl Cursive {
|
|||||||
// (If set_fps was called, this returns -1 now and then)
|
// (If set_fps was called, this returns -1 now and then)
|
||||||
let event = Cursive::poll_event();
|
let event = Cursive::poll_event();
|
||||||
|
|
||||||
|
// Event dispatch order:
|
||||||
|
// * Focused element:
|
||||||
|
// * Menubar (if active)
|
||||||
|
// * Current screen (top layer)
|
||||||
|
// * Global callbacks
|
||||||
|
if self.menu.selected {
|
||||||
|
if let Some(cb) = self.menu.on_event(event) {
|
||||||
|
cb(self);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
match self.screen_mut().on_event(event) {
|
match self.screen_mut().on_event(event) {
|
||||||
// If the event was ignored, it is our turn to play with it.
|
// If the event was ignored, it is our turn to play with it.
|
||||||
EventResult::Ignored => self.on_event(event),
|
EventResult::Ignored => self.on_event(event),
|
||||||
@ -267,6 +323,7 @@ impl Cursive {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Stops the event loop.
|
/// Stops the event loop.
|
||||||
pub fn quit(&mut self) {
|
pub fn quit(&mut self) {
|
||||||
|
35
src/menubar.rs
Normal file
35
src/menubar.rs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
use menu::*;
|
||||||
|
use theme::ColorPair;
|
||||||
|
use printer::Printer;
|
||||||
|
use event::*;
|
||||||
|
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
pub struct Menubar {
|
||||||
|
pub menu: MenuTree,
|
||||||
|
pub autohide: bool,
|
||||||
|
pub selected: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Menubar {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Menubar {
|
||||||
|
menu: MenuTree::new(),
|
||||||
|
autohide: true,
|
||||||
|
selected: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw(&mut self, printer: &Printer) {
|
||||||
|
// Draw the bar at the top
|
||||||
|
printer.with_color(ColorPair::Primary, |printer| {
|
||||||
|
printer.print_hline((0, 0), printer.size.x, " ");
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO: draw the rest
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn on_event(&mut self, event: Event) -> Option<Rc<Callback>> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user