freya_core/states/
layer.rs

1use std::sync::{
2    Arc,
3    Mutex,
4};
5
6use freya_native_core::{
7    attributes::AttributeName,
8    exports::shipyard::Component,
9    node_ref::NodeView,
10    prelude::{
11        AttributeMaskBuilder,
12        Dependancy,
13        NodeMaskBuilder,
14        State,
15    },
16    NodeId,
17    SendAnyMap,
18};
19use freya_native_core_macro::partial_derive_state;
20
21use crate::{
22    custom_attributes::CustomAttributeValues,
23    layers::Layers,
24    parsing::{
25        ParseAttribute,
26        ParseError,
27    },
28};
29
30#[derive(Default, PartialEq, Clone, Debug, Component)]
31pub struct LayerState {
32    pub layer: i16,
33    pub layer_for_children: i16,
34}
35
36impl ParseAttribute for LayerState {
37    fn parse_attribute(
38        &mut self,
39        attr: freya_native_core::prelude::OwnedAttributeView<CustomAttributeValues>,
40    ) -> Result<(), ParseError> {
41        #[allow(clippy::single_match)]
42        match attr.attribute {
43            AttributeName::Layer => {
44                if let Some(value) = attr.value.as_text() {
45                    let layer = value.parse::<i16>().map_err(|_| ParseError)?;
46                    self.layer -= layer;
47                    self.layer_for_children += layer;
48                }
49            }
50            _ => {}
51        }
52
53        Ok(())
54    }
55}
56
57#[partial_derive_state]
58impl State<CustomAttributeValues> for LayerState {
59    type ParentDependencies = (Self,);
60
61    type ChildDependencies = ();
62
63    type NodeDependencies = ();
64
65    const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new()
66        .with_attrs(AttributeMaskBuilder::Some(&[AttributeName::Layer]))
67        .with_tag();
68
69    fn update<'a>(
70        &mut self,
71        node_view: NodeView<CustomAttributeValues>,
72        _node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
73        parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
74        _children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
75        context: &SendAnyMap,
76    ) -> bool {
77        if !node_view.node_type().is_visible_element() {
78            return false;
79        }
80
81        let root_id = context.get::<NodeId>().unwrap();
82        let layers = context.get::<Arc<Mutex<Layers>>>().unwrap();
83        let inherited_layer = parent.map(|(p,)| p.layer_for_children).unwrap_or(0i16);
84
85        let mut layer_state = LayerState {
86            layer: node_view.height() as i16 - inherited_layer,
87            layer_for_children: inherited_layer,
88        };
89
90        if let Some(attributes) = node_view.attributes() {
91            for attr in attributes {
92                layer_state.parse_safe(attr);
93            }
94        }
95
96        let changed = &layer_state != self;
97
98        let is_orphan = node_view.height() == 0 && node_view.node_id() != *root_id;
99
100        if changed && !is_orphan {
101            layers
102                .lock()
103                .unwrap()
104                .insert_node_in_layer(node_view.node_id(), layer_state.layer);
105        }
106
107        *self = layer_state;
108        changed
109    }
110}