1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-09 12:50:35 +00:00

Add an option to center children around the new parent when reparenting

This commit is contained in:
Bitlytic
2023-11-16 20:58:23 -05:00
committed by Rémi Verschelde
parent 28258dfc48
commit f9e03459e8
4 changed files with 60 additions and 0 deletions

View File

@@ -1059,6 +1059,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
case TOOL_AUTO_EXPAND: {
scene_tree->set_auto_expand_selected(!EDITOR_GET("docks/scene_tree/auto_expand_to_selected"), true);
} break;
case TOOL_CENTER_PARENT: {
EditorSettings::get_singleton()->set("docks/scene_tree/center_node_on_reparent", !EDITOR_GET("docks/scene_tree/center_node_on_reparent"));
} break;
case TOOL_SCENE_EDITABLE_CHILDREN: {
if (!profile_allow_editing) {
break;
@@ -2687,6 +2690,9 @@ void SceneTreeDock::_create() {
int smaller_path_to_top = first->get_path_to(scene_root).get_name_count();
Node *top_node = first;
bool center_parent = EDITOR_GET("docks/scene_tree/center_node_on_reparent");
Vector<Node *> top_level_nodes;
for (List<Node *>::Element *E = selection.front()->next(); E; E = E->next()) {
Node *n = E->get();
ERR_FAIL_NULL(n);
@@ -2698,10 +2704,17 @@ void SceneTreeDock::_create() {
top_node = n;
smaller_path_to_top = path_length;
only_one_top_node = true;
if (center_parent) {
top_level_nodes.clear();
top_level_nodes.append(n);
}
} else if (smaller_path_to_top == path_length) {
if (only_one_top_node && top_node->get_parent() != n->get_parent()) {
only_one_top_node = false;
}
if (center_parent) {
top_level_nodes.append(n);
}
}
}
}
@@ -2722,6 +2735,44 @@ void SceneTreeDock::_create() {
// This works because editor_selection was cleared and populated with last created node in _do_create()
Node *last_created = editor_selection->get_selected_node_list().front()->get();
if (center_parent) {
// Find parent type and only average positions of relevant nodes.
Node3D *parent_node_3d = Object::cast_to<Node3D>(last_created);
if (parent_node_3d) {
Vector3 position;
uint32_t node_count = 0;
for (const Node *node : nodes) {
const Node3D *node_3d = Object::cast_to<Node3D>(node);
if (node_3d) {
position += node_3d->get_global_position();
node_count++;
}
}
if (node_count > 0) {
parent_node_3d->set_global_position(position / node_count);
}
}
Node2D *parent_node_2d = Object::cast_to<Node2D>(last_created);
if (parent_node_2d) {
Vector2 position;
uint32_t node_count = 0;
for (const Node *node : nodes) {
const Node2D *node_2d = Object::cast_to<Node2D>(node);
if (node_2d) {
position += node_2d->get_global_position();
node_count++;
}
}
if (node_count > 0) {
parent_node_2d->set_global_position(position / (real_t)node_count);
}
}
}
_do_reparent(last_created, -1, nodes, true);
}
@@ -3446,6 +3497,10 @@ void SceneTreeDock::_update_tree_menu() {
tree_menu->add_check_item(TTR("Auto Expand to Selected"), TOOL_AUTO_EXPAND);
tree_menu->set_item_checked(tree_menu->get_item_index(TOOL_AUTO_EXPAND), EDITOR_GET("docks/scene_tree/auto_expand_to_selected"));
tree_menu->add_check_item(TTR("Center Node on Reparent"), TOOL_CENTER_PARENT);
tree_menu->set_item_checked(tree_menu->get_item_index(TOOL_CENTER_PARENT), EDITOR_GET("docks/scene_tree/center_node_on_reparent"));
tree_menu->set_item_tooltip(tree_menu->get_item_index(TOOL_CENTER_PARENT), TTR("If enabled, Reparent to New Node will create the new node in the center of the selected nodes, if possible."));
PopupMenu *resource_list = memnew(PopupMenu);
resource_list->set_name("AllResources");
resource_list->connect("about_to_popup", callable_mp(this, &SceneTreeDock::_list_all_subresources).bind(resource_list));