1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
//! A general widget type that can be specialized at runtime. use widget_prelude::*; use ::KISSContext; use std::borrow::Borrow; /// A general widget type that can be specialized at runtime via `Downcast`. pub struct BaseWidget(IUPPtr); impl BaseWidget { /// Attempt to load a widget named by `name` from internal storage. /// /// If successful, the `BaseWidget` can then be downcast to the original widget type. /// /// Returns `None` if no widget by that name was found. /// /// ##Panics /// If called before `kiss_ui::show_gui()` is invoked or after it returns. pub fn load<N: Borrow<str>>(name: N) -> Option<BaseWidget> { KISSContext::load_widget(&name) } /// Attempt to downcast this `BaseWidget` to a more specialized widget type. /// /// This will return an error if the underlying widget class is different than the one /// it is being cast to. pub fn try_downcast<T>(self) -> Result<T, Self> where T: Downcast { T::try_downcast(self) } } impl_widget! { BaseWidget } /// A trait describing a widget's ability to be downcast from `BaseWidget`. pub trait Downcast: Widget { /// Attempt to downcast `base` to the `Self` type, /// returning `Err(base)` if unsuccessful. fn try_downcast(base: BaseWidget) -> Result<Self, BaseWidget> { if Self::can_downcast(&base) { Ok(unsafe { Self::downcast(base) }) } else { Err(base) } } // These are not meant for end-users to call. // They are an implementation detail of `try_downcast()`. #[doc(hidden)] unsafe fn downcast(base: BaseWidget) -> Self { Self::from_ptr(base.ptr()) } #[doc(hidden)] fn can_downcast(base: &BaseWidget) -> bool; }