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

View File

@ -7,23 +7,23 @@ mod curses;
pub use self::curses::NcursesBackend; pub use self::curses::NcursesBackend;
pub trait Backend { pub trait Backend {
fn init(); fn init() -> Self;
fn finish(); fn finish(&mut self);
fn clear(); 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, fn init_color_style(&mut self, style: theme::ColorStyle,
background: &theme::Color); 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 poll_event(&self) -> event::Event;
fn set_refresh_rate(fps: u32); fn set_refresh_rate(&mut self, fps: u32);
fn screen_size() -> (usize, usize); fn screen_size(&self) -> (usize, usize);
fn with_color<F: FnOnce()>(color: theme::ColorStyle, f: F); fn with_color<F: FnOnce()>(&self, color: theme::ColorStyle, f: F);
fn with_effect<F: FnOnce()>(effect: theme::Effect, 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. /// Creates a new Cursive root, and initialize ncurses.
pub fn new() -> Self { pub fn new() -> Self {
// Default delay is way too long. 25 is imperceptible yet works fine. // Default delay is way too long. 25 is imperceptible yet works fine.
B::init(); let mut backend = B::init();
let theme = theme::load_default(); let theme = theme::load_default();
theme.activate(); theme.activate(&mut backend);
// let theme = theme::load_theme("assets/style.toml").unwrap(); // let theme = theme::load_theme("assets/style.toml").unwrap();
let (tx, rx) = mpsc::channel(); let (tx, rx) = mpsc::channel();
@ -166,7 +166,7 @@ impl Cursive {
running: true, running: true,
cb_source: rx, cb_source: rx,
cb_sink: tx, cb_sink: tx,
backend: NcursesBackend, backend: backend,
}; };
res.screens.push(views::StackView::new()); res.screens.push(views::StackView::new());
@ -258,7 +258,7 @@ impl Cursive {
/// Sets the current theme. /// Sets the current theme.
pub fn set_theme(&mut self, theme: theme::Theme) { pub fn set_theme(&mut self, theme: theme::Theme) {
self.theme = theme; self.theme = theme;
self.theme.activate(); self.theme.activate(&mut self.backend);
B::clear(); B::clear();
} }
@ -284,8 +284,8 @@ impl Cursive {
/// Regularly redraws everything, even when no input is given. /// Regularly redraws everything, even when no input is given.
/// Between 0 and 1000. /// Between 0 and 1000.
/// Call with fps=0 to disable (default value). /// Call with fps=0 to disable (default value).
pub fn set_fps(&self, fps: u32) { pub fn set_fps(&mut self, fps: u32) {
B::set_refresh_rate(fps) self.backend.set_refresh_rate(fps)
} }
/// Returns a reference to the currently active screen. /// Returns a reference to the currently active screen.
@ -430,7 +430,7 @@ impl Cursive {
/// Returns the size of the screen, in characters. /// Returns the size of the screen, in characters.
pub fn screen_size(&self) -> Vec2 { pub fn screen_size(&self) -> Vec2 {
let (x, y) = B::screen_size(); let (x, y) = self.backend.screen_size();
Vec2 { Vec2 {
x: x as usize, x: x as usize,
@ -472,7 +472,7 @@ impl Cursive {
let id = self.active_screen; let id = self.active_screen;
self.screens.get_mut(id).unwrap().draw(&printer); self.screens.get_mut(id).unwrap().draw(&printer);
B::refresh(); self.backend.refresh();
} }
/// Runs the event loop. /// Runs the event loop.
@ -500,7 +500,7 @@ impl Cursive {
// Wait for next event. // Wait for next event.
// (If set_fps was called, this returns -1 now and then) // (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 { if event == Event::WindowResize {
B::clear(); B::clear();
} }
@ -535,6 +535,6 @@ impl Cursive {
impl Drop for Cursive { impl Drop for Cursive {
fn drop(&mut self) { 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 text = &text[..prefix_len];
let p = p + self.offset; 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. /// Prints a vertical line using the given character.
@ -69,7 +69,7 @@ impl<'a> Printer<'a> {
let p = p + self.offset; let p = p + self.offset;
for y in 0..len { 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; let p = p + self.offset;
for x in 0..len { 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) pub fn with_color<F>(&self, c: ColorStyle, f: F)
where F: FnOnce(&Printer) 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, /// 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) pub fn with_effect<F>(&self, effect: Effect, f: F)
where F: FnOnce(&Printer) where F: FnOnce(&Printer)
{ {
B::with_effect(effect, || f(self)); self.backend.with_effect(effect, || f(self));
} }
/// Prints a rectangular box. /// Prints a rectangular box.

View File

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