summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/connections_dialog.cpp7
-rw-r--r--editor/connections_dialog.h3
-rw-r--r--editor/debugger/editor_debugger_node.cpp6
-rw-r--r--editor/editor_audio_buses.cpp2
-rw-r--r--editor/editor_autoload_settings.cpp10
-rw-r--r--editor/editor_build_profile.cpp4
-rw-r--r--editor/editor_data.cpp2
-rw-r--r--editor/editor_fonts.cpp32
-rw-r--r--editor/editor_help.cpp2
-rw-r--r--editor/editor_inspector.cpp20
-rw-r--r--editor/editor_inspector.h8
-rw-r--r--editor/editor_locale_dialog.cpp6
-rw-r--r--editor/editor_locale_dialog.h3
-rw-r--r--editor/editor_log.cpp3
-rw-r--r--editor/editor_node.cpp19
-rw-r--r--editor/editor_node.h3
-rw-r--r--editor/editor_plugin.cpp13
-rw-r--r--editor/editor_plugin.h5
-rw-r--r--editor/editor_plugin_settings.h1
-rw-r--r--editor/editor_properties.cpp5
-rw-r--r--editor/editor_properties_array_dict.cpp2
-rw-r--r--editor/editor_settings.cpp2
-rw-r--r--editor/editor_settings_dialog.cpp8
-rw-r--r--editor/editor_settings_dialog.h4
-rw-r--r--editor/editor_undo_redo_manager.cpp62
-rw-r--r--editor/editor_undo_redo_manager.h4
-rw-r--r--editor/filesystem_dock.cpp77
-rw-r--r--editor/groups_editor.cpp16
-rw-r--r--editor/groups_editor.h8
-rw-r--r--editor/history_dock.cpp251
-rw-r--r--editor/history_dock.h66
-rw-r--r--editor/import/resource_importer_layered_texture.cpp2
-rw-r--r--editor/inspector_dock.cpp2
-rw-r--r--editor/localization_editor.cpp11
-rw-r--r--editor/localization_editor.h2
-rw-r--r--editor/node_dock.cpp2
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.cpp7
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.h3
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.cpp14
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.h4
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp12
-rw-r--r--editor/plugins/animation_player_editor_plugin.h3
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp66
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h5
-rw-r--r--editor/plugins/curve_editor_plugin.cpp63
-rw-r--r--editor/plugins/editor_preview_plugins.cpp2
-rw-r--r--editor/plugins/gradient_editor.cpp2
-rw-r--r--editor/plugins/light_occluder_2d_editor_plugin.cpp5
-rw-r--r--editor/plugins/line_2d_editor_plugin.cpp4
-rw-r--r--editor/plugins/navigation_polygon_editor_plugin.cpp7
-rw-r--r--editor/plugins/node_3d_editor_gizmos.cpp27
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp102
-rw-r--r--editor/plugins/node_3d_editor_plugin.h7
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.cpp8
-rw-r--r--editor/plugins/resource_preloader_editor_plugin.cpp1
-rw-r--r--editor/plugins/script_editor_plugin.cpp2
-rw-r--r--editor/plugins/shader_editor_plugin.cpp3
-rw-r--r--editor/plugins/texture_region_editor_plugin.cpp83
-rw-r--r--editor/plugins/texture_region_editor_plugin.h2
-rw-r--r--editor/plugins/tiles/tile_set_atlas_source_editor.cpp11
-rw-r--r--editor/plugins/tiles/tile_set_atlas_source_editor.h2
-rw-r--r--editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp8
-rw-r--r--editor/plugins/tiles/tile_set_scenes_collection_source_editor.h4
-rw-r--r--editor/plugins/version_control_editor_plugin.cpp2
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp10
-rw-r--r--editor/project_settings_editor.cpp11
-rw-r--r--editor/project_settings_editor.h2
-rw-r--r--editor/scene_tree_dock.cpp5
-rw-r--r--editor/scene_tree_editor.cpp12
-rw-r--r--editor/scene_tree_editor.h6
-rw-r--r--editor/shader_globals_editor.cpp2
71 files changed, 856 insertions, 324 deletions
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp
index de7f5c8b88..ed2044c117 100644
--- a/editor/connections_dialog.cpp
+++ b/editor/connections_dialog.cpp
@@ -684,6 +684,7 @@ void ConnectionsDock::_connect(ConnectDialog::ConnectionData p_cd) {
}
Callable callable = p_cd.get_callable();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(vformat(TTR("Connect '%s' to '%s'"), String(p_cd.signal), String(p_cd.method)));
undo_redo->add_do_method(source, "connect", p_cd.signal, callable, p_cd.flags);
undo_redo->add_undo_method(source, "disconnect", p_cd.signal, callable);
@@ -704,6 +705,7 @@ void ConnectionsDock::_disconnect(TreeItem &p_item) {
ERR_FAIL_COND(cd.source != selected_node); // Shouldn't happen but... Bugcheck.
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(vformat(TTR("Disconnect '%s' from '%s'"), cd.signal, cd.method));
Callable callable = cd.get_callable();
@@ -730,6 +732,7 @@ void ConnectionsDock::_disconnect_all() {
TreeItem *child = item->get_first_child();
String signal_name = item->get_metadata(0).operator Dictionary()["name"];
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(vformat(TTR("Disconnect all from signal: '%s'"), signal_name));
while (child) {
@@ -991,10 +994,6 @@ void ConnectionsDock::_bind_methods() {
ClassDB::bind_method("update_tree", &ConnectionsDock::update_tree);
}
-void ConnectionsDock::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) {
- undo_redo = p_undo_redo;
-}
-
void ConnectionsDock::set_node(Node *p_node) {
selected_node = p_node;
update_tree();
diff --git a/editor/connections_dialog.h b/editor/connections_dialog.h
index 126a0ca828..fcfc501386 100644
--- a/editor/connections_dialog.h
+++ b/editor/connections_dialog.h
@@ -47,7 +47,6 @@
#include "scene/gui/tree.h"
class ConnectDialogBinds;
-class EditorUndoRedoManager;
class ConnectDialog : public ConfirmationDialog {
GDCLASS(ConnectDialog, ConfirmationDialog);
@@ -197,7 +196,6 @@ class ConnectionsDock : public VBoxContainer {
Button *connect_button = nullptr;
PopupMenu *signal_menu = nullptr;
PopupMenu *slot_menu = nullptr;
- Ref<EditorUndoRedoManager> undo_redo;
LineEdit *search_box = nullptr;
HashMap<StringName, HashMap<StringName, String>> descr_cache;
@@ -231,7 +229,6 @@ protected:
static void _bind_methods();
public:
- void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo);
void set_node(Node *p_node);
void update_tree();
diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp
index edcbcaf963..68aff328ed 100644
--- a/editor/debugger/editor_debugger_node.cpp
+++ b/editor/debugger/editor_debugger_node.cpp
@@ -229,6 +229,12 @@ void EditorDebuggerNode::stop() {
if (server.is_valid()) {
server->stop();
EditorNode::get_log()->add_message("--- Debugging process stopped ---", EditorLog::MSG_TYPE_EDITOR);
+
+ if (EditorNode::get_singleton()->is_movie_maker_enabled()) {
+ // Request attention in case the user was doing something else when movie recording is finished.
+ DisplayServer::get_singleton()->window_request_attention();
+ }
+
server.unref();
}
// Also close all debugging sessions.
diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp
index 46df618d57..24116a8053 100644
--- a/editor/editor_audio_buses.cpp
+++ b/editor/editor_audio_buses.cpp
@@ -338,7 +338,7 @@ float EditorAudioBus::_normalized_volume_to_scaled_db(float normalized) {
* values to relative decibal values.
* One formula is an exponential graph which intends to counteract
* the logarithmic nature of human hearing. This is an approximation
- * of the behaviour of a 'logarithmic potentiometer' found on most
+ * of the behavior of a 'logarithmic potentiometer' found on most
* musical instruments and also emulated in popular software.
* The other two equations are hand-tuned linear tapers that intend to
* try to ease the exponential equation in areas where it makes sense.*/
diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp
index 90310bb43c..598bcdc639 100644
--- a/editor/editor_autoload_settings.cpp
+++ b/editor/editor_autoload_settings.cpp
@@ -194,7 +194,7 @@ void EditorAutoloadSettings::_autoload_edited() {
TreeItem *ti = tree->get_edited();
int column = tree->get_edited_column();
- Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
if (column == 0) {
String name = ti->get_text(0);
@@ -289,7 +289,7 @@ void EditorAutoloadSettings::_autoload_button_pressed(Object *p_item, int p_colu
String name = "autoload/" + ti->get_text(0);
- Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
switch (p_button) {
case BUTTON_OPEN: {
@@ -714,7 +714,7 @@ void EditorAutoloadSettings::drop_data_fw(const Point2 &p_point, const Variant &
orders.sort();
- Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Rearrange Autoloads"));
@@ -757,7 +757,7 @@ bool EditorAutoloadSettings::autoload_add(const String &p_name, const String &p_
name = "autoload/" + name;
- Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add Autoload"));
// Singleton autoloads are represented with a leading "*" in their path.
@@ -783,7 +783,7 @@ bool EditorAutoloadSettings::autoload_add(const String &p_name, const String &p_
void EditorAutoloadSettings::autoload_remove(const String &p_name) {
String name = "autoload/" + p_name;
- Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
int order = ProjectSettings::get_singleton()->get_order(name);
diff --git a/editor/editor_build_profile.cpp b/editor/editor_build_profile.cpp
index 7fd27692b0..96c69c0bd1 100644
--- a/editor/editor_build_profile.cpp
+++ b/editor/editor_build_profile.cpp
@@ -875,7 +875,7 @@ EditorBuildProfileManager::EditorBuildProfileManager() {
import_profile = memnew(EditorFileDialog);
add_child(import_profile);
import_profile->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
- import_profile->add_filter("*.build", TTR("Egine Build Profile"));
+ import_profile->add_filter("*.build", TTR("Engine Build Profile"));
import_profile->connect("files_selected", callable_mp(this, &EditorBuildProfileManager::_import_profile));
import_profile->set_title(TTR("Load Profile"));
import_profile->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
@@ -883,7 +883,7 @@ EditorBuildProfileManager::EditorBuildProfileManager() {
export_profile = memnew(EditorFileDialog);
add_child(export_profile);
export_profile->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
- export_profile->add_filter("*.build", TTR("Egine Build Profile"));
+ export_profile->add_filter("*.build", TTR("Engine Build Profile"));
export_profile->connect("file_selected", callable_mp(this, &EditorBuildProfileManager::_export_profile));
export_profile->set_title(TTR("Export Profile"));
export_profile->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp
index 6d8f0df452..a3dd19bb67 100644
--- a/editor/editor_data.cpp
+++ b/editor/editor_data.cpp
@@ -457,12 +457,10 @@ Callable EditorData::get_move_array_element_function(const StringName &p_class)
}
void EditorData::remove_editor_plugin(EditorPlugin *p_plugin) {
- p_plugin->undo_redo = Ref<EditorUndoRedoManager>();
editor_plugins.erase(p_plugin);
}
void EditorData::add_editor_plugin(EditorPlugin *p_plugin) {
- p_plugin->undo_redo = undo_redo_manager;
editor_plugins.push_back(p_plugin);
}
diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp
index 90f3f8d2f5..51ebc31df3 100644
--- a/editor/editor_fonts.cpp
+++ b/editor/editor_fonts.cpp
@@ -57,6 +57,24 @@ Ref<FontFile> load_external_font(const String &p_path, TextServer::Hinting p_hin
return font;
}
+Ref<SystemFont> load_system_font(const PackedStringArray &p_names, TextServer::Hinting p_hinting, TextServer::FontAntialiasing p_aa, bool p_autohint, TextServer::SubpixelPositioning p_font_subpixel_positioning, bool p_msdf = false, TypedArray<Font> *r_fallbacks = nullptr) {
+ Ref<SystemFont> font;
+ font.instantiate();
+
+ font->set_font_names(p_names);
+ font->set_multichannel_signed_distance_field(p_msdf);
+ font->set_antialiasing(p_aa);
+ font->set_hinting(p_hinting);
+ font->set_force_autohinter(p_autohint);
+ font->set_subpixel_positioning(p_font_subpixel_positioning);
+
+ if (r_fallbacks != nullptr) {
+ r_fallbacks->push_back(font);
+ }
+
+ return font;
+}
+
Ref<FontFile> load_internal_font(const uint8_t *p_data, size_t p_size, TextServer::Hinting p_hinting, TextServer::FontAntialiasing p_aa, bool p_autohint, TextServer::SubpixelPositioning p_font_subpixel_positioning, bool p_msdf = false, TypedArray<Font> *r_fallbacks = nullptr) {
Ref<FontFile> font;
font.instantiate();
@@ -166,6 +184,20 @@ void editor_register_fonts(Ref<Theme> p_theme) {
Ref<FontFile> thai_font_bold = load_internal_font(_font_NotoSansThaiUI_Bold, _font_NotoSansThaiUI_Bold_size, font_hinting, font_antialiasing, true, font_subpixel_positioning, false, &fallbacks_bold);
Ref<FontVariation> fallback_font_bold = make_bold_font(fallback_font, embolden_strength, &fallbacks_bold);
Ref<FontVariation> japanese_font_bold = make_bold_font(japanese_font, embolden_strength, &fallbacks_bold);
+
+ if (OS::get_singleton()->has_feature("system_fonts")) {
+ PackedStringArray emoji_font_names;
+ emoji_font_names.push_back("Apple Color Emoji");
+ emoji_font_names.push_back("Segoe UI Emoji");
+ emoji_font_names.push_back("Noto Color Emoji");
+ emoji_font_names.push_back("Twitter Color Emoji");
+ emoji_font_names.push_back("OpenMoji");
+ emoji_font_names.push_back("EmojiOne Color");
+ Ref<SystemFont> emoji_font = load_system_font(emoji_font_names, font_hinting, font_antialiasing, true, font_subpixel_positioning, false);
+ fallbacks.push_back(emoji_font);
+ fallbacks_bold.push_back(emoji_font);
+ }
+
default_font_bold->set_fallbacks(fallbacks_bold);
default_font_bold_msdf->set_fallbacks(fallbacks_bold);
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index ddb9bb30f1..89398409a2 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -375,7 +375,7 @@ void EditorHelp::_add_method(const DocData::MethodDoc &p_method, bool p_overview
if (qualifier == "vararg") {
hint = TTR("This method supports a variable number of arguments.");
} else if (qualifier == "virtual") {
- hint = TTR("This method is called by the engine.\nIt can be overriden to customise built-in behavior.");
+ hint = TTR("This method is called by the engine.\nIt can be overridden to customize built-in behavior.");
} else if (qualifier == "const") {
hint = TTR("This method has no side effects.\nIt does not modify the object in any way.");
} else if (qualifier == "static") {
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index 94dd4d0606..6e18bde303 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -39,6 +39,7 @@
#include "editor/editor_property_name_processor.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/script_editor_plugin.h"
#include "multi_node_edit.h"
#include "scene/gui/center_container.h"
@@ -1698,6 +1699,7 @@ void EditorInspectorArray::_move_element(int p_element_index, int p_to_pos) {
} else {
action_name = vformat("Move element %d to position %d in property array with prefix %s.", p_element_index, p_to_pos, array_element_prefix);
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(action_name);
if (mode == MODE_USE_MOVE_ARRAY_ELEMENT_FUNCTION) {
// Call the function.
@@ -1841,6 +1843,7 @@ void EditorInspectorArray::_move_element(int p_element_index, int p_to_pos) {
}
void EditorInspectorArray::_clear_array() {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(vformat("Clear property array with prefix %s.", array_element_prefix));
if (mode == MODE_USE_MOVE_ARRAY_ELEMENT_FUNCTION) {
for (int i = count - 1; i >= 0; i--) {
@@ -1893,6 +1896,7 @@ void EditorInspectorArray::_resize_array(int p_size) {
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(vformat("Resize property array with prefix %s.", array_element_prefix));
if (p_size > count) {
if (mode == MODE_USE_MOVE_ARRAY_ELEMENT_FUNCTION) {
@@ -2242,10 +2246,6 @@ void EditorInspectorArray::_bind_methods() {
ADD_SIGNAL(MethodInfo("page_change_request"));
}
-void EditorInspectorArray::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) {
- undo_redo = p_undo_redo;
-}
-
void EditorInspectorArray::setup_with_move_element_function(Object *p_object, String p_label, const StringName &p_array_element_prefix, int p_page, const Color &p_bg_color, bool p_foldable, bool p_movable, bool p_numbered, int p_page_length, const String &p_add_item_text) {
count_property = "";
mode = MODE_USE_MOVE_ARRAY_ELEMENT_FUNCTION;
@@ -2508,10 +2508,6 @@ Button *EditorInspector::create_inspector_action_button(const String &p_text) {
return button;
}
-void EditorInspector::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) {
- undo_redo = p_undo_redo;
-}
-
String EditorInspector::get_selected_path() const {
return property_selected;
}
@@ -3077,7 +3073,6 @@ void EditorInspector::update_tree() {
int page = per_array_page.has(array_element_prefix) ? per_array_page[array_element_prefix] : 0;
editor_inspector_array->setup_with_move_element_function(object, array_label, array_element_prefix, page, c, use_folding);
editor_inspector_array->connect("page_change_request", callable_mp(this, &EditorInspector::_page_change_request).bind(array_element_prefix));
- editor_inspector_array->set_undo_redo(undo_redo);
} else if (p.type == Variant::INT) {
// Setup the array to use the count property and built-in functions to create/move/delete elements.
if (class_name_components.size() >= 2) {
@@ -3087,8 +3082,6 @@ void EditorInspector::update_tree() {
editor_inspector_array->setup_with_count_property(object, class_name_components[0], p.name, array_element_prefix, page, c, foldable, movable, numbered, page_size, add_button_text, swap_method);
editor_inspector_array->connect("page_change_request", callable_mp(this, &EditorInspector::_page_change_request).bind(array_element_prefix));
-
- editor_inspector_array->set_undo_redo(undo_redo);
}
}
@@ -3565,6 +3558,7 @@ void EditorInspector::_edit_set(const String &p_name, const Variant &p_value, bo
}
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
if (!undo_redo.is_valid() || bool(object->call("_dont_undo_redo"))) {
object->set(p_name, p_value);
if (p_refresh_all) {
@@ -3685,6 +3679,7 @@ void EditorInspector::_multiple_properties_changed(Vector<String> p_paths, Array
}
names += p_paths[i];
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Set Multiple:") + " " + names, UndoRedo::MERGE_ENDS);
for (int i = 0; i < p_paths.size(); i++) {
_edit_set(p_paths[i], p_values[i], false, "");
@@ -3719,6 +3714,7 @@ void EditorInspector::_property_deleted(const String &p_path) {
if (p_path.begins_with("metadata/")) {
String name = p_path.replace_first("metadata/", "");
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(vformat(TTR("Remove metadata %s"), name));
undo_redo->add_do_method(object, "remove_meta", name);
undo_redo->add_undo_method(object, "set_meta", name, object->get_meta(name));
@@ -3784,6 +3780,7 @@ void EditorInspector::_property_pinned(const String &p_path, bool p_pinned) {
Node *node = Object::cast_to<Node>(object);
ERR_FAIL_COND(!node);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
if (undo_redo.is_valid()) {
undo_redo->create_action(vformat(p_pinned ? TTR("Pinned %s") : TTR("Unpinned %s"), p_path));
undo_redo->add_do_method(node, "_set_property_pinned", p_path, p_pinned);
@@ -3981,6 +3978,7 @@ void EditorInspector::_add_meta_confirm() {
Variant defval;
Callable::CallError ce;
Variant::construct(Variant::Type(add_meta_type->get_selected_id()), defval, nullptr, 0, ce);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(vformat(TTR("Add metadata %s"), name));
undo_redo->add_do_method(object, "set_meta", name, defval);
undo_redo->add_undo_method(object, "remove_meta", name);
diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h
index bada02e254..1b93b19845 100644
--- a/editor/editor_inspector.h
+++ b/editor/editor_inspector.h
@@ -31,7 +31,6 @@
#ifndef EDITOR_INSPECTOR_H
#define EDITOR_INSPECTOR_H
-#include "editor/editor_undo_redo_manager.h"
#include "editor_property_name_processor.h"
#include "scene/gui/box_container.h"
#include "scene/gui/button.h"
@@ -305,8 +304,6 @@ public:
class EditorInspectorArray : public EditorInspectorSection {
GDCLASS(EditorInspectorArray, EditorInspectorSection);
- Ref<EditorUndoRedoManager> undo_redo;
-
enum Mode {
MODE_NONE,
MODE_USE_COUNT_PROPERTY,
@@ -401,8 +398,6 @@ protected:
static void _bind_methods();
public:
- void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo);
-
void setup_with_move_element_function(Object *p_object, String p_label, const StringName &p_array_element_prefix, int p_page, const Color &p_bg_color, bool p_foldable, bool p_movable = true, bool p_numbered = false, int p_page_length = 5, const String &p_add_item_text = "");
void setup_with_count_property(Object *p_object, String p_label, const StringName &p_count_property, const StringName &p_array_element_prefix, int p_page, const Color &p_bg_color, bool p_foldable, bool p_movable = true, bool p_numbered = false, int p_page_length = 5, const String &p_add_item_text = "", const String &p_swap_method = "");
VBoxContainer *get_vbox(int p_index);
@@ -441,7 +436,6 @@ public:
class EditorInspector : public ScrollContainer {
GDCLASS(EditorInspector, ScrollContainer);
- Ref<EditorUndoRedoManager> undo_redo;
enum {
MAX_PLUGINS = 1024
};
@@ -555,8 +549,6 @@ public:
static EditorProperty *instantiate_property_editor(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide = false);
- void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo);
-
String get_selected_path() const;
void update_tree();
diff --git a/editor/editor_locale_dialog.cpp b/editor/editor_locale_dialog.cpp
index 106cc61947..a913fb2fd9 100644
--- a/editor/editor_locale_dialog.cpp
+++ b/editor/editor_locale_dialog.cpp
@@ -141,6 +141,7 @@ void EditorLocaleDialog::_filter_lang_option_changed() {
f_lang_all.sort();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Changed Locale Language Filter"));
undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/language_filter", f_lang_all);
undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/language_filter", prev);
@@ -174,6 +175,7 @@ void EditorLocaleDialog::_filter_script_option_changed() {
f_script_all.sort();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Changed Locale Script Filter"));
undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/script_filter", f_script_all);
undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/script_filter", prev);
@@ -207,6 +209,7 @@ void EditorLocaleDialog::_filter_cnt_option_changed() {
f_cnt_all.sort();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Changed Locale Country Filter"));
undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/country_filter", f_cnt_all);
undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/country_filter", prev);
@@ -221,6 +224,7 @@ void EditorLocaleDialog::_filter_mode_changed(int p_mode) {
prev = GLOBAL_GET("internationalization/locale/locale_filter_mode");
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Changed Locale Filter Mode"));
undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/locale_filter_mode", f_mode);
undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/locale_filter_mode", prev);
@@ -385,8 +389,6 @@ void EditorLocaleDialog::popup_locale_dialog() {
}
EditorLocaleDialog::EditorLocaleDialog() {
- undo_redo = EditorNode::get_undo_redo();
-
set_title(TTR("Select a Locale"));
VBoxContainer *vb = memnew(VBoxContainer);
diff --git a/editor/editor_locale_dialog.h b/editor/editor_locale_dialog.h
index 8ac642a038..48f9edd4b0 100644
--- a/editor/editor_locale_dialog.h
+++ b/editor/editor_locale_dialog.h
@@ -40,7 +40,6 @@ class VBoxContainer;
class LineEdit;
class Tree;
class OptionButton;
-class EditorUndoRedoManager;
class EditorLocaleDialog : public ConfirmationDialog {
GDCLASS(EditorLocaleDialog, ConfirmationDialog);
@@ -63,8 +62,6 @@ class EditorLocaleDialog : public ConfirmationDialog {
Tree *script_list = nullptr;
Tree *cnt_list = nullptr;
- Ref<EditorUndoRedoManager> undo_redo;
-
bool locale_set = false;
bool updating_lists = false;
diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp
index 0f2543f708..84284a7f31 100644
--- a/editor/editor_log.cpp
+++ b/editor/editor_log.cpp
@@ -30,6 +30,7 @@
#include "editor_log.h"
+#include "core/object/undo_redo.h"
#include "core/os/keyboard.h"
#include "core/version.h"
#include "editor/editor_node.h"
@@ -226,7 +227,7 @@ void EditorLog::add_message(const String &p_msg, MessageType p_type) {
// Make text split by new lines their own message.
// See #41321 for reasoning. At time of writing, multiple print()'s in running projects
// get grouped together and sent to the editor log as one message. This can mess with the
- // search functionality (see the comments on the PR above for more details). This behaviour
+ // search functionality (see the comments on the PR above for more details). This behavior
// also matches that of other IDE's.
Vector<String> lines = p_msg.split("\n", true);
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index bbb7fb384a..716e0b454f 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -110,6 +110,7 @@
#include "editor/export/export_template_manager.h"
#include "editor/export/project_export.h"
#include "editor/filesystem_dock.h"
+#include "editor/history_dock.h"
#include "editor/import/audio_stream_import_settings.h"
#include "editor/import/dynamic_font_import_settings.h"
#include "editor/import/editor_import_collada.h"
@@ -3560,6 +3561,14 @@ bool EditorNode::is_addon_plugin_enabled(const String &p_addon) const {
return addon_name_to_plugin.has("res://addons/" + p_addon + "/plugin.cfg");
}
+void EditorNode::set_movie_maker_enabled(bool p_enabled) {
+ write_movie_button->set_pressed(p_enabled);
+}
+
+bool EditorNode::is_movie_maker_enabled() const {
+ return write_movie_button->is_pressed();
+}
+
void EditorNode::_remove_edited_scene(bool p_change_tab) {
int new_index = editor_data.get_edited_scene();
int old_index = new_index;
@@ -3689,6 +3698,7 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) {
EditorDebuggerNode::get_singleton()->update_live_edit_root();
ScriptEditor::get_singleton()->set_scene_root_script(editor_data.get_scene_root_script(editor_data.get_edited_scene()));
editor_data.notify_edited_scene_changed();
+ emit_signal(SNAME("scene_changed"));
}
bool EditorNode::is_changing_scene() const {
@@ -4075,7 +4085,7 @@ void EditorNode::_quick_opened() {
List<String> scene_extensions;
ResourceLoader::get_recognized_extensions_for_type("PackedScene", &scene_extensions);
- if (open_scene_dialog || scene_extensions.find(files[i].get_extension())) {
+ if (open_scene_dialog || scene_extensions.find(files[i].get_extension().to_lower())) {
open_request(res_path);
} else {
load_resource(res_path);
@@ -6032,6 +6042,7 @@ void EditorNode::_bind_methods() {
ADD_SIGNAL(MethodInfo("resource_saved", PropertyInfo(Variant::OBJECT, "obj")));
ADD_SIGNAL(MethodInfo("scene_saved", PropertyInfo(Variant::STRING, "path")));
ADD_SIGNAL(MethodInfo("project_settings_changed"));
+ ADD_SIGNAL(MethodInfo("scene_changed"));
}
static Node *_resource_get_edited_scene() {
@@ -7097,6 +7108,8 @@ EditorNode::EditorNode() {
filesystem_dock->connect("display_mode_changed", callable_mp(this, &EditorNode::_save_docks));
get_project_settings()->connect_filesystem_dock_signals(filesystem_dock);
+ HistoryDock *hd = memnew(HistoryDock);
+
// Scene: Top left.
dock_slot[DOCK_SLOT_LEFT_UR]->add_child(SceneTreeDock::get_singleton());
dock_slot[DOCK_SLOT_LEFT_UR]->set_tab_title(dock_slot[DOCK_SLOT_LEFT_UR]->get_tab_idx_from_control(SceneTreeDock::get_singleton()), TTR("Scene"));
@@ -7117,6 +7130,10 @@ EditorNode::EditorNode() {
dock_slot[DOCK_SLOT_RIGHT_UL]->add_child(NodeDock::get_singleton());
dock_slot[DOCK_SLOT_RIGHT_UL]->set_tab_title(dock_slot[DOCK_SLOT_RIGHT_UL]->get_tab_idx_from_control(NodeDock::get_singleton()), TTR("Node"));
+ // History: Full height right, behind Node.
+ dock_slot[DOCK_SLOT_RIGHT_UL]->add_child(hd);
+ dock_slot[DOCK_SLOT_RIGHT_UL]->set_tab_title(dock_slot[DOCK_SLOT_RIGHT_UL]->get_tab_idx_from_control(hd), TTR("History"));
+
// Hide unused dock slots and vsplits.
dock_slot[DOCK_SLOT_LEFT_UL]->hide();
dock_slot[DOCK_SLOT_LEFT_BL]->hide();
diff --git a/editor/editor_node.h b/editor/editor_node.h
index b5d844558e..9c8d564057 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -770,6 +770,9 @@ public:
void set_addon_plugin_enabled(const String &p_addon, bool p_enabled, bool p_config_changed = false);
bool is_addon_plugin_enabled(const String &p_addon) const;
+ void set_movie_maker_enabled(bool p_enabled);
+ bool is_movie_maker_enabled() const;
+
void edit_node(Node *p_node);
void edit_resource(const Ref<Resource> &p_resource) { InspectorDock::get_singleton()->edit_resource(p_resource); };
diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp
index e852100555..8fca21ae7b 100644
--- a/editor/editor_plugin.cpp
+++ b/editor/editor_plugin.cpp
@@ -289,6 +289,14 @@ bool EditorInterface::is_plugin_enabled(const String &p_plugin) const {
return EditorNode::get_singleton()->is_addon_plugin_enabled(p_plugin);
}
+void EditorInterface::set_movie_maker_enabled(bool p_enabled) {
+ EditorNode::get_singleton()->set_movie_maker_enabled(p_enabled);
+}
+
+bool EditorInterface::is_movie_maker_enabled() const {
+ return EditorNode::get_singleton()->is_movie_maker_enabled();
+}
+
EditorInspector *EditorInterface::get_inspector() const {
return InspectorDock::get_inspector_singleton();
}
@@ -364,6 +372,9 @@ void EditorInterface::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_plugin_enabled", "plugin", "enabled"), &EditorInterface::set_plugin_enabled);
ClassDB::bind_method(D_METHOD("is_plugin_enabled", "plugin"), &EditorInterface::is_plugin_enabled);
+ ClassDB::bind_method(D_METHOD("set_movie_maker_enabled", "enabled"), &EditorInterface::set_movie_maker_enabled);
+ ClassDB::bind_method(D_METHOD("is_movie_maker_enabled"), &EditorInterface::is_movie_maker_enabled);
+
ClassDB::bind_method(D_METHOD("get_inspector"), &EditorInterface::get_inspector);
ClassDB::bind_method(D_METHOD("save_scene"), &EditorInterface::save_scene);
@@ -956,7 +967,7 @@ void EditorPlugin::_bind_methods() {
}
Ref<EditorUndoRedoManager> EditorPlugin::get_undo_redo() {
- return undo_redo;
+ return EditorNode::get_undo_redo();
}
EditorPluginCreateFunc EditorPlugins::creation_funcs[MAX_CREATE_FUNCS];
diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h
index 1211bcf53c..753ccedf70 100644
--- a/editor/editor_plugin.h
+++ b/editor/editor_plugin.h
@@ -32,7 +32,6 @@
#define EDITOR_PLUGIN_H
#include "core/io/config_file.h"
-#include "core/object/undo_redo.h"
#include "editor/debugger/editor_debugger_node.h"
#include "editor/editor_inspector.h"
#include "editor/editor_translation_parser.h"
@@ -113,6 +112,9 @@ public:
void set_plugin_enabled(const String &p_plugin, bool p_enabled);
bool is_plugin_enabled(const String &p_plugin) const;
+ void set_movie_maker_enabled(bool p_enabled);
+ bool is_movie_maker_enabled() const;
+
EditorInspector *get_inspector() const;
Error save_scene();
@@ -131,7 +133,6 @@ public:
class EditorPlugin : public Node {
GDCLASS(EditorPlugin, Node);
friend class EditorData;
- Ref<EditorUndoRedoManager> undo_redo;
bool input_event_forwarding_always_enabled = false;
bool force_draw_over_forwarding_enabled = false;
diff --git a/editor/editor_plugin_settings.h b/editor/editor_plugin_settings.h
index 9c619066f2..829135b544 100644
--- a/editor/editor_plugin_settings.h
+++ b/editor/editor_plugin_settings.h
@@ -31,7 +31,6 @@
#ifndef EDITOR_PLUGIN_SETTINGS_H
#define EDITOR_PLUGIN_SETTINGS_H
-#include "core/object/undo_redo.h"
#include "editor/editor_data.h"
#include "editor/plugin_config_dialog.h"
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index 84caed9db5..d76dce0c1d 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -2688,7 +2688,7 @@ void EditorPropertyQuaternion::_custom_value_changed(double val) {
v.y = Math::deg_to_rad(edit_euler.y);
v.z = Math::deg_to_rad(edit_euler.z);
- Quaternion temp_q = Quaternion(v);
+ Quaternion temp_q = Quaternion::from_euler(v);
spin[0]->set_value(temp_q.x);
spin[1]->set_value(temp_q.y);
spin[2]->set_value(temp_q.z);
@@ -2725,7 +2725,7 @@ void EditorPropertyQuaternion::update_property() {
spin[2]->set_value(val.z);
spin[3]->set_value(val.w);
if (!is_grabbing_euler()) {
- Vector3 v = val.normalized().get_euler_yxz();
+ Vector3 v = val.normalized().get_euler();
edit_euler.x = Math::rad_to_deg(v.x);
edit_euler.y = Math::rad_to_deg(v.y);
edit_euler.z = Math::rad_to_deg(v.z);
@@ -4097,7 +4097,6 @@ void EditorPropertyResource::update_property() {
sub_inspector->set_keying(is_keying());
sub_inspector->set_read_only(is_read_only());
sub_inspector->set_use_folding(is_using_folding());
- sub_inspector->set_undo_redo(EditorNode::get_undo_redo());
sub_inspector_vbox = memnew(VBoxContainer);
add_child(sub_inspector_vbox);
diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp
index bec05a0cd6..659221ee0b 100644
--- a/editor/editor_properties_array_dict.cpp
+++ b/editor/editor_properties_array_dict.cpp
@@ -466,7 +466,7 @@ void EditorPropertyArray::drop_data_fw(const Point2 &p_point, const Variant &p_d
Variant array = object->get_array();
- // Handle the case where array is not initialised yet.
+ // Handle the case where array is not initialized yet.
if (!array.is_array()) {
Callable::CallError ce;
Variant::construct(array_type, array, nullptr, 0, ce);
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 409ef95fb0..11b8f224f5 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -159,7 +159,7 @@ bool EditorSettings::_get(const StringName &p_name, Variant &r_ret) const {
if (!sc->has_meta("original")) {
// Getting the meta when it doesn't exist will return an empty array. If the 'shortcut_events' have been cleared,
- // we still want save the shortcut in this case so that shortcuts that the user has customised are not reset,
+ // we still want save the shortcut in this case so that shortcuts that the user has customized are not reset,
// even if the 'original' has not been populated yet. This can happen when calling save() from the Project Manager.
save_array.push_back(dict);
continue;
diff --git a/editor/editor_settings_dialog.cpp b/editor/editor_settings_dialog.cpp
index db501aac03..a72c545b2f 100644
--- a/editor/editor_settings_dialog.cpp
+++ b/editor/editor_settings_dialog.cpp
@@ -132,6 +132,7 @@ void EditorSettingsDialog::_notification(int p_what) {
} break;
case NOTIFICATION_READY: {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->get_or_create_history(EditorUndoRedoManager::GLOBAL_HISTORY).undo_redo->set_method_notify_callback(EditorDebuggerNode::_method_changeds, nullptr);
undo_redo->get_or_create_history(EditorUndoRedoManager::GLOBAL_HISTORY).undo_redo->set_property_notify_callback(EditorDebuggerNode::_property_changeds, nullptr);
undo_redo->get_or_create_history(EditorUndoRedoManager::GLOBAL_HISTORY).undo_redo->set_commit_notify_callback(_undo_redo_callback, this);
@@ -158,9 +159,9 @@ void EditorSettingsDialog::_notification(int p_what) {
void EditorSettingsDialog::shortcut_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
const Ref<InputEventKey> k = p_event;
-
if (k.is_valid() && k->is_pressed()) {
bool handled = false;
@@ -229,6 +230,7 @@ void EditorSettingsDialog::_event_config_confirmed() {
void EditorSettingsDialog::_update_builtin_action(const String &p_name, const Array &p_events) {
Array old_input_array = EditorSettings::get_singleton()->get_builtin_action_overrides(p_name);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Edit Built-in Action") + " '" + p_name + "'");
undo_redo->add_do_method(EditorSettings::get_singleton(), "mark_setting_changed", "builtin_action_overrides");
undo_redo->add_undo_method(EditorSettings::get_singleton(), "mark_setting_changed", "builtin_action_overrides");
@@ -244,6 +246,7 @@ void EditorSettingsDialog::_update_builtin_action(const String &p_name, const Ar
void EditorSettingsDialog::_update_shortcut_events(const String &p_path, const Array &p_events) {
Ref<Shortcut> current_sc = EditorSettings::get_singleton()->get_shortcut(p_path);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Edit Shortcut") + " '" + p_path + "'");
undo_redo->add_do_method(current_sc.ptr(), "set_events", p_events);
undo_redo->add_undo_method(current_sc.ptr(), "set_events", current_sc->get_events());
@@ -697,8 +700,6 @@ void EditorSettingsDialog::_bind_methods() {
EditorSettingsDialog::EditorSettingsDialog() {
set_title(TTR("Editor Settings"));
- undo_redo = EditorNode::get_undo_redo();
-
tabs = memnew(TabContainer);
tabs->set_theme_type_variation("TabContainerOdd");
tabs->connect("tab_changed", callable_mp(this, &EditorSettingsDialog::_tabs_tab_changed));
@@ -723,7 +724,6 @@ EditorSettingsDialog::EditorSettingsDialog() {
inspector->get_inspector()->set_use_filter(true);
inspector->register_search_box(search_box);
inspector->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- inspector->get_inspector()->set_undo_redo(undo_redo);
tab_general->add_child(inspector);
inspector->get_inspector()->connect("property_edited", callable_mp(this, &EditorSettingsDialog::_settings_property_edited));
inspector->get_inspector()->connect("restart_requested", callable_mp(this, &EditorSettingsDialog::_editor_restart_request));
diff --git a/editor/editor_settings_dialog.h b/editor/editor_settings_dialog.h
index 05424a64ed..a330de1e2c 100644
--- a/editor/editor_settings_dialog.h
+++ b/editor/editor_settings_dialog.h
@@ -40,8 +40,6 @@
#include "scene/gui/tab_container.h"
#include "scene/gui/texture_rect.h"
-class EditorUndoRedoManager;
-
class EditorSettingsDialog : public AcceptDialog {
GDCLASS(EditorSettingsDialog, AcceptDialog);
@@ -75,8 +73,6 @@ class EditorSettingsDialog : public AcceptDialog {
Timer *timer = nullptr;
- Ref<EditorUndoRedoManager> undo_redo;
-
virtual void cancel_pressed() override;
virtual void ok_pressed() override;
diff --git a/editor/editor_undo_redo_manager.cpp b/editor/editor_undo_redo_manager.cpp
index 064448fd96..09b567fc68 100644
--- a/editor/editor_undo_redo_manager.cpp
+++ b/editor/editor_undo_redo_manager.cpp
@@ -241,6 +241,7 @@ void EditorUndoRedoManager::commit_action(bool p_execute) {
history.undo_stack.push_back(pending_action);
pending_action = Action();
is_committing = false;
+ emit_signal(SNAME("history_changed"));
}
bool EditorUndoRedoManager::is_committing_action() const {
@@ -252,14 +253,14 @@ bool EditorUndoRedoManager::undo() {
return false;
}
- History *selected_history = nullptr;
+ int selected_history = INVALID_HISTORY;
double global_timestamp = 0;
// Pick the history with greatest last action timestamp (either global or current scene).
{
History &history = get_or_create_history(GLOBAL_HISTORY);
if (!history.undo_stack.is_empty()) {
- selected_history = &history;
+ selected_history = history.id;
global_timestamp = history.undo_stack.back()->get().timestamp;
}
}
@@ -267,32 +268,44 @@ bool EditorUndoRedoManager::undo() {
{
History &history = get_or_create_history(EditorNode::get_editor_data().get_current_edited_scene_history_id());
if (!history.undo_stack.is_empty() && history.undo_stack.back()->get().timestamp > global_timestamp) {
- selected_history = &history;
+ selected_history = history.id;
}
}
- if (selected_history) {
- Action action = selected_history->undo_stack.back()->get();
- selected_history->undo_stack.pop_back();
- selected_history->redo_stack.push_back(action);
- return selected_history->undo_redo->undo();
+ if (selected_history != INVALID_HISTORY) {
+ return undo_history(selected_history);
}
return false;
}
+bool EditorUndoRedoManager::undo_history(int p_id) {
+ ERR_FAIL_COND_V(p_id == INVALID_HISTORY, false);
+ History &history = get_or_create_history(p_id);
+
+ Action action = history.undo_stack.back()->get();
+ history.undo_stack.pop_back();
+ history.redo_stack.push_back(action);
+
+ bool success = history.undo_redo->undo();
+ if (success) {
+ emit_signal(SNAME("version_changed"));
+ }
+ return success;
+}
+
bool EditorUndoRedoManager::redo() {
if (!has_redo()) {
return false;
}
- History *selected_history = nullptr;
+ int selected_history = INVALID_HISTORY;
double global_timestamp = INFINITY;
// Pick the history with lowest last action timestamp (either global or current scene).
{
History &history = get_or_create_history(GLOBAL_HISTORY);
if (!history.redo_stack.is_empty()) {
- selected_history = &history;
+ selected_history = history.id;
global_timestamp = history.redo_stack.back()->get().timestamp;
}
}
@@ -300,19 +313,31 @@ bool EditorUndoRedoManager::redo() {
{
History &history = get_or_create_history(EditorNode::get_editor_data().get_current_edited_scene_history_id());
if (!history.redo_stack.is_empty() && history.redo_stack.back()->get().timestamp < global_timestamp) {
- selected_history = &history;
+ selected_history = history.id;
}
}
- if (selected_history) {
- Action action = selected_history->redo_stack.back()->get();
- selected_history->redo_stack.pop_back();
- selected_history->undo_stack.push_back(action);
- return selected_history->undo_redo->redo();
+ if (selected_history != INVALID_HISTORY) {
+ return redo_history(selected_history);
}
return false;
}
+bool EditorUndoRedoManager::redo_history(int p_id) {
+ ERR_FAIL_COND_V(p_id == INVALID_HISTORY, false);
+ History &history = get_or_create_history(p_id);
+
+ Action action = history.redo_stack.back()->get();
+ history.redo_stack.pop_back();
+ history.undo_stack.push_back(action);
+
+ bool success = history.undo_redo->redo();
+ if (success) {
+ emit_signal(SNAME("version_changed"));
+ }
+ return success;
+}
+
void EditorUndoRedoManager::set_history_as_saved(int p_id) {
History &history = get_or_create_history(p_id);
history.saved_version = history.undo_redo->get_version();
@@ -352,6 +377,7 @@ void EditorUndoRedoManager::clear_history(bool p_increase_version, int p_idx) {
if (!p_increase_version) {
set_history_as_saved(p_idx);
}
+ emit_signal(SNAME("history_changed"));
return;
}
@@ -359,6 +385,7 @@ void EditorUndoRedoManager::clear_history(bool p_increase_version, int p_idx) {
E.value.undo_redo->clear_history(p_increase_version);
set_history_as_saved(E.key);
}
+ emit_signal(SNAME("history_changed"));
}
String EditorUndoRedoManager::get_current_action_name() {
@@ -434,6 +461,9 @@ void EditorUndoRedoManager::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_object_history_id", "object"), &EditorUndoRedoManager::get_history_id_for_object);
ClassDB::bind_method(D_METHOD("get_history_undo_redo", "id"), &EditorUndoRedoManager::get_history_undo_redo);
+ ADD_SIGNAL(MethodInfo("history_changed"));
+ ADD_SIGNAL(MethodInfo("version_changed"));
+
BIND_ENUM_CONSTANT(GLOBAL_HISTORY);
BIND_ENUM_CONSTANT(INVALID_HISTORY);
}
diff --git a/editor/editor_undo_redo_manager.h b/editor/editor_undo_redo_manager.h
index c4d85daa22..60bcd059df 100644
--- a/editor/editor_undo_redo_manager.h
+++ b/editor/editor_undo_redo_manager.h
@@ -44,7 +44,6 @@ public:
INVALID_HISTORY = -99,
};
-private:
struct Action {
int history_id = INVALID_HISTORY;
double timestamp = 0;
@@ -60,6 +59,7 @@ private:
List<Action> redo_stack;
};
+private:
HashMap<int, History> history_map;
Action pending_action;
@@ -114,7 +114,9 @@ public:
bool is_committing_action() const;
bool undo();
+ bool undo_history(int p_id);
bool redo();
+ bool redo_history(int p_id);
void clear_history(bool p_increase_version = true, int p_idx = INVALID_HISTORY);
void set_history_as_saved(int p_idx);
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index 608e7ce3cb..62bcf0b193 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -1283,42 +1283,71 @@ void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const Strin
}
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
- print_verbose("Duplicating " + old_path + " -> " + new_path);
- Error err = p_item.is_file ? da->copy(old_path, new_path) : da->copy_dir(old_path, new_path);
- if (err == OK) {
- // Move/Rename any corresponding import settings too.
- if (p_item.is_file && FileAccess::exists(old_path + ".import")) {
- err = da->copy(old_path + ".import", new_path + ".import");
+
+ if (p_item.is_file) {
+ print_verbose("Duplicating " + old_path + " -> " + new_path);
+
+ // Create the directory structure.
+ da->make_dir_recursive(new_path.get_base_dir());
+
+ if (FileAccess::exists(old_path + ".import")) {
+ Error err = da->copy(old_path, new_path);
if (err != OK) {
- EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + "\n" + old_path + ".import\n");
+ EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + "\n" + old_path + ": " + error_names[err] + "\n");
+ return;
}
// Remove uid from .import file to avoid conflict.
Ref<ConfigFile> cfg;
cfg.instantiate();
- cfg->load(new_path + ".import");
+ cfg->load(old_path + ".import");
cfg->erase_section_key("remap", "uid");
- cfg->save(new_path + ".import");
- } else if (p_item.is_file && (old_path.get_extension() == "tscn" || old_path.get_extension() == "tres")) {
- // FIXME: Quick hack to fix text resources. This should be fixed properly.
- Ref<FileAccess> file = FileAccess::open(old_path, FileAccess::READ, &err);
- if (err == OK) {
- PackedStringArray lines = file->get_as_utf8_string().split("\n");
- String line = lines[0];
-
- if (line.contains("uid")) {
- line = line.substr(0, line.find(" uid")) + "]";
- lines.write[0] = line;
+ err = cfg->save(new_path + ".import");
+ if (err != OK) {
+ EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + "\n" + old_path + ".import: " + error_names[err] + "\n");
+ return;
+ }
+ } else {
+ // Files which do not use an uid can just be copied.
+ if (ResourceLoader::get_resource_uid(old_path) == ResourceUID::INVALID_ID) {
+ Error err = da->copy(old_path, new_path);
+ if (err != OK) {
+ EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + "\n" + old_path + ": " + error_names[err] + "\n");
+ }
+ return;
+ }
- Ref<FileAccess> file2 = FileAccess::open(new_path, FileAccess::WRITE, &err);
- if (err == OK) {
- file2->store_string(String("\n").join(lines));
- }
+ // Load the resource and save it again in the new location (this generates a new UID).
+ Error err;
+ Ref<Resource> res = ResourceLoader::load(old_path, "", ResourceFormatLoader::CACHE_MODE_REUSE, &err);
+ if (err == OK && res.is_valid()) {
+ err = ResourceSaver::save(res, new_path, ResourceSaver::FLAG_COMPRESS);
+ if (err != OK) {
+ EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + " " + vformat(TTR("Failed to save resource at %s: %s"), new_path, error_names[err]));
}
+ } else if (err != OK) {
+ // When loading files like text files the error is OK but the resource is still null.
+ // We can ignore such files.
+ EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + " " + vformat(TTR("Failed to load resource at %s: %s"), new_path, error_names[err]));
}
}
} else {
- EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + "\n" + old_path + "\n");
+ // Recursively duplicate all files inside the folder.
+ Ref<DirAccess> old_dir = DirAccess::open(old_path);
+ Ref<FileAccess> file_access = FileAccess::create(FileAccess::ACCESS_RESOURCES);
+ old_dir->set_include_navigational(false);
+ old_dir->list_dir_begin();
+ for (String f = old_dir->_get_next(); !f.is_empty(); f = old_dir->_get_next()) {
+ if (f.get_extension() == "import") {
+ continue;
+ }
+ if (file_access->file_exists(old_path + f)) {
+ _try_duplicate_item(FileOrFolder(old_path + f, true), new_path + f);
+ } else if (da->dir_exists(old_path + f)) {
+ _try_duplicate_item(FileOrFolder(old_path + f, false), new_path + f);
+ }
+ }
+ old_dir->list_dir_end();
}
}
diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp
index f11e328087..ab96caa88c 100644
--- a/editor/groups_editor.cpp
+++ b/editor/groups_editor.cpp
@@ -130,6 +130,7 @@ void GroupDialog::_add_pressed() {
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add to Group"));
while (selected) {
@@ -159,6 +160,7 @@ void GroupDialog::_removed_pressed() {
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Remove from Group"));
while (selected) {
@@ -246,6 +248,7 @@ void GroupDialog::_group_renamed() {
renamed_group->set_text(0, name); // Spaces trimmed.
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Rename Group"));
List<Node *> nodes;
@@ -322,6 +325,7 @@ void GroupDialog::_modify_group_pressed(Object *p_item, int p_column, int p_id,
case DELETE_GROUP: {
String name = ti->get_text(0);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Delete Group"));
List<Node *> nodes;
@@ -402,10 +406,6 @@ void GroupDialog::_notification(int p_what) {
}
}
-void GroupDialog::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) {
- undo_redo = p_undo_redo;
-}
-
void GroupDialog::edit() {
popup_centered();
@@ -597,6 +597,7 @@ void GroupsEditor::_add_group(const String &p_group) {
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add to Group"));
undo_redo->add_do_method(node, "add_to_group", name, true);
@@ -651,6 +652,7 @@ void GroupsEditor::_group_renamed() {
ti->set_text(0, name); // Spaces trimmed.
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Rename Group"));
undo_redo->add_do_method(node, "remove_from_group", selected_group);
@@ -686,6 +688,7 @@ void GroupsEditor::_modify_group(Object *p_item, int p_column, int p_id, MouseBu
switch (p_id) {
case DELETE_GROUP: {
const String name = ti->get_text(0);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Remove from Group"));
undo_redo->add_do_method(node, "remove_from_group", name);
@@ -764,10 +767,6 @@ void GroupsEditor::update_tree() {
}
}
-void GroupsEditor::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) {
- undo_redo = p_undo_redo;
-}
-
void GroupsEditor::set_current(Node *p_node) {
node = p_node;
update_tree();
@@ -775,7 +774,6 @@ void GroupsEditor::set_current(Node *p_node) {
void GroupsEditor::_show_group_dialog() {
group_dialog->edit();
- group_dialog->set_undo_redo(undo_redo);
}
void GroupsEditor::_bind_methods() {
diff --git a/editor/groups_editor.h b/editor/groups_editor.h
index 5d012a3501..3900e0e28c 100644
--- a/editor/groups_editor.h
+++ b/editor/groups_editor.h
@@ -39,8 +39,6 @@
#include "scene/gui/popup.h"
#include "scene/gui/tree.h"
-class EditorUndoRedoManager;
-
class GroupDialog : public AcceptDialog {
GDCLASS(GroupDialog, AcceptDialog);
@@ -69,8 +67,6 @@ class GroupDialog : public AcceptDialog {
String selected_group;
- Ref<EditorUndoRedoManager> undo_redo;
-
void _group_selected();
void _remove_filter_changed(const String &p_filter);
@@ -102,7 +98,6 @@ public:
};
void edit();
- void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo);
GroupDialog();
};
@@ -120,8 +115,6 @@ class GroupsEditor : public VBoxContainer {
Button *add = nullptr;
Tree *tree = nullptr;
- Ref<EditorUndoRedoManager> undo_redo;
-
String selected_group;
void update_tree();
@@ -143,7 +136,6 @@ public:
COPY_GROUP,
};
- void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo);
void set_current(Node *p_node);
GroupsEditor();
diff --git a/editor/history_dock.cpp b/editor/history_dock.cpp
new file mode 100644
index 0000000000..57088a76cb
--- /dev/null
+++ b/editor/history_dock.cpp
@@ -0,0 +1,251 @@
+/*************************************************************************/
+/* history_dock.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "history_dock.h"
+
+#include "editor/editor_node.h"
+#include "editor/editor_undo_redo_manager.h"
+#include "scene/gui/check_box.h"
+#include "scene/gui/item_list.h"
+
+struct SortActionsByTimestamp {
+ bool operator()(const EditorUndoRedoManager::Action &l, const EditorUndoRedoManager::Action &r) const {
+ return l.timestamp > r.timestamp;
+ }
+};
+
+void HistoryDock::on_history_changed() {
+ if (is_visible_in_tree()) {
+ refresh_history();
+ } else {
+ need_refresh = true;
+ }
+}
+
+void HistoryDock::refresh_history() {
+ action_list->clear();
+ bool include_scene = current_scene_checkbox->is_pressed();
+ bool include_global = global_history_checkbox->is_pressed();
+
+ if (!include_scene && !include_global) {
+ action_list->add_item(TTR("The Beginning"));
+ return;
+ }
+
+ const EditorUndoRedoManager::History &current_scene_history = ur_manager->get_or_create_history(EditorNode::get_editor_data().get_current_edited_scene_history_id());
+ const EditorUndoRedoManager::History &global_history = ur_manager->get_or_create_history(EditorUndoRedoManager::GLOBAL_HISTORY);
+
+ Vector<EditorUndoRedoManager::Action> full_history;
+ {
+ int full_size = 0;
+ if (include_scene) {
+ full_size += current_scene_history.redo_stack.size() + current_scene_history.undo_stack.size();
+ }
+ if (include_global) {
+ full_size += global_history.redo_stack.size() + global_history.undo_stack.size();
+ }
+ full_history.resize(full_size);
+ }
+
+ int i = 0;
+ if (include_scene) {
+ for (const EditorUndoRedoManager::Action &E : current_scene_history.redo_stack) {
+ full_history.write[i] = E;
+ i++;
+ }
+ for (const EditorUndoRedoManager::Action &E : current_scene_history.undo_stack) {
+ full_history.write[i] = E;
+ i++;
+ }
+ }
+ if (include_global) {
+ for (const EditorUndoRedoManager::Action &E : global_history.redo_stack) {
+ full_history.write[i] = E;
+ i++;
+ }
+ for (const EditorUndoRedoManager::Action &E : global_history.undo_stack) {
+ full_history.write[i] = E;
+ i++;
+ }
+ }
+
+ full_history.sort_custom<SortActionsByTimestamp>();
+ for (const EditorUndoRedoManager::Action &E : full_history) {
+ action_list->add_item(E.action_name);
+ if (E.history_id == EditorUndoRedoManager::GLOBAL_HISTORY) {
+ action_list->set_item_custom_fg_color(-1, get_theme_color(SNAME("accent_color"), SNAME("Editor")));
+ }
+ }
+
+ action_list->add_item(TTR("The Beginning"));
+ refresh_version();
+}
+
+void HistoryDock::on_version_changed() {
+ if (is_visible_in_tree()) {
+ refresh_version();
+ } else {
+ need_refresh = true;
+ }
+}
+
+void HistoryDock::refresh_version() {
+ int idx = 0;
+ bool include_scene = current_scene_checkbox->is_pressed();
+ bool include_global = global_history_checkbox->is_pressed();
+
+ if (!include_scene && !include_global) {
+ current_version = idx;
+ action_list->set_current(idx);
+ return;
+ }
+
+ const EditorUndoRedoManager::History &current_scene_history = ur_manager->get_or_create_history(EditorNode::get_editor_data().get_current_edited_scene_history_id());
+ const EditorUndoRedoManager::History &global_history = ur_manager->get_or_create_history(EditorUndoRedoManager::GLOBAL_HISTORY);
+ double newest_undo_timestamp = 0;
+
+ if (include_scene && !current_scene_history.undo_stack.is_empty()) {
+ newest_undo_timestamp = current_scene_history.undo_stack.front()->get().timestamp;
+ }
+
+ if (include_global && !global_history.undo_stack.is_empty()) {
+ double global_undo_timestamp = global_history.undo_stack.front()->get().timestamp;
+ if (global_undo_timestamp > newest_undo_timestamp) {
+ newest_undo_timestamp = global_undo_timestamp;
+ }
+ }
+
+ if (include_scene) {
+ int skip = 0;
+ for (const EditorUndoRedoManager::Action &E : current_scene_history.redo_stack) {
+ if (E.timestamp < newest_undo_timestamp) {
+ skip++;
+ } else {
+ break;
+ }
+ }
+ idx += current_scene_history.redo_stack.size() - skip;
+ }
+
+ if (include_global) {
+ int skip = 0;
+ for (const EditorUndoRedoManager::Action &E : global_history.redo_stack) {
+ if (E.timestamp < newest_undo_timestamp) {
+ skip++;
+ } else {
+ break;
+ }
+ }
+ idx += global_history.redo_stack.size() - skip;
+ }
+
+ current_version = idx;
+ action_list->set_current(idx);
+}
+
+void HistoryDock::seek_history(int p_index) {
+ bool include_scene = current_scene_checkbox->is_pressed();
+ bool include_global = global_history_checkbox->is_pressed();
+
+ if (!include_scene && !include_global) {
+ return;
+ }
+ int current_scene_id = EditorNode::get_editor_data().get_current_edited_scene_history_id();
+
+ while (current_version < p_index) {
+ if (include_scene) {
+ if (include_global) {
+ ur_manager->undo();
+ } else {
+ ur_manager->undo_history(current_scene_id);
+ }
+ } else {
+ ur_manager->undo_history(EditorUndoRedoManager::GLOBAL_HISTORY);
+ }
+ }
+
+ while (current_version > p_index) {
+ if (include_scene) {
+ if (include_global) {
+ ur_manager->redo();
+ } else {
+ ur_manager->redo_history(current_scene_id);
+ }
+ } else {
+ ur_manager->redo_history(EditorUndoRedoManager::GLOBAL_HISTORY);
+ }
+ }
+}
+
+void HistoryDock::_notification(int p_notification) {
+ switch (p_notification) {
+ case NOTIFICATION_ENTER_TREE: {
+ EditorNode::get_singleton()->connect("scene_changed", callable_mp(this, &HistoryDock::on_history_changed));
+ } break;
+
+ case NOTIFICATION_VISIBILITY_CHANGED: {
+ if (is_visible_in_tree() && need_refresh) {
+ refresh_history();
+ }
+ } break;
+ }
+}
+
+HistoryDock::HistoryDock() {
+ ur_manager = EditorNode::get_undo_redo();
+ ur_manager->connect("history_changed", callable_mp(this, &HistoryDock::on_history_changed));
+ ur_manager->connect("version_changed", callable_mp(this, &HistoryDock::on_version_changed));
+
+ HBoxContainer *mode_hb = memnew(HBoxContainer);
+ add_child(mode_hb);
+
+ current_scene_checkbox = memnew(CheckBox);
+ mode_hb->add_child(current_scene_checkbox);
+ current_scene_checkbox->set_flat(true);
+ current_scene_checkbox->set_pressed(true);
+ current_scene_checkbox->set_text(TTR("Scene"));
+ current_scene_checkbox->set_h_size_flags(SIZE_EXPAND_FILL);
+ current_scene_checkbox->set_clip_text(true);
+ current_scene_checkbox->connect("toggled", callable_mp(this, &HistoryDock::refresh_history).unbind(1));
+
+ global_history_checkbox = memnew(CheckBox);
+ mode_hb->add_child(global_history_checkbox);
+ global_history_checkbox->set_flat(true);
+ global_history_checkbox->set_pressed(true);
+ global_history_checkbox->set_text(TTR("Global"));
+ global_history_checkbox->set_h_size_flags(SIZE_EXPAND_FILL);
+ global_history_checkbox->set_clip_text(true);
+ global_history_checkbox->connect("toggled", callable_mp(this, &HistoryDock::refresh_history).unbind(1));
+
+ action_list = memnew(ItemList);
+ add_child(action_list);
+ action_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ action_list->connect("item_selected", callable_mp(this, &HistoryDock::seek_history));
+}
diff --git a/editor/history_dock.h b/editor/history_dock.h
new file mode 100644
index 0000000000..9dda8165e6
--- /dev/null
+++ b/editor/history_dock.h
@@ -0,0 +1,66 @@
+/*************************************************************************/
+/* history_dock.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef HISTORY_DOCK_H
+#define HISTORY_DOCK_H
+
+#include "scene/gui/box_container.h"
+
+class CheckBox;
+class ItemList;
+class EditorUndoRedoManager;
+
+class HistoryDock : public VBoxContainer {
+ GDCLASS(HistoryDock, VBoxContainer);
+
+ Ref<EditorUndoRedoManager> ur_manager;
+ ItemList *action_list = nullptr;
+
+ CheckBox *current_scene_checkbox = nullptr;
+ CheckBox *global_history_checkbox = nullptr;
+
+ bool need_refresh = true;
+ int current_version = 0;
+
+ void on_history_changed();
+ void refresh_history();
+ void on_version_changed();
+ void refresh_version();
+
+protected:
+ void _notification(int p_notification);
+
+public:
+ void seek_history(int p_index);
+
+ HistoryDock();
+};
+
+#endif // HISTORY_DOCK_H
diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp
index ab15aa4fdc..9adabfb5d1 100644
--- a/editor/import/resource_importer_layered_texture.cpp
+++ b/editor/import/resource_importer_layered_texture.cpp
@@ -368,7 +368,7 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const
for (int j = 0; j < hslices; j++) {
int x = slice_w * j;
int y = slice_h * i;
- Ref<Image> slice = image->get_rect(Rect2i(x, y, slice_w, slice_h));
+ Ref<Image> slice = image->get_region(Rect2i(x, y, slice_w, slice_h));
ERR_CONTINUE(slice.is_null() || slice->is_empty());
if (slice->get_width() != slice_w || slice->get_height() != slice_h) {
slice->resize(slice_w, slice_h);
diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp
index 27b261f320..bd2eb5fd9e 100644
--- a/editor/inspector_dock.cpp
+++ b/editor/inspector_dock.cpp
@@ -34,6 +34,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/script_editor_plugin.h"
InspectorDock *InspectorDock::singleton = nullptr;
@@ -769,7 +770,6 @@ InspectorDock::InspectorDock(EditorData &p_editor_data) {
inspector->set_property_name_style(EditorPropertyNameProcessor::get_default_inspector_style());
inspector->set_use_folding(!bool(EDITOR_GET("interface/inspector/disable_folding")));
inspector->register_text_enter(search);
- inspector->set_undo_redo(editor_data->get_undo_redo());
inspector->set_use_filter(true); // TODO: check me
diff --git a/editor/localization_editor.cpp b/editor/localization_editor.cpp
index 7727ff31e4..4b8257969c 100644
--- a/editor/localization_editor.cpp
+++ b/editor/localization_editor.cpp
@@ -81,6 +81,7 @@ void LocalizationEditor::_translation_add(const PackedStringArray &p_paths) {
}
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(vformat(TTR("Add %d Translations"), p_paths.size()));
undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translations", translations);
undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translations", GLOBAL_GET("internationalization/locale/translations"));
@@ -111,6 +112,7 @@ void LocalizationEditor::_translation_delete(Object *p_item, int p_column, int p
translations.remove_at(idx);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Remove Translation"));
undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translations", translations);
undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translations", GLOBAL_GET("internationalization/locale/translations"));
@@ -141,6 +143,7 @@ void LocalizationEditor::_translation_res_add(const PackedStringArray &p_paths)
}
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(vformat(TTR("Translation Resource Remap: Add %d Path(s)"), p_paths.size()));
undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", remaps);
undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", prev);
@@ -172,6 +175,7 @@ void LocalizationEditor::_translation_res_option_add(const PackedStringArray &p_
}
remaps[key] = r;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(vformat(TTR("Translation Resource Remap: Add %d Remap(s)"), p_paths.size()));
undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", remaps);
undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", GLOBAL_GET("internationalization/locale/translation_remaps"));
@@ -234,6 +238,8 @@ void LocalizationEditor::_translation_res_option_changed() {
remaps[key] = r;
updating_translations = true;
+
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Change Resource Remap Language"));
undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", remaps);
undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", GLOBAL_GET("internationalization/locale/translation_remaps"));
@@ -267,6 +273,7 @@ void LocalizationEditor::_translation_res_delete(Object *p_item, int p_column, i
remaps.erase(key);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Remove Resource Remap"));
undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", remaps);
undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", GLOBAL_GET("internationalization/locale/translation_remaps"));
@@ -306,6 +313,7 @@ void LocalizationEditor::_translation_res_option_delete(Object *p_item, int p_co
r.remove_at(idx);
remaps[key] = r;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Remove Resource Remap Option"));
undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", remaps);
undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translation_remaps", GLOBAL_GET("internationalization/locale/translation_remaps"));
@@ -324,6 +332,7 @@ void LocalizationEditor::_pot_add(const PackedStringArray &p_paths) {
}
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(vformat(TTR("Add %d file(s) for POT generation"), p_paths.size()));
undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translations_pot_files", pot_translations);
undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translations_pot_files", GLOBAL_GET("internationalization/locale/translations_pot_files"));
@@ -350,6 +359,7 @@ void LocalizationEditor::_pot_delete(Object *p_item, int p_column, int p_button,
pot_translations.remove_at(idx);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Remove file from POT generation"));
undo_redo->add_do_property(ProjectSettings::get_singleton(), "internationalization/locale/translations_pot_files", pot_translations);
undo_redo->add_undo_property(ProjectSettings::get_singleton(), "internationalization/locale/translations_pot_files", GLOBAL_GET("internationalization/locale/translations_pot_files"));
@@ -592,7 +602,6 @@ void LocalizationEditor::_bind_methods() {
}
LocalizationEditor::LocalizationEditor() {
- undo_redo = EditorNode::get_undo_redo();
localization_changed = "localization_changed";
TabContainer *translations = memnew(TabContainer);
diff --git a/editor/localization_editor.h b/editor/localization_editor.h
index ecac171fe3..5fa6d9519a 100644
--- a/editor/localization_editor.h
+++ b/editor/localization_editor.h
@@ -31,7 +31,6 @@
#ifndef LOCALIZATION_EDITOR_H
#define LOCALIZATION_EDITOR_H
-#include "core/object/undo_redo.h"
#include "editor/editor_locale_dialog.h"
#include "scene/gui/tree.h"
@@ -56,7 +55,6 @@ class LocalizationEditor : public VBoxContainer {
EditorFileDialog *pot_file_open_dialog = nullptr;
EditorFileDialog *pot_generate_dialog = nullptr;
- Ref<EditorUndoRedoManager> undo_redo;
bool updating_translations = false;
String localization_changed;
diff --git a/editor/node_dock.cpp b/editor/node_dock.cpp
index 55fa2f22dd..266b265819 100644
--- a/editor/node_dock.cpp
+++ b/editor/node_dock.cpp
@@ -117,13 +117,11 @@ NodeDock::NodeDock() {
groups_button->connect("pressed", callable_mp(this, &NodeDock::show_groups));
connections = memnew(ConnectionsDock);
- connections->set_undo_redo(EditorNode::get_undo_redo());
add_child(connections);
connections->set_v_size_flags(SIZE_EXPAND_FILL);
connections->hide();
groups = memnew(GroupsEditor);
- groups->set_undo_redo(EditorNode::get_undo_redo());
add_child(groups);
groups->set_v_size_flags(SIZE_EXPAND_FILL);
groups->hide();
diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp
index cb07d8cf01..ecb4837695 100644
--- a/editor/plugins/abstract_polygon_2d_editor.cpp
+++ b/editor/plugins/abstract_polygon_2d_editor.cpp
@@ -91,6 +91,7 @@ void AbstractPolygon2DEditor::_set_polygon(int p_idx, const Variant &p_polygon)
void AbstractPolygon2DEditor::_action_set_polygon(int p_idx, const Variant &p_previous, const Variant &p_polygon) {
Node2D *node = _get_node();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->add_do_method(node, "set_polygon", p_polygon);
undo_redo->add_undo_method(node, "set_polygon", p_previous);
}
@@ -100,6 +101,7 @@ Vector2 AbstractPolygon2DEditor::_get_offset(int p_idx) const {
}
void AbstractPolygon2DEditor::_commit_action() {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->add_do_method(canvas_item_editor, "update_viewport");
undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
undo_redo->commit_action();
@@ -203,6 +205,7 @@ void AbstractPolygon2DEditor::_wip_close() {
if (_is_line()) {
_set_polygon(0, wip);
} else if (wip.size() >= (_is_line() ? 2 : 3)) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Create Polygon"));
_action_add_polygon(wip);
if (_has_uv()) {
@@ -254,6 +257,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
return false;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
Ref<InputEventMouseButton> mb = p_event;
if (!_has_resource()) {
@@ -611,6 +615,7 @@ void AbstractPolygon2DEditor::_bind_methods() {
}
void AbstractPolygon2DEditor::remove_point(const Vertex &p_vertex) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
Vector<Vector2> vertices = _get_polygon(p_vertex.polygon);
if (vertices.size() > (_is_line() ? 2 : 3)) {
@@ -706,8 +711,6 @@ AbstractPolygon2DEditor::PosVertex AbstractPolygon2DEditor::closest_edge_point(c
}
AbstractPolygon2DEditor::AbstractPolygon2DEditor(bool p_wip_destructive) {
- undo_redo = EditorNode::get_undo_redo();
-
edited_point = PosVertex();
wip_destructive = p_wip_destructive;
diff --git a/editor/plugins/abstract_polygon_2d_editor.h b/editor/plugins/abstract_polygon_2d_editor.h
index 1fbbe67c8d..8a3db9d837 100644
--- a/editor/plugins/abstract_polygon_2d_editor.h
+++ b/editor/plugins/abstract_polygon_2d_editor.h
@@ -36,7 +36,6 @@
#include "scene/gui/box_container.h"
class CanvasItemEditor;
-class EditorUndoRedoManager;
class AbstractPolygon2DEditor : public HBoxContainer {
GDCLASS(AbstractPolygon2DEditor, HBoxContainer);
@@ -100,8 +99,6 @@ protected:
int mode = MODE_EDIT;
- Ref<EditorUndoRedoManager> undo_redo;
-
virtual void _menu_option(int p_option);
void _wip_changed();
void _wip_close();
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp
index e45081fd67..6d00e77a4b 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.cpp
+++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp
@@ -153,7 +153,8 @@ void AnimationNodeBlendTreeEditor::update_graph() {
node->add_child(name);
node->set_slot(0, false, 0, Color(), true, read_only ? -1 : 0, get_theme_color(SNAME("font_color"), SNAME("Label")));
name->connect("text_submitted", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_renamed).bind(agnode), CONNECT_DEFERRED);
- name->connect("focus_exited", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_renamed_focus_out).bind(name, agnode), CONNECT_DEFERRED);
+ name->connect("focus_exited", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_renamed_focus_out).bind(agnode), CONNECT_DEFERRED);
+ name->connect("text_changed", callable_mp(this, &AnimationNodeBlendTreeEditor::_node_rename_lineedit_changed), CONNECT_DEFERRED);
base = 1;
node->set_show_close_button(true);
node->connect("close_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_delete_request).bind(E), CONNECT_DEFERRED);
@@ -993,13 +994,18 @@ void AnimationNodeBlendTreeEditor::_node_renamed(const String &p_text, Ref<Anima
}
update_graph(); // Needed to update the signal connections with the new name.
+ current_node_rename_text = String();
}
-void AnimationNodeBlendTreeEditor::_node_renamed_focus_out(Node *le, Ref<AnimationNode> p_node) {
- if (le == nullptr) {
+void AnimationNodeBlendTreeEditor::_node_renamed_focus_out(Ref<AnimationNode> p_node) {
+ if (current_node_rename_text.is_empty()) {
return; // The text_submitted signal triggered the graph update and freed the LineEdit.
}
- _node_renamed(le->call("get_text"), p_node);
+ _node_renamed(current_node_rename_text, p_node);
+}
+
+void AnimationNodeBlendTreeEditor::_node_rename_lineedit_changed(const String &p_text) {
+ current_node_rename_text = p_text;
}
bool AnimationNodeBlendTreeEditor::can_edit(const Ref<AnimationNode> &p_node) {
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.h b/editor/plugins/animation_blend_tree_editor_plugin.h
index 46e0d18c69..b55fc3b617 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.h
+++ b/editor/plugins/animation_blend_tree_editor_plugin.h
@@ -92,9 +92,11 @@ class AnimationNodeBlendTreeEditor : public AnimationTreeNodeEditorPlugin {
void _node_dragged(const Vector2 &p_from, const Vector2 &p_to, const StringName &p_which);
void _node_renamed(const String &p_text, Ref<AnimationNode> p_node);
- void _node_renamed_focus_out(Node *le, Ref<AnimationNode> p_node);
+ void _node_renamed_focus_out(Ref<AnimationNode> p_node);
+ void _node_rename_lineedit_changed(const String &p_text);
void _node_changed(const StringName &p_node_name);
+ String current_node_rename_text;
bool updating;
void _connection_request(const String &p_from, int p_from_index, const String &p_to, int p_to_index);
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index b4737976d8..1ebe81c4b0 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -39,6 +39,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/canvas_item_editor_plugin.h" // For onion skinning.
#include "editor/plugins/node_3d_editor_plugin.h" // For onion skinning.
#include "editor/scene_tree_dock.h"
@@ -167,6 +168,7 @@ void AnimationPlayerEditor::_autoplay_pressed() {
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
String current = animation->get_item_text(animation->get_selected());
if (player->get_autoplay() == current) {
//unset
@@ -383,6 +385,7 @@ void AnimationPlayerEditor::_animation_remove_confirmed() {
if (current.contains("/")) {
current = current.get_slice("/", 1);
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Remove Animation"));
if (player->get_autoplay() == current) {
undo_redo->add_do_method(player, "set_autoplay", "");
@@ -458,6 +461,7 @@ void AnimationPlayerEditor::_animation_name_edited() {
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
switch (name_dialog_op) {
case TOOL_RENAME_ANIM: {
String current = animation->get_item_text(animation->get_selected());
@@ -592,6 +596,7 @@ void AnimationPlayerEditor::_blend_editor_next_changed(const int p_idx) {
String current = animation->get_item_text(animation->get_selected());
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Blend Next Changed"));
undo_redo->add_do_method(player, "animation_set_next", current, blend_editor.next->get_item_text(p_idx));
undo_redo->add_undo_method(player, "animation_set_next", current, player->animation_get_next(current));
@@ -678,6 +683,7 @@ void AnimationPlayerEditor::_blend_edited() {
float blend_time = selected->get_range(1);
float prev_blend_time = player->get_blend_time(current, to);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Change Blend Time"));
undo_redo->add_do_method(player, "set_blend_time", current, to, blend_time);
undo_redo->add_undo_method(player, "set_blend_time", current, to, prev_blend_time);
@@ -984,10 +990,6 @@ void AnimationPlayerEditor::_update_name_dialog_library_dropdown() {
}
}
-void AnimationPlayerEditor::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) {
- undo_redo = p_undo_redo;
-}
-
void AnimationPlayerEditor::edit(AnimationPlayer *p_player) {
if (player && pin->is_pressed()) {
return; // Ignore, pinned.
@@ -1894,7 +1896,6 @@ void AnimationPlayerEditorPlugin::_update_keying() {
}
void AnimationPlayerEditorPlugin::edit(Object *p_object) {
- anim_editor->set_undo_redo(get_undo_redo());
if (!p_object) {
return;
}
@@ -1915,7 +1916,6 @@ void AnimationPlayerEditorPlugin::make_visible(bool p_visible) {
AnimationPlayerEditorPlugin::AnimationPlayerEditorPlugin() {
anim_editor = memnew(AnimationPlayerEditor(this));
- anim_editor->set_undo_redo(EditorNode::get_undo_redo());
EditorNode::get_singleton()->add_bottom_panel_item(TTR("Animation"), anim_editor);
}
diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h
index ae570e53f3..6370b00ea8 100644
--- a/editor/plugins/animation_player_editor_plugin.h
+++ b/editor/plugins/animation_player_editor_plugin.h
@@ -41,7 +41,6 @@
#include "scene/gui/texture_button.h"
#include "scene/gui/tree.h"
-class EditorUndoRedoManager;
class AnimationPlayerEditorPlugin;
class AnimationPlayerEditor : public VBoxContainer {
@@ -101,7 +100,6 @@ class AnimationPlayerEditor : public VBoxContainer {
LineEdit *name = nullptr;
OptionButton *library = nullptr;
Label *name_title = nullptr;
- Ref<EditorUndoRedoManager> undo_redo;
Ref<Texture2D> autoplay_icon;
Ref<Texture2D> reset_icon;
@@ -237,7 +235,6 @@ public:
void ensure_visibility();
- void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo);
void edit(AnimationPlayer *p_player);
void forward_force_draw_over_viewport(Control *p_overlay);
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 291b939fe9..1d6f41d4c4 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -868,6 +868,7 @@ void CanvasItemEditor::_commit_canvas_item_state(List<CanvasItem *> p_canvas_ite
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(action_name);
for (CanvasItem *ci : modified_canvas_items) {
CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(ci);
@@ -934,6 +935,7 @@ void CanvasItemEditor::_add_node_pressed(int p_result) {
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Move Node(s) to Position"));
for (Node *node : nodes_to_move) {
CanvasItem *ci = Object::cast_to<CanvasItem>(node);
@@ -1022,6 +1024,7 @@ void CanvasItemEditor::_on_grid_menu_id_pressed(int p_id) {
}
bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_event) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
Ref<InputEventMouseButton> b = p_event;
Ref<InputEventMouseMotion> m = p_event;
@@ -4000,10 +4003,6 @@ void CanvasItemEditor::_selection_changed() {
selected_from_canvas = false;
}
-void CanvasItemEditor::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) {
- undo_redo = p_undo_redo;
-}
-
void CanvasItemEditor::edit(CanvasItem *p_canvas_item) {
Array selection = editor_selection->get_selected_nodes();
if (selection.size() != 1 || Object::cast_to<Node>(selection[0]) != p_canvas_item) {
@@ -4278,6 +4277,7 @@ void CanvasItemEditor::_update_override_camera_button(bool p_game_running) {
}
void CanvasItemEditor::_popup_callback(int p_op) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
last_option = MenuOption(p_op);
switch (p_op) {
case SHOW_ORIGIN: {
@@ -4983,7 +4983,6 @@ CanvasItemEditor::CanvasItemEditor() {
snap_target[0] = SNAP_TARGET_NONE;
snap_target[1] = SNAP_TARGET_NONE;
- undo_redo = EditorNode::get_singleton()->get_undo_redo();
editor_selection = EditorNode::get_singleton()->get_editor_selection();
editor_selection->add_editor_plugin(this);
editor_selection->connect("selection_changed", callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw));
@@ -5434,7 +5433,6 @@ CanvasItemEditor::CanvasItemEditor() {
CanvasItemEditor *CanvasItemEditor::singleton = nullptr;
void CanvasItemEditorPlugin::edit(Object *p_object) {
- canvas_item_editor->set_undo_redo(EditorNode::get_undo_redo());
canvas_item_editor->edit(Object::cast_to<CanvasItem>(p_object));
}
@@ -5581,37 +5579,38 @@ void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String &
String name = path.get_file().get_basename();
child->set_name(Node::adjust_name_casing(name));
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
Ref<Texture2D> texture = ResourceCache::get_ref(path);
if (parent) {
- editor_data->get_undo_redo()->add_do_method(parent, "add_child", child, true);
- editor_data->get_undo_redo()->add_do_method(child, "set_owner", EditorNode::get_singleton()->get_edited_scene());
- editor_data->get_undo_redo()->add_do_reference(child);
- editor_data->get_undo_redo()->add_undo_method(parent, "remove_child", child);
+ undo_redo->add_do_method(parent, "add_child", child, true);
+ undo_redo->add_do_method(child, "set_owner", EditorNode::get_singleton()->get_edited_scene());
+ undo_redo->add_do_reference(child);
+ undo_redo->add_undo_method(parent, "remove_child", child);
} else { // If no parent is selected, set as root node of the scene.
- editor_data->get_undo_redo()->add_do_method(EditorNode::get_singleton(), "set_edited_scene", child);
- editor_data->get_undo_redo()->add_do_method(child, "set_owner", EditorNode::get_singleton()->get_edited_scene());
- editor_data->get_undo_redo()->add_do_reference(child);
- editor_data->get_undo_redo()->add_undo_method(EditorNode::get_singleton(), "set_edited_scene", (Object *)nullptr);
+ undo_redo->add_do_method(EditorNode::get_singleton(), "set_edited_scene", child);
+ undo_redo->add_do_method(child, "set_owner", EditorNode::get_singleton()->get_edited_scene());
+ undo_redo->add_do_reference(child);
+ undo_redo->add_undo_method(EditorNode::get_singleton(), "set_edited_scene", (Object *)nullptr);
}
if (parent) {
String new_name = parent->validate_child_name(child);
EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton();
- editor_data->get_undo_redo()->add_do_method(ed, "live_debug_create_node", EditorNode::get_singleton()->get_edited_scene()->get_path_to(parent), child->get_class(), new_name);
- editor_data->get_undo_redo()->add_undo_method(ed, "live_debug_remove_node", NodePath(String(EditorNode::get_singleton()->get_edited_scene()->get_path_to(parent)) + "/" + new_name));
+ undo_redo->add_do_method(ed, "live_debug_create_node", EditorNode::get_singleton()->get_edited_scene()->get_path_to(parent), child->get_class(), new_name);
+ undo_redo->add_undo_method(ed, "live_debug_remove_node", NodePath(String(EditorNode::get_singleton()->get_edited_scene()->get_path_to(parent)) + "/" + new_name));
}
if (Object::cast_to<TouchScreenButton>(child) || Object::cast_to<TextureButton>(child)) {
- editor_data->get_undo_redo()->add_do_property(child, "texture_normal", texture);
+ undo_redo->add_do_property(child, "texture_normal", texture);
} else {
- editor_data->get_undo_redo()->add_do_property(child, "texture", texture);
+ undo_redo->add_do_property(child, "texture", texture);
}
// make visible for certain node type
if (Object::cast_to<Control>(child)) {
Size2 texture_size = texture->get_size();
- editor_data->get_undo_redo()->add_do_property(child, "rect_size", texture_size);
+ undo_redo->add_do_property(child, "rect_size", texture_size);
} else if (Object::cast_to<Polygon2D>(child)) {
Size2 texture_size = texture->get_size();
Vector<Vector2> list = {
@@ -5620,7 +5619,7 @@ void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String &
Vector2(texture_size.width, texture_size.height),
Vector2(0, texture_size.height)
};
- editor_data->get_undo_redo()->add_do_property(child, "polygon", list);
+ undo_redo->add_do_property(child, "polygon", list);
}
// Compute the global position
@@ -5629,7 +5628,7 @@ void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String &
// there's nothing to be used as source position so snapping will work as absolute if enabled
target_position = canvas_item_editor->snap_point(target_position);
- editor_data->get_undo_redo()->add_do_method(child, "set_global_position", target_position);
+ undo_redo->add_do_method(child, "set_global_position", target_position);
}
bool CanvasItemEditorViewport::_create_instance(Node *parent, String &path, const Point2 &p_point) {
@@ -5654,15 +5653,16 @@ bool CanvasItemEditorViewport::_create_instance(Node *parent, String &path, cons
instantiated_scene->set_scene_file_path(ProjectSettings::get_singleton()->localize_path(path));
- editor_data->get_undo_redo()->add_do_method(parent, "add_child", instantiated_scene, true);
- editor_data->get_undo_redo()->add_do_method(instantiated_scene, "set_owner", edited_scene);
- editor_data->get_undo_redo()->add_do_reference(instantiated_scene);
- editor_data->get_undo_redo()->add_undo_method(parent, "remove_child", instantiated_scene);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
+ undo_redo->add_do_method(parent, "add_child", instantiated_scene, true);
+ undo_redo->add_do_method(instantiated_scene, "set_owner", edited_scene);
+ undo_redo->add_do_reference(instantiated_scene);
+ undo_redo->add_undo_method(parent, "remove_child", instantiated_scene);
String new_name = parent->validate_child_name(instantiated_scene);
EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton();
- editor_data->get_undo_redo()->add_do_method(ed, "live_debug_instance_node", edited_scene->get_path_to(parent), path, new_name);
- editor_data->get_undo_redo()->add_undo_method(ed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(parent)) + "/" + new_name));
+ undo_redo->add_do_method(ed, "live_debug_instance_node", edited_scene->get_path_to(parent), path, new_name);
+ undo_redo->add_undo_method(ed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(parent)) + "/" + new_name));
CanvasItem *instance_ci = Object::cast_to<CanvasItem>(instantiated_scene);
if (instance_ci) {
@@ -5676,7 +5676,7 @@ bool CanvasItemEditorViewport::_create_instance(Node *parent, String &path, cons
// Preserve instance position of the original scene.
target_pos += instance_ci->_edit_get_position();
- editor_data->get_undo_redo()->add_do_method(instantiated_scene, "set_position", target_pos);
+ undo_redo->add_do_method(instantiated_scene, "set_position", target_pos);
}
return true;
@@ -5694,7 +5694,8 @@ void CanvasItemEditorViewport::_perform_drop_data() {
Vector<String> error_files;
- editor_data->get_undo_redo()->create_action(TTR("Create Node"));
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
+ undo_redo->create_action(TTR("Create Node"));
for (int i = 0; i < selected_files.size(); i++) {
String path = selected_files[i];
@@ -5725,7 +5726,7 @@ void CanvasItemEditorViewport::_perform_drop_data() {
}
}
- editor_data->get_undo_redo()->commit_action();
+ undo_redo->commit_action();
if (error_files.size() > 0) {
String files_str;
@@ -5751,8 +5752,10 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian
ResourceLoader::get_recognized_extensions_for_type("Texture2D", &texture_extensions);
for (int i = 0; i < files.size(); i++) {
+ String extension = files[i].get_extension().to_lower();
+
// Check if dragged files with texture or scene extension can be created at least once.
- if (texture_extensions.find(files[i].get_extension()) || scene_extensions.find(files[i].get_extension())) {
+ if (texture_extensions.find(extension) || scene_extensions.find(extension)) {
Ref<Resource> res = ResourceLoader::load(files[i]);
if (res.is_null()) {
continue;
@@ -5916,7 +5919,6 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(CanvasItemEditor *p_canvas_it
texture_node_types.push_back("NinePatchRect");
target_node = nullptr;
- editor_data = SceneTreeDock::get_singleton()->get_editor_data();
canvas_item_editor = p_canvas_item_editor;
preview_node = memnew(Control);
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index 3ade048e4b..ba193a67b8 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -45,7 +45,6 @@
class EditorData;
class CanvasItemEditorViewport;
class ViewPanner;
-class EditorUndoRedoManager;
class CanvasItemEditorSelectedItem : public Object {
GDCLASS(CanvasItemEditorSelectedItem, Object);
@@ -401,8 +400,6 @@ private:
void _prepare_grid_menu();
void _on_grid_menu_id_pressed(int p_id);
- Ref<EditorUndoRedoManager> undo_redo;
-
List<CanvasItem *> _get_edited_canvas_items(bool retrieve_locked = false, bool remove_canvas_item_if_parent_in_selection = true);
Rect2 _get_encompassing_rect_from_list(List<CanvasItem *> p_list);
void _expand_encompassing_rect_using_children(Rect2 &r_rect, const Node *p_node, bool &r_first, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D(), bool include_locked_nodes = true);
@@ -548,7 +545,6 @@ public:
Tool get_current_tool() { return tool; }
void set_current_tool(Tool p_tool);
- void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo);
void edit(CanvasItem *p_canvas_item);
void focus_selection();
@@ -593,7 +589,6 @@ class CanvasItemEditorViewport : public Control {
Node *target_node = nullptr;
Point2 drop_pos;
- EditorData *editor_data = nullptr;
CanvasItemEditor *canvas_item_editor = nullptr;
Control *preview_node = nullptr;
AcceptDialog *accept = nullptr;
diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp
index 4aee9b879e..c7bb6b79ef 100644
--- a/editor/plugins/curve_editor_plugin.cpp
+++ b/editor/plugins/curve_editor_plugin.cpp
@@ -37,6 +37,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_undo_redo_manager.h"
CurveEditor::CurveEditor() {
_selected_point = -1;
@@ -139,14 +140,13 @@ void CurveEditor::gui_input(const Ref<InputEvent> &p_event) {
if (!mb.is_pressed() && _dragging && mb.get_button_index() == MouseButton::LEFT) {
_dragging = false;
if (_has_undo_data) {
- Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
-
- ur->create_action(_selected_tangent == TANGENT_NONE ? TTR("Modify Curve Point") : TTR("Modify Curve Tangent"));
- ur->add_do_method(*_curve_ref, "_set_data", _curve_ref->get_data());
- ur->add_undo_method(*_curve_ref, "_set_data", _undo_data);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
+ undo_redo->create_action(_selected_tangent == TANGENT_NONE ? TTR("Modify Curve Point") : TTR("Modify Curve Tangent"));
+ undo_redo->add_do_method(*_curve_ref, "_set_data", _curve_ref->get_data());
+ undo_redo->add_undo_method(*_curve_ref, "_set_data", _undo_data);
// Note: this will trigger one more "changed" signal even if nothing changes,
// but it's ok since it would have fired every frame during the drag anyways
- ur->commit_action();
+ undo_redo->commit_action();
_has_undo_data = false;
}
@@ -301,13 +301,11 @@ void CurveEditor::on_preset_item_selected(int preset_id) {
break;
}
- Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
- ur->create_action(TTR("Load Curve Preset"));
-
- ur->add_do_method(&curve, "_set_data", curve.get_data());
- ur->add_undo_method(&curve, "_set_data", previous_data);
-
- ur->commit_action();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
+ undo_redo->create_action(TTR("Load Curve Preset"));
+ undo_redo->add_do_method(&curve, "_set_data", curve.get_data());
+ undo_redo->add_undo_method(&curve, "_set_data", previous_data);
+ undo_redo->commit_action();
}
void CurveEditor::_curve_changed() {
@@ -435,8 +433,8 @@ CurveEditor::TangentIndex CurveEditor::get_tangent_at(Vector2 pos) const {
void CurveEditor::add_point(Vector2 pos) {
ERR_FAIL_COND(_curve_ref.is_null());
- Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
- ur->create_action(TTR("Remove Curve Point"));
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
+ undo_redo->create_action(TTR("Remove Curve Point"));
Vector2 point_pos = get_world_pos(pos);
if (point_pos.y < 0.0) {
@@ -449,22 +447,21 @@ void CurveEditor::add_point(Vector2 pos) {
int i = _curve_ref->add_point(point_pos);
_curve_ref->remove_point(i);
- ur->add_do_method(*_curve_ref, "add_point", point_pos);
- ur->add_undo_method(*_curve_ref, "remove_point", i);
-
- ur->commit_action();
+ undo_redo->add_do_method(*_curve_ref, "add_point", point_pos);
+ undo_redo->add_undo_method(*_curve_ref, "remove_point", i);
+ undo_redo->commit_action();
}
void CurveEditor::remove_point(int index) {
ERR_FAIL_COND(_curve_ref.is_null());
- Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
- ur->create_action(TTR("Remove Curve Point"));
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
+ undo_redo->create_action(TTR("Remove Curve Point"));
Curve::Point p = _curve_ref->get_point(index);
- ur->add_do_method(*_curve_ref, "remove_point", index);
- ur->add_undo_method(*_curve_ref, "add_point", p.position, p.left_tangent, p.right_tangent, p.left_mode, p.right_mode);
+ undo_redo->add_do_method(*_curve_ref, "remove_point", index);
+ undo_redo->add_undo_method(*_curve_ref, "add_point", p.position, p.left_tangent, p.right_tangent, p.left_mode, p.right_mode);
if (index == _selected_point) {
set_selected_point(-1);
@@ -474,14 +471,14 @@ void CurveEditor::remove_point(int index) {
set_hover_point_index(-1);
}
- ur->commit_action();
+ undo_redo->commit_action();
}
void CurveEditor::toggle_linear(TangentIndex tangent) {
ERR_FAIL_COND(_curve_ref.is_null());
- Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
- ur->create_action(TTR("Toggle Curve Linear Tangent"));
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
+ undo_redo->create_action(TTR("Toggle Curve Linear Tangent"));
if (tangent == TANGENT_NONE) {
tangent = _selected_tangent;
@@ -493,8 +490,8 @@ void CurveEditor::toggle_linear(TangentIndex tangent) {
Curve::TangentMode prev_mode = _curve_ref->get_point_left_mode(_selected_point);
Curve::TangentMode mode = is_linear ? Curve::TANGENT_FREE : Curve::TANGENT_LINEAR;
- ur->add_do_method(*_curve_ref, "set_point_left_mode", _selected_point, mode);
- ur->add_undo_method(*_curve_ref, "set_point_left_mode", _selected_point, prev_mode);
+ undo_redo->add_do_method(*_curve_ref, "set_point_left_mode", _selected_point, mode);
+ undo_redo->add_undo_method(*_curve_ref, "set_point_left_mode", _selected_point, prev_mode);
} else {
bool is_linear = _curve_ref->get_point_right_mode(_selected_point) == Curve::TANGENT_LINEAR;
@@ -502,11 +499,11 @@ void CurveEditor::toggle_linear(TangentIndex tangent) {
Curve::TangentMode prev_mode = _curve_ref->get_point_right_mode(_selected_point);
Curve::TangentMode mode = is_linear ? Curve::TANGENT_FREE : Curve::TANGENT_LINEAR;
- ur->add_do_method(*_curve_ref, "set_point_right_mode", _selected_point, mode);
- ur->add_undo_method(*_curve_ref, "set_point_right_mode", _selected_point, prev_mode);
+ undo_redo->add_do_method(*_curve_ref, "set_point_right_mode", _selected_point, mode);
+ undo_redo->add_undo_method(*_curve_ref, "set_point_right_mode", _selected_point, prev_mode);
}
- ur->commit_action();
+ undo_redo->commit_action();
}
void CurveEditor::set_selected_point(int index) {
@@ -755,10 +752,10 @@ void CurveEditor::_draw() {
float width = view_size.x - 60 * EDSCALE;
if (_selected_point > 0 && _selected_point + 1 < curve.get_point_count()) {
text_color.a *= 0.4;
- draw_multiline_string(font, Vector2(50 * EDSCALE, font_height), TTR("Hold Shift to edit tangents individually"), HORIZONTAL_ALIGNMENT_LEFT, width, -1, font_size, text_color);
+ draw_multiline_string(font, Vector2(50 * EDSCALE, font_height), TTR("Hold Shift to edit tangents individually"), HORIZONTAL_ALIGNMENT_LEFT, width, font_size, -1, text_color);
} else if (curve.get_point_count() == 0) {
text_color.a *= 0.4;
- draw_multiline_string(font, Vector2(50 * EDSCALE, font_height), TTR("Right click to add point"), HORIZONTAL_ALIGNMENT_LEFT, width, -1, font_size, text_color);
+ draw_multiline_string(font, Vector2(50 * EDSCALE, font_height), TTR("Right click to add point"), HORIZONTAL_ALIGNMENT_LEFT, width, font_size, -1, text_color);
}
}
diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp
index 997dc0b2b5..5f9446c3b1 100644
--- a/editor/plugins/editor_preview_plugins.cpp
+++ b/editor/plugins/editor_preview_plugins.cpp
@@ -93,7 +93,7 @@ Ref<Texture2D> EditorTexturePreviewPlugin::generate(const Ref<Resource> &p_from,
return Ref<Texture2D>();
}
- img = atlas->get_rect(atex->get_region());
+ img = atlas->get_region(atex->get_region());
} else {
Ref<Texture2D> tex = p_from;
if (tex.is_valid()) {
diff --git a/editor/plugins/gradient_editor.cpp b/editor/plugins/gradient_editor.cpp
index 822f303d93..7039ada10a 100644
--- a/editor/plugins/gradient_editor.cpp
+++ b/editor/plugins/gradient_editor.cpp
@@ -99,7 +99,7 @@ void GradientEditor::_gradient_changed() {
void GradientEditor::_ramp_changed() {
editing = true;
- Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Gradient Edited"), UndoRedo::MERGE_ENDS);
undo_redo->add_do_method(gradient.ptr(), "set_offsets", get_offsets());
undo_redo->add_do_method(gradient.ptr(), "set_colors", get_colors());
diff --git a/editor/plugins/light_occluder_2d_editor_plugin.cpp b/editor/plugins/light_occluder_2d_editor_plugin.cpp
index e7ef65c32b..f2c46cc9e8 100644
--- a/editor/plugins/light_occluder_2d_editor_plugin.cpp
+++ b/editor/plugins/light_occluder_2d_editor_plugin.cpp
@@ -30,6 +30,9 @@
#include "light_occluder_2d_editor_plugin.h"
+#include "editor/editor_node.h"
+#include "editor/editor_undo_redo_manager.h"
+
Ref<OccluderPolygon2D> LightOccluder2DEditor::_ensure_occluder() const {
Ref<OccluderPolygon2D> occluder = node->get_occluder_polygon();
if (!occluder.is_valid()) {
@@ -81,6 +84,7 @@ void LightOccluder2DEditor::_set_polygon(int p_idx, const Variant &p_polygon) co
void LightOccluder2DEditor::_action_set_polygon(int p_idx, const Variant &p_previous, const Variant &p_polygon) {
Ref<OccluderPolygon2D> occluder = _ensure_occluder();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->add_do_method(occluder.ptr(), "set_polygon", p_polygon);
undo_redo->add_undo_method(occluder.ptr(), "set_polygon", p_previous);
}
@@ -94,6 +98,7 @@ void LightOccluder2DEditor::_create_resource() {
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Create Occluder Polygon"));
undo_redo->add_do_method(node, "set_occluder_polygon", Ref<OccluderPolygon2D>(memnew(OccluderPolygon2D)));
undo_redo->add_undo_method(node, "set_occluder_polygon", Variant(Ref<RefCounted>()));
diff --git a/editor/plugins/line_2d_editor_plugin.cpp b/editor/plugins/line_2d_editor_plugin.cpp
index d73761d770..9182b23867 100644
--- a/editor/plugins/line_2d_editor_plugin.cpp
+++ b/editor/plugins/line_2d_editor_plugin.cpp
@@ -30,6 +30,9 @@
#include "line_2d_editor_plugin.h"
+#include "editor/editor_node.h"
+#include "editor/editor_undo_redo_manager.h"
+
Node2D *Line2DEditor::_get_node() const {
return node;
}
@@ -52,6 +55,7 @@ void Line2DEditor::_set_polygon(int p_idx, const Variant &p_polygon) const {
void Line2DEditor::_action_set_polygon(int p_idx, const Variant &p_previous, const Variant &p_polygon) {
Node2D *_node = _get_node();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->add_do_method(_node, "set_points", p_polygon);
undo_redo->add_undo_method(_node, "set_points", p_previous);
}
diff --git a/editor/plugins/navigation_polygon_editor_plugin.cpp b/editor/plugins/navigation_polygon_editor_plugin.cpp
index 8f3553b8cf..664e18f555 100644
--- a/editor/plugins/navigation_polygon_editor_plugin.cpp
+++ b/editor/plugins/navigation_polygon_editor_plugin.cpp
@@ -30,6 +30,9 @@
#include "navigation_polygon_editor_plugin.h"
+#include "editor/editor_node.h"
+#include "editor/editor_undo_redo_manager.h"
+
Ref<NavigationPolygon> NavigationPolygonEditor::_ensure_navpoly() const {
Ref<NavigationPolygon> navpoly = node->get_navigation_polygon();
if (!navpoly.is_valid()) {
@@ -73,6 +76,7 @@ void NavigationPolygonEditor::_set_polygon(int p_idx, const Variant &p_polygon)
void NavigationPolygonEditor::_action_add_polygon(const Variant &p_polygon) {
Ref<NavigationPolygon> navpoly = _ensure_navpoly();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->add_do_method(navpoly.ptr(), "add_outline", p_polygon);
undo_redo->add_undo_method(navpoly.ptr(), "remove_outline", navpoly->get_outline_count());
undo_redo->add_do_method(navpoly.ptr(), "make_polygons_from_outlines");
@@ -81,6 +85,7 @@ void NavigationPolygonEditor::_action_add_polygon(const Variant &p_polygon) {
void NavigationPolygonEditor::_action_remove_polygon(int p_idx) {
Ref<NavigationPolygon> navpoly = _ensure_navpoly();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->add_do_method(navpoly.ptr(), "remove_outline", p_idx);
undo_redo->add_undo_method(navpoly.ptr(), "add_outline_at_index", navpoly->get_outline(p_idx), p_idx);
undo_redo->add_do_method(navpoly.ptr(), "make_polygons_from_outlines");
@@ -89,6 +94,7 @@ void NavigationPolygonEditor::_action_remove_polygon(int p_idx) {
void NavigationPolygonEditor::_action_set_polygon(int p_idx, const Variant &p_previous, const Variant &p_polygon) {
Ref<NavigationPolygon> navpoly = _ensure_navpoly();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->add_do_method(navpoly.ptr(), "set_outline", p_idx, p_polygon);
undo_redo->add_undo_method(navpoly.ptr(), "set_outline", p_idx, p_previous);
undo_redo->add_do_method(navpoly.ptr(), "make_polygons_from_outlines");
@@ -104,6 +110,7 @@ void NavigationPolygonEditor::_create_resource() {
return;
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Create Navigation Polygon"));
undo_redo->add_do_method(node, "set_navigation_polygon", Ref<NavigationPolygon>(memnew(NavigationPolygon)));
undo_redo->add_undo_method(node, "set_navigation_polygon", Variant(Ref<RefCounted>()));
diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp
index 508e485a86..0af2a13df2 100644
--- a/editor/plugins/node_3d_editor_gizmos.cpp
+++ b/editor/plugins/node_3d_editor_gizmos.cpp
@@ -110,7 +110,9 @@ void EditorNode3DGizmo::clear() {
collision_mesh = Ref<TriangleMesh>();
instances.clear();
handles.clear();
+ handle_ids.clear();
secondary_handles.clear();
+ secondary_handle_ids.clear();
}
void EditorNode3DGizmo::redraw() {
@@ -406,12 +408,15 @@ void EditorNode3DGizmo::add_handles(const Vector<Vector3> &p_handles, const Ref<
return;
}
- ERR_FAIL_COND(!spatial_node);
+ ERR_FAIL_NULL(spatial_node);
+
+ Vector<Vector3> &handle_list = p_secondary ? secondary_handles : handles;
+ Vector<int> &id_list = p_secondary ? secondary_handle_ids : handle_ids;
if (p_ids.is_empty()) {
- ERR_FAIL_COND_MSG((!handles.is_empty() && !handle_ids.is_empty()) || (!secondary_handles.is_empty() && !secondary_handle_ids.is_empty()), "Fail");
+ ERR_FAIL_COND_MSG(!id_list.is_empty(), "IDs must be provided for all handles, as handles with IDs already exist.");
} else {
- ERR_FAIL_COND_MSG(handles.size() != handle_ids.size() || secondary_handles.size() != secondary_handle_ids.size(), "Fail");
+ ERR_FAIL_COND_MSG(p_handles.size() != p_ids.size(), "The number of IDs should be the same as the number of handles.");
}
bool is_current_hover_gizmo = Node3DEditor::get_singleton()->get_current_hover_gizmo() == this;
@@ -464,19 +469,17 @@ void EditorNode3DGizmo::add_handles(const Vector<Vector3> &p_handles, const Ref<
}
instances.push_back(ins);
- Vector<Vector3> &h = p_secondary ? secondary_handles : handles;
- int current_size = h.size();
- h.resize(current_size + p_handles.size());
+ int current_size = handle_list.size();
+ handle_list.resize(current_size + p_handles.size());
for (int i = 0; i < p_handles.size(); i++) {
- h.write[current_size + i] = p_handles[i];
+ handle_list.write[current_size + i] = p_handles[i];
}
if (!p_ids.is_empty()) {
- Vector<int> &ids = p_secondary ? secondary_handle_ids : handle_ids;
- current_size = ids.size();
- ids.resize(current_size + p_ids.size());
+ current_size = id_list.size();
+ id_list.resize(current_size + p_ids.size());
for (int i = 0; i < p_ids.size(); i++) {
- ids.write[current_size + i] = p_ids[i];
+ id_list.write[current_size + i] = p_ids[i];
}
}
}
@@ -1145,7 +1148,7 @@ int EditorNode3DGizmoPlugin::subgizmos_intersect_ray(const EditorNode3DGizmo *p_
}
Vector<int> EditorNode3DGizmoPlugin::subgizmos_intersect_frustum(const EditorNode3DGizmo *p_gizmo, const Camera3D *p_camera, const Vector<Plane> &p_frustum) const {
- TypedArray<Transform3D> frustum;
+ TypedArray<Plane> frustum;
frustum.resize(p_frustum.size());
for (int i = 0; i < p_frustum.size(); i++) {
frustum[i] = p_frustum[i];
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 675f27f1f6..7febb50f5c 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -40,6 +40,7 @@
#include "editor/debugger/editor_debugger_node.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
+#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/animation_player_editor_plugin.h"
#include "editor/plugins/node_3d_editor_gizmos.h"
#include "editor/plugins/script_editor_plugin.h"
@@ -1650,12 +1651,12 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
se->gizmo->commit_subgizmos(ids, restore, false);
- spatial_editor->update_transform_gizmo();
} else {
commit_transform();
}
_edit.mode = TRANSFORM_NONE;
set_message("");
+ spatial_editor->update_transform_gizmo();
}
surface->queue_redraw();
}
@@ -2664,7 +2665,7 @@ void Node3DEditorViewport::_notification(int p_what) {
return;
}
if (preview_node->is_inside_tree()) {
- preview_node_pos = _get_instance_position(preview_node_viewport_pos);
+ preview_node_pos = spatial_editor->snap_point(_get_instance_position(preview_node_viewport_pos));
Transform3D preview_gl_transform = Transform3D(Basis(), preview_node_pos);
preview_node->set_global_transform(preview_gl_transform);
if (!preview_node->is_visible()) {
@@ -2898,6 +2899,7 @@ void Node3DEditorViewport::_draw() {
}
void Node3DEditorViewport::_menu_option(int p_option) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
switch (p_option) {
case VIEW_TOP: {
cursor.y_rot = 0;
@@ -3748,24 +3750,45 @@ void Node3DEditorViewport::assign_pending_data_pointers(Node3D *p_preview_node,
Vector3 Node3DEditorViewport::_get_instance_position(const Point2 &p_pos) const {
const float MAX_DISTANCE = 50.0;
+ const float FALLBACK_DISTANCE = 5.0;
Vector3 world_ray = _get_ray(p_pos);
Vector3 world_pos = _get_ray_pos(p_pos);
- Vector3 point = world_pos + world_ray * MAX_DISTANCE;
-
PhysicsDirectSpaceState3D *ss = get_tree()->get_root()->get_world_3d()->get_direct_space_state();
PhysicsDirectSpaceState3D::RayParameters ray_params;
ray_params.from = world_pos;
- ray_params.to = world_pos + world_ray * MAX_DISTANCE;
+ ray_params.to = world_pos + world_ray * camera->get_far();
PhysicsDirectSpaceState3D::RayResult result;
if (ss->intersect_ray(ray_params, result)) {
- point = result.position;
+ return result.position;
+ }
+
+ const bool is_orthogonal = camera->get_projection() == Camera3D::PROJECTION_ORTHOGONAL;
+
+ // The XZ plane.
+ Vector3 intersection;
+ Plane plane(Vector3(0, 1, 0));
+ if (plane.intersects_ray(world_pos, world_ray, &intersection)) {
+ if (is_orthogonal || world_pos.distance_to(intersection) <= MAX_DISTANCE) {
+ return intersection;
+ }
+ }
+
+ // Plane facing the camera using fallback distance.
+ if (is_orthogonal) {
+ plane = Plane(world_ray, cursor.pos - world_ray * (cursor.distance - FALLBACK_DISTANCE));
+ } else {
+ plane = Plane(world_ray, world_pos + world_ray * FALLBACK_DISTANCE);
+ }
+ if (plane.intersects_ray(world_pos, world_ray, &intersection)) {
+ return intersection;
}
- return point;
+ // Not likely, but just in case...
+ return world_pos + world_ray * FALLBACK_DISTANCE;
}
AABB Node3DEditorViewport::_calculate_spatial_bounds(const Node3D *p_parent, bool p_exclude_top_level_transform) {
@@ -4027,15 +4050,16 @@ bool Node3DEditorViewport::_create_instance(Node *parent, String &path, const Po
instantiated_scene->set_scene_file_path(ProjectSettings::get_singleton()->localize_path(path));
}
- editor_data->get_undo_redo()->add_do_method(parent, "add_child", instantiated_scene, true);
- editor_data->get_undo_redo()->add_do_method(instantiated_scene, "set_owner", EditorNode::get_singleton()->get_edited_scene());
- editor_data->get_undo_redo()->add_do_reference(instantiated_scene);
- editor_data->get_undo_redo()->add_undo_method(parent, "remove_child", instantiated_scene);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
+ undo_redo->add_do_method(parent, "add_child", instantiated_scene, true);
+ undo_redo->add_do_method(instantiated_scene, "set_owner", EditorNode::get_singleton()->get_edited_scene());
+ undo_redo->add_do_reference(instantiated_scene);
+ undo_redo->add_undo_method(parent, "remove_child", instantiated_scene);
String new_name = parent->validate_child_name(instantiated_scene);
EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton();
- editor_data->get_undo_redo()->add_do_method(ed, "live_debug_instance_node", EditorNode::get_singleton()->get_edited_scene()->get_path_to(parent), path, new_name);
- editor_data->get_undo_redo()->add_undo_method(ed, "live_debug_remove_node", NodePath(String(EditorNode::get_singleton()->get_edited_scene()->get_path_to(parent)) + "/" + new_name));
+ undo_redo->add_do_method(ed, "live_debug_instance_node", EditorNode::get_singleton()->get_edited_scene()->get_path_to(parent), path, new_name);
+ undo_redo->add_undo_method(ed, "live_debug_remove_node", NodePath(String(EditorNode::get_singleton()->get_edited_scene()->get_path_to(parent)) + "/" + new_name));
Node3D *node3d = Object::cast_to<Node3D>(instantiated_scene);
if (node3d) {
@@ -4045,29 +4069,30 @@ bool Node3DEditorViewport::_create_instance(Node *parent, String &path, const Po
gl_transform = parent_node3d->get_global_gizmo_transform();
}
- gl_transform.origin = spatial_editor->snap_point(preview_node_pos);
+ gl_transform.origin = preview_node_pos;
gl_transform.basis *= node3d->get_transform().basis;
- editor_data->get_undo_redo()->add_do_method(instantiated_scene, "set_global_transform", gl_transform);
+ undo_redo->add_do_method(instantiated_scene, "set_global_transform", gl_transform);
}
return true;
}
void Node3DEditorViewport::_perform_drop_data() {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
if (spatial_editor->get_preview_material_target().is_valid()) {
GeometryInstance3D *geometry_instance = Object::cast_to<GeometryInstance3D>(ObjectDB::get_instance(spatial_editor->get_preview_material_target()));
MeshInstance3D *mesh_instance = Object::cast_to<MeshInstance3D>(ObjectDB::get_instance(spatial_editor->get_preview_material_target()));
if (mesh_instance && spatial_editor->get_preview_material_surface() != -1) {
- editor_data->get_undo_redo()->create_action(vformat(TTR("Set Surface %d Override Material"), spatial_editor->get_preview_material_surface()));
- editor_data->get_undo_redo()->add_do_method(geometry_instance, "set_surface_override_material", spatial_editor->get_preview_material_surface(), spatial_editor->get_preview_material());
- editor_data->get_undo_redo()->add_undo_method(geometry_instance, "set_surface_override_material", spatial_editor->get_preview_material_surface(), spatial_editor->get_preview_reset_material());
- editor_data->get_undo_redo()->commit_action();
+ undo_redo->create_action(vformat(TTR("Set Surface %d Override Material"), spatial_editor->get_preview_material_surface()));
+ undo_redo->add_do_method(geometry_instance, "set_surface_override_material", spatial_editor->get_preview_material_surface(), spatial_editor->get_preview_material());
+ undo_redo->add_undo_method(geometry_instance, "set_surface_override_material", spatial_editor->get_preview_material_surface(), spatial_editor->get_preview_reset_material());
+ undo_redo->commit_action();
} else if (geometry_instance) {
- editor_data->get_undo_redo()->create_action(TTR("Set Material Override"));
- editor_data->get_undo_redo()->add_do_method(geometry_instance, "set_material_override", spatial_editor->get_preview_material());
- editor_data->get_undo_redo()->add_undo_method(geometry_instance, "set_material_override", spatial_editor->get_preview_reset_material());
- editor_data->get_undo_redo()->commit_action();
+ undo_redo->create_action(TTR("Set Material Override"));
+ undo_redo->add_do_method(geometry_instance, "set_material_override", spatial_editor->get_preview_material());
+ undo_redo->add_undo_method(geometry_instance, "set_material_override", spatial_editor->get_preview_reset_material());
+ undo_redo->commit_action();
}
_remove_preview_material();
@@ -4078,7 +4103,7 @@ void Node3DEditorViewport::_perform_drop_data() {
Vector<String> error_files;
- editor_data->get_undo_redo()->create_action(TTR("Create Node"));
+ undo_redo->create_action(TTR("Create Node"));
for (int i = 0; i < selected_files.size(); i++) {
String path = selected_files[i];
@@ -4096,7 +4121,7 @@ void Node3DEditorViewport::_perform_drop_data() {
}
}
- editor_data->get_undo_redo()->commit_action();
+ undo_redo->commit_action();
if (error_files.size() > 0) {
String files_str;
@@ -4129,11 +4154,13 @@ bool Node3DEditorViewport::can_drop_data_fw(const Point2 &p_point, const Variant
ResourceLoader::get_recognized_extensions_for_type("Texture", &texture_extensions);
for (int i = 0; i < files.size(); i++) {
+ String extension = files[i].get_extension().to_lower();
+
// Check if dragged files with mesh or scene extension can be created at least once.
- if (mesh_extensions.find(files[i].get_extension()) ||
- scene_extensions.find(files[i].get_extension()) ||
- material_extensions.find(files[i].get_extension()) ||
- texture_extensions.find(files[i].get_extension())) {
+ if (mesh_extensions.find(extension) ||
+ scene_extensions.find(extension) ||
+ material_extensions.find(extension) ||
+ texture_extensions.find(extension)) {
Ref<Resource> res = ResourceLoader::load(files[i]);
if (res.is_null()) {
continue;
@@ -4262,6 +4289,7 @@ void Node3DEditorViewport::commit_transform() {
TTRC("Translate"),
TTRC("Scale"),
};
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(_transform_name[_edit.mode]);
List<Node *> &selection = editor_selection->get_selected_node_list();
@@ -4667,9 +4695,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p
_edit.gizmo_handle_secondary = false;
index = p_index;
- editor_data = SceneTreeDock::get_singleton()->get_editor_data();
editor_selection = EditorNode::get_singleton()->get_editor_selection();
- undo_redo = EditorNode::get_singleton()->get_undo_redo();
orthogonal = false;
auto_orthogonal = false;
@@ -5753,6 +5779,7 @@ void Node3DEditor::_xform_dialog_action() {
t.basis.rotate(rotate);
t.origin = translate;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("XForm Dialog"));
const List<Node *> &selection = editor_selection->get_selected_node_list();
@@ -5864,6 +5891,7 @@ void Node3DEditor::_update_camera_override_viewport(Object *p_viewport) {
}
void Node3DEditor::_menu_item_pressed(int p_option) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
switch (p_option) {
case MENU_TOOL_SELECT:
case MENU_TOOL_MOVE:
@@ -7049,6 +7077,7 @@ void Node3DEditor::_snap_selected_nodes_to_floor() {
}
if (snapped_to_floor) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Snap Nodes to Floor"));
// Perform snapping if at least one node can be snapped
@@ -7118,6 +7147,7 @@ void Node3DEditor::_add_sun_to_scene(bool p_already_added_environment) {
ERR_FAIL_COND(!base);
Node *new_sun = preview_sun->duplicate();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add Preview Sun to Scene"));
undo_redo->add_do_method(base, "add_child", new_sun, true);
// Move to the beginning of the scene tree since more "global" nodes
@@ -7151,6 +7181,7 @@ void Node3DEditor::_add_environment_to_scene(bool p_already_added_sun) {
new_env->set_camera_attributes(preview_environment->get_camera_attributes()->duplicate(true));
}
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add Preview Environment to Scene"));
undo_redo->add_do_method(base, "add_child", new_env, true);
// Move to the beginning of the scene tree since more "global" nodes
@@ -7290,14 +7321,6 @@ Vector<int> Node3DEditor::get_subgizmo_selection() {
return ret;
}
-void Node3DEditor::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) {
- undo_redo = p_undo_redo;
-}
-
-Ref<EditorUndoRedoManager> Node3DEditor::get_undo_redo() {
- return undo_redo;
-}
-
void Node3DEditor::add_control_to_menu_panel(Control *p_control) {
context_menu_hbox->add_child(p_control);
}
@@ -7748,7 +7771,6 @@ Node3DEditor::Node3DEditor() {
gizmo.scale = 1.0;
viewport_environment = Ref<Environment>(memnew(Environment));
- undo_redo = EditorNode::get_singleton()->get_undo_redo();
VBoxContainer *vbc = this;
custom_camera = nullptr;
diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h
index 7dbe153efd..5ea1bf6dc1 100644
--- a/editor/plugins/node_3d_editor_plugin.h
+++ b/editor/plugins/node_3d_editor_plugin.h
@@ -53,7 +53,6 @@ class Node3DEditorViewport;
class SubViewportContainer;
class DirectionalLight3D;
class WorldEnvironment;
-class EditorUndoRedoManager;
class ViewportRotationControl : public Control {
GDCLASS(ViewportRotationControl, Control);
@@ -203,9 +202,7 @@ private:
Node *target_node = nullptr;
Point2 drop_pos;
- EditorData *editor_data = nullptr;
EditorSelection *editor_selection = nullptr;
- Ref<EditorUndoRedoManager> undo_redo;
CheckBox *preview_camera = nullptr;
SubViewportContainer *subviewport_container = nullptr;
@@ -686,7 +683,6 @@ private:
HBoxContainer *context_menu_hbox = nullptr;
void _generate_selection_boxes();
- Ref<EditorUndoRedoManager> undo_redo;
int camera_override_viewport_id;
@@ -835,9 +831,6 @@ public:
Ref<Environment> get_viewport_environment() { return viewport_environment; }
- void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo);
- Ref<EditorUndoRedoManager> get_undo_redo();
-
void add_control_to_menu_panel(Control *p_control);
void remove_control_from_menu_panel(Control *p_control);
diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp
index 3f8ca825c0..6218c887fb 100644
--- a/editor/plugins/polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/polygon_2d_editor_plugin.cpp
@@ -32,8 +32,10 @@
#include "core/input/input_event.h"
#include "core/math/geometry_2d.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
#include "scene/2d/skeleton_2d.h"
#include "scene/gui/menu_button.h"
@@ -150,6 +152,7 @@ void Polygon2DEditor::_sync_bones() {
Array new_bones = node->call("_get_bones");
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Sync Bones"));
undo_redo->add_do_method(node, "_set_bones", new_bones);
undo_redo->add_undo_method(node, "_set_bones", prev_bones);
@@ -279,6 +282,7 @@ void Polygon2DEditor::_uv_edit_popup_hide() {
}
void Polygon2DEditor::_menu_option(int p_option) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
switch (p_option) {
case MODE_EDIT_UV: {
if (node->get_texture().is_null()) {
@@ -391,6 +395,7 @@ void Polygon2DEditor::_update_polygon_editing_state() {
void Polygon2DEditor::_commit_action() {
// Makes that undo/redoing actions made outside of the UV editor still affect its polygon.
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->add_do_method(uv_edit_draw, "queue_redraw");
undo_redo->add_undo_method(uv_edit_draw, "queue_redraw");
undo_redo->add_do_method(CanvasItemEditor::get_singleton(), "update_viewport");
@@ -458,8 +463,9 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
mtx.columns[2] = -uv_draw_ofs;
mtx.scale_basis(Vector2(uv_draw_zoom, uv_draw_zoom));
- Ref<InputEventMouseButton> mb = p_input;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
+ Ref<InputEventMouseButton> mb = p_input;
if (mb.is_valid()) {
if (mb->get_button_index() == MouseButton::LEFT) {
if (mb->is_pressed()) {
diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp
index 21647d1b69..e35e794b24 100644
--- a/editor/plugins/resource_preloader_editor_plugin.cpp
+++ b/editor/plugins/resource_preloader_editor_plugin.cpp
@@ -36,6 +36,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_undo_redo_manager.h"
void ResourcePreloaderEditor::_notification(int p_what) {
switch (p_what) {
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index e4f0192c64..4ff3919e9b 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -3892,7 +3892,7 @@ ScriptEditor::ScriptEditor() {
vbc->add_child(disk_changed_list);
disk_changed_list->set_v_size_flags(SIZE_EXPAND_FILL);
- disk_changed->connect("confirmed", callable_mp(this, &ScriptEditor::reload_scripts));
+ disk_changed->connect("confirmed", callable_mp(this, &ScriptEditor::reload_scripts).bind(false));
disk_changed->set_ok_button_text(TTR("Reload"));
disk_changed->add_button(TTR("Resave"), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "resave");
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 456c28d887..2f80e41dd4 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -32,6 +32,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
+#include "editor/editor_undo_redo_manager.h"
#include "editor/filesystem_dock.h"
#include "editor/plugins/text_shader_editor.h"
#include "editor/plugins/visual_shader_editor_plugin.h"
@@ -225,7 +226,7 @@ void ShaderEditorPlugin::_close_shader(int p_index) {
memdelete(c);
edited_shaders.remove_at(p_index);
_update_shader_list();
- EditorNode::get_singleton()->get_undo_redo()->clear_history(); // To prevent undo on deleted graphs.
+ EditorNode::get_undo_redo()->clear_history(); // To prevent undo on deleted graphs.
}
void ShaderEditorPlugin::_resource_saved(Object *obj) {
diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp
index f0a08cb4f5..a7a8d526d0 100644
--- a/editor/plugins/texture_region_editor_plugin.cpp
+++ b/editor/plugins/texture_region_editor_plugin.cpp
@@ -86,8 +86,8 @@ void TextureRegionEditor::_region_draw() {
mtx.scale_basis(Vector2(draw_zoom, draw_zoom));
RS::get_singleton()->canvas_item_add_set_transform(edit_draw->get_canvas_item(), mtx);
- edit_draw->draw_rect(Rect2(Point2(), base_tex->get_size()), Color(0.5, 0.5, 0.5, 0.5), false);
- edit_draw->draw_texture(base_tex, Point2());
+ edit_draw->draw_rect(Rect2(Point2(), preview_tex->get_size()), Color(0.5, 0.5, 0.5, 0.5), false);
+ edit_draw->draw_texture(preview_tex, Point2());
RS::get_singleton()->canvas_item_add_set_transform(edit_draw->get_canvas_item(), Transform2D());
const Color color = get_theme_color(SNAME("mono_color"), SNAME("Editor"));
@@ -905,6 +905,13 @@ void TextureRegionEditor::edit(Object *p_obj) {
if (atlas_tex.is_valid()) {
atlas_tex->disconnect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed));
}
+
+ node_sprite_2d = nullptr;
+ node_sprite_3d = nullptr;
+ node_ninepatch = nullptr;
+ obj_styleBox = Ref<StyleBoxTexture>(nullptr);
+ atlas_tex = Ref<AtlasTexture>(nullptr);
+
if (p_obj) {
node_sprite_2d = Object::cast_to<Sprite2D>(p_obj);
node_sprite_3d = Object::cast_to<Sprite3D>(p_obj);
@@ -926,13 +933,8 @@ void TextureRegionEditor::edit(Object *p_obj) {
p_obj->connect("texture_changed", callable_mp(this, &TextureRegionEditor::_texture_changed));
}
_edit_region();
- } else {
- node_sprite_2d = nullptr;
- node_sprite_3d = nullptr;
- node_ninepatch = nullptr;
- obj_styleBox = Ref<StyleBoxTexture>(nullptr);
- atlas_tex = Ref<AtlasTexture>(nullptr);
}
+
edit_draw->queue_redraw();
popup_centered_ratio(0.5);
request_center = true;
@@ -946,20 +948,80 @@ void TextureRegionEditor::_texture_changed() {
}
void TextureRegionEditor::_edit_region() {
+ CanvasItem::TextureFilter filter = CanvasItem::TEXTURE_FILTER_NEAREST_WITH_MIPMAPS;
+
Ref<Texture2D> texture = nullptr;
if (atlas_tex.is_valid()) {
texture = atlas_tex->get_atlas();
} else if (node_sprite_2d) {
texture = node_sprite_2d->get_texture();
+ filter = node_sprite_2d->get_texture_filter_in_tree();
} else if (node_sprite_3d) {
texture = node_sprite_3d->get_texture();
+
+ StandardMaterial3D::TextureFilter filter_3d = node_sprite_3d->get_texture_filter();
+
+ switch (filter_3d) {
+ case StandardMaterial3D::TEXTURE_FILTER_NEAREST:
+ filter = CanvasItem::TEXTURE_FILTER_NEAREST;
+ break;
+ case StandardMaterial3D::TEXTURE_FILTER_LINEAR:
+ filter = CanvasItem::TEXTURE_FILTER_LINEAR;
+ break;
+ case StandardMaterial3D::TEXTURE_FILTER_NEAREST_WITH_MIPMAPS:
+ filter = CanvasItem::TEXTURE_FILTER_NEAREST_WITH_MIPMAPS;
+ break;
+ case StandardMaterial3D::TEXTURE_FILTER_LINEAR_WITH_MIPMAPS:
+ filter = CanvasItem::TEXTURE_FILTER_LINEAR_WITH_MIPMAPS;
+ break;
+ case StandardMaterial3D::TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC:
+ filter = CanvasItem::TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC;
+ break;
+ case StandardMaterial3D::TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC:
+ filter = CanvasItem::TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC;
+ break;
+ default:
+ // fallback to project default
+ filter = CanvasItem::TEXTURE_FILTER_PARENT_NODE;
+ break;
+ }
} else if (node_ninepatch) {
texture = node_ninepatch->get_texture();
+ filter = node_ninepatch->get_texture_filter_in_tree();
} else if (obj_styleBox.is_valid()) {
texture = obj_styleBox->get_texture();
}
+ // occurs when get_texture_filter_in_tree reaches the scene root
+ if (filter == CanvasItem::TEXTURE_FILTER_PARENT_NODE) {
+ SubViewport *root = EditorNode::get_singleton()->get_scene_root();
+
+ if (root != nullptr) {
+ Viewport::DefaultCanvasItemTextureFilter filter_default = root->get_default_canvas_item_texture_filter();
+
+ // depending on default filter, set filter to match, otherwise fall back on nearest w/ mipmaps
+ switch (filter_default) {
+ case DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST:
+ filter = CanvasItem::TEXTURE_FILTER_NEAREST;
+ break;
+ case DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR:
+ filter = CanvasItem::TEXTURE_FILTER_LINEAR;
+ break;
+ case DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS:
+ filter = CanvasItem::TEXTURE_FILTER_LINEAR_WITH_MIPMAPS;
+ break;
+ case DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS:
+ default:
+ filter = CanvasItem::TEXTURE_FILTER_NEAREST_WITH_MIPMAPS;
+ break;
+ }
+ } else {
+ filter = CanvasItem::TEXTURE_FILTER_NEAREST_WITH_MIPMAPS;
+ }
+ }
+
if (texture.is_null()) {
+ preview_tex->set_diffuse_texture(nullptr);
_zoom_reset();
hscroll->hide();
vscroll->hide();
@@ -967,6 +1029,9 @@ void TextureRegionEditor::_edit_region() {
return;
}
+ preview_tex->set_texture_filter(filter);
+ preview_tex->set_diffuse_texture(texture);
+
if (cache_map.has(texture->get_rid())) {
autoslice_cache = cache_map[texture->get_rid()];
autoslice_is_dirty = false;
@@ -1002,6 +1067,8 @@ TextureRegionEditor::TextureRegionEditor() {
atlas_tex = Ref<AtlasTexture>(nullptr);
undo_redo = EditorNode::get_singleton()->get_undo_redo();
+ preview_tex = Ref<CanvasTexture>(memnew(CanvasTexture));
+
snap_step = Vector2(10, 10);
snap_separation = Vector2(0, 0);
snap_mode = SNAP_NONE;
diff --git a/editor/plugins/texture_region_editor_plugin.h b/editor/plugins/texture_region_editor_plugin.h
index e3bbaf49fc..7eda4f469f 100644
--- a/editor/plugins/texture_region_editor_plugin.h
+++ b/editor/plugins/texture_region_editor_plugin.h
@@ -86,6 +86,8 @@ class TextureRegionEditor : public AcceptDialog {
Ref<StyleBoxTexture> obj_styleBox;
Ref<AtlasTexture> atlas_tex;
+ Ref<CanvasTexture> preview_tex;
+
Rect2 rect;
Rect2 rect_prev;
float prev_margin = 0.0f;
diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
index f1dfba6f35..8bf99db43b 100644
--- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
+++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
@@ -33,7 +33,9 @@
#include "tiles_editor_plugin.h"
#include "editor/editor_inspector.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
+#include "editor/editor_undo_redo_manager.h"
#include "editor/progress_dialog.h"
#include "editor/editor_node.h"
@@ -1310,6 +1312,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_gui_input(const Ref<InputEven
}
void TileSetAtlasSourceEditor::_end_dragging() {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
switch (drag_type) {
case DRAG_TYPE_CREATE_TILES:
undo_redo->create_action(TTR("Create tiles"));
@@ -1540,6 +1543,8 @@ HashMap<Vector2i, List<const PropertyInfo *>> TileSetAtlasSourceEditor::_group_p
}
void TileSetAtlasSourceEditor::_menu_option(int p_option) {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
+
switch (p_option) {
case TILE_DELETE: {
List<PropertyInfo> list;
@@ -2198,6 +2203,7 @@ void TileSetAtlasSourceEditor::_auto_create_tiles() {
Vector2i separation = tile_set_atlas_source->get_separation();
Vector2i texture_region_size = tile_set_atlas_source->get_texture_region_size();
Size2i grid_size = tile_set_atlas_source->get_atlas_grid_size();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Create tiles in non-transparent texture regions"));
for (int y = 0; y < grid_size.y; y++) {
for (int x = 0; x < grid_size.x; x++) {
@@ -2243,6 +2249,7 @@ void TileSetAtlasSourceEditor::_auto_remove_tiles() {
Vector2i texture_region_size = tile_set_atlas_source->get_texture_region_size();
Vector2i grid_size = tile_set_atlas_source->get_atlas_grid_size();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Remove tiles in fully transparent texture regions"));
List<PropertyInfo> list;
@@ -2336,8 +2343,6 @@ void TileSetAtlasSourceEditor::_bind_methods() {
}
TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() {
- undo_redo = EditorNode::get_undo_redo();
-
set_process_unhandled_key_input(true);
set_process_internal(true);
@@ -2366,7 +2371,6 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() {
tile_proxy_object->connect("changed", callable_mp(this, &TileSetAtlasSourceEditor::_tile_proxy_object_changed));
tile_inspector = memnew(EditorInspector);
- tile_inspector->set_undo_redo(undo_redo);
tile_inspector->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
tile_inspector->edit(tile_proxy_object);
tile_inspector->set_use_folding(true);
@@ -2414,7 +2418,6 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() {
atlas_source_proxy_object->connect("changed", callable_mp(this, &TileSetAtlasSourceEditor::_atlas_source_proxy_object_changed));
atlas_source_inspector = memnew(EditorInspector);
- atlas_source_inspector->set_undo_redo(undo_redo);
atlas_source_inspector->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
atlas_source_inspector->edit(atlas_source_proxy_object);
middle_vbox_container->add_child(atlas_source_inspector);
diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.h b/editor/plugins/tiles/tile_set_atlas_source_editor.h
index badb702e29..8e217e359f 100644
--- a/editor/plugins/tiles/tile_set_atlas_source_editor.h
+++ b/editor/plugins/tiles/tile_set_atlas_source_editor.h
@@ -114,8 +114,6 @@ private:
TileSetAtlasSource *tile_set_atlas_source = nullptr;
int tile_set_atlas_source_id = TileSet::INVALID_SOURCE;
- Ref<EditorUndoRedoManager> undo_redo;
-
bool tile_set_changed_needs_update = false;
// -- Properties painting --
diff --git a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp
index ef69326686..3b711a568e 100644
--- a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp
+++ b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp
@@ -35,6 +35,7 @@
#include "editor/editor_resource_preview.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_undo_redo_manager.h"
#include "scene/gui/item_list.h"
@@ -235,6 +236,7 @@ void TileSetScenesCollectionSourceEditor::_scenes_list_item_activated(int p_inde
void TileSetScenesCollectionSourceEditor::_source_add_pressed() {
int scene_id = tile_set_scenes_collection_source->get_next_scene_tile_id();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add a Scene Tile"));
undo_redo->add_do_method(tile_set_scenes_collection_source, "create_scene_tile", Ref<PackedScene>(), scene_id);
undo_redo->add_undo_method(tile_set_scenes_collection_source, "remove_scene_tile", scene_id);
@@ -249,6 +251,7 @@ void TileSetScenesCollectionSourceEditor::_source_delete_pressed() {
ERR_FAIL_COND(selected_indices.size() <= 0);
int scene_id = scene_tiles_list->get_item_metadata(selected_indices[0]);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Remove a Scene Tile"));
undo_redo->add_do_method(tile_set_scenes_collection_source, "remove_scene_tile", scene_id);
undo_redo->add_undo_method(tile_set_scenes_collection_source, "create_scene_tile", tile_set_scenes_collection_source->get_scene_tile_scene(scene_id), scene_id);
@@ -400,6 +403,7 @@ void TileSetScenesCollectionSourceEditor::_drop_data_fw(const Point2 &p_point, c
Ref<PackedScene> resource = ResourceLoader::load(files[i]);
if (resource.is_valid()) {
int scene_id = tile_set_scenes_collection_source->get_next_scene_tile_id();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add a Scene Tile"));
undo_redo->add_do_method(tile_set_scenes_collection_source, "create_scene_tile", resource, scene_id);
undo_redo->add_undo_method(tile_set_scenes_collection_source, "remove_scene_tile", scene_id);
@@ -453,8 +457,6 @@ void TileSetScenesCollectionSourceEditor::_bind_methods() {
}
TileSetScenesCollectionSourceEditor::TileSetScenesCollectionSourceEditor() {
- undo_redo = EditorNode::get_undo_redo();
-
// -- Right side --
HSplitContainer *split_container_right_side = memnew(HSplitContainer);
split_container_right_side->set_h_size_flags(SIZE_EXPAND_FILL);
@@ -479,7 +481,6 @@ TileSetScenesCollectionSourceEditor::TileSetScenesCollectionSourceEditor() {
scenes_collection_source_proxy_object->connect("changed", callable_mp(this, &TileSetScenesCollectionSourceEditor::_scenes_collection_source_proxy_object_changed));
scenes_collection_source_inspector = memnew(EditorInspector);
- scenes_collection_source_inspector->set_undo_redo(undo_redo);
scenes_collection_source_inspector->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
scenes_collection_source_inspector->edit(scenes_collection_source_proxy_object);
middle_vbox_container->add_child(scenes_collection_source_inspector);
@@ -495,7 +496,6 @@ TileSetScenesCollectionSourceEditor::TileSetScenesCollectionSourceEditor() {
tile_proxy_object->connect("changed", callable_mp(this, &TileSetScenesCollectionSourceEditor::_update_action_buttons).unbind(1));
tile_inspector = memnew(EditorInspector);
- tile_inspector->set_undo_redo(undo_redo);
tile_inspector->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
tile_inspector->edit(tile_proxy_object);
tile_inspector->set_use_folding(true);
diff --git a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h
index 0284b45c0f..7270cccbd8 100644
--- a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h
+++ b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h
@@ -37,8 +37,6 @@
#include "scene/gui/item_list.h"
#include "scene/resources/tile_set.h"
-class UndoRedo;
-
class TileSetScenesCollectionSourceEditor : public HBoxContainer {
GDCLASS(TileSetScenesCollectionSourceEditor, HBoxContainer);
@@ -97,8 +95,6 @@ private:
TileSetScenesCollectionSource *tile_set_scenes_collection_source = nullptr;
int tile_set_source_id = -1;
- Ref<EditorUndoRedoManager> undo_redo;
-
bool tile_set_scenes_collection_source_changed_needs_update = false;
// Source inspector.
diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp
index 336ce9e4c8..4fdfaed50e 100644
--- a/editor/plugins/version_control_editor_plugin.cpp
+++ b/editor/plugins/version_control_editor_plugin.cpp
@@ -430,7 +430,7 @@ void VersionControlEditorPlugin::_discard_file(String p_file_path, EditorVCSInte
CHECK_PLUGIN_INITIALIZED();
EditorVCSInterface::get_singleton()->discard_file(p_file_path);
}
- // FIXIT: The project.godot file shows weird behaviour
+ // FIXIT: The project.godot file shows weird behavior
EditorFileSystem::get_singleton()->update_file(p_file_path);
}
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 9b6ff894b9..c8f6a2431d 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -4062,7 +4062,7 @@ void VisualShaderEditor::_input_select_item(Ref<VisualShaderNodeInput> p_input,
bool type_changed = next_input_type != prev_input_type;
- Ref<EditorUndoRedoManager> undo_redo_man = EditorNode::get_undo_redo();
+ Ref<EditorUndoRedoManager> &undo_redo_man = EditorNode::get_undo_redo();
undo_redo_man->create_action(TTR("Visual Shader Input Type Changed"));
undo_redo_man->add_do_method(p_input.ptr(), "set_input_name", p_name);
@@ -4131,7 +4131,7 @@ void VisualShaderEditor::_parameter_ref_select_item(Ref<VisualShaderNodeParamete
bool type_changed = p_parameter_ref->get_parameter_type_by_name(p_name) != p_parameter_ref->get_parameter_type_by_name(prev_name);
- Ref<EditorUndoRedoManager> undo_redo_man = EditorNode::get_undo_redo();
+ Ref<EditorUndoRedoManager> &undo_redo_man = EditorNode::get_undo_redo();
undo_redo_man->create_action(TTR("ParameterRef Name Changed"));
undo_redo_man->add_do_method(p_parameter_ref.ptr(), "set_parameter_name", p_name);
@@ -4175,7 +4175,7 @@ void VisualShaderEditor::_varying_select_item(Ref<VisualShaderNodeVarying> p_var
bool is_getter = Ref<VisualShaderNodeVaryingGetter>(p_varying.ptr()).is_valid();
- Ref<EditorUndoRedoManager> undo_redo_man = EditorNode::get_undo_redo();
+ Ref<EditorUndoRedoManager> &undo_redo_man = EditorNode::get_undo_redo();
undo_redo_man->create_action(TTR("Varying Name Changed"));
undo_redo_man->add_do_method(p_varying.ptr(), "set_varying_name", p_name);
@@ -5892,7 +5892,7 @@ public:
return;
}
- Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
updating = true;
undo_redo->create_action(TTR("Edit Visual Property:") + " " + p_property, UndoRedo::MERGE_ENDS);
@@ -6094,7 +6094,7 @@ void EditorPropertyVisualShaderMode::_option_selected(int p_which) {
return;
}
- Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Visual Shader Mode Changed"));
//do is easy
undo_redo->add_do_method(visual_shader.ptr(), "set_mode", p_which);
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index f23b08409e..28111bed58 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -114,6 +114,7 @@ void ProjectSettingsEditor::_add_setting() {
Variant value;
Variant::construct(Variant::Type(type_box->get_selected_id()), value, nullptr, 0, ce);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add Project Setting"));
undo_redo->add_do_property(ps, setting, value);
undo_redo->add_undo_property(ps, setting, ps->has_setting(setting) ? ps->get(setting) : Variant());
@@ -133,6 +134,7 @@ void ProjectSettingsEditor::_delete_setting() {
Variant value = ps->get(setting);
int order = ps->get_order(setting);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Delete Item"));
undo_redo->add_do_method(ps, "clear", setting);
@@ -221,9 +223,9 @@ void ProjectSettingsEditor::_select_type(Variant::Type p_type) {
void ProjectSettingsEditor::shortcut_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
const Ref<InputEventKey> k = p_event;
-
if (k.is_valid() && k->is_pressed()) {
bool handled = false;
@@ -339,6 +341,7 @@ void ProjectSettingsEditor::_action_added(const String &p_name) {
action["events"] = Array();
action["deadzone"] = 0.5f;
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Add Input Action"));
undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, action);
undo_redo->add_undo_method(ProjectSettings::get_singleton(), "clear", name);
@@ -354,6 +357,7 @@ void ProjectSettingsEditor::_action_edited(const String &p_name, const Dictionar
const String property_name = "input/" + p_name;
Dictionary old_val = GLOBAL_GET(property_name);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
if (old_val["deadzone"] != p_action["deadzone"]) {
// Deadzone Changed
undo_redo->create_action(TTR("Change Action deadzone"));
@@ -390,6 +394,7 @@ void ProjectSettingsEditor::_action_removed(const String &p_name) {
Dictionary old_val = GLOBAL_GET(property_name);
int order = ProjectSettings::get_singleton()->get_order(property_name);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Erase Input Action"));
undo_redo->add_do_method(ProjectSettings::get_singleton(), "clear", property_name);
undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", property_name, old_val);
@@ -412,6 +417,7 @@ void ProjectSettingsEditor::_action_renamed(const String &p_old_name, const Stri
int order = ProjectSettings::get_singleton()->get_order(old_property_name);
Dictionary action = GLOBAL_GET(old_property_name);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Rename Input Action Event"));
// Do: clear old, set new
undo_redo->add_do_method(ProjectSettings::get_singleton(), "clear", old_property_name);
@@ -441,6 +447,7 @@ void ProjectSettingsEditor::_action_reordered(const String &p_action_name, const
HashMap<String, Variant> action_values;
ProjectSettings::get_singleton()->get_property_list(&props);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Update Input Action Order"));
for (const PropertyInfo &prop : props) {
@@ -573,7 +580,6 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
set_title(TTR("Project Settings (project.godot)"));
ps = ProjectSettings::get_singleton();
- undo_redo = p_data->get_undo_redo();
data = p_data;
tab_container = memnew(TabContainer);
@@ -632,7 +638,6 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
custom_properties->add_child(del_button);
general_settings_inspector = memnew(SectionedInspector);
- general_settings_inspector->get_inspector()->set_undo_redo(EditorNode::get_undo_redo());
general_settings_inspector->set_v_size_flags(Control::SIZE_EXPAND_FILL);
general_settings_inspector->register_search_box(search_box);
general_settings_inspector->get_inspector()->set_use_filter(true);
diff --git a/editor/project_settings_editor.h b/editor/project_settings_editor.h
index ec10c76cb7..7f6dd1b692 100644
--- a/editor/project_settings_editor.h
+++ b/editor/project_settings_editor.h
@@ -42,7 +42,6 @@
#include "editor/shader_globals_editor.h"
#include "scene/gui/tab_container.h"
-class EditorUndoRedoManager;
class FileSystemDock;
class ProjectSettingsEditor : public AcceptDialog {
@@ -78,7 +77,6 @@ class ProjectSettingsEditor : public AcceptDialog {
ImportDefaultsEditor *import_defaults_editor = nullptr;
EditorData *data = nullptr;
- Ref<EditorUndoRedoManager> undo_redo;
void _advanced_toggled(bool p_button_pressed);
void _update_advanced(bool p_is_advanced);
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 6a935b4f7b..64ac38aaa5 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -42,6 +42,7 @@
#include "editor/editor_paths.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_undo_redo_manager.h"
#include "editor/multi_node_edit.h"
#include "editor/plugins/animation_player_editor_plugin.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
@@ -267,7 +268,7 @@ void SceneTreeDock::_replace_with_branch_scene(const String &p_file, Node *base)
return;
}
- Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Replace with Branch Scene"));
Node *parent = base->get_parent();
@@ -3568,7 +3569,7 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec
editor_selection->connect("selection_changed", callable_mp(this, &SceneTreeDock::_selection_changed));
- scene_tree->set_undo_redo(editor_data->get_undo_redo());
+ scene_tree->set_as_scene_tree_dock();
scene_tree->set_editor_selection(editor_selection);
create_dialog = memnew(CreateDialog);
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp
index c8bc189106..46d3502a24 100644
--- a/editor/scene_tree_editor.cpp
+++ b/editor/scene_tree_editor.cpp
@@ -68,6 +68,7 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i
Node *n = get_node(np);
ERR_FAIL_COND(!n);
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
if (p_id == BUTTON_SUBSCENE) {
if (n == get_scene_node()) {
if (n && n->get_scene_inherited_state().is_valid()) {
@@ -167,6 +168,7 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i
void SceneTreeEditor::_toggle_visible(Node *p_node) {
if (p_node->has_method("is_visible") && p_node->has_method("set_visible")) {
bool v = bool(p_node->call("is_visible"));
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->add_do_method(p_node, "set_visible", !v);
undo_redo->add_undo_method(p_node, "set_visible", v);
}
@@ -379,8 +381,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
item->set_tooltip_text(0, tooltip);
}
- if (can_open_instance && undo_redo.is_valid()) { //Show buttons only when necessary(SceneTreeDock) to avoid crashes
-
+ if (can_open_instance && is_scene_tree_dock) { // Show buttons only when necessary (SceneTreeDock) to avoid crashes.
if (!p_node->is_connected("script_changed", callable_mp(this, &SceneTreeEditor::_node_script_changed))) {
p_node->connect("script_changed", callable_mp(this, &SceneTreeEditor::_node_script_changed).bind(p_node));
}
@@ -997,11 +998,12 @@ void SceneTreeEditor::_renamed() {
return;
}
- if (!undo_redo.is_valid()) {
+ if (!is_scene_tree_dock) {
n->set_name(new_name);
which->set_metadata(0, n->get_path());
emit_signal(SNAME("node_renamed"));
} else {
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Rename Node"));
emit_signal(SNAME("node_prerename"), n, new_name);
undo_redo->add_do_method(this, "_rename_node", n->get_instance_id(), new_name);
@@ -1045,8 +1047,8 @@ String SceneTreeEditor::get_filter_term_warning() {
return filter_term_warning;
}
-void SceneTreeEditor::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) {
- undo_redo = p_undo_redo;
+void SceneTreeEditor::set_as_scene_tree_dock() {
+ is_scene_tree_dock = true;
}
void SceneTreeEditor::set_display_foreign_nodes(bool p_display) {
diff --git a/editor/scene_tree_editor.h b/editor/scene_tree_editor.h
index dcdfead885..33ef5dbcb3 100644
--- a/editor/scene_tree_editor.h
+++ b/editor/scene_tree_editor.h
@@ -37,8 +37,6 @@
#include "scene/gui/dialogs.h"
#include "scene/gui/tree.h"
-class EditorUndoRedoManager;
-
class SceneTreeEditor : public Control {
GDCLASS(SceneTreeEditor, Control);
@@ -98,9 +96,9 @@ class SceneTreeEditor : public Control {
bool can_open_instance;
bool updating_tree = false;
bool show_enabled_subscene = false;
+ bool is_scene_tree_dock = false;
void _renamed();
- Ref<EditorUndoRedoManager> undo_redo;
HashSet<Node *> marked;
bool marked_selectable = false;
@@ -145,7 +143,7 @@ public:
String get_filter() const;
String get_filter_term_warning();
- void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo);
+ void set_as_scene_tree_dock();
void set_display_foreign_nodes(bool p_display);
void set_marked(const HashSet<Node *> &p_marked, bool p_selectable = false, bool p_children_selectable = true);
diff --git a/editor/shader_globals_editor.cpp b/editor/shader_globals_editor.cpp
index 6967536692..596b3eefba 100644
--- a/editor/shader_globals_editor.cpp
+++ b/editor/shader_globals_editor.cpp
@@ -86,7 +86,7 @@ protected:
return false;
}
- Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo();
+ Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Set Shader Global Variable"));
undo_redo->add_do_method(RS::get_singleton(), "global_shader_parameter_set", p_name, p_value);