Skip to content

Commit

Permalink
Add option to apply instance changes to base scene
Browse files Browse the repository at this point in the history
  • Loading branch information
KoBeWi committed Feb 13, 2025
1 parent c2732ae commit ac7c769
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 6 deletions.
55 changes: 51 additions & 4 deletions editor/scene_tree_dock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1260,7 +1260,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
bool editable = EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(node);

if (editable) {
editable_instance_remove_dialog->set_text(TTR("Disabling \"editable_instance\" will cause all properties of the node to be reverted to their default."));
editable_instance_remove_dialog->set_text(TTRC("Disabling \"editable_instance\" will cause all properties of the node to be reverted to their default.\nYou can choose to apply changes to base scene instead."));
editable_instance_remove_dialog->popup_centered();
break;
}
Expand Down Expand Up @@ -1303,6 +1303,34 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
}
} break;
case TOOL_SCENE_APPLY_TO_BASE: {
if (!profile_allow_editing) {
break;
}

List<Node *> selection = editor_selection->get_selected_node_list();
List<Node *>::Element *e = selection.front();
if (!e) {
break;
}

Node *local_instance = e->get();
if (!local_instance) {
break;
}

const String &scene_path = local_instance->get_scene_file_path();
if (scene_path.is_empty()) {
break;
}

Dictionary options;
options[TTR("Reset Position")] = true;
options[TTR("Reset Scale")] = true;
options[TTR("Reset Rotation")] = true;
_new_scene_from(scene_path, true, options);
EditorUndoRedoManager::get_singleton()->set_history_as_unsaved(editor_data->get_current_edited_scene_history_id());
} break;
case TOOL_SCENE_MAKE_LOCAL: {
if (!profile_allow_editing) {
break;
Expand Down Expand Up @@ -2725,6 +2753,11 @@ void SceneTreeDock::_toggle_editable_children(Node *p_node) {
undo_redo->commit_action();
}

void SceneTreeDock::_apply_editable_children() {
editable_instance_remove_dialog->hide();
_tool_selected(TOOL_SCENE_APPLY_TO_BASE);
}

void SceneTreeDock::_delete_confirm(bool p_cut) {
List<Node *> remove_list = editor_selection->get_selected_node_list();

Expand Down Expand Up @@ -3327,7 +3360,7 @@ void SceneTreeDock::set_selected(Node *p_node, bool p_emit_selected) {
scene_tree->set_selected(p_node, p_emit_selected);
}

void SceneTreeDock::_new_scene_from(const String &p_file) {
void SceneTreeDock::_new_scene_from(const String &p_file, bool p_apply_changes, const Dictionary &p_custom_options) {
List<Node *> selection = editor_selection->get_selected_node_list();

if (selection.size() != 1) {
Expand All @@ -3336,7 +3369,7 @@ void SceneTreeDock::_new_scene_from(const String &p_file) {
return;
}

if (EditorNode::get_singleton()->is_scene_open(p_file)) {
if (!p_apply_changes && EditorNode::get_singleton()->is_scene_open(p_file)) {
accept->set_text(TTR("Can't overwrite scene that is still open!"));
accept->popup_centered();
return;
Expand All @@ -3360,7 +3393,7 @@ void SceneTreeDock::_new_scene_from(const String &p_file) {
// Root node cannot ever be unique name in its own Scene!
copy->set_unique_name_in_owner(false);

const Dictionary dict = new_scene_from_dialog->get_selected_options();
const Dictionary dict = p_custom_options.is_empty() ? new_scene_from_dialog->get_selected_options() : p_custom_options;
bool reset_position = dict.get(TTR("Reset Position"), true);
bool reset_scale = dict.get(TTR("Reset Scale"), false);
bool reset_rotation = dict.get(TTR("Reset Rotation"), false);
Expand Down Expand Up @@ -3417,6 +3450,12 @@ void SceneTreeDock::_new_scene_from(const String &p_file) {
accept->popup_centered();
return;
}

if (p_apply_changes) {
EditorNode::get_singleton()->get_editor_selection_history()->clear();
EditorNode::get_singleton()->reload_scene(p_file);
EditorNode::get_singleton()->reload_instances_with_path_in_edited_scenes();
}
}

void SceneTreeDock::_set_node_owner_recursive(Node *p_node, Node *p_owner, const HashMap<const Node *, Node *> &p_inverse_duplimap) {
Expand Down Expand Up @@ -3904,6 +3943,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->set_item_shortcut(-1, ED_GET_SHORTCUT("scene_tree/toggle_editable_children"));

menu->add_check_item(TTR("Load as Placeholder"), TOOL_SCENE_USE_PLACEHOLDER);
menu->add_icon_item(get_editor_theme_icon(SNAME("ExternalLink")), TTRC("Apply Changes to Base Scene"), TOOL_SCENE_APPLY_TO_BASE);
menu->add_item(TTR("Make Local"), TOOL_SCENE_MAKE_LOCAL);
}
menu->add_icon_item(get_editor_theme_icon(SNAME("Load")), TTR("Open in Editor"), TOOL_SCENE_OPEN);
Expand Down Expand Up @@ -4817,6 +4857,13 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec
vb->add_child(delete_tracks_checkbox);

editable_instance_remove_dialog = memnew(ConfirmationDialog);
editable_instance_remove_dialog->get_ok_button()->set_text(TTRC("Revert"));

{
Button *apply = editable_instance_remove_dialog->add_button(TTRC("Apply to Base Scene"));
apply->connect(SceneStringName(pressed), callable_mp(this, &SceneTreeDock::_apply_editable_children));
}

add_child(editable_instance_remove_dialog);
editable_instance_remove_dialog->connect(SceneStringName(confirmed), callable_mp(this, &SceneTreeDock::_toggle_editable_children_from_selection));

Expand Down
5 changes: 3 additions & 2 deletions editor/scene_tree_dock.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ class SceneTreeDock : public VBoxContainer {
TOOL_AUTO_EXPAND,
TOOL_SCENE_EDITABLE_CHILDREN,
TOOL_SCENE_USE_PLACEHOLDER,
TOOL_SCENE_APPLY_TO_BASE,
TOOL_SCENE_MAKE_LOCAL,
TOOL_SCENE_OPEN,
TOOL_SCENE_CLEAR_INHERITANCE,
Expand Down Expand Up @@ -213,13 +214,13 @@ class SceneTreeDock : public VBoxContainer {
void _shader_creation_closed();

void _delete_confirm(bool p_cut = false);
void _delete_dialog_closed();

void _toggle_editable_children_from_selection();

void _reparent_nodes_to_root(Node *p_root, const Array &p_nodes, Node *p_owner);
void _reparent_nodes_to_paths_with_transform_and_name(Node *p_root, const Array &p_nodes, const Array &p_paths, const Array &p_transforms, const Array &p_names, Node *p_owner);
void _toggle_editable_children(Node *p_node);
void _apply_editable_children();

void _toggle_placeholder_from_selection();

Expand All @@ -241,7 +242,7 @@ class SceneTreeDock : public VBoxContainer {
virtual void shortcut_input(const Ref<InputEvent> &p_event) override;
void _scene_tree_gui_input(Ref<InputEvent> p_event);

void _new_scene_from(const String &p_file);
void _new_scene_from(const String &p_file, bool p_apply_changes = false, const Dictionary &p_custom_options = Dictionary());
void _set_node_owner_recursive(Node *p_node, Node *p_owner, const HashMap<const Node *, Node *> &p_inverse_duplimap);

bool _validate_no_foreign();
Expand Down

0 comments on commit ac7c769

Please sign in to comment.