| 522 | } |
| 523 | |
| 524 | void Node::_move_child(Node *p_child, int p_index, bool p_ignore_end) { |
| 525 | ERR_FAIL_COND_MSG(data.blocked > 0, "Parent node is busy setting up children, `move_child()` failed. Consider using `move_child.call_deferred(child, index)` instead (or `popup.call_deferred()` if this is from a popup)."); |
| 526 | |
| 527 | // Specifying one place beyond the end |
| 528 | // means the same as moving to the last index |
| 529 | if (!p_ignore_end) { /// @todo p_ignore_end is a little hack to make back internal children work properly. |
| 530 | if (p_child->data.internal_mode == INTERNAL_MODE_FRONT) { |
| 531 | if (p_index == data.internal_children_front_count_cache) { |
| 532 | p_index--; |
| 533 | } |
| 534 | } else if (p_child->data.internal_mode == INTERNAL_MODE_BACK) { |
| 535 | if (p_index == (int)data.children_cache.size()) { |
| 536 | p_index--; |
| 537 | } |
| 538 | } else { |
| 539 | if (p_index == (int)data.children_cache.size() - data.internal_children_back_count_cache) { |
| 540 | p_index--; |
| 541 | } |
| 542 | } |
| 543 | } |
| 544 | |
| 545 | int child_index = p_child->get_index(); |
| 546 | |
| 547 | if (child_index == p_index) { |
| 548 | return; //do nothing |
| 549 | } |
| 550 | |
| 551 | int motion_from = MIN(p_index, child_index); |
| 552 | int motion_to = MAX(p_index, child_index); |
| 553 | |
| 554 | data.children_cache.remove_at(child_index); |
| 555 | data.children_cache.insert(p_index, p_child); |
| 556 | |
| 557 | if (data.tree) { |
| 558 | data.tree->tree_changed(); |
| 559 | } |
| 560 | |
| 561 | data.blocked++; |
| 562 | //new pos first |
| 563 | for (int i = motion_from; i <= motion_to; i++) { |
| 564 | if (data.children_cache[i]->data.internal_mode == INTERNAL_MODE_DISABLED) { |
| 565 | data.children_cache[i]->data.index = i - data.internal_children_front_count_cache; |
| 566 | } else if (data.children_cache[i]->data.internal_mode == INTERNAL_MODE_BACK) { |
| 567 | data.children_cache[i]->data.index = i - data.internal_children_front_count_cache - data.external_children_count_cache; |
| 568 | } else { |
| 569 | data.children_cache[i]->data.index = i; |
| 570 | } |
| 571 | } |
| 572 | // notification second |
| 573 | move_child_notify(p_child); |
| 574 | notification(NOTIFICATION_CHILD_ORDER_CHANGED); |
| 575 | emit_signal(SNAME("child_order_changed")); |
| 576 | p_child->_propagate_groups_dirty(); |
| 577 | |
| 578 | data.blocked--; |
| 579 | } |
| 580 | |
| 581 | void Node::_propagate_groups_dirty() { |
no test coverage detected