Add per-scene UndoRedo

This commit is contained in:
kobewi 2022-03-25 18:06:46 +01:00
parent 99548e521d
commit ece3df3938
122 changed files with 1498 additions and 642 deletions

View file

@ -532,7 +532,7 @@
</description>
</method>
<method name="get_undo_redo">
<return type="UndoRedo" />
<return type="EditorUndoRedoManager" />
<description>
Gets the undo/redo object. Most actions in the editor can be undoable, so use this object to make sure this happens when it's worth it.
</description>

View file

@ -0,0 +1,118 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="EditorUndoRedoManager" inherits="RefCounted" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
Manages undo history of scenes opened in the editor.
</brief_description>
<description>
[EditorUndoRedoManager] is a manager for [UndoRedo] objects associated with edited scenes. Each scene has its own undo history and [EditorUndoRedoManager] ensures that each action performed in the editor gets associated with a proper scene. For actions not related to scenes ([ProjectSettings] edits, external resources, etc.), a separate global history is used.
The usage is mostly the same as [UndoRedo]. You create and commit actions and the manager automatically decides under-the-hood what scenes it belongs to. The scene is deduced based on the first operation in an action, using the object from the operation. The rules are as follows:
- If the object is a [Node], use the currently edited scene;
- If the object is a built-in resource, use the scene from its path;
- If the object is external resource or anything else, use global history.
This guessing can sometimes yield false results, so you can provide a custom context object when creating an action.
</description>
<tutorials>
</tutorials>
<methods>
<method name="add_do_method" qualifiers="vararg">
<return type="void" />
<param index="0" name="object" type="Object" />
<param index="1" name="method" type="StringName" />
<description>
Register a method that will be called when the action is committed (i.e. the "do" action).
If this is the first operation, the [param object] will be used to deduce target undo history.
</description>
</method>
<method name="add_do_property">
<return type="void" />
<param index="0" name="object" type="Object" />
<param index="1" name="property" type="StringName" />
<param index="2" name="value" type="Variant" />
<description>
Register a property value change for "do".
If this is the first operation, the [param object] will be used to deduce target undo history.
</description>
</method>
<method name="add_do_reference">
<return type="void" />
<param index="0" name="object" type="Object" />
<description>
Register a reference for "do" that will be erased if the "do" history is lost. This is useful mostly for new nodes created for the "do" call. Do not use for resources.
</description>
</method>
<method name="add_undo_method" qualifiers="vararg">
<return type="void" />
<param index="0" name="object" type="Object" />
<param index="1" name="method" type="StringName" />
<description>
Register a method that will be called when the action is undone (i.e. the "undo" action).
If this is the first operation, the [param object] will be used to deduce target undo history.
</description>
</method>
<method name="add_undo_property">
<return type="void" />
<param index="0" name="object" type="Object" />
<param index="1" name="property" type="StringName" />
<param index="2" name="value" type="Variant" />
<description>
Register a property value change for "undo".
If this is the first operation, the [param object] will be used to deduce target undo history.
</description>
</method>
<method name="add_undo_reference">
<return type="void" />
<param index="0" name="object" type="Object" />
<description>
Register a reference for "undo" that will be erased if the "undo" history is lost. This is useful mostly for nodes removed with the "do" call (not the "undo" call!).
</description>
</method>
<method name="commit_action">
<return type="void" />
<param index="0" name="execute" type="bool" default="true" />
<description>
Commit the action. If [param execute] is true (default), all "do" methods/properties are called/set when this function is called.
</description>
</method>
<method name="create_action">
<return type="void" />
<param index="0" name="name" type="String" />
<param index="1" name="merge_mode" type="int" enum="UndoRedo.MergeMode" default="0" />
<param index="2" name="custom_context" type="Object" default="null" />
<description>
Create a new action. After this is called, do all your calls to [method add_do_method], [method add_undo_method], [method add_do_property], and [method add_undo_property], then commit the action with [method commit_action].
The way actions are merged is dictated by the [param merge_mode] argument. See [enum UndoRedo.MergeMode] for details.
If [param custom_context] object is provided, it will be used for deducing target history (instead of using the first operation).
</description>
</method>
<method name="get_history_undo_redo" qualifiers="const">
<return type="UndoRedo" />
<param index="0" name="id" type="int" />
<description>
Returns the [UndoRedo] object associated with the given history [param id].
[param id] above [code]0[/code] are mapped to the opened scene tabs (but it doesn't match their order). [param id] of [code]0[/code] or lower have special meaning (see [enum SpecialHistory]).
Best used with [method get_object_history_id]. This method is only provided in case you need some more advanced methods of [UndoRedo] (but keep in mind that directly operating on the [UndoRedo] object might affect editor's stability).
</description>
</method>
<method name="get_object_history_id" qualifiers="const">
<return type="int" />
<param index="0" name="object" type="Object" />
<description>
Returns the history ID deduced from the given [param object]. It can be used with [method get_history_undo_redo].
</description>
</method>
<method name="is_committing_action" qualifiers="const">
<return type="bool" />
<description>
Returns [code]true[/code] if the [EditorUndoRedoManager] is currently committing the action, i.e. running its "do" method or property change (see [method commit_action]).
</description>
</method>
</methods>
<constants>
<constant name="GLOBAL_HISTORY" value="0" enum="SpecialHistory">
Global history not associated with any scene, but with external resources etc.
</constant>
<constant name="INVALID_HISTORY" value="-99" enum="SpecialHistory">
Invalid "null" history. It's a special value, not associated with any object.
</constant>
</constants>
</class>

View file

@ -32,6 +32,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_undo_redo_manager.h"
#include "scene/gui/view_panner.h"
#include "scene/resources/text_line.h"
@ -649,7 +650,7 @@ Size2 AnimationBezierTrackEdit::get_minimum_size() const {
return Vector2(1, 1);
}
void AnimationBezierTrackEdit::set_undo_redo(UndoRedo *p_undo_redo) {
void AnimationBezierTrackEdit::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) {
undo_redo = p_undo_redo;
}

View file

@ -34,6 +34,7 @@
#include "animation_track_editor.h"
#include "core/templates/rb_set.h"
class EditorUndoRedoManager;
class ViewPanner;
class AnimationBezierTrackEdit : public Control {
@ -48,7 +49,7 @@ class AnimationBezierTrackEdit : public Control {
};
AnimationTimelineEdit *timeline = nullptr;
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
Node *root = nullptr;
Control *play_position = nullptr; //separate control used to draw so updates for only position changed are much faster
float play_position_pos = 0;
@ -180,7 +181,7 @@ public:
void set_animation_and_track(const Ref<Animation> &p_animation, int p_track, bool p_read_only);
virtual Size2 get_minimum_size() const override;
void set_undo_redo(UndoRedo *p_undo_redo);
void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo);
void set_timeline(AnimationTimelineEdit *p_timeline);
void set_editor(AnimationTrackEditor *p_editor);
void set_root(Node *p_root);

View file

@ -35,6 +35,7 @@
#include "editor/animation_bezier_editor.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/animation_player_editor_plugin.h"
#include "scene/animation/animation_player.h"
#include "scene/gui/separator.h"
@ -680,7 +681,7 @@ public:
}
}
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
Ref<Animation> animation;
int track = -1;
float key_ofs = 0;
@ -1374,7 +1375,7 @@ public:
bool use_fps = false;
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
void notify_change() {
notify_property_list_changed();
@ -1708,7 +1709,7 @@ Size2 AnimationTimelineEdit::get_minimum_size() const {
return ms;
}
void AnimationTimelineEdit::set_undo_redo(UndoRedo *p_undo_redo) {
void AnimationTimelineEdit::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) {
undo_redo = p_undo_redo;
}
@ -2507,10 +2508,14 @@ Size2 AnimationTrackEdit::get_minimum_size() const {
return Vector2(1, max_h + separation);
}
void AnimationTrackEdit::set_undo_redo(UndoRedo *p_undo_redo) {
void AnimationTrackEdit::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) {
undo_redo = p_undo_redo;
}
Ref<EditorUndoRedoManager> AnimationTrackEdit::get_undo_redo() const {
return undo_redo;
}
void AnimationTrackEdit::set_timeline(AnimationTimelineEdit *p_timeline) {
timeline = p_timeline;
timeline->set_track_edit(this);
@ -6065,7 +6070,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
case EDIT_OPTIMIZE_ANIMATION_CONFIRM: {
animation->optimize(optimize_linear_error->get_value(), optimize_angular_error->get_value(), optimize_max_angle->get_value());
_update_tracks();
undo_redo->clear_history();
undo_redo->clear_history(true, undo_redo->get_history_for_object(animation.ptr()).id);
} break;
case EDIT_CLEAN_UP_ANIMATION: {
@ -6133,7 +6138,7 @@ void AnimationTrackEditor::_cleanup_animation(Ref<Animation> p_animation) {
}
}
undo_redo->clear_history();
undo_redo->clear_history(true, undo_redo->get_history_for_object(animation.ptr()).id);
_update_tracks();
}
@ -6303,7 +6308,7 @@ void AnimationTrackEditor::_pick_track_filter_input(const Ref<InputEvent> &p_ie)
}
AnimationTrackEditor::AnimationTrackEditor() {
undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo = EditorNode::get_undo_redo();
main_panel = memnew(PanelContainer);
main_panel->set_focus_mode(FOCUS_ALL); // Allow panel to have focus so that shortcuts work as expected.

View file

@ -78,7 +78,7 @@ class AnimationTimelineEdit : public Range {
void _anim_loop_pressed();
void _play_position_draw();
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
Rect2 hsize_rect;
bool editing = false;
@ -112,7 +112,7 @@ public:
void set_track_edit(AnimationTrackEdit *p_track_edit);
void set_zoom(Range *p_zoom);
Range *get_zoom() const { return zoom; }
void set_undo_redo(UndoRedo *p_undo_redo);
void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo);
void set_play_position(float p_pos);
float get_play_position() const;
@ -153,7 +153,7 @@ class AnimationTrackEdit : public Control {
};
AnimationTimelineEdit *timeline = nullptr;
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
Popup *path_popup = nullptr;
LineEdit *path = nullptr;
Node *root = nullptr;
@ -234,12 +234,12 @@ public:
Ref<Animation> get_animation() const;
AnimationTimelineEdit *get_timeline() const { return timeline; }
AnimationTrackEditor *get_editor() const { return editor; }
UndoRedo *get_undo_redo() const { return undo_redo; }
Ref<EditorUndoRedoManager> get_undo_redo() const;
NodePath get_path() const;
void set_animation_and_track(const Ref<Animation> &p_animation, int p_track, bool p_read_only);
virtual Size2 get_minimum_size() const override;
void set_undo_redo(UndoRedo *p_undo_redo);
void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo);
void set_timeline(AnimationTimelineEdit *p_timeline);
void set_editor(AnimationTrackEditor *p_editor);
void set_root(Node *p_root);
@ -334,7 +334,7 @@ class AnimationTrackEditor : public VBoxContainer {
void _animation_track_remove_request(int p_track, Ref<Animation> p_from_animation);
void _track_grab_focus(int p_track);
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
void _update_scroll(double);
void _update_step(double p_new_step);

View file

@ -33,6 +33,7 @@
#include "editor/audio_stream_preview.h"
#include "editor/editor_resource_preview.h"
#include "editor/editor_scale.h"
#include "editor/editor_undo_redo_manager.h"
#include "scene/2d/animated_sprite_2d.h"
#include "scene/2d/sprite_2d.h"
#include "scene/3d/sprite_3d.h"

View file

@ -32,6 +32,7 @@
#include "core/io/marshalls.h"
#include "editor/editor_node.h"
#include "editor/editor_undo_redo_manager.h"
#define ITEMS_PER_PAGE 100
@ -87,7 +88,7 @@ bool ArrayPropertyEdit::_set(const StringName &p_name, const Variant &p_value) {
return true;
}
UndoRedo *ur = EditorNode::get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Resize Array"));
ur->add_do_method(this, "_set_size", newsize);
ur->add_undo_method(this, "_set_size", size);
@ -134,7 +135,7 @@ bool ArrayPropertyEdit::_set(const StringName &p_name, const Variant &p_value) {
Callable::CallError ce;
Variant new_value;
Variant::construct(Variant::Type(type), new_value, nullptr, 0, ce);
UndoRedo *ur = EditorNode::get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Change Array Value Type"));
ur->add_do_method(this, "_set_value", idx, new_value);
@ -150,7 +151,7 @@ bool ArrayPropertyEdit::_set(const StringName &p_name, const Variant &p_value) {
Variant arr = get_array();
Variant value = arr.get(idx);
UndoRedo *ur = EditorNode::get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Change Array Value"));
ur->add_do_method(this, "_set_value", idx, p_value);

View file

@ -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/scene_tree_dock.h"
#include "plugins/script_editor_plugin.h"
@ -924,6 +925,10 @@ 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();

View file

@ -31,7 +31,6 @@
#ifndef CONNECTIONS_DIALOG_H
#define CONNECTIONS_DIALOG_H
#include "core/object/undo_redo.h"
#include "editor/editor_inspector.h"
#include "editor/scene_tree_editor.h"
#include "scene/gui/button.h"
@ -48,6 +47,7 @@
#include "scene/gui/tree.h"
class ConnectDialogBinds;
class EditorUndoRedoManager;
class ConnectDialog : public ConfirmationDialog {
GDCLASS(ConnectDialog, ConfirmationDialog);
@ -194,7 +194,7 @@ class ConnectionsDock : public VBoxContainer {
Button *connect_button = nullptr;
PopupMenu *signal_menu = nullptr;
PopupMenu *slot_menu = nullptr;
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
LineEdit *search_box = nullptr;
HashMap<StringName, HashMap<StringName, String>> descr_cache;
@ -225,7 +225,7 @@ protected:
static void _bind_methods();
public:
void set_undoredo(UndoRedo *p_undo_redo) { undo_redo = p_undo_redo; }
void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo);
void set_node(Node *p_node);
void update_tree();

View file

@ -30,6 +30,7 @@
#include "editor_debugger_node.h"
#include "core/object/undo_redo.h"
#include "editor/debugger/editor_debugger_tree.h"
#include "editor/debugger/script_editor_debugger.h"
#include "editor/editor_log.h"
@ -83,8 +84,6 @@ EditorDebuggerNode::EditorDebuggerNode() {
inspect_edited_object_timeout = EDITOR_DEF("debugger/remote_inspect_refresh_interval", 0.2);
EditorNode *editor = EditorNode::get_singleton();
editor->get_undo_redo()->set_method_notify_callback(_method_changeds, this);
editor->get_undo_redo()->set_property_notify_callback(_property_changeds, this);
editor->get_pause_button()->connect("pressed", callable_mp(this, &EditorDebuggerNode::_paused));
}
@ -181,6 +180,11 @@ void EditorDebuggerNode::_bind_methods() {
ADD_SIGNAL(MethodInfo("breakpoint_toggled", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::INT, "line"), PropertyInfo(Variant::BOOL, "enabled")));
}
void EditorDebuggerNode::register_undo_redo(UndoRedo *p_undo_redo) {
p_undo_redo->set_method_notify_callback(_method_changeds, this);
p_undo_redo->set_property_notify_callback(_property_changeds, this);
}
EditorDebuggerRemoteObject *EditorDebuggerNode::get_inspected_remote_object() {
return Object::cast_to<EditorDebuggerRemoteObject>(ObjectDB::get_instance(EditorNode::get_singleton()->get_editor_selection_history()->get_current()));
}

View file

@ -41,6 +41,7 @@ class EditorDebuggerRemoteObject;
class MenuButton;
class ScriptEditorDebugger;
class TabContainer;
class UndoRedo;
class EditorDebuggerNode : public MarginContainer {
GDCLASS(EditorDebuggerNode, MarginContainer);
@ -152,6 +153,7 @@ protected:
public:
static EditorDebuggerNode *get_singleton() { return singleton; }
void register_undo_redo(UndoRedo *p_undo_redo);
ScriptEditorDebugger *get_current_debugger() const;
ScriptEditorDebugger *get_default_debugger() const;

View file

@ -30,6 +30,7 @@
#include "dictionary_property_edit.h"
#include "editor/editor_node.h"
#include "editor/editor_undo_redo_manager.h"
void DictionaryPropertyEdit::_notif_change() {
notify_property_list_changed();
@ -118,7 +119,7 @@ bool DictionaryPropertyEdit::_set(const StringName &p_name, const Variant &p_val
int index = pn.substr(0, slash).to_int();
if (type == "key" && index < keys.size()) {
const Variant &key = keys[index];
UndoRedo *ur = EditorNode::get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Change Dictionary Key"));
ur->add_do_method(this, "_set_key", key, p_value);
@ -130,7 +131,7 @@ bool DictionaryPropertyEdit::_set(const StringName &p_name, const Variant &p_val
const Variant &key = keys[index];
if (dict.has(key)) {
Variant value = dict[key];
UndoRedo *ur = EditorNode::get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Change Dictionary Value"));
ur->add_do_method(this, "_set_value", key, p_value);

View file

@ -38,6 +38,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
#include "filesystem_dock.h"
#include "scene/resources/font.h"
#include "servers/audio_server.h"
@ -280,7 +281,7 @@ void EditorAudioBus::_name_changed(const String &p_new_name) {
}
updating_bus = true;
UndoRedo *ur = EditorNode::get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
StringName current = AudioServer::get_singleton()->get_bus_name(get_index());
ur->create_action(TTR("Rename Audio Bus"));
@ -321,7 +322,7 @@ void EditorAudioBus::_volume_changed(float p_normalized) {
slider->set_value(_scaled_db_to_normalized_volume(Math::round(p_db)));
}
UndoRedo *ur = EditorNode::get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Change Audio Bus Volume"), UndoRedo::MERGE_ENDS);
ur->add_do_method(AudioServer::get_singleton(), "set_bus_volume_db", get_index(), p_db);
ur->add_undo_method(AudioServer::get_singleton(), "set_bus_volume_db", get_index(), AudioServer::get_singleton()->get_bus_volume_db(get_index()));
@ -415,7 +416,7 @@ void EditorAudioBus::_hide_value_preview() {
void EditorAudioBus::_solo_toggled() {
updating_bus = true;
UndoRedo *ur = EditorNode::get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Toggle Audio Bus Solo"));
ur->add_do_method(AudioServer::get_singleton(), "set_bus_solo", get_index(), solo->is_pressed());
ur->add_undo_method(AudioServer::get_singleton(), "set_bus_solo", get_index(), AudioServer::get_singleton()->is_bus_solo(get_index()));
@ -429,7 +430,7 @@ void EditorAudioBus::_solo_toggled() {
void EditorAudioBus::_mute_toggled() {
updating_bus = true;
UndoRedo *ur = EditorNode::get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Toggle Audio Bus Mute"));
ur->add_do_method(AudioServer::get_singleton(), "set_bus_mute", get_index(), mute->is_pressed());
ur->add_undo_method(AudioServer::get_singleton(), "set_bus_mute", get_index(), AudioServer::get_singleton()->is_bus_mute(get_index()));
@ -443,7 +444,7 @@ void EditorAudioBus::_mute_toggled() {
void EditorAudioBus::_bypass_toggled() {
updating_bus = true;
UndoRedo *ur = EditorNode::get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Toggle Audio Bus Bypass Effects"));
ur->add_do_method(AudioServer::get_singleton(), "set_bus_bypass_effects", get_index(), bypass->is_pressed());
ur->add_undo_method(AudioServer::get_singleton(), "set_bus_bypass_effects", get_index(), AudioServer::get_singleton()->is_bus_bypassing_effects(get_index()));
@ -457,7 +458,7 @@ void EditorAudioBus::_bypass_toggled() {
void EditorAudioBus::_send_selected(int p_which) {
updating_bus = true;
UndoRedo *ur = EditorNode::get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Select Audio Bus Send"));
ur->add_do_method(AudioServer::get_singleton(), "set_bus_send", get_index(), send->get_item_text(p_which));
ur->add_undo_method(AudioServer::get_singleton(), "set_bus_send", get_index(), AudioServer::get_singleton()->get_bus_send(get_index()));
@ -507,7 +508,7 @@ void EditorAudioBus::_effect_edited() {
int index = effect->get_metadata(0);
updating_bus = true;
UndoRedo *ur = EditorNode::get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Select Audio Bus Send"));
ur->add_do_method(AudioServer::get_singleton(), "set_bus_effect_enabled", get_index(), index, effect->is_checked(0));
ur->add_undo_method(AudioServer::get_singleton(), "set_bus_effect_enabled", get_index(), index, AudioServer::get_singleton()->is_bus_effect_enabled(get_index(), index));
@ -534,7 +535,7 @@ void EditorAudioBus::_effect_add(int p_which) {
afxr->set_name(effect_options->get_item_text(p_which));
UndoRedo *ur = EditorNode::get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Add Audio Bus Effect"));
ur->add_do_method(AudioServer::get_singleton(), "add_bus_effect", get_index(), afxr, -1);
ur->add_undo_method(AudioServer::get_singleton(), "remove_bus_effect", get_index(), AudioServer::get_singleton()->get_bus_effect_count(get_index()));
@ -688,7 +689,7 @@ void EditorAudioBus::drop_data_fw(const Point2 &p_point, const Variant &p_data,
bool enabled = AudioServer::get_singleton()->is_bus_effect_enabled(bus, effect);
UndoRedo *ur = EditorNode::get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Move Bus Effect"));
ur->add_do_method(AudioServer::get_singleton(), "remove_bus_effect", bus, effect);
ur->add_do_method(AudioServer::get_singleton(), "add_bus_effect", get_index(), AudioServer::get_singleton()->get_bus_effect(bus, effect), paste_at);
@ -730,7 +731,7 @@ void EditorAudioBus::_delete_effect_pressed(int p_option) {
int index = item->get_metadata(0);
UndoRedo *ur = EditorNode::get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Delete Bus Effect"));
ur->add_do_method(AudioServer::get_singleton(), "remove_bus_effect", get_index(), index);
ur->add_undo_method(AudioServer::get_singleton(), "add_bus_effect", get_index(), AudioServer::get_singleton()->get_bus_effect(get_index(), index), index);
@ -1063,7 +1064,7 @@ void EditorAudioBuses::_notification(int p_what) {
}
void EditorAudioBuses::_add_bus() {
UndoRedo *ur = EditorNode::get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Add Audio Bus"));
ur->add_do_method(AudioServer::get_singleton(), "set_bus_count", AudioServer::get_singleton()->get_bus_count() + 1);
@ -1095,7 +1096,7 @@ void EditorAudioBuses::_delete_bus(Object *p_which) {
return;
}
UndoRedo *ur = EditorNode::get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Delete Audio Bus"));
ur->add_do_method(AudioServer::get_singleton(), "remove_bus", index);
@ -1117,7 +1118,7 @@ void EditorAudioBuses::_delete_bus(Object *p_which) {
void EditorAudioBuses::_duplicate_bus(int p_which) {
int add_at_pos = p_which + 1;
UndoRedo *ur = EditorNode::get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Duplicate Audio Bus"));
ur->add_do_method(AudioServer::get_singleton(), "add_bus", add_at_pos);
ur->add_do_method(AudioServer::get_singleton(), "set_bus_name", add_at_pos, AudioServer::get_singleton()->get_bus_name(p_which) + " Copy");
@ -1140,7 +1141,7 @@ void EditorAudioBuses::_reset_bus_volume(Object *p_which) {
EditorAudioBus *bus = Object::cast_to<EditorAudioBus>(p_which);
int index = bus->get_index();
UndoRedo *ur = EditorNode::get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Reset Bus Volume"));
ur->add_do_method(AudioServer::get_singleton(), "set_bus_volume_db", index, 0.f);
ur->add_undo_method(AudioServer::get_singleton(), "set_bus_volume_db", index, AudioServer::get_singleton()->get_bus_volume_db(index));
@ -1160,7 +1161,7 @@ void EditorAudioBuses::_request_drop_end() {
}
void EditorAudioBuses::_drop_at_index(int p_bus, int p_index) {
UndoRedo *ur = EditorNode::get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Move Audio Bus"));
ur->add_do_method(AudioServer::get_singleton(), "move_bus", p_bus, p_index);
@ -1219,7 +1220,7 @@ void EditorAudioBuses::_load_default_layout() {
file->set_text(String(TTR("Layout:")) + " " + layout_path.get_file());
AudioServer::get_singleton()->set_bus_layout(state);
_update_buses();
EditorNode::get_singleton()->get_undo_redo()->clear_history();
EditorNode::get_undo_redo()->clear_history(true, EditorUndoRedoManager::GLOBAL_HISTORY);
call_deferred(SNAME("_select_layout"));
}
@ -1235,7 +1236,7 @@ void EditorAudioBuses::_file_dialog_callback(const String &p_string) {
file->set_text(String(TTR("Layout:")) + " " + p_string.get_file());
AudioServer::get_singleton()->set_bus_layout(state);
_update_buses();
EditorNode::get_singleton()->get_undo_redo()->clear_history();
EditorNode::get_undo_redo()->clear_history(true, EditorUndoRedoManager::GLOBAL_HISTORY);
call_deferred(SNAME("_select_layout"));
} else if (file_dialog->get_file_mode() == EditorFileDialog::FILE_MODE_SAVE_FILE) {
@ -1255,7 +1256,7 @@ void EditorAudioBuses::_file_dialog_callback(const String &p_string) {
edited_path = p_string;
file->set_text(String(TTR("Layout:")) + " " + p_string.get_file());
_update_buses();
EditorNode::get_singleton()->get_undo_redo()->clear_history();
EditorNode::get_undo_redo()->clear_history(true, EditorUndoRedoManager::GLOBAL_HISTORY);
call_deferred(SNAME("_select_layout"));
}
}
@ -1354,7 +1355,7 @@ void EditorAudioBuses::open_layout(const String &p_path) {
file->set_text(p_path.get_file());
AudioServer::get_singleton()->set_bus_layout(state);
_update_buses();
EditorNode::get_singleton()->get_undo_redo()->clear_history();
EditorNode::get_undo_redo()->clear_history(true, EditorUndoRedoManager::GLOBAL_HISTORY);
call_deferred(SNAME("_select_layout"));
}

View file

@ -35,6 +35,7 @@
#include "editor/editor_file_dialog.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/filesystem_dock.h"
#include "project_settings_editor.h"
#include "scene/main/window.h"
@ -193,7 +194,7 @@ void EditorAutoloadSettings::_autoload_edited() {
TreeItem *ti = tree->get_edited();
int column = tree->get_edited_column();
UndoRedo *undo_redo = EditorNode::get_undo_redo();
Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo();
if (column == 0) {
String name = ti->get_text(0);
@ -288,7 +289,7 @@ void EditorAutoloadSettings::_autoload_button_pressed(Object *p_item, int p_colu
String name = "autoload/" + ti->get_text(0);
UndoRedo *undo_redo = EditorNode::get_undo_redo();
Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo();
switch (p_button) {
case BUTTON_OPEN: {
@ -713,7 +714,7 @@ void EditorAutoloadSettings::drop_data_fw(const Point2 &p_point, const Variant &
orders.sort();
UndoRedo *undo_redo = EditorNode::get_undo_redo();
Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo();
undo_redo->create_action(TTR("Rearrange Autoloads"));
@ -757,7 +758,7 @@ bool EditorAutoloadSettings::autoload_add(const String &p_name, const String &p_
name = "autoload/" + name;
UndoRedo *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 +784,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;
UndoRedo *undo_redo = EditorNode::get_undo_redo();
Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_undo_redo();
int order = ProjectSettings::get_singleton()->get_order(name);

View file

@ -35,6 +35,7 @@
#include "core/io/resource_loader.h"
#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/script_editor_plugin.h"
#include "scene/resources/packed_scene.h"
@ -364,13 +365,13 @@ void EditorData::restore_editor_global_states() {
void EditorData::paste_object_params(Object *p_object) {
ERR_FAIL_NULL(p_object);
undo_redo.create_action(TTR("Paste Params"));
undo_redo_manager->create_action(TTR("Paste Params"));
for (const PropertyData &E : clipboard) {
String name = E.name;
undo_redo.add_do_property(p_object, name, E.value);
undo_redo.add_undo_property(p_object, name, p_object->get(name));
undo_redo_manager->add_do_property(p_object, name, E.value);
undo_redo_manager->add_undo_property(p_object, name, p_object->get(name));
}
undo_redo.commit_action();
undo_redo_manager->commit_action();
}
bool EditorData::call_build() {
@ -383,8 +384,49 @@ bool EditorData::call_build() {
return result;
}
UndoRedo &EditorData::get_undo_redo() {
return undo_redo;
void EditorData::set_scene_as_saved(int p_idx) {
if (p_idx == -1) {
p_idx = current_edited_scene;
}
ERR_FAIL_INDEX(p_idx, edited_scene.size());
get_undo_redo()->set_history_as_saved(edited_scene[p_idx].history_id);
}
bool EditorData::is_scene_changed(int p_idx) {
if (p_idx == -1) {
p_idx = current_edited_scene;
}
ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), false);
uint64_t current_scene_version = get_undo_redo()->get_or_create_history(edited_scene[p_idx].history_id).undo_redo->get_version();
bool is_changed = edited_scene[p_idx].last_checked_version != current_scene_version;
edited_scene.write[p_idx].last_checked_version = current_scene_version;
return is_changed;
}
int EditorData::get_scene_history_id_from_path(const String &p_path) const {
for (const EditedScene &E : edited_scene) {
if (E.path == p_path) {
return E.history_id;
}
}
return 0;
}
int EditorData::get_current_edited_scene_history_id() const {
if (current_edited_scene != -1) {
return edited_scene[current_edited_scene].history_id;
}
return 0;
}
int EditorData::get_scene_history_id(int p_idx) const {
return edited_scene[p_idx].history_id;
}
Ref<EditorUndoRedoManager> &EditorData::get_undo_redo() {
return undo_redo_manager;
}
void EditorData::add_undo_redo_inspector_hook_callback(Callable p_callable) {
@ -415,12 +457,12 @@ Callable EditorData::get_move_array_element_function(const StringName &p_class)
}
void EditorData::remove_editor_plugin(EditorPlugin *p_plugin) {
p_plugin->undo_redo = nullptr;
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;
p_plugin->undo_redo = undo_redo_manager;
editor_plugins.push_back(p_plugin);
}
@ -505,8 +547,8 @@ int EditorData::add_edited_scene(int p_at_pos) {
es.path = String();
es.file_modified_time = 0;
es.history_current = -1;
es.version = 0;
es.live_edit_root = NodePath(String("/root"));
es.history_id = last_created_scene++;
if (p_at_pos == edited_scene.size()) {
edited_scene.push_back(es);
@ -547,6 +589,7 @@ void EditorData::remove_scene(int p_idx) {
ScriptEditor::get_singleton()->close_builtin_scripts_from_scene(edited_scene[p_idx].path);
}
undo_redo_manager->discard_history(edited_scene[p_idx].history_id);
edited_scene.remove_at(p_idx);
}
@ -679,26 +722,10 @@ Vector<EditorData::EditedScene> EditorData::get_edited_scenes() const {
return out_edited_scenes_list;
}
void EditorData::set_edited_scene_version(uint64_t version, int p_scene_idx) {
ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
if (p_scene_idx < 0) {
edited_scene.write[current_edited_scene].version = version;
} else {
ERR_FAIL_INDEX(p_scene_idx, edited_scene.size());
edited_scene.write[p_scene_idx].version = version;
}
}
uint64_t EditorData::get_scene_version(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), 0);
return edited_scene[p_idx].version;
}
void EditorData::set_scene_modified_time(int p_idx, uint64_t p_time) {
if (p_idx == -1) {
p_idx = current_edited_scene;
}
ERR_FAIL_INDEX(p_idx, edited_scene.size());
edited_scene.write[p_idx].file_modified_time = p_time;
@ -991,6 +1018,7 @@ void EditorData::script_class_load_icon_paths() {
EditorData::EditorData() {
current_edited_scene = -1;
undo_redo_manager.instantiate();
script_class_load_icon_paths();
}

View file

@ -31,12 +31,12 @@
#ifndef EDITOR_DATA_H
#define EDITOR_DATA_H
#include "core/object/undo_redo.h"
#include "core/templates/list.h"
#include "scene/resources/texture.h"
class ConfigFile;
class EditorPlugin;
class EditorUndoRedoManager;
/**
* Stores the history of objects which have been selected for editing in the Editor & the Inspector.
@ -118,8 +118,9 @@ public:
Vector<EditorSelectionHistory::HistoryElement> history_stored;
int history_current = 0;
Dictionary custom_state;
uint64_t version = 0;
NodePath live_edit_root;
int history_id = 0;
uint64_t last_checked_version = 0;
};
private:
@ -132,12 +133,13 @@ private:
HashMap<String, Vector<CustomType>> custom_types;
List<PropertyData> clipboard;
UndoRedo undo_redo;
Ref<EditorUndoRedoManager> undo_redo_manager;
Vector<Callable> undo_redo_callbacks;
HashMap<StringName, Callable> move_element_functions;
Vector<EditedScene> edited_scene;
int current_edited_scene;
int current_edited_scene = -1;
int last_created_scene = 1;
bool _find_updated_instances(Node *p_root, Node *p_node, HashSet<String> &checked_paths);
@ -166,7 +168,7 @@ public:
int get_editor_plugin_count() const;
EditorPlugin *get_editor_plugin(int p_idx);
UndoRedo &get_undo_redo();
Ref<EditorUndoRedoManager> &get_undo_redo();
void add_undo_redo_inspector_hook_callback(Callable p_callable); // Callbacks should have this signature: void (Object* undo_redo, Object *modified_object, String property, Variant new_value)
void remove_undo_redo_inspector_hook_callback(Callable p_callable);
const Vector<Callable> get_undo_redo_inspector_hook_callback();
@ -200,7 +202,6 @@ public:
void set_scene_path(int p_idx, const String &p_path);
Ref<Script> get_scene_root_script(int p_idx) const;
void set_edited_scene_version(uint64_t version, int p_scene_idx = -1);
uint64_t get_scene_version(int p_idx) const;
void set_scene_modified_time(int p_idx, uint64_t p_time);
uint64_t get_scene_modified_time(int p_idx) const;
void clear_edited_scenes();
@ -210,6 +211,13 @@ public:
void move_edited_scene_to_index(int p_idx);
bool call_build();
void set_scene_as_saved(int p_idx);
bool is_scene_changed(int p_idx);
int get_scene_history_id_from_path(const String &p_path) const;
int get_current_edited_scene_history_id() const;
int get_scene_history_id(int p_idx) const;
void set_plugin_window_layout(Ref<ConfigFile> p_layout);
void get_plugin_window_layout(Ref<ConfigFile> p_layout);

View file

@ -1701,7 +1701,7 @@ void EditorInspectorArray::_move_element(int p_element_index, int p_to_pos) {
// Call the function.
Callable move_function = EditorNode::get_singleton()->get_editor_data().get_move_array_element_function(object->get_class_name());
if (move_function.is_valid()) {
Variant args[] = { (Object *)undo_redo, object, array_element_prefix, p_element_index, p_to_pos };
Variant args[] = { undo_redo.ptr(), object, array_element_prefix, p_element_index, p_to_pos };
const Variant *args_p[] = { &args[0], &args[1], &args[2], &args[3], &args[4] };
Variant return_value;
Callable::CallError call_error;
@ -1845,7 +1845,7 @@ void EditorInspectorArray::_clear_array() {
// Call the function.
Callable move_function = EditorNode::get_singleton()->get_editor_data().get_move_array_element_function(object->get_class_name());
if (move_function.is_valid()) {
Variant args[] = { (Object *)undo_redo, object, array_element_prefix, i, -1 };
Variant args[] = { undo_redo.ptr(), object, array_element_prefix, i, -1 };
const Variant *args_p[] = { &args[0], &args[1], &args[2], &args[3], &args[4] };
Variant return_value;
Callable::CallError call_error;
@ -1898,7 +1898,7 @@ void EditorInspectorArray::_resize_array(int p_size) {
// Call the function.
Callable move_function = EditorNode::get_singleton()->get_editor_data().get_move_array_element_function(object->get_class_name());
if (move_function.is_valid()) {
Variant args[] = { (Object *)undo_redo, object, array_element_prefix, -1, -1 };
Variant args[] = { undo_redo.ptr(), object, array_element_prefix, -1, -1 };
const Variant *args_p[] = { &args[0], &args[1], &args[2], &args[3], &args[4] };
Variant return_value;
Callable::CallError call_error;
@ -1917,7 +1917,7 @@ void EditorInspectorArray::_resize_array(int p_size) {
// Call the function.
Callable move_function = EditorNode::get_singleton()->get_editor_data().get_move_array_element_function(object->get_class_name());
if (move_function.is_valid()) {
Variant args[] = { (Object *)undo_redo, object, array_element_prefix, i, -1 };
Variant args[] = { undo_redo.ptr(), object, array_element_prefix, i, -1 };
const Variant *args_p[] = { &args[0], &args[1], &args[2], &args[3], &args[4] };
Variant return_value;
Callable::CallError call_error;
@ -2240,7 +2240,7 @@ void EditorInspectorArray::_bind_methods() {
ADD_SIGNAL(MethodInfo("page_change_request"));
}
void EditorInspectorArray::set_undo_redo(UndoRedo *p_undo_redo) {
void EditorInspectorArray::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) {
undo_redo = p_undo_redo;
}
@ -2502,7 +2502,7 @@ Button *EditorInspector::create_inspector_action_button(const String &p_text) {
return button;
}
void EditorInspector::set_undo_redo(UndoRedo *p_undo_redo) {
void EditorInspector::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) {
undo_redo = p_undo_redo;
}
@ -3525,7 +3525,7 @@ void EditorInspector::_edit_set(const String &p_name, const Variant &p_value, bo
}
}
if (!undo_redo || bool(object->call("_dont_undo_redo"))) {
if (!undo_redo.is_valid() || bool(object->call("_dont_undo_redo"))) {
object->set(p_name, p_value);
if (p_refresh_all) {
_edit_request_change(object, "");
@ -3568,7 +3568,7 @@ void EditorInspector::_edit_set(const String &p_name, const Variant &p_value, bo
}
}
Variant v_undo_redo = (Object *)undo_redo;
Variant v_undo_redo = undo_redo;
Variant v_object = object;
Variant v_name = p_name;
for (int i = 0; i < EditorNode::get_singleton()->get_editor_data().get_undo_redo_inspector_hook_callback().size(); i++) {
@ -3744,7 +3744,7 @@ void EditorInspector::_property_pinned(const String &p_path, bool p_pinned) {
Node *node = Object::cast_to<Node>(object);
ERR_FAIL_COND(!node);
if (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);
undo_redo->add_undo_method(node, "_set_property_pinned", p_path, !p_pinned);
@ -4026,7 +4026,6 @@ void EditorInspector::_bind_methods() {
EditorInspector::EditorInspector() {
object = nullptr;
undo_redo = nullptr;
main_vbox = memnew(VBoxContainer);
main_vbox->set_h_size_flags(SIZE_EXPAND_FILL);
main_vbox->add_theme_constant_override("separation", 0);

View file

@ -31,6 +31,7 @@
#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"
@ -42,8 +43,6 @@
#include "scene/gui/spin_box.h"
#include "scene/gui/texture_rect.h"
class UndoRedo;
class EditorPropertyRevert {
public:
static bool get_instantiated_node_original_property(Node *p_node, const StringName &p_prop, Variant &value, bool p_check_class_default = true);
@ -313,7 +312,7 @@ public:
class EditorInspectorArray : public EditorInspectorSection {
GDCLASS(EditorInspectorArray, EditorInspectorSection);
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
enum Mode {
MODE_NONE,
@ -408,7 +407,7 @@ protected:
static void _bind_methods();
public:
void set_undo_redo(UndoRedo *p_undo_redo);
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 = "");
@ -448,7 +447,7 @@ public:
class EditorInspector : public ScrollContainer {
GDCLASS(EditorInspector, ScrollContainer);
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
enum {
MAX_PLUGINS = 1024
};
@ -562,7 +561,7 @@ 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(UndoRedo *p_undo_redo);
void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo);
String get_selected_path() const;

View file

@ -33,6 +33,7 @@
#include "core/config/project_settings.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_undo_redo_manager.h"
#include "scene/gui/check_button.h"
#include "scene/gui/line_edit.h"
#include "scene/gui/option_button.h"

View file

@ -40,7 +40,7 @@ class VBoxContainer;
class LineEdit;
class Tree;
class OptionButton;
class UndoRedo;
class EditorUndoRedoManager;
class EditorLocaleDialog : public ConfirmationDialog {
GDCLASS(EditorLocaleDialog, ConfirmationDialog);
@ -63,7 +63,7 @@ class EditorLocaleDialog : public ConfirmationDialog {
Tree *script_list = nullptr;
Tree *cnt_list = nullptr;
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
bool locale_set = false;
bool updating_lists = false;

View file

@ -224,6 +224,10 @@ void EditorLog::set_tool_button(Button *p_tool_button) {
tool_button = p_tool_button;
}
void EditorLog::register_undo_redo(UndoRedo *p_undo_redo) {
p_undo_redo->set_commit_notify_callback(_undo_redo_cbk, this);
}
void EditorLog::_undo_redo_cbk(void *p_self, const String &p_name) {
EditorLog *self = static_cast<EditorLog *>(p_self);
self->add_message(p_name, EditorLog::MSG_TYPE_EDITOR);
@ -458,8 +462,6 @@ EditorLog::EditorLog() {
add_error_handler(&eh);
current = Thread::get_caller_id();
EditorNode::get_undo_redo()->set_commit_notify_callback(_undo_redo_cbk, this);
}
void EditorLog::deinit() {

View file

@ -41,6 +41,8 @@
#include "scene/gui/texture_button.h"
#include "scene/gui/texture_rect.h"
class UndoRedo;
class EditorLog : public HBoxContainer {
GDCLASS(EditorLog, HBoxContainer);
@ -182,6 +184,7 @@ protected:
public:
void add_message(const String &p_msg, MessageType p_type = MSG_TYPE_STD);
void set_tool_button(Button *p_tool_button);
void register_undo_redo(UndoRedo *p_undo_redo);
void deinit();
void clear();

View file

@ -105,6 +105,7 @@
#include "editor/editor_themes.h"
#include "editor/editor_toaster.h"
#include "editor/editor_translation_parser.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/export/editor_export.h"
#include "editor/export/export_template_manager.h"
#include "editor/export/project_export.h"
@ -349,8 +350,7 @@ void EditorNode::_update_scene_tabs() {
icon = EditorNode::get_singleton()->get_object_icon(type_node, "Node");
}
int current = editor_data.get_edited_scene();
bool unsaved = (i == current) ? saved_version != editor_data.get_undo_redo().get_version() : editor_data.get_scene_version(i) != 0;
bool unsaved = get_undo_redo()->is_history_unsaved(editor_data.get_scene_history_id(i));
scene_tabs->add_tab(disambiguated_scene_names[i] + (unsaved ? "(*)" : ""), icon);
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_GLOBAL_MENU)) {
@ -597,15 +597,15 @@ void EditorNode::_notification(int p_what) {
opening_prev = false;
}
bool unsaved_cache_changed = false;
if (unsaved_cache != (saved_version != editor_data.get_undo_redo().get_version())) {
unsaved_cache = (saved_version != editor_data.get_undo_redo().get_version());
unsaved_cache_changed = true;
bool global_unsaved = get_undo_redo()->is_history_unsaved(EditorUndoRedoManager::GLOBAL_HISTORY);
bool scene_or_global_unsaved = global_unsaved || get_undo_redo()->is_history_unsaved(editor_data.get_current_edited_scene_history_id());
if (unsaved_cache != scene_or_global_unsaved) {
unsaved_cache = scene_or_global_unsaved;
_update_title();
}
if (last_checked_version != editor_data.get_undo_redo().get_version()) {
if (editor_data.is_scene_changed(-1)) {
_update_scene_tabs();
last_checked_version = editor_data.get_undo_redo().get_version();
}
// Update the animation frame of the update spinner.
@ -631,7 +631,7 @@ void EditorNode::_notification(int p_what) {
ResourceImporterTexture::get_singleton()->update_imports();
if (settings_changed || unsaved_cache_changed) {
if (settings_changed) {
_update_title();
}
@ -1127,7 +1127,6 @@ void EditorNode::_reload_modified_scenes() {
}
}
get_undo_redo()->clear_history(false);
set_current_scene(current_idx);
_update_scene_tabs();
disk_changed->hide();
@ -1681,6 +1680,8 @@ int EditorNode::_save_external_resources() {
saved++;
}
get_undo_redo()->set_history_as_saved(EditorUndoRedoManager::GLOBAL_HISTORY);
return saved;
}
@ -1762,11 +1763,7 @@ void EditorNode::_save_scene(String p_file, int idx) {
if (err == OK) {
scene->set_scene_file_path(ProjectSettings::get_singleton()->localize_path(p_file));
if (idx < 0 || idx == editor_data.get_edited_scene()) {
set_current_version(editor_data.get_undo_redo().get_version());
} else {
editor_data.set_edited_scene_version(0, idx);
}
editor_data.set_scene_as_saved(idx);
editor_data.set_scene_modified_time(idx, FileAccess::get_modified_time(p_file));
editor_folding.save_scene_folding(scene, p_file);
@ -1858,12 +1855,9 @@ void EditorNode::_mark_unsaved_scenes() {
}
String path = node->get_scene_file_path();
if (!(path.is_empty() || FileAccess::exists(path))) {
if (i == editor_data.get_edited_scene()) {
set_current_version(-1);
} else {
editor_data.set_edited_scene_version(-1, i);
}
if (!path.is_empty() && !FileAccess::exists(path)) {
// Mark scene tab as unsaved if the file is gone.
get_undo_redo()->set_history_as_unsaved(editor_data.get_scene_history_id(i));
}
}
@ -2721,9 +2715,9 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
if ((int)Input::get_singleton()->get_mouse_button_mask() & 0x7) {
log->add_message(TTR("Can't undo while mouse buttons are pressed."), EditorLog::MSG_TYPE_EDITOR);
} else {
String action = editor_data.get_undo_redo().get_current_action_name();
String action = editor_data.get_undo_redo()->get_current_action_name();
if (!editor_data.get_undo_redo().undo()) {
if (!editor_data.get_undo_redo()->undo()) {
log->add_message(TTR("Nothing to undo."), EditorLog::MSG_TYPE_EDITOR);
} else if (!action.is_empty()) {
log->add_message(vformat(TTR("Undo: %s"), action), EditorLog::MSG_TYPE_EDITOR);
@ -2734,10 +2728,10 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
if ((int)Input::get_singleton()->get_mouse_button_mask() & 0x7) {
log->add_message(TTR("Can't redo while mouse buttons are pressed."), EditorLog::MSG_TYPE_EDITOR);
} else {
if (!editor_data.get_undo_redo().redo()) {
if (!editor_data.get_undo_redo()->redo()) {
log->add_message(TTR("Nothing to redo."), EditorLog::MSG_TYPE_EDITOR);
} else {
String action = editor_data.get_undo_redo().get_current_action_name();
String action = editor_data.get_undo_redo()->get_current_action_name();
log->add_message(vformat(TTR("Redo: %s"), action), EditorLog::MSG_TYPE_EDITOR);
}
}
@ -2772,7 +2766,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
ERR_PRINT("Failed to load scene");
}
editor_data.move_edited_scene_to_index(cur_idx);
get_undo_redo()->clear_history(false);
get_undo_redo()->clear_history(false, editor_data.get_current_edited_scene_history_id());
scene_tabs->set_current_tab(cur_idx);
} break;
@ -3085,8 +3079,7 @@ int EditorNode::_next_unsaved_scene(bool p_valid_filename, int p_start) {
if (!editor_data.get_edited_scene_root(i)) {
continue;
}
int current = editor_data.get_edited_scene();
bool unsaved = (i == current) ? saved_version != editor_data.get_undo_redo().get_version() : editor_data.get_scene_version(i) != 0;
bool unsaved = get_undo_redo()->is_history_unsaved(editor_data.get_scene_history_id(i));
if (unsaved) {
String scene_filename = editor_data.get_edited_scene_root(i)->get_scene_file_path();
if (p_valid_filename && scene_filename.length() == 0) {
@ -3193,9 +3186,9 @@ void EditorNode::_update_file_menu_opened() {
file_menu->set_item_disabled(file_menu->get_item_index(FILE_OPEN_PREV), previous_scenes.is_empty());
const UndoRedo &undo_redo = editor_data.get_undo_redo();
file_menu->set_item_disabled(file_menu->get_item_index(EDIT_UNDO), !undo_redo.has_undo());
file_menu->set_item_disabled(file_menu->get_item_index(EDIT_REDO), !undo_redo.has_redo());
Ref<EditorUndoRedoManager> undo_redo = editor_data.get_undo_redo();
file_menu->set_item_disabled(file_menu->get_item_index(EDIT_UNDO), !undo_redo->has_undo());
file_menu->set_item_disabled(file_menu->get_item_index(EDIT_REDO), !undo_redo->has_redo());
}
void EditorNode::_update_file_menu_closed() {
@ -3451,7 +3444,6 @@ void EditorNode::_remove_edited_scene(bool p_change_tab) {
_scene_tab_changed(new_index);
}
editor_data.remove_scene(old_index);
editor_data.get_undo_redo().clear_history(false);
_update_title();
_update_scene_tabs();
}
@ -3507,7 +3499,6 @@ Dictionary EditorNode::_get_main_scene_state() {
state["main_tab"] = _get_current_main_editor();
state["scene_tree_offset"] = SceneTreeDock::get_singleton()->get_tree_editor()->get_scene_tree()->get_vscroll_bar()->get_value();
state["property_edit_offset"] = InspectorDock::get_inspector_singleton()->get_scroll_offset();
state["saved_version"] = saved_version;
state["node_filter"] = SceneTreeDock::get_singleton()->get_filter();
return state;
}
@ -3567,11 +3558,6 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) {
editor_data.notify_edited_scene_changed();
}
void EditorNode::set_current_version(uint64_t p_version) {
saved_version = p_version;
editor_data.set_edited_scene_version(p_version);
}
bool EditorNode::is_changing_scene() const {
return changing_scene;
}
@ -3591,7 +3577,7 @@ void EditorNode::set_current_scene(int p_idx) {
editor_folding.load_scene_folding(editor_data.get_edited_scene_root(p_idx), editor_data.get_scene_path(p_idx));
}
call_deferred(SNAME("_clear_undo_history"));
get_undo_redo()->clear_history(false, editor_data.get_scene_history_id(p_idx));
}
changing_scene = true;
@ -3608,8 +3594,8 @@ void EditorNode::set_current_scene(int p_idx) {
Node *new_scene = editor_data.get_edited_scene_root();
if (Object::cast_to<Popup>(new_scene)) {
Object::cast_to<Popup>(new_scene)->show();
if (Popup *p = Object::cast_to<Popup>(new_scene)) {
p->show();
}
SceneTreeDock::get_singleton()->set_edited_scene(new_scene);
@ -3627,6 +3613,7 @@ void EditorNode::set_current_scene(int p_idx) {
_edit_current(true);
_update_title();
_update_scene_tabs();
call_deferred(SNAME("_set_main_scene_state"), state, get_edited_scene()); // Do after everything else is done setting up.
}
@ -3785,7 +3772,6 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b
set_edited_scene(new_scene);
_get_scene_metadata(p_scene);
saved_version = editor_data.get_undo_redo().get_version();
_update_title();
_update_scene_tabs();
_add_to_recent_scenes(lpath);
@ -3836,6 +3822,10 @@ void EditorNode::request_instantiate_scenes(const Vector<String> &p_files) {
SceneTreeDock::get_singleton()->instantiate_scenes(p_files);
}
Ref<EditorUndoRedoManager> &EditorNode::get_undo_redo() {
return singleton->editor_data.get_undo_redo();
}
void EditorNode::_inherit_request(String p_file) {
current_menu_option = FILE_NEW_INHERITED_SCENE;
_dialog_action(p_file);
@ -3996,6 +3986,7 @@ void EditorNode::register_editor_types() {
GDREGISTER_CLASS(EditorSpinSlider);
GDREGISTER_CLASS(EditorResourcePicker);
GDREGISTER_CLASS(EditorScriptPicker);
GDREGISTER_ABSTRACT_CLASS(EditorUndoRedoManager);
GDREGISTER_ABSTRACT_CLASS(FileSystemDock);
GDREGISTER_VIRTUAL_CLASS(EditorFileSystemImportFormatSupportQuery);
@ -5128,9 +5119,7 @@ void EditorNode::_scene_tab_closed(int p_tab, int option) {
return;
}
bool unsaved = (p_tab == editor_data.get_edited_scene())
? saved_version != editor_data.get_undo_redo().get_version()
: editor_data.get_scene_version(p_tab) != 0;
bool unsaved = get_undo_redo()->is_history_unsaved(editor_data.get_scene_history_id(p_tab));
if (unsaved) {
save_confirmation->set_ok_button_text(TTR("Save & Close"));
save_confirmation->set_text(vformat(TTR("Save changes to '%s' before closing?"), !scene->get_scene_file_path().is_empty() ? scene->get_scene_file_path() : "unsaved scene"));
@ -5242,23 +5231,10 @@ void EditorNode::_thumbnail_done(const String &p_path, const Ref<Texture2D> &p_p
void EditorNode::_scene_tab_changed(int p_tab) {
tab_preview_panel->hide();
bool unsaved = (saved_version != editor_data.get_undo_redo().get_version());
if (p_tab == editor_data.get_edited_scene()) {
return; // Pointless.
}
uint64_t next_scene_version = editor_data.get_scene_version(p_tab);
editor_data.get_undo_redo().create_action(TTR("Switch Scene Tab"));
editor_data.get_undo_redo().add_do_method(this, "set_current_version", unsaved ? saved_version : 0);
editor_data.get_undo_redo().add_do_method(this, "set_current_scene", p_tab);
editor_data.get_undo_redo().add_do_method(this, "set_current_version", next_scene_version == 0 ? editor_data.get_undo_redo().get_version() + 1 : next_scene_version);
editor_data.get_undo_redo().add_undo_method(this, "set_current_version", next_scene_version);
editor_data.get_undo_redo().add_undo_method(this, "set_current_scene", editor_data.get_edited_scene());
editor_data.get_undo_redo().add_undo_method(this, "set_current_version", saved_version);
editor_data.get_undo_redo().commit_action();
set_current_scene(p_tab);
}
Button *EditorNode::add_bottom_panel_item(String p_text, Control *p_item) {
@ -5644,7 +5620,7 @@ void EditorNode::reload_scene(const String &p_path) {
if (scene_idx == -1) {
if (get_edited_scene()) {
// Scene is not open, so at it might be instantiated. We'll refresh the whole scene later.
editor_data.get_undo_redo().clear_history();
editor_data.get_undo_redo()->clear_history(false, editor_data.get_current_edited_scene_history_id());
}
return;
}
@ -5660,7 +5636,7 @@ void EditorNode::reload_scene(const String &p_path) {
// Adjust index so tab is back a the previous position.
editor_data.move_edited_scene_to_index(scene_idx);
get_undo_redo()->clear_history();
get_undo_redo()->clear_history(false, editor_data.get_scene_history_id(scene_idx));
// Recover the tab.
scene_tabs->set_current_tab(current_tab);
@ -5844,7 +5820,6 @@ void EditorNode::_bind_methods() {
ClassDB::bind_method("stop_child_process", &EditorNode::stop_child_process);
ClassDB::bind_method("set_current_scene", &EditorNode::set_current_scene);
ClassDB::bind_method("set_current_version", &EditorNode::set_current_version);
ClassDB::bind_method("_thumbnail_done", &EditorNode::_thumbnail_done);
ClassDB::bind_method("_set_main_scene_state", &EditorNode::_set_main_scene_state);
ClassDB::bind_method("_update_recent_scenes", &EditorNode::_update_recent_scenes);

View file

@ -72,6 +72,7 @@ class EditorRun;
class EditorRunNative;
class EditorSettingsDialog;
class EditorToaster;
class EditorUndoRedoManager;
class ExportTemplateManager;
class FileDialog;
class FileSystemDock;
@ -471,9 +472,6 @@ private:
String open_navigate;
String run_custom_filename;
uint64_t saved_version = 1;
uint64_t last_checked_version = 0;
DynamicFontImportSettings *fontdata_import_settings = nullptr;
SceneImportSettings *scene_import_settings = nullptr;
AudioStreamImportSettings *audio_stream_import_settings = nullptr;
@ -705,7 +703,7 @@ public:
static EditorLog *get_log() { return singleton->log; }
static EditorData &get_editor_data() { return singleton->editor_data; }
static EditorFolding &get_editor_folding() { return singleton->editor_folding; }
static UndoRedo *get_undo_redo() { return &singleton->editor_data.get_undo_redo(); }
static Ref<EditorUndoRedoManager> &get_undo_redo();
static HBoxContainer *get_menu_hb() { return singleton->menu_hb; }
static VSplitContainer *get_top_split() { return singleton->top_split; }
@ -789,7 +787,6 @@ public:
bool is_scene_open(const String &p_path);
void set_current_version(uint64_t p_version);
void set_current_scene(int p_idx);
void setup_color_picker(ColorPicker *picker);

View file

@ -35,6 +35,7 @@
#include "editor/editor_paths.h"
#include "editor/editor_resource_preview.h"
#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/export/editor_export.h"
#include "editor/filesystem_dock.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
@ -885,7 +886,7 @@ void EditorPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("make_bottom_panel_item_visible", "item"), &EditorPlugin::make_bottom_panel_item_visible);
ClassDB::bind_method(D_METHOD("hide_bottom_panel"), &EditorPlugin::hide_bottom_panel);
ClassDB::bind_method(D_METHOD("get_undo_redo"), &EditorPlugin::_get_undo_redo);
ClassDB::bind_method(D_METHOD("get_undo_redo"), &EditorPlugin::get_undo_redo);
ClassDB::bind_method(D_METHOD("add_undo_redo_inspector_hook_callback", "callable"), &EditorPlugin::add_undo_redo_inspector_hook_callback);
ClassDB::bind_method(D_METHOD("remove_undo_redo_inspector_hook_callback", "callable"), &EditorPlugin::remove_undo_redo_inspector_hook_callback);
ClassDB::bind_method(D_METHOD("queue_save_layout"), &EditorPlugin::queue_save_layout);
@ -965,6 +966,10 @@ void EditorPlugin::_bind_methods() {
BIND_ENUM_CONSTANT(DOCK_SLOT_MAX);
}
Ref<EditorUndoRedoManager> EditorPlugin::get_undo_redo() {
return undo_redo;
}
EditorPluginCreateFunc EditorPlugins::creation_funcs[MAX_CREATE_FUNCS];
int EditorPlugins::creation_func_count = 0;

View file

@ -53,6 +53,7 @@ class EditorImportPlugin;
class EditorExportPlugin;
class EditorNode3DGizmoPlugin;
class EditorResourcePreview;
class EditorUndoRedoManager;
class EditorFileSystem;
class EditorToolAddons;
class EditorPaths;
@ -129,9 +130,7 @@ public:
class EditorPlugin : public Node {
GDCLASS(EditorPlugin, Node);
friend class EditorData;
UndoRedo *undo_redo = nullptr;
UndoRedo *_get_undo_redo() { return undo_redo; }
Ref<EditorUndoRedoManager> undo_redo;
bool input_event_forwarding_always_enabled = false;
bool force_draw_over_forwarding_enabled = false;
@ -144,7 +143,7 @@ protected:
void _notification(int p_what);
static void _bind_methods();
UndoRedo &get_undo_redo() { return *undo_redo; }
Ref<EditorUndoRedoManager> get_undo_redo();
void add_custom_type(const String &p_type, const String &p_base, const Ref<Script> &p_script, const Ref<Texture2D> &p_icon);
void remove_custom_type(const String &p_type);

View file

@ -40,6 +40,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 "scene/gui/margin_container.h"
void EditorSettingsDialog::ok_pressed() {
@ -124,9 +125,9 @@ void EditorSettingsDialog::_notification(int p_what) {
} break;
case NOTIFICATION_READY: {
undo_redo->set_method_notify_callback(EditorDebuggerNode::_method_changeds, nullptr);
undo_redo->set_property_notify_callback(EditorDebuggerNode::_property_changeds, nullptr);
undo_redo->set_commit_notify_callback(_undo_redo_callback, this);
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);
} break;
case NOTIFICATION_ENTER_TREE: {
@ -680,7 +681,7 @@ void EditorSettingsDialog::_bind_methods() {
EditorSettingsDialog::EditorSettingsDialog() {
set_title(TTR("Editor Settings"));
undo_redo = memnew(UndoRedo);
undo_redo = EditorNode::get_undo_redo();
tabs = memnew(TabContainer);
tabs->set_theme_type_variation("TabContainerOdd");
@ -776,5 +777,4 @@ EditorSettingsDialog::EditorSettingsDialog() {
}
EditorSettingsDialog::~EditorSettingsDialog() {
memdelete(undo_redo);
}

View file

@ -40,6 +40,8 @@
#include "scene/gui/tab_container.h"
#include "scene/gui/texture_rect.h"
class EditorUndoRedoManager;
class EditorSettingsDialog : public AcceptDialog {
GDCLASS(EditorSettingsDialog, AcceptDialog);
@ -73,7 +75,7 @@ class EditorSettingsDialog : public AcceptDialog {
Timer *timer = nullptr;
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
virtual void cancel_pressed() override;
virtual void ok_pressed() override;

View file

@ -0,0 +1,442 @@
/*************************************************************************/
/* editor_undo_redo_manager.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 "editor_undo_redo_manager.h"
#include "core/io/resource.h"
#include "core/os/os.h"
#include "core/templates/local_vector.h"
#include "editor/editor_log.h"
#include "editor/editor_node.h"
#include "scene/main/node.h"
EditorUndoRedoManager::History &EditorUndoRedoManager::get_or_create_history(int p_idx) {
if (!history_map.has(p_idx)) {
History history;
history.undo_redo = memnew(UndoRedo);
history.id = p_idx;
history_map[p_idx] = history;
EditorNode::get_singleton()->get_log()->register_undo_redo(history.undo_redo);
EditorDebuggerNode::get_singleton()->register_undo_redo(history.undo_redo);
}
return history_map[p_idx];
}
UndoRedo *EditorUndoRedoManager::get_history_undo_redo(int p_idx) const {
ERR_FAIL_COND_V(!history_map.has(p_idx), nullptr);
return history_map[p_idx].undo_redo;
}
int EditorUndoRedoManager::get_history_id_for_object(Object *p_object) const {
int history_id = INVALID_HISTORY;
if (Node *node = Object::cast_to<Node>(p_object)) {
Node *edited_scene = EditorNode::get_singleton()->get_edited_scene();
if (edited_scene && (node == edited_scene || edited_scene->is_ancestor_of(node))) {
int idx = EditorNode::get_singleton()->get_editor_data().get_current_edited_scene_history_id();
if (idx > 0) {
history_id = idx;
}
}
}
if (Resource *res = Object::cast_to<Resource>(p_object)) {
if (res->is_built_in()) {
if (res->get_path().is_empty()) {
int idx = EditorNode::get_singleton()->get_editor_data().get_current_edited_scene_history_id();
if (idx > 0) {
history_id = idx;
}
} else {
int idx = EditorNode::get_singleton()->get_editor_data().get_scene_history_id_from_path(res->get_path().get_slice("::", 0));
if (idx > 0) {
history_id = idx;
}
}
}
}
if (history_id == INVALID_HISTORY) {
if (pending_action.history_id != INVALID_HISTORY) {
history_id = pending_action.history_id;
} else {
history_id = GLOBAL_HISTORY;
}
}
return history_id;
}
EditorUndoRedoManager::History &EditorUndoRedoManager::get_history_for_object(Object *p_object) {
int history_id = get_history_id_for_object(p_object);
ERR_FAIL_COND_V_MSG(pending_action.history_id != INVALID_HISTORY && history_id != pending_action.history_id, get_or_create_history(pending_action.history_id), vformat("UndoRedo history mismatch: expected %d, got %d.", pending_action.history_id, history_id));
History &history = get_or_create_history(history_id);
if (pending_action.history_id == INVALID_HISTORY) {
pending_action.history_id = history_id;
history.undo_redo->create_action(pending_action.action_name, pending_action.merge_mode);
}
return history;
}
void EditorUndoRedoManager::create_action_for_history(const String &p_name, int p_history_id, UndoRedo::MergeMode p_mode) {
pending_action.action_name = p_name;
pending_action.timestamp = OS::get_singleton()->get_unix_time();
pending_action.merge_mode = p_mode;
if (p_history_id != INVALID_HISTORY) {
pending_action.history_id = p_history_id;
History &history = get_or_create_history(p_history_id);
history.undo_redo->create_action(pending_action.action_name, pending_action.merge_mode);
}
}
void EditorUndoRedoManager::create_action(const String &p_name, UndoRedo::MergeMode p_mode, Object *p_custom_context) {
create_action_for_history(p_name, INVALID_HISTORY, p_mode);
if (p_custom_context) {
// This assigns context to pending action.
get_history_for_object(p_custom_context);
}
}
void EditorUndoRedoManager::add_do_methodp(Object *p_object, const StringName &p_method, const Variant **p_args, int p_argcount) {
UndoRedo *undo_redo = get_history_for_object(p_object).undo_redo;
undo_redo->add_do_methodp(p_object, p_method, p_args, p_argcount);
}
void EditorUndoRedoManager::add_undo_methodp(Object *p_object, const StringName &p_method, const Variant **p_args, int p_argcount) {
UndoRedo *undo_redo = get_history_for_object(p_object).undo_redo;
undo_redo->add_undo_methodp(p_object, p_method, p_args, p_argcount);
}
void EditorUndoRedoManager::_add_do_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
if (p_argcount < 2) {
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 0;
return;
}
if (p_args[0]->get_type() != Variant::OBJECT) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
return;
}
if (p_args[1]->get_type() != Variant::STRING_NAME && p_args[1]->get_type() != Variant::STRING) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 1;
r_error.expected = Variant::STRING_NAME;
return;
}
r_error.error = Callable::CallError::CALL_OK;
Object *object = *p_args[0];
StringName method = *p_args[1];
add_do_methodp(object, method, p_args + 2, p_argcount - 2);
}
void EditorUndoRedoManager::_add_undo_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
if (p_argcount < 2) {
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 0;
return;
}
if (p_args[0]->get_type() != Variant::OBJECT) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
return;
}
if (p_args[1]->get_type() != Variant::STRING_NAME && p_args[1]->get_type() != Variant::STRING) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 1;
r_error.expected = Variant::STRING_NAME;
return;
}
r_error.error = Callable::CallError::CALL_OK;
Object *object = *p_args[0];
StringName method = *p_args[1];
add_undo_methodp(object, method, p_args + 2, p_argcount - 2);
}
void EditorUndoRedoManager::add_do_property(Object *p_object, const StringName &p_property, const Variant &p_value) {
UndoRedo *undo_redo = get_history_for_object(p_object).undo_redo;
undo_redo->add_do_property(p_object, p_property, p_value);
}
void EditorUndoRedoManager::add_undo_property(Object *p_object, const StringName &p_property, const Variant &p_value) {
UndoRedo *undo_redo = get_history_for_object(p_object).undo_redo;
undo_redo->add_undo_property(p_object, p_property, p_value);
}
void EditorUndoRedoManager::add_do_reference(Object *p_object) {
UndoRedo *undo_redo = get_history_for_object(p_object).undo_redo;
undo_redo->add_do_reference(p_object);
}
void EditorUndoRedoManager::add_undo_reference(Object *p_object) {
UndoRedo *undo_redo = get_history_for_object(p_object).undo_redo;
undo_redo->add_undo_reference(p_object);
}
void EditorUndoRedoManager::commit_action(bool p_execute) {
ERR_FAIL_COND(pending_action.history_id == INVALID_HISTORY);
is_committing = true;
History &history = get_or_create_history(pending_action.history_id);
history.undo_redo->commit_action(p_execute);
history.redo_stack.clear();
if (!history.undo_stack.is_empty()) {
const Action &prev_action = history.undo_stack.back()->get();
if (pending_action.merge_mode != UndoRedo::MERGE_DISABLE && pending_action.merge_mode == prev_action.merge_mode && pending_action.action_name == prev_action.action_name) {
// Discard action if it should be merged (UndoRedo handles merging internally).
pending_action = Action();
is_committing = false;
return;
}
}
history.undo_stack.push_back(pending_action);
pending_action = Action();
is_committing = false;
}
bool EditorUndoRedoManager::is_committing_action() const {
return is_committing;
}
bool EditorUndoRedoManager::undo() {
if (!has_undo()) {
return false;
}
History *selected_history = nullptr;
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;
global_timestamp = history.undo_stack.back()->get().timestamp;
}
}
{
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;
}
}
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();
}
return false;
}
bool EditorUndoRedoManager::redo() {
if (!has_redo()) {
return false;
}
History *selected_history = nullptr;
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;
global_timestamp = history.redo_stack.back()->get().timestamp;
}
}
{
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;
}
}
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();
}
return false;
}
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();
}
void EditorUndoRedoManager::set_history_as_unsaved(int p_id) {
History &history = get_or_create_history(p_id);
history.saved_version = -1;
}
bool EditorUndoRedoManager::is_history_unsaved(int p_id) {
History &history = get_or_create_history(p_id);
return history.undo_redo->get_version() != history.saved_version;
}
bool EditorUndoRedoManager::has_undo() {
for (const KeyValue<int, History> &E : history_map) {
if ((E.key == GLOBAL_HISTORY || E.key == EditorNode::get_editor_data().get_current_edited_scene_history_id()) && !E.value.undo_stack.is_empty()) {
return true;
}
}
return false;
}
bool EditorUndoRedoManager::has_redo() {
for (const KeyValue<int, History> &E : history_map) {
if ((E.key == GLOBAL_HISTORY || E.key == EditorNode::get_editor_data().get_current_edited_scene_history_id()) && !E.value.redo_stack.is_empty()) {
return true;
}
}
return false;
}
void EditorUndoRedoManager::clear_history(bool p_increase_version, int p_idx) {
if (p_idx != INVALID_HISTORY) {
get_or_create_history(p_idx).undo_redo->clear_history(p_increase_version);
if (!p_increase_version) {
set_history_as_saved(p_idx);
}
return;
}
for (const KeyValue<int, History> &E : history_map) {
E.value.undo_redo->clear_history(p_increase_version);
set_history_as_saved(E.key);
}
}
String EditorUndoRedoManager::get_current_action_name() {
if (has_undo()) {
History *selected_history = nullptr;
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;
global_timestamp = history.undo_stack.back()->get().timestamp;
}
}
{
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;
}
}
if (selected_history) {
return selected_history->undo_redo->get_current_action_name();
}
}
return "";
}
void EditorUndoRedoManager::discard_history(int p_idx, bool p_erase_from_map) {
ERR_FAIL_COND(!history_map.has(p_idx));
History &history = history_map[p_idx];
if (history.undo_redo) {
memdelete(history.undo_redo);
history.undo_redo = nullptr;
}
if (p_erase_from_map) {
history_map.erase(p_idx);
}
}
void EditorUndoRedoManager::_bind_methods() {
ClassDB::bind_method(D_METHOD("create_action", "name", "merge_mode", "custom_context"), &EditorUndoRedoManager::create_action, DEFVAL(UndoRedo::MERGE_DISABLE), DEFVAL((Object *)nullptr));
ClassDB::bind_method(D_METHOD("commit_action", "execute"), &EditorUndoRedoManager::commit_action, DEFVAL(true));
ClassDB::bind_method(D_METHOD("is_committing_action"), &EditorUndoRedoManager::is_committing_action);
{
MethodInfo mi;
mi.name = "add_do_method";
mi.arguments.push_back(PropertyInfo(Variant::OBJECT, "object"));
mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "method"));
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "add_do_method", &EditorUndoRedoManager::_add_do_method, mi, varray(), false);
}
{
MethodInfo mi;
mi.name = "add_undo_method";
mi.arguments.push_back(PropertyInfo(Variant::OBJECT, "object"));
mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "method"));
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "add_undo_method", &EditorUndoRedoManager::_add_undo_method, mi, varray(), false);
}
ClassDB::bind_method(D_METHOD("add_do_property", "object", "property", "value"), &EditorUndoRedoManager::add_do_property);
ClassDB::bind_method(D_METHOD("add_undo_property", "object", "property", "value"), &EditorUndoRedoManager::add_undo_property);
ClassDB::bind_method(D_METHOD("add_do_reference", "object"), &EditorUndoRedoManager::add_do_reference);
ClassDB::bind_method(D_METHOD("add_undo_reference", "object"), &EditorUndoRedoManager::add_undo_reference);
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);
BIND_ENUM_CONSTANT(GLOBAL_HISTORY);
BIND_ENUM_CONSTANT(INVALID_HISTORY);
}
EditorUndoRedoManager::~EditorUndoRedoManager() {
for (const KeyValue<int, History> &E : history_map) {
discard_history(E.key, false);
}
}

View file

@ -0,0 +1,134 @@
/*************************************************************************/
/* editor_undo_redo_manager.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 EDITOR_UNDO_REDO_MANAGER_H
#define EDITOR_UNDO_REDO_MANAGER_H
#include "core/object/class_db.h"
#include "core/object/ref_counted.h"
#include "core/object/undo_redo.h"
class EditorUndoRedoManager : public RefCounted {
GDCLASS(EditorUndoRedoManager, RefCounted);
public:
enum SpecialHistory {
GLOBAL_HISTORY = 0,
INVALID_HISTORY = -99,
};
private:
struct Action {
int history_id = INVALID_HISTORY;
double timestamp = 0;
String action_name;
UndoRedo::MergeMode merge_mode = UndoRedo::MERGE_DISABLE;
};
struct History {
int id = INVALID_HISTORY;
UndoRedo *undo_redo = nullptr;
uint64_t saved_version = 1;
List<Action> undo_stack;
List<Action> redo_stack;
};
HashMap<int, History> history_map;
Action pending_action;
bool is_committing = false;
protected:
static void _bind_methods();
public:
History &get_or_create_history(int p_idx);
UndoRedo *get_history_undo_redo(int p_idx) const;
int get_history_id_for_object(Object *p_object) const;
History &get_history_for_object(Object *p_object);
void create_action_for_history(const String &p_name, int p_history_id, UndoRedo::MergeMode p_mode = UndoRedo::MERGE_DISABLE);
void create_action(const String &p_name = "", UndoRedo::MergeMode p_mode = UndoRedo::MERGE_DISABLE, Object *p_custom_context = nullptr);
void add_do_methodp(Object *p_object, const StringName &p_method, const Variant **p_args, int p_argcount);
void add_undo_methodp(Object *p_object, const StringName &p_method, const Variant **p_args, int p_argcount);
template <typename... VarArgs>
void add_do_method(Object *p_object, const StringName &p_method, VarArgs... p_args) {
Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
const Variant *argptrs[sizeof...(p_args) + 1];
for (uint32_t i = 0; i < sizeof...(p_args); i++) {
argptrs[i] = &args[i];
}
add_do_methodp(p_object, p_method, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
}
template <typename... VarArgs>
void add_undo_method(Object *p_object, const StringName &p_method, VarArgs... p_args) {
Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
const Variant *argptrs[sizeof...(p_args) + 1];
for (uint32_t i = 0; i < sizeof...(p_args); i++) {
argptrs[i] = &args[i];
}
add_undo_methodp(p_object, p_method, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
}
void _add_do_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
void _add_undo_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
void add_do_property(Object *p_object, const StringName &p_property, const Variant &p_value);
void add_undo_property(Object *p_object, const StringName &p_property, const Variant &p_value);
void add_do_reference(Object *p_object);
void add_undo_reference(Object *p_object);
void commit_action(bool p_execute = true);
bool is_committing_action() const;
bool undo();
bool redo();
void clear_history(bool p_increase_version = true, int p_idx = INVALID_HISTORY);
void set_history_as_saved(int p_idx);
void set_history_as_unsaved(int p_idx);
bool is_history_unsaved(int p_idx);
bool has_undo();
bool has_redo();
String get_current_action_name();
void discard_history(int p_idx, bool p_erase_from_map = true);
~EditorUndoRedoManager();
};
VARIANT_ENUM_CAST(EditorUndoRedoManager::SpecialHistory);
#endif // EDITOR_UNDO_REDO_MANAGER_H

View file

@ -32,6 +32,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/scene_tree_dock.h"
#include "editor/scene_tree_editor.h"
#include "scene/gui/box_container.h"
@ -397,6 +398,10 @@ 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();
@ -696,6 +701,10 @@ 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();

View file

@ -31,7 +31,6 @@
#ifndef GROUPS_EDITOR_H
#define GROUPS_EDITOR_H
#include "core/object/undo_redo.h"
#include "editor/scene_tree_editor.h"
#include "scene/gui/button.h"
#include "scene/gui/dialogs.h"
@ -40,6 +39,8 @@
#include "scene/gui/popup.h"
#include "scene/gui/tree.h"
class EditorUndoRedoManager;
class GroupDialog : public AcceptDialog {
GDCLASS(GroupDialog, AcceptDialog);
@ -68,7 +69,7 @@ class GroupDialog : public AcceptDialog {
String selected_group;
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
void _group_selected();
@ -103,7 +104,7 @@ public:
};
void edit();
void set_undo_redo(UndoRedo *p_undoredo) { undo_redo = p_undoredo; }
void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo);
GroupDialog();
};
@ -119,7 +120,7 @@ class GroupsEditor : public VBoxContainer {
Button *add = nullptr;
Tree *tree = nullptr;
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
void update_tree();
void _add_group(const String &p_group = "");
@ -137,7 +138,7 @@ public:
COPY_GROUP,
};
void set_undo_redo(UndoRedo *p_undoredo) { undo_redo = p_undoredo; }
void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo);
void set_current(Node *p_node);
GroupsEditor();

View file

@ -178,7 +178,8 @@ void InspectorDock::_menu_option_confirm(int p_option, bool p_confirmed) {
}
}
editor_data->get_undo_redo().clear_history();
int history_id = editor_data->get_undo_redo()->get_history_for_object(current).id;
editor_data->get_undo_redo()->clear_history(true, history_id);
EditorNode::get_singleton()->get_editor_plugins_over()->edit(nullptr);
EditorNode::get_singleton()->get_editor_plugins_over()->edit(current);
@ -755,7 +756,7 @@ 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_undo_redo(editor_data->get_undo_redo());
inspector->set_use_filter(true); // TODO: check me

View file

@ -36,6 +36,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_translation_parser.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/filesystem_dock.h"
#include "editor/pot_generator.h"
#include "scene/gui/control.h"

View file

@ -56,7 +56,7 @@ class LocalizationEditor : public VBoxContainer {
EditorFileDialog *pot_file_open_dialog = nullptr;
EditorFileDialog *pot_generate_dialog = nullptr;
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
bool updating_translations = false;
String localization_changed;

View file

@ -32,6 +32,7 @@
#include "core/math/math_fieldwise.h"
#include "editor/editor_node.h"
#include "editor/editor_undo_redo_manager.h"
bool MultiNodeEdit::_set(const StringName &p_name, const Variant &p_value) {
return _set_impl(p_name, p_value, "");
@ -54,7 +55,7 @@ bool MultiNodeEdit::_set_impl(const StringName &p_name, const Variant &p_value,
node_path_target = es->get_node(p_value);
}
UndoRedo *ur = EditorNode::get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("MultiNode Set") + " " + String(name), UndoRedo::MERGE_ENDS);
for (const NodePath &E : nodes) {

View file

@ -117,7 +117,7 @@ NodeDock::NodeDock() {
groups_button->connect("pressed", callable_mp(this, &NodeDock::show_groups));
connections = memnew(ConnectionsDock);
connections->set_undoredo(EditorNode::get_undo_redo());
connections->set_undo_redo(EditorNode::get_undo_redo());
add_child(connections);
connections->set_v_size_flags(SIZE_EXPAND_FILL);
connections->hide();

View file

@ -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"
#include "scene/gui/separator.h"
bool AbstractPolygon2DEditor::Vertex::operator==(const AbstractPolygon2DEditor::Vertex &p_vertex) const {

View file

@ -36,6 +36,7 @@
#include "scene/gui/box_container.h"
class CanvasItemEditor;
class EditorUndoRedoManager;
class AbstractPolygon2DEditor : public HBoxContainer {
GDCLASS(AbstractPolygon2DEditor, HBoxContainer);
@ -99,7 +100,7 @@ protected:
int mode = MODE_EDIT;
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
virtual void _menu_option(int p_option);
void _wip_changed();

View file

@ -35,6 +35,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
#include "scene/animation/animation_blend_tree.h"
StringName AnimationNodeBlendSpace1DEditor::get_blend_position_path() const {

View file

@ -40,6 +40,8 @@
#include "scene/gui/separator.h"
#include "scene/gui/tree.h"
class EditorUndoRedoManager;
class AnimationNodeBlendSpace1DEditor : public AnimationTreeNodeEditorPlugin {
GDCLASS(AnimationNodeBlendSpace1DEditor, AnimationTreeNodeEditorPlugin);
@ -76,7 +78,7 @@ class AnimationNodeBlendSpace1DEditor : public AnimationTreeNodeEditorPlugin {
bool updating = false;
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
static AnimationNodeBlendSpace1DEditor *singleton;

View file

@ -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 "scene/animation/animation_blend_tree.h"
#include "scene/animation/animation_player.h"
#include "scene/gui/menu_button.h"

View file

@ -40,6 +40,8 @@
#include "scene/gui/separator.h"
#include "scene/gui/tree.h"
class EditorUndoRedoManager;
class AnimationNodeBlendSpace2DEditor : public AnimationTreeNodeEditorPlugin {
GDCLASS(AnimationNodeBlendSpace2DEditor, AnimationTreeNodeEditorPlugin);
@ -82,7 +84,7 @@ class AnimationNodeBlendSpace2DEditor : public AnimationTreeNodeEditorPlugin {
bool updating;
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
static AnimationNodeBlendSpace2DEditor *singleton;

View file

@ -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 "scene/animation/animation_player.h"
#include "scene/gui/menu_button.h"
#include "scene/gui/panel.h"

View file

@ -41,6 +41,7 @@
class ProgressBar;
class EditorFileDialog;
class EditorUndoRedoManager;
class AnimationNodeBlendTreeEditor : public AnimationTreeNodeEditorPlugin {
GDCLASS(AnimationNodeBlendTreeEditor, AnimationTreeNodeEditorPlugin);
@ -54,7 +55,7 @@ class AnimationNodeBlendTreeEditor : public AnimationTreeNodeEditorPlugin {
PanelContainer *error_panel = nullptr;
Label *error_label = nullptr;
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
AcceptDialog *filter_dialog = nullptr;
Tree *filters = nullptr;

View file

@ -32,6 +32,7 @@
#include "editor/editor_file_dialog.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_undo_redo_manager.h"
void AnimationLibraryEditor::set_animation_player(Object *p_player) {
player = p_player;
@ -92,7 +93,7 @@ void AnimationLibraryEditor::_add_library_validate(const String &p_name) {
void AnimationLibraryEditor::_add_library_confirm() {
if (adding_animation) {
String anim_name = add_library_name->get_text();
UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo();
Ref<AnimationLibrary> al = player->call("get_animation_library", adding_animation_to_library);
ERR_FAIL_COND(!al.is_valid());
@ -109,7 +110,7 @@ void AnimationLibraryEditor::_add_library_confirm() {
} else {
String lib_name = add_library_name->get_text();
UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo();
Ref<AnimationLibrary> al;
al.instantiate();
@ -203,7 +204,7 @@ void AnimationLibraryEditor::_file_popup_selected(int p_id) {
// TODO: should probably make all foreign animations assigned to this library
// unique too.
UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo->create_action(vformat(TTR("Make Animation Library Unique: %s"), lib_name));
undo_redo->add_do_method(player, "remove_animation_library", lib_name);
undo_redo->add_do_method(player, "add_animation_library", lib_name, ald);
@ -272,7 +273,7 @@ void AnimationLibraryEditor::_file_popup_selected(int p_id) {
Ref<Animation> animd = anim->duplicate();
UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo->create_action(vformat(TTR("Make Animation Unique: %s"), anim_name));
undo_redo->add_do_method(al.ptr(), "remove_animation", anim_name);
undo_redo->add_do_method(al.ptr(), "add_animation", anim_name, animd);
@ -320,7 +321,7 @@ void AnimationLibraryEditor::_load_file(String p_path) {
name = p_path.get_file().get_basename() + " " + itos(attempt);
}
UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo->create_action(vformat(TTR("Add Animation Library: %s"), name));
undo_redo->add_do_method(player, "add_animation_library", name, al);
@ -358,7 +359,7 @@ void AnimationLibraryEditor::_load_file(String p_path) {
name = p_path.get_file().get_basename() + " " + itos(attempt);
}
UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo->create_action(vformat(TTR("Load Animation into Library: %s"), name));
undo_redo->add_do_method(al.ptr(), "add_animation", name, anim);
@ -374,7 +375,7 @@ void AnimationLibraryEditor::_load_file(String p_path) {
EditorNode::get_singleton()->save_resource_in_path(al, p_path);
if (al->get_path() != prev_path) { // Save successful.
UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo->create_action(vformat(TTR("Save Animation library to File: %s"), file_dialog_library));
undo_redo->add_do_method(al.ptr(), "set_path", al->get_path());
@ -395,7 +396,7 @@ void AnimationLibraryEditor::_load_file(String p_path) {
String prev_path = anim->get_path();
EditorNode::get_singleton()->save_resource_in_path(anim, p_path);
if (anim->get_path() != prev_path) { // Save successful.
UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo->create_action(vformat(TTR("Save Animation to File: %s"), file_dialog_animation));
undo_redo->add_do_method(anim.ptr(), "set_path", anim->get_path());
@ -413,7 +414,7 @@ void AnimationLibraryEditor::_item_renamed() {
String text = ti->get_text(0);
String old_text = ti->get_metadata(0);
bool restore_text = false;
UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo();
if (String(text).contains("/") || String(text).contains(":") || String(text).contains(",") || String(text).contains("[")) {
restore_text = true;
@ -527,7 +528,7 @@ void AnimationLibraryEditor::_button_pressed(TreeItem *p_item, int p_column, int
name = base_name + " (" + itos(attempt) + ")";
}
UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo->create_action(vformat(TTR("Add Animation to Library: %s"), name));
undo_redo->add_do_method(al.ptr(), "add_animation", name, anim);
@ -553,7 +554,7 @@ void AnimationLibraryEditor::_button_pressed(TreeItem *p_item, int p_column, int
file_dialog_library = lib_name;
} break;
case LIB_BUTTON_DELETE: {
UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo->create_action(vformat(TTR("Remove Animation Library: %s"), lib_name));
undo_redo->add_do_method(player, "remove_animation_library", lib_name);
undo_redo->add_undo_method(player, "add_animation_library", lib_name, al);
@ -594,7 +595,7 @@ void AnimationLibraryEditor::_button_pressed(TreeItem *p_item, int p_column, int
} break;
case ANIM_BUTTON_DELETE: {
UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo->create_action(vformat(TTR("Remove Animation from Library: %s"), anim_name));
undo_redo->add_do_method(al.ptr(), "remove_animation", anim_name);
undo_redo->add_undo_method(al.ptr(), "add_animation", anim_name, anim);

View file

@ -1045,6 +1045,10 @@ 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.
@ -1925,7 +1929,7 @@ void AnimationPlayerEditorPlugin::_update_keying() {
}
void AnimationPlayerEditorPlugin::edit(Object *p_object) {
anim_editor->set_undo_redo(&get_undo_redo());
anim_editor->set_undo_redo(get_undo_redo());
if (!p_object) {
return;
}

View file

@ -41,6 +41,7 @@
#include "scene/gui/texture_button.h"
#include "scene/gui/tree.h"
class EditorUndoRedoManager;
class AnimationPlayerEditorPlugin;
class AnimationPlayerEditor : public VBoxContainer {
@ -100,7 +101,7 @@ class AnimationPlayerEditor : public VBoxContainer {
LineEdit *name = nullptr;
OptionButton *library = nullptr;
Label *name_title = nullptr;
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
Ref<Texture2D> autoplay_icon;
Ref<Texture2D> reset_icon;
@ -233,7 +234,7 @@ public:
void ensure_visibility();
void set_undo_redo(UndoRedo *p_undo_redo) { undo_redo = p_undo_redo; }
void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo);
void edit(AnimationPlayer *p_player);
void forward_force_draw_over_viewport(Control *p_overlay);

View file

@ -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 "scene/animation/animation_blend_tree.h"
#include "scene/animation/animation_player.h"
#include "scene/gui/menu_button.h"

View file

@ -40,6 +40,7 @@
#include "scene/gui/tree.h"
class EditorFileDialog;
class EditorUndoRedoManager;
class AnimationNodeStateMachineEditor : public AnimationTreeNodeEditorPlugin {
GDCLASS(AnimationNodeStateMachineEditor, AnimationTreeNodeEditorPlugin);
@ -76,7 +77,7 @@ class AnimationNodeStateMachineEditor : public AnimationTreeNodeEditorPlugin {
bool updating = false;
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
static AnimationNodeStateMachineEditor *singleton;

View file

@ -31,6 +31,7 @@
#include "audio_stream_randomizer_editor_plugin.h"
#include "editor/editor_node.h"
#include "editor/editor_undo_redo_manager.h"
void AudioStreamRandomizerEditorPlugin::edit(Object *p_object) {
}
@ -43,8 +44,8 @@ void AudioStreamRandomizerEditorPlugin::make_visible(bool p_visible) {
}
void AudioStreamRandomizerEditorPlugin::_move_stream_array_element(Object *p_undo_redo, Object *p_edited, String p_array_prefix, int p_from_index, int p_to_pos) {
UndoRedo *undo_redo = Object::cast_to<UndoRedo>(p_undo_redo);
ERR_FAIL_COND(!undo_redo);
Ref<EditorUndoRedoManager> undo_redo = Object::cast_to<EditorUndoRedoManager>(p_undo_redo);
ERR_FAIL_COND(undo_redo.is_null());
AudioStreamRandomizer *randomizer = Object::cast_to<AudioStreamRandomizer>(p_edited);
if (!randomizer) {

View file

@ -40,6 +40,7 @@
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
#include "editor/editor_toaster.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/animation_player_editor_plugin.h"
#include "editor/plugins/script_editor_plugin.h"
#include "editor/scene_tree_dock.h"
@ -3988,6 +3989,10 @@ 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) {
@ -5419,7 +5424,7 @@ CanvasItemEditor::CanvasItemEditor() {
CanvasItemEditor *CanvasItemEditor::singleton = nullptr;
void CanvasItemEditorPlugin::edit(Object *p_object) {
canvas_item_editor->set_undo_redo(&get_undo_redo());
canvas_item_editor->set_undo_redo(EditorNode::get_undo_redo());
canvas_item_editor->edit(Object::cast_to<CanvasItem>(p_object));
}
@ -5572,34 +5577,34 @@ void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String &
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);
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);
} 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);
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);
}
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));
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));
}
if (Object::cast_to<TouchScreenButton>(child) || Object::cast_to<TextureButton>(child)) {
editor_data->get_undo_redo().add_do_property(child, "texture_normal", texture);
editor_data->get_undo_redo()->add_do_property(child, "texture_normal", texture);
} else {
editor_data->get_undo_redo().add_do_property(child, "texture", texture);
editor_data->get_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);
editor_data->get_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 = {
@ -5608,7 +5613,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);
editor_data->get_undo_redo()->add_do_property(child, "polygon", list);
}
// Compute the global position
@ -5617,7 +5622,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);
editor_data->get_undo_redo()->add_do_method(child, "set_global_position", target_position);
}
bool CanvasItemEditorViewport::_create_instance(Node *parent, String &path, const Point2 &p_point) {
@ -5642,15 +5647,15 @@ 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);
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);
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));
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));
CanvasItem *instance_ci = Object::cast_to<CanvasItem>(instantiated_scene);
if (instance_ci) {
@ -5664,7 +5669,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);
editor_data->get_undo_redo()->add_do_method(instantiated_scene, "set_position", target_pos);
}
return true;
@ -5682,7 +5687,7 @@ void CanvasItemEditorViewport::_perform_drop_data() {
Vector<String> error_files;
editor_data->get_undo_redo().create_action(TTR("Create Node"));
editor_data->get_undo_redo()->create_action(TTR("Create Node"));
for (int i = 0; i < selected_files.size(); i++) {
String path = selected_files[i];
@ -5713,7 +5718,7 @@ void CanvasItemEditorViewport::_perform_drop_data() {
}
}
editor_data->get_undo_redo().commit_action();
editor_data->get_undo_redo()->commit_action();
if (error_files.size() > 0) {
String files_str;

View file

@ -45,6 +45,7 @@
class EditorData;
class CanvasItemEditorViewport;
class ViewPanner;
class EditorUndoRedoManager;
class CanvasItemEditorSelectedItem : public Object {
GDCLASS(CanvasItemEditorSelectedItem, Object);
@ -400,7 +401,7 @@ private:
void _prepare_grid_menu();
void _on_grid_menu_id_pressed(int p_id);
UndoRedo *undo_redo = nullptr;
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);
@ -547,7 +548,7 @@ public:
Tool get_current_tool() { return tool; }
void set_current_tool(Tool p_tool);
void set_undo_redo(UndoRedo *p_undo_redo) { undo_redo = p_undo_redo; }
void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo);
void edit(CanvasItem *p_canvas_item);
void focus_selection();

View file

@ -32,6 +32,7 @@
#include "canvas_item_editor_plugin.h"
#include "editor/editor_node.h"
#include "editor/editor_undo_redo_manager.h"
#include "scene/2d/ray_cast_2d.h"
#include "scene/2d/shape_cast_2d.h"

View file

@ -35,11 +35,12 @@
#include "scene/2d/node_2d.h"
class CanvasItemEditor;
class EditorUndoRedoManager;
class Cast2DEditor : public Control {
GDCLASS(Cast2DEditor, Control);
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
CanvasItemEditor *canvas_item_editor = nullptr;
Node2D *node;

View file

@ -33,6 +33,7 @@
#include "canvas_item_editor_plugin.h"
#include "core/os/keyboard.h"
#include "editor/editor_node.h"
#include "editor/editor_undo_redo_manager.h"
#include "scene/resources/capsule_shape_2d.h"
#include "scene/resources/circle_shape_2d.h"
#include "scene/resources/concave_polygon_shape_2d.h"

View file

@ -35,6 +35,7 @@
#include "scene/2d/collision_shape_2d.h"
class CanvasItemEditor;
class EditorUndoRedoManager;
class CollisionShape2DEditor : public Control {
GDCLASS(CollisionShape2DEditor, Control);
@ -61,7 +62,7 @@ class CollisionShape2DEditor : public Control {
Point2(1, -1),
};
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
CanvasItemEditor *canvas_item_editor = nullptr;
CollisionShape2D *node = nullptr;

View file

@ -33,6 +33,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"
#include "scene/gui/separator.h"

View file

@ -44,6 +44,8 @@
#include "scene/gui/separator.h"
#include "scene/gui/texture_rect.h"
class EditorUndoRedoManager;
// Inspector controls.
class ControlPositioningWarning : public MarginContainer {
GDCLASS(ControlPositioningWarning, MarginContainer);
@ -203,7 +205,7 @@ public:
class ControlEditorToolbar : public HBoxContainer {
GDCLASS(ControlEditorToolbar, HBoxContainer);
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
EditorSelection *editor_selection = nullptr;
ControlEditorPopupButton *anchors_button = nullptr;

View file

@ -34,6 +34,7 @@
#include "core/io/image_loader.h"
#include "editor/editor_file_dialog.h"
#include "editor/editor_node.h"
#include "editor/editor_undo_redo_manager.h"
#include "scene/2d/cpu_particles_2d.h"
#include "scene/gui/separator.h"
#include "scene/resources/particles_material.h"

View file

@ -39,6 +39,7 @@
class EditorPlugin;
class SpinBox;
class EditorFileDialog;
class EditorUndoRedoManager;
class CPUParticles2DEditorPlugin : public EditorPlugin {
GDCLASS(CPUParticles2DEditorPlugin, EditorPlugin);
@ -70,7 +71,7 @@ class CPUParticles2DEditorPlugin : public EditorPlugin {
String source_emission_file;
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
void _file_selected(const String &p_file);
void _menu_callback(int p_idx);
void _generate_emission_mask();

View file

@ -139,14 +139,14 @@ 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) {
UndoRedo &ur = *EditorNode::get_singleton()->get_undo_redo();
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);
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);
// 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();
ur->commit_action();
_has_undo_data = false;
}
@ -301,13 +301,13 @@ void CurveEditor::on_preset_item_selected(int preset_id) {
break;
}
UndoRedo &ur = *EditorNode::get_singleton()->get_undo_redo();
ur.create_action(TTR("Load Curve Preset"));
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->add_do_method(&curve, "_set_data", curve.get_data());
ur->add_undo_method(&curve, "_set_data", previous_data);
ur.commit_action();
ur->commit_action();
}
void CurveEditor::_curve_changed() {
@ -435,8 +435,8 @@ CurveEditor::TangentIndex CurveEditor::get_tangent_at(Vector2 pos) const {
void CurveEditor::add_point(Vector2 pos) {
ERR_FAIL_COND(_curve_ref.is_null());
UndoRedo &ur = *EditorNode::get_singleton()->get_undo_redo();
ur.create_action(TTR("Remove Curve Point"));
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Remove Curve Point"));
Vector2 point_pos = get_world_pos(pos);
if (point_pos.y < 0.0) {
@ -449,22 +449,22 @@ 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->add_do_method(*_curve_ref, "add_point", point_pos);
ur->add_undo_method(*_curve_ref, "remove_point", i);
ur.commit_action();
ur->commit_action();
}
void CurveEditor::remove_point(int index) {
ERR_FAIL_COND(_curve_ref.is_null());
UndoRedo &ur = *EditorNode::get_singleton()->get_undo_redo();
ur.create_action(TTR("Remove Curve Point"));
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->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);
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);
if (index == _selected_point) {
set_selected_point(-1);
@ -474,14 +474,14 @@ void CurveEditor::remove_point(int index) {
set_hover_point_index(-1);
}
ur.commit_action();
ur->commit_action();
}
void CurveEditor::toggle_linear(TangentIndex tangent) {
ERR_FAIL_COND(_curve_ref.is_null());
UndoRedo &ur = *EditorNode::get_singleton()->get_undo_redo();
ur.create_action(TTR("Toggle Curve Linear Tangent"));
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Toggle Curve Linear Tangent"));
if (tangent == TANGENT_NONE) {
tangent = _selected_tangent;
@ -493,8 +493,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);
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);
} else {
bool is_linear = _curve_ref->get_point_right_mode(_selected_point) == Curve::TANGENT_LINEAR;
@ -502,11 +502,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);
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);
}
ur.commit_action();
ur->commit_action();
}
void CurveEditor::set_selected_point(int index) {

View file

@ -34,6 +34,7 @@
#include "core/io/image_loader.h"
#include "editor/editor_file_dialog.h"
#include "editor/editor_node.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/scene_tree_dock.h"
#include "scene/2d/cpu_particles_2d.h"
#include "scene/gui/separator.h"
@ -111,7 +112,7 @@ void GPUParticles2DEditorPlugin::_menu_callback(int p_idx) {
cpu_particles->set_process_mode(particles->get_process_mode());
cpu_particles->set_z_index(particles->get_z_index());
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action(TTR("Convert to CPUParticles2D"));
ur->add_do_method(SceneTreeDock::get_singleton(), "replace_node", particles, cpu_particles, true, false);
ur->add_do_reference(cpu_particles);

View file

@ -38,6 +38,7 @@
#include "scene/gui/spin_box.h"
class EditorFileDialog;
class EditorUndoRedoManager;
class GPUParticles2DEditorPlugin : public EditorPlugin {
GDCLASS(GPUParticles2DEditorPlugin, EditorPlugin);
@ -75,7 +76,7 @@ class GPUParticles2DEditorPlugin : public EditorPlugin {
String source_emission_file;
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
void _file_selected(const String &p_file);
void _menu_callback(int p_idx);
void _generate_visibility_rect();

View file

@ -32,6 +32,7 @@
#include "core/io/resource_loader.h"
#include "editor/editor_node.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "editor/scene_tree_dock.h"
#include "scene/3d/cpu_particles_3d.h"
@ -271,7 +272,7 @@ void GPUParticles3DEditor::_menu_option(int p_option) {
cpu_particles->set_visible(node->is_visible());
cpu_particles->set_process_mode(node->get_process_mode());
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action(TTR("Convert to CPUParticles3D"));
ur->add_do_method(SceneTreeDock::get_singleton(), "replace_node", node, cpu_particles, true, false);
ur->add_do_reference(cpu_particles);
@ -321,7 +322,7 @@ void GPUParticles3DEditor::_generate_aabb() {
node->set_emitting(false);
}
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action(TTR("Generate Visibility AABB"));
ur->add_do_method(node, "set_visibility_aabb", rect);
ur->add_undo_method(node, "set_visibility_aabb", node->get_visibility_aabb());

View file

@ -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 "node_3d_editor_plugin.h"
Size2 GradientEditor::get_minimum_size() const {
@ -55,7 +56,7 @@ void GradientEditor::_gradient_changed() {
void GradientEditor::_ramp_changed() {
editing = true;
UndoRedo *undo_redo = EditorNode::get_singleton()->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());

View file

@ -32,6 +32,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_undo_redo_manager.h"
#include "scene/gui/box_container.h"
#include "scene/gui/flow_container.h"
#include "scene/gui/separator.h"
@ -175,7 +176,7 @@ void GradientTexture2DEditorRect::_notification(int p_what) {
}
GradientTexture2DEditorRect::GradientTexture2DEditorRect() {
undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo = EditorNode::get_undo_redo();
checkerboard = memnew(TextureRect);
checkerboard->set_stretch_mode(TextureRect::STRETCH_TILE);
@ -222,7 +223,7 @@ void GradientTexture2DEditor::_notification(int p_what) {
}
GradientTexture2DEditor::GradientTexture2DEditor() {
undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo = EditorNode::get_undo_redo();
HFlowContainer *toolbar = memnew(HFlowContainer);
add_child(toolbar);

View file

@ -34,6 +34,8 @@
#include "editor/editor_plugin.h"
#include "editor/editor_spin_slider.h"
class EditorUndoRedoManager;
class GradientTexture2DEditorRect : public Control {
GDCLASS(GradientTexture2DEditorRect, Control);
@ -44,7 +46,7 @@ class GradientTexture2DEditorRect : public Control {
};
Ref<GradientTexture2D> texture;
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
bool snap_enabled = false;
float snap_size = 0;
@ -74,7 +76,7 @@ class GradientTexture2DEditor : public VBoxContainer {
GDCLASS(GradientTexture2DEditor, VBoxContainer);
Ref<GradientTexture2D> texture;
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
Button *reverse_button = nullptr;
Button *snap_button = nullptr;

View file

@ -33,6 +33,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
#include "scene/gui/subviewport_container.h"
#include "scene/resources/fog_material.h"
#include "scene/resources/particles_material.h"
@ -261,10 +262,8 @@ void EditorInspectorPluginMaterial::parse_begin(Object *p_object) {
}
void EditorInspectorPluginMaterial::_undo_redo_inspector_callback(Object *p_undo_redo, Object *p_edited, String p_property, Variant p_new_value) {
UndoRedo *undo_redo = Object::cast_to<UndoRedo>(p_undo_redo);
if (!undo_redo) {
return;
}
Ref<EditorUndoRedoManager> undo_redo = Object::cast_to<EditorUndoRedoManager>(p_undo_redo);
ERR_FAIL_COND(!undo_redo.is_valid());
// For BaseMaterial3D, if a roughness or metallic textures is being assigned to an empty slot,
// set the respective metallic or roughness factor to 1.0 as a convenience feature

View file

@ -32,6 +32,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_undo_redo_manager.h"
#include "node_3d_editor_plugin.h"
#include "scene/3d/collision_shape_3d.h"
#include "scene/3d/navigation_region_3d.h"
@ -60,7 +61,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
switch (p_option) {
case MENU_OPTION_CREATE_STATIC_TRIMESH_BODY: {
EditorSelection *editor_selection = EditorNode::get_singleton()->get_editor_selection();
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_singleton()->get_undo_redo();
List<Node *> selection = editor_selection->get_selected_node_list();
@ -147,7 +148,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
Node *owner = get_tree()->get_edited_scene_root();
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action(TTR("Create Trimesh Static Shape"));
@ -177,7 +178,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
err_dialog->popup_centered();
return;
}
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_singleton()->get_undo_redo();
if (simplify) {
ur->create_action(TTR("Create Simplified Convex Shape"));
@ -217,7 +218,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
err_dialog->popup_centered();
return;
}
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action(TTR("Create Multiple Convex Shapes"));
@ -254,7 +255,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
Node *owner = get_tree()->get_edited_scene_root();
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action(TTR("Create Navigation Mesh"));
ur->add_do_method(node, "add_child", nmi, true);
@ -311,7 +312,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
return;
}
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action(TTR("Unwrap UV2"));
ur->add_do_method(node, "set_mesh", unwrapped_mesh);
@ -470,7 +471,7 @@ void MeshInstance3DEditor::_create_outline_mesh() {
mi->set_mesh(mesho);
Node *owner = get_tree()->get_edited_scene_root();
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action(TTR("Create Outline"));

View file

@ -35,6 +35,7 @@
#include "core/math/geometry_3d.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "scene/3d/audio_listener_3d.h"
#include "scene/3d/audio_stream_player_3d.h"
@ -1347,13 +1348,13 @@ void Light3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_i
light->set_param(p_id == 0 ? Light3D::PARAM_RANGE : Light3D::PARAM_SPOT_ANGLE, p_restore);
} else if (p_id == 0) {
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Change Light Radius"));
ur->add_do_method(light, "set_param", Light3D::PARAM_RANGE, light->get_param(Light3D::PARAM_RANGE));
ur->add_undo_method(light, "set_param", Light3D::PARAM_RANGE, p_restore);
ur->commit_action();
} else if (p_id == 1) {
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Change Light Radius"));
ur->add_do_method(light, "set_param", Light3D::PARAM_SPOT_ANGLE, light->get_param(Light3D::PARAM_SPOT_ANGLE));
ur->add_undo_method(light, "set_param", Light3D::PARAM_SPOT_ANGLE, p_restore);
@ -1571,7 +1572,7 @@ void AudioStreamPlayer3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gi
player->set_emission_angle(p_restore);
} else {
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Change AudioStreamPlayer3D Emission Angle"));
ur->add_do_method(player, "set_emission_angle", player->get_emission_angle());
ur->add_undo_method(player, "set_emission_angle", p_restore);
@ -1814,7 +1815,7 @@ void Camera3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_
if (p_cancel) {
camera->set("fov", p_restore);
} else {
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Change Camera FOV"));
ur->add_do_property(camera, "fov", camera->get_fov());
ur->add_undo_property(camera, "fov", p_restore);
@ -1825,7 +1826,7 @@ void Camera3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_
if (p_cancel) {
camera->set("size", p_restore);
} else {
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Change Camera Size"));
ur->add_do_property(camera, "size", camera->get_size());
ur->add_undo_property(camera, "size", p_restore);
@ -2141,7 +2142,7 @@ void OccluderInstance3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_giz
return;
}
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Change Sphere Shape Radius"));
ur->add_do_method(so.ptr(), "set_radius", so->get_radius());
ur->add_undo_method(so.ptr(), "set_radius", p_restore);
@ -2155,7 +2156,7 @@ void OccluderInstance3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_giz
return;
}
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Change Box Shape Size"));
ur->add_do_method(bo.ptr(), "set_size", bo->get_size());
ur->add_undo_method(bo.ptr(), "set_size", p_restore);
@ -2169,7 +2170,7 @@ void OccluderInstance3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_giz
return;
}
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Change Box Shape Size"));
ur->add_do_method(qo.ptr(), "set_size", qo->get_size());
ur->add_undo_method(qo.ptr(), "set_size", p_restore);
@ -2870,7 +2871,7 @@ void VisibleOnScreenNotifier3DGizmoPlugin::commit_handle(const EditorNode3DGizmo
return;
}
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Change Notifier AABB"));
ur->add_do_method(notifier, "set_aabb", notifier->get_aabb());
ur->add_undo_method(notifier, "set_aabb", p_restore);
@ -3061,7 +3062,7 @@ void GPUParticles3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo,
return;
}
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Change Particles AABB"));
ur->add_do_method(particles, "set_visibility_aabb", particles->get_visibility_aabb());
ur->add_undo_method(particles, "set_visibility_aabb", p_restore);
@ -3227,7 +3228,7 @@ void GPUParticlesCollision3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *
return;
}
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Change Radius"));
ur->add_do_method(sn, "set_radius", sn->call("get_radius"));
ur->add_undo_method(sn, "set_radius", p_restore);
@ -3240,7 +3241,7 @@ void GPUParticlesCollision3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *
return;
}
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Change Box Shape Extents"));
ur->add_do_method(sn, "set_extents", sn->call("get_extents"));
ur->add_undo_method(sn, "set_extents", p_restore);
@ -3499,7 +3500,7 @@ void ReflectionProbeGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo,
return;
}
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Change Probe Extents"));
ur->add_do_method(probe, "set_extents", probe->get_extents());
ur->add_do_method(probe, "set_origin_offset", probe->get_origin_offset());
@ -3651,7 +3652,7 @@ void DecalGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id,
return;
}
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Change Decal Extents"));
ur->add_do_method(decal, "set_extents", decal->get_extents());
ur->add_undo_method(decal, "set_extents", restore);
@ -3791,7 +3792,7 @@ void VoxelGIGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_i
return;
}
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Change Probe Extents"));
ur->add_do_method(probe, "set_extents", probe->get_extents());
ur->add_undo_method(probe, "set_extents", restore);
@ -4406,7 +4407,7 @@ void CollisionShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo
return;
}
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Change Sphere Shape Radius"));
ur->add_do_method(ss.ptr(), "set_radius", ss->get_radius());
ur->add_undo_method(ss.ptr(), "set_radius", p_restore);
@ -4420,7 +4421,7 @@ void CollisionShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo
return;
}
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Change Box Shape Size"));
ur->add_do_method(ss.ptr(), "set_size", ss->get_size());
ur->add_undo_method(ss.ptr(), "set_size", p_restore);
@ -4437,7 +4438,7 @@ void CollisionShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo
return;
}
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
if (p_id == 0) {
ur->create_action(TTR("Change Capsule Shape Radius"));
ur->add_do_method(ss.ptr(), "set_radius", ss->get_radius());
@ -4462,7 +4463,7 @@ void CollisionShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo
return;
}
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
if (p_id == 0) {
ur->create_action(TTR("Change Cylinder Shape Radius"));
ur->add_do_method(ss.ptr(), "set_radius", ss->get_radius());
@ -4487,7 +4488,7 @@ void CollisionShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo
return;
}
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Change Separation Ray Shape Length"));
ur->add_do_method(ss.ptr(), "set_length", ss->get_length());
ur->add_undo_method(ss.ptr(), "set_length", p_restore);
@ -5745,7 +5746,7 @@ void FogVolumeGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p
return;
}
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Change Fog Volume Extents"));
ur->add_do_method(sn, "set_extents", sn->call("get_extents"));
ur->add_undo_method(sn, "set_extents", p_restore);

View file

@ -4003,15 +4003,15 @@ 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);
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);
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));
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));
Node3D *node3d = Object::cast_to<Node3D>(instantiated_scene);
if (node3d) {
@ -4024,7 +4024,7 @@ bool Node3DEditorViewport::_create_instance(Node *parent, String &path, const Po
global_transform.origin = spatial_editor->snap_point(_get_instance_position(p_point));
global_transform.basis *= node3d->get_transform().basis;
editor_data->get_undo_redo().add_do_method(instantiated_scene, "set_global_transform", global_transform);
editor_data->get_undo_redo()->add_do_method(instantiated_scene, "set_global_transform", global_transform);
}
return true;
@ -4035,15 +4035,15 @@ void Node3DEditorViewport::_perform_drop_data() {
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();
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();
} 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();
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();
}
_remove_preview_material();
@ -4054,7 +4054,7 @@ void Node3DEditorViewport::_perform_drop_data() {
Vector<String> error_files;
editor_data->get_undo_redo().create_action(TTR("Create Node"));
editor_data->get_undo_redo()->create_action(TTR("Create Node"));
for (int i = 0; i < selected_files.size(); i++) {
String path = selected_files[i];
@ -4072,7 +4072,7 @@ void Node3DEditorViewport::_perform_drop_data() {
}
}
editor_data->get_undo_redo().commit_action();
editor_data->get_undo_redo()->commit_action();
if (error_files.size() > 0) {
String files_str;
@ -7247,6 +7247,14 @@ 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);
}

View file

@ -53,6 +53,7 @@ class Node3DEditorViewport;
class SubViewportContainer;
class DirectionalLight3D;
class WorldEnvironment;
class EditorUndoRedoManager;
class ViewportRotationControl : public Control {
GDCLASS(ViewportRotationControl, Control);
@ -201,7 +202,7 @@ private:
EditorData *editor_data = nullptr;
EditorSelection *editor_selection = nullptr;
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
CheckBox *preview_camera = nullptr;
SubViewportContainer *subviewport_container = nullptr;
@ -682,7 +683,7 @@ private:
HBoxContainer *context_menu_hbox = nullptr;
void _generate_selection_boxes();
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
int camera_override_viewport_id;
@ -820,13 +821,13 @@ public:
void select_gizmo_highlight_axis(int p_axis);
void set_custom_camera(Node *p_camera) { custom_camera = p_camera; }
void set_undo_redo(UndoRedo *p_undo_redo) { undo_redo = p_undo_redo; }
Dictionary get_state() const;
void set_state(const Dictionary &p_state);
Ref<Environment> get_viewport_environment() { return viewport_environment; }
UndoRedo *get_undo_redo() { return undo_redo; }
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);

View file

@ -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 Path2DEditor::_notification(int p_what) {
switch (p_what) {

View file

@ -36,11 +36,12 @@
#include "scene/gui/separator.h"
class CanvasItemEditor;
class EditorUndoRedoManager;
class Path2DEditor : public HBoxContainer {
GDCLASS(Path2DEditor, HBoxContainer);
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
CanvasItemEditor *canvas_item_editor = nullptr;
Panel *panel = nullptr;

View file

@ -35,6 +35,7 @@
#include "core/os/keyboard.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
#include "node_3d_editor_plugin.h"
#include "scene/resources/curve.h"
@ -172,7 +173,7 @@ void Path3DGizmo::commit_handle(int p_id, bool p_secondary, const Variant &p_res
return;
}
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
if (!p_secondary) {
if (p_cancel) {
@ -385,7 +386,7 @@ EditorPlugin::AfterGUIInput Path3DEditorPlugin::forward_spatial_gui_input(Camera
}
}
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
if (closest_seg != -1) {
//subdivide
@ -427,21 +428,21 @@ EditorPlugin::AfterGUIInput Path3DEditorPlugin::forward_spatial_gui_input(Camera
// Find the offset and point index of the place to break up.
// Also check for the control points.
if (dist_to_p < click_dist) {
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Remove Path Point"));
ur->add_do_method(c.ptr(), "remove_point", i);
ur->add_undo_method(c.ptr(), "add_point", c->get_point_position(i), c->get_point_in(i), c->get_point_out(i), i);
ur->commit_action();
return EditorPlugin::AFTER_GUI_INPUT_STOP;
} else if (dist_to_p_out < click_dist) {
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Remove Out-Control Point"));
ur->add_do_method(c.ptr(), "set_point_out", i, Vector3());
ur->add_undo_method(c.ptr(), "set_point_out", i, c->get_point_out(i));
ur->commit_action();
return EditorPlugin::AFTER_GUI_INPUT_STOP;
} else if (dist_to_p_in < click_dist) {
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Remove In-Control Point"));
ur->add_do_method(c.ptr(), "set_point_in", i, Vector3());
ur->add_undo_method(c.ptr(), "set_point_in", i, c->get_point_in(i));
@ -520,7 +521,7 @@ void Path3DEditorPlugin::_close_curve() {
if (c->get_point_position(0) == c->get_point_position(c->get_point_count() - 1)) {
return;
}
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Close Curve"));
ur->add_do_method(c.ptr(), "add_point", c->get_point_position(0), c->get_point_in(0), c->get_point_out(0), -1);
ur->add_undo_method(c.ptr(), "remove_point", c->get_point_count());

View file

@ -38,6 +38,7 @@
#include "core/os/keyboard.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
#include "editor/editor_undo_redo_manager.h"
#include "node_3d_editor_plugin.h"
#include "scene/3d/camera_3d.h"

View file

@ -37,11 +37,12 @@
#include "scene/resources/immediate_mesh.h"
class CanvasItemEditor;
class EditorUndoRedoManager;
class Polygon3DEditor : public HBoxContainer {
GDCLASS(Polygon3DEditor, HBoxContainer);
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
enum Mode {
MODE_CREATE,
MODE_EDIT,

View file

@ -234,6 +234,10 @@ void ResourcePreloaderEditor::_cell_button_pressed(Object *p_item, int p_column,
}
}
void ResourcePreloaderEditor::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) {
undo_redo = p_undo_redo;
}
void ResourcePreloaderEditor::edit(ResourcePreloader *p_preloader) {
preloader = p_preloader;
@ -387,7 +391,7 @@ ResourcePreloaderEditor::ResourcePreloaderEditor() {
}
void ResourcePreloaderEditorPlugin::edit(Object *p_object) {
preloader_editor->set_undo_redo(&get_undo_redo());
preloader_editor->set_undo_redo(EditorNode::get_undo_redo());
ResourcePreloader *s = Object::cast_to<ResourcePreloader>(p_object);
if (!s) {
return;

View file

@ -37,6 +37,7 @@
#include "scene/main/resource_preloader.h"
class EditorFileDialog;
class EditorUndoRedoManager;
class ResourcePreloaderEditor : public PanelContainer {
GDCLASS(ResourcePreloaderEditor, PanelContainer);
@ -66,7 +67,7 @@ class ResourcePreloaderEditor : public PanelContainer {
void _cell_button_pressed(Object *p_item, int p_column, int p_id, MouseButton p_button);
void _item_edited();
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
Variant get_drag_data_fw(const Point2 &p_point, Control *p_from);
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
@ -78,7 +79,7 @@ protected:
static void _bind_methods();
public:
void set_undo_redo(UndoRedo *p_undo_redo) { undo_redo = p_undo_redo; }
void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo);
void edit(ResourcePreloader *p_preloader);
ResourcePreloaderEditor();

View file

@ -1408,8 +1408,6 @@ void ScriptEditor::_menu_option(int p_option) {
es->set_editor(EditorNode::get_singleton());
es->_run();
EditorNode::get_undo_redo()->clear_history();
} break;
case FILE_CLOSE: {
if (current->is_unsaved()) {

View file

@ -32,6 +32,7 @@
#include "canvas_item_editor_plugin.h"
#include "editor/editor_node.h"
#include "editor/editor_undo_redo_manager.h"
#include "scene/2d/mesh_instance_2d.h"
#include "scene/gui/box_container.h"
#include "thirdparty/misc/clipper.hpp"
@ -59,7 +60,7 @@ void Skeleton2DEditor::_menu_option(int p_option) {
err_dialog->popup_centered();
return;
}
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Set Rest Pose to Bones"));
for (int i = 0; i < node->get_bone_count(); i++) {
Bone2D *bone = node->get_bone(i);
@ -75,7 +76,7 @@ void Skeleton2DEditor::_menu_option(int p_option) {
err_dialog->popup_centered();
return;
}
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Create Rest Pose from Bones"));
for (int i = 0; i < node->get_bone_count(); i++) {
Bone2D *bone = node->get_bone(i);

View file

@ -35,6 +35,7 @@
#include "editor/editor_node.h"
#include "editor/editor_properties.h"
#include "editor/editor_scale.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/animation_player_editor_plugin.h"
#include "node_3d_editor_plugin.h"
#include "scene/3d/collision_shape_3d.h"
@ -267,7 +268,7 @@ void Skeleton3DEditor::reset_pose(const bool p_all_bones) {
return;
}
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Set Bone Transform"), UndoRedo::MERGE_ENDS);
if (p_all_bones) {
for (int i = 0; i < bone_len; i++) {
@ -334,7 +335,7 @@ void Skeleton3DEditor::pose_to_rest(const bool p_all_bones) {
return;
}
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Set Bone Rest"), UndoRedo::MERGE_ENDS);
if (p_all_bones) {
for (int i = 0; i < bone_len; i++) {
@ -354,7 +355,7 @@ void Skeleton3DEditor::pose_to_rest(const bool p_all_bones) {
}
void Skeleton3DEditor::create_physical_skeleton() {
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ERR_FAIL_COND(!get_tree());
Node *owner = get_tree()->get_edited_scene_root();
@ -587,7 +588,7 @@ void Skeleton3DEditor::move_skeleton_bone(NodePath p_skeleton_path, int32_t p_se
Node *node = get_node_or_null(p_skeleton_path);
Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(node);
ERR_FAIL_NULL(skeleton);
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Set Bone Parentage"));
// If the target is a child of ourselves, we move only *us* and not our children.
if (skeleton->is_bone_parent_of(p_target_boneidx, p_selected_boneidx)) {
@ -1309,7 +1310,7 @@ void Skeleton3DGizmoPlugin::commit_subgizmos(const EditorNode3DGizmo *p_gizmo, c
Skeleton3DEditor *se = Skeleton3DEditor::get_singleton();
Node3DEditor *ne = Node3DEditor::get_singleton();
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Set Bone Transform"));
if (ne->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || ne->get_tool_mode() == Node3DEditor::TOOL_MODE_MOVE) {
for (int i = 0; i < p_ids.size(); i++) {

View file

@ -40,6 +40,7 @@
#include "scene/resources/immediate_mesh.h"
class EditorInspectorPluginSkeleton;
class EditorUndoRedoManager;
class Joint;
class PhysicalBone3D;
class Skeleton3DEditorPlugin;
@ -63,7 +64,7 @@ class BoneTransformEditor : public VBoxContainer {
Skeleton3D *skeleton = nullptr;
// String property;
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
bool toggle_enabled = false;
bool updating = false;

View file

@ -34,6 +34,7 @@
#include "core/math/geometry_2d.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/scene_tree_dock.h"
#include "scene/2d/collision_polygon_2d.h"
#include "scene/2d/light_occluder_2d.h"
@ -342,7 +343,7 @@ void Sprite2DEditor::_convert_to_mesh_2d_node() {
MeshInstance2D *mesh_instance = memnew(MeshInstance2D);
mesh_instance->set_mesh(mesh);
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Convert to MeshInstance2D"));
ur->add_do_method(SceneTreeDock::get_singleton(), "replace_node", node, mesh_instance, true, false);
ur->add_do_reference(mesh_instance);
@ -400,7 +401,7 @@ void Sprite2DEditor::_convert_to_polygon_2d_node() {
polygon_2d_instance->set_polygon(polygon);
polygon_2d_instance->set_polygons(polys);
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Convert to Polygon2D"));
ur->add_do_method(SceneTreeDock::get_singleton(), "replace_node", node, polygon_2d_instance, true, false);
ur->add_do_reference(polygon_2d_instance);
@ -422,7 +423,7 @@ void Sprite2DEditor::_create_collision_polygon_2d_node() {
CollisionPolygon2D *collision_polygon_2d_instance = memnew(CollisionPolygon2D);
collision_polygon_2d_instance->set_polygon(outline);
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Create CollisionPolygon2D Sibling"));
ur->add_do_method(this, "_add_as_sibling_or_child", node, collision_polygon_2d_instance);
ur->add_do_reference(collision_polygon_2d_instance);
@ -455,7 +456,7 @@ void Sprite2DEditor::_create_light_occluder_2d_node() {
LightOccluder2D *light_occluder_2d_instance = memnew(LightOccluder2D);
light_occluder_2d_instance->set_occluder_polygon(polygon);
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Create LightOccluder2D Sibling"));
ur->add_do_method(this, "_add_as_sibling_or_child", node, light_occluder_2d_instance);
ur->add_do_reference(light_occluder_2d_instance);

View file

@ -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"
#include "editor/scene_tree_dock.h"
#include "scene/3d/sprite_3d.h"
#include "scene/gui/center_container.h"
@ -1010,6 +1011,10 @@ void SpriteFramesEditor::edit(SpriteFrames *p_frames) {
}
}
void SpriteFramesEditor::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) {
undo_redo = p_undo_redo;
}
Variant SpriteFramesEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
if (!frames->has_animation(edited_anim)) {
return false;
@ -1471,7 +1476,7 @@ SpriteFramesEditor::SpriteFramesEditor() {
}
void SpriteFramesEditorPlugin::edit(Object *p_object) {
frames_editor->set_undo_redo(&get_undo_redo());
frames_editor->set_undo_redo(get_undo_redo());
SpriteFrames *s;
AnimatedSprite2D *animated_sprite = Object::cast_to<AnimatedSprite2D>(p_object);

View file

@ -45,6 +45,7 @@
#include "scene/gui/tree.h"
class EditorFileDialog;
class EditorUndoRedoManager;
class SpriteFramesEditor : public HSplitContainer {
GDCLASS(SpriteFramesEditor, HSplitContainer);
@ -151,7 +152,7 @@ class SpriteFramesEditor : public HSplitContainer {
bool updating;
bool updating_split_settings = false; // Skip SpinBox/Range callback when setting value by code.
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
Variant get_drag_data_fw(const Point2 &p_point, Control *p_from);
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
@ -176,7 +177,7 @@ protected:
static void _bind_methods();
public:
void set_undo_redo(UndoRedo *p_undo_redo) { undo_redo = p_undo_redo; }
void set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo);
void edit(SpriteFrames *p_frames);
SpriteFramesEditor();

View file

@ -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"
#include "scene/gui/check_box.h"
#include "scene/gui/separator.h"
#include "scene/gui/view_panner.h"

View file

@ -40,6 +40,7 @@
#include "scene/resources/texture.h"
class ViewPanner;
class EditorUndoRedoManager;
class TextureRegionEditor : public AcceptDialog {
GDCLASS(TextureRegionEditor, AcceptDialog);
@ -68,7 +69,7 @@ class TextureRegionEditor : public AcceptDialog {
VScrollBar *vscroll = nullptr;
HScrollBar *hscroll = nullptr;
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
Vector2 draw_ofs;
float draw_zoom = 0.0;

View file

@ -35,6 +35,7 @@
#include "editor/editor_node.h"
#include "editor/editor_resource_picker.h"
#include "editor/editor_scale.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/progress_dialog.h"
#include "scene/gui/color_picker.h"
@ -796,7 +797,7 @@ void ThemeItemImportTree::_import_selected() {
ProgressDialog::get_singleton()->end_task("import_theme_items");
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Import Theme Items"));
ur->add_do_method(*edited_theme, "clear");
@ -1494,7 +1495,7 @@ void ThemeItemEditorDialog::_item_tree_button_pressed(Object *p_item, int p_colu
String item_name = item->get_text(0);
int data_type = item->get_parent()->get_metadata(0);
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Remove Theme Item"));
ur->add_do_method(*edited_theme, "clear_theme_item", (Theme::DataType)data_type, item_name, edited_item_type);
ur->add_undo_method(*edited_theme, "set_theme_item", (Theme::DataType)data_type, item_name, edited_item_type, edited_theme->get_theme_item((Theme::DataType)data_type, item_name, edited_item_type));
@ -1513,7 +1514,7 @@ void ThemeItemEditorDialog::_add_theme_type(const String &p_new_text) {
const String new_type = edit_add_type_value->get_text().strip_edges();
edit_add_type_value->clear();
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Add Theme Type"));
ur->add_do_method(*edited_theme, "add_type", new_type);
@ -1525,7 +1526,7 @@ void ThemeItemEditorDialog::_add_theme_type(const String &p_new_text) {
}
void ThemeItemEditorDialog::_add_theme_item(Theme::DataType p_data_type, String p_item_name, String p_item_type) {
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Create Theme Item"));
switch (p_data_type) {
@ -1570,7 +1571,7 @@ void ThemeItemEditorDialog::_remove_theme_type(const String &p_theme_type) {
Ref<Theme> old_snapshot = edited_theme->duplicate();
Ref<Theme> new_snapshot = edited_theme->duplicate();
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Remove Theme Type"));
new_snapshot->remove_type(p_theme_type);
@ -1593,7 +1594,7 @@ void ThemeItemEditorDialog::_remove_data_type_items(Theme::DataType p_data_type,
Ref<Theme> old_snapshot = edited_theme->duplicate();
Ref<Theme> new_snapshot = edited_theme->duplicate();
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Remove Data Type Items From Theme"));
new_snapshot->get_theme_item_list(p_data_type, p_item_type, &names);
@ -1622,7 +1623,7 @@ void ThemeItemEditorDialog::_remove_class_items() {
Ref<Theme> old_snapshot = edited_theme->duplicate();
Ref<Theme> new_snapshot = edited_theme->duplicate();
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Remove Class Items From Theme"));
for (int dt = 0; dt < Theme::DATA_TYPE_MAX; dt++) {
@ -1658,7 +1659,7 @@ void ThemeItemEditorDialog::_remove_custom_items() {
Ref<Theme> old_snapshot = edited_theme->duplicate();
Ref<Theme> new_snapshot = edited_theme->duplicate();
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Remove Custom Items From Theme"));
for (int dt = 0; dt < Theme::DATA_TYPE_MAX; dt++) {
@ -1694,7 +1695,7 @@ void ThemeItemEditorDialog::_remove_all_items() {
Ref<Theme> old_snapshot = edited_theme->duplicate();
Ref<Theme> new_snapshot = edited_theme->duplicate();
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Remove All Items From Theme"));
for (int dt = 0; dt < Theme::DATA_TYPE_MAX; dt++) {
@ -1798,7 +1799,7 @@ void ThemeItemEditorDialog::_confirm_edit_theme_item() {
if (item_popup_mode == CREATE_THEME_ITEM) {
_add_theme_item(edit_item_data_type, theme_item_name->get_text(), edited_item_type);
} else if (item_popup_mode == RENAME_THEME_ITEM) {
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Rename Theme Item"));
ur->add_do_method(*edited_theme, "rename_theme_item", edit_item_data_type, edit_item_old_name, theme_item_name->get_text(), edited_item_type);
@ -2824,7 +2825,7 @@ void ThemeTypeEditor::_add_default_type_items() {
updating = false;
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Override All Default Theme Items"));
ur->add_do_method(*edited_theme, "merge_with", new_snapshot);
@ -2844,7 +2845,7 @@ void ThemeTypeEditor::_item_add_cbk(int p_data_type, Control *p_control) {
}
String item_name = le->get_text().strip_edges();
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Add Theme Item"));
switch (p_data_type) {
@ -2889,7 +2890,7 @@ void ThemeTypeEditor::_item_add_lineedit_cbk(String p_value, int p_data_type, Co
}
void ThemeTypeEditor::_item_override_cbk(int p_data_type, String p_item_name) {
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Override Theme Item"));
switch (p_data_type) {
@ -2928,7 +2929,7 @@ void ThemeTypeEditor::_item_override_cbk(int p_data_type, String p_item_name) {
}
void ThemeTypeEditor::_item_remove_cbk(int p_data_type, String p_item_name) {
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Remove Theme Item"));
switch (p_data_type) {
@ -3002,7 +3003,7 @@ void ThemeTypeEditor::_item_rename_confirmed(int p_data_type, String p_item_name
return;
}
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Rename Theme Item"));
switch (p_data_type) {
@ -3058,7 +3059,7 @@ void ThemeTypeEditor::_item_rename_canceled(int p_data_type, String p_item_name,
}
void ThemeTypeEditor::_color_item_changed(Color p_value, String p_item_name) {
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Set Color Item in Theme"), UndoRedo::MERGE_ENDS);
ur->add_do_method(*edited_theme, "set_color", p_item_name, edited_type, p_value);
ur->add_undo_method(*edited_theme, "set_color", p_item_name, edited_type, edited_theme->get_color(p_item_name, edited_type));
@ -3066,7 +3067,7 @@ void ThemeTypeEditor::_color_item_changed(Color p_value, String p_item_name) {
}
void ThemeTypeEditor::_constant_item_changed(float p_value, String p_item_name) {
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Set Constant Item in Theme"));
ur->add_do_method(*edited_theme, "set_constant", p_item_name, edited_type, p_value);
ur->add_undo_method(*edited_theme, "set_constant", p_item_name, edited_type, edited_theme->get_constant(p_item_name, edited_type));
@ -3074,7 +3075,7 @@ void ThemeTypeEditor::_constant_item_changed(float p_value, String p_item_name)
}
void ThemeTypeEditor::_font_size_item_changed(float p_value, String p_item_name) {
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Set Font Size Item in Theme"));
ur->add_do_method(*edited_theme, "set_font_size", p_item_name, edited_type, p_value);
ur->add_undo_method(*edited_theme, "set_font_size", p_item_name, edited_type, edited_theme->get_font_size(p_item_name, edited_type));
@ -3086,7 +3087,7 @@ void ThemeTypeEditor::_edit_resource_item(Ref<Resource> p_resource, bool p_edit)
}
void ThemeTypeEditor::_font_item_changed(Ref<Font> p_value, String p_item_name) {
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Set Font Item in Theme"));
ur->add_do_method(*edited_theme, "set_font", p_item_name, edited_type, p_value.is_valid() ? p_value : Ref<Font>());
@ -3103,7 +3104,7 @@ void ThemeTypeEditor::_font_item_changed(Ref<Font> p_value, String p_item_name)
}
void ThemeTypeEditor::_icon_item_changed(Ref<Texture2D> p_value, String p_item_name) {
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Set Icon Item in Theme"));
ur->add_do_method(*edited_theme, "set_icon", p_item_name, edited_type, p_value.is_valid() ? p_value : Ref<Texture2D>());
@ -3120,7 +3121,7 @@ void ThemeTypeEditor::_icon_item_changed(Ref<Texture2D> p_value, String p_item_n
}
void ThemeTypeEditor::_stylebox_item_changed(Ref<StyleBox> p_value, String p_item_name) {
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Set Stylebox Item in Theme"));
ur->add_do_method(*edited_theme, "set_stylebox", p_item_name, edited_type, p_value.is_valid() ? p_value : Ref<StyleBox>());
@ -3163,7 +3164,7 @@ void ThemeTypeEditor::_on_pin_leader_button_pressed(Control *p_editor, String p_
stylebox = Object::cast_to<EditorResourcePicker>(p_editor)->get_edited_resource();
}
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Pin Stylebox"));
ur->add_do_method(this, "_pin_leading_stylebox", p_item_name, stylebox);
@ -3196,7 +3197,7 @@ void ThemeTypeEditor::_pin_leading_stylebox(String p_item_name, Ref<StyleBox> p_
}
void ThemeTypeEditor::_on_unpin_leader_button_pressed() {
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Unpin Stylebox"));
ur->add_do_method(this, "_unpin_leading_stylebox");
ur->add_undo_method(this, "_pin_leading_stylebox", leading_stylebox.item_name, leading_stylebox.stylebox);
@ -3265,7 +3266,7 @@ void ThemeTypeEditor::_update_stylebox_from_leading() {
}
void ThemeTypeEditor::_type_variation_changed(const String p_value) {
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
Ref<EditorUndoRedoManager> &ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Set Theme Type Variation"));
if (p_value.is_empty()) {

View file

@ -33,6 +33,7 @@
#include "editor/editor_file_dialog.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_undo_redo_manager.h"
#include "scene/gui/control.h"
#include "scene/gui/split_container.h"

View file

@ -38,6 +38,7 @@
#include "scene/resources/tile_set.h"
class EditorFileDialog;
class EditorUndoRedoManager;
class AtlasMergingDialog : public ConfirmationDialog {
GDCLASS(AtlasMergingDialog, ConfirmationDialog);
@ -49,7 +50,7 @@ private:
LocalVector<HashMap<Vector2i, Vector2i>> merged_mapping;
Ref<TileSet> tile_set;
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
// Settings.
int next_line_after_column = 30;

View file

@ -38,6 +38,7 @@
#include "editor/editor_node.h"
#include "editor/editor_properties.h"
#include "editor/editor_scale.h"
#include "editor/editor_undo_redo_manager.h"
void TileDataEditor::_tile_set_changed_plan_update() {
_tile_set_changed_update_needed = true;
@ -248,7 +249,14 @@ void GenericTilePolygonEditor::_zoom_changed() {
}
void GenericTilePolygonEditor::_advanced_menu_item_pressed(int p_item_pressed) {
UndoRedo *undo_redo = use_undo_redo ? editor_undo_redo : memnew(UndoRedo);
Ref<EditorUndoRedoManager> undo_redo;
if (use_undo_redo) {
undo_redo = editor_undo_redo;
} else {
// This nice hack allows for discarding undo actions without making code too complex.
undo_redo.instantiate();
}
switch (p_item_pressed) {
case RESET_TO_DEFAULT_TILE: {
undo_redo->create_action(TTR("Reset Polygons"));
@ -322,9 +330,6 @@ void GenericTilePolygonEditor::_advanced_menu_item_pressed(int p_item_pressed) {
default:
break;
}
if (!use_undo_redo) {
memdelete(undo_redo);
}
}
void GenericTilePolygonEditor::_grab_polygon_point(Vector2 p_pos, const Transform2D &p_polygon_xform, int &r_polygon_index, int &r_point_index) {
@ -409,7 +414,14 @@ void GenericTilePolygonEditor::_snap_to_half_pixel(Point2 &r_point) {
}
void GenericTilePolygonEditor::_base_control_gui_input(Ref<InputEvent> p_event) {
UndoRedo *undo_redo = use_undo_redo ? editor_undo_redo : memnew(UndoRedo);
Ref<EditorUndoRedoManager> undo_redo;
if (use_undo_redo) {
undo_redo = editor_undo_redo;
} else {
// This nice hack allows for discarding undo actions without making code too complex.
undo_redo.instantiate();
}
real_t grab_threshold = EDITOR_GET("editors/polygon_editor/point_grab_radius");
hovered_polygon_index = -1;
@ -600,10 +612,6 @@ void GenericTilePolygonEditor::_base_control_gui_input(Ref<InputEvent> p_event)
}
base_control->update();
if (!use_undo_redo) {
memdelete(undo_redo);
}
}
void GenericTilePolygonEditor::set_use_undo_redo(bool p_use_undo_redo) {

View file

@ -39,6 +39,8 @@
#include "scene/gui/control.h"
#include "scene/gui/label.h"
class EditorUndoRedoManager;
class TileDataEditor : public VBoxContainer {
GDCLASS(TileDataEditor, VBoxContainer);
@ -93,7 +95,7 @@ private:
bool multiple_polygon_mode = false;
bool use_undo_redo = true;
UndoRedo *editor_undo_redo = nullptr;
Ref<EditorUndoRedoManager> editor_undo_redo;
// UI
int hovered_polygon_index = -1;
@ -214,7 +216,7 @@ private:
protected:
DummyObject *dummy_object = memnew(DummyObject);
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
StringName type;
String property;
@ -279,7 +281,7 @@ private:
virtual void _setup_undo_redo_action(TileSetAtlasSource *p_tile_set_atlas_source, HashMap<TileMapCell, Variant, TileMapCell> p_previous_values, Variant p_new_value) override;
protected:
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
virtual void _tile_set_changed() override;
@ -314,7 +316,7 @@ class TileDataCollisionEditor : public TileDataDefaultEditor {
virtual void _setup_undo_redo_action(TileSetAtlasSource *p_tile_set_atlas_source, HashMap<TileMapCell, Variant, TileMapCell> p_previous_values, Variant p_new_value) override;
protected:
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
virtual void _tile_set_changed() override;
@ -366,7 +368,7 @@ protected:
void _notification(int p_what);
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
public:
virtual Control *get_toolbar() override { return toolbar; };
@ -399,7 +401,7 @@ private:
virtual void _setup_undo_redo_action(TileSetAtlasSource *p_tile_set_atlas_source, HashMap<TileMapCell, Variant, TileMapCell> p_previous_values, Variant p_new_value) override;
protected:
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
virtual void _tile_set_changed() override;

View file

@ -35,6 +35,7 @@
#include "editor/editor_node.h"
#include "editor/editor_resource_preview.h"
#include "editor/editor_scale.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
#include "scene/2d/camera_2d.h"
@ -3697,8 +3698,8 @@ void TileMapEditor::_update_layers_selection() {
}
void TileMapEditor::_move_tile_map_array_element(Object *p_undo_redo, Object *p_edited, String p_array_prefix, int p_from_index, int p_to_pos) {
UndoRedo *undo_redo = Object::cast_to<UndoRedo>(p_undo_redo);
ERR_FAIL_COND(!undo_redo);
Ref<EditorUndoRedoManager> undo_redo = Object::cast_to<EditorUndoRedoManager>(p_undo_redo);
ERR_FAIL_COND(undo_redo.is_null());
TileMap *tile_map = Object::cast_to<TileMap>(p_edited);
if (!tile_map) {

View file

@ -47,7 +47,7 @@
#include "scene/gui/tab_bar.h"
#include "scene/gui/tree.h"
class UndoRedo;
class EditorUndoRedoManager;
class TileMapEditorPlugin : public Object {
public:
@ -70,7 +70,7 @@ class TileMapEditorTilesPlugin : public TileMapEditorPlugin {
GDCLASS(TileMapEditorTilesPlugin, TileMapEditorPlugin);
private:
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
ObjectID tile_map_id;
int tile_map_layer = -1;
virtual void edit(ObjectID p_tile_map_id, int p_tile_map_layer) override;
@ -223,7 +223,7 @@ class TileMapEditorTerrainsPlugin : public TileMapEditorPlugin {
GDCLASS(TileMapEditorTerrainsPlugin, TileMapEditorPlugin);
private:
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
ObjectID tile_map_id;
int tile_map_layer = -1;
virtual void edit(ObjectID p_tile_map_id, int p_tile_map_layer) override;
@ -317,7 +317,7 @@ class TileMapEditor : public VBoxContainer {
GDCLASS(TileMapEditor, VBoxContainer);
private:
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
bool tileset_changed_needs_update = false;
ObjectID tile_map_id;
int tile_map_layer = -1;

View file

@ -32,6 +32,7 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_undo_redo_manager.h"
void TileProxiesManagerDialog::_right_clicked(int p_item, Vector2 p_local_mouse_pos, Object *p_item_list, MouseButton p_mouse_button_index) {
if (p_mouse_button_index != MouseButton::RIGHT) {

View file

@ -43,7 +43,7 @@ private:
int commited_actions_count = 0;
Ref<TileSet> tile_set;
UndoRedo *undo_redo = nullptr;
Ref<EditorUndoRedoManager> undo_redo;
TileMapCell from;
TileMapCell to;

View file

@ -2058,14 +2058,16 @@ void TileSetAtlasSourceEditor::_atlas_source_proxy_object_changed(String p_what)
}
void TileSetAtlasSourceEditor::_undo_redo_inspector_callback(Object *p_undo_redo, Object *p_edited, String p_property, Variant p_new_value) {
UndoRedo *undo_redo = Object::cast_to<UndoRedo>(p_undo_redo);
ERR_FAIL_COND(!undo_redo);
Ref<EditorUndoRedoManager> undo_redo = Object::cast_to<EditorUndoRedoManager>(p_undo_redo);
ERR_FAIL_COND(!undo_redo.is_valid());
#define ADD_UNDO(obj, property) undo_redo->add_undo_property(obj, property, obj->get(property));
undo_redo->start_force_keep_in_merge_ends();
AtlasTileProxyObject *tile_data_proxy = Object::cast_to<AtlasTileProxyObject>(p_edited);
if (tile_data_proxy) {
UndoRedo *internal_undo_redo = undo_redo->get_history_for_object(tile_data_proxy).undo_redo;
internal_undo_redo->start_force_keep_in_merge_ends();
Vector<String> components = String(p_property).split("/", true, 2);
if (components.size() == 2 && components[1] == "polygons_count") {
int layer_index = components[0].trim_prefix("physics_layer_").to_int();
@ -2088,6 +2090,7 @@ void TileSetAtlasSourceEditor::_undo_redo_inspector_callback(Object *p_undo_redo
}
}
}
internal_undo_redo->end_force_keep_in_merge_ends();
}
TileSetAtlasSourceProxyObject *atlas_source_proxy = Object::cast_to<TileSetAtlasSourceProxyObject>(p_edited);
@ -2095,6 +2098,9 @@ void TileSetAtlasSourceEditor::_undo_redo_inspector_callback(Object *p_undo_redo
TileSetAtlasSource *atlas_source = atlas_source_proxy->get_edited();
ERR_FAIL_COND(!atlas_source);
UndoRedo *internal_undo_redo = undo_redo->get_history_for_object(atlas_source).undo_redo;
internal_undo_redo->start_force_keep_in_merge_ends();
PackedVector2Array arr;
if (p_property == "texture") {
arr = atlas_source->get_tiles_to_be_removed_on_change(p_new_value, atlas_source->get_margins(), atlas_source->get_separation(), atlas_source->get_texture_region_size());
@ -2121,8 +2127,8 @@ void TileSetAtlasSourceEditor::_undo_redo_inspector_callback(Object *p_undo_redo
}
}
}
internal_undo_redo->end_force_keep_in_merge_ends();
}
undo_redo->end_force_keep_in_merge_ends();
#undef ADD_UNDO
}

Some files were not shown because too many files have changed in this diff Show more