extact dsl_token; flip Dsl; try to obviate ViewContext

This commit is contained in:
🪞👃🪞 2025-05-20 16:27:05 +03:00
parent f08593f0f8
commit f797a7143d
12 changed files with 264 additions and 209 deletions

View file

@ -37,7 +37,7 @@ pub struct Align<A>(Alignment, A);
#[cfg(feature = "dsl")]
impl<'state, E: Output + 'state, T: ViewContext<'state, E>>
FromDsl<'state, T> for Align<RenderBox<'state, E>> {
Dsl<T> for Align<RenderBox<'state, E>> {
fn take_from <'source: 'state> (state: &'state T, iter: &mut TokenIter<'source>) -> Perhaps<Self> {
if let Some(Token { value: Value::Key(key), .. }) = iter.peek() {
match key {

View file

@ -22,7 +22,7 @@ impl<E: Output, A: Content<E>, B: Content<E>> Content<E> for Bsp<A, B> {
}
#[cfg(feature = "dsl")]
impl<'state, E: Output + 'state, T: ViewContext<'state, E>>
FromDsl<'state, T> for Bsp<RenderBox<'state, E>, RenderBox<'state, E>> {
Dsl<T> for Bsp<RenderBox<'state, E>, RenderBox<'state, E>> {
fn take_from <'source: 'state> (state: &'state T, iter: &mut TokenIter<'source>) -> Perhaps<Self> {
Ok(if let Some(Token {
value: Value::Key("bsp/n"|"bsp/s"|"bsp/e"|"bsp/w"|"bsp/a"|"bsp/b"),

View file

@ -20,7 +20,7 @@ impl<A, B> Either<A, B> {
#[cfg(feature = "dsl")]
impl<'state, E: Output + 'state, T: ViewContext<'state, E>>
FromDsl<'state, T> for When<RenderBox<'state, E>> {
Dsl<T> for When<RenderBox<'state, E>> {
fn take_from <'source: 'state> (state: &'state T, iter: &mut TokenIter<'source>) -> Perhaps<Self> {
Ok(if let Some(Token {
value: Value::Key("when"),
@ -39,7 +39,7 @@ FromDsl<'state, T> for When<RenderBox<'state, E>> {
#[cfg(feature = "dsl")]
impl<'state, E: Output + 'state, T: ViewContext<'state, E>>
FromDsl<'state, T> for Either<RenderBox<'state, E>, RenderBox<'state, E>> {
Dsl<T> for Either<RenderBox<'state, E>, RenderBox<'state, E>> {
fn take_from <'source: 'state> (state: &'state T, iter: &mut TokenIter<'source>) -> Perhaps<Self> {
if let Some(Token { value: Value::Key("either"), .. }) = iter.peek() {
let base = iter.clone();

View file

@ -1,4 +1,5 @@
use crate::*;
use Direction::*;
pub struct Stack<E, F> {
__: PhantomData<E>,
@ -10,68 +11,76 @@ impl<E, F> Stack<E, F> {
Self { direction, callback, __: Default::default(), }
}
pub fn north (callback: F) -> Self {
Self::new(Direction::North, callback)
Self::new(North, callback)
}
pub fn south (callback: F) -> Self {
Self::new(Direction::South, callback)
Self::new(South, callback)
}
pub fn east (callback: F) -> Self {
Self::new(Direction::East, callback)
Self::new(East, callback)
}
pub fn west (callback: F) -> Self {
Self::new(Direction::West, callback)
Self::new(West, callback)
}
}
impl<E: Output, F: Fn(&mut dyn FnMut(&dyn Render<E>)->())->()> Content<E> for Stack<E, F> {
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();
let (mut w_used, mut w_remaining) = (E::Unit::zero(), to.w());
let (mut h_used, mut h_remaining) = (E::Unit::zero(), to.h());
(self.callback)(&mut move |component: &dyn Render<E>|{
let layout = component.layout([x, y, w, h].into());
let [_, _, w, h] = component.layout([x, y, w_remaining, h_remaining].into()).xywh();
match self.direction {
Direction::North => {
todo!()
South => {
y = y.plus(h);
h_used = h_used.plus(h);
h_remaining = h_remaining.minus(h);
w_used = w_used.max(w);
},
Direction::South => {
y = y + layout.h();
h = h.minus(layout.h());
East => {
x = x.plus(w);
w_used = w_used.plus(w);
w_remaining = w_remaining.minus(w);
h_used = h_used.max(h);
},
Direction::East => {
x = x + layout.w();
w = w.minus(layout.w());
},
Direction::West => {
North | West => {
todo!()
},
_ => unreachable!(),
}
});
to
match self.direction {
North | West => {
todo!()
},
South | East => {
[to.x(), to.y(), w_used.into(), h_used.into()].into()
},
_ => unreachable!(),
}
}
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();
let (mut w_used, mut w_remaining) = (E::Unit::zero(), to.w());
let (mut h_used, mut h_remaining) = (E::Unit::zero(), to.h());
(self.callback)(&mut move |component: &dyn Render<E>|{
let layout = component.layout([x, y, w, h].into());
let layout = component.layout([x, y, w_remaining, h_remaining].into());
match self.direction {
Direction::North => {
todo!()
},
Direction::South => {
y = y + layout.h();
h = h.minus(layout.h());
South => {
y = y.plus(layout.h());
h_remaining = h_remaining.minus(layout.h());
h_used = h_used.plus(layout.h());
to.place(layout, component);
},
Direction::East => {
x = x + layout.w();
w = w.minus(layout.w());
East => {
x = x.plus(layout.w());
w_remaining = w_remaining.minus(layout.w());
w_used = w_used.plus(layout.h());
to.place(layout, component);
},
Direction::West => {
North | West => {
todo!()
},
_ => unreachable!()

View file

@ -40,7 +40,7 @@ macro_rules! transform_xy {
}
#[cfg(feature = "dsl")]
impl<'state, E: Output + 'state, T: ViewContext<'state, E>>
FromDsl<'state, T> for $Enum<RenderBox<'state, E>> {
Dsl<T> for $Enum<RenderBox<'state, E>> {
fn take_from <'source: 'state> (state: &'state T, iter: &mut TokenIter<'source>) -> Perhaps<Self> {
if let Some(Token { value: Value::Key(k), .. }) = iter.peek() {
let mut base = iter.clone();
@ -85,7 +85,7 @@ macro_rules! transform_xy_unit {
}
#[cfg(feature = "dsl")]
impl<'state, E: Output + 'state, T: ViewContext<'state, E>>
FromDsl<'state, T> for $Enum<E::Unit, RenderBox<'state, E>> {
Dsl<T> for $Enum<E::Unit, RenderBox<'state, E>> {
fn take_from <'source: 'state> (state: &'state T, iter: &mut TokenIter<'source>) -> Perhaps<Self> {
Ok(if let Some(Token { value: Value::Key($x|$y|$xy), .. }) = iter.peek() {
let mut base = iter.clone();

View file

@ -3,7 +3,7 @@ use crate::*;
#[cfg(feature = "dsl")]
#[macro_export] macro_rules! try_delegate {
($s:ident, $dsl:expr, $T:ty) => {
let value: Option<$T> = FromDsl::take_from($s, $dsl)?;
let value: Option<$T> = Dsl::take_from($s, $dsl)?;
if let Some(value) = value {
return Ok(Some(value.boxed()))
}
@ -12,10 +12,10 @@ use crate::*;
// Provides components to the view.
#[cfg(feature = "dsl")]
pub trait ViewContext<'state, E: Output + 'state>: Send + Sync
+ Dsl<bool>
+ Dsl<usize>
+ Dsl<E::Unit>
pub trait ViewContext<'state, E: Output + 'state>: Send + Sync where
bool: Dsl<Self>,
usize: Dsl<Self>,
E::Unit: Dsl<Self>,
{
fn get_content_or_fail <'source: 'state> (&'state self, iter: &mut TokenIter<'source>)
-> Usually<RenderBox<'state, E>>