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
use super::*; pub struct Row<'a> { core: WidgetCore, children: Vec<Box<dyn Widget + 'a>>, } impl<'a> Deref for Row<'a> { type Target = Vec<Box<dyn Widget + 'a>>; fn deref(&self) -> &Self::Target { &self.children } } impl DerefMut for Row<'_> { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.children } } pub fn row<'a>(widgets: Vec<Box<dyn Widget + 'a>>) -> Row<'a> { Row { core: WidgetCore::void(), children: widgets, } } #[macro_export] macro_rules! row { ($($x:expr,)*) => { $crate::row(vec![$(Box::new($x)),*]) }; ($($x:expr),*) => { $crate::row!($($x,)*) }; } impl<'a> Widget for Row<'a> { fn core(&self) -> &WidgetCore { &self.core } fn core_mut(&mut self) -> &mut WidgetCore { &mut self.core } fn calc_constraints(&mut self) { self.core_mut().constraints.min_size.x = self .children .iter() .map(|child| child.core().constraints.min_size.x) .sum(); self.core_mut().constraints.min_size.y = self .children .iter() .map(|child| child.core().constraints.min_size.y) .max_by(|a, b| a.partial_cmp(b).unwrap()) .unwrap_or(0.0); self.core_mut().constraints.flex.x = self .children .iter() .map(|child| child.core().constraints.flex.x) .sum(); self.core_mut().constraints.flex.y = self .children .iter() .map(|child| child.core().constraints.flex.y) .max_by(|a, b| a.partial_cmp(b).unwrap()) .unwrap_or(0.0); } fn layout_children(&mut self) { let total_flex = self .children .iter() .map(|child| child.core().constraints.flex.x) .sum::<f64>(); let size_per_flex = if total_flex == 0.0 { 0.0 } else { (self.core().position.width() - self .children .iter() .map(|child| child.core().constraints.min_size.x) .sum::<f64>()) / total_flex }; let mut pos = self.core().position.x_min; for child in &mut self.children { let width = child.core().constraints.min_size.x + child.core().constraints.flex.x * size_per_flex; child.core_mut().position = AABB::pos_size( vec2(pos, self.core.position.y_min), vec2(width, self.core.position.height()), ); pos += width; } } fn walk_children_mut<'b>(&mut self, mut f: Box<dyn FnMut(&mut dyn Widget) + 'b>) { for child in &mut self.children { f(child.deref_mut()); } } }