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 72 73 74 75 76 77
// renderable.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::BBox; use crate::Cap; use crate::Renderer; /// A trait representing a renderable object. pub trait Renderable: 'static + Debug { /// Get the `TypeId` of `self`. fn type_id(&self) -> TypeId; /// Render the renderable object. /// /// This method just forwards the call to the given `Renderer`, /// supplying a trait object of the actual widget. The renderer is /// advised to honor the given `BBox` and is free to inquire /// additional state using the supplied `Cap`. fn render(&self, renderer: &dyn Renderer, bbox: BBox, cap: &dyn Cap) -> BBox; } impl dyn Renderable { /// Check if the widget is of type `T`. pub fn is<T>(&self) -> bool where T: Renderable, { let t = TypeId::of::<T>(); let own_t = self.type_id(); t == own_t } /// Downcast the widget reference to type `T`. pub fn downcast_ref<T>(&self) -> Option<&T> where T: Renderable, { if self.is::<T>() { unsafe { Some(&*(self as *const dyn Renderable as *const T)) } } else { None } } /// Downcast the widget reference to type `T`. pub fn downcast_mut<T>(&mut self) -> Option<&mut T> where T: Renderable, { if self.is::<T>() { unsafe { Some(&mut *(self as *mut dyn Renderable as *mut T)) } } else { None } } }