use std::{cell::RefCell, rc::Rc};
use rs_math3d::Dimensioni;
use crate::{
atlas::AtlasHandle,
input::{ControlState, ResourceState, WidgetBehaviourOption, WidgetOption},
style::Style,
widget::{widget_id_of, Widget, WidgetId},
widget_ctx::WidgetCtx,
CustomRenderArgs,
};
pub type WidgetHandle<T> = Rc<RefCell<T>>;
pub fn widget_handle<T>(value: T) -> WidgetHandle<T> {
Rc::new(RefCell::new(value))
}
pub(crate) type TreeCustomRender = Rc<RefCell<Box<dyn FnMut(Dimensioni, &CustomRenderArgs) + 'static>>>;
pub(crate) trait WidgetStateHandleDyn {
fn widget_id(&self) -> WidgetId;
fn effective_widget_opt(&self) -> WidgetOption;
fn effective_behaviour_opt(&self) -> WidgetBehaviourOption;
fn measure(&self, style: &Style, atlas: &AtlasHandle, avail: Dimensioni) -> Dimensioni;
fn needs_input_snapshot(&self) -> bool;
fn run(&self, ctx: &mut WidgetCtx<'_>, control: &ControlState) -> ResourceState;
}
struct WidgetStateHandle<W: Widget + 'static> {
handle: WidgetHandle<W>,
}
impl<W: Widget + 'static> WidgetStateHandleDyn for WidgetStateHandle<W> {
fn widget_id(&self) -> WidgetId {
let widget = self.handle.borrow();
widget_id_of(&*widget)
}
fn effective_widget_opt(&self) -> WidgetOption {
let widget = self.handle.borrow();
widget.effective_widget_opt()
}
fn effective_behaviour_opt(&self) -> WidgetBehaviourOption {
let widget = self.handle.borrow();
widget.effective_behaviour_opt()
}
fn measure(&self, style: &Style, atlas: &AtlasHandle, avail: Dimensioni) -> Dimensioni {
let widget = self.handle.borrow();
widget.measure(style, atlas, avail)
}
fn needs_input_snapshot(&self) -> bool {
let widget = self.handle.borrow();
widget.needs_input_snapshot()
}
fn run(&self, ctx: &mut WidgetCtx<'_>, control: &ControlState) -> ResourceState {
let mut widget = self.handle.borrow_mut();
widget.run(ctx, control)
}
}
pub(crate) fn erased_widget_state<W: Widget + 'static>(handle: WidgetHandle<W>) -> Box<dyn WidgetStateHandleDyn> {
Box::new(WidgetStateHandle { handle })
}