Add Text widget
This commit is contained in:
parent
70d33d4d5d
commit
f793ec79ac
3 changed files with 96 additions and 0 deletions
|
|
@ -14,6 +14,7 @@ mod frame;
|
|||
mod styled;
|
||||
mod terminal;
|
||||
mod widget;
|
||||
pub mod widgets;
|
||||
mod widthdb;
|
||||
mod wrap;
|
||||
|
||||
|
|
|
|||
3
src/widgets.rs
Normal file
3
src/widgets.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
mod text;
|
||||
|
||||
pub use text::*;
|
||||
92
src/widgets/text.rs
Normal file
92
src/widgets/text.rs
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
use async_trait::async_trait;
|
||||
|
||||
use crate::{AsyncWidget, Frame, Pos, Size, Styled, Widget, WidthDb};
|
||||
|
||||
pub struct Text {
|
||||
styled: Styled,
|
||||
wrap: bool,
|
||||
}
|
||||
|
||||
impl Text {
|
||||
pub fn new<S: Into<Styled>>(styled: S) -> Self {
|
||||
Self {
|
||||
styled: styled.into(),
|
||||
wrap: true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn wrap(mut self, wrap: bool) -> Self {
|
||||
self.wrap = wrap;
|
||||
self
|
||||
}
|
||||
|
||||
fn wrapped(&self, widthdb: &mut WidthDb, max_width: Option<u16>) -> Vec<Styled> {
|
||||
let max_width = max_width
|
||||
.filter(|_| self.wrap)
|
||||
.map(|w| w as usize)
|
||||
.unwrap_or(usize::MAX);
|
||||
|
||||
let indices = widthdb.wrap(self.styled.text(), max_width);
|
||||
self.styled.clone().split_at_indices(&indices)
|
||||
}
|
||||
|
||||
fn size(&self, widthdb: &mut WidthDb, max_width: Option<u16>) -> Size {
|
||||
let lines = self.wrapped(widthdb, max_width);
|
||||
|
||||
let min_width = lines
|
||||
.iter()
|
||||
.map(|l| widthdb.width(l.text().trim_end()))
|
||||
.max()
|
||||
.unwrap_or(0);
|
||||
let min_height = lines.len();
|
||||
|
||||
let min_width: u16 = min_width.try_into().unwrap_or(u16::MAX);
|
||||
let min_height: u16 = min_height.try_into().unwrap_or(u16::MAX);
|
||||
Size::new(min_width, min_height)
|
||||
}
|
||||
|
||||
fn draw(self, frame: &mut Frame) {
|
||||
let size = frame.size();
|
||||
for (i, line) in self
|
||||
.wrapped(frame.widthdb(), Some(size.width))
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
{
|
||||
let i: i32 = i.try_into().unwrap_or(i32::MAX);
|
||||
frame.write(Pos::new(0, i), line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> Widget<E> for Text {
|
||||
fn size(
|
||||
&self,
|
||||
frame: &mut Frame,
|
||||
max_width: Option<u16>,
|
||||
_max_height: Option<u16>,
|
||||
) -> Result<Size, E> {
|
||||
Ok(self.size(frame.widthdb(), max_width))
|
||||
}
|
||||
|
||||
fn draw(self, frame: &mut Frame) -> Result<(), E> {
|
||||
self.draw(frame);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<E> AsyncWidget<E> for Text {
|
||||
async fn size(
|
||||
&self,
|
||||
frame: &mut Frame,
|
||||
max_width: Option<u16>,
|
||||
_max_height: Option<u16>,
|
||||
) -> Result<Size, E> {
|
||||
Ok(self.size(frame.widthdb(), max_width))
|
||||
}
|
||||
|
||||
async fn draw(self, frame: &mut Frame) -> Result<(), E> {
|
||||
self.draw(frame);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue