From b25977d878713f3ab89ed12b910eed67a1f88524 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sat, 17 May 2025 05:47:51 +0300 Subject: [PATCH 1/2] add has!, MaybeHas, maybe_has! --- core/src/lib.rs | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/core/src/lib.rs b/core/src/lib.rs index f3cf313..b512ae9 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -16,6 +16,29 @@ pub type Perhaps = Result, Box>; } pub trait Has: Send + Sync { - fn get (&self) -> &T; + fn get (&self) -> &T; fn get_mut (&mut self) -> &mut T; } + +#[macro_export] macro_rules! has { + ($T:ty: |$self:ident : $S:ty| $x:expr) => { + impl Has<$T> for $S { + fn get (&$self) -> &$T { &$x } + fn get_mut (&mut $self) -> &mut $T { &mut $x } + } + }; +} + +pub trait MaybeHas: Send + Sync { + fn get (&self) -> Option<&T>; + fn get_mut (&mut self) -> Option<&mut T>; +} + +#[macro_export] macro_rules! maybe_has { + ($T:ty: |$self:ident : $S:ty| $x:block; $y:block $(;)?) => { + impl MaybeHas<$T> for $S { + fn get (&$self) -> Option<&$T> $x + fn get_mut (&mut $self) -> Option<&mut $T> $y + } + }; +} From a55e84c29f51606e0996f7f88b7664ca0d37365b Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sat, 17 May 2025 10:15:07 +0300 Subject: [PATCH 2/2] output, tui: Stack implementation --- output/src/ops.rs | 1 + output/src/ops/stack.rs | 82 ++++++++++++++++++++++++++++++++ output/src/output.rs | 2 +- tui/src/tui_engine/tui_output.rs | 2 +- 4 files changed, 85 insertions(+), 2 deletions(-) diff --git a/output/src/ops.rs b/output/src/ops.rs index 2cd1784..4c6ea2a 100644 --- a/output/src/ops.rs +++ b/output/src/ops.rs @@ -2,6 +2,7 @@ mod align; pub use self::align::*; mod bsp; pub use self::bsp::*; mod cond; pub use self::cond::*; mod map; pub use self::map::*; +mod stack; pub use self::stack::*; //mod reduce; pub use self::reduce::*; mod thunk; pub use self::thunk::*; mod transform; pub use self::transform::*; diff --git a/output/src/ops/stack.rs b/output/src/ops/stack.rs index ba8b949..816713c 100644 --- a/output/src/ops/stack.rs +++ b/output/src/ops/stack.rs @@ -1,3 +1,85 @@ +use crate::*; + +pub struct Stack { + __: PhantomData, + direction: Direction, + callback: F +} +impl Stack { + pub fn new (direction: Direction, callback: F) -> Self { + Self { direction, callback, __: Default::default(), } + } + pub fn north (callback: F) -> Self { + Self::new(Direction::North, callback) + } + pub fn south (callback: F) -> Self { + Self::new(Direction::South, callback) + } + pub fn east (callback: F) -> Self { + Self::new(Direction::East, callback) + } + pub fn west (callback: F) -> Self { + Self::new(Direction::West, callback) + } +} +impl)->())->()> Content for Stack { + fn layout (&self, mut to: E::Area) -> E::Area { + let mut x = to.x(); + let mut y = to.y(); + let mut w = to.w(); + let mut h = to.h(); + (self.callback)(&mut move |component: &dyn Render|{ + let layout = component.layout([x, y, w, h].into()); + match self.direction { + Direction::North => { + todo!() + }, + Direction::South => { + y = y + layout.h(); + h = h.minus(layout.h()); + }, + Direction::East => { + x = x + layout.w(); + w = w.minus(layout.w()); + }, + Direction::West => { + todo!() + }, + _ => unreachable!(), + } + }); + to + } + fn render (&self, to: &mut E) { + let mut x = to.x(); + let mut y = to.y(); + let mut w = to.w(); + let mut h = to.h(); + (self.callback)(&mut move |component: &dyn Render|{ + let layout = component.layout([x, y, w, h].into()); + match self.direction { + Direction::North => { + todo!() + }, + Direction::South => { + y = y + layout.h(); + h = h.minus(layout.h()); + to.place(layout, component); + }, + Direction::East => { + x = x + layout.w(); + w = w.minus(layout.w()); + to.place(layout, component); + }, + Direction::West => { + todo!() + }, + _ => unreachable!() + } + }); + } +} + /*Stack::down(|add|{ let mut i = 0; for (_, name) in self.dirs.iter() { diff --git a/output/src/output.rs b/output/src/output.rs index 98e3659..b5cc1fc 100644 --- a/output/src/output.rs +++ b/output/src/output.rs @@ -14,7 +14,7 @@ pub trait Output: Send + Sync + Sized { /// Mutable pointer to area fn area_mut (&mut self) -> &mut Self::Area; /// Render widget in area - fn place (&mut self, area: Self::Area, content: &impl Render); + fn place + ?Sized> (&mut self, area: Self::Area, content: &T); #[inline] fn x (&self) -> Self::Unit { self.area().x() } #[inline] fn y (&self) -> Self::Unit { self.area().y() } #[inline] fn w (&self) -> Self::Unit { self.area().w() } diff --git a/tui/src/tui_engine/tui_output.rs b/tui/src/tui_engine/tui_output.rs index 161f146..33b46ff 100644 --- a/tui/src/tui_engine/tui_output.rs +++ b/tui/src/tui_engine/tui_output.rs @@ -12,7 +12,7 @@ impl Output for TuiOut { type Area = [Self::Unit;4]; #[inline] fn area (&self) -> [u16;4] { self.area } #[inline] fn area_mut (&mut self) -> &mut [u16;4] { &mut self.area } - #[inline] fn place (&mut self, area: [u16;4], content: &impl Render) { + #[inline] fn place + ?Sized> (&mut self, area: [u16;4], content: &T) { let last = self.area(); *self.area_mut() = area; content.render(self);