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