feather_ui/layout/
domain_write.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: 2025 Fundament Research Institute <https://fundament.institute>
3
4use super::base::{Empty, RLimits};
5use super::{Concrete, Desc, Layout, Renderable, Staged};
6use crate::{CrossReferenceDomain, SourceID, render, rtree};
7use std::marker::PhantomData;
8use std::rc::Rc;
9use std::sync::Arc;
10
11// A DomainWrite layout spawns a renderable that writes it's area to the target
12// cross-reference domain
13pub trait Prop {
14    fn domain(&self) -> Arc<CrossReferenceDomain>;
15}
16
17crate::gen_from_to_dyn!(Prop);
18
19impl Prop for Arc<CrossReferenceDomain> {
20    fn domain(&self) -> Arc<CrossReferenceDomain> {
21        self.clone()
22    }
23}
24
25impl Empty for Arc<CrossReferenceDomain> {}
26impl RLimits for Arc<CrossReferenceDomain> {}
27impl super::fixed::Child for Arc<CrossReferenceDomain> {}
28
29impl Desc for dyn Prop {
30    type Props = dyn Prop;
31    type Child = dyn Empty;
32    type Children = PhantomData<dyn Layout<Self::Child>>;
33
34    fn stage<'a>(
35        props: &Self::Props,
36        mut outer_area: crate::PxRect,
37        outer_limits: crate::PxLimits,
38        _: &Self::Children,
39        id: std::sync::Weak<SourceID>,
40        renderable: Option<Rc<dyn Renderable>>,
41        window: &mut crate::component::window::WindowState,
42    ) -> Box<dyn Staged + 'a> {
43        outer_area = super::nuetralize_unsized(outer_area);
44        outer_area = super::limit_area(outer_area, outer_limits);
45
46        debug_assert!(outer_area.v.is_finite().all());
47        Box::new(Concrete {
48            area: outer_area,
49            renderable: Some(Rc::new(render::domain::Write {
50                id: id.clone(),
51                domain: props.domain().clone(),
52                base: renderable,
53            })),
54            rtree: rtree::Node::new(
55                outer_area.to_untyped(),
56                None,
57                Default::default(),
58                id,
59                window,
60            ),
61            children: Default::default(),
62            layer: None,
63        })
64    }
65}