use std::mem; use async_trait::async_trait; use crate::buffer::Buffer; use crate::{AsyncWidget, Frame, Pos, Size, Style, Styled, Widget, WidthDb}; #[derive(Debug, Clone)] pub struct Predrawn { buffer: Buffer, } impl Predrawn { pub fn new>(inner: W, widthdb: &mut WidthDb) -> Result { let mut tmp_frame = Frame::default(); let size = inner.size(widthdb, None, None)?; tmp_frame.buffer.resize(size); mem::swap(widthdb, &mut tmp_frame.widthdb); inner.draw(&mut tmp_frame)?; mem::swap(widthdb, &mut tmp_frame.widthdb); let buffer = tmp_frame.buffer; Ok(Self { buffer }) } pub async fn new_async>( inner: W, widthdb: &mut WidthDb, ) -> Result { let mut tmp_frame = Frame::default(); let size = inner.size(widthdb, None, None).await?; tmp_frame.buffer.resize(size); mem::swap(widthdb, &mut tmp_frame.widthdb); inner.draw(&mut tmp_frame).await?; mem::swap(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)); } if let Some(cursor) = self.buffer.cursor() { frame.set_cursor(Some(cursor)); } } } 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(()) } }