small software-rendered rust tty
-rw-r--r--src/main.rs1
-rw-r--r--src/render.rs28
-rw-r--r--src/term.rs15
3 files changed, 34 insertions, 10 deletions
diff --git a/src/main.rs b/src/main.rs
index c5fdb5f..7efe0b8 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -163,6 +163,7 @@ fn main() -> Result<()> {
let mut f = File::create("x").unwrap();
loop {
+ t.scroll(w.get_scroll_wheel().unwrap_or_default().1);
while let Ok(x) = trx.recv_timeout(Duration::from_millis(16)) {
f.write_all(&x)?;
for char in x {
diff --git a/src/render.rs b/src/render.rs
index 0f4a582..2c978fe 100644
--- a/src/render.rs
+++ b/src/render.rs
@@ -17,7 +17,13 @@ pub fn render(
let m = FONT.metrics(&[]);
let sz = ppem * (m.max_width / m.units_per_em as f32);
let mut i = Image::build(w as _, h as _).fill(colors::BACKGROUND);
- for (col, k) in x.cells.rows().zip(1..) {
+ let c = x.cells.c();
+ let r = x.cells.r();
+ for (col, k) in x.cells.cells
+ [(x.view_o * c) as usize..(x.view_o * c + r * c) as usize]
+ .chunks_exact(c as _)
+ .zip(1..)
+ {
for (&(mut cell), j) in col.iter().zip(0..) {
if cell.style.flags & crate::term::INVERT != 0 {
std::mem::swap(&mut cell.style.bg, &mut cell.style.color);
@@ -108,15 +114,17 @@ pub fn render(
}
}
- let cell = Image::<_, 4>::build(3, (ppem * 1.25).ceil() as u32)
- .fill([0xFF, 0xCC, 0x66, 255]);
- unsafe {
- i.as_mut().overlay_at(
- &cell,
- 4 + ((x.cursor.0 - 1) as f32 * sz) as u32,
- (x.cursor.1 as f32 * (ppem * 1.25)) as u32 - 20,
- )
- };
+ if x.view_o == x.cells.row {
+ let cell = Image::<_, 4>::build(3, (ppem * 1.25).ceil() as u32)
+ .fill([0xFF, 0xCC, 0x66, 255]);
+ unsafe {
+ i.as_mut().overlay_at(
+ &cell,
+ 4 + ((x.cursor.0 - 1) as f32 * sz) as u32,
+ (x.cursor.1 as f32 * (ppem * 1.25)) as u32 - 20,
+ )
+ };
+ }
i
}
diff --git a/src/term.rs b/src/term.rs
index 8e42781..ebf20a7 100644
--- a/src/term.rs
+++ b/src/term.rs
@@ -11,6 +11,7 @@ pub struct Terminal {
pub cursor: (u16, u16),
pub saved_cursor: (u16, u16),
+ pub view_o: u16,
pub cells: Cells,
pub p: TerminalInputParser,
pub mode: Mode,
@@ -22,6 +23,7 @@ use std::default::Default::default;
impl Terminal {
pub fn new(sz: (u16, u16), alt: bool) -> Self {
Self {
+ view_o: 0,
style: default(),
saved_cursor: (1, 1),
cursor: (1, 1),
@@ -42,6 +44,16 @@ pub enum Mode {
}
impl Terminal {
+ pub fn scroll(&mut self, rows: f32) {
+ if rows < 0.0 {
+ let rows = rows.ceil().abs() as u16;
+ self.view_o = (self.view_o + rows).min(self.cells.row);
+ } else {
+ let rows = rows.floor() as u16;
+ self.view_o = self.view_o.saturating_sub(rows);
+ }
+ }
+
fn decsc(&mut self) {
self.saved_cursor = self.cursor;
}
@@ -65,6 +77,9 @@ impl Terminal {
println!("newline");
self.cursor.1 -= 1;
self.cells.grow(1);
+ if self.view_o + 1 == self.cells.row {
+ self.view_o += 1;
+ }
}
let w = self.cells.c();
let c = self.cells.get_at(self.cursor);