mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
semblance of groovebox launches from edn layout!
This commit is contained in:
parent
a702170d16
commit
7b3de1e68d
7 changed files with 209 additions and 152 deletions
16
layout/src/either.rs
Normal file
16
layout/src/either.rs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
use crate::*;
|
||||
|
||||
/// Show one item if a condition is true and another if the condition is false
|
||||
pub struct Either<A, B>(pub bool, pub A, pub B);
|
||||
|
||||
impl<E: Output, A: Render<E>, B: Render<E>> Content<E> for Either<A, B> {
|
||||
fn layout (&self, to: E::Area) -> E::Area {
|
||||
let Self(cond, a, b) = self;
|
||||
if *cond { a.layout(to) } else { b.layout(to) }
|
||||
}
|
||||
fn render (&self, to: &mut E) {
|
||||
let Self(cond, a, b) = self;
|
||||
if *cond { a.render(to) } else { b.render(to) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,10 +1,14 @@
|
|||
#![feature(type_alias_impl_trait)]
|
||||
#![feature(impl_trait_in_assoc_type)]
|
||||
|
||||
mod when; pub use self::when::*;
|
||||
mod either; pub use self::either::*;
|
||||
mod map; pub use self::map::*;
|
||||
mod reduce; pub use self::reduce::*;
|
||||
|
||||
mod align; pub use self::align::*;
|
||||
mod direction; pub use self::direction::*;
|
||||
mod measure; pub use self::measure::*;
|
||||
mod ops; pub use self::ops::*;
|
||||
mod transform_xy; pub use self::transform_xy::*;
|
||||
mod transform_xy_unit; pub use self::transform_xy_unit::*;
|
||||
|
||||
|
|
|
|||
55
layout/src/map.rs
Normal file
55
layout/src/map.rs
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
use crate::*;
|
||||
|
||||
pub fn map_south<O: Output>(
|
||||
item_offset: O::Unit,
|
||||
item_height: O::Unit,
|
||||
item: impl Content<O>
|
||||
) -> impl Content<O> {
|
||||
Push::y(item_offset,
|
||||
Align::n(Fixed::y(item_height,
|
||||
Fill::x(item))))
|
||||
}
|
||||
|
||||
pub struct Map<A, B, I, F, G>(pub F, pub G) where
|
||||
I: Iterator<Item = A> + Send + Sync,
|
||||
F: Fn() -> I + Send + Sync,
|
||||
G: Fn(A, usize)->B + Send + Sync;
|
||||
|
||||
impl<E, A, B, I, F, G> Content<E> for Map<A, B, I, F, G> where
|
||||
E: Output,
|
||||
B: Render<E>,
|
||||
I: Iterator<Item = A> + Send + Sync,
|
||||
F: Fn() -> I + Send + Sync,
|
||||
G: Fn(A, usize)->B + Send + Sync
|
||||
{
|
||||
fn layout (&self, area: E::Area) -> E::Area {
|
||||
let Self(get_iterator, callback) = self;
|
||||
let mut index = 0;
|
||||
let [mut min_x, mut min_y] = area.center();
|
||||
let [mut max_x, mut max_y] = area.center();
|
||||
for item in get_iterator() {
|
||||
let area = callback(item, index).layout(area).xywh();
|
||||
let [x,y,w,h] = area.xywh();
|
||||
min_x = min_x.min(x.into());
|
||||
min_y = min_y.min(y.into());
|
||||
max_x = max_x.max((x + w).into());
|
||||
max_y = max_y.max((y + h).into());
|
||||
index += 1;
|
||||
}
|
||||
let w = max_x - min_x;
|
||||
let h = max_y - min_y;
|
||||
//[min_x.into(), min_y.into(), w.into(), h.into()].into()
|
||||
area.center_xy([w.into(), h.into()].into()).into()
|
||||
}
|
||||
fn render (&self, to: &mut E) {
|
||||
let Self(get_iterator, callback) = self;
|
||||
let mut index = 0;
|
||||
//let area = self.layout(to.area());
|
||||
for item in get_iterator() {
|
||||
let item = callback(item, index);
|
||||
//to.place(area.into(), &item);
|
||||
to.place(to.area().into(), &item);
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,147 +0,0 @@
|
|||
use crate::*;
|
||||
|
||||
/// Show an item only when a condition is true.
|
||||
pub struct When<A>(pub bool, pub A);
|
||||
|
||||
impl<E: Output, A: Render<E>> Content<E> for When<A> {
|
||||
fn layout (&self, to: E::Area) -> E::Area {
|
||||
let Self(cond, item) = self;
|
||||
let mut area = E::Area::zero();
|
||||
if *cond {
|
||||
let item_area = item.layout(to);
|
||||
area[0] = item_area.x();
|
||||
area[1] = item_area.y();
|
||||
area[2] = item_area.w();
|
||||
area[3] = item_area.h();
|
||||
}
|
||||
area.into()
|
||||
}
|
||||
fn render (&self, to: &mut E) {
|
||||
let Self(cond, item) = self;
|
||||
if *cond { item.render(to) }
|
||||
}
|
||||
}
|
||||
|
||||
/// Show one item if a condition is true and another if the condition is false
|
||||
pub struct Either<A, B>(pub bool, pub A, pub B);
|
||||
|
||||
impl<E: Output, A: Render<E>, B: Render<E>> Content<E> for Either<A, B> {
|
||||
fn layout (&self, to: E::Area) -> E::Area {
|
||||
let Self(cond, a, b) = self;
|
||||
if *cond { a.layout(to) } else { b.layout(to) }
|
||||
}
|
||||
fn render (&self, to: &mut E) {
|
||||
let Self(cond, a, b) = self;
|
||||
if *cond { a.render(to) } else { b.render(to) }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Map<A, B, I, F, G>(pub F, pub G) where
|
||||
I: Iterator<Item = A> + Send + Sync,
|
||||
F: Fn() -> I + Send + Sync,
|
||||
G: Fn(A, usize)->B + Send + Sync;
|
||||
|
||||
impl<E, A, B, I, F, G> Content<E> for Map<A, B, I, F, G> where
|
||||
E: Output,
|
||||
B: Render<E>,
|
||||
I: Iterator<Item = A> + Send + Sync,
|
||||
F: Fn() -> I + Send + Sync,
|
||||
G: Fn(A, usize)->B + Send + Sync
|
||||
{
|
||||
fn layout (&self, area: E::Area) -> E::Area {
|
||||
let Self(get_iterator, callback) = self;
|
||||
let mut index = 0;
|
||||
let [mut min_x, mut min_y] = area.center();
|
||||
let [mut max_x, mut max_y] = area.center();
|
||||
for item in get_iterator() {
|
||||
let area = callback(item, index).layout(area).xywh();
|
||||
let [x,y,w,h] = area.xywh();
|
||||
min_x = min_x.min(x.into());
|
||||
min_y = min_y.min(y.into());
|
||||
max_x = max_x.max((x + w).into());
|
||||
max_y = max_y.max((y + h).into());
|
||||
index += 1;
|
||||
}
|
||||
let w = max_x - min_x;
|
||||
let h = max_y - min_y;
|
||||
//[min_x.into(), min_y.into(), w.into(), h.into()].into()
|
||||
area.center_xy([w.into(), h.into()].into()).into()
|
||||
}
|
||||
fn render (&self, to: &mut E) {
|
||||
let Self(get_iterator, callback) = self;
|
||||
let mut index = 0;
|
||||
//let area = self.layout(to.area());
|
||||
for item in get_iterator() {
|
||||
let item = callback(item, index);
|
||||
//to.place(area.into(), &item);
|
||||
to.place(to.area().into(), &item);
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
//pub fn reduce <E, T, I, R, F>(iterator: I, callback: F) -> Reduce<E, T, I, R, F> where
|
||||
//E: Output,
|
||||
//I: Iterator<Item = T> + Send + Sync,
|
||||
//R: Render<E>,
|
||||
//F: Fn(R, T, usize) -> R + Send + Sync
|
||||
//{
|
||||
//Reduce(Default::default(), iterator, callback)
|
||||
//}
|
||||
pub struct Reduce<E, T, I, R, F>(PhantomData<(E, R)>, I, F) where
|
||||
E: Output,
|
||||
I: Iterator<Item = T> + Send + Sync,
|
||||
R: Render<E>,
|
||||
F: Fn(R, T, usize) -> R + Send + Sync;
|
||||
impl<E, T, I, R, F> Content<E> for Reduce<E, T, I, R, F> where
|
||||
E: Output,
|
||||
I: Iterator<Item = T> + Send + Sync,
|
||||
R: Render<E>,
|
||||
F: Fn(R, T, usize) -> R + Send + Sync
|
||||
{
|
||||
fn render (&self, to: &mut E) {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
//macro_rules! define_ops {
|
||||
//($Trait:ident<$E:ident:$Output:path> { $(
|
||||
//$(#[$attr:meta $($attr_args:tt)*])*
|
||||
//(
|
||||
//$fn:ident
|
||||
//$(<$($G:ident$(:$Gen:path)?, )+>)?
|
||||
//$Op:ident
|
||||
//($($arg:ident:$Arg:ty),*)
|
||||
//)
|
||||
//)* }) => {
|
||||
//impl<$E: $Output> $Trait<E> for E {}
|
||||
//pub trait $Trait<$E: $Output> {
|
||||
//$(
|
||||
//$(#[$attr $($attr_args)*])*
|
||||
//fn $fn $(<$($G),+>)?
|
||||
//($($arg:$Arg),*)-> $Op<$($(, $G)+)?>
|
||||
//$(where $($G: $($Gen + Send + Sync)?),+)?
|
||||
//{ $Op($($arg),*) }
|
||||
//)*
|
||||
//}
|
||||
//}
|
||||
//}
|
||||
|
||||
//define_ops! {
|
||||
//Layout<E: Output> {
|
||||
//(when <A: Render<E>,>
|
||||
//When(cond: bool, item: A))
|
||||
///// When `cond` is `true`, render `a`, otherwise render `b`.
|
||||
//(either <A: Render<E>, B: Render<E>,>
|
||||
//Either(cond: bool, a: A, b: B))
|
||||
///// If `opt` is `Some(T)` renders `cb(t)`, otherwise nothing.
|
||||
//(opt <A, F: Fn(A) -> B, B: Render<E>,>
|
||||
//Opt(option: Option<A>, cb: F))
|
||||
///// Maps items of iterator through callback.
|
||||
//(map <A, B: Render<E>, I: Iterator<Item = A>, F: Fn() -> I, G: Fn(A, usize)->B,>
|
||||
//Map(get_iterator: F, callback: G))
|
||||
//}
|
||||
//}
|
||||
93
layout/src/reduce.rs
Normal file
93
layout/src/reduce.rs
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
use crate::*;
|
||||
|
||||
pub struct Reduce<A, B, I, F, G>(pub PhantomData<A>, pub F, pub G) where
|
||||
A: Send + Sync, B: Send + Sync,
|
||||
I: Iterator<Item = B> + Send + Sync,
|
||||
F: Fn() -> I + Send + Sync,
|
||||
G: Fn(A, B, usize)->A + Send + Sync;
|
||||
|
||||
impl<A, B, I, F, G> Reduce<A, B, I, F, G> where
|
||||
A: Send + Sync, B: Send + Sync,
|
||||
I: Iterator<Item = B> + Send + Sync,
|
||||
F: Fn() -> I + Send + Sync,
|
||||
G: Fn(A, B, usize)->A + Send + Sync
|
||||
{
|
||||
pub fn new (f: F, g: G) -> Self { Self(Default::default(), f, g) }
|
||||
}
|
||||
|
||||
impl<E: Output, A, B, I, F, G> Content<E> for Reduce<A, B, I, F, G> where
|
||||
A: Send + Sync, B: Send + Sync,
|
||||
I: Iterator<Item = B> + Send + Sync,
|
||||
F: Fn() -> I + Send + Sync,
|
||||
G: Fn(A, B, usize)->A + Send + Sync
|
||||
{
|
||||
fn content (&self) -> impl Render<E> {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
//pub fn reduce <E, T, I, R, F>(iterator: I, callback: F) -> Reduce<E, T, I, R, F> where
|
||||
//E: Output,
|
||||
//I: Iterator<Item = T> + Send + Sync,
|
||||
//R: Render<E>,
|
||||
//F: Fn(R, T, usize) -> R + Send + Sync
|
||||
//{
|
||||
//Reduce(Default::default(), iterator, callback)
|
||||
//}
|
||||
pub struct Reduce<E, T, I, R, F>(PhantomData<(E, R)>, I, F) where
|
||||
E: Output,
|
||||
I: Iterator<Item = T> + Send + Sync,
|
||||
R: Render<E>,
|
||||
F: Fn(R, T, usize) -> R + Send + Sync;
|
||||
impl<E, T, I, R, F> Content<E> for Reduce<E, T, I, R, F> where
|
||||
E: Output,
|
||||
I: Iterator<Item = T> + Send + Sync,
|
||||
R: Render<E>,
|
||||
F: Fn(R, T, usize) -> R + Send + Sync
|
||||
{
|
||||
fn render (&self, to: &mut E) {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
//macro_rules! define_ops {
|
||||
//($Trait:ident<$E:ident:$Output:path> { $(
|
||||
//$(#[$attr:meta $($attr_args:tt)*])*
|
||||
//(
|
||||
//$fn:ident
|
||||
//$(<$($G:ident$(:$Gen:path)?, )+>)?
|
||||
//$Op:ident
|
||||
//($($arg:ident:$Arg:ty),*)
|
||||
//)
|
||||
//)* }) => {
|
||||
//impl<$E: $Output> $Trait<E> for E {}
|
||||
//pub trait $Trait<$E: $Output> {
|
||||
//$(
|
||||
//$(#[$attr $($attr_args)*])*
|
||||
//fn $fn $(<$($G),+>)?
|
||||
//($($arg:$Arg),*)-> $Op<$($(, $G)+)?>
|
||||
//$(where $($G: $($Gen + Send + Sync)?),+)?
|
||||
//{ $Op($($arg),*) }
|
||||
//)*
|
||||
//}
|
||||
//}
|
||||
//}
|
||||
|
||||
//define_ops! {
|
||||
//Layout<E: Output> {
|
||||
//(when <A: Render<E>,>
|
||||
//When(cond: bool, item: A))
|
||||
///// When `cond` is `true`, render `a`, otherwise render `b`.
|
||||
//(either <A: Render<E>, B: Render<E>,>
|
||||
//Either(cond: bool, a: A, b: B))
|
||||
///// If `opt` is `Some(T)` renders `cb(t)`, otherwise nothing.
|
||||
//(opt <A, F: Fn(A) -> B, B: Render<E>,>
|
||||
//Opt(option: Option<A>, cb: F))
|
||||
///// Maps items of iterator through callback.
|
||||
//(map <A, B: Render<E>, I: Iterator<Item = A>, F: Fn() -> I, G: Fn(A, usize)->B,>
|
||||
//Map(get_iterator: F, callback: G))
|
||||
//}
|
||||
//}
|
||||
|
||||
23
layout/src/when.rs
Normal file
23
layout/src/when.rs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
use crate::*;
|
||||
|
||||
/// Show an item only when a condition is true.
|
||||
pub struct When<A>(pub bool, pub A);
|
||||
|
||||
impl<E: Output, A: Render<E>> Content<E> for When<A> {
|
||||
fn layout (&self, to: E::Area) -> E::Area {
|
||||
let Self(cond, item) = self;
|
||||
let mut area = E::Area::zero();
|
||||
if *cond {
|
||||
let item_area = item.layout(to);
|
||||
area[0] = item_area.x();
|
||||
area[1] = item_area.y();
|
||||
area[2] = item_area.w();
|
||||
area[3] = item_area.h();
|
||||
}
|
||||
area.into()
|
||||
}
|
||||
fn render (&self, to: &mut E) {
|
||||
let Self(cond, item) = self;
|
||||
if *cond { item.render(to) }
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue