freya_core/states/
layer.rs1use 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}