diff --git a/tests/test_node.py b/tests/test_node.py index c578cb4..f7ce223 100644 --- a/tests/test_node.py +++ b/tests/test_node.py @@ -143,3 +143,51 @@ def __init__(self, style, children=None): self.assertEqual(child1.applicator.tasks, []) self.assertEqual(child2.applicator.tasks, []) self.assertEqual(child3.applicator.tasks, []) + + def test_add(self): + "Nodes can be added as children to another node" + + style = Style() + node = Node(style=style, children=[]) + + child = Node(style=style) + node.add(child) + + self.assertTrue(child in node.children) + self.assertEqual(child.parent, node) + self.assertEqual(child.root, node.root) + + def test_insert(self): + "Node can be inserted at a specific position as a child" + + style = Style() + child1 = Node(style=style) + child2 = Node(style=style) + child3 = Node(style=style) + node = Node(style=style, children=[child1, child2, child3]) + + child4 = Node(style=style) + + index = 2 + node.insert(index, child4) + + self.assertTrue(child4 in node.children) + self.assertEqual(child4.parent, node) + self.assertEqual(child4.root, node.root) + + self.assertEqual(node.children.index(child4), index) + + def test_remove(self): + "Children can be removed from node" + + style = Style() + child1 = Node(style=style) + child2 = Node(style=style) + child3 = Node(style=style) + node = Node(style=style, children=[child1, child2, child3]) + + node.remove(child1) + + self.assertFalse(child1 in node.children) + self.assertEqual(child1.parent, None) + self.assertEqual(child1.root, child1) diff --git a/travertino/layout.py b/travertino/layout.py index ddf0985..ee74d86 100644 --- a/travertino/layout.py +++ b/travertino/layout.py @@ -119,11 +119,10 @@ def content_top(self): @content_top.setter def content_top(self, value): - if value != self._content_top: - self._content_top = value - for child in self.node.children: - if child.layout: - child.layout._origin_top = self.absolute_content_top + self._content_top = value + for child in self.node.children: + if child.layout: + child.layout._origin_top = self.absolute_content_top @property def content_left(self): @@ -131,11 +130,10 @@ def content_left(self): @content_left.setter def content_left(self, value): - if value != self._content_left: - self._content_left = value - for child in self.node.children: - if child.layout: - child.layout._origin_left = self.absolute_content_left + self._content_left = value + for child in self.node.children: + if child.layout: + child.layout._origin_left = self.absolute_content_left ###################################################################### # Absolute content box position diff --git a/travertino/node.py b/travertino/node.py index 7e9efcf..325ad3b 100644 --- a/travertino/node.py +++ b/travertino/node.py @@ -79,6 +79,37 @@ def add(self, child): child._parent = self set_root(child, self.root) + def insert(self, index, child): + """Insert a node as a child of this one. + Args: + index: Index of child position. + child: A node to insert as a child to this node. + + Raises: + ValueError: If this node is a leaf, and cannot have children. + """ + if self._children is None: + raise ValueError('Cannot insert child') + + self._children.insert(index, child) + child._parent = self + set_root(child, self.root) + + def remove(self, child): + """Remove child from this node. + Args: + child: The child to remove from this node. + + Raises: + ValueError: If this node is a leaf, and cannot have children. + """ + if self._children is None: + raise ValueError('Cannot remove children') + + self._children.remove(child) + child._parent = None + set_root(child, None) + def refresh(self, viewport): """Refresh the layout and appearance of the tree this node is contained in.""" if self._root: