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 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
pub mod content; pub mod flex; pub mod grid; pub mod image; pub mod size; pub mod text; use crate::widget::{ node::WidgetNode, unit::{ content::ContentBox, flex::FlexBox, grid::GridBox, image::ImageBox, size::SizeBox, text::TextBox, }, WidgetId, }; use serde::{Deserialize, Serialize}; use std::convert::TryFrom; #[derive(Debug, Default, Clone, Serialize, Deserialize)] pub struct WidgetUnitInspectionNode { pub id: WidgetId, pub children: Vec<WidgetUnitInspectionNode>, } pub trait WidgetUnitData { fn id(&self) -> &WidgetId; fn get_children<'a>(&'a self) -> Vec<&'a WidgetUnit> { vec![] } } #[derive(Debug, Clone, Serialize, Deserialize)] pub enum WidgetUnit { None, ContentBox(ContentBox), FlexBox(FlexBox), GridBox(GridBox), SizeBox(SizeBox), ImageBox(ImageBox), TextBox(TextBox), } impl Default for WidgetUnit { fn default() -> Self { Self::None } } impl WidgetUnit { pub fn is_none(&self) -> bool { match self { Self::None => true, _ => false, } } pub fn is_some(&self) -> bool { match self { Self::None => false, _ => true, } } pub fn as_data(&self) -> Option<&dyn WidgetUnitData> { match self { Self::None => None, Self::ContentBox(v) => Some(v as &dyn WidgetUnitData), Self::FlexBox(v) => Some(v as &dyn WidgetUnitData), Self::GridBox(v) => Some(v as &dyn WidgetUnitData), Self::SizeBox(v) => Some(v as &dyn WidgetUnitData), Self::ImageBox(v) => Some(v as &dyn WidgetUnitData), Self::TextBox(v) => Some(v as &dyn WidgetUnitData), } } pub fn inspect(&self) -> Option<WidgetUnitInspectionNode> { if let Some(data) = self.as_data() { Some(WidgetUnitInspectionNode { id: data.id().to_owned(), children: data .get_children() .into_iter() .filter_map(|child| child.inspect()) .collect::<Vec<_>>(), }) } else { None } } } impl TryFrom<WidgetNode> for WidgetUnit { type Error = (); fn try_from(node: WidgetNode) -> Result<Self, Self::Error> { if let WidgetNode::Unit(v) = node { Ok(v) } else { Err(()) } } } impl From<()> for WidgetUnit { fn from(_: ()) -> Self { Self::None } } macro_rules! implement_from_unit { { $( $type_name:ident ),+ $(,)? } => { $( impl From<$type_name> for WidgetUnit { fn from(unit: $type_name) -> Self { Self::$type_name(unit) } } )+ }; } implement_from_unit! { ContentBox, FlexBox, GridBox, SizeBox, ImageBox, TextBox, }