mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2026-09-18 13:26:42 +02:00
This commit is contained in:
parent
cf67185ffd
commit
799e497622
10 changed files with 456 additions and 460 deletions
|
|
@ -34,7 +34,9 @@ impl<T: AsRef<Azimuth>> HasOrigin for T {
|
|||
}
|
||||
|
||||
fn_kw_layout!(kw_align |state, output, expr| {
|
||||
Ok(matches!(expr.head()?, Some("align")).then(||{
|
||||
let head = expr.head();
|
||||
let mut frags = head.src()?.unwrap_or_default().split("/");
|
||||
Ok(matches!(frags.next(), Some("align")).then(||{
|
||||
draw(move|output: &mut O|{state.interpret(output, &expr.tail().head())}).align(
|
||||
eval_enum!("align", output, state,
|
||||
expr.head().src()?.unwrap_or_default().split("/").skip(1).next(),
|
||||
|
|
@ -95,9 +97,13 @@ pub struct Align<T>(
|
|||
|
||||
impl<S: Screen, T: Draw<S>> Draw<S> for Align<T> {
|
||||
fn draw (&self, to: &mut S) -> Perhaps<XYWH<S::Unit>> {
|
||||
let area = to.area();
|
||||
Ok(if let Some(area) = align::<S>(area, to.size(area, &self.1)?, self.0) {
|
||||
to.draw(area, &self.1)?
|
||||
let Self(azimuth, item) = self;
|
||||
let area0 = to.area();
|
||||
let size = to.size(area0, item)?;
|
||||
let area1 = align::<S>(area0, size, *azimuth);
|
||||
//println!("\n\r{azimuth:?} {area0:?} {size:?}=>{area1:?}");
|
||||
Ok(if let Some(area) = area1 {
|
||||
to.draw(area, &item)?
|
||||
} else {
|
||||
None
|
||||
})
|
||||
|
|
@ -176,84 +182,6 @@ impl<S: Screen, A: Draw<S>, B: Draw<S>> Draw<S> for Pair<S, A, B> {
|
|||
}
|
||||
}
|
||||
|
||||
impl Split {
|
||||
|
||||
/// ```
|
||||
/// use tengri::*;
|
||||
/// let _ = Split::Above.stack(&"", &"");
|
||||
/// let _ = Split::Below.stack(&"", &"");
|
||||
/// let _ = Split::North.stack(&"", &"");
|
||||
/// let _ = Split::South.stack(&"", &"");
|
||||
/// let _ = Split::East.stack(&"", &"");
|
||||
/// let _ = Split::West.stack(&"", &"");
|
||||
/// ```
|
||||
pub const fn stack <S: Screen, A: Draw<S>, B: Draw<S>> (&self, a: A, b: B) -> impl Draw<S> {
|
||||
Pair(*self, a, b, PhantomData)
|
||||
}
|
||||
|
||||
/// ```
|
||||
/// use tengri::*;
|
||||
/// let _ = Split::Above.half(&"", &"");
|
||||
/// let _ = Split::Below.half(&"", &"");
|
||||
/// let _ = Split::North.half(&"", &"");
|
||||
/// let _ = Split::South.half(&"", &"");
|
||||
/// let _ = Split::East.half(&"", &"");
|
||||
/// let _ = Split::West.half(&"", &"");
|
||||
/// ```
|
||||
pub const fn half <S: Screen, A: Draw<S>, B: Draw<S>> (&self, a: &A, b: &B) -> impl Draw<S> {
|
||||
draw(move|to: &mut S|{
|
||||
let (area_a, area_b) = to.xywh().split_half(self);
|
||||
let (origin_a, origin_b) = self.origins();
|
||||
let (drawn_a, drawn_b) = draw_stacks(self, to, a, area_a, origin_a, b, area_b, origin_b)?;
|
||||
Ok(stack_drawn(self, drawn_a, drawn_b))
|
||||
})
|
||||
}
|
||||
|
||||
/// Newly split areas begin at the center of the split
|
||||
/// to maintain centeredness in the user's field of view.
|
||||
///
|
||||
/// Use [align] to override that and always start
|
||||
/// at the top, bottom, etc.
|
||||
///
|
||||
/// ```
|
||||
/// /*
|
||||
///
|
||||
/// Split east: Split south:
|
||||
/// | | | | A |
|
||||
/// | <-A|B-> | |---------|
|
||||
/// | | | | B |
|
||||
///
|
||||
/// */
|
||||
/// ```
|
||||
const fn origins (&self) -> (Azimuth, Azimuth) {
|
||||
use Azimuth::*;
|
||||
match self {
|
||||
Self::South => (S, N),
|
||||
Self::East => (E, W),
|
||||
Self::North => (N, S),
|
||||
Self::West => (W, E),
|
||||
Self::Above => (C, C),
|
||||
Self::Below => (C, C),
|
||||
}
|
||||
}
|
||||
|
||||
///// ```
|
||||
///// use tengri::*;
|
||||
///// let _ = Split::Below.iter([
|
||||
///// "Leftbar"
|
||||
///// .min_w(10).max_w(15).align(Azimuth::NW),
|
||||
///// "Rightbar"
|
||||
///// .min_w(10).max_w(12).align(Azimuth::NE),
|
||||
///// "Center"
|
||||
///// .min_w(20).max_w(40).align(Azimuth::C),
|
||||
///// ].iter());
|
||||
///// ```
|
||||
//pub fn iter <S: Screen, T: Draw<S>> (&self, _: impl Iterator<Item = T>) {
|
||||
//todo!()
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
fn draw_stacks <S: Screen> (
|
||||
split: &Split,
|
||||
to: &mut S,
|
||||
|
|
@ -352,6 +280,108 @@ fn stack_drawn <S: Coord> (
|
|||
}
|
||||
}
|
||||
|
||||
impl Split {
|
||||
|
||||
/// ```
|
||||
/// use tengri::*;
|
||||
/// let _ = Split::Above.stack(&"", &"");
|
||||
/// let _ = Split::Below.stack(&"", &"");
|
||||
/// let _ = Split::North.stack(&"", &"");
|
||||
/// let _ = Split::South.stack(&"", &"");
|
||||
/// let _ = Split::East.stack(&"", &"");
|
||||
/// let _ = Split::West.stack(&"", &"");
|
||||
/// ```
|
||||
pub const fn stack <S: Screen, A: Draw<S>, B: Draw<S>> (&self, a: A, b: B) -> impl Draw<S> {
|
||||
Pair(*self, a, b, PhantomData)
|
||||
}
|
||||
|
||||
/// ```
|
||||
/// use tengri::*;
|
||||
/// let _ = Split::Above.half(&"", &"");
|
||||
/// let _ = Split::Below.half(&"", &"");
|
||||
/// let _ = Split::North.half(&"", &"");
|
||||
/// let _ = Split::South.half(&"", &"");
|
||||
/// let _ = Split::East.half(&"", &"");
|
||||
/// let _ = Split::West.half(&"", &"");
|
||||
/// ```
|
||||
pub const fn half <S: Screen, A: Draw<S>, B: Draw<S>> (&self, a: &A, b: &B) -> impl Draw<S> {
|
||||
draw(move|to: &mut S|{
|
||||
let (area_a, area_b) = to.xywh().split_half(self);
|
||||
let (origin_a, origin_b) = self.origins();
|
||||
let (drawn_a, drawn_b) = draw_stacks(self, to, a, area_a, origin_a, b, area_b, origin_b)?;
|
||||
Ok(stack_drawn(self, drawn_a, drawn_b))
|
||||
})
|
||||
}
|
||||
|
||||
/// Newly split areas begin at the center of the split
|
||||
/// to maintain centeredness in the user's field of view.
|
||||
///
|
||||
/// Use [align] to override that and always start
|
||||
/// at the top, bottom, etc.
|
||||
///
|
||||
/// ```
|
||||
/// /*
|
||||
///
|
||||
/// Split east: Split south:
|
||||
/// | | | | A |
|
||||
/// | <-A|B-> | |---------|
|
||||
/// | | | | B |
|
||||
///
|
||||
/// */
|
||||
/// ```
|
||||
const fn origins (&self) -> (Azimuth, Azimuth) {
|
||||
use Azimuth::*;
|
||||
match self {
|
||||
Self::South => (S, N),
|
||||
Self::East => (E, W),
|
||||
Self::North => (N, S),
|
||||
Self::West => (W, E),
|
||||
Self::Above => (C, C),
|
||||
Self::Below => (C, C),
|
||||
}
|
||||
}
|
||||
|
||||
///// ```
|
||||
///// use tengri::*;
|
||||
///// let _ = Split::Below.iter([
|
||||
///// "Leftbar"
|
||||
///// .min_w(10).max_w(15).align(Azimuth::NW),
|
||||
///// "Rightbar"
|
||||
///// .min_w(10).max_w(12).align(Azimuth::NE),
|
||||
///// "Center"
|
||||
///// .min_w(20).max_w(40).align(Azimuth::C),
|
||||
///// ].iter());
|
||||
///// ```
|
||||
//pub fn iter <S: Screen, T: Draw<S>> (&self, _: impl Iterator<Item = T>) {
|
||||
//todo!()
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
pub const fn east <S: Screen, A: Draw<S>, B: Draw<S>> (a: A, b: B) -> impl Draw<S> {
|
||||
Pair(Split::East, a, b, PhantomData)
|
||||
}
|
||||
|
||||
pub const fn north <S: Screen, A: Draw<S>, B: Draw<S>> (a: A, b: B) -> impl Draw<S> {
|
||||
Pair(Split::North, a, b, PhantomData)
|
||||
}
|
||||
|
||||
pub const fn west <S: Screen, A: Draw<S>, B: Draw<S>> (a: A, b: B) -> impl Draw<S> {
|
||||
Pair(Split::West, a, b, PhantomData)
|
||||
}
|
||||
|
||||
pub const fn south <S: Screen, A: Draw<S>, B: Draw<S>> (a: A, b: B) -> impl Draw<S> {
|
||||
Pair(Split::South, a, b, PhantomData)
|
||||
}
|
||||
|
||||
pub const fn above <S: Screen, A: Draw<S>, B: Draw<S>> (a: A, b: B) -> impl Draw<S> {
|
||||
Pair(Split::Above, a, b, PhantomData)
|
||||
}
|
||||
|
||||
pub const fn below <S: Screen, A: Draw<S>, B: Draw<S>> (a: A, b: B) -> impl Draw<S> {
|
||||
Pair(Split::Below, a, b, PhantomData)
|
||||
}
|
||||
|
||||
#[macro_export] macro_rules! north {
|
||||
($head:expr $(,)?) => { $head };
|
||||
($head:expr, $($tail:expr),* $(,)?) => { north($head, north!($($tail,)*)) };
|
||||
|
|
@ -382,30 +412,6 @@ fn stack_drawn <S: Coord> (
|
|||
($head:expr, $($tail:expr),* $(,)?) => { below($head, below!($($tail,)*)) };
|
||||
}
|
||||
|
||||
pub const fn east <S: Screen, A: Draw<S>, B: Draw<S>> (a: A, b: B) -> impl Draw<S> {
|
||||
Pair(Split::East, a, b, PhantomData)
|
||||
}
|
||||
|
||||
pub const fn north <S: Screen, A: Draw<S>, B: Draw<S>> (a: A, b: B) -> impl Draw<S> {
|
||||
Pair(Split::North, a, b, PhantomData)
|
||||
}
|
||||
|
||||
pub const fn west <S: Screen, A: Draw<S>, B: Draw<S>> (a: A, b: B) -> impl Draw<S> {
|
||||
Pair(Split::West, a, b, PhantomData)
|
||||
}
|
||||
|
||||
pub const fn south <S: Screen, A: Draw<S>, B: Draw<S>> (a: A, b: B) -> impl Draw<S> {
|
||||
Pair(Split::South, a, b, PhantomData)
|
||||
}
|
||||
|
||||
pub const fn above <S: Screen, A: Draw<S>, B: Draw<S>> (a: A, b: B) -> impl Draw<S> {
|
||||
Pair(Split::Above, a, b, PhantomData)
|
||||
}
|
||||
|
||||
pub const fn below <S: Screen, A: Draw<S>, B: Draw<S>> (a: A, b: B) -> impl Draw<S> {
|
||||
Pair(Split::Below, a, b, PhantomData)
|
||||
}
|
||||
|
||||
#[cfg(test)] #[test] fn test_stack_areas () -> Usually<()> {
|
||||
let area = XYWH(0u16, 0, 80, 25);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue