Răsfoiți Sursa

Provide a way to hook into Inspectors UndoRedo.

Gilles Roudière 4 ani în urmă
părinte
comite
b46672db72

+ 19 - 0
doc/classes/EditorPlugin.xml

@@ -157,6 +157,16 @@
 				Registers a custom translation parser plugin for extracting translatable strings from custom files.
 			</description>
 		</method>
+		<method name="add_undo_redo_inspector_hook_callback">
+			<return type="void">
+			</return>
+			<argument index="0" name="callable" type="Callable">
+			</argument>
+			<description>
+				Hooks a callback into the undo/redo action creation when a property is modified in the inspector. This allows, for example, to save other properties that may be lost when a given property is modified.
+				The callback should have 4 arguments: [Object] [code]undo_redo[/code], [Object] [code]modified_object[/code], [String] [code]property[/code] and [Variant] [code]new_value[/code]. They are, respectively, the [UndoRedo] object used by the inspector, the currently modified object, the name of the modified property and the new value the property is about to take.
+			</description>
+		</method>
 		<method name="apply_changes" qualifiers="virtual">
 			<return type="void">
 			</return>
@@ -622,6 +632,15 @@
 				Removes a registered custom translation parser plugin.
 			</description>
 		</method>
+		<method name="remove_undo_redo_inspector_hook_callback">
+			<return type="void">
+			</return>
+			<argument index="0" name="callable" type="Callable">
+			</argument>
+			<description>
+				Removes a callback previsously added by [method add_undo_redo_inspector_hook_callback].
+			</description>
+		</method>
 		<method name="save_external_data" qualifiers="virtual">
 			<return type="void">
 			</return>

+ 12 - 0
editor/editor_data.cpp

@@ -426,6 +426,18 @@ UndoRedo &EditorData::get_undo_redo() {
 	return undo_redo;
 }
 
+void EditorData::add_undo_redo_inspector_hook_callback(Callable p_callable) {
+	undo_redo_callbacks.push_back(p_callable);
+}
+
+void EditorData::remove_undo_redo_inspector_hook_callback(Callable p_callable) {
+	undo_redo_callbacks.erase(p_callable);
+}
+
+const Vector<Callable> EditorData::get_undo_redo_inspector_hook_callback() {
+	return undo_redo_callbacks;
+}
+
 void EditorData::remove_editor_plugin(EditorPlugin *p_plugin) {
 	p_plugin->undo_redo = nullptr;
 	editor_plugins.erase(p_plugin);

+ 4 - 0
editor/editor_data.h

@@ -132,6 +132,7 @@ private:
 
 	List<PropertyData> clipboard;
 	UndoRedo undo_redo;
+	Vector<Callable> undo_redo_callbacks;
 
 	void _cleanup_history();
 
@@ -166,6 +167,9 @@ public:
 	EditorPlugin *get_editor_plugin(int p_idx);
 
 	UndoRedo &get_undo_redo();
+	void add_undo_redo_inspector_hook_callback(Callable p_callable); // Callbacks shoud have 4 args: (Object* undo_redo, Object *modified_object, String property, Varian new_value)
+	void remove_undo_redo_inspector_hook_callback(Callable p_callable);
+	const Vector<Callable> get_undo_redo_inspector_hook_callback();
 
 	void save_editor_global_states();
 	void restore_editor_global_states();

+ 16 - 0
editor/editor_inspector.cpp

@@ -2266,6 +2266,22 @@ void EditorInspector::_edit_set(const String &p_name, const Variant &p_value, bo
 		undo_redo->add_do_property(object, p_name, p_value);
 		undo_redo->add_undo_property(object, p_name, object->get(p_name));
 
+		Variant v_undo_redo = (Object *)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++) {
+			const Callable &callback = EditorNode::get_singleton()->get_editor_data().get_undo_redo_inspector_hook_callback()[i];
+
+			const Variant *p_arguments[] = { &v_undo_redo, &v_object, &v_name, &p_value };
+			Variant return_value;
+			Callable::CallError call_error;
+
+			callback.call(p_arguments, 4, return_value, call_error);
+			if (call_error.error != Callable::CallError::CALL_OK) {
+				ERR_PRINT("Invalid UndoRedo callback.");
+			}
+		}
+
 		if (p_refresh_all) {
 			undo_redo->add_do_method(this, "_edit_request_change", object, "");
 			undo_redo->add_undo_method(this, "_edit_request_change", object, "");

+ 10 - 0
editor/editor_plugin.cpp

@@ -703,6 +703,14 @@ bool EditorPlugin::get_remove_list(List<Node *> *p_list) {
 void EditorPlugin::restore_global_state() {}
 void EditorPlugin::save_global_state() {}
 
+void EditorPlugin::add_undo_redo_inspector_hook_callback(Callable p_callable) {
+	EditorNode::get_singleton()->get_editor_data().add_undo_redo_inspector_hook_callback(p_callable);
+}
+
+void EditorPlugin::remove_undo_redo_inspector_hook_callback(Callable p_callable) {
+	EditorNode::get_singleton()->get_editor_data().remove_undo_redo_inspector_hook_callback(p_callable);
+}
+
 void EditorPlugin::add_translation_parser_plugin(const Ref<EditorTranslationParserPlugin> &p_parser) {
 	EditorTranslationParser::get_singleton()->add_parser(p_parser, EditorTranslationParser::CUSTOM);
 }
@@ -862,6 +870,8 @@ void EditorPlugin::_bind_methods() {
 	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("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);
 	ClassDB::bind_method(D_METHOD("add_translation_parser_plugin", "parser"), &EditorPlugin::add_translation_parser_plugin);
 	ClassDB::bind_method(D_METHOD("remove_translation_parser_plugin", "parser"), &EditorPlugin::remove_translation_parser_plugin);

+ 3 - 0
editor/editor_plugin.h

@@ -225,6 +225,9 @@ public:
 	EditorInterface *get_editor_interface();
 	ScriptCreateDialog *get_script_create_dialog();
 
+	void add_undo_redo_inspector_hook_callback(Callable p_callable);
+	void remove_undo_redo_inspector_hook_callback(Callable p_callable);
+
 	int update_overlays() const;
 
 	void queue_save_layout();