tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 788HTML 740Markdown 12TOML 62536 Sutichaykuna

Add a new method `insert_child_at_index`. (#487)

Co-authored-by: Nico Burns <nico@nicoburns.com>

23b63f058e462b47e83ed166597bfcfe1ad8a1c1 · ruwaq Remtori · (3 wata ñawpaq) · tayta 0bd2f1947 · kay commitpi sach'ata qhaway

Semántico sayk'uy · 2

src/tree/taffy_tree/tree.rs

2 qillqakuna · +44 −0

diff --git a/RELEASES.md b/RELEASES.md
index 6426ca647..7c9f62e99 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -31,6 +31,7 @@ Example usage change:
 ### Added
 
 - Support for [CSS Block layout](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow#elements_participating_in_a_block_formatting_context) has been added. This can be used via the new `Display::Block` variant of the `Display` enum. Note that inline, inline-block and float have *not* been implemented. The use case supported is block container nodes which contain block-level children.
+- Added `insert_child_at_index()` method to the `Taffy` tree. This can be used to insert a child node at any position instead of just the end.
 
 ### Removed
 
diff --git a/src/tree/taffy_tree/tree.rs b/src/tree/taffy_tree/tree.rs
index 40fd70317..060bb3519 100644
--- a/src/tree/taffy_tree/tree.rs
+++ b/src/tree/taffy_tree/tree.rs
@@ -263,6 +263,22 @@ impl Taffy {
         Ok(())
     }
 
+    /// Inserts a `child` node at the given `child_index` under the supplied `parent`, shifting all children after it to the right.
+    pub fn insert_child_at_index(&mut self, parent: NodeId, child_index: usize, child: NodeId) -> TaffyResult<()> {
+        let parent_key = parent.into();
+
+        let child_count = self.children[parent_key].len();
+        if child_index > child_count {
+            return Err(TaffyError::ChildIndexOutOfBounds { parent, child_index, child_count });
+        }
+
+        self.parents[child.into()] = Some(parent);
+        self.children[parent_key].insert(child_index, child);
+        self.mark_dirty(parent)?;
+
+        Ok(())
+    }
+
     /// Directly sets the `children` of the supplied `parent`
     pub fn set_children(&mut self, parent: NodeId, children: &[NodeId]) -> TaffyResult<()> {
         let parent_key = parent.into();
@@ -561,6 +577,33 @@ mod tests {
         assert_eq!(taffy.child_count(node).unwrap(), 2);
     }
 
+    #[test]
+    fn insert_child_at_index() {
+        let mut taffy = Taffy::new();
+
+        let child0 = taffy.new_leaf(Style::default()).unwrap();
+        let child1 = taffy.new_leaf(Style::default()).unwrap();
+        let child2 = taffy.new_leaf(Style::default()).unwrap();
+
+        let node = taffy.new_leaf(Style::default()).unwrap();
+        assert_eq!(taffy.child_count(node).unwrap(), 0);
+
+        taffy.insert_child_at_index(node, 0, child0).unwrap();
+        assert_eq!(taffy.child_count(node).unwrap(), 1);
+        assert_eq!(taffy.children(node).unwrap()[0], child0);
+
+        taffy.insert_child_at_index(node, 0, child1).unwrap();
+        assert_eq!(taffy.child_count(node).unwrap(), 2);
+        assert_eq!(taffy.children(node).unwrap()[0], child1);
+        assert_eq!(taffy.children(node).unwrap()[1], child0);
+
+        taffy.insert_child_at_index(node, 1, child2).unwrap();
+        assert_eq!(taffy.child_count(node).unwrap(), 3);
+        assert_eq!(taffy.children(node).unwrap()[0], child1);
+        assert_eq!(taffy.children(node).unwrap()[1], child2);
+        assert_eq!(taffy.children(node).unwrap()[2], child0);
+    }
+
     #[test]
     fn set_children() {
         let mut taffy = Taffy::new();