use std::marker::PhantomData;
use crate::kurbo::Size;
use crate::{BoxConstraints, Data, Env, Event, EventCtx, LayoutCtx, PaintCtx, UpdateCtx, Widget};
pub struct EnvScope<T: Data, W: Widget<T>> {
f: Box<dyn Fn(&mut Env)>,
child: W,
phantom: PhantomData<T>,
}
impl<T: Data, W: Widget<T>> EnvScope<T, W> {
pub fn new(f: impl Fn(&mut Env) + 'static, child: W) -> EnvScope<T, W> {
EnvScope {
f: Box::new(f),
child,
phantom: Default::default(),
}
}
}
impl<T: Data, W: Widget<T>> Widget<T> for EnvScope<T, W> {
fn event(&mut self, ctx: &mut EventCtx, event: &Event, data: &mut T, env: &Env) {
let mut new_env = env.clone();
(self.f)(&mut new_env);
self.child.event(ctx, event, data, &new_env)
}
fn update(&mut self, ctx: &mut UpdateCtx, old_data: Option<&T>, data: &T, env: &Env) {
let mut new_env = env.clone();
(self.f)(&mut new_env);
self.child.update(ctx, old_data, data, &new_env);
}
fn layout(
&mut self,
layout_ctx: &mut LayoutCtx,
bc: &BoxConstraints,
data: &T,
env: &Env,
) -> Size {
bc.debug_check("EnvScope");
let mut new_env = env.clone();
(self.f)(&mut new_env);
self.child.layout(layout_ctx, &bc, data, &new_env)
}
fn paint(&mut self, paint_ctx: &mut PaintCtx, data: &T, env: &Env) {
let mut new_env = env.clone();
(self.f)(&mut new_env);
self.child.paint(paint_ctx, data, &new_env);
}
}