use std::time::Duration;
use iced::widget::{Space, sensor};
use iced::{Element, Theme};
use serde_json::Value;
use crate::PlushieRenderer;
use crate::message::Message;
use crate::protocol::TreeNode;
use crate::registry::PlushieWidget;
use crate::render_ctx::RenderCtx;
use crate::widget::helpers::*;
use plushie_core::types::PlushieType;
struct SensorProps {
delay: Option<f64>,
anticipate: Option<f32>,
on_resize: Option<String>,
}
impl SensorProps {
fn from_node(node: &TreeNode) -> Self {
let p = &node.props;
Self {
delay: f64::extract(p, "delay"),
anticipate: f32::extract(p, "anticipate"),
on_resize: prop_str(p, "on_resize"),
}
}
}
pub(crate) struct SensorWidget;
impl<R: PlushieRenderer> PlushieWidget<R> for SensorWidget {
fn type_names(&self) -> &[&str] {
&["sensor"]
}
fn render<'a>(
&'a self,
node: &'a TreeNode,
ctx: &RenderCtx<'a, R>,
) -> Element<'a, Message, Theme, R> {
let sp = SensorProps::from_node(node);
let child: Element<'a, Message, Theme, R> = node
.children
.first()
.map(|c| ctx.render_child(c))
.unwrap_or_else(|| Space::new().into());
let id = node.id.clone();
let window_id = ctx.window_id.to_string();
let mut s = sensor(child).key(id);
if let Some(ref tag) = sp.on_resize {
{
let wid = window_id.clone();
let nid = node.id.clone();
let family = format!("{}:show", tag);
s = s.on_show(move |size| Message::Event {
window_id: wid.clone(),
id: nid.clone(),
family: family.clone(),
value: serde_json::json!({"width": size.width, "height": size.height}),
});
}
{
let wid = window_id.clone();
let nid = node.id.clone();
let family = tag.clone();
s = s.on_resize(move |size| Message::Event {
window_id: wid.clone(),
id: nid.clone(),
family: family.clone(),
value: serde_json::json!({"width": size.width, "height": size.height}),
});
}
{
let wid = window_id.clone();
let nid = node.id.clone();
let family = format!("{}:hide", tag);
s = s.on_hide(Message::Event {
window_id: wid,
id: nid,
family,
value: Value::Null,
});
}
}
if let Some(d) = sp.delay {
s = s.delay(Duration::from_millis(d as u64));
}
if let Some(a) = sp.anticipate {
s = s.anticipate(a);
}
s.into()
}
fn fresh_for_session(&self) -> Box<dyn PlushieWidget<R>> {
Box::new(SensorWidget)
}
}