mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Add Backend::print_at_rep and make Printer::print_hline use it. (#326)
* Add Backend::print_at_rep and make Printer::print_hline use it. This avoids a string allocation in `print_hline` and makes it faster, presumably for all backends. This speeds up the rendering of the background in StackView. * Fix a bug in how Printer::print_hline computes the repetition count.
This commit is contained in:
parent
4b5a7867e3
commit
ea7b5dbae2
@ -17,6 +17,7 @@ use crate::backend;
|
||||
use crate::event::{Event, Key, MouseButton, MouseEvent};
|
||||
use crate::theme::{BaseColor, Color, ColorPair, Effect};
|
||||
use crate::vec::Vec2;
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
|
||||
enum ColorRole {
|
||||
Foreground,
|
||||
|
@ -373,6 +373,17 @@ impl backend::Backend for Backend {
|
||||
fn print_at(&self, pos: Vec2, text: &str) {
|
||||
ncurses::mvaddstr(pos.y as i32, pos.x as i32, text);
|
||||
}
|
||||
|
||||
fn print_at_rep(&self, pos: Vec2, repetitions: usize, text: &str) {
|
||||
if repetitions > 0 {
|
||||
ncurses::mvaddstr(pos.y as i32, pos.x as i32, text);
|
||||
let mut dupes_left = repetitions - 1;
|
||||
while dupes_left > 0 {
|
||||
ncurses::addstr(text);
|
||||
dupes_left -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the Key enum corresponding to the given ncurses event.
|
||||
|
@ -417,6 +417,17 @@ impl backend::Backend for Backend {
|
||||
self.window.mvaddstr(pos.y as i32, pos.x as i32, text);
|
||||
}
|
||||
|
||||
fn print_at_rep(&self, pos: Vec2, repetitions: usize, text: &str) {
|
||||
if repetitions > 0 {
|
||||
self.window.mvaddstr(pos.y as i32, pos.x as i32, text);
|
||||
let mut dupes_left = repetitions - 1;
|
||||
while dupes_left > 0 {
|
||||
self.window.addstr(text);
|
||||
dupes_left -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn poll_event(&mut self) -> Option<Event> {
|
||||
self.parse_next()
|
||||
}
|
||||
|
@ -38,6 +38,8 @@ impl backend::Backend for Backend {
|
||||
|
||||
fn print_at(&self, _: Vec2, _: &str) {}
|
||||
|
||||
fn print_at_rep(&self, _pos: Vec2, _repetitions: usize, _text: &str) {}
|
||||
|
||||
fn clear(&self, _: theme::Color) {}
|
||||
|
||||
// This sets the Colours and returns the previous colours
|
||||
|
@ -10,6 +10,7 @@
|
||||
use crate::event::Event;
|
||||
use crate::theme;
|
||||
use crate::vec::Vec2;
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
|
||||
#[cfg(unix)]
|
||||
mod resize;
|
||||
@ -64,6 +65,24 @@ pub trait Backend {
|
||||
/// Main method used for printing
|
||||
fn print_at(&self, pos: Vec2, text: &str);
|
||||
|
||||
/// First positions the cursor, similar to `print_at`, and then prints the given number of
|
||||
/// `repetitions` of `text`.
|
||||
fn print_at_rep(&self, pos: Vec2, repetitions: usize, text: &str) {
|
||||
if repetitions > 0 {
|
||||
self.print_at(pos, text);
|
||||
|
||||
let width = text.width();
|
||||
let mut pos = pos;
|
||||
let mut dupes_left = repetitions - 1;
|
||||
|
||||
while dupes_left > 0 {
|
||||
pos = pos.saturating_add((width, 0));
|
||||
self.print_at(pos, text);
|
||||
dupes_left -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Clears the screen with the given color.
|
||||
fn clear(&self, color: theme::Color);
|
||||
|
||||
|
@ -268,6 +268,24 @@ impl backend::Backend for Backend {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn print_at_rep(&self, pos: Vec2, repetitions: usize, text: &str) {
|
||||
if repetitions > 0 {
|
||||
let mut out = self.terminal.borrow_mut();
|
||||
write!(
|
||||
out,
|
||||
"{}{}",
|
||||
termion::cursor::Goto(1 + pos.x as u16, 1 + pos.y as u16),
|
||||
text
|
||||
).unwrap();
|
||||
|
||||
let mut dupes_left = repetitions - 1;
|
||||
while dupes_left > 0 {
|
||||
write!(out, "{}", text).unwrap();
|
||||
dupes_left -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn poll_event(&mut self) -> Option<Event> {
|
||||
let event = select! {
|
||||
recv(self.input_receiver) -> event => event.ok(),
|
||||
|
@ -255,13 +255,10 @@ impl<'a, 'b> Printer<'a, 'b> {
|
||||
let start = start - self.content_offset;
|
||||
|
||||
// Don't write too much if we're close to the end
|
||||
let width = min(width, (self.output_size.x - start.x) / c.width());
|
||||
|
||||
// Could we avoid allocating?
|
||||
let text: String = ::std::iter::repeat(c).take(width).collect();
|
||||
let repetitions = min(width, self.output_size.x - start.x) / c.width();
|
||||
|
||||
let start = start + self.offset;
|
||||
self.backend.print_at(start, &text);
|
||||
self.backend.print_at_rep(start, repetitions, c);
|
||||
}
|
||||
|
||||
/// Call the given closure with a colored printer,
|
||||
|
Loading…
Reference in New Issue
Block a user