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 {
type Unit: Coord;
/// 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> (
state: &S, output: &mut O, expr: &'a impl Expression
) -> Usually<bool> where
) -> Perhaps<XYWH<O::Unit>> where
S: Interpret<O, XYWH<O::Unit>>
+ for<'b> Namespace<'b, bool>
+ for<'b> Namespace<'b, O::Unit>
@ -100,7 +100,7 @@ pub fn eval_view <'a, O: Screen + 'a, S> (
let arg2 = tail1.head();
// First `frags.next()` calls returns the namespace.
match frags.next() {
Some(match frags.next() {
Some("when") => when(
state.namespace(arg0?)?.unwrap(),
@ -132,26 +132,30 @@ pub fn eval_view <'a, O: Screen + 'a, S> (
).draw(output),
Some("exact") => eval_xy!(
"exact", expr, head, output, state, frags.next(), arg0, arg1, arg2, wh_exact, w_exact, h_exact
),
Some("min") => eval_xy!(
"min", expr, head, output, state, frags.next(), arg0, arg1, arg2, wh_min, w_min, h_min
),
Some("max") => eval_xy!(
"max", expr, head, output, state, frags.next(), arg0, arg1, arg2, wh_max, w_max, h_max
),
Some("push") => eval_xy!(
"push", expr, head, output, state, frags.next(), arg0, arg1, arg2, xy_push, x_push, y_push
"exact", expr, head, output, state, frags.next(),
arg0, arg1, arg2, wh_exact, w_exact, h_exact
),
_ => return Ok(false)
Some("min") => eval_xy!(
"min", expr, head, output, state, frags.next(),
arg0, arg1, arg2, wh_min, w_min, h_min
),
}?;
Some("max") => eval_xy!(
"max", expr, head, output, state, frags.next(),
arg0, arg1, arg2, wh_max, w_max, h_max
),
Ok(true)
Some("push") => eval_xy!(
"push", expr, head, output, state, frags.next(),
arg0, arg1, arg2, xy_push, x_push, y_push
),
_ => return Ok(None)
}).transpose()
}
/// 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> (
state: &S, output: &mut Tui, expr: impl Expression + 'a
) -> Usually<bool> where
S: Interpret<Tui, ()>
) -> Perhaps<XYWH<u16>> where
S: Interpret<Tui, XYWH<u16>>
+ for<'b>Namespace<'b, bool>
+ for<'b>Namespace<'b, u16>
+ for<'b>Namespace<'b, Color>
@ -187,11 +191,13 @@ pub fn eval_view_tui <'a, S> (
let arg0 = args.head();
let tail0 = args.tail();
let arg1 = tail0.head();
match frags.next() {
Ok(Some(match frags.next() {
Some("text") => {
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)?;
// FIXME?: don't max out the used area?
Ok(output.area().into())
})))
})))?
},
Some("bg") => {
@ -212,11 +218,10 @@ pub fn eval_view_tui <'a, S> (
state.interpret(output, &arg1)?;
// FIXME?: don't max out the used area?
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`
fn show <'t, T: Draw<Self>> (
&mut self, area: XYWH<u16>, content: T
) {
) -> Usually<XYWH<u16>> {
let previous_area = self.1;
self.1 = area;
let _result_area = content.draw(self);
let result_area = content.draw(self);
self.1 = previous_area;
result_area
}
}