From 11ecf669a183b0817fa869609bd61305c77df3de Mon Sep 17 00:00:00 2001 From: unspeaker Date: Thu, 12 Sep 2024 17:05:08 +0300 Subject: [PATCH] test and fix behaviors of some of the layout components --- crates/tek_core/src/engine.rs | 103 +++++++++++++++++++--------------- crates/tek_core/src/lib.rs | 4 +- crates/tek_core/src/tui.rs | 16 +++--- crates/tek_test/src/main.rs | 70 +++++++++++++++++++++-- 4 files changed, 137 insertions(+), 56 deletions(-) diff --git a/crates/tek_core/src/engine.rs b/crates/tek_core/src/engine.rs index 8128d619..8b1cad37 100644 --- a/crates/tek_core/src/engine.rs +++ b/crates/tek_core/src/engine.rs @@ -453,11 +453,11 @@ impl> Widget for Min { } fn render (&self, to: &mut E) -> Perhaps { // 🡘 🡙 ←🡙→ - self.layout(to.area())? - .map(|area|to.with_area(area.x(), area.y(), area.w(), area.h())) - .map(|to|self.inner().render(to)) - .transpose() - .map(|x|x.flatten()) + if let Some(area) = self.layout(to.area())? { + to.render_in(area, self.inner()) + } else { + Ok(None) + } } } @@ -499,11 +499,11 @@ impl> Widget for Max { } } fn render (&self, to: &mut E) -> Perhaps { - self.layout(to.area())? - .map(|area|to.with_area(area.x(), area.y(), area.w(), area.h())) - .map(|to|self.inner().render(to)) - .transpose() - .map(|x|x.flatten()) + if let Some(area) = self.layout(to.area())? { + to.render_in(area, self.inner()) + } else { + Ok(None) + } } } @@ -530,24 +530,30 @@ impl Outset { impl> Widget for Outset { type Engine = E; fn layout (&self, area: E::Area) -> Perhaps { - match self { - Self::W(w, item) => if area.x() < *w { Ok(None) } else { - item.layout([area.x() - *w, area.y(), area.w() + *w, area.h()].into()) + Ok(match self { + Self::W(w, item) => if area.x() < *w { None } else { + item.layout(area)?.map(|area|[ + area.x() - *w, area.y(), area.w() + *w + *w, area.h() + ].into()) }, - Self::H(h, item) => if area.y() < *h { Ok(None) } else { - item.layout([area.x(), area.y() - *h, area.w(), area.h() + *h].into()) + Self::H(h, item) => if area.y() < *h { None } else { + item.layout(area)?.map(|area|[ + area.x(), area.y() - *h, area.w(), area.h() + *h + *h + ].into()) }, - Self::WH(w, h, item) => if area.x() < *w || area.y() < *h { Ok(None) } else { - item.layout([area.x()- *w, area.y() - *h, area.w() + *w, area.h() + *h].into()) + Self::WH(w, h, item) => if area.x() < *w || area.y() < *h { None } else { + item.layout(area)?.map(|area|[ + area.x()- *w, area.y() - *h, area.w() + *w + *w, area.h() + *h + *h + ].into()) } - } + }) } fn render (&self, to: &mut E) -> Perhaps { - self.layout(to.area())? - .map(|area|to.with_area(area.x(), area.y(), area.w(), area.h())) - .map(|to|self.inner().render(to)) - .transpose() - .map(|x|x.flatten()) + if let Some(area) = self.layout(to.area())? { + to.render_in(area, self.inner()) + } else { + Ok(None) + } } } @@ -574,24 +580,30 @@ impl Inset { impl> Widget for Inset { type Engine = E; fn layout (&self, area: E::Area) -> Perhaps { - match self { - Self::W(w, item) => if area.w() < *w { Ok(None) } else { - item.layout([area.x() + *w, area.y(), area.w() - *w, area.h()].into()) + Ok(match self { + Self::W(w, item) => if area.w() < *w { None } else { + item.layout(area)?.map(|area|[ + area.x() + *w, area.y(), area.w() - *w, area.h() + ].into()) }, - Self::H(h, item) => if area.h() < *h { Ok(None) } else { - item.layout([area.x(), area.y() + *h, area.w(), area.h() - *h].into()) + Self::H(h, item) => if area.h() < *h { None } else { + item.layout(area)?.map(|area|[ + area.x(), area.y() + *h, area.w(), area.h() - *h + ].into()) }, - Self::WH(w, h, item) => if area.w() < *w || area.h() < *h { Ok(None) } else { - item.layout([area.x() - *w, area.y() - *h, area.w() + *w, area.h() + *h].into()) + Self::WH(w, h, item) => if area.w() < *w || area.h() < *h { None } else { + item.layout(area)?.map(|area|[ + area.x() - *w, area.y() - *h, area.w() + *w, area.h() + *h + ].into()) } - } + }) } fn render (&self, to: &mut E) -> Perhaps { - self.layout(to.area())? - .map(|area|to.with_area(area.x(), area.y(), area.w(), area.h())) - .map(|to|self.inner().render(to)) - .transpose() - .map(|x|x.flatten()) + if let Some(area) = self.layout(to.area())? { + to.render_in(area, self.inner()) + } else { + Ok(None) + } } } @@ -617,22 +629,25 @@ impl> Widget for Offset { fn layout (&self, area: E::Area) -> Perhaps { match self { Self::X(x, item) => if area.w() < *x { Ok(None) } else { - item.layout([area.x() + *x, area.y(), area.w() - *x, area.h()].into()) + let offset_area = [area.x() + *x, area.y(), area.w() - *x, area.h()]; + item.layout(offset_area.into()) }, Self::Y(y, item) => if area.h() < *y { Ok(None) } else { - item.layout([area.x(), area.y() + *y, area.w(), area.h() - *y].into()) + let offset_area = [area.x(), area.y() + *y, area.w(), area.h() - *y]; + item.layout(offset_area.into()) }, Self::XY(x, y, item) => if area.w() < *x || area.h() < *y { Ok(None) } else { - item.layout([area.x() + *x, area.y() + *y, area.w() - *x, area.h() - *y].into()) + let offset_area = [area.x() + *x, area.y() + *y, area.w() - *x, area.h() - *y]; + item.layout(offset_area.into()) } } } fn render (&self, to: &mut E) -> Perhaps { - self.layout(to.area())? - .map(|area|to.with_area(area.x(), area.y(), area.w(), area.h())) - .map(|to|self.inner().render(to)) - .transpose() - .map(|x|x.flatten()) + if let Some(area) = self.layout(to.area())? { + to.render_in(area, self.inner()) + } else { + Ok(None) + } } } diff --git a/crates/tek_core/src/lib.rs b/crates/tek_core/src/lib.rs index 40967bd3..f170d2c5 100644 --- a/crates/tek_core/src/lib.rs +++ b/crates/tek_core/src/lib.rs @@ -16,7 +16,7 @@ pub(crate) use std::thread::{spawn, JoinHandle}; pub(crate) use std::time::Duration; pub(crate) use atomic_float::*; use better_panic::{Settings, Verbosity}; -use std::ops::{Add, Sub, Div}; +use std::ops::{Add, Sub, Mul, Div}; use std::cmp::{Ord, Eq, PartialEq}; use std::fmt::{Debug, Display}; @@ -49,6 +49,7 @@ pub type Perhaps = Result, Box>; pub trait Number: Send + Sync + Copy + Add + Sub + + Mul + Div + Ord + PartialEq + Eq + Debug + Display {} @@ -57,6 +58,7 @@ impl Number for T where T: Send + Sync + Copy + Add + Sub + + Mul + Div + Ord + PartialEq + Eq + Debug + Display diff --git a/crates/tek_core/src/tui.rs b/crates/tek_core/src/tui.rs index ab813b81..3c1ad180 100644 --- a/crates/tek_core/src/tui.rs +++ b/crates/tek_core/src/tui.rs @@ -288,6 +288,9 @@ pub struct FillBg(pub Color); impl Widget for FillBg { type Engine = Tui; + fn layout (&self, [x,y,_,_]: [u16;4]) -> Perhaps<[u16;4]> { + Ok(Some([x,y,0,0])) + } fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { to.fill_bg(to.area(), self.0); Ok(Some(to.area)) @@ -457,9 +460,8 @@ where if h >= to.h() { return Ok(()) } - if let Some([_, _, width, height]) = Offset::Y( - h, component as &dyn Widget - ).layout(to)? { + let area = Offset::Y(h, component as &dyn Widget).layout(to)?; + if let Some([_, _, width, height]) = area { h += height; w = w.max(width) } @@ -554,14 +556,14 @@ where impl> Widget for Align { type Engine = Tui; fn layout (&self, outer_area: [u16;4]) -> Perhaps<[u16;4]> { - Ok(self.inner().layout(outer_area)?.map(|inner_area|match self { - Self::Center(_) => { + Ok(match self { + Self::Center(_) => self.inner().layout(outer_area)?.map(|inner_area|{ let [_, _, w, h] = inner_area.xywh(); let offset_x = (outer_area.w() / 2).saturating_sub(w / 2); let offset_y = (outer_area.h() / 2).saturating_sub(h / 2); let result = [outer_area.x() + offset_x, outer_area.y() + offset_y, w, h]; result - }, + }), Self::NW(_) => { todo!() }, Self::N(_) => { todo!() }, Self::NE(_) => { todo!() }, @@ -570,7 +572,7 @@ impl> Widget for Align { Self::SW(_) => { todo!() }, Self::S(_) => { todo!() }, Self::SE(_) => { todo!() }, - })) + }) } fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { self.layout(to.area())? diff --git a/crates/tek_test/src/main.rs b/crates/tek_test/src/main.rs index ea320088..08536b05 100644 --- a/crates/tek_test/src/main.rs +++ b/crates/tek_test/src/main.rs @@ -41,23 +41,25 @@ impl Content for Demo { //Layers2::new(|add|add(&Align::Center("FOO"))) //Align::Center(&self.items[self.index] as &dyn Widget) Align::Center(Layers::new(|add|{ - add(&Outset::WH(1, 1, FillBg(Color::Rgb(0,128,128))))?; add(&Split::down(|add|{ add(&Layers::new(|add|{ - add(&Outset::WH(1, 1, FillBg(Color::Rgb(0,128,0))))?; + //add(&Outset::WH(1, 1, FillBg(Color::Rgb(0,128,0))))?; add(&Align::Center("55555"))?; add(&Align::Center("FOO"))?; //add(&FillBg(Color::Rgb(0,128,0)))?; + //add(&FillBg(Color::Rgb(0,128,0)))?; Ok(()) }))?; add(&Layers::new(|add|{ - add(&Outset::WH(1, 1, FillBg(Color::Rgb(0,0,128))))?; add(&Align::Center("7777777"))?; add(&Align::Center("BAR"))?; + //add(&Outset::WH(1, 1, FillBg(Color::Rgb(0,0,128))))?; + //add(&FillBg(Color::Rgb(0,0,128)))?; //add(&FillBg(Color::Rgb(0,0,128)))?; Ok(()) })) - })) + }))?; + //add(&Outset::WH(1, 1, FillBg(Color::Rgb(0,128,128)))) })) } } @@ -81,3 +83,63 @@ impl Handle for Demo { } } } + +#[cfg(test)] +mod test { + use tek_core::*; + #[test] + fn test_stuff () -> Usually<()> { + let area: [u16;4] = [0, 0, 100, 100]; + assert_eq!("1".layout(area)?, + Some([0, 0, 1, 1])); + assert_eq!("333".layout(area)?, + Some([0, 0, 3, 1])); + assert_eq!(Layers::new(|add|{add(&"1")?;add(&"333")}).layout(area)?, + Some([0, 0, 3, 1])); + assert_eq!(Split::down(|add|{add(&"1")?;add(&"333")}).layout(area)?, + Some([0, 0, 3, 2])); + assert_eq!(Split::right(|add|{add(&"1")?;add(&"333")}).layout(area)?, + Some([0, 0, 4, 1])); + assert_eq!(Split::down(|add|{ + add(&Split::right(|add|{add(&"1")?;add(&"333")}))?; + add(&"55555") + }).layout(area)?, + Some([0, 0, 5, 2])); + let area: [u16;4] = [1, 1, 100, 100]; + assert_eq!(Outset::W(1, Split::right(|add|{add(&"1")?;add(&"333")})).layout(area)?, + Some([0, 1, 6, 1])); + assert_eq!(Outset::H(1, Split::right(|add|{add(&"1")?;add(&"333")})).layout(area)?, + Some([1, 0, 4, 3])); + assert_eq!(Outset::WH(1, 1, Split::right(|add|{add(&"1")?;add(&"333")})).layout(area)?, + Some([0, 0, 6, 3])); + assert_eq!(Split::down(|add|{ + add(&Outset::WH(1, 1, "1"))?; + add(&Outset::WH(1, 1, "333")) + }).layout(area)?, + Some([1, 1, 5, 6])); + let area: [u16;4] = [1, 1, 95, 100]; + assert_eq!(Align::Center(Split::down(|add|{ + add(&Outset::WH(1, 1, "1"))?; + add(&Outset::WH(1, 1, "333")) + })).layout(area)?, + Some([46, 48, 5, 6])); + assert_eq!(Align::Center(Split::down(|add|{ + add(&Layers::new(|add|{ + //add(&Outset::WH(1, 1, FillBg(Color::Rgb(0,128,0))))?; + add(&Outset::WH(1, 1, "1"))?; + add(&Outset::WH(1, 1, "333"))?; + //add(&FillBg(Color::Rgb(0,128,0)))?; + Ok(()) + }))?; + add(&Layers::new(|add|{ + //add(&Outset::WH(1, 1, FillBg(Color::Rgb(0,0,128))))?; + add(&Outset::WH(1, 1, "555"))?; + add(&Outset::WH(1, 1, "777777"))?; + //add(&FillBg(Color::Rgb(0,0,128)))?; + Ok(()) + })) + })).layout(area)?, + Some([46, 48, 5, 6])); + Ok(()) + } +}