tidy_tree/
node.rs

1use std::{collections::VecDeque, ptr::NonNull};
2
3use crate::{geometry::Coord, layout::BoundingBox};
4
5#[derive(Debug)]
6pub struct TidyData {
7    pub thread_left: Option<NonNull<Node>>,
8    pub thread_right: Option<NonNull<Node>>,
9    /// ```text
10    /// this.extreme_left == this.thread_left.extreme_left ||
11    /// this.extreme_left == this.children[0].extreme_left
12    /// ```
13    pub extreme_left: Option<NonNull<Node>>,
14    /// ```text
15    /// this.extreme_right == this.thread_right.extreme_right ||
16    /// this.extreme_right == this.children[-1].extreme_right
17    /// ```
18    pub extreme_right: Option<NonNull<Node>>,
19
20    /// Cached change of x position.
21    pub shift_acceleration: Coord,
22    /// Cached change of x position
23    pub shift_change: Coord,
24
25    /// this.x = parent.x + modifier_to_subtree
26    pub modifier_to_subtree: Coord,
27    /// this.x + modifier_thread_left == thread_left.x
28    pub modifier_thread_left: Coord,
29    /// this.x + modifier_thread_right == thread_right.x
30    pub modifier_thread_right: Coord,
31    /// this.x + modifier_extreme_left == extreme_left.x
32    pub modifier_extreme_left: Coord,
33    /// this.x + modifier_extreme_right == extreme_right.x
34    pub modifier_extreme_right: Coord,
35}
36
37#[derive(Debug)]
38pub struct Node {
39    pub id: usize,
40    pub width: Coord,
41    pub height: Coord,
42    pub x: Coord,
43    pub y: Coord,
44    /// node x position relative to its parent
45    pub relative_x: Coord,
46    /// node y position relative to its parent
47    pub relative_y: Coord,
48    pub bbox: BoundingBox,
49    pub parent: Option<NonNull<Node>>,
50    /// Children need boxing to get a stable addr in the heap
51    pub children: Vec<Box<Node>>,
52    pub tidy: Option<Box<TidyData>>,
53}
54
55impl Clone for Node {
56    fn clone(&self) -> Self {
57        let mut root = Self {
58            id: self.id,
59            width: self.width,
60            height: self.height,
61            x: self.x,
62            y: self.y,
63            relative_x: self.relative_x,
64            relative_y: self.relative_y,
65            bbox: self.bbox.clone(),
66            parent: None,
67            children: self.children.clone(),
68            tidy: None,
69        };
70
71        if self.parent.is_none() {
72            root.post_order_traversal_mut(|node| {
73                let node_ptr = node.into();
74                for child in node.children.iter_mut() {
75                    child.parent = Some(node_ptr);
76                }
77            });
78        }
79
80        root
81    }
82}
83
84impl Default for Node {
85    fn default() -> Self {
86        Self {
87            id: usize::MAX,
88            width: 0.,
89            height: 0.,
90            x: 0.,
91            y: 0.,
92            relative_x: 0.,
93            relative_y: 0.,
94            children: vec![],
95            parent: None,
96            bbox: Default::default(),
97            tidy: None,
98        }
99    }
100}
101
102impl Node {
103    pub fn new(id: usize, width: Coord, height: Coord) -> Self {
104        Node {
105            id,
106            width,
107            height,
108            bbox: Default::default(),
109            x: 0.,
110            y: 0.,
111            relative_x: 0.,
112            relative_y: 0.,
113            children: vec![],
114            parent: None,
115            tidy: None,
116        }
117    }
118
119    pub fn depth(&self) -> usize {
120        let mut depth = 0;
121        let mut node = self;
122        while node.parent.is_some() {
123            node = node.parent().unwrap();
124            depth += 1;
125        }
126
127        depth
128    }
129
130    pub fn parent_mut(&mut self) -> Option<&mut Self> {
131        unsafe { self.parent.map(|mut node| node.as_mut()) }
132    }
133
134    pub fn parent(&self) -> Option<&Self> {
135        unsafe { self.parent.map(|node| node.as_ref()) }
136    }
137
138    pub fn bottom(&self) -> Coord {
139        self.height + self.y
140    }
141
142    pub fn tidy_mut(&mut self) -> &mut TidyData {
143        self.tidy.as_mut().unwrap()
144    }
145
146    pub fn tidy(&self) -> &TidyData {
147        self.tidy.as_ref().unwrap()
148    }
149
150    fn reset_parent_link_of_children(&mut self) {
151        if self.children.is_empty() {
152            return;
153        }
154
155        let ptr = self.into();
156        for child in self.children.iter_mut() {
157            child.parent = Some(ptr);
158        }
159    }
160
161    pub fn append_child(&mut self, mut child: Self) -> NonNull<Self> {
162        child.parent = Some(self.into());
163        let mut boxed = Box::new(child);
164        boxed.reset_parent_link_of_children();
165        let ptr = boxed.as_mut().into();
166        self.children.push(boxed);
167        ptr
168    }
169
170    pub fn new_with_child(id: usize, width: Coord, height: Coord, child: Self) -> Self {
171        let mut node = Node::new(id, width, height);
172        node.append_child(child);
173        node
174    }
175
176    pub fn new_with_children(id: usize, width: Coord, height: Coord, children: Vec<Self>) -> Self {
177        let mut node = Node::new(id, width, height);
178        for child in children {
179            node.append_child(child);
180        }
181        node
182    }
183
184    pub fn intersects(&self, other: &Self) -> bool {
185        self.x - self.width / 2. < other.x + other.width / 2.
186            && self.x + self.width / 2. > other.x - other.width / 2.
187            && self.y < other.y + other.height
188            && self.y + self.height > other.y
189    }
190
191    pub fn post_order_traversal<F>(&self, mut f: F)
192    where
193        F: FnMut(&Node),
194    {
195        let mut stack: Vec<(NonNull<Self>, bool)> = vec![(self.into(), true)];
196        while let Some((mut node_ptr, is_first)) = stack.pop() {
197            let node = unsafe { node_ptr.as_mut() };
198            if !is_first {
199                f(node);
200                continue;
201            }
202
203            stack.push((node_ptr, false));
204            for child in node.children.iter_mut() {
205                stack.push((child.as_mut().into(), true));
206            }
207        }
208    }
209
210    pub fn post_order_traversal_mut<F>(&mut self, mut f: F)
211    where
212        F: FnMut(&mut Node),
213    {
214        let mut stack: Vec<(NonNull<Self>, bool)> = vec![(self.into(), true)];
215        while let Some((mut node_ptr, is_first)) = stack.pop() {
216            let node = unsafe { node_ptr.as_mut() };
217            if !is_first {
218                f(node);
219                continue;
220            }
221
222            stack.push((node_ptr, false));
223            for child in node.children.iter_mut() {
224                stack.push((child.as_mut().into(), true));
225            }
226        }
227    }
228
229    pub fn pre_order_traversal<F>(&self, mut f: F)
230    where
231        F: FnMut(&Node),
232    {
233        let mut stack: Vec<NonNull<Self>> = vec![self.into()];
234        while let Some(mut node) = stack.pop() {
235            let node = unsafe { node.as_mut() };
236            f(node);
237            for child in node.children.iter_mut() {
238                stack.push(child.as_mut().into());
239            }
240        }
241    }
242
243    pub fn pre_order_traversal_mut<F>(&mut self, mut f: F)
244    where
245        F: FnMut(&mut Node),
246    {
247        let mut stack: Vec<NonNull<Self>> = vec![self.into()];
248        while let Some(mut node) = stack.pop() {
249            let node = unsafe { node.as_mut() };
250            f(node);
251            for child in node.children.iter_mut() {
252                stack.push(child.as_mut().into());
253            }
254        }
255    }
256
257    pub fn bfs_traversal_with_depth_mut<F>(&mut self, mut f: F)
258    where
259        F: FnMut(&mut Node, usize),
260    {
261        let mut queue: VecDeque<(NonNull<Self>, usize)> = VecDeque::new();
262        queue.push_back((self.into(), 0));
263        while let Some((mut node, depth)) = queue.pop_front() {
264            let node = unsafe { node.as_mut() };
265            f(node, depth);
266            for child in node.children.iter_mut() {
267                queue.push_back((child.as_mut().into(), depth + 1));
268            }
269        }
270    }
271
272    pub fn remove_child(&mut self, id: usize) {
273        let pos = self.children.iter().position(|node| node.id == id);
274        if let Some(index) = pos {
275            self.children.remove(index);
276        }
277    }
278
279    pub fn pre_order_traversal_with_depth_mut<F>(&mut self, mut f: F)
280    where
281        F: FnMut(&mut Node, usize),
282    {
283        let mut stack: Vec<(NonNull<Self>, usize)> = vec![(self.into(), 0)];
284        while let Some((mut node, depth)) = stack.pop() {
285            let node = unsafe { node.as_mut() };
286            f(node, depth);
287            for child in node.children.iter_mut() {
288                stack.push((child.as_mut().into(), depth + 1));
289            }
290        }
291    }
292
293    pub fn str(&self) -> String {
294        let mut s = String::new();
295        if self.tidy.is_some() {
296            s.push_str(&format!(
297                "x: {}, y: {}, width: {}, height: {}, rx: {}, mod: {}, id: {}\n",
298                self.x,
299                self.y,
300                self.width,
301                self.height,
302                self.relative_x,
303                self.tidy().modifier_to_subtree,
304                self.id
305            ));
306        } else {
307            s.push_str(&format!(
308                "x: {}, y: {}, width: {}, height: {}, rx: {}, id: {}\n",
309                self.x, self.y, self.width, self.height, self.relative_x, self.id
310            ));
311        }
312        for child in self.children.iter() {
313            for line in child.str().split('\n') {
314                if line.is_empty() {
315                    continue;
316                }
317
318                s.push_str(&format!("    {}\n", line));
319            }
320        }
321
322        s
323    }
324}