Skip to main content

feather_ui/layout/
base.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: 2025 Fundament Research Institute <https://fundament.institute>
3
4use crate::{DAbsRect, DPoint, DRect, ZERO_DRECT};
5use std::rc::Rc;
6
7#[macro_export]
8macro_rules! gen_from_to_dyn {
9    ($idx:ident) => {
10        impl<'a, T: $idx + 'static> From<&'a T> for &'a (dyn $idx + 'static) {
11            fn from(value: &'a T) -> Self {
12                return value;
13            }
14        }
15    };
16}
17
18pub trait Empty {}
19
20impl Empty for () {}
21impl RLimits for () {}
22impl Margin for () {}
23impl Order for () {}
24impl crate::layout::fixed::Child for () {}
25impl crate::layout::list::Child for () {}
26
27impl<T: Empty> Empty for Rc<T> {}
28
29impl Empty for DRect {}
30
31gen_from_to_dyn!(Empty);
32
33impl crate::layout::Desc for dyn Empty {
34    type Props = dyn Empty;
35    type Child = dyn Empty;
36    type Children = ();
37
38    fn stage<'a>(
39        _: &Self::Props,
40        mut outer_area: crate::PxRect,
41        outer_limits: crate::PxLimits,
42        _: &Self::Children,
43        id: std::sync::Weak<crate::SourceID>,
44        renderable: Option<Rc<dyn crate::render::Renderable>>,
45        window: &mut crate::component::window::WindowState,
46    ) -> Box<dyn super::Staged + 'a> {
47        outer_area = super::nuetralize_unsized(outer_area);
48        outer_area = super::limit_area(outer_area, outer_limits);
49
50        Box::new(crate::layout::Concrete::new(
51            renderable,
52            outer_area,
53            crate::rtree::Node::new(
54                outer_area.to_untyped(),
55                None,
56                Default::default(),
57                id,
58                window,
59            ),
60            Default::default(),
61        ))
62    }
63}
64
65pub trait Obstacles {
66    fn obstacles(&self) -> &[DAbsRect];
67}
68
69pub trait ZIndex {
70    fn zindex(&self) -> i32 {
71        0
72    }
73}
74
75impl ZIndex for DRect {}
76
77// Padding is used so an element's actual area can be larger than the area it
78// draws children inside (like text).
79pub trait Padding {
80    fn padding(&self) -> &DAbsRect {
81        &crate::ZERO_DABSRECT
82    }
83}
84
85impl Padding for DRect {}
86
87// Relative to parent's area, but only ever used to determine spacing between
88// child elements.
89pub trait Margin {
90    fn margin(&self) -> &DRect {
91        &ZERO_DRECT
92    }
93}
94
95// Relative to child's assigned area (outer area)
96pub trait Area {
97    fn area(&self) -> &DRect;
98}
99
100impl Area for DRect {
101    fn area(&self) -> &DRect {
102        self
103    }
104}
105
106gen_from_to_dyn!(Area);
107
108// Relative to child's evaluated area (inner area)
109pub trait Anchor {
110    fn anchor(&self) -> &DPoint {
111        &crate::ZERO_DPOINT
112    }
113}
114
115impl Anchor for DRect {}
116
117pub trait Limits {
118    fn limits(&self) -> &crate::DLimits {
119        &crate::DEFAULT_DLIMITS
120    }
121}
122
123// Relative to parent's area
124pub trait RLimits {
125    fn rlimits(&self) -> &crate::RelLimits {
126        &crate::DEFAULT_RLIMITS
127    }
128}
129
130pub trait Order {
131    fn order(&self) -> i64 {
132        0
133    }
134}
135
136pub trait Direction {
137    fn direction(&self) -> crate::RowDirection {
138        crate::RowDirection::LeftToRight
139    }
140}
141
142impl Limits for DRect {}
143impl RLimits for DRect {}
144
145pub trait TextEdit {
146    fn textedit(&self) -> &crate::text::EditView;
147}