Add Text widget
This commit is contained in:
parent
f08f653bfc
commit
53a0f8d4af
4 changed files with 71 additions and 10 deletions
|
|
@ -4,7 +4,7 @@ mod list;
|
|||
mod room;
|
||||
mod rooms;
|
||||
mod util;
|
||||
mod widget;
|
||||
mod widgets;
|
||||
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::time::Duration;
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
use async_trait::async_trait;
|
||||
use toss::frame::{Frame, Pos, Size};
|
||||
|
||||
#[async_trait]
|
||||
pub trait Widget {
|
||||
fn size(max_width: Option<u16>, max_height: Option<u16>) -> Size;
|
||||
|
||||
async fn render(frame: &mut Frame, pos: Pos, size: Size);
|
||||
}
|
||||
11
src/ui/widgets.rs
Normal file
11
src/ui/widgets.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
pub mod text;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use toss::frame::{Frame, Pos, Size};
|
||||
|
||||
#[async_trait]
|
||||
pub trait Widget {
|
||||
fn size(&self, frame: &mut Frame, max_width: Option<u16>, max_height: Option<u16>) -> Size;
|
||||
|
||||
async fn render(&self, frame: &mut Frame, pos: Pos, size: Size);
|
||||
}
|
||||
59
src/ui/widgets/text.rs
Normal file
59
src/ui/widgets/text.rs
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
use async_trait::async_trait;
|
||||
use toss::frame::{Frame, Pos, Size};
|
||||
use toss::styled::Styled;
|
||||
|
||||
use super::Widget;
|
||||
|
||||
pub struct Text {
|
||||
styled: Styled,
|
||||
wrap: bool,
|
||||
}
|
||||
|
||||
impl Text {
|
||||
pub fn new<S: Into<Styled>>(styled: S) -> Self {
|
||||
Self {
|
||||
styled: styled.into(),
|
||||
wrap: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn wrap(mut self) -> Self {
|
||||
self.wrap = true;
|
||||
self
|
||||
}
|
||||
|
||||
fn wrapped(&self, frame: &mut Frame, max_width: Option<u16>) -> Vec<Styled> {
|
||||
let max_width = if self.wrap {
|
||||
max_width.map(|w| w as usize).unwrap_or(usize::MAX)
|
||||
} else {
|
||||
usize::MAX
|
||||
};
|
||||
|
||||
let indices = frame.wrap(&self.styled.text(), max_width);
|
||||
self.styled.clone().split_at_indices(&indices)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Widget for Text {
|
||||
fn size(&self, frame: &mut Frame, max_width: Option<u16>, _max_height: Option<u16>) -> Size {
|
||||
let lines = self.wrapped(frame, max_width);
|
||||
let min_width = lines
|
||||
.iter()
|
||||
.map(|l| frame.width(&l.text()))
|
||||
.max()
|
||||
.unwrap_or(0);
|
||||
let min_height = lines.len();
|
||||
Size::new(min_width as u16, min_height as u16)
|
||||
}
|
||||
|
||||
async fn render(&self, frame: &mut Frame, pos: Pos, size: Size) {
|
||||
for (i, line) in self
|
||||
.wrapped(frame, Some(size.width))
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
{
|
||||
frame.write(pos + Pos::new(0, i as i32), line);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue