From 4b413cfb60e2e3d22eaf3f74214c7f2cf95dbde8 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Thu, 12 Sep 2024 23:49:22 +0300 Subject: [PATCH] wip: Outset=Center+2*Grow, Inset=Center+2*Shrink --- crates/tek_core/src/engine.rs | 128 ++++++++++++++-------- crates/tek_core/src/test.rs | 195 ++++++++++++++++++++-------------- 2 files changed, 203 insertions(+), 120 deletions(-) diff --git a/crates/tek_core/src/engine.rs b/crates/tek_core/src/engine.rs index bb3e4190..e8edf32f 100644 --- a/crates/tek_core/src/engine.rs +++ b/crates/tek_core/src/engine.rs @@ -418,13 +418,11 @@ impl Min { impl> Widget for Min { type Engine = E; fn layout (&self, to: E::Area) -> Perhaps { - Ok(match self { - Self::X(w, _) => (to.w() < *w).then(||[to.x() + *w, to.y(), to.w() - *w, to.h()]), - Self::Y(h, _) => (to.h() < *h).then(||[to.x(), to.y() + *h, to.w(), to.h() - *h]), - Self::XY(w, h, _) => (to.w() < *w || to.h() < *h).then(||[ - to.x() + *w, to.y() + *h, to.w() - *w, to.h() - *h - ]) - }.map(|stretched|self.inner().layout(stretched.into())).transpose()?.flatten()) + Ok(self.inner().layout(to)?.map(|to|match *self { + Self::X(w, _) => [to.x(), to.y(), to.w().max(w), to.h()], + Self::Y(h, _) => [to.x(), to.y(), to.w(), to.h().max(h)], + Self::XY(w, h, _) => [to.x(), to.y(), to.w().max(w), to.h().max(h)], + }.into())) } // TODO: 🡘 🡙 ←🡙→ fn render (&self, to: &mut E) -> Perhaps { @@ -451,13 +449,11 @@ impl Max { impl> Widget for Max { type Engine = E; fn layout (&self, to: E::Area) -> Perhaps { - Ok(match self { - Self::X(w, _) => (*w <= to.w()).then(||[to.x(), to.y(), to.w().min(*w), to.h()]), - Self::Y(h, _) => (*h <= to.h()).then(||[to.x(), to.y(), to.w(), to.h().min(*h)]), - Self::XY(w, h, _) => (*w <= to.w() || *h <= to.h()).then(||[ - to.x(), to.y(), to.w().min(*w), to.h().min(*h) - ]) - }.map(|clamped|self.inner().layout(clamped.into())).transpose()?.flatten()) + Ok(self.inner().layout(to)?.map(|to|match *self { + Self::X(w, _) => [to.x(), to.y(), to.w().min(w), to.h()], + Self::Y(h, _) => [to.x(), to.y(), to.w(), to.h().min(h)], + Self::XY(w, h, _) => [to.x(), to.y(), to.w().min(w), to.h().min(h)], + }.into())) } fn render (&self, to: &mut E) -> Perhaps { Ok(self.layout(to.area())?.map(|a|to.render_in(a, self.inner())).transpose()?.flatten()) @@ -465,7 +461,7 @@ impl> Widget for Max { } /// Expand drawing area -pub enum Outset { +pub enum Grow { /// Increase width X(N, T), /// Increase height @@ -474,22 +470,20 @@ pub enum Outset { XY(N, N, T) } -impl Outset { +impl Grow { fn inner (&self) -> &T { match self { Self::X(_, i) => i, Self::Y(_, i) => i, Self::XY(_, _, i) => i, } } } -impl> Widget for Outset { +impl> Widget for Grow { type Engine = E; fn layout (&self, to: E::Area) -> Perhaps { - Ok(match self { - Self::X(w, _) => (*w <= to.w()).then(||[to.x() - *w, to.y(), to.w() + *w + *w, to.h()]), - Self::Y(h, _) => (*h <= to.h()).then(||[to.x(), to.y() - *h, to.w(), to.h() + *h + *h]), - Self::XY(w, h, _) => (*w <= to.w() || *h <= to.h()).then(||[ - to.x()- *w, to.y() - *h, to.w() + *w + *w, to.h() + *h + *h - ]) - }.map(|grown|self.inner().layout(grown.into())).transpose()?.flatten()) + Ok(self.inner().layout(to)?.map(|to|match *self { + Self::X(w, _) => [to.x(), to.y(), to.w() + w, to.h()], + Self::Y(h, _) => [to.x(), to.y(), to.w(), to.h() + h], + Self::XY(w, h, _) => [to.x(), to.y(), to.w() + w, to.h() + h], + }.into())) } fn render (&self, to: &mut E) -> Perhaps { Ok(self.layout(to.area())?.map(|a|to.render_in(a, self.inner())).transpose()?.flatten()) @@ -497,6 +491,36 @@ impl> Widget for Outset { } /// Shrink drawing area +pub enum Shrink { + /// Decrease width + X(N, T), + /// Decrease height + Y(N, T), + /// Decrease width and height + XY(N, N, T), +} + +impl Shrink { + fn inner (&self) -> &T { + match self { Self::X(_, i) => i, Self::Y(_, i) => i, Self::XY(_, _, i) => i, } + } +} + +impl> Widget for Shrink { + type Engine = E; + fn layout (&self, to: E::Area) -> Perhaps { + Ok(self.inner().layout(to)?.map(|to|match *self { + Self::X(w, _) => [to.x(), to.y(), to.w() - w, to.h()], + Self::Y(h, _) => [to.x(), to.y(), to.w(), to.h() - h], + Self::XY(w, h, _) => [to.x(), to.y(), to.w() - w, to.h() - h] + }.into())) + } + fn render (&self, to: &mut E) -> Perhaps { + Ok(self.layout(to.area())?.map(|a|to.render_in(a, self.inner())).transpose()?.flatten()) + } +} + +/// Shrink from each side pub enum Inset { /// Decrease width X(N, T), @@ -512,19 +536,41 @@ impl Inset { } } -impl> Widget for Inset { +impl> Content for Inset { type Engine = E; - fn layout (&self, to: E::Area) -> Perhaps { - Ok(match self { - Self::X(w, _) => (*w <= to.w()).then(||[to.x() + *w, to.y(), to.w() - *w, to.h()]), - Self::Y(h, _) => (*h <= to.h()).then(||[to.x(), to.y() + *h, to.w(), to.h() - *h]), - Self::XY(w, h, _) => (*w <= to.w() || *h <= to.h()).then(||[ - to.x() - *w, to.y() - *h, to.w() + *w, to.h() + *h - ]) - }.map(|shrunk|self.inner().layout(shrunk.into())).transpose()?.flatten()) + fn content (&self) -> impl Widget { + Align::Center(match *self { + Self::X(x, inner) => Shrink::X(x + x, inner), + Self::Y(y, inner) => Shrink::X(y + y, inner), + Self::XY(x, y, inner) => Shrink::XY(x, y, inner), + }) } - fn render (&self, to: &mut E) -> Perhaps { - Ok(self.layout(to.area())?.map(|a|to.render_in(a, self.inner())).transpose()?.flatten()) +} + +/// Grow on each side +pub enum Outset { + /// Increase width + X(N, T), + /// Increase height + Y(N, T), + /// Increase width and height + XY(N, N, T), +} + +impl Outset { + fn inner (&self) -> &T { + match self { Self::X(_, i) => i, Self::Y(_, i) => i, Self::XY(_, _, i) => i, } + } +} + +impl> Content for Outset { + type Engine = E; + fn content (&self) -> impl Widget { + Align::Center(match self { + Self::X(x, inner) => Grow::X(*x + *x, inner), + Self::Y(y, inner) => Grow::X(*y + *y, inner), + Self::XY(x, y, inner) => Grow::XY(*x, *y, inner), + }) } } @@ -553,13 +599,11 @@ impl Offset { impl> Widget for Offset { type Engine = E; fn layout (&self, to: E::Area) -> Perhaps { - Ok(match self { - Self::X(w, _) => (*w <= to.w()).then(||[to.x() + *w, to.y(), to.w() - *w, to.h()]), - Self::Y(h, _) => (*h <= to.h()).then(||[to.x(), to.y() + *h, to.w(), to.h() - *h]), - Self::XY(w, h, _) => (*w <= to.w() || *h <= to.h()).then(||[ - to.x() + *w, to.y() + *h, to.w() - *w, to.h() - *h - ]) - }.map(|shifted|self.inner().layout(shifted.into())).transpose()?.flatten()) + Ok(self.inner().layout(to)?.map(|to|match *self { + Self::X(x, _) => [to.x() + x, to.y(), to.w(), to.h()], + Self::Y(y, _) => [to.x(), to.y() + y, to.w(), to.h()], + Self::XY(x, y, _) => [to.x() + x, to.y() + y, to.w(), to.h()] + }.into())) } fn render (&self, to: &mut E) -> Perhaps { Ok(self.layout(to.area())?.map(|a|to.render_in(a, self.inner())).transpose()?.flatten()) diff --git a/crates/tek_core/src/test.rs b/crates/tek_core/src/test.rs index 5b04e761..01fe8c98 100644 --- a/crates/tek_core/src/test.rs +++ b/crates/tek_core/src/test.rs @@ -14,87 +14,126 @@ impl Widget for TestArea { } #[test] -fn test_offset () -> Usually<()> { - let area: [u16;4] = [50, 50, 100, 100]; - let test = TestArea(3, 3); - assert_eq!(Offset::X(1, test).layout(area)?, Some([51, 50, 3, 3])); - assert_eq!(Offset::Y(1, test).layout(area)?, Some([50, 51, 3, 3])); - assert_eq!(Offset::XY(1, 1, test).layout(area)?, Some([51, 51, 3, 3])); - Ok(()) -} - -#[test] -fn test_outset () -> Usually<()> { - let area: [u16;4] = [50, 50, 100, 100]; - let test = TestArea(3, 3); - assert_eq!(Outset::X(1, test).layout(area)?, Some([49, 50, 5, 1])); - assert_eq!(Outset::Y(1, test).layout(area)?, Some([50, 49, 1, 5])); - assert_eq!(Outset::XY(1, 1, test).layout(area)?, Some([49, 49, 5, 5])); - Ok(()) -} - -#[test] -fn test_inset () -> Usually<()> { - let area: [u16;4] = [50, 50, 100, 100]; - let test = TestArea(3, 3); - assert_eq!(Inset::X(1, test).layout(area)?, Some([51, 50, 1, 3])); - assert_eq!(Inset::Y(1, test).layout(area)?, Some([50, 51, 3, 1])); - assert_eq!(Inset::XY(1, 1, test).layout(area)?, Some([51, 51, 1, 1])); - Ok(()) -} - -#[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::X(1, Split::right(|add|{add(&"1")?;add(&"333")})).layout(area)?, - Some([0, 1, 6, 1])); - assert_eq!(Outset::Y(1, Split::right(|add|{add(&"1")?;add(&"333")})).layout(area)?, - Some([1, 0, 4, 3])); - assert_eq!(Outset::XY(1, 1, Split::right(|add|{add(&"1")?;add(&"333")})).layout(area)?, - Some([0, 0, 6, 3])); - assert_eq!(Split::down(|add|{ - add(&Outset::XY(1, 1, "1"))?; - add(&Outset::XY(1, 1, "333")) - }).layout(area)?, - Some([1, 1, 5, 6])); - let area: [u16;4] = [1, 1, 95, 100]; +fn test_misc () -> Usually<()> { + let area: [u16;4] = [0, 0, 10, 10]; + let test = TestArea(4, 4); + assert_eq!(test.layout(area)?, + Some([0, 0, 4, 4])); + assert_eq!(Align::Center(test).layout(area)?, + Some([3, 3, 4, 4])); assert_eq!(Align::Center(Split::down(|add|{ - add(&Outset::XY(1, 1, "1"))?; - add(&Outset::XY(1, 1, "333")) + add(&test)?; + add(&test) })).layout(area)?, - Some([46, 48, 5, 6])); + Some([3, 1, 4, 8])); assert_eq!(Align::Center(Split::down(|add|{ - add(&Layers::new(|add|{ - //add(&Outset::XY(1, 1, FillBg(Color::Rgb(0,128,0))))?; - add(&Outset::XY(1, 1, "1"))?; - add(&Outset::XY(1, 1, "333"))?; - //add(&FillBg(Color::Rgb(0,128,0)))?; - Ok(()) + add(&Outset::XY(2, 2, test))?; + add(&test) + })).layout(area)?, + Some([2, 0, 6, 10])); + assert_eq!(Align::Center(Split::down(|add|{ + add(&Outset::XY(2, 2, test))?; + add(&Inset::XY(2, 2, test)) + })).layout(area)?, + Some([2, 1, 6, 8])); + assert_eq!(Split::down(|add|{ + add(&Outset::XY(2, 2, test))?; + add(&Inset::XY(2, 2, test)) + }).layout(area)?, + Some([0, 0, 6, 8])); + assert_eq!(Split::right(|add|{ + add(&Split::down(|add|{ + add(&Outset::XY(2, 2, test))?; + add(&Inset::XY(2, 2, test)) }))?; - add(&Layers::new(|add|{ - //add(&Outset::XY(1, 1, FillBg(Color::Rgb(0,0,128))))?; - add(&Outset::XY(1, 1, "555"))?; - add(&Outset::XY(1, 1, "777777"))?; - //add(&FillBg(Color::Rgb(0,0,128)))?; - Ok(()) - })) - })).layout(area)?, - Some([46, 48, 5, 6])); + add(&Align::Center(TestArea(2 ,2))) + }).layout(area)?, + Some([0, 0, 8, 8])); Ok(()) } + +//#[test] +//fn test_offset () -> Usually<()> { + //let area: [u16;4] = [50, 50, 100, 100]; + //let test = TestArea(3, 3); + //assert_eq!(Offset::X(1, test).layout(area)?, Some([51, 50, 3, 3])); + //assert_eq!(Offset::Y(1, test).layout(area)?, Some([50, 51, 3, 3])); + //assert_eq!(Offset::XY(1, 1, test).layout(area)?, Some([51, 51, 3, 3])); + //Ok(()) +//} + +//#[test] +//fn test_outset () -> Usually<()> { + //let area: [u16;4] = [50, 50, 100, 100]; + //let test = TestArea(3, 3); + //assert_eq!(Outset::X(1, test).layout(area)?, Some([49, 50, 5, 3])); + //assert_eq!(Outset::Y(1, test).layout(area)?, Some([50, 49, 3, 5])); + //assert_eq!(Outset::XY(1, 1, test).layout(area)?, Some([49, 49, 5, 5])); + //Ok(()) +//} + +//#[test] +//fn test_inset () -> Usually<()> { + //let area: [u16;4] = [50, 50, 100, 100]; + //let test = TestArea(3, 3); + //assert_eq!(Inset::X(1, test).layout(area)?, Some([51, 50, 1, 3])); + //assert_eq!(Inset::Y(1, test).layout(area)?, Some([50, 51, 3, 1])); + //assert_eq!(Inset::XY(1, 1, test).layout(area)?, Some([51, 51, 1, 1])); + //Ok(()) +//} + +//#[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::X(1, Split::right(|add|{add(&"1")?;add(&"333")})).layout(area)?, + //Some([0, 1, 6, 1])); + //assert_eq!(Outset::Y(1, Split::right(|add|{add(&"1")?;add(&"333")})).layout(area)?, + //Some([1, 0, 4, 3])); + //assert_eq!(Outset::XY(1, 1, Split::right(|add|{add(&"1")?;add(&"333")})).layout(area)?, + //Some([0, 0, 6, 3])); + //assert_eq!(Split::down(|add|{ + //add(&Outset::XY(1, 1, "1"))?; + //add(&Outset::XY(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::XY(1, 1, "1"))?; + //add(&Outset::XY(1, 1, "333")) + //})).layout(area)?, + //Some([46, 48, 5, 6])); + //assert_eq!(Align::Center(Split::down(|add|{ + //add(&Layers::new(|add|{ + ////add(&Outset::XY(1, 1, FillBg(Color::Rgb(0,128,0))))?; + //add(&Outset::XY(1, 1, "1"))?; + //add(&Outset::XY(1, 1, "333"))?; + ////add(&FillBg(Color::Rgb(0,128,0)))?; + //Ok(()) + //}))?; + //add(&Layers::new(|add|{ + ////add(&Outset::XY(1, 1, FillBg(Color::Rgb(0,0,128))))?; + //add(&Outset::XY(1, 1, "555"))?; + //add(&Outset::XY(1, 1, "777777"))?; + ////add(&FillBg(Color::Rgb(0,0,128)))?; + //Ok(()) + //})) + //})).layout(area)?, + //Some([46, 48, 5, 6])); + //Ok(()) +//}