add origin and align methods to Layout trait

This commit is contained in:
facile pop culture reference 2026-07-10 18:24:44 +03:00
parent 09463649c6
commit 13c886d9e0
18 changed files with 333 additions and 248 deletions

View file

@ -70,11 +70,96 @@ pub trait Layout<S: Screen>: Draw<S> + Sized {
fn push_xy <N: Into<Option<S::Unit>>> (self, x: N, y: N) -> impl Draw<S> {
Push::XY(self, x.into(), y.into())
}
fn align (self, azimuth: impl Into<Option<Azimuth>>) -> impl Draw<S> {
Align(azimuth.into(), self)
}
fn align_c (self) -> impl Draw<S> {
Align(Some(Azimuth::C), self)
}
fn align_x (self) -> impl Draw<S> {
Align(Some(Azimuth::X), self)
}
fn align_y (self) -> impl Draw<S> {
Align(Some(Azimuth::Y), self)
}
fn align_n (self) -> impl Draw<S> {
Align(Some(Azimuth::N), self)
}
fn align_s (self) -> impl Draw<S> {
Align(Some(Azimuth::S), self)
}
fn align_e (self) -> impl Draw<S> {
Align(Some(Azimuth::E), self)
}
fn align_w (self) -> impl Draw<S> {
Align(Some(Azimuth::W), self)
}
fn align_ne (self) -> impl Draw<S> {
Align(Some(Azimuth::NE), self)
}
fn align_se (self) -> impl Draw<S> {
Align(Some(Azimuth::SE), self)
}
fn align_nw (self) -> impl Draw<S> {
Align(Some(Azimuth::NW), self)
}
fn align_sw (self) -> impl Draw<S> {
Align(Some(Azimuth::SW), self)
}
fn origin (self, azimuth: impl Into<Option<Azimuth>>) -> impl Draw<S> {
Origin(azimuth.into(), self)
}
fn origin_c (self) -> impl Draw<S> {
Origin(Some(Azimuth::C), self)
}
fn origin_x (self) -> impl Draw<S> {
Origin(Some(Azimuth::X), self)
}
fn origin_y (self) -> impl Draw<S> {
Origin(Some(Azimuth::Y), self)
}
fn origin_n (self) -> impl Draw<S> {
Origin(Some(Azimuth::N), self)
}
fn origin_s (self) -> impl Draw<S> {
Origin(Some(Azimuth::S), self)
}
fn origin_e (self) -> impl Draw<S> {
Origin(Some(Azimuth::E), self)
}
fn origin_w (self) -> impl Draw<S> {
Origin(Some(Azimuth::W), self)
}
fn origin_ne (self) -> impl Draw<S> {
Origin(Some(Azimuth::NE), self)
}
fn origin_se (self) -> impl Draw<S> {
Origin(Some(Azimuth::SE), self)
}
fn origin_nw (self) -> impl Draw<S> {
Origin(Some(Azimuth::NW), self)
}
fn origin_sw (self) -> impl Draw<S> {
Origin(Some(Azimuth::SW), self)
}
}
impl<S: Screen, T: Draw<S>> Layout<S> for T {}
/// Use whole drawing area along one or both axes.
///
/// ```
/// use tengri::Layout;
/// let _ = "".full_w();
/// let _ = "".full_h();
/// let _ = "".full_wh();
/// ```
pub enum Full<T: Screen, I: Draw<T>> {
__(PhantomData<T>),
W(I),
@ -82,14 +167,17 @@ pub enum Full<T: Screen, I: Draw<T>> {
WH(I),
}
impl_draw!(<T: Screen, I: Draw<T>,>|self: Full<T, I>, to: T|{
impl_draw!(<T: Screen, I: Draw<T>,>|self: Full<T, I>, _to: T|{
todo!()
});
/// Only draw content if area is above a certain size.
/// Move content in the positive direction of one or both axes.
///
/// ```
/// let min = tengri::wh_min(3, 5, "Hello"); // 5x5
/// use tengri::Layout;
/// let _ = "".push_x(1);
/// let _ = "".push_y(1);
/// let _ = "".push_xy(1, 1);
/// ```
pub enum Push<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>> {
__(PhantomData<T>),
@ -98,14 +186,17 @@ pub enum Push<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>> {
XY(I, X, X),
}
impl_draw!(<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>,>|self: Push<T, I, X>, to: T|{
impl_draw!(<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>,>|self: Push<T, I, X>, _to: T|{
todo!()
});
/// Only draw content if area is above a certain size.
/// Move content in the negative direction of one or both axes.
///
/// ```
/// let min = tengri::wh_min(3, 5, "Hello"); // 5x5
/// use tengri::Layout;
/// let _ = "".pull_x(1);
/// let _ = "".pull_y(1);
/// let _ = "".pull_xy(1, 1);
/// ```
pub enum Pull<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>> {
__(PhantomData<T>),
@ -114,14 +205,17 @@ pub enum Pull<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>> {
XY(I, X, X),
}
impl_draw!(<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>,>|self: Pull<T, I, X>, to: T|{
impl_draw!(<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>,>|self: Pull<T, I, X>, _to: T|{
todo!()
});
/// Only draw content if area is above a certain size.
///
/// ```
/// let min = tengri::wh_min(3, 5, "Hello"); // 5x5
/// use tengri::Layout;
/// let _ = "".min_w(1);
/// let _ = "".min_h(1);
/// let _ = "".min_wh(1, 1);
/// ```
pub enum Min<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>> {
__(PhantomData<T>),
@ -130,16 +224,17 @@ pub enum Min<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>> {
WH(I, X, X),
}
impl_draw!(<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>,>|self: Min<T, I, X>, to: T|{
impl_draw!(<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>,>|self: Min<T, I, X>, _to: T|{
todo!()
});
/// Set maximum size of of drawing area.
///
/// ```
/// let max = tengri::w_max(3, "Hello");
/// let max = tengri::w_max(None, "Hello");
/// let max = tengri::w_max(Some(3), "Hello");
/// use tengri::Layout;
/// let _ = "".max_w(1);
/// let _ = "".max_h(1);
/// let _ = "".max_wh(1, 1);
/// ```
pub enum Max<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>> {
__(PhantomData<T>),
@ -148,16 +243,17 @@ pub enum Max<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>> {
WH(I, X, X),
}
impl_draw!(<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>,>|self: Max<T, I, X>, to: T|{
impl_draw!(<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>,>|self: Max<T, I, X>, _to: T|{
todo!()
});
/// Set size of of drawing area.
///
/// ```
/// let max = tengri::w_max(3, "Hello");
/// let max = tengri::w_max(None, "Hello");
/// let max = tengri::w_max(Some(3), "Hello");
/// use tengri::Layout;
/// let _ = "".exact_w(1);
/// let _ = "".exact_h(1);
/// let _ = "".exact_wh(1, 1);
/// ```
pub enum Exact<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>> {
__(PhantomData<T>),
@ -166,16 +262,17 @@ pub enum Exact<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>> {
WH(I, X, X),
}
impl_draw!(<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>,>|self: Exact<T, I, X>, to: T|{
impl_draw!(<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>,>|self: Exact<T, I, X>, _to: T|{
todo!()
});
/// Define inner drawing area.
///
/// ```
/// let max = tengri::w_max(3, "Hello");
/// let max = tengri::w_max(None, "Hello");
/// let max = tengri::w_max(Some(3), "Hello");
/// use tengri::Layout;
/// let _ = "".pad_w(1);
/// let _ = "".pad_h(1);
/// let _ = "".pad_wh(1, 1);
/// ```
pub enum Pad<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>> {
__(PhantomData<T>),
@ -184,6 +281,59 @@ pub enum Pad<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>> {
WH(I, X, X),
}
impl_draw!(<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>,>|self: Pad<T, I, X>, to: T|{
impl_draw!(<T: Screen, I: Draw<T>, X: Into<Option<T::Unit>>,>|self: Pad<T, I, X>, _to: T|{
todo!()
});
pub struct Align<T>(Option<Azimuth>, T);
impl_draw!(<S: Screen, T: Draw<S>,>|self: Align<T>, _to: S|{
todo!()
});
/// Where is [0, 0] located?
///
/// ```
/// use tengri::*;
/// use Azimuth::*;
/// let _ = "".align(NW);
/// ```
#[cfg_attr(test, derive(Arbitrary))]
#[derive(Debug, Copy, Clone, Default)] pub enum Azimuth {
#[default] C, X, Y, NW, N, NE, E, SE, S, SW, W
}
/// ```
/// use tengri::*;
/// let _ = area(None, "unareaed");
/// let _ = area(XYWH(1, 2, 3, 4), "southeast");
/// let _ = area(Some(XYWH(1, 2, 3, 4)), "southeast");
/// ```
pub fn area <S: Screen, T: Draw<S>, U: Into<Option<XYWH<S::Unit>>>> (
origin: U, it: T
) -> Area<S, T> {
Area(origin.into(), it)
}
pub struct Area<S: Screen, T: Draw<S>>(Option<XYWH<S::Unit>>, T);
impl_draw!(<S: Screen, T: Draw<S>,>|self: Area<S, T>, _to: S|{
todo!()
});
pub struct Origin<T>(Option<Azimuth>, T);
impl_draw!(<S: Screen, T: Draw<S>,>|self: Origin<T>, _to: S|{
todo!()
});
/// Something that has `[0, 0]` at a particular point.
pub trait HasOrigin {
fn origin (&self) -> Azimuth;
}
impl<T: AsRef<Azimuth>> HasOrigin for T {
fn origin (&self) -> Azimuth {
*self.as_ref()
}
}