diff --git a/editor/scene/scene_tree_editor.cpp b/editor/scene/scene_tree_editor.cpp index 4f85224f73c..fe654d26d1f 100644 --- a/editor/scene/scene_tree_editor.cpp +++ b/editor/scene/scene_tree_editor.cpp @@ -770,20 +770,24 @@ void SceneTreeEditor::_node_script_changed(Node *p_node) { void SceneTreeEditor::_move_node_children(HashMap::Iterator &p_I) { TreeItem *item = p_I->value.item; + TreeItem *previous_item = nullptr; Node *node = p_I->key; int cc = node->get_child_count(false); for (int i = 0; i < cc; i++) { HashMap::Iterator CI = node_cache.get(node->get_child(i, false)); if (CI) { - _move_node_item(item, CI); + _move_node_item(item, CI, previous_item); + previous_item = CI->value.item; + } else { + previous_item = nullptr; } } p_I->value.has_moved_children = false; } -void SceneTreeEditor::_move_node_item(TreeItem *p_parent, HashMap::Iterator &p_I) { +void SceneTreeEditor::_move_node_item(TreeItem *p_parent, HashMap::Iterator &p_I, TreeItem *p_correct_prev) { if (!p_parent) { return; } @@ -806,13 +810,19 @@ void SceneTreeEditor::_move_node_item(TreeItem *p_parent, HashMapvalue.index != current_node_index) { - // If we just re-parented we know our index. - if (current_item_index == -1) { - current_item_index = item->get_index(); + bool already_in_correct_location; + if (current_item_index >= 0) { + // If we just re-parented we know our index. + already_in_correct_location = current_item_index == current_node_index; + } else if (p_correct_prev) { + // It's cheaper to check if we're set up correctly by checking via correct_prev if we can + already_in_correct_location = item->get_prev() == p_correct_prev; + } else { + already_in_correct_location = item->get_index() == current_node_index; } // Are we already in the right place? - if (current_node_index == current_item_index) { + if (already_in_correct_location) { p_I->value.index = current_node_index; return; } @@ -820,11 +830,14 @@ void SceneTreeEditor::_move_node_item(TreeItem *p_parent, HashMapget_child(0); + TreeItem *neighbor_item = p_parent->get_first_child(); item->move_before(neighbor_item); } else { - TreeItem *neighbor_item = p_parent->get_child(CLAMP(current_node_index - 1, 0, p_parent->get_child_count() - 1)); - item->move_after(neighbor_item); + TreeItem *prev_item = p_correct_prev; + if (!prev_item) { + prev_item = p_parent->get_child(CLAMP(current_node_index - 1, 0, p_parent->get_child_count() - 1)); + } + item->move_after(prev_item); } p_I->value.index = current_node_index; diff --git a/editor/scene/scene_tree_editor.h b/editor/scene/scene_tree_editor.h index 2b30707d293..9b5ad3cb8b6 100644 --- a/editor/scene/scene_tree_editor.h +++ b/editor/scene/scene_tree_editor.h @@ -152,7 +152,7 @@ class SceneTreeEditor : public Control { void _tree_process_mode_changed(); void _move_node_children(HashMap::Iterator &p_I); - void _move_node_item(TreeItem *p_parent, HashMap::Iterator &p_I); + void _move_node_item(TreeItem *p_parent, HashMap::Iterator &p_I, TreeItem *p_correct_prev = nullptr); void _node_child_order_changed(Node *p_node); void _node_editor_state_changed(Node *p_node); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index adb9f3a6b85..557642486a2 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -895,7 +895,7 @@ TreeItem *TreeItem::create_child(int p_index) { } else { int idx = 0; if (!children_cache.is_empty()) { - idx = MIN(children_cache.size() - 1, p_index); + idx = MIN(int(children_cache.size()) - 1, p_index); item_next = children_cache[idx]; item_prev = item_next->prev; } @@ -920,7 +920,7 @@ TreeItem *TreeItem::create_child(int p_index) { if (ti->next) { children_cache.insert(p_index, ti); } else { - children_cache.append(ti); + children_cache.push_back(ti); } } } else { @@ -957,7 +957,7 @@ void TreeItem::add_child(TreeItem *p_item) { last_child = p_item; if (!children_cache.is_empty()) { - children_cache.append(p_item); + children_cache.push_back(p_item); } validate_cache(); @@ -1111,15 +1111,15 @@ TreeItem *TreeItem::get_child(int p_index) { if (p_index < 0) { p_index += children_cache.size(); } - ERR_FAIL_INDEX_V(p_index, children_cache.size(), nullptr); + ERR_FAIL_INDEX_V(p_index, (int)children_cache.size(), nullptr); - return children_cache.get(p_index); + return children_cache[p_index]; } int TreeItem::get_visible_child_count() { _create_children_cache(); int visible_count = 0; - for (int i = 0; i < children_cache.size(); i++) { + for (uint32_t i = 0; i < children_cache.size(); i++) { if (children_cache[i]->is_visible()) { visible_count += 1; } @@ -1175,7 +1175,7 @@ void TreeItem::validate_cache() const { return; } TreeItem *scan = parent->first_child; - int index = 0; + uint32_t index = 0; while (scan) { DEV_ASSERT(parent->children_cache[index] == scan); ++index; @@ -1265,7 +1265,7 @@ void TreeItem::move_after(TreeItem *p_item) { // If the cache is empty, it has not been built but there // are items in the tree (note p_item != nullptr,) so we cannot update it. if (!parent->children_cache.is_empty()) { - parent->children_cache.append(this); + parent->children_cache.push_back(this); } } diff --git a/scene/gui/tree.h b/scene/gui/tree.h index b65e5197fdb..fff16f4bb82 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -150,7 +150,7 @@ private: TreeItem *first_child = nullptr; TreeItem *last_child = nullptr; - Vector children_cache; + LocalVector children_cache; bool is_root = false; // For tree root. Tree *tree = nullptr; // Tree (for reference). @@ -169,7 +169,7 @@ private: if (children_cache.is_empty()) { TreeItem *c = first_child; while (c) { - children_cache.append(c); + children_cache.push_back(c); c = c->next; } } @@ -201,7 +201,7 @@ private: } if (parent) { if (!parent->children_cache.is_empty()) { - parent->children_cache.remove_at(get_index()); + parent->children_cache.erase(this); } if (parent->first_child == this) { parent->first_child = next;