Make Backend::clear take &self

This commit is contained in:
Alexandre Bury 2016-10-09 15:47:06 -07:00
parent a3b5ef3bca
commit 44dbd5826e
6 changed files with 49 additions and 10 deletions

View File

@ -70,7 +70,7 @@ impl backend::Backend for NcursesBackend {
ncurses::attroff(style);
}
fn clear() {
fn clear(&self) {
ncurses::clear();
}

View File

@ -10,7 +10,7 @@ pub trait Backend {
fn init() -> Self;
fn finish(&mut self);
fn clear();
fn clear(&self);
fn refresh(&self);
fn has_colors(&self) -> bool;

View File

@ -273,7 +273,14 @@ impl Cursive {
pub fn set_theme(&mut self, theme: theme::Theme) {
self.theme = theme;
self.theme.activate(&mut self.backend);
B::clear();
self.backend.clear();
}
/// Clears the screen.
///
/// If a view becomes smaller, clearing the screen may be necessary.
pub fn clear(&self) {
self.backend.clear();
}
/// Loads a theme from the given file.
@ -516,7 +523,7 @@ impl Cursive {
// (If set_fps was called, this returns -1 now and then)
let event = self.backend.poll_event();
if event == Event::WindowResize {
B::clear();
self.backend.clear();
}
// Event dispatch order:

View File

@ -3,7 +3,9 @@
use B;
use backend::Backend;
use std::cell::Cell;
use std::cmp::min;
use std::rc::Rc;
use theme::{BorderStyle, ColorStyle, Effect, Theme};
use unicode_segmentation::UnicodeSegmentation;
@ -22,6 +24,9 @@ pub struct Printer<'a> {
/// Currently used theme
pub theme: Theme,
/// `true` if nothing has been drawn yet.
new: Rc<Cell<bool>>,
/// Backend used to actually draw things
backend: &'a B,
}
@ -36,14 +41,29 @@ impl<'a> Printer<'a> {
size: size.into(),
focused: true,
theme: theme,
new: Rc::new(Cell::new(true)),
backend: backend,
}
}
/// Clear the screen.
///
/// Careful with this method, it will discard anything drawn before.
pub fn clear(&self) {
self.backend.clear();
}
/// Returns `true` if nothing has been printed yet.
pub fn is_new(&self) -> bool {
self.new.get()
}
// TODO: use &mut self? We don't *need* it, but it may make sense.
// We don't want people to start calling prints in parallel?
/// Prints some text at the given position relative to the window.
pub fn print<S: Into<Vec2>>(&self, pos: S, text: &str) {
self.new.set(false);
let p = pos.into();
if p.y >= self.size.y || p.x >= self.size.x {
return;
@ -61,6 +81,8 @@ impl<'a> Printer<'a> {
/// Prints a vertical line using the given character.
pub fn print_vline<T: Into<Vec2>>(&self, start: T, len: usize, c: &str) {
self.new.set(false);
let p = start.into();
if p.y > self.size.y || p.x > self.size.x {
return;
@ -75,6 +97,8 @@ impl<'a> Printer<'a> {
/// Prints a horizontal line using the given character.
pub fn print_hline<T: Into<Vec2>>(&self, start: T, len: usize, c: &str) {
self.new.set(false);
let p = start.into();
if p.y > self.size.y || p.x > self.size.x {
return;
@ -135,6 +159,8 @@ impl<'a> Printer<'a> {
/// ```
pub fn print_box<T: Into<Vec2>, S: Into<Vec2>>(&self, start: T, size: S,
invert: bool) {
self.new.set(false);
let start = start.into();
let size = size.into();
if size.x < 2 || size.y < 2 {
@ -234,6 +260,7 @@ impl<'a> Printer<'a> {
focused: self.focused && focused,
theme: self.theme.clone(),
backend: self.backend,
new: self.new.clone(),
}
}

View File

@ -1,6 +1,5 @@
use Cursive;
use Printer;
use backend::Backend;
use direction;
use event::*;
use menu::MenuTree;
@ -61,7 +60,6 @@ impl Menubar {
/// Hides the menubar.
fn hide(&mut self) {
self.state = State::Inactive;
::B::clear();
}
/// True if we should be receiving events.
@ -144,7 +142,10 @@ impl View for Menubar {
fn on_event(&mut self, event: Event) -> EventResult {
match event {
Event::Key(Key::Esc) => self.hide(),
Event::Key(Key::Esc) => {
self.hide();
return EventResult::with_cb(|s| s.clear());
}
Event::Key(Key::Left) => {
if self.focus > 0 {
self.focus -= 1

View File

@ -1,5 +1,4 @@
use Printer;
use backend::Backend;
use direction::Direction;
use event::{Event, EventResult};
@ -14,6 +13,7 @@ use views::ShadowView;
pub struct StackView {
layers: Vec<Layer>,
last_size: Vec2,
needs_clear: bool,
}
struct Layer {
@ -32,6 +32,7 @@ impl StackView {
StackView {
layers: Vec::new(),
last_size: Vec2::zero(),
needs_clear: false,
}
}
@ -57,7 +58,7 @@ impl StackView {
/// Remove the top-most layer.
pub fn pop_layer(&mut self) {
self.layers.pop();
::B::clear();
self.needs_clear = true;
}
/// Computes the offset of the current top view.
@ -74,6 +75,9 @@ impl StackView {
impl View for StackView {
fn draw(&self, printer: &Printer) {
if self.needs_clear && printer.is_new() {
printer.clear();
}
let last = self.layers.len();
let mut previous = Vec2::zero();
printer.with_color(ColorStyle::Primary, |printer| {
@ -107,7 +111,7 @@ impl View for StackView {
// Give each guy what he asks for, within the budget constraints.
let size = Vec2::min(size, layer.view.get_min_size(size));
if !layer.size.fits_in(size) {
::B::clear();
self.needs_clear = true;
}
layer.size = size;
layer.view.layout(layer.size);