|
@@ -1059,6 +1059,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
|
|
case TOOL_AUTO_EXPAND: {
|
|
case TOOL_AUTO_EXPAND: {
|
|
scene_tree->set_auto_expand_selected(!EDITOR_GET("docks/scene_tree/auto_expand_to_selected"), true);
|
|
scene_tree->set_auto_expand_selected(!EDITOR_GET("docks/scene_tree/auto_expand_to_selected"), true);
|
|
} break;
|
|
} 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: {
|
|
case TOOL_SCENE_EDITABLE_CHILDREN: {
|
|
if (!profile_allow_editing) {
|
|
if (!profile_allow_editing) {
|
|
break;
|
|
break;
|
|
@@ -2687,6 +2690,9 @@ void SceneTreeDock::_create() {
|
|
int smaller_path_to_top = first->get_path_to(scene_root).get_name_count();
|
|
int smaller_path_to_top = first->get_path_to(scene_root).get_name_count();
|
|
Node *top_node = first;
|
|
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()) {
|
|
for (List<Node *>::Element *E = selection.front()->next(); E; E = E->next()) {
|
|
Node *n = E->get();
|
|
Node *n = E->get();
|
|
ERR_FAIL_NULL(n);
|
|
ERR_FAIL_NULL(n);
|
|
@@ -2698,10 +2704,17 @@ void SceneTreeDock::_create() {
|
|
top_node = n;
|
|
top_node = n;
|
|
smaller_path_to_top = path_length;
|
|
smaller_path_to_top = path_length;
|
|
only_one_top_node = true;
|
|
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) {
|
|
} else if (smaller_path_to_top == path_length) {
|
|
if (only_one_top_node && top_node->get_parent() != n->get_parent()) {
|
|
if (only_one_top_node && top_node->get_parent() != n->get_parent()) {
|
|
only_one_top_node = false;
|
|
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()
|
|
// 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();
|
|
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);
|
|
_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->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->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);
|
|
PopupMenu *resource_list = memnew(PopupMenu);
|
|
resource_list->set_name("AllResources");
|
|
resource_list->set_name("AllResources");
|
|
resource_list->connect("about_to_popup", callable_mp(this, &SceneTreeDock::_list_all_subresources).bind(resource_list));
|
|
resource_list->connect("about_to_popup", callable_mp(this, &SceneTreeDock::_list_all_subresources).bind(resource_list));
|