mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Making backend::Backend
into a std::Box
able trait (#229)
* Making Backend into a Boxable Trait * Fixed up some typos in the previous and modified some of the docs so they still compile. * Minor Changes requested by @gyscos * Whoops
This commit is contained in:
parent
8c64ea0101
commit
76d340f11d
@ -145,7 +145,7 @@ impl Concrete {
|
||||
}
|
||||
|
||||
impl backend::Backend for Concrete {
|
||||
fn init() -> Self {
|
||||
fn init() -> Box<Self> {
|
||||
terminal::open("Cursive", 80, 24);
|
||||
terminal::set(terminal::config::Window::empty().resizeable(true));
|
||||
terminal::set(vec![
|
||||
@ -159,37 +159,59 @@ impl backend::Backend for Concrete {
|
||||
},
|
||||
]);
|
||||
|
||||
Concrete {
|
||||
let c = Concrete {
|
||||
mouse_position: Vec2::zero(),
|
||||
buttons_pressed: HashSet::new(),
|
||||
}
|
||||
};
|
||||
|
||||
Box::new(c)
|
||||
}
|
||||
|
||||
fn finish(&mut self) {
|
||||
terminal::close();
|
||||
}
|
||||
|
||||
fn with_color<F: FnOnce()>(&self, color: ColorPair, f: F) {
|
||||
fn set_color(&self, color: ColorPair) -> ColorPair {
|
||||
let current = ColorPair {
|
||||
front: blt_colour_to_colour(state::foreground()),
|
||||
back: blt_colour_to_colour(state::background())
|
||||
};
|
||||
|
||||
let fg = colour_to_blt_colour(color.front, ColorRole::Foreground);
|
||||
let bg = colour_to_blt_colour(color.back, ColorRole::Background);
|
||||
terminal::with_colors(fg, bg, f);
|
||||
|
||||
terminal::set_colors(fg, bg);
|
||||
|
||||
current
|
||||
}
|
||||
|
||||
fn with_effect<F: FnOnce()>(&self, effect: Effect, f: F) {
|
||||
fn set_effect(&self, effect: Effect) {
|
||||
match effect {
|
||||
// TODO: does BLT support bold/italic/underline?
|
||||
Effect::Bold
|
||||
| Effect::Italic
|
||||
| Effect::Underline
|
||||
| Effect::Simple => f(),
|
||||
| Effect::Simple => {},
|
||||
// TODO: how to do this correctly?`
|
||||
// BLT itself doesn't do this kind of thing,
|
||||
// we'd need the colours in our position,
|
||||
// but `f()` can do whatever
|
||||
Effect::Reverse => terminal::with_colors(
|
||||
BltColor::from_rgb(0, 0, 0),
|
||||
BltColor::from_rgb(255, 255, 255),
|
||||
f,
|
||||
Effect::Reverse => terminal::set_colors(
|
||||
state::background(), state::foreground()
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn unset_effect(&self, effect: Effect) {
|
||||
match effect {
|
||||
// TODO: does BLT support bold/italic/underline?
|
||||
Effect::Bold
|
||||
| Effect::Italic
|
||||
| Effect::Underline
|
||||
| Effect::Simple => {},
|
||||
// The process of reversing is the same as unreversing
|
||||
Effect::Reverse => terminal::set_colors(
|
||||
state::background(), state::foreground()
|
||||
),
|
||||
}
|
||||
}
|
||||
@ -282,6 +304,10 @@ impl backend::Backend for Concrete {
|
||||
}
|
||||
}
|
||||
|
||||
fn blt_colour_to_colour(c: BltColor) -> Color {
|
||||
Color::Rgb(c.red, c.green, c.blue)
|
||||
}
|
||||
|
||||
fn colour_to_blt_colour(clr: Color, role: ColorRole) -> BltColor {
|
||||
let (r, g, b) = match clr {
|
||||
Color::TerminalDefault => {
|
||||
|
@ -150,7 +150,7 @@ impl Concrete {
|
||||
}
|
||||
|
||||
impl backend::Backend for Concrete {
|
||||
fn init() -> Self {
|
||||
fn init() -> Box<Self> {
|
||||
// Change the locale.
|
||||
// For some reasons it's mandatory to get some UTF-8 support.
|
||||
ncurses::setlocale(ncurses::LcCategory::all, "");
|
||||
@ -186,7 +186,7 @@ impl backend::Backend for Concrete {
|
||||
print!("\x1B[?1002h");
|
||||
stdout().flush().expect("could not flush stdout");
|
||||
|
||||
Concrete {
|
||||
let c = Concrete {
|
||||
current_style: Cell::new(ColorPair::from_256colors(0, 0)),
|
||||
pairs: RefCell::new(HashMap::new()),
|
||||
|
||||
@ -194,7 +194,9 @@ impl backend::Backend for Concrete {
|
||||
event_queue: Vec::new(),
|
||||
|
||||
key_codes: initialize_keymap(),
|
||||
}
|
||||
};
|
||||
|
||||
Box::new(c)
|
||||
}
|
||||
|
||||
fn screen_size(&self) -> (usize, usize) {
|
||||
@ -214,21 +216,16 @@ impl backend::Backend for Concrete {
|
||||
ncurses::endwin();
|
||||
}
|
||||
|
||||
fn with_color<F: FnOnce()>(&self, colors: ColorPair, f: F) {
|
||||
fn set_color(&self, colors: ColorPair) -> ColorPair {
|
||||
// eprintln!("Color used: {:?}", colors);
|
||||
let current = self.current_style.get();
|
||||
if current != colors {
|
||||
self.set_colors(colors);
|
||||
}
|
||||
|
||||
f();
|
||||
|
||||
if current != colors {
|
||||
self.set_colors(current);
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
fn with_effect<F: FnOnce()>(&self, effect: Effect, f: F) {
|
||||
fn set_effect(&self, effect: Effect) {
|
||||
let style = match effect {
|
||||
Effect::Reverse => ncurses::A_REVERSE(),
|
||||
Effect::Simple => ncurses::A_NORMAL(),
|
||||
@ -237,7 +234,16 @@ impl backend::Backend for Concrete {
|
||||
Effect::Underline => ncurses::A_UNDERLINE(),
|
||||
};
|
||||
ncurses::attron(style);
|
||||
f();
|
||||
}
|
||||
|
||||
fn unset_effect(&self, effect: Effect) {
|
||||
let style = match effect {
|
||||
Effect::Reverse => ncurses::A_REVERSE(),
|
||||
Effect::Simple => ncurses::A_NORMAL(),
|
||||
Effect::Bold => ncurses::A_BOLD(),
|
||||
Effect::Italic => ncurses::A_ITALIC(),
|
||||
Effect::Underline => ncurses::A_UNDERLINE(),
|
||||
};
|
||||
ncurses::attroff(style);
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,7 @@ impl Concrete {
|
||||
}
|
||||
|
||||
impl backend::Backend for Concrete {
|
||||
fn init() -> Self {
|
||||
fn init() -> Box<Self> {
|
||||
::std::env::set_var("ESCDELAY", "25");
|
||||
|
||||
let window = pancurses::initscr();
|
||||
@ -155,14 +155,16 @@ impl backend::Backend for Concrete {
|
||||
print!("\x1B[?1002h");
|
||||
stdout().flush().expect("could not flush stdout");
|
||||
|
||||
Concrete {
|
||||
let c = Concrete {
|
||||
current_style: Cell::new(ColorPair::from_256colors(0, 0)),
|
||||
pairs: RefCell::new(HashMap::new()),
|
||||
window: window,
|
||||
last_mouse_button: None,
|
||||
event_queue: Vec::new(),
|
||||
key_codes: initialize_keymap(),
|
||||
}
|
||||
};
|
||||
|
||||
Box::new(c)
|
||||
}
|
||||
|
||||
fn screen_size(&self) -> (usize, usize) {
|
||||
@ -180,21 +182,17 @@ impl backend::Backend for Concrete {
|
||||
pancurses::endwin();
|
||||
}
|
||||
|
||||
fn with_color<F: FnOnce()>(&self, colors: ColorPair, f: F) {
|
||||
fn set_color(&self, colors: ColorPair) -> ColorPair {
|
||||
let current = self.current_style.get();
|
||||
|
||||
if current != colors {
|
||||
self.set_colors(colors);
|
||||
}
|
||||
|
||||
f();
|
||||
|
||||
if current != colors {
|
||||
self.set_colors(current);
|
||||
}
|
||||
current
|
||||
}
|
||||
|
||||
fn with_effect<F: FnOnce()>(&self, effect: Effect, f: F) {
|
||||
fn set_effect(&self, effect: Effect) {
|
||||
let style = match effect {
|
||||
Effect::Simple => pancurses::Attribute::Normal,
|
||||
Effect::Reverse => pancurses::Attribute::Reverse,
|
||||
@ -203,7 +201,16 @@ impl backend::Backend for Concrete {
|
||||
Effect::Underline => pancurses::Attribute::Underline,
|
||||
};
|
||||
self.window.attron(style);
|
||||
f();
|
||||
}
|
||||
|
||||
fn unset_effect(&self, effect: Effect) {
|
||||
let style = match effect {
|
||||
Effect::Simple => pancurses::Attribute::Normal,
|
||||
Effect::Reverse => pancurses::Attribute::Reverse,
|
||||
Effect::Bold => pancurses::Attribute::Bold,
|
||||
Effect::Italic => pancurses::Attribute::Italic,
|
||||
Effect::Underline => pancurses::Attribute::Underline,
|
||||
};
|
||||
self.window.attroff(style);
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ pub use self::curses::*;
|
||||
pub use self::termion::*;
|
||||
|
||||
pub trait Backend {
|
||||
fn init() -> Self;
|
||||
fn init() -> Box<Self> where Self: Sized;
|
||||
// TODO: take `self` by value?
|
||||
// Or implement Drop?
|
||||
fn finish(&mut self);
|
||||
@ -34,7 +34,11 @@ pub trait Backend {
|
||||
fn clear(&self, color: theme::Color);
|
||||
|
||||
fn set_refresh_rate(&mut self, fps: u32);
|
||||
// TODO: unify those into a single method?
|
||||
fn with_color<F: FnOnce()>(&self, colors: theme::ColorPair, f: F);
|
||||
fn with_effect<F: FnOnce()>(&self, effect: theme::Effect, f: F);
|
||||
|
||||
// This sets the Colours and returns the previous colours
|
||||
// to allow you to set them back when you're done.
|
||||
fn set_color(&self, colors: theme::ColorPair) -> theme::ColorPair;
|
||||
|
||||
fn set_effect(&self, effect: theme::Effect);
|
||||
fn unset_effect(&self, effect: theme::Effect);
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ impl Concrete {
|
||||
}
|
||||
|
||||
impl backend::Backend for Concrete {
|
||||
fn init() -> Self {
|
||||
fn init() -> Box<Self> {
|
||||
print!("{}", termion::cursor::Hide);
|
||||
|
||||
let resize = chan_signal::notify(&[chan_signal::Signal::WINCH]);
|
||||
@ -157,14 +157,16 @@ impl backend::Backend for Concrete {
|
||||
}
|
||||
});
|
||||
|
||||
Concrete {
|
||||
let c = Concrete {
|
||||
terminal: terminal,
|
||||
current_style: Cell::new(theme::ColorPair::from_256colors(0, 0)),
|
||||
input: receiver,
|
||||
resize: resize,
|
||||
timeout: None,
|
||||
last_button: None,
|
||||
}
|
||||
};
|
||||
|
||||
Box::new(c)
|
||||
}
|
||||
|
||||
fn finish(&mut self) {
|
||||
@ -177,7 +179,7 @@ impl backend::Backend for Concrete {
|
||||
);
|
||||
}
|
||||
|
||||
fn with_color<F: FnOnce()>(&self, color: theme::ColorPair, f: F) {
|
||||
fn set_color(&self, color: theme::ColorPair) -> theme::ColorPair {
|
||||
let current_style = self.current_style.get();
|
||||
|
||||
if current_style != color {
|
||||
@ -185,17 +187,14 @@ impl backend::Backend for Concrete {
|
||||
self.current_style.set(color);
|
||||
}
|
||||
|
||||
f();
|
||||
|
||||
if current_style != color {
|
||||
self.current_style.set(current_style);
|
||||
self.apply_colors(current_style);
|
||||
}
|
||||
return current_style;
|
||||
}
|
||||
|
||||
fn with_effect<F: FnOnce()>(&self, effect: theme::Effect, f: F) {
|
||||
fn set_effect(&self, effect: theme::Effect) {
|
||||
effect.on();
|
||||
f();
|
||||
}
|
||||
|
||||
fn unset_effect(&self, effect: theme::Effect) {
|
||||
effect.off();
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ pub struct Cursive {
|
||||
|
||||
running: bool,
|
||||
|
||||
backend: backend::Concrete,
|
||||
backend: Box<backend::Backend>,
|
||||
|
||||
cb_source: mpsc::Receiver<Box<CbFunc>>,
|
||||
cb_sink: mpsc::Sender<Box<CbFunc>>,
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Makes drawing on ncurses windows easier.
|
||||
|
||||
use backend::{self, Backend};
|
||||
use backend::Backend;
|
||||
use enumset::EnumSet;
|
||||
use std::cell::Cell;
|
||||
use std::cmp::min;
|
||||
@ -24,7 +24,7 @@ pub struct Printer<'a> {
|
||||
/// `true` if nothing has been drawn yet.
|
||||
new: Rc<Cell<bool>>,
|
||||
/// Backend used to actually draw things
|
||||
backend: &'a backend::Concrete,
|
||||
backend: &'a Box<Backend>,
|
||||
}
|
||||
|
||||
impl<'a> Printer<'a> {
|
||||
@ -33,7 +33,7 @@ impl<'a> Printer<'a> {
|
||||
/// But nobody needs to know that.
|
||||
#[doc(hidden)]
|
||||
pub fn new<T: Into<Vec2>>(
|
||||
size: T, theme: &'a Theme, backend: &'a backend::Concrete
|
||||
size: T, theme: &'a Theme, backend: &'a Box<Backend>
|
||||
) -> Self {
|
||||
Printer {
|
||||
offset: Vec2::zero(),
|
||||
@ -121,7 +121,7 @@ impl<'a> Printer<'a> {
|
||||
/// # use cursive::Printer;
|
||||
/// # use cursive::theme;
|
||||
/// # use cursive::backend::{self, Backend};
|
||||
/// # let b = backend::Concrete::init();
|
||||
/// # let b: Box<Backend> = backend::Concrete::init();
|
||||
/// # let t = theme::load_default();
|
||||
/// # let printer = Printer::new((6,4), &t, &b);
|
||||
/// printer.with_color(theme::ColorStyle::highlight(), |printer| {
|
||||
@ -132,8 +132,9 @@ impl<'a> Printer<'a> {
|
||||
where
|
||||
F: FnOnce(&Printer),
|
||||
{
|
||||
self.backend
|
||||
.with_color(c.resolve(&self.theme.palette), || f(self));
|
||||
let old = self.backend.set_color(c.resolve(&self.theme.palette));
|
||||
f(self);
|
||||
self.backend.set_color(old);
|
||||
}
|
||||
|
||||
/// Call the given closure with a styled printer,
|
||||
@ -165,7 +166,9 @@ impl<'a> Printer<'a> {
|
||||
where
|
||||
F: FnOnce(&Printer),
|
||||
{
|
||||
self.backend.with_effect(effect, || f(self));
|
||||
self.backend.set_effect(effect);
|
||||
f(self);
|
||||
self.backend.unset_effect(effect);
|
||||
}
|
||||
|
||||
/// Call the given closure with a modified printer
|
||||
@ -196,7 +199,7 @@ impl<'a> Printer<'a> {
|
||||
/// # use cursive::Printer;
|
||||
/// # use cursive::theme;
|
||||
/// # use cursive::backend::{self, Backend};
|
||||
/// # let b = backend::Concrete::init();
|
||||
/// # let b: Box<Backend> = backend::Concrete::init();
|
||||
/// # let t = theme::load_default();
|
||||
/// # let printer = Printer::new((6,4), &t, &b);
|
||||
/// printer.print_box((0,0), (6,4), false);
|
||||
|
@ -232,7 +232,7 @@ impl ScrollBase {
|
||||
/// # use cursive::theme;
|
||||
/// # use cursive::backend::{self, Backend};
|
||||
/// # let scrollbase = ScrollBase::new();
|
||||
/// # let b = backend::Concrete::init();
|
||||
/// # let b: Box<Backend> = backend::Concrete::init();
|
||||
/// # let t = theme::load_default();
|
||||
/// # let printer = Printer::new((5,1), &t, &b);
|
||||
/// # let printer = &printer;
|
||||
|
Loading…
Reference in New Issue
Block a user