Describe the problem or limitation you are having in your project:
There is currently no way to directly add a child at an arbitrary index. The options we are have are either:
add_child then move it with move_childadd_child_below_node to specifiy a sibling. This method is already pretty poor and has been replaced with add_sibling in master, and it doesn't allow you to add a node at index 0 because the new node is added after the sibling.Honestly, I was a little surprised to find this feature missing.
Describe the feature / enhancement and how it helps to overcome the problem or limitation:
Implement a simple add_child_at which takes an index parameter in addition to the child. E.g.
# Add child at index 0
parent.add_child_at(child, 0)
If this enhancement will not be used often, can it be worked around with a few lines of script?:
It's pretty fast to work around with add then move, but tree mutations seem like common enough operations to be worth adding. If we think add_sibling was a common enough use-case, then this seems pretty reasonable too.
Is there a reason why this should be core and not an add-on in the asset library?:
Complements existing core functionality.
How about insert_child(pos, child)? This would be consistent with other existing insert() methods for various Variant types.
Out of curiosity, what's the use case for adding a child at a specific index? The only time I can think of where child order mattered to me was with viewport textures, which I still hope is a bug that can be fixed (https://github.com/godotengine/godot/issues/27790)
Out of curiosity, what's the use case for adding a child at a specific index?
Any case where you want to make changes to the tree and that the order of the nodes matters.
Control nodes are a common use case for me. They have no z-index property (that's a separate discussion) so visual ordering is managed by tree position. Godot's input events are also cascaded in tree order. This means for almost all UI work the order of the nodes is important.
ninja'd, basically what @andy-noisyduck said.
How about
insert_child(pos, child)? This would be consistent with other existinginsert()methods for various Variant types.
I'm open to any reasonable implementation of this really. I think I slightly prefer _at to insert, but I wouldn't fight for it.
I actually think we actually shouldn't aim for consistency if the other operations are also not consistent. Variants with insert normally have a matching append method, compared to nodes which use add instead. I think deliberate inconsistency is less confusing than having partial consistency. Using the add_child_at also means anyone will be able to see the method when auto-completing add_child when editing.
I guess a third option is to just make the current implementation of add_child take a 2nd index parameter, and have it default to -1 or something to mean append? Though I think _at is cleaner.
What about if add_child had a 2nd optional parameter for the index, defaulting to -1, which means auto/at the end?
Anyway, I think any implementation should have the argument order be (child, index).
Also, let's avoid the words pos and/or position since this can be confused with transforming/translating.
Anyway, I think any implementation should have the argument order be
(child, index).
This would make it inconsistent with the rest of the Variant methods where the order is (index, child), so either the entire codebase would have to be changed, or the order must comply with the existing convention.
What about if
add_childhad a 2nd optional parameter for the index, defaulting to -1, which means auto/at the end?
It might be that the logic behind having (index, element) order is to prevent the default index specifically to prevent programming errors, dunno.
Out of curiosity, what's the use case for adding a child at a specific index?
Any case where you want to make changes to the tree and that the order of the nodes matters.
Controlnodes are a common use case for me. They have no z-index property (that's a separate discussion) so visual ordering is managed by tree position. Godot's input events are also cascaded in tree order. This means for almost all UI work the order of the nodes is important.
I can't really imagine use for 3d, for 2d there's ysort node
>
I can't really imagine use for 3d, for 2d there's ysort node
YSort isn't really helpful because it sorts via the y coordinates of the childs (Like if a tree is higher than a house on the y coordinate then it goes behind it). What if you have 2 WindowDialogs and you want to have the one, which is focused by the user, to go on the top of the screen.? You would have to move the focused Dialog below the 2nd Dialog which doesn't make sense (This is the exact same problem from #839 ).
I know this is not really contributing to this issue but I just wanted to say that :)
Most helpful comment
Any case where you want to make changes to the tree and that the order of the nodes matters.
Controlnodes are a common use case for me. They have no z-index property (that's a separate discussion) so visual ordering is managed by tree position. Godot's input events are also cascaded in tree order. This means for almost all UI work the order of the nodes is important.