From 88e66e17ec3da5c37445e5155a483bdc948c2752 Mon Sep 17 00:00:00 2001 From: Joscha Date: Thu, 6 Apr 2023 00:48:53 +0200 Subject: [PATCH] Add Predrawn widget --- src/widgets.rs | 2 + src/widgets/predrawn.rs | 86 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 src/widgets/predrawn.rs diff --git a/src/widgets.rs b/src/widgets.rs index dc80eb7..49c65a5 100644 --- a/src/widgets.rs +++ b/src/widgets.rs @@ -8,6 +8,7 @@ pub mod float; pub mod join; pub mod layer; pub mod padding; +pub mod predrawn; pub mod resize; pub mod text; @@ -21,5 +22,6 @@ pub use float::*; pub use join::*; pub use layer::*; pub use padding::*; +pub use predrawn::*; pub use resize::*; pub use text::*; diff --git a/src/widgets/predrawn.rs b/src/widgets/predrawn.rs new file mode 100644 index 0000000..e11d9f8 --- /dev/null +++ b/src/widgets/predrawn.rs @@ -0,0 +1,86 @@ +use std::mem; + +use async_trait::async_trait; + +use crate::buffer::Buffer; +use crate::{AsyncWidget, Frame, Pos, Size, Style, Styled, Widget, WidthDb}; + +pub struct Predrawn { + buffer: Buffer, +} + +impl Predrawn { + pub fn new>(inner: W, frame: &mut Frame) -> Result { + let mut tmp_frame = Frame::default(); + tmp_frame.buffer.resize(frame.size()); + mem::swap(&mut frame.widthdb, &mut tmp_frame.widthdb); + + inner.draw(&mut tmp_frame)?; + + mem::swap(&mut frame.widthdb, &mut tmp_frame.widthdb); + + let buffer = tmp_frame.buffer; + Ok(Self { buffer }) + } + + pub async fn new_async>(inner: W, frame: &mut Frame) -> Result { + let mut tmp_frame = Frame::default(); + tmp_frame.buffer.resize(frame.size()); + mem::swap(&mut frame.widthdb, &mut tmp_frame.widthdb); + + inner.draw(&mut tmp_frame).await?; + + mem::swap(&mut frame.widthdb, &mut tmp_frame.widthdb); + + let buffer = tmp_frame.buffer; + Ok(Self { buffer }) + } + + pub fn size(&self) -> Size { + self.buffer.size() + } + + fn draw_impl(&self, frame: &mut Frame) { + for (x, y, cell) in self.buffer.cells() { + let pos = Pos::new(x.into(), y.into()); + let style = Style { + content_style: cell.style, + opaque: true, + }; + frame.write(pos, Styled::new(&cell.content, style)); + } + } +} + +impl Widget for Predrawn { + fn size( + &self, + _widthdb: &mut WidthDb, + _max_width: Option, + _max_height: Option, + ) -> Result { + Ok(self.buffer.size()) + } + + fn draw(self, frame: &mut Frame) -> Result<(), E> { + self.draw_impl(frame); + Ok(()) + } +} + +#[async_trait] +impl AsyncWidget for Predrawn { + async fn size( + &self, + _widthdb: &mut WidthDb, + _max_width: Option, + _max_height: Option, + ) -> Result { + Ok(self.buffer.size()) + } + + async fn draw(self, frame: &mut Frame) -> Result<(), E> { + self.draw_impl(frame); + Ok(()) + } +}