mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 04:06:45 +01:00
Offset -> Plus; add Minus
This commit is contained in:
parent
dc03a664a4
commit
00da7de142
5 changed files with 176 additions and 77 deletions
|
|
@ -36,22 +36,27 @@ impl Demo<Tui> {
|
||||||
impl Content for Demo<Tui> {
|
impl Content for Demo<Tui> {
|
||||||
type Engine = Tui;
|
type Engine = Tui;
|
||||||
fn content (&self) -> impl Widget<Engine = Tui> {
|
fn content (&self) -> impl Widget<Engine = Tui> {
|
||||||
Align::Center(Layers::new(|add|{
|
Layers::new(|add|{
|
||||||
add(&FillBg(Color::Rgb(128,0,0)))?;
|
add(&FillBg(Color::Rgb(128,0,0)))?;
|
||||||
add(&Outset::XY(2, 2, Align::Center(Split::down(|add|{
|
add(&Outset::X(1, "foo"))?;
|
||||||
add(&Layers::new(|add|{
|
Ok(())
|
||||||
add(&FillBg(Color::Rgb(0,128,0)))?;
|
})
|
||||||
add(&Outset::XY(2, 2, Align::Center("12345")))?;
|
//Align::Y(Layers::new(|add|{
|
||||||
add(&Align::Center("FOO"))
|
//add(&FillBg(Color::Rgb(128,0,0)))?;
|
||||||
}))?;
|
//add(&Outset::X(1, Align::Center(Split::down(|add|{
|
||||||
add(&Layers::new(|add|{
|
//add(&Align::X(Layers::new(|add|{
|
||||||
add(&Outset::XY(2, 2, Align::Center("1234567")))?;
|
//add(&FillBg(Color::Rgb(0,128,0)))?;
|
||||||
add(&Align::Center("BAR"))?;
|
//add(&Outset::Y(1, Align::Center("12345")))?;
|
||||||
add(&FillBg(Color::Rgb(0,0,128)))
|
//add(&Align::Center("FOO"))
|
||||||
}))?;
|
//})))?;
|
||||||
Ok(())
|
//add(&Layers::new(|add|{
|
||||||
}))))
|
//add(&Outset::XY(1, 1, Align::Center("1234567")))?;
|
||||||
}))
|
//add(&Align::Center("BAR"))?;
|
||||||
|
//add(&FillBg(Color::Rgb(0,0,128)))
|
||||||
|
//}))?;
|
||||||
|
//Ok(())
|
||||||
|
//}))))
|
||||||
|
//}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -351,6 +351,10 @@ impl Direction {
|
||||||
pub enum Align<L> {
|
pub enum Align<L> {
|
||||||
/// Draw at center of container
|
/// Draw at center of container
|
||||||
Center(L),
|
Center(L),
|
||||||
|
/// Draw at center of X axis
|
||||||
|
X(L),
|
||||||
|
/// Draw at center of Y axis
|
||||||
|
Y(L),
|
||||||
/// Draw at upper left corner of contaier
|
/// Draw at upper left corner of contaier
|
||||||
NW(L),
|
NW(L),
|
||||||
/// Draw at center of upper edge of container
|
/// Draw at center of upper edge of container
|
||||||
|
|
@ -373,6 +377,8 @@ impl<T> Align<T> {
|
||||||
pub fn inner (&self) -> &T {
|
pub fn inner (&self) -> &T {
|
||||||
match self {
|
match self {
|
||||||
Self::Center(inner) => inner,
|
Self::Center(inner) => inner,
|
||||||
|
Self::X(inner) => inner,
|
||||||
|
Self::Y(inner) => inner,
|
||||||
Self::NW(inner) => inner,
|
Self::NW(inner) => inner,
|
||||||
Self::N(inner) => inner,
|
Self::N(inner) => inner,
|
||||||
Self::NE(inner) => inner,
|
Self::NE(inner) => inner,
|
||||||
|
|
@ -396,6 +402,18 @@ impl<E: Engine, T: Widget<Engine = E>> Widget for Align<T> {
|
||||||
let result = [outer_area.x() + offset_x, outer_area.y() + offset_y, w, h];
|
let result = [outer_area.x() + offset_x, outer_area.y() + offset_y, w, h];
|
||||||
result.into()
|
result.into()
|
||||||
}),
|
}),
|
||||||
|
Self::X(_) => self.inner().layout(outer_area)?.map(|inner_area|{
|
||||||
|
let [_, y, w, h] = inner_area.xywh();
|
||||||
|
let offset_x = (outer_area.w() - w) / 2.into();
|
||||||
|
let result = [outer_area.x() + offset_x, y, w, h];
|
||||||
|
result.into()
|
||||||
|
}),
|
||||||
|
Self::Y(_) => self.inner().layout(outer_area)?.map(|inner_area|{
|
||||||
|
let [x, _, w, h] = inner_area.xywh();
|
||||||
|
let offset_y = (outer_area.h() / 2.into()) - (h / 2.into());
|
||||||
|
let result = [x, outer_area.y() + offset_y, w, h];
|
||||||
|
result.into()
|
||||||
|
}),
|
||||||
Self::NW(_) => { todo!() },
|
Self::NW(_) => { todo!() },
|
||||||
Self::N(_) => { todo!() },
|
Self::N(_) => { todo!() },
|
||||||
Self::NE(_) => { todo!() },
|
Self::NE(_) => { todo!() },
|
||||||
|
|
@ -583,7 +601,7 @@ impl<N: Number, T: Widget> Outset<N, T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Move origin point of drawing area
|
/// Move origin point of drawing area
|
||||||
pub enum Offset<N: Number, T: Widget> {
|
pub enum Plus<N: Number, T: Widget> {
|
||||||
/// Move origin to the right
|
/// Move origin to the right
|
||||||
X(N, T),
|
X(N, T),
|
||||||
/// Move origin downwards
|
/// Move origin downwards
|
||||||
|
|
@ -592,7 +610,7 @@ pub enum Offset<N: Number, T: Widget> {
|
||||||
XY(N, N, T),
|
XY(N, N, T),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Number, T: Widget> Offset<N, T> {
|
impl<N: Number, T: Widget> Plus<N, T> {
|
||||||
fn inner (&self) -> &T {
|
fn inner (&self) -> &T {
|
||||||
match self { Self::X(_, i) => i, Self::Y(_, i) => i, Self::XY(_, _, i) => i, }
|
match self { Self::X(_, i) => i, Self::Y(_, i) => i, Self::XY(_, _, i) => i, }
|
||||||
}
|
}
|
||||||
|
|
@ -604,7 +622,7 @@ impl<N: Number, T: Widget> Offset<N, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Engine, T: Widget<Engine = E>> Widget for Offset<E::Unit, T> {
|
impl<E: Engine, T: Widget<Engine = E>> Widget for Plus<E::Unit, T> {
|
||||||
type Engine = E;
|
type Engine = E;
|
||||||
fn layout (&self, to: E::Area) -> Perhaps<E::Area> {
|
fn layout (&self, to: E::Area) -> Perhaps<E::Area> {
|
||||||
Ok(self.inner().layout(to)?.map(|to|match *self {
|
Ok(self.inner().layout(to)?.map(|to|match *self {
|
||||||
|
|
@ -618,6 +636,42 @@ impl<E: Engine, T: Widget<Engine = E>> Widget for Offset<E::Unit, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Move origin point of drawing area
|
||||||
|
pub enum Minus<N: Number, T: Widget> {
|
||||||
|
/// Move origin to the right
|
||||||
|
X(N, T),
|
||||||
|
/// Move origin downwards
|
||||||
|
Y(N, T),
|
||||||
|
/// Move origin to the right and downwards
|
||||||
|
XY(N, N, T),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: Number, T: Widget> Minus<N, T> {
|
||||||
|
fn inner (&self) -> &T {
|
||||||
|
match self { Self::X(_, i) => i, Self::Y(_, i) => i, Self::XY(_, _, i) => i, }
|
||||||
|
}
|
||||||
|
fn x (&self) -> N {
|
||||||
|
match self { Self::X(x, _) => *x, Self::Y(_, _) => N::default(), Self::XY(x, _, _) => *x }
|
||||||
|
}
|
||||||
|
fn y (&self) -> N {
|
||||||
|
match self { Self::X(_, _) => N::default(), Self::Y(y, _) => *y, Self::XY(_, y, _) => *y }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: Engine, T: Widget<Engine = E>> Widget for Minus<E::Unit, T> {
|
||||||
|
type Engine = E;
|
||||||
|
fn layout (&self, to: E::Area) -> Perhaps<E::Area> {
|
||||||
|
Ok(self.inner().layout(to)?.map(|to|match *self {
|
||||||
|
Self::X(x, _) => [to.x().minus(x), to.y(), to.w(), to.h()],
|
||||||
|
Self::Y(y, _) => [to.x(), to.y().minus(y), to.w(), to.h()],
|
||||||
|
Self::XY(x, y, _) => [to.x().minus(x), to.y().minus(y), to.w(), to.h()]
|
||||||
|
}.into()))
|
||||||
|
}
|
||||||
|
fn render (&self, to: &mut E) -> Perhaps<E::Area> {
|
||||||
|
Ok(self.layout(to.area())?.map(|a|to.render_in(a, self.inner())).transpose()?.flatten())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A component that may contain [Focusable] components.
|
/// A component that may contain [Focusable] components.
|
||||||
pub trait Focus <const N: usize, E: Engine>: Widget<Engine = E> + Handle<E> {
|
pub trait Focus <const N: usize, E: Engine>: Widget<Engine = E> + Handle<E> {
|
||||||
fn focus (&self) -> usize;
|
fn focus (&self) -> usize;
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,16 @@ pub trait Number: Send + Sync + Copy
|
||||||
+ Div<Self, Output=Self>
|
+ Div<Self, Output=Self>
|
||||||
+ Ord + PartialEq + Eq
|
+ Ord + PartialEq + Eq
|
||||||
+ Debug + Display + Default
|
+ Debug + Display + Default
|
||||||
+ From<u16> {}
|
+ From<u16>
|
||||||
|
{
|
||||||
|
fn minus (self, other: Self) -> Self {
|
||||||
|
if self >= other {
|
||||||
|
self - other
|
||||||
|
} else {
|
||||||
|
0.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> Number for T where
|
impl<T> Number for T where
|
||||||
T: Send + Sync + Copy
|
T: Send + Sync + Copy
|
||||||
|
|
|
||||||
|
|
@ -14,51 +14,68 @@ impl Widget for TestArea {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_misc () -> Usually<()> {
|
fn test_0 () -> Usually<()> {
|
||||||
let area: [u16;4] = [0, 0, 10, 10];
|
let area: [u16;4] = [0, 0, 10, 10];
|
||||||
let test = TestArea(4, 4);
|
let test = TestArea(4, 4);
|
||||||
assert_eq!(test.layout(area)?,
|
assert_eq!(test.layout(area)?,
|
||||||
Some([0, 0, 4, 4]));
|
Some([0, 0, 4, 4]));
|
||||||
assert_eq!(Align::Center(test).layout(area)?,
|
assert_eq!(Outset::X(1, test).layout(area)?,
|
||||||
Some([3, 3, 4, 4]));
|
Some([0, 0, 6, 4]));
|
||||||
assert_eq!(Align::Center(Split::down(|add|{
|
assert_eq!(Align::X(test).layout(area)?,
|
||||||
add(&test)?;
|
Some([3, 0, 4, 4]));
|
||||||
add(&test)
|
assert_eq!(Align::X(Outset::X(1, test)).layout(area)?,
|
||||||
})).layout(area)?,
|
Some([2, 0, 6, 4]));
|
||||||
Some([3, 1, 4, 8]));
|
assert_eq!(Outset::X(1, Align::X(test)).layout(area)?,
|
||||||
assert_eq!(Align::Center(Split::down(|add|{
|
Some([2, 0, 6, 4]));
|
||||||
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(&Align::Center(TestArea(2 ,2)))
|
|
||||||
}).layout(area)?,
|
|
||||||
Some([0, 0, 8, 8]));
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#[test]
|
||||||
|
//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(&test)?;
|
||||||
|
//add(&test)
|
||||||
|
//})).layout(area)?,
|
||||||
|
//Some([3, 1, 4, 8]));
|
||||||
|
//assert_eq!(Align::Center(Split::down(|add|{
|
||||||
|
//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(&Align::Center(TestArea(2 ,2)))
|
||||||
|
//}).layout(area)?,
|
||||||
|
//Some([0, 0, 8, 8]));
|
||||||
|
//Ok(())
|
||||||
|
//}
|
||||||
|
|
||||||
//#[test]
|
//#[test]
|
||||||
//fn test_offset () -> Usually<()> {
|
//fn test_offset () -> Usually<()> {
|
||||||
//let area: [u16;4] = [50, 50, 100, 100];
|
//let area: [u16;4] = [50, 50, 100, 100];
|
||||||
//let test = TestArea(3, 3);
|
//let test = TestArea(3, 3);
|
||||||
//assert_eq!(Offset::X(1, test).layout(area)?, Some([51, 50, 3, 3]));
|
//assert_eq!(Plus::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!(Plus::Y(1, test).layout(area)?, Some([50, 51, 3, 3]));
|
||||||
//assert_eq!(Offset::XY(1, 1, test).layout(area)?, Some([51, 51, 3, 3]));
|
//assert_eq!(Plus::XY(1, 1, test).layout(area)?, Some([51, 51, 3, 3]));
|
||||||
//Ok(())
|
//Ok(())
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -487,7 +487,7 @@ where
|
||||||
if h >= to.h() {
|
if h >= to.h() {
|
||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
let area = Offset::Y(h, component as &dyn Widget<Engine = Tui>).layout(to)?;
|
let area = Plus::Y(h, component as &dyn Widget<Engine = Tui>).layout(to)?;
|
||||||
if let Some([_, _, width, height]) = area {
|
if let Some([_, _, width, height]) = area {
|
||||||
h += height;
|
h += height;
|
||||||
w = w.max(width)
|
w = w.max(width)
|
||||||
|
|
@ -500,7 +500,7 @@ where
|
||||||
if w >= to.w() {
|
if w >= to.w() {
|
||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
let area = Offset::X(w, component as &dyn Widget<Engine = Tui>).layout(to)?;
|
let area = Plus::X(w, component as &dyn Widget<Engine = Tui>).layout(to)?;
|
||||||
if let Some([_, _, width, height]) = area {
|
if let Some([_, _, width, height]) = area {
|
||||||
w += width;
|
w += width;
|
||||||
h = h.max(height)
|
h = h.max(height)
|
||||||
|
|
@ -522,7 +522,7 @@ where
|
||||||
if h >= area.h() {
|
if h >= area.h() {
|
||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
let area = Offset::Y(h, component as &dyn Widget<Engine = Tui>).render(to)?;
|
let area = Plus::Y(h, component as &dyn Widget<Engine = Tui>).render(to)?;
|
||||||
if let Some([_, _, width, height]) = area {
|
if let Some([_, _, width, height]) = area {
|
||||||
h += height;
|
h += height;
|
||||||
w = w.max(width)
|
w = w.max(width)
|
||||||
|
|
@ -535,7 +535,7 @@ where
|
||||||
if w >= area.w() {
|
if w >= area.w() {
|
||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
let area = Offset::X(w, component as &dyn Widget<Engine = Tui>).render(to)?;
|
let area = Plus::X(w, component as &dyn Widget<Engine = Tui>).render(to)?;
|
||||||
if let Some([_, _, width, height]) = area {
|
if let Some([_, _, width, height]) = area {
|
||||||
w += width;
|
w += width;
|
||||||
h = h.max(height)
|
h = h.max(height)
|
||||||
|
|
@ -578,31 +578,45 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Widget<Engine = Tui>> Widget for Inset<u16, T> {
|
impl<T: Widget<Engine = Tui>> Content for Inset<u16, T> {
|
||||||
type Engine = Tui;
|
type Engine = Tui;
|
||||||
fn layout (&self, to: [u16;4]) -> Perhaps<[u16;4]> {
|
fn content (&self) -> impl Widget<Engine = Tui> {
|
||||||
Align::Center(match self {
|
match self {
|
||||||
Self::X(x, inner) => Shrink::X(*x + *x, inner as &dyn Widget<Engine = Tui>),
|
Self::X(x, inner) =>
|
||||||
Self::Y(y, inner) => Shrink::X(*y + *y, inner as &dyn Widget<Engine = Tui>),
|
Plus::X(*x, Shrink::X(*x + *x, Align::X(inner as &dyn Widget<Engine = Tui>))),
|
||||||
Self::XY(x, y, inner) => Shrink::XY(*x, *y, inner as &dyn Widget<Engine = Tui>),
|
Self::Y(y, inner) =>
|
||||||
}).layout(to)
|
Plus::Y(*y, Shrink::X(*y + *y, Align::Y(inner as &dyn Widget<Engine = Tui>))),
|
||||||
}
|
Self::XY(x, y, inner) =>
|
||||||
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
|
Plus::XY(*x, *y, Shrink::XY(*x, *y, Align::Center(inner as &dyn Widget<Engine = Tui>))),
|
||||||
Ok(self.layout(to.area())?.map(|a|to.render_in(a, self.inner())).transpose()?.flatten())
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Widget<Engine = Tui>> Widget for Outset<u16, T> {
|
//impl<T: Widget<Engine = Tui>> Widget for Inset<u16, T> {
|
||||||
|
//type Engine = Tui;
|
||||||
|
//fn layout (&self, to: [u16;4]) -> Perhaps<[u16;4]> {
|
||||||
|
//match self {
|
||||||
|
//Self::X(x, inner) => Shrink::X(*x + *x, Align::Center(inner as &dyn Widget<Engine = Tui>)),
|
||||||
|
//Self::Y(y, inner) => Shrink::X(*y + *y, Align::Center(inner as &dyn Widget<Engine = Tui>)),
|
||||||
|
//Self::XY(x, y, inner) => Shrink::XY(*x, *y, Align::Center(inner as &dyn Widget<Engine = Tui>)),
|
||||||
|
//}.layout(to)
|
||||||
|
//}
|
||||||
|
//fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
|
||||||
|
//Ok(self.layout(to.area())?.map(|a|to.render_in(a, self.inner())).transpose()?.flatten())
|
||||||
|
//}
|
||||||
|
//}
|
||||||
|
|
||||||
|
impl<T: Widget<Engine = Tui>> Content for Outset<u16, T> {
|
||||||
type Engine = Tui;
|
type Engine = Tui;
|
||||||
fn layout (&self, to: [u16;4]) -> Perhaps<[u16;4]> {
|
fn content (&self) -> impl Widget<Engine = Tui> {
|
||||||
Align::Center(match self {
|
match *self {
|
||||||
Self::X(x, inner) => Grow::X(*x + *x, inner as &dyn Widget<Engine = Tui>),
|
Self::X(x, ref inner) =>
|
||||||
Self::Y(y, inner) => Grow::X(*y + *y, inner as &dyn Widget<Engine = Tui>),
|
Grow::X(x + x, inner as &dyn Widget<Engine = Tui>),
|
||||||
Self::XY(x, y, inner) => Grow::XY(*x, *y, inner as &dyn Widget<Engine = Tui>),
|
Self::Y(y, ref inner) =>
|
||||||
}).layout(to)
|
Grow::Y(y + y, inner as &dyn Widget<Engine = Tui>),
|
||||||
}
|
Self::XY(x, y, ref inner) =>
|
||||||
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
|
Grow::XY(x, y, inner as &dyn Widget<Engine = Tui>),
|
||||||
Ok(self.layout(to.area())?.map(|a|to.render_in(a, self.inner())).transpose()?.flatten())
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue