Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 1 commit into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/classes/EditorSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,9 @@
<member name="docks/scene_tree/auto_expand_to_selected" type="bool" setter="" getter="">
If [code]true[/code], the scene tree dock will automatically unfold nodes when a node that has folded parents is selected.
</member>
<member name="docks/scene_tree/center_node_on_reparent" type="bool" setter="" getter="">
If [code]true[/code], new node created when reparenting node(s) will be positioned at the average position of the selected node(s).
</member>
<member name="docks/scene_tree/start_create_dialog_fully_expanded" type="bool" setter="" getter="">
If [code]true[/code], the Create dialog (Create New Node/Create New Resource) will start with all its sections expanded. Otherwise, sections will be collapsed until the user starts searching (which will automatically expand sections as needed).
</member>
Expand Down
1 change: 1 addition & 0 deletions editor/editor_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
// SceneTree
_initial_set("docks/scene_tree/start_create_dialog_fully_expanded", false);
_initial_set("docks/scene_tree/auto_expand_to_selected", true);
_initial_set("docks/scene_tree/center_node_on_reparent", false);

// FileSystem
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "docks/filesystem/thumbnail_size", 64, "32,128,16")
Expand Down
55 changes: 55 additions & 0 deletions editor/scene_tree_dock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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);
}
}
}
}
Expand All @@ -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);
}

Expand Down Expand Up @@ -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);
KoBeWi marked this conversation as resolved.
Show resolved Hide resolved
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));
Expand Down
1 change: 1 addition & 0 deletions editor/scene_tree_dock.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ class SceneTreeDock : public VBoxContainer {
TOOL_CREATE_3D_SCENE,
TOOL_CREATE_USER_INTERFACE,
TOOL_CREATE_FAVORITE,
TOOL_CENTER_PARENT,

};

Expand Down
Loading