tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 497HTML 254C 19JavaScript 81329 Definiciones

⎇ 6940cc51d905ede2b42ebe9120cb5abb43fa36e9 src/node.rs Rust · 131 líneas · 3.8 KB Historia Quién tocó qué crudo

Implemented all methods on node 6940cc51d · Emil Sjölander ·

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