1#[cfg(not(feature = "std"))]
2use alloc::{vec, vec::Vec};
3
4use std::cell::RefCell;
5use std::fmt;
6use std::rc::Rc;
7use std::rc::Weak;
8
9use crate::algo;
10use crate::geometry::Size;
11use crate::number::Number;
12use crate::result::{Cache, Layout, Result};
13use crate::style::*;
14
15type MeasureFunc = Box<Fn(Size<Number>) -> Result<Size<f32>>>;
16
17pub(crate) struct InternalNode {
18 pub(crate) style: Style,
19 pub(crate) parents: Vec<Weak<RefCell<InternalNode>>>,
20 pub(crate) children: Vec<Rc<RefCell<InternalNode>>>,
21 pub(crate) measure: Option<MeasureFunc>,
22 pub(crate) layout_cache: RefCell<Option<Cache>>,
23}
24
25pub struct Node(Rc<RefCell<InternalNode>>);
26
27impl Node {
28 pub fn new_leaf(style: Style, measure: Option<MeasureFunc>) -> Node {
29 Node(Rc::new(RefCell::new(InternalNode {
30 style,
31 parents: vec![],
32 children: vec![],
33 measure,
34 layout_cache: RefCell::new(None),
35 })))
36 }
37
38 pub fn new(style: Style, children: Vec<&Node>) -> Node {
39 let mut parent = Node(Rc::new(RefCell::new(InternalNode {
40 style,
41 parents: vec![],
42 children: vec![],
43 measure: None,
44 layout_cache: RefCell::new(None),
45 })));
46
47 for child in children {
48 parent.add_child(child);
49 }
50
51 parent
52 }
53
54 pub fn add_child(&mut self, child: &Node) {
55 child.0.borrow_mut().parents.push(Rc::downgrade(&self.0));
56 self.0.borrow_mut().children.push(Rc::clone(&child.0));
57 self.mark_dirty();
58 }
59
60 pub fn set_children(&mut self, children: Vec<&Node>) {
61 for child in &self.0.borrow().children {
62 let position =
63 child.borrow().parents.iter().position(|x| Rc::ptr_eq(&x.upgrade().unwrap(), &self.0)).unwrap();
64 child.borrow_mut().parents.remove(position);
65 }
66
67 self.0.borrow_mut().children = vec![];
68
69 for child in children {
70 self.add_child(child);
71 }
72 }
73
74 pub fn remove_child(&mut self, child: &Node) -> Node {
75 self.remove_child_at_index({
76 let parent = self.0.borrow();
77 parent.children.iter().position(|x| Rc::ptr_eq(&x, &child.0)).unwrap()
78 })
79 }
80
81 pub fn remove_child_at_index(&mut self, index: usize) -> Node {
82 let child = {
83 let mut parent = self.0.borrow_mut();
84 let child = parent.children.remove(index);
85 let position =
86 child.borrow().parents.iter().position(|x| Rc::ptr_eq(&x.upgrade().unwrap(), &self.0)).unwrap();
87 child.borrow_mut().parents.remove(position);
88 child
89 };
90
91 self.mark_dirty();
92 Node(child)
93 }
94
95 pub fn replace_child_at_index(&mut self, index: usize, child: &Node) -> Node {
96 child.0.borrow_mut().parents.push(Rc::downgrade(&self.0));
97 let old_child = std::mem::replace(&mut self.0.borrow_mut().children[index], Rc::clone(&child.0));
98
99 let position =
100 old_child.borrow().parents.iter().position(|x| Rc::ptr_eq(&x.upgrade().unwrap(), &self.0)).unwrap();
101 old_child.borrow_mut().parents.remove(position);
102
103 self.mark_dirty();
104
105 Node(old_child)
106 }
107
108 pub fn children(&self) -> Vec<Node> {
109 let node = self.0.borrow_mut();
110 node.children.iter().map(|child| Node(Rc::clone(child))).collect()
111 }
112
113 pub fn set_style(&mut self, style: Style) {
114 self.0.borrow_mut().style = style;
115 self.mark_dirty();
116 }
117
118 pub fn style(&self) -> Style {
119 self.0.borrow().style
120 }
121
122 pub fn mark_dirty(&mut self) {
123 let node = self.0.borrow_mut();
124 node.layout_cache.replace(None);
125
126 for parent in &node.parents {
127 if let Some(parent) = parent.upgrade() {
128 Node(parent).mark_dirty();
129 }
130 }
131 }
132
133 pub fn is_dirty(&mut self) -> bool {
134 let node = self.0.borrow();
135 let layout_cache = node.layout_cache.borrow();
136 if let Some(_) = layout_cache.as_ref() {
137 false
138 } else {
139 true
140 }
141 }
142
143 pub fn compute_layout(&self, size: Size<Number>) -> Result<Layout> {
144 algo::compute(&self.0.borrow(), size)
145 }
146}
147
148impl fmt::Debug for Node {
149 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
150 let style = &self.0.borrow().style;
151 let children: Vec<_> = self.0.borrow().children.iter().map(|c| Node(Rc::clone(c))).collect();
152 write!(f, "Node {{ style: {:?}, children: {:?} }}", style, children)
153 }
154}
155
156impl PartialEq for Node {
157 fn eq(&self, other: &Node) -> bool {
158 Rc::ptr_eq(&self.0, &other.0)
159 }
160}
161
162impl Eq for Node {}