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 59 60 61 62 63 64 65 66 67 68 69 70 71
// widget.rs // ************************************************************************* // * Copyright (C) 2018-2019 Daniel Mueller (deso@posteo.net) * // * * // * This program is free software: you can redistribute it and/or modify * // * it under the terms of the GNU General Public License as published by * // * the Free Software Foundation, either version 3 of the License, or * // * (at your option) any later version. * // * * // * This program is distributed in the hope that it will be useful, * // * but WITHOUT ANY WARRANTY; without even the implied warranty of * // * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * // * GNU General Public License for more details. * // * * // * You should have received a copy of the GNU General Public License * // * along with this program. If not, see <http://www.gnu.org/licenses/>. * // ************************************************************************* use std::any::TypeId; use std::fmt::Debug; use crate::Handleable; use crate::Object; use crate::Renderable; /// A widget as used by a `Ui`. /// /// In addition to taking care of `Id` management and parent-child /// relationships, the `Ui` is responsible for dispatching events to /// widgets and rendering them. Hence, a widget usable for the `Ui` /// needs to implement `Handleable`, `Renderable`, and `Object`. pub trait Widget<E>: Handleable<E> + Renderable + Object + Debug where E: 'static, { /// Get the `TypeId` of `self`. fn type_id(&self) -> TypeId; } impl<E> dyn Widget<E> where E: 'static, { /// Check if the widget is of type `T`. pub fn is<T: Widget<E>>(&self) -> bool { let t = TypeId::of::<T>(); let own_t = Widget::type_id(self); t == own_t } /// Downcast the widget reference to type `T`. pub fn downcast_ref<T: Widget<E>>(&self) -> Option<&T> { if self.is::<T>() { unsafe { Some(&*(self as *const dyn Widget<E> as *const T)) } } else { None } } /// Downcast the widget reference to type `T`. pub fn downcast_mut<T: Widget<E>>(&mut self) -> Option<&mut T> { if self.is::<T>() { unsafe { Some(&mut *(self as *mut dyn Widget<E> as *mut T)) } } else { None } } }