Doing screen buffering to eliminate flicker.
At the moment, it's brain-dead and really slow.
This commit is contained in:
parent
b63bb6f87d
commit
66a80baeed
|
@ -52,6 +52,7 @@ macro_rules! ui_loop {
|
||||||
$term_ui.width = w as usize;
|
$term_ui.width = w as usize;
|
||||||
$term_ui.height = h as usize;
|
$term_ui.height = h as usize;
|
||||||
$term_ui.editor.update_dim($term_ui.height - 1, $term_ui.width);
|
$term_ui.editor.update_dim($term_ui.height - 1, $term_ui.width);
|
||||||
|
$term_ui.screen.resize(w as usize, h as usize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if stop || $term_ui.quit {
|
if stop || $term_ui.quit {
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
|
use std;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
|
use unicode_width::UnicodeWidthStr;
|
||||||
|
use unicode_segmentation::UnicodeSegmentation;
|
||||||
use termion;
|
use termion;
|
||||||
use termion::screen::AlternateScreen;
|
use termion::screen::AlternateScreen;
|
||||||
use termion::color;
|
use termion::color;
|
||||||
|
@ -9,29 +12,81 @@ use termion::raw::{IntoRawMode, RawTerminal};
|
||||||
|
|
||||||
pub(crate) struct Screen {
|
pub(crate) struct Screen {
|
||||||
out: RefCell<AlternateScreen<RawTerminal<io::Stdout>>>,
|
out: RefCell<AlternateScreen<RawTerminal<io::Stdout>>>,
|
||||||
|
buf: RefCell<Vec<Option<String>>>,
|
||||||
|
w: usize,
|
||||||
|
h: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Screen {
|
impl Screen {
|
||||||
pub(crate) fn new() -> Self {
|
pub(crate) fn new() -> Self {
|
||||||
|
let (w, h) = termion::terminal_size().unwrap();
|
||||||
|
let buf = std::iter::repeat(Some(format!(
|
||||||
|
"{}{} ",
|
||||||
|
color::Fg(color::Black),
|
||||||
|
color::Bg(color::Black)
|
||||||
|
))).take(w as usize * h as usize)
|
||||||
|
.collect();
|
||||||
Screen {
|
Screen {
|
||||||
out: RefCell::new(AlternateScreen::from(io::stdout().into_raw_mode().unwrap())),
|
out: RefCell::new(AlternateScreen::from(io::stdout().into_raw_mode().unwrap())),
|
||||||
|
buf: RefCell::new(buf),
|
||||||
|
w: w as usize,
|
||||||
|
h: h as usize,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn clear(&self) {
|
pub(crate) fn clear(&self) {
|
||||||
write!(
|
for cell in self.buf.borrow_mut().iter_mut() {
|
||||||
self.out.borrow_mut(),
|
match *cell {
|
||||||
"{}{}",
|
Some(ref mut text) => {
|
||||||
color::Bg(color::Black),
|
text.clear();
|
||||||
termion::clear::All
|
text.push_str(&format!(
|
||||||
).unwrap();
|
"{}{} ",
|
||||||
|
color::Fg(color::Black),
|
||||||
|
color::Bg(color::Black)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
*cell = Some(format!(
|
||||||
|
"{}{} ",
|
||||||
|
color::Fg(color::Black),
|
||||||
|
color::Bg(color::Black)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn resize(&mut self, w: usize, h: usize) {
|
||||||
|
self.w = w;
|
||||||
|
self.h = h;
|
||||||
|
self.buf.borrow_mut().resize(
|
||||||
|
w * h,
|
||||||
|
Some(format!(
|
||||||
|
"{}{} ",
|
||||||
|
color::Fg(color::Black),
|
||||||
|
color::Bg(color::Black)
|
||||||
|
)),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn present(&self) {
|
pub(crate) fn present(&self) {
|
||||||
|
let buf = self.buf.borrow();
|
||||||
|
for y in 0..self.h {
|
||||||
|
for x in 0..self.w {
|
||||||
|
if let Some(ref cell) = buf[y * self.w + x] {
|
||||||
|
write!(
|
||||||
|
self.out.borrow_mut(),
|
||||||
|
"{}{}",
|
||||||
|
termion::cursor::Goto((x + 1) as u16, (y + 1) as u16),
|
||||||
|
cell
|
||||||
|
).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
self.out.borrow_mut().flush().unwrap();
|
self.out.borrow_mut().flush().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn draw<C1: color::Color, C2: color::Color>(
|
pub(crate) fn draw<C1: color::Color + Copy, C2: color::Color + Copy>(
|
||||||
&self,
|
&self,
|
||||||
x: usize,
|
x: usize,
|
||||||
y: usize,
|
y: usize,
|
||||||
|
@ -39,14 +94,19 @@ impl Screen {
|
||||||
fg: C1,
|
fg: C1,
|
||||||
bg: C2,
|
bg: C2,
|
||||||
) {
|
) {
|
||||||
write!(
|
let mut buf = self.buf.borrow_mut();
|
||||||
self.out.borrow_mut(),
|
let mut x = x;
|
||||||
"{}{}{}{}",
|
for g in UnicodeSegmentation::graphemes(text, true) {
|
||||||
termion::cursor::Goto((x + 1) as u16, (y + 1) as u16),
|
let width = UnicodeWidthStr::width(g);
|
||||||
color::Fg(fg),
|
if width > 0 {
|
||||||
color::Bg(bg),
|
buf[y * self.w + x] = Some(format!("{}{}{}", color::Fg(fg), color::Bg(bg), g));
|
||||||
text
|
x += 1;
|
||||||
).unwrap();
|
for _ in 0..(width - 1) {
|
||||||
|
buf[y * self.w + x] = None;
|
||||||
|
x += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn hide_cursor(&self) {
|
pub(crate) fn hide_cursor(&self) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user