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 draws children inside (like text).
78pub trait Padding {
79    fn padding(&self) -> &DAbsRect {
80        &crate::ZERO_DABSRECT
81    }
82}
83
84impl Padding for DRect {}
85
86// Relative to parent's area, but only ever used to determine spacing between child elements.
87pub trait Margin {
88    fn margin(&self) -> &DRect {
89        &ZERO_DRECT
90    }
91}
92
93// Relative to child's assigned area (outer area)
94pub trait Area {
95    fn area(&self) -> &DRect;
96}
97
98impl Area for DRect {
99    fn area(&self) -> &DRect {
100        self
101    }
102}
103
104gen_from_to_dyn!(Area);
105
106// Relative to child's evaluated area (inner area)
107pub trait Anchor {
108    fn anchor(&self) -> &DPoint {
109        &crate::ZERO_DPOINT
110    }
111}
112
113impl Anchor for DRect {}
114
115pub trait Limits {
116    fn limits(&self) -> &crate::DLimits {
117        &crate::DEFAULT_DLIMITS
118    }
119}
120
121// Relative to parent's area
122pub trait RLimits {
123    fn rlimits(&self) -> &crate::RelLimits {
124        &crate::DEFAULT_RLIMITS
125    }
126}
127
128pub trait Order {
129    fn order(&self) -> i64 {
130        0
131    }
132}
133
134pub trait Direction {
135    fn direction(&self) -> crate::RowDirection {
136        crate::RowDirection::LeftToRight
137    }
138}
139
140impl Limits for DRect {}
141impl RLimits for DRect {}
142
143pub trait TextEdit {
144    fn textedit(&self) -> &crate::text::EditView;
145}