From 64c83b5460d30e108b11656c28d59ad914761cff Mon Sep 17 00:00:00 2001 From: facile pop culture reference Date: Sat, 1 Aug 2026 21:25:29 +0300 Subject: [PATCH] layout (no-draw) mode for tui --- src/lib.rs | 154 ++++++++++++++++++++++++++++++--------------- src/term/border.rs | 8 +-- src/term/repeat.rs | 20 +++--- src/term/scroll.rs | 90 +++++++++++++------------- 4 files changed, 167 insertions(+), 105 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 48415ef..45d50a2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1325,21 +1325,45 @@ macro_rules! eval_xy ( crossterm::event::read, }; - impl Deref for Tui { type Target = Buffer; fn deref (&self) -> &Buffer { &self.0 } } - impl DerefMut for Tui { fn deref_mut (&mut self) -> &mut Buffer { &mut self.0 } } - impl AsMut for Tui { fn as_mut (&mut self) -> &mut Buffer { &mut self.0 } } - impl Wide for Tui { fn w (&self) -> u16 { self.1.2 } } - impl Tall for Tui { fn h (&self) -> u16 { self.1.3 } } + //impl Deref for Tui { type Target = Buffer; fn deref (&self) -> &Buffer { &self.0 } } + //impl DerefMut for Tui { fn deref_mut (&mut self) -> &mut Buffer { &mut self.0 } } + //impl AsMut for Tui { fn as_mut (&mut self) -> &mut Buffer { &mut self.0 } } + impl AsRef> for Tui { + fn as_ref (&self) -> &XYWH { + match self { + Self::Draw(_, area) => area, + Self::Layout(area) => area + } + } + } + + impl Wide for Tui { + fn w (&self) -> u16 { self.as_ref().2 } + } + + impl Tall for Tui { + fn h (&self) -> u16 { self.as_ref().3 } + } + + impl Xy for Tui { + fn x (&self) -> u16 { self.as_ref().0 } + fn y (&self) -> u16 { self.as_ref().1 } + } + impl HasOrigin for Tui { fn origin (&self) -> Azimuth { Azimuth::NW } } - impl Xy for Tui { fn x (&self) -> u16 { self.1.0 } fn y (&self) -> u16 { self.1.1 } } /// Terminal output. - pub struct Tui( - /// Ratatui buffer; area is screen size - pub Buffer, - /// Current draw area - pub XYWH - ); + pub enum Tui { + Draw ( + /// Ratatui buffer; area is screen size + Buffer, + /// Current draw area + XYWH + ), + Layout ( + XYWH + ) + } impl Tui { pub fn setup_panic () { @@ -1402,14 +1426,16 @@ macro_rules! eval_xy ( disable_raw_mode().map_err(Into::into) } pub fn new (width: u16, height: u16) -> Self { - Self(Buffer::empty(Rect { x: 0, y: 0, width, height }), XYWH(0, 0, width, height)) + Self::Draw(Buffer::empty(Rect { x: 0, y: 0, width, height }), XYWH(0, 0, width, height)) } pub fn resize (&mut self, back: &mut CrosstermBackend, width: u16, height: u16) { let size = Rect { x: 0, y: 0, width, height }; - if self.0.area != size { - back.clear_region(ClearType::All).unwrap(); - self.0.resize(size); - self.0.reset(); + if let Self::Draw(buffer, ..) = self { + if buffer.area != size { + back.clear_region(ClearType::All).unwrap(); + buffer.resize(size); + buffer.reset(); + } } } pub fn redraw <'b, W: Write> ( @@ -1417,20 +1443,25 @@ macro_rules! eval_xy ( back: &mut CrosstermBackend, mut next: &'b mut Self ) { - let updates = self.0.diff(&next.0); - back.draw(updates.into_iter()).expect("failed to render"); - Backend::flush(back).expect("failed to flush output new"); - std::mem::swap(self, &mut next); - next.0.reset(); + if let Self::Draw(prev, ..) = self && let Self::Draw(next, ..) = next { + let updates = prev.diff(&next); + back.draw(updates.into_iter()).expect("failed to render"); + Backend::flush(back).expect("failed to flush output new"); + std::mem::swap(prev, next); + next.reset(); + } } pub fn update (&mut self, callback: &impl Fn(&mut Cell, u16, u16)) -> XYWH { - for row in 0..self.h() { - let y = self.y() + row; - for col in 0..self.w() { - let x = self.x() + col; - if x < self.0.area.width && y < self.0.area.height { - if let Some(cell) = self.0.cell_mut(Position { x, y }) { - callback(cell, col, row); + let XYWH(x0, y0, w, h) = self.area(); + if let Self::Draw(buffer, ..) = self { + for row in 0..h { + let y = y0 + row; + for col in 0..w { + let x = x0 + col; + if x < buffer.area.width && y < buffer.area.height { + if let Some(cell) = buffer.cell_mut(Position { x, y }) { + callback(cell, col, row); + } } } } @@ -1438,17 +1469,21 @@ macro_rules! eval_xy ( self.xywh() } pub fn blit (&mut self, text: &impl AsRef, x: u16, y: u16, style: Option