use std::{fmt::Display, mem, str::FromStr};
use druid::{
kurbo::Size, BoxConstraints, Data, Env, Event, EventCtx, LayoutCtx, LifeCycle, LifeCycleCtx,
PaintCtx, UpdateCtx, Widget, WidgetId,
};
pub struct ParseLazy<W> {
widget: W,
state: String,
}
impl<W> ParseLazy<W> {
pub fn new(widget: W) -> Self {
Self {
widget,
state: String::new(),
}
}
}
impl<T: FromStr + Display + Data, W: Widget<String>> Widget<T> for ParseLazy<W> {
fn event(&mut self, ctx: &mut EventCtx, event: &Event, data: &mut T, env: &Env) {
self.widget.event(ctx, event, &mut self.state, env);
if let Ok(res) = self.state.parse() {
*data = res;
}
}
fn lifecycle(&mut self, ctx: &mut LifeCycleCtx, event: &LifeCycle, data: &T, env: &Env) {
if let LifeCycle::WidgetAdded = event {
self.state = data.to_string();
}
self.widget.lifecycle(ctx, event, &self.state, env)
}
fn update(&mut self, ctx: &mut UpdateCtx, _old_data: &T, data: &T, env: &Env) {
let old = mem::replace(&mut self.state, data.to_string());
self.widget.update(ctx, &old, &self.state, env)
}
fn layout(&mut self, ctx: &mut LayoutCtx, bc: &BoxConstraints, _data: &T, env: &Env) -> Size {
self.widget.layout(ctx, bc, &self.state, env)
}
fn paint(&mut self, paint: &mut PaintCtx, _data: &T, env: &Env) {
self.widget.paint(paint, &self.state, env)
}
fn id(&self) -> Option<WidgetId> {
self.widget.id()
}
}