1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use dioxus_native_core::prelude::ElementNode;
use dioxus_native_core::real_dom::NodeImmutable;
use dioxus_native_core::{node::NodeType, NodeId};
use freya_common::NodeReferenceLayout;
use freya_dom::prelude::DioxusDOM;
use freya_layout::Layers;

use freya_engine::prelude::*;
use freya_node_state::{CursorMode, CursorSettings, LayoutState, References, Style};
use rustc_hash::FxHashMap;
use torin::torin::Torin;

pub fn process_layers(
    layers: &mut Layers,
    rdom: &DioxusDOM,
    layout: &Torin<NodeId>,
    font_collection: &FontCollection,
    scale_factor: f32,
) {
    let mut inherit_layers = FxHashMap::default();

    rdom.traverse_depth_first(|node| {
        let areas = layout.get(node.id());

        if let Some(areas) = areas {
            // Add the Node to a Layer
            let node_style = node.get::<Style>().unwrap();

            let inherited_relative_layer = node
                .parent_id()
                .map(|p| *inherit_layers.get(&p).unwrap())
                .unwrap_or(0);

            let (node_layer, node_relative_layer) = Layers::calculate_layer(
                node_style.relative_layer,
                node.height() as i16,
                inherited_relative_layer,
            );

            inherit_layers.insert(node.id(), node_relative_layer);
            layers.add_element(node.id(), node_layer);

            // Register paragraph elements

            if let NodeType::Element(ElementNode { tag, .. }) = &*node.node_type() {
                if tag == "paragraph" {
                    let cursor_settings = node.get::<CursorSettings>().unwrap();
                    let is_editable = CursorMode::Editable == cursor_settings.mode;

                    let references = node.get::<References>().unwrap();
                    if is_editable {
                        if let Some(cursor_ref) = &references.cursor_ref {
                            let text_group = layers
                                .paragraph_elements
                                .entry(cursor_ref.text_id)
                                .or_insert_with(Vec::default);

                            text_group.push(node.id());
                        }
                    }
                }
            }

            // Notify layout references

            let size_state = &*node.get::<LayoutState>().unwrap();

            if let Some(reference) = &size_state.node_ref {
                let mut node_layout = NodeReferenceLayout {
                    area: areas.area,
                    inner: areas.inner_sizes,
                };
                node_layout.div(scale_factor);
                reference.send(node_layout).ok();
            }
        }
    });

    layers.measure_all_paragraph_elements(rdom, layout, font_collection, scale_factor);
}