Merge pull request #84995 from Bitlytic/reparent-center
Add an option to center children around the new parent when reparenting
This commit is contained in:
commit
d3f64bf2d2
4 changed files with 60 additions and 0 deletions
|
@ -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>
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -94,6 +94,7 @@ class SceneTreeDock : public VBoxContainer {
|
|||
TOOL_CREATE_3D_SCENE,
|
||||
TOOL_CREATE_USER_INTERFACE,
|
||||
TOOL_CREATE_FAVORITE,
|
||||
TOOL_CENTER_PARENT,
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue