use crate::UiRsc; use super::*; use std::marker::Unsize; pub trait WidgetLike: Sized { type Widget: Widget + ?Sized + Unsize; fn add(self, rsc: &mut Rsc) -> WeakWidget; fn add_strong(self, rsc: &mut Rsc) -> StrongWidget { self.add(rsc).upgrade(rsc) } fn with_id( self, f: impl FnOnce(&mut Rsc, WeakWidget) -> WeakWidget, ) -> impl WidgetIdFn { move |state| { let id = self.add(state); f(state, id) } } fn set_root(self, rsc: &mut Rsc, root: &mut impl HasRoot) { let id = self.add_strong(rsc); root.set_root(id); } } pub trait HasRoot { fn set_root(&mut self, root: StrongWidget); } pub trait WidgetArrLike { #[track_caller] fn add(self, state: &mut Rsc) -> WidgetArr; } impl WidgetArrLike for WidgetArr { fn add(self, _: &mut Rsc) -> WidgetArr { self } } // variadic generics please save us macro_rules! impl_widget_arr { ($n:expr;$($W:ident)*) => { impl_widget_arr!($n;$($W)*;$(${concat($W,Tag)})*); }; ($n:expr;$($W:ident)*;$($Tag:ident)*) => { impl,$Tag,)*> WidgetArrLike for ($($W,)*) { fn add(self, rsc: &mut Rsc) -> WidgetArr<$n> { #[allow(non_snake_case)] let ($($W,)*) = self; WidgetArr::new( [$($W.add(rsc).upgrade(rsc),)*], ) } } }; } impl_widget_arr!(1;A); impl_widget_arr!(2;A B); impl_widget_arr!(3;A B C); impl_widget_arr!(4;A B C D); impl_widget_arr!(5;A B C D E); impl_widget_arr!(6;A B C D E F); impl_widget_arr!(7;A B C D E F G); impl_widget_arr!(8;A B C D E F G H); impl_widget_arr!(9;A B C D E F G H I); impl_widget_arr!(10;A B C D E F G H I J); impl_widget_arr!(11;A B C D E F G H I J K); impl_widget_arr!(12;A B C D E F G H I J K L);