Skip to main content

ferroui_base/styling/
container.rs

1use super::{ContainerSizing, VisualQueryProvider};
2use crate::layout::Layoutable;
3use crate::{ferro_property, AttachedProperty, FerroObject, FerroProperty, StyledPropertyOptions};
4
5/// Provides container attached properties: a layoutable that is a container
6/// publishes its size to the container queries of its descendants.
7pub struct Container;
8
9crate::ferro_static_type!(Container);
10
11crate::ferro_properties! { impl Container {
12    ferro_property!(
13        /// Defines the Name attached property.
14        pub fn name_property() -> AttachedProperty<Option<String>> {
15            FerroProperty::register_attached::<Container, Layoutable, _>("Name", None)
16        }
17    );
18
19    ferro_property!(
20        /// Defines the Sizing attached property.
21        pub fn sizing_property() -> AttachedProperty<ContainerSizing> {
22            FerroProperty::register_attached_with::<Container, Layoutable, _>(
23                "Sizing",
24                StyledPropertyOptions::new(ContainerSizing::Normal).coerce(Container::update_query_provider),
25            )
26        }
27    );
28
29    ferro_property!(
30        /// Defines the QueryProvider attached property.
31        pub(crate) fn query_provider_property() -> AttachedProperty<Option<VisualQueryProvider>> {
32            FerroProperty::register_attached::<Container, Layoutable, _>("QueryProvider", None)
33        }
34    );
35} }
36
37impl Container {
38    fn update_query_provider(obj: &FerroObject, sizing: ContainerSizing) -> ContainerSizing {
39        if let Some(layoutable) = obj.downcast_ref::<Layoutable>() {
40            if sizing != ContainerSizing::Normal {
41                if Self::get_query_provider(layoutable).is_none() {
42                    layoutable.set_value(Self::query_provider_property(), Some(VisualQueryProvider::new()));
43                }
44            } else {
45                layoutable.set_value(Self::query_provider_property(), None);
46            }
47        }
48
49        sizing
50    }
51
52    /// Gets the name of the container.
53    pub fn get_name(layoutable: &Layoutable) -> Option<String> {
54        layoutable.get_value(Self::name_property())
55    }
56
57    /// Sets the name of the container.
58    pub fn set_name(layoutable: &Layoutable, name: Option<String>) {
59        layoutable.set_value(Self::name_property(), name);
60    }
61
62    /// Gets the container sizing behavior.
63    pub fn get_sizing(layoutable: &Layoutable) -> ContainerSizing {
64        layoutable.get_value(Self::sizing_property())
65    }
66
67    /// Sets the container sizing behavior.
68    pub fn set_sizing(layoutable: &Layoutable, sizing: ContainerSizing) {
69        layoutable.set_value(Self::sizing_property(), sizing);
70    }
71
72    /// Gets the query provider of the container.
73    pub(crate) fn get_query_provider(layoutable: &Layoutable) -> Option<VisualQueryProvider> {
74        layoutable.get_value(Self::query_provider_property())
75    }
76
77    /// Reports the size of a container to its query provider, if it has
78    /// one. For layoutables that replace the core measure pass (the roots
79    /// of windows), which reports the size otherwise.
80    pub fn set_query_provider_size(layoutable: &Layoutable, width: f64, height: f64, sizing: ContainerSizing) {
81        if let Some(query_provider) = Self::get_query_provider(layoutable) {
82            query_provider.set_size(width, height, sizing);
83        }
84    }
85}