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
81
82
83
84
85
use super::Id;
use accesskit::Point;
use std::collections::HashMap;
use taffy::{
    prelude::{Layout, Node, Size},
    style::Style,
    style_helpers::TaffyMaxContent,
    Taffy,
};

pub struct LayoutContext {
    pub taffy: Taffy,
    pub children: Vec<Node>,
    pub root: Node,
    pub keys: HashMap<Node, Id>,
}

impl Default for LayoutContext {
    fn default() -> Self {
        let mut taffy = Taffy::new();
        let root = taffy.new_leaf(Style::DEFAULT).unwrap();

        Self {
            taffy,
            children: Vec::new(),
            root,
            keys: HashMap::new(),
        }
    }
}

impl LayoutContext {
    pub fn insert(&mut self, id: Id, style: Style) -> Node {
        let key = self.taffy.new_leaf(style).unwrap();
        self.children.push(key);
        self.keys.insert(key, id);
        key
    }

    pub fn iter(&self) -> Iter {
        Iter {
            taffy: &self.taffy,
            keys: vec![self.root],
        }
    }

    pub fn targets(&self, point: Point) -> impl Iterator<Item = Id> + '_ {
        self.iter().filter_map(move |(key, layout)| {
            if layout.location.x <= point.x as _
                && layout.location.x + layout.size.width >= point.x as _
                && layout.location.y <= point.y as _
                && layout.location.y + layout.size.height >= point.y as _
            {
                self.keys.get(&key).copied()
            } else {
                None
            }
        })
    }

    pub fn compute_layout(&mut self) {
        self.taffy.set_children(self.root, &self.children).unwrap();

        taffy::compute_layout(&mut self.taffy, self.root, Size::MAX_CONTENT).unwrap();
    }
}

pub struct Iter<'a> {
    taffy: &'a Taffy,
    keys: Vec<Node>,
}

impl<'a> Iterator for Iter<'a> {
    type Item = (Node, &'a Layout);

    fn next(&mut self) -> Option<Self::Item> {
        self.keys.pop().map(|key| {
            let children = self.taffy.children(key).unwrap();
            self.keys.extend_from_slice(&children);

            let layout = self.taffy.layout(key).unwrap();
            (key, layout)
        })
    }
}