Remove Printer::is_new

This commit is contained in:
Alexandre Bury 2018-04-17 16:18:59 -07:00
parent a8326aef28
commit b80af07268

View File

@ -1,38 +1,43 @@
//! Makes drawing on ncurses windows easier. //! Provide higher-level abstraction to draw things on backends.
use backend::Backend; use backend::Backend;
use enumset::EnumSet; use enumset::EnumSet;
use std::cell::Cell;
use std::cmp::min; use std::cmp::min;
use std::rc::Rc;
use theme::{BorderStyle, ColorStyle, Effect, PaletteColor, Style, Theme}; use theme::{BorderStyle, ColorStyle, Effect, PaletteColor, Style, Theme};
use unicode_segmentation::UnicodeSegmentation; use unicode_segmentation::UnicodeSegmentation;
use unicode_width::UnicodeWidthStr;
use utils::lines::simple::prefix; use utils::lines::simple::prefix;
use vec::Vec2; use vec::Vec2;
use with::With; use with::With;
/// Convenient interface to draw on a subset of the screen. /// Convenient interface to draw on a subset of the screen.
///
/// The area it can print on is defined by `offset` and `size`.
///
/// The part of the content it will print there is defined by `content_offset`
/// and `size`.
pub struct Printer<'a> { pub struct Printer<'a> {
/// Offset into the window this printer should start drawing at. /// Offset into the window this printer should start drawing at.
///
/// Printing at `x` will really print at `x + offset`.
pub offset: Vec2, pub offset: Vec2,
/// Offset into the view for this printer.
pub content_offset: Vec2,
/// Size of the area we are allowed to draw on. /// Size of the area we are allowed to draw on.
/// ///
/// Anything outside of this should be discarded. /// Anything outside of this should be discarded.
pub size: Vec2, pub size: Vec2,
/// Offset into the view for this printer.
///
/// Printing at `x`, will really print at `x - content_offset`.
pub content_offset: Vec2,
/// Whether the view to draw is currently focused or not. /// Whether the view to draw is currently focused or not.
pub focused: bool, pub focused: bool,
/// Currently used theme /// Currently used theme
pub theme: &'a Theme, pub theme: &'a Theme,
/// `true` if nothing has been drawn yet.
new: Rc<Cell<bool>>,
/// Backend used to actually draw things /// Backend used to actually draw things
backend: &'a Backend, backend: &'a Backend,
} }
@ -46,7 +51,6 @@ impl<'a> Clone for Printer<'a> {
focused: self.focused, focused: self.focused,
theme: self.theme, theme: self.theme,
backend: self.backend, backend: self.backend,
new: Rc::clone(&self.new),
} }
} }
} }
@ -65,7 +69,6 @@ impl<'a> Printer<'a> {
size: size.into(), size: size.into(),
focused: true, focused: true,
theme, theme,
new: Rc::new(Cell::new(true)),
backend, backend,
} }
} }
@ -80,61 +83,52 @@ impl<'a> Printer<'a> {
.clear(self.theme.palette[PaletteColor::Background]); .clear(self.theme.palette[PaletteColor::Background]);
} }
/// 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. // 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? // We don't want people to start calling prints in parallel?
/// Prints some text at the given position relative to the window. /// Prints some text at the given position relative to the window.
pub fn print<S: Into<Vec2>>(&self, pos: S, text: &str) { pub fn print<S: Into<Vec2>>(&self, pos: S, text: &str) {
self.new.set(false); let pos = pos.into();
if !pos.fits_in(self.size) {
let p = pos.into();
if p.y >= self.size.y || p.x >= self.size.x {
return; return;
} }
// Do we have enough room for the entire line? // Do we have enough room for the entire line?
let room = self.size.x - p.x; let room = self.size.x - pos.x;
// Drop the end of the text if it's too long
// We want the number of CHARACTERS, not bytes. // We want the number of CHARACTERS, not bytes.
// (Actually we want the "width" of the string, see unicode-width) // (Actually we want the "width" of the string, see unicode-width)
let prefix_len = prefix(text.graphemes(true), room, "").length; let prefix_len = prefix(text.graphemes(true), room, "").length;
let text = &text[..prefix_len]; let text = &text[..prefix_len];
let p = p + self.offset; let pos = pos + self.offset;
self.backend.print_at(p, text); self.backend.print_at(pos, text);
} }
/// Prints a vertical line using the given character. /// Prints a vertical line using the given character.
pub fn print_vline<T: Into<Vec2>>(&self, start: T, len: usize, c: &str) { pub fn print_vline<T: Into<Vec2>>(&self, start: T, len: usize, c: &str) {
self.new.set(false); let start = start.into();
if !start.fits_in(self.size) {
let p = start.into();
if p.y > self.size.y || p.x > self.size.x {
return; return;
} }
let len = min(len, self.size.y - p.y); let len = min(len, self.size.y - start.y);
let p = p + self.offset; let start = start + self.offset;
for y in 0..len { for y in 0..len {
self.backend.print_at(p + (0,y), c); self.backend.print_at(start + (0,y), c);
} }
} }
/// Prints a horizontal line using the given character. /// Prints a horizontal line using the given character.
pub fn print_hline<T: Into<Vec2>>(&self, start: T, len: usize, c: &str) { pub fn print_hline<T: Into<Vec2>>(&self, start: T, len: usize, c: &str) {
self.new.set(false); let start = start.into();
if !start.fits_in(self.size) {
let p = start.into();
if p.y > self.size.y || p.x > self.size.x {
return; return;
} }
let len = min(len, self.size.x - p.x); let len = min(len, (self.size.x - start.x) / c.width());
let text: String = ::std::iter::repeat(c).take(len).collect(); let text: String = ::std::iter::repeat(c).take(len).collect();
let p = p + self.offset; let start = start + self.offset;
self.backend.print_at(p, &text); self.backend.print_at(start, &text);
} }
/// Call the given closure with a colored printer, /// Call the given closure with a colored printer,
@ -232,8 +226,6 @@ impl<'a> Printer<'a> {
pub fn print_box<T: Into<Vec2>, S: Into<Vec2>>( pub fn print_box<T: Into<Vec2>, S: Into<Vec2>>(
&self, start: T, size: S, invert: bool &self, start: T, size: S, invert: bool
) { ) {
self.new.set(false);
let start = start.into(); let start = start.into();
let size = size.into(); let size = size.into();