move method
void
move(})
Move a node to a new position in the tree, takes the following arguments:
- node: the node to be moved
- index: the position the new node should be inserted at among its new siblings
- (optional) newParent: the new parent for this node, if null the node will be inserted in the root of the tree
Index must be valid or this method will throw. The node must also be attached to the tree controller.
Implementation
void move(
TreeNode node,
int index, {
TreeNode? newParent,
bool notify = true,
}) {
assert(node.isAttached, '''
Node must be attached in order for it to be able to be moved
''');
assert(index >= 0, 'Index must be greater than 0');
if (newParent != null) {
assert(
index <= newParent.children.length,
'Index must be within bounds 0 <= index <= new sibling array length',
);
}
if (newParent == null) {
assert(
index <= rootCount,
'Index must be within bounds 0 <= index <= new sibling array length',
);
}
final newSiblings = newParent?.children ?? rootNodes;
if (node.siblings == newSiblings) {
final oldIndex = newSiblings.indexOf(node);
if (oldIndex == index) return;
var targetIndex = index;
if (oldIndex < index) {
targetIndex--;
}
newSiblings.removeAt(oldIndex);
newSiblings.insert(targetIndex, node);
if (_onMoved != null) {
for (
var i = math.min(oldIndex, targetIndex);
i <= math.max(oldIndex, targetIndex);
i++
) {
if (i < newSiblings.length) {
_onMoved(newSiblings[i], i, node.parent, node.parent);
}
}
}
if (_onChanged != null) {
_onChanged();
}
if (notify) notifyListeners();
} else {
final oldParent = node.parent;
node.siblings.remove(node);
node._parent = newParent;
//if the node is attached as root, depth will be 0
node.depth = (newParent?.depth ?? -1) + 1;
newSiblings.insert(index, node);
if (_onMoved != null) {
_onMoved(node, index, oldParent, newParent);
for (final (subIndex, sibling)
in newSiblings.sublist(index + 1).indexed) {
_onMoved(
sibling,
subIndex + index + 1,
sibling.parent,
sibling.parent,
);
}
}
if (_onChanged != null) {
_onChanged();
}
if (notify) notifyListeners();
}
}