mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +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 align;
|
||||
pub mod orientation;
|
||||
pub mod menu;
|
||||
|
||||
// This probably doesn't need to be public?
|
||||
mod menubar;
|
||||
|
||||
mod div;
|
||||
mod utf8;
|
||||
@ -43,9 +47,9 @@ use std::path::Path;
|
||||
use vec::Vec2;
|
||||
use printer::Printer;
|
||||
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.
|
||||
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.
|
||||
pub struct Cursive {
|
||||
theme: theme::Theme,
|
||||
screens: Vec<StackView>,
|
||||
global_callbacks: HashMap<Event, Rc<Callback>>,
|
||||
menu: menubar::Menubar,
|
||||
|
||||
active_screen: ScreenId,
|
||||
|
||||
running: bool,
|
||||
|
||||
global_callbacks: HashMap<Event, Rc<Callback>>,
|
||||
|
||||
theme: theme::Theme,
|
||||
}
|
||||
|
||||
impl Cursive {
|
||||
@ -88,11 +91,12 @@ impl Cursive {
|
||||
ncurses::COLOR_PAIR(theme::ColorPair::Background.ncurses_id()));
|
||||
|
||||
let mut res = Cursive {
|
||||
theme: theme,
|
||||
screens: Vec::new(),
|
||||
global_callbacks: HashMap::new(),
|
||||
menu: menubar::Menubar::new(),
|
||||
active_screen: 0,
|
||||
running: true,
|
||||
global_callbacks: HashMap::new(),
|
||||
theme: theme,
|
||||
};
|
||||
|
||||
res.screens.push(StackView::new());
|
||||
@ -100,6 +104,24 @@ impl Cursive {
|
||||
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
|
||||
pub fn current_theme(&self) -> &theme::Theme {
|
||||
&self.theme
|
||||
@ -150,7 +172,8 @@ impl Cursive {
|
||||
/// Sets the active screen. Panics if no such screen exist.
|
||||
pub fn set_screen(&mut self, screen_id: ScreenId) {
|
||||
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,
|
||||
self.screens.len());
|
||||
}
|
||||
@ -222,8 +245,28 @@ impl Cursive {
|
||||
}
|
||||
|
||||
fn draw(&mut self) {
|
||||
// TODO: don't clone the theme
|
||||
// Reference it or something
|
||||
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();
|
||||
}
|
||||
|
||||
@ -232,13 +275,16 @@ impl Cursive {
|
||||
|
||||
// Is it a UTF-8 starting point?
|
||||
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 {
|
||||
Event::KeyEvent(Key::from_ncurses(ch))
|
||||
}
|
||||
}
|
||||
|
||||
/// Runs the event loop.
|
||||
///
|
||||
/// It will wait for user input (key presses) and trigger callbacks accordingly.
|
||||
/// Blocks until quit() is called.
|
||||
pub fn run(&mut self) {
|
||||
@ -259,6 +305,16 @@ impl Cursive {
|
||||
// (If set_fps was called, this returns -1 now and then)
|
||||
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) {
|
||||
// If the event was ignored, it is our turn to play with it.
|
||||
EventResult::Ignored => self.on_event(event),
|
||||
@ -267,6 +323,7 @@ impl Cursive {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Stops the event loop.
|
||||
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