Make Layer* more like Join*

This commit is contained in:
Joscha 2023-04-08 15:21:51 +02:00
parent 88e66e17ec
commit 77e72de9ad
2 changed files with 165 additions and 32 deletions

View file

@ -1,7 +1,7 @@
use async_trait::async_trait; use async_trait::async_trait;
use crate::widgets::{ use crate::widgets::{
Background, Border, Either2, Either3, Float, JoinSegment, Layer, Padding, Resize, Background, Border, Either2, Either3, Float, JoinSegment, Layer2, Padding, Resize,
}; };
use crate::{Frame, Size, WidthDb}; use crate::{Frame, Size, WidthDb};
@ -67,12 +67,12 @@ pub trait WidgetExt: Sized {
JoinSegment::new(self) JoinSegment::new(self)
} }
fn below<W>(self, above: W) -> Layer<Self, W> { fn below<W>(self, above: W) -> Layer2<Self, W> {
Layer::new(self, above) Layer2::new(self, above)
} }
fn above<W>(self, below: W) -> Layer<W, Self> { fn above<W>(self, below: W) -> Layer2<W, Self> {
Layer::new(below, self) Layer2::new(below, self)
} }
fn padding(self) -> Padding<Self> { fn padding(self) -> Padding<Self> {

View file

@ -2,26 +2,19 @@ use async_trait::async_trait;
use crate::{AsyncWidget, Frame, Size, Widget, WidthDb}; use crate::{AsyncWidget, Frame, Size, Widget, WidthDb};
#[derive(Debug, Clone, Copy)] pub struct Layer<I> {
pub struct Layer<I1, I2> { layers: Vec<I>,
pub below: I1,
pub above: I2,
} }
impl<I1, I2> Layer<I1, I2> { impl<I> Layer<I> {
pub fn new(below: I1, above: I2) -> Self { pub fn new(layers: Vec<I>) -> Self {
Self { below, above } Self { layers }
}
fn size(below: Size, above: Size) -> Size {
Size::new(below.width.max(above.width), below.height.max(above.height))
} }
} }
impl<E, I1, I2> Widget<E> for Layer<I1, I2> impl<E, I> Widget<E> for Layer<I>
where where
I1: Widget<E>, I: Widget<E>,
I2: Widget<E>,
{ {
fn size( fn size(
&self, &self,
@ -29,23 +22,27 @@ where
max_width: Option<u16>, max_width: Option<u16>,
max_height: Option<u16>, max_height: Option<u16>,
) -> Result<Size, E> { ) -> Result<Size, E> {
let bottom = self.below.size(widthdb, max_width, max_height)?; let mut size = Size::ZERO;
let top = self.above.size(widthdb, max_width, max_height)?; for layer in &self.layers {
Ok(Self::size(bottom, top)) let lsize = layer.size(widthdb, max_width, max_height)?;
size.width = size.width.max(lsize.width);
size.height = size.height.max(lsize.height);
}
Ok(size)
} }
fn draw(self, frame: &mut Frame) -> Result<(), E> { fn draw(self, frame: &mut Frame) -> Result<(), E> {
self.below.draw(frame)?; for layer in self.layers {
self.above.draw(frame)?; layer.draw(frame)?;
}
Ok(()) Ok(())
} }
} }
#[async_trait] #[async_trait]
impl<E, I1, I2> AsyncWidget<E> for Layer<I1, I2> impl<E, I> AsyncWidget<E> for Layer<I>
where where
I1: AsyncWidget<E> + Send + Sync, I: AsyncWidget<E> + Send + Sync,
I2: AsyncWidget<E> + Send + Sync,
{ {
async fn size( async fn size(
&self, &self,
@ -53,14 +50,150 @@ where
max_width: Option<u16>, max_width: Option<u16>,
max_height: Option<u16>, max_height: Option<u16>,
) -> Result<Size, E> { ) -> Result<Size, E> {
let bottom = self.below.size(widthdb, max_width, max_height).await?; let mut size = Size::ZERO;
let top = self.above.size(widthdb, max_width, max_height).await?; for layer in &self.layers {
Ok(Self::size(bottom, top)) let lsize = layer.size(widthdb, max_width, max_height).await?;
size.width = size.width.max(lsize.width);
size.height = size.height.max(lsize.height);
}
Ok(size)
} }
async fn draw(self, frame: &mut Frame) -> Result<(), E> { async fn draw(self, frame: &mut Frame) -> Result<(), E> {
self.below.draw(frame).await?; for layer in self.layers {
self.above.draw(frame).await?; layer.draw(frame).await?;
}
Ok(()) Ok(())
} }
} }
macro_rules! mk_layer {
(
pub struct $name:ident {
$( pub $arg:ident: $type:ident, )+
}
) => {
pub struct $name< $($type),+ >{
$( pub $arg: $type, )+
}
impl< $($type),+ > $name< $($type),+ >{
pub fn new( $($arg: $type),+ ) -> Self {
Self { $( $arg, )+ }
}
}
impl<E, $($type),+ > Widget<E> for $name< $($type),+ >
where
$( $type: Widget<E>, )+
{
fn size(
&self,
widthdb: &mut WidthDb,
max_width: Option<u16>,
max_height: Option<u16>,
) -> Result<Size, E> {
let mut size = Size::ZERO;
$({
let lsize = self.$arg.size(widthdb, max_width, max_height)?;
size.width = size.width.max(lsize.width);
size.height = size.height.max(lsize.height);
})+
Ok(size)
}
fn draw(self, frame: &mut Frame) -> Result<(), E> {
$( self.$arg.draw(frame)?; )+
Ok(())
}
}
#[async_trait]
impl<E, $($type),+ > AsyncWidget<E> for $name< $($type),+ >
where
E: Send,
$( $type: AsyncWidget<E> + Send + Sync, )+
{
async fn size(
&self,
widthdb: &mut WidthDb,
max_width: Option<u16>,
max_height: Option<u16>,
) -> Result<Size, E> {
let mut size = Size::ZERO;
$({
let lsize = self.$arg.size(widthdb, max_width, max_height).await?;
size.width = size.width.max(lsize.width);
size.height = size.height.max(lsize.height);
})+
Ok(size)
}
async fn draw(self, frame: &mut Frame) -> Result<(), E> {
$( self.$arg.draw(frame).await?; )+
Ok(())
}
}
};
}
mk_layer!(
pub struct Layer2 {
pub first: I1,
pub second: I2,
}
);
mk_layer!(
pub struct Layer3 {
pub first: I1,
pub second: I2,
pub third: I3,
}
);
mk_layer!(
pub struct Layer4 {
pub first: I1,
pub second: I2,
pub third: I3,
pub fourth: I4,
}
);
mk_layer!(
pub struct Layer5 {
pub first: I1,
pub second: I2,
pub third: I3,
pub fourth: I4,
pub fifth: I5,
}
);
mk_layer!(
pub struct Layer6 {
pub first: I1,
pub second: I2,
pub third: I3,
pub fourth: I4,
pub fifth: I5,
pub sixth: I6,
}
);
mk_layer!(
pub struct Layer7 {
pub first: I1,
pub second: I2,
pub third: I3,
pub fourth: I4,
pub fifth: I5,
pub sixth: I6,
pub seventh: I7,
}
);