screen: return damaged area

This commit is contained in:
facile pop culture reference 2026-06-30 15:38:47 +03:00
parent 4e6c62a7f1
commit 347151f7fc
3 changed files with 35 additions and 28 deletions

View file

@ -22,5 +22,6 @@ use super::*;
pub trait Screen: Space<Self::Unit> + Send + Sync + Sized { pub trait Screen: Space<Self::Unit> + Send + Sync + Sized {
type Unit: Coord; type Unit: Coord;
/// Render drawable in subarea specified by `area` /// Render drawable in subarea specified by `area`
fn show <'t, T: Draw<Self>> (&mut self, area: XYWH<Self::Unit>, content: T); fn show <'t, T: Draw<Self>> (&mut self, area: XYWH<Self::Unit>, content: T) ->
Usually<XYWH<Self::Unit>>;
} }

View file

@ -77,7 +77,7 @@ macro_rules! eval_enum ((
/// ``` /// ```
pub fn eval_view <'a, O: Screen + 'a, S> ( pub fn eval_view <'a, O: Screen + 'a, S> (
state: &S, output: &mut O, expr: &'a impl Expression state: &S, output: &mut O, expr: &'a impl Expression
) -> Usually<bool> where ) -> Perhaps<XYWH<O::Unit>> where
S: Interpret<O, XYWH<O::Unit>> S: Interpret<O, XYWH<O::Unit>>
+ for<'b> Namespace<'b, bool> + for<'b> Namespace<'b, bool>
+ for<'b> Namespace<'b, O::Unit> + for<'b> Namespace<'b, O::Unit>
@ -100,7 +100,7 @@ pub fn eval_view <'a, O: Screen + 'a, S> (
let arg2 = tail1.head(); let arg2 = tail1.head();
// First `frags.next()` calls returns the namespace. // First `frags.next()` calls returns the namespace.
match frags.next() { Some(match frags.next() {
Some("when") => when( Some("when") => when(
state.namespace(arg0?)?.unwrap(), state.namespace(arg0?)?.unwrap(),
@ -132,26 +132,30 @@ pub fn eval_view <'a, O: Screen + 'a, S> (
).draw(output), ).draw(output),
Some("exact") => eval_xy!( Some("exact") => eval_xy!(
"exact", expr, head, output, state, frags.next(), arg0, arg1, arg2, wh_exact, w_exact, h_exact "exact", expr, head, output, state, frags.next(),
arg0, arg1, arg2, wh_exact, w_exact, h_exact
), ),
Some("min") => eval_xy!( Some("min") => eval_xy!(
"min", expr, head, output, state, frags.next(), arg0, arg1, arg2, wh_min, w_min, h_min "min", expr, head, output, state, frags.next(),
arg0, arg1, arg2, wh_min, w_min, h_min
), ),
Some("max") => eval_xy!( Some("max") => eval_xy!(
"max", expr, head, output, state, frags.next(), arg0, arg1, arg2, wh_max, w_max, h_max "max", expr, head, output, state, frags.next(),
arg0, arg1, arg2, wh_max, w_max, h_max
), ),
Some("push") => eval_xy!( Some("push") => eval_xy!(
"push", expr, head, output, state, frags.next(), arg0, arg1, arg2, xy_push, x_push, y_push "push", expr, head, output, state, frags.next(),
arg0, arg1, arg2, xy_push, x_push, y_push
), ),
_ => return Ok(false) _ => return Ok(None)
}?; }).transpose()
Ok(true)
} }
/// Interpret TUI-specific layout operation. /// Interpret TUI-specific layout operation.
/// ///
/// ``` /// ```
@ -174,8 +178,8 @@ pub fn eval_view <'a, O: Screen + 'a, S> (
/// ``` /// ```
pub fn eval_view_tui <'a, S> ( pub fn eval_view_tui <'a, S> (
state: &S, output: &mut Tui, expr: impl Expression + 'a state: &S, output: &mut Tui, expr: impl Expression + 'a
) -> Usually<bool> where ) -> Perhaps<XYWH<u16>> where
S: Interpret<Tui, ()> S: Interpret<Tui, XYWH<u16>>
+ for<'b>Namespace<'b, bool> + for<'b>Namespace<'b, bool>
+ for<'b>Namespace<'b, u16> + for<'b>Namespace<'b, u16>
+ for<'b>Namespace<'b, Color> + for<'b>Namespace<'b, Color>
@ -187,11 +191,13 @@ pub fn eval_view_tui <'a, S> (
let arg0 = args.head(); let arg0 = args.head();
let tail0 = args.tail(); let tail0 = args.tail();
let arg1 = tail0.head(); let arg1 = tail0.head();
match frags.next() { Ok(Some(match frags.next() {
Some("text") => { Some("text") => {
if let Some(src) = args?.src()? { if let Some(src) = args?.src()? {
output.show(output.xywh(), &src) output.show(output.xywh(), &src)?
} else {
return Ok(None)
} }
}, },
@ -202,7 +208,7 @@ pub fn eval_view_tui <'a, S> (
state.interpret(output, &arg1)?; state.interpret(output, &arg1)?;
// FIXME?: don't max out the used area? // FIXME?: don't max out the used area?
Ok(output.area().into()) Ok(output.area().into())
}))) })))?
}, },
Some("bg") => { Some("bg") => {
@ -212,11 +218,10 @@ pub fn eval_view_tui <'a, S> (
state.interpret(output, &arg1)?; state.interpret(output, &arg1)?;
// FIXME?: don't max out the used area? // FIXME?: don't max out the used area?
Ok(output.area().into()) Ok(output.area().into())
}))) })))?
}, },
_ => return Ok(false) _ => return Ok(None)
}; }))
Ok(true)
} }

View file

@ -194,11 +194,12 @@ impl Screen for Tui {
/// Render drawable in subarea specified by `area` /// Render drawable in subarea specified by `area`
fn show <'t, T: Draw<Self>> ( fn show <'t, T: Draw<Self>> (
&mut self, area: XYWH<u16>, content: T &mut self, area: XYWH<u16>, content: T
) { ) -> Usually<XYWH<u16>> {
let previous_area = self.1; let previous_area = self.1;
self.1 = area; self.1 = area;
let _result_area = content.draw(self); let result_area = content.draw(self);
self.1 = previous_area; self.1 = previous_area;
result_area
} }
} }