Make Backend methods not static anymore

This commit is contained in:
Alexandre Bury 2016-09-24 16:51:42 -07:00
parent 2e06dd70cb
commit fa2ad3261b
5 changed files with 50 additions and 48 deletions

View File

@ -8,7 +8,7 @@ use ncurses;
pub struct NcursesBackend;
impl backend::Backend for NcursesBackend {
fn init() {
fn init() -> Self {
::std::env::set_var("ESCDELAY", "25");
ncurses::setlocale(ncurses::LcCategory::all, "");
ncurses::initscr();
@ -19,25 +19,27 @@ impl backend::Backend for NcursesBackend {
ncurses::curs_set(ncurses::CURSOR_VISIBILITY::CURSOR_INVISIBLE);
ncurses::wbkgd(unsafe { ncurses::stdscr },
ncurses::COLOR_PAIR(ColorStyle::Background.id()));
NcursesBackend
}
fn screen_size() -> (usize, usize) {
fn screen_size(&self) -> (usize, usize) {
let mut x: i32 = 0;
let mut y: i32 = 0;
ncurses::getmaxyx(unsafe { ncurses::stdscr }, &mut y, &mut x);
(x as usize, y as usize)
}
fn has_colors() -> bool {
fn has_colors(&self) -> bool {
ncurses::has_colors()
}
fn finish() {
fn finish(&mut self) {
ncurses::endwin();
}
fn init_color_style(style: ColorStyle, foreground: &Color,
fn init_color_style(&mut self, style: ColorStyle, foreground: &Color,
background: &Color) {
// TODO: build the color on the spot
@ -46,7 +48,7 @@ impl backend::Backend for NcursesBackend {
find_closest(background) as i16);
}
fn with_color<F: FnOnce()>(color: ColorStyle, f: F) {
fn with_color<F: FnOnce()>(&self, color: ColorStyle, f: F) {
let mut current_style: ncurses::attr_t = 0;
let mut current_color: i16 = 0;
ncurses::attr_get(&mut current_style, &mut current_color);
@ -58,7 +60,7 @@ impl backend::Backend for NcursesBackend {
ncurses::attron(current_style);
}
fn with_effect<F: FnOnce()>(effect: Effect, f: F) {
fn with_effect<F: FnOnce()>(&self, effect: Effect, f: F) {
let style = match effect {
Effect::Reverse => ncurses::A_REVERSE(),
Effect::Simple => ncurses::A_NORMAL(),
@ -72,15 +74,15 @@ impl backend::Backend for NcursesBackend {
ncurses::clear();
}
fn refresh() {
fn refresh(&self) {
ncurses::refresh();
}
fn print_at((x, y): (usize, usize), text: &str) {
fn print_at(&self, (x, y): (usize, usize), text: &str) {
ncurses::mvaddstr(y as i32, x as i32, text);
}
fn poll_event() -> Event {
fn poll_event(&self) -> Event {
let ch: i32 = ncurses::getch();
// Is it a UTF-8 starting point?
@ -92,7 +94,7 @@ impl backend::Backend for NcursesBackend {
}
}
fn set_refresh_rate(fps: u32) {
fn set_refresh_rate(&mut self, fps: u32) {
if fps == 0 {
ncurses::timeout(-1);
} else {

View File

@ -7,23 +7,23 @@ mod curses;
pub use self::curses::NcursesBackend;
pub trait Backend {
fn init();
fn finish();
fn init() -> Self;
fn finish(&mut self);
fn clear();
fn refresh();
fn refresh(&self);
fn has_colors() -> bool;
fn has_colors(&self) -> bool;
fn init_color_style(style: theme::ColorStyle, foreground: &theme::Color,
background: &theme::Color);
fn init_color_style(&mut self, style: theme::ColorStyle,
foreground: &theme::Color, background: &theme::Color);
fn print_at((usize, usize), &str);
fn print_at(&self, (usize, usize), &str);
fn poll_event() -> event::Event;
fn set_refresh_rate(fps: u32);
fn screen_size() -> (usize, usize);
fn poll_event(&self) -> event::Event;
fn set_refresh_rate(&mut self, fps: u32);
fn screen_size(&self) -> (usize, usize);
fn with_color<F: FnOnce()>(color: theme::ColorStyle, f: F);
fn with_effect<F: FnOnce()>(effect: theme::Effect, f: F);
fn with_color<F: FnOnce()>(&self, color: theme::ColorStyle, f: F);
fn with_effect<F: FnOnce()>(&self, effect: theme::Effect, f: F);
}

View File

@ -149,10 +149,10 @@ impl Cursive {
/// Creates a new Cursive root, and initialize ncurses.
pub fn new() -> Self {
// Default delay is way too long. 25 is imperceptible yet works fine.
B::init();
let mut backend = B::init();
let theme = theme::load_default();
theme.activate();
theme.activate(&mut backend);
// let theme = theme::load_theme("assets/style.toml").unwrap();
let (tx, rx) = mpsc::channel();
@ -166,7 +166,7 @@ impl Cursive {
running: true,
cb_source: rx,
cb_sink: tx,
backend: NcursesBackend,
backend: backend,
};
res.screens.push(views::StackView::new());
@ -258,7 +258,7 @@ impl Cursive {
/// Sets the current theme.
pub fn set_theme(&mut self, theme: theme::Theme) {
self.theme = theme;
self.theme.activate();
self.theme.activate(&mut self.backend);
B::clear();
}
@ -284,8 +284,8 @@ impl Cursive {
/// Regularly redraws everything, even when no input is given.
/// Between 0 and 1000.
/// Call with fps=0 to disable (default value).
pub fn set_fps(&self, fps: u32) {
B::set_refresh_rate(fps)
pub fn set_fps(&mut self, fps: u32) {
self.backend.set_refresh_rate(fps)
}
/// Returns a reference to the currently active screen.
@ -430,7 +430,7 @@ impl Cursive {
/// Returns the size of the screen, in characters.
pub fn screen_size(&self) -> Vec2 {
let (x, y) = B::screen_size();
let (x, y) = self.backend.screen_size();
Vec2 {
x: x as usize,
@ -472,7 +472,7 @@ impl Cursive {
let id = self.active_screen;
self.screens.get_mut(id).unwrap().draw(&printer);
B::refresh();
self.backend.refresh();
}
/// Runs the event loop.
@ -500,7 +500,7 @@ impl Cursive {
// Wait for next event.
// (If set_fps was called, this returns -1 now and then)
let event = B::poll_event();
let event = self.backend.poll_event();
if event == Event::WindowResize {
B::clear();
}
@ -535,6 +535,6 @@ impl Cursive {
impl Drop for Cursive {
fn drop(&mut self) {
B::finish();
self.backend.finish();
}
}

View File

@ -56,7 +56,7 @@ impl<'a> Printer<'a> {
let text = &text[..prefix_len];
let p = p + self.offset;
B::print_at((p.x, p.y), text);
self.backend.print_at((p.x, p.y), text);
}
/// Prints a vertical line using the given character.
@ -69,7 +69,7 @@ impl<'a> Printer<'a> {
let p = p + self.offset;
for y in 0..len {
B::print_at((p.x, (p.y + y)), c);
self.backend.print_at((p.x, (p.y + y)), c);
}
}
@ -83,7 +83,7 @@ impl<'a> Printer<'a> {
let p = p + self.offset;
for x in 0..len {
B::print_at((p.x + x, p.y), c);
self.backend.print_at((p.x + x, p.y), c);
}
}
@ -105,7 +105,7 @@ impl<'a> Printer<'a> {
pub fn with_color<F>(&self, c: ColorStyle, f: F)
where F: FnOnce(&Printer)
{
B::with_color(c, || f(self));
self.backend.with_color(c, || f(self));
}
/// Same as `with_color`, but apply a ncurses style instead,
@ -115,7 +115,7 @@ impl<'a> Printer<'a> {
pub fn with_effect<F>(&self, effect: Effect, f: F)
where F: FnOnce(&Printer)
{
B::with_effect(effect, || f(self));
self.backend.with_effect(effect, || f(self));
}
/// Prints a rectangular box.

View File

@ -230,33 +230,33 @@ impl Theme {
/// **Don't use this directly.** Uses [`Cursive::set_theme`] instead.
///
/// [`Cursive::set_theme`]: ../struct.Cursive.html#method.set_theme
pub fn activate(&self) {
pub fn activate(&self, backend: &mut B) {
// Initialize each color with the backend
B::init_color_style(ColorStyle::Background,
backend.init_color_style(ColorStyle::Background,
&self.colors.view,
&self.colors.background);
B::init_color_style(ColorStyle::Shadow,
backend.init_color_style(ColorStyle::Shadow,
&self.colors.shadow,
&self.colors.shadow);
B::init_color_style(ColorStyle::Primary,
backend.init_color_style(ColorStyle::Primary,
&self.colors.primary,
&self.colors.view);
B::init_color_style(ColorStyle::Secondary,
backend.init_color_style(ColorStyle::Secondary,
&self.colors.secondary,
&self.colors.view);
B::init_color_style(ColorStyle::Tertiary,
backend.init_color_style(ColorStyle::Tertiary,
&self.colors.tertiary,
&self.colors.view);
B::init_color_style(ColorStyle::TitlePrimary,
backend.init_color_style(ColorStyle::TitlePrimary,
&self.colors.title_primary,
&self.colors.view);
B::init_color_style(ColorStyle::TitleSecondary,
backend.init_color_style(ColorStyle::TitleSecondary,
&self.colors.title_secondary,
&self.colors.view);
B::init_color_style(ColorStyle::Highlight,
backend.init_color_style(ColorStyle::Highlight,
&self.colors.view,
&self.colors.highlight);
B::init_color_style(ColorStyle::HighlightInactive,
backend.init_color_style(ColorStyle::HighlightInactive,
&self.colors.view,
&self.colors.highlight_inactive);
}