Add hack to associate undo-redo actions with global history
This commit is contained in:
parent
9ae61e0556
commit
c94ec7613d
|
@ -37,7 +37,6 @@
|
||||||
#include "editor/editor_interface.h"
|
#include "editor/editor_interface.h"
|
||||||
#include "editor/editor_paths.h"
|
#include "editor/editor_paths.h"
|
||||||
#include "editor/editor_settings.h"
|
#include "editor/editor_settings.h"
|
||||||
#include "editor/editor_undo_redo_manager.h"
|
|
||||||
#include "editor/filesystem_dock.h"
|
#include "editor/filesystem_dock.h"
|
||||||
#include "editor/gui/editor_bottom_panel.h"
|
#include "editor/gui/editor_bottom_panel.h"
|
||||||
#include "editor/inspector_dock.h"
|
#include "editor/inspector_dock.h"
|
||||||
|
@ -58,7 +57,6 @@
|
||||||
#include <godot_cpp/classes/editor_interface.hpp>
|
#include <godot_cpp/classes/editor_interface.hpp>
|
||||||
#include <godot_cpp/classes/editor_paths.hpp>
|
#include <godot_cpp/classes/editor_paths.hpp>
|
||||||
#include <godot_cpp/classes/editor_settings.hpp>
|
#include <godot_cpp/classes/editor_settings.hpp>
|
||||||
#include <godot_cpp/classes/editor_undo_redo_manager.hpp>
|
|
||||||
#include <godot_cpp/classes/file_access.hpp>
|
#include <godot_cpp/classes/file_access.hpp>
|
||||||
#include <godot_cpp/classes/file_system_dock.hpp>
|
#include <godot_cpp/classes/file_system_dock.hpp>
|
||||||
#include <godot_cpp/classes/input.hpp>
|
#include <godot_cpp/classes/input.hpp>
|
||||||
|
@ -82,14 +80,25 @@ _FORCE_INLINE_ String _get_script_template_path() {
|
||||||
return templates_search_path.path_join("BTTask").path_join("custom_task.gd");
|
return templates_search_path.path_join("BTTask").path_join("custom_task.gd");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EditorUndoRedoManager *LimboAIEditor::_new_undo_redo_action(const String &p_name, UndoRedo::MergeMode p_mode) {
|
||||||
|
#ifdef LIMBOAI_MODULE
|
||||||
|
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
|
||||||
|
#elif LIMBOAI_GDEXTENSION
|
||||||
|
EditorUndoRedoManager *undo_redo = plugin->get_undo_redo();
|
||||||
|
#endif
|
||||||
|
// ! HACK: Force global history to be used for resources without a set path.
|
||||||
|
undo_redo->create_action(p_name, p_mode, dummy_history_context);
|
||||||
|
undo_redo->force_fixed_history();
|
||||||
|
return undo_redo;
|
||||||
|
}
|
||||||
|
|
||||||
void LimboAIEditor::_add_task(const Ref<BTTask> &p_task, bool p_as_sibling) {
|
void LimboAIEditor::_add_task(const Ref<BTTask> &p_task, bool p_as_sibling) {
|
||||||
if (task_tree->get_bt().is_null()) {
|
if (task_tree->get_bt().is_null()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ERR_FAIL_COND(p_task.is_null());
|
ERR_FAIL_COND(p_task.is_null());
|
||||||
|
|
||||||
EditorUndoRedoManager *undo_redo = GET_UNDO_REDO();
|
EditorUndoRedoManager *undo_redo = _new_undo_redo_action(TTR("Add BT Task"));
|
||||||
undo_redo->create_action(TTR("Add BT Task"));
|
|
||||||
|
|
||||||
int insert_idx = -1;
|
int insert_idx = -1;
|
||||||
Ref<BTTask> selected = task_tree->get_selected();
|
Ref<BTTask> selected = task_tree->get_selected();
|
||||||
|
@ -169,8 +178,7 @@ void LimboAIEditor::_add_task_by_class_or_path(const String &p_class_or_path) {
|
||||||
void LimboAIEditor::_remove_task(const Ref<BTTask> &p_task) {
|
void LimboAIEditor::_remove_task(const Ref<BTTask> &p_task) {
|
||||||
ERR_FAIL_COND(p_task.is_null());
|
ERR_FAIL_COND(p_task.is_null());
|
||||||
ERR_FAIL_COND(task_tree->get_bt().is_null());
|
ERR_FAIL_COND(task_tree->get_bt().is_null());
|
||||||
EditorUndoRedoManager *undo_redo = GET_UNDO_REDO();
|
EditorUndoRedoManager *undo_redo = _new_undo_redo_action(TTR("Remove BT Task"));
|
||||||
undo_redo->create_action(TTR("Remove BT Task"));
|
|
||||||
if (p_task->get_parent() == nullptr) {
|
if (p_task->get_parent() == nullptr) {
|
||||||
ERR_FAIL_COND(task_tree->get_bt()->get_root_task() != p_task);
|
ERR_FAIL_COND(task_tree->get_bt()->get_root_task() != p_task);
|
||||||
undo_redo->add_do_method(task_tree->get_bt().ptr(), LW_NAME(set_root_task), Variant());
|
undo_redo->add_do_method(task_tree->get_bt().ptr(), LW_NAME(set_root_task), Variant());
|
||||||
|
@ -226,7 +234,7 @@ void LimboAIEditor::_disable_editing() {
|
||||||
usage_hint->show();
|
usage_hint->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LimboAIEditor::edit_bt(Ref<BehaviorTree> p_behavior_tree, bool p_force_refresh) {
|
void LimboAIEditor::edit_bt(const Ref<BehaviorTree> &p_behavior_tree, bool p_force_refresh) {
|
||||||
ERR_FAIL_COND_MSG(p_behavior_tree.is_null(), "p_behavior_tree is null");
|
ERR_FAIL_COND_MSG(p_behavior_tree.is_null(), "p_behavior_tree is null");
|
||||||
|
|
||||||
if (!p_force_refresh && task_tree->get_bt() == p_behavior_tree) {
|
if (!p_force_refresh && task_tree->get_bt() == p_behavior_tree) {
|
||||||
|
@ -327,8 +335,7 @@ void LimboAIEditor::_extract_subtree(const String &p_path) {
|
||||||
Ref<BTTask> selected = task_tree->get_selected();
|
Ref<BTTask> selected = task_tree->get_selected();
|
||||||
ERR_FAIL_COND(selected.is_null());
|
ERR_FAIL_COND(selected.is_null());
|
||||||
|
|
||||||
EditorUndoRedoManager *undo_redo = GET_UNDO_REDO();
|
EditorUndoRedoManager *undo_redo = _new_undo_redo_action(TTR("Extract Subtree"));
|
||||||
undo_redo->create_action(TTR("Extract Subtree"));
|
|
||||||
|
|
||||||
Ref<BehaviorTree> bt = memnew(BehaviorTree);
|
Ref<BehaviorTree> bt = memnew(BehaviorTree);
|
||||||
bt->set_root_task(selected->clone());
|
bt->set_root_task(selected->clone());
|
||||||
|
@ -459,7 +466,6 @@ void LimboAIEditor::_on_tree_rmb(const Vector2 &p_menu_pos) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LimboAIEditor::_action_selected(int p_id) {
|
void LimboAIEditor::_action_selected(int p_id) {
|
||||||
EditorUndoRedoManager *undo_redo = GET_UNDO_REDO();
|
|
||||||
switch (p_id) {
|
switch (p_id) {
|
||||||
case ACTION_RENAME: {
|
case ACTION_RENAME: {
|
||||||
if (!task_tree->get_selected().is_valid()) {
|
if (!task_tree->get_selected().is_valid()) {
|
||||||
|
@ -537,7 +543,7 @@ void LimboAIEditor::_action_selected(int p_id) {
|
||||||
Ref<BTTask> parent = sel->get_parent();
|
Ref<BTTask> parent = sel->get_parent();
|
||||||
int idx = sel->get_index();
|
int idx = sel->get_index();
|
||||||
if (idx > 0 && idx < parent->get_child_count()) {
|
if (idx > 0 && idx < parent->get_child_count()) {
|
||||||
undo_redo->create_action(TTR("Move BT Task"));
|
EditorUndoRedoManager *undo_redo = _new_undo_redo_action(TTR("Move BT Task"));
|
||||||
undo_redo->add_do_method(parent.ptr(), LW_NAME(remove_child), sel);
|
undo_redo->add_do_method(parent.ptr(), LW_NAME(remove_child), sel);
|
||||||
undo_redo->add_do_method(parent.ptr(), LW_NAME(add_child_at_index), sel, idx - 1);
|
undo_redo->add_do_method(parent.ptr(), LW_NAME(add_child_at_index), sel, idx - 1);
|
||||||
undo_redo->add_undo_method(parent.ptr(), LW_NAME(remove_child), sel);
|
undo_redo->add_undo_method(parent.ptr(), LW_NAME(remove_child), sel);
|
||||||
|
@ -555,7 +561,7 @@ void LimboAIEditor::_action_selected(int p_id) {
|
||||||
Ref<BTTask> parent = sel->get_parent();
|
Ref<BTTask> parent = sel->get_parent();
|
||||||
int idx = sel->get_index();
|
int idx = sel->get_index();
|
||||||
if (idx >= 0 && idx < (parent->get_child_count() - 1)) {
|
if (idx >= 0 && idx < (parent->get_child_count() - 1)) {
|
||||||
undo_redo->create_action(TTR("Move BT Task"));
|
EditorUndoRedoManager *undo_redo = _new_undo_redo_action(TTR("Move BT Task"));
|
||||||
undo_redo->add_do_method(parent.ptr(), LW_NAME(remove_child), sel);
|
undo_redo->add_do_method(parent.ptr(), LW_NAME(remove_child), sel);
|
||||||
undo_redo->add_do_method(parent.ptr(), LW_NAME(add_child_at_index), sel, idx + 1);
|
undo_redo->add_do_method(parent.ptr(), LW_NAME(add_child_at_index), sel, idx + 1);
|
||||||
undo_redo->add_undo_method(parent.ptr(), LW_NAME(remove_child), sel);
|
undo_redo->add_undo_method(parent.ptr(), LW_NAME(remove_child), sel);
|
||||||
|
@ -570,7 +576,7 @@ void LimboAIEditor::_action_selected(int p_id) {
|
||||||
case ACTION_DUPLICATE: {
|
case ACTION_DUPLICATE: {
|
||||||
Ref<BTTask> sel = task_tree->get_selected();
|
Ref<BTTask> sel = task_tree->get_selected();
|
||||||
if (sel.is_valid()) {
|
if (sel.is_valid()) {
|
||||||
undo_redo->create_action(TTR("Duplicate BT Task"));
|
EditorUndoRedoManager *undo_redo = _new_undo_redo_action(TTR("Duplicate BT Task"));
|
||||||
Ref<BTTask> parent = sel->get_parent();
|
Ref<BTTask> parent = sel->get_parent();
|
||||||
if (parent.is_null()) {
|
if (parent.is_null()) {
|
||||||
parent = sel;
|
parent = sel;
|
||||||
|
@ -589,7 +595,7 @@ void LimboAIEditor::_action_selected(int p_id) {
|
||||||
if (sel.is_valid() && task_tree->get_bt()->get_root_task() != sel) {
|
if (sel.is_valid() && task_tree->get_bt()->get_root_task() != sel) {
|
||||||
Ref<BTTask> parent = sel->get_parent();
|
Ref<BTTask> parent = sel->get_parent();
|
||||||
ERR_FAIL_COND(parent.is_null());
|
ERR_FAIL_COND(parent.is_null());
|
||||||
undo_redo->create_action(TTR("Make Root"));
|
EditorUndoRedoManager *undo_redo = _new_undo_redo_action(TTR("Make Root"));
|
||||||
undo_redo->add_do_method(parent.ptr(), LW_NAME(remove_child), sel);
|
undo_redo->add_do_method(parent.ptr(), LW_NAME(remove_child), sel);
|
||||||
Ref<BTTask> old_root = task_tree->get_bt()->get_root_task();
|
Ref<BTTask> old_root = task_tree->get_bt()->get_root_task();
|
||||||
undo_redo->add_do_method(task_tree->get_bt().ptr(), LW_NAME(set_root_task), sel);
|
undo_redo->add_do_method(task_tree->get_bt().ptr(), LW_NAME(set_root_task), sel);
|
||||||
|
@ -616,8 +622,7 @@ void LimboAIEditor::_action_selected(int p_id) {
|
||||||
if (p_id == ACTION_CUT) {
|
if (p_id == ACTION_CUT) {
|
||||||
clipboard_task = sel->clone();
|
clipboard_task = sel->clone();
|
||||||
}
|
}
|
||||||
|
EditorUndoRedoManager *undo_redo = _new_undo_redo_action(TTR("Remove BT Task"));
|
||||||
undo_redo->create_action(TTR("Remove BT Task"));
|
|
||||||
if (sel->is_root()) {
|
if (sel->is_root()) {
|
||||||
undo_redo->add_do_method(task_tree->get_bt().ptr(), LW_NAME(set_root_task), Variant());
|
undo_redo->add_do_method(task_tree->get_bt().ptr(), LW_NAME(set_root_task), Variant());
|
||||||
undo_redo->add_undo_method(task_tree->get_bt().ptr(), LW_NAME(set_root_task), task_tree->get_bt()->get_root_task());
|
undo_redo->add_undo_method(task_tree->get_bt().ptr(), LW_NAME(set_root_task), task_tree->get_bt()->get_root_task());
|
||||||
|
@ -848,8 +853,7 @@ void LimboAIEditor::_on_task_dragged(Ref<BTTask> p_task, Ref<BTTask> p_to_task,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
EditorUndoRedoManager *undo_redo = GET_UNDO_REDO();
|
EditorUndoRedoManager *undo_redo = _new_undo_redo_action(TTR("Drag BT Task"));
|
||||||
undo_redo->create_action(TTR("Drag BT Task"));
|
|
||||||
undo_redo->add_do_method(p_task->get_parent().ptr(), LW_NAME(remove_child), p_task);
|
undo_redo->add_do_method(p_task->get_parent().ptr(), LW_NAME(remove_child), p_task);
|
||||||
|
|
||||||
if (p_type == 0) {
|
if (p_type == 0) {
|
||||||
|
@ -943,8 +947,7 @@ void LimboAIEditor::_task_type_selected(const String &p_class_or_path) {
|
||||||
Ref<BTTask> new_task = _create_task_by_class_or_path(p_class_or_path);
|
Ref<BTTask> new_task = _create_task_by_class_or_path(p_class_or_path);
|
||||||
ERR_FAIL_COND_MSG(new_task.is_null(), "LimboAI: Unable to construct task.");
|
ERR_FAIL_COND_MSG(new_task.is_null(), "LimboAI: Unable to construct task.");
|
||||||
|
|
||||||
EditorUndoRedoManager *undo_redo = GET_UNDO_REDO();
|
EditorUndoRedoManager *undo_redo = _new_undo_redo_action(TTR("Change BT task type"));
|
||||||
undo_redo->create_action(TTR("Change BT task type"));
|
|
||||||
undo_redo->add_do_method(this, LW_NAME(_replace_task), selected_task, new_task);
|
undo_redo->add_do_method(this, LW_NAME(_replace_task), selected_task, new_task);
|
||||||
undo_redo->add_undo_method(this, LW_NAME(_replace_task), new_task, selected_task);
|
undo_redo->add_undo_method(this, LW_NAME(_replace_task), new_task, selected_task);
|
||||||
undo_redo->add_do_method(task_tree, LW_NAME(update_tree));
|
undo_redo->add_do_method(task_tree, LW_NAME(update_tree));
|
||||||
|
@ -1198,8 +1201,7 @@ void LimboAIEditor::_rename_task_confirmed() {
|
||||||
ERR_FAIL_COND(!task_tree->get_selected().is_valid());
|
ERR_FAIL_COND(!task_tree->get_selected().is_valid());
|
||||||
rename_dialog->hide();
|
rename_dialog->hide();
|
||||||
|
|
||||||
EditorUndoRedoManager *undo_redo = GET_UNDO_REDO();
|
EditorUndoRedoManager *undo_redo = _new_undo_redo_action(TTR("Set Custom Name"));
|
||||||
undo_redo->create_action(TTR("Set Custom Name"));
|
|
||||||
undo_redo->add_do_method(task_tree->get_selected().ptr(), LW_NAME(set_custom_name), rename_edit->get_text());
|
undo_redo->add_do_method(task_tree->get_selected().ptr(), LW_NAME(set_custom_name), rename_edit->get_text());
|
||||||
undo_redo->add_undo_method(task_tree->get_selected().ptr(), LW_NAME(set_custom_name), task_tree->get_selected()->get_custom_name());
|
undo_redo->add_undo_method(task_tree->get_selected().ptr(), LW_NAME(set_custom_name), task_tree->get_selected()->get_custom_name());
|
||||||
undo_redo->add_do_method(task_tree, LW_NAME(update_task), task_tree->get_selected());
|
undo_redo->add_do_method(task_tree, LW_NAME(update_task), task_tree->get_selected());
|
||||||
|
@ -1462,6 +1464,7 @@ void LimboAIEditor::_bind_methods() {
|
||||||
LimboAIEditor::LimboAIEditor() {
|
LimboAIEditor::LimboAIEditor() {
|
||||||
plugin = nullptr;
|
plugin = nullptr;
|
||||||
idx_history = 0;
|
idx_history = 0;
|
||||||
|
dummy_history_context = memnew(Object);
|
||||||
|
|
||||||
EDITOR_DEF("limbo_ai/editor/prefer_online_documentation", false);
|
EDITOR_DEF("limbo_ai/editor/prefer_online_documentation", false);
|
||||||
|
|
||||||
|
@ -1795,6 +1798,7 @@ LimboAIEditor::LimboAIEditor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
LimboAIEditor::~LimboAIEditor() {
|
LimboAIEditor::~LimboAIEditor() {
|
||||||
|
memdelete(dummy_history_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
//**** LimboAIEditor ^
|
//**** LimboAIEditor ^
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "core/object/object.h"
|
#include "core/object/object.h"
|
||||||
#include "core/templates/hash_set.h"
|
#include "core/templates/hash_set.h"
|
||||||
#include "editor/editor_node.h"
|
#include "editor/editor_node.h"
|
||||||
|
#include "editor/editor_undo_redo_manager.h"
|
||||||
#include "editor/gui/editor_spin_slider.h"
|
#include "editor/gui/editor_spin_slider.h"
|
||||||
#include "editor/plugins/editor_plugin.h"
|
#include "editor/plugins/editor_plugin.h"
|
||||||
#include "scene/gui/box_container.h"
|
#include "scene/gui/box_container.h"
|
||||||
|
@ -42,9 +43,6 @@
|
||||||
#include "scene/gui/split_container.h"
|
#include "scene/gui/split_container.h"
|
||||||
#include "scene/gui/tree.h"
|
#include "scene/gui/tree.h"
|
||||||
#include "scene/resources/texture.h"
|
#include "scene/resources/texture.h"
|
||||||
|
|
||||||
#define GET_UNDO_REDO() EditorUndoRedoManager::get_singleton()
|
|
||||||
|
|
||||||
#endif // LIMBOAI_MODULE
|
#endif // LIMBOAI_MODULE
|
||||||
|
|
||||||
#ifdef LIMBOAI_GDEXTENSION
|
#ifdef LIMBOAI_GDEXTENSION
|
||||||
|
@ -52,6 +50,7 @@
|
||||||
#include <godot_cpp/classes/control.hpp>
|
#include <godot_cpp/classes/control.hpp>
|
||||||
#include <godot_cpp/classes/editor_plugin.hpp>
|
#include <godot_cpp/classes/editor_plugin.hpp>
|
||||||
#include <godot_cpp/classes/editor_spin_slider.hpp>
|
#include <godot_cpp/classes/editor_spin_slider.hpp>
|
||||||
|
#include <godot_cpp/classes/editor_undo_redo_manager.hpp>
|
||||||
#include <godot_cpp/classes/file_dialog.hpp>
|
#include <godot_cpp/classes/file_dialog.hpp>
|
||||||
#include <godot_cpp/classes/h_box_container.hpp>
|
#include <godot_cpp/classes/h_box_container.hpp>
|
||||||
#include <godot_cpp/classes/h_split_container.hpp>
|
#include <godot_cpp/classes/h_split_container.hpp>
|
||||||
|
@ -67,8 +66,6 @@
|
||||||
|
|
||||||
using namespace godot;
|
using namespace godot;
|
||||||
|
|
||||||
#define GET_UNDO_REDO() plugin->get_undo_redo()
|
|
||||||
|
|
||||||
#endif // LIMBOAI_GDEXTENSION
|
#endif // LIMBOAI_GDEXTENSION
|
||||||
|
|
||||||
class LimboAIEditor : public Control {
|
class LimboAIEditor : public Control {
|
||||||
|
@ -189,6 +186,10 @@ private:
|
||||||
|
|
||||||
AcceptDialog *info_dialog;
|
AcceptDialog *info_dialog;
|
||||||
|
|
||||||
|
// ! HACK: Force global history to be used for resources without a set path.
|
||||||
|
Object *dummy_history_context = nullptr;
|
||||||
|
EditorUndoRedoManager *_new_undo_redo_action(const String &p_name = "", UndoRedo::MergeMode p_mode = UndoRedo::MERGE_DISABLE);
|
||||||
|
|
||||||
void _add_task(const Ref<BTTask> &p_task, bool p_as_sibling);
|
void _add_task(const Ref<BTTask> &p_task, bool p_as_sibling);
|
||||||
void _add_task_with_prototype(const Ref<BTTask> &p_prototype);
|
void _add_task_with_prototype(const Ref<BTTask> &p_prototype);
|
||||||
Ref<BTTask> _create_task_by_class_or_path(const String &p_class_or_path) const;
|
Ref<BTTask> _create_task_by_class_or_path(const String &p_class_or_path) const;
|
||||||
|
@ -258,7 +259,7 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void set_plugin(EditorPlugin *p_plugin) { plugin = p_plugin; };
|
void set_plugin(EditorPlugin *p_plugin) { plugin = p_plugin; };
|
||||||
void edit_bt(Ref<BehaviorTree> p_behavior_tree, bool p_force_refresh = false);
|
void edit_bt(const Ref<BehaviorTree> &p_behavior_tree, bool p_force_refresh = false);
|
||||||
Ref<BlackboardPlan> get_edited_blackboard_plan();
|
Ref<BlackboardPlan> get_edited_blackboard_plan();
|
||||||
|
|
||||||
void apply_changes();
|
void apply_changes();
|
||||||
|
|
Loading…
Reference in New Issue