1use std::any::TypeId;
5use std::fmt::Debug;
6
7use crate::Cap;
8use crate::Handleable;
9use crate::MutCap;
10use crate::Object;
11use crate::Renderable;
12
13
14pub trait Widget<E, M>: Handleable<E, M> + Renderable + Object + Debug {
22 fn type_id(&self) -> TypeId;
24
25 fn data<'c, D>(&self, cap: &'c dyn Cap) -> &'c D
32 where
33 Self: Sized,
34 D: 'static,
35 {
36 cap.data(self.id()).downcast_ref::<D>().unwrap()
37 }
38
39 fn data_mut<'c, D>(&self, cap: &'c mut dyn MutCap<E, M>) -> &'c mut D
46 where
47 Self: Sized,
48 D: 'static,
49 {
50 cap.data_mut(self.id()).downcast_mut::<D>().unwrap()
51 }
52}
53
54impl<E, M> dyn Widget<E, M>
55where
56 E: 'static,
57 M: 'static,
58{
59 pub fn is<T: Widget<E, M>>(&self) -> bool {
61 let t = TypeId::of::<T>();
62 let own_t = Widget::type_id(self);
63
64 t == own_t
65 }
66
67 pub fn downcast_ref<T: Widget<E, M>>(&self) -> Option<&T> {
69 if self.is::<T>() {
70 unsafe { Some(&*(self as *const dyn Widget<E, M> as *const T)) }
71 } else {
72 None
73 }
74 }
75
76 pub fn downcast_mut<T: Widget<E, M>>(&mut self) -> Option<&mut T> {
78 if self.is::<T>() {
79 unsafe { Some(&mut *(self as *mut dyn Widget<E, M> as *mut T)) }
80 } else {
81 None
82 }
83 }
84}