Add Background widget

This commit is contained in:
Joscha 2023-02-16 16:26:47 +01:00
parent b327dee3c3
commit 3f7e985b3f
4 changed files with 80 additions and 1 deletions

View file

@ -18,6 +18,8 @@ fn widget() -> impl Widget<Infallible> {
.border()
.look(BorderLook::LINE_DOUBLE)
.style(ContentStyle::default().dark_red())
.background()
.style(ContentStyle::default().on_dark_yellow())
.float()
.all(0.5)
}

View file

@ -1,6 +1,6 @@
use async_trait::async_trait;
use crate::widgets::{Border, Float, Padding};
use crate::widgets::{Background, Border, Float, Padding};
use crate::{Frame, Size};
// TODO Feature-gate these traits
@ -29,6 +29,10 @@ pub trait AsyncWidget<E> {
}
pub trait WidgetExt: Sized {
fn background(self) -> Background<Self> {
Background::new(self)
}
fn border(self) -> Border<Self> {
Border::new(self)
}

View file

@ -1,9 +1,11 @@
mod background;
mod border;
mod empty;
mod float;
mod padding;
mod text;
pub use background::*;
pub use border::*;
pub use empty::*;
pub use float::*;

71
src/widgets/background.rs Normal file
View file

@ -0,0 +1,71 @@
use async_trait::async_trait;
use crossterm::style::ContentStyle;
use crate::{AsyncWidget, Frame, Pos, Size, Widget};
pub struct Background<I> {
inner: I,
style: ContentStyle,
}
impl<I> Background<I> {
pub fn new(inner: I) -> Self {
Self {
inner,
style: ContentStyle::default(),
}
}
pub fn style(mut self, style: ContentStyle) -> Self {
self.style = style;
self
}
fn fill(&self, frame: &mut Frame) {
let size = frame.size();
for dy in 0..size.height {
for dx in 0..size.width {
frame.write(Pos::new(dx.into(), dy.into()), (" ", self.style));
}
}
}
}
impl<E, I> Widget<E> for Background<I>
where
I: Widget<E>,
{
fn size(
&self,
frame: &mut Frame,
max_width: Option<u16>,
max_height: Option<u16>,
) -> Result<Size, E> {
self.inner.size(frame, max_width, max_height)
}
fn draw(self, frame: &mut Frame) -> Result<(), E> {
self.fill(frame);
self.inner.draw(frame)
}
}
#[async_trait]
impl<E, I> AsyncWidget<E> for Background<I>
where
I: AsyncWidget<E> + Send + Sync,
{
async fn size(
&self,
frame: &mut Frame,
max_width: Option<u16>,
max_height: Option<u16>,
) -> Result<Size, E> {
self.inner.size(frame, max_width, max_height).await
}
async fn draw(self, frame: &mut Frame) -> Result<(), E> {
self.fill(frame);
self.inner.draw(frame).await
}
}