2015-05-15 19:16:58 +00:00
|
|
|
//! Makes drawing on ncurses windows easier.
|
|
|
|
|
2015-05-15 18:58:47 +00:00
|
|
|
use ncurses;
|
2015-05-22 06:29:49 +00:00
|
|
|
|
|
|
|
use color;
|
2015-05-18 18:51:30 +00:00
|
|
|
use vec::{Vec2,ToVec2};
|
2015-05-15 18:58:47 +00:00
|
|
|
|
2015-05-23 22:58:06 +00:00
|
|
|
/// Convenient interface to draw on a subset of the screen.
|
2015-05-15 18:58:47 +00:00
|
|
|
pub struct Printer {
|
|
|
|
/// Offset into the window this printer should start drawing at.
|
|
|
|
pub offset: Vec2,
|
|
|
|
/// Size of the area we are allowed to draw on.
|
|
|
|
pub size: Vec2,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Printer {
|
2015-05-22 06:29:49 +00:00
|
|
|
/// Creates a new printer on the given window.
|
2015-05-23 22:58:06 +00:00
|
|
|
pub fn new<T: ToVec2>(size: T) -> Self {
|
2015-05-22 06:29:49 +00:00
|
|
|
Printer {
|
|
|
|
offset: Vec2::zero(),
|
|
|
|
size: size.to_vec2(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-15 18:58:47 +00:00
|
|
|
/// Prints some text at the given position relative to the window.
|
|
|
|
pub fn print<S: ToVec2>(&self, pos: S, text: &str) {
|
2015-05-24 03:12:11 +00:00
|
|
|
let mut p = pos.to_vec2();
|
|
|
|
if p.y >= self.size.y { return; }
|
|
|
|
p = p + self.offset;
|
2015-05-23 22:58:06 +00:00
|
|
|
ncurses::mvprintw(p.y as i32, p.x as i32, text);
|
2015-05-15 18:58:47 +00:00
|
|
|
}
|
|
|
|
|
2015-05-20 17:31:38 +00:00
|
|
|
/// Prints a vertical line using the given character.
|
2015-05-22 06:29:49 +00:00
|
|
|
pub fn print_vline<T: ToVec2>(&self, start: T, len: u32, c: u64) {
|
|
|
|
let p = start.to_vec2() + self.offset;
|
2015-05-23 22:58:06 +00:00
|
|
|
ncurses::mvvline(p.y as i32, p.x as i32, c, len as i32);
|
2015-05-20 17:31:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Prints a horizontal line using the given character.
|
2015-05-22 06:29:49 +00:00
|
|
|
pub fn print_hline<T: ToVec2>(&self, start: T, len: u32, c: u64) {
|
|
|
|
let p = start.to_vec2() + self.offset;
|
2015-05-23 22:58:06 +00:00
|
|
|
ncurses::mvhline(p.y as i32, p.x as i32, c, len as i32);
|
2015-05-22 06:29:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns a wrapper around this printer,
|
|
|
|
/// that will apply the given style on prints.
|
2015-05-23 22:58:06 +00:00
|
|
|
pub fn with_style<'a, F>(&'a self, style: color::ThemeColor, f: F)
|
|
|
|
where F: Fn(&Printer)
|
|
|
|
{
|
|
|
|
ncurses::attron(ncurses::COLOR_PAIR(style));
|
|
|
|
f(self);
|
|
|
|
ncurses::attroff(ncurses::COLOR_PAIR(style));
|
|
|
|
ncurses::attron(ncurses::COLOR_PAIR(color::PRIMARY));
|
2015-05-20 17:31:38 +00:00
|
|
|
}
|
|
|
|
|
2015-05-20 17:36:35 +00:00
|
|
|
/// Prints a rectangular box.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// printer.print_box((0,0), (6,4), '+', '-', '|');
|
|
|
|
/// ```
|
2015-05-22 06:29:49 +00:00
|
|
|
pub fn print_box<T: ToVec2>(&self, start: T, size: T) {
|
2015-05-20 17:31:38 +00:00
|
|
|
let start_v = start.to_vec2();
|
|
|
|
let size_v = size.to_vec2() - (1,1);
|
|
|
|
|
2015-05-22 06:29:49 +00:00
|
|
|
self.print(start_v, "┌");
|
|
|
|
self.print(start_v + size_v.keep_x(), "┐");
|
|
|
|
self.print(start_v + size_v.keep_y(), "└");
|
|
|
|
self.print(start_v + size_v, "┘");
|
|
|
|
|
|
|
|
self.print_hline(start_v + (1,0), size_v.x - 1, ncurses::ACS_HLINE());
|
|
|
|
self.print_vline(start_v + (0,1), size_v.y - 1, ncurses::ACS_VLINE());
|
|
|
|
self.print_hline(start_v + (1,0) + size_v.keep_y(), size_v.x - 1, ncurses::ACS_HLINE());
|
|
|
|
self.print_vline(start_v + (0,1) + size_v.keep_x(), size_v.y - 1, ncurses::ACS_VLINE());
|
2015-05-20 17:31:38 +00:00
|
|
|
}
|
|
|
|
|
2015-05-15 18:58:47 +00:00
|
|
|
/// Returns a printer on a subset of this one's area.
|
|
|
|
pub fn sub_printer<S: ToVec2>(&self, offset: S, size: S) -> Printer {
|
|
|
|
let offset_v = offset.to_vec2();
|
|
|
|
Printer {
|
|
|
|
offset: self.offset + offset_v,
|
|
|
|
// We can't be larger than what remains
|
|
|
|
size: Vec2::min(self.size - offset_v, size.to_vec2()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|