2023-07-21 09:50:06 +00:00
|
|
|
/**
|
|
|
|
* limbo_ai_editor_plugin.h
|
|
|
|
* =============================================================================
|
2024-03-21 20:38:57 +00:00
|
|
|
* Copyright 2021-2024 Serhii Snitsaruk
|
2023-07-21 09:50:06 +00:00
|
|
|
*
|
|
|
|
* Use of this source code is governed by an MIT-style
|
|
|
|
* license that can be found in the LICENSE file or at
|
|
|
|
* https://opensource.org/licenses/MIT.
|
|
|
|
* =============================================================================
|
|
|
|
*/
|
2022-09-01 22:20:37 +00:00
|
|
|
|
2022-09-02 12:25:03 +00:00
|
|
|
#ifdef TOOLS_ENABLED
|
2024-01-09 12:34:24 +00:00
|
|
|
|
2022-09-01 22:20:37 +00:00
|
|
|
#ifndef LIMBO_AI_EDITOR_PLUGIN_H
|
|
|
|
#define LIMBO_AI_EDITOR_PLUGIN_H
|
|
|
|
|
2024-01-09 12:34:24 +00:00
|
|
|
#include "../bt/behavior_tree.h"
|
|
|
|
#include "../bt/tasks/bt_task.h"
|
2024-01-28 16:49:38 +00:00
|
|
|
#include "editor_property_variable_name.h"
|
2024-05-28 15:21:35 +00:00
|
|
|
#include "owner_picker.h"
|
2023-08-26 08:08:01 +00:00
|
|
|
#include "task_palette.h"
|
2023-08-26 08:24:08 +00:00
|
|
|
#include "task_tree.h"
|
2023-07-20 16:35:36 +00:00
|
|
|
|
2024-01-09 12:34:24 +00:00
|
|
|
#ifdef LIMBOAI_MODULE
|
2022-12-15 07:26:52 +00:00
|
|
|
#include "core/object/class_db.h"
|
|
|
|
#include "core/object/object.h"
|
|
|
|
#include "core/templates/hash_set.h"
|
2022-09-01 22:20:37 +00:00
|
|
|
#include "editor/editor_node.h"
|
2023-09-25 16:07:26 +00:00
|
|
|
#include "editor/gui/editor_spin_slider.h"
|
2024-07-02 09:55:22 +00:00
|
|
|
#include "editor/plugins/editor_plugin.h"
|
2022-09-02 12:25:03 +00:00
|
|
|
#include "scene/gui/box_container.h"
|
2022-12-15 07:26:52 +00:00
|
|
|
#include "scene/gui/control.h"
|
2024-01-17 14:17:22 +00:00
|
|
|
#include "scene/gui/dialogs.h"
|
2022-09-01 22:20:37 +00:00
|
|
|
#include "scene/gui/file_dialog.h"
|
2022-09-02 12:25:03 +00:00
|
|
|
#include "scene/gui/flow_container.h"
|
|
|
|
#include "scene/gui/line_edit.h"
|
2024-05-30 13:55:49 +00:00
|
|
|
#include "scene/gui/link_button.h"
|
2023-08-21 16:17:34 +00:00
|
|
|
#include "scene/gui/margin_container.h"
|
2022-12-15 07:26:52 +00:00
|
|
|
#include "scene/gui/panel_container.h"
|
2023-12-14 22:18:44 +00:00
|
|
|
#include "scene/gui/popup.h"
|
2022-09-01 22:20:37 +00:00
|
|
|
#include "scene/gui/popup_menu.h"
|
2022-09-06 11:28:25 +00:00
|
|
|
#include "scene/gui/split_container.h"
|
2022-09-01 22:20:37 +00:00
|
|
|
#include "scene/gui/tree.h"
|
2022-09-05 14:39:40 +00:00
|
|
|
#include "scene/resources/texture.h"
|
2022-09-01 22:20:37 +00:00
|
|
|
|
2024-01-09 12:34:24 +00:00
|
|
|
#define GET_UNDO_REDO() EditorUndoRedoManager::get_singleton()
|
|
|
|
|
2024-01-13 16:10:42 +00:00
|
|
|
#endif // LIMBOAI_MODULE
|
2024-01-09 12:34:24 +00:00
|
|
|
|
|
|
|
#ifdef LIMBOAI_GDEXTENSION
|
2024-01-17 14:17:22 +00:00
|
|
|
#include "godot_cpp/classes/accept_dialog.hpp"
|
2024-01-09 12:34:24 +00:00
|
|
|
#include <godot_cpp/classes/control.hpp>
|
|
|
|
#include <godot_cpp/classes/editor_plugin.hpp>
|
|
|
|
#include <godot_cpp/classes/editor_spin_slider.hpp>
|
|
|
|
#include <godot_cpp/classes/file_dialog.hpp>
|
|
|
|
#include <godot_cpp/classes/h_box_container.hpp>
|
|
|
|
#include <godot_cpp/classes/h_split_container.hpp>
|
|
|
|
#include <godot_cpp/classes/input_event.hpp>
|
2024-05-30 13:55:49 +00:00
|
|
|
#include <godot_cpp/classes/link_button.hpp>
|
2024-01-09 12:34:24 +00:00
|
|
|
#include <godot_cpp/classes/menu_button.hpp>
|
|
|
|
#include <godot_cpp/classes/panel.hpp>
|
|
|
|
#include <godot_cpp/classes/popup_menu.hpp>
|
2024-05-27 12:27:14 +00:00
|
|
|
#include <godot_cpp/classes/tab_bar.hpp>
|
2024-01-09 12:34:24 +00:00
|
|
|
#include <godot_cpp/classes/texture2d.hpp>
|
|
|
|
#include <godot_cpp/variant/packed_string_array.hpp>
|
|
|
|
#include <godot_cpp/variant/variant.hpp>
|
|
|
|
|
|
|
|
using namespace godot;
|
|
|
|
|
|
|
|
#define GET_UNDO_REDO() plugin->get_undo_redo()
|
|
|
|
|
2024-01-13 16:10:42 +00:00
|
|
|
#endif // LIMBOAI_GDEXTENSION
|
2024-01-09 12:34:24 +00:00
|
|
|
|
2022-09-01 22:20:37 +00:00
|
|
|
class LimboAIEditor : public Control {
|
|
|
|
GDCLASS(LimboAIEditor, Control);
|
|
|
|
|
|
|
|
private:
|
|
|
|
enum Action {
|
2023-12-17 14:24:38 +00:00
|
|
|
ACTION_EDIT_PROBABILITY,
|
2023-08-16 14:07:04 +00:00
|
|
|
ACTION_RENAME,
|
2023-12-14 22:18:44 +00:00
|
|
|
ACTION_CHANGE_TYPE,
|
2023-08-17 09:41:40 +00:00
|
|
|
ACTION_EDIT_SCRIPT,
|
2023-08-17 13:29:12 +00:00
|
|
|
ACTION_OPEN_DOC,
|
2024-02-08 16:10:31 +00:00
|
|
|
ACTION_CUT,
|
|
|
|
ACTION_COPY,
|
|
|
|
ACTION_PASTE,
|
|
|
|
ACTION_PASTE_AFTER,
|
2022-09-01 22:20:37 +00:00
|
|
|
ACTION_MOVE_UP,
|
|
|
|
ACTION_MOVE_DOWN,
|
|
|
|
ACTION_DUPLICATE,
|
|
|
|
ACTION_MAKE_ROOT,
|
2023-12-17 14:24:38 +00:00
|
|
|
ACTION_EXTRACT_SUBTREE,
|
2023-08-16 14:07:04 +00:00
|
|
|
ACTION_REMOVE,
|
2022-09-01 22:20:37 +00:00
|
|
|
};
|
|
|
|
|
2023-08-20 09:34:13 +00:00
|
|
|
enum MiscMenu {
|
2024-01-13 21:40:27 +00:00
|
|
|
MISC_ONLINE_DOCUMENTATION,
|
2024-01-17 14:51:24 +00:00
|
|
|
MISC_DOC_INTRODUCTION,
|
|
|
|
MISC_DOC_CUSTOM_TASKS,
|
2023-08-20 09:34:13 +00:00
|
|
|
MISC_OPEN_DEBUGGER,
|
2024-07-06 07:18:50 +00:00
|
|
|
MISC_LAYOUT_CLASSIC,
|
|
|
|
MISC_LAYOUT_WIDESCREEN_OPTIMIZED,
|
2023-08-21 09:51:19 +00:00
|
|
|
MISC_PROJECT_SETTINGS,
|
2023-08-21 11:46:35 +00:00
|
|
|
MISC_CREATE_SCRIPT_TEMPLATE,
|
2023-08-20 09:34:13 +00:00
|
|
|
};
|
|
|
|
|
2024-05-27 14:53:44 +00:00
|
|
|
enum TabMenu {
|
|
|
|
TAB_SHOW_IN_FILESYSTEM,
|
2024-05-29 08:53:54 +00:00
|
|
|
TAB_JUMP_TO_OWNER,
|
2024-05-27 14:53:44 +00:00
|
|
|
TAB_CLOSE,
|
|
|
|
TAB_CLOSE_OTHER,
|
|
|
|
TAB_CLOSE_RIGHT,
|
|
|
|
TAB_CLOSE_ALL,
|
|
|
|
};
|
|
|
|
|
2024-07-05 15:02:29 +00:00
|
|
|
enum EditorLayout {
|
2024-07-06 07:18:50 +00:00
|
|
|
LAYOUT_CLASSIC,
|
|
|
|
LAYOUT_WIDESCREEN_OPTIMIZED,
|
2024-07-02 09:55:22 +00:00
|
|
|
};
|
|
|
|
|
2023-08-29 09:47:48 +00:00
|
|
|
struct ThemeCache {
|
|
|
|
Ref<Texture2D> duplicate_task_icon;
|
|
|
|
Ref<Texture2D> edit_script_icon;
|
|
|
|
Ref<Texture2D> make_root_icon;
|
|
|
|
Ref<Texture2D> move_task_down_icon;
|
|
|
|
Ref<Texture2D> move_task_up_icon;
|
|
|
|
Ref<Texture2D> open_debugger_icon;
|
2024-01-13 21:40:27 +00:00
|
|
|
Ref<Texture2D> doc_icon;
|
|
|
|
Ref<Texture2D> introduction_icon;
|
2023-09-26 14:12:10 +00:00
|
|
|
Ref<Texture2D> percent_icon;
|
2023-08-29 09:47:48 +00:00
|
|
|
Ref<Texture2D> remove_task_icon;
|
|
|
|
Ref<Texture2D> rename_task_icon;
|
2023-12-14 22:18:44 +00:00
|
|
|
Ref<Texture2D> change_type_icon;
|
2023-12-17 14:24:38 +00:00
|
|
|
Ref<Texture2D> extract_subtree_icon;
|
2024-01-09 12:34:24 +00:00
|
|
|
Ref<Texture2D> behavior_tree_icon;
|
2024-02-08 16:10:31 +00:00
|
|
|
Ref<Texture2D> cut_icon;
|
|
|
|
Ref<Texture2D> copy_icon;
|
|
|
|
Ref<Texture2D> paste_icon;
|
2023-08-29 09:47:48 +00:00
|
|
|
} theme_cache;
|
|
|
|
|
2024-01-09 12:34:24 +00:00
|
|
|
EditorPlugin *plugin;
|
2024-07-05 15:02:29 +00:00
|
|
|
EditorLayout editor_layout;
|
2022-09-02 13:43:54 +00:00
|
|
|
Vector<Ref<BehaviorTree>> history;
|
|
|
|
int idx_history;
|
2024-05-27 11:48:08 +00:00
|
|
|
bool updating_tabs = false;
|
2022-12-15 07:26:52 +00:00
|
|
|
HashSet<Ref<BehaviorTree>> dirty;
|
2024-02-08 16:10:31 +00:00
|
|
|
Ref<BTTask> clipboard_task;
|
2022-09-02 13:43:54 +00:00
|
|
|
|
2023-08-22 10:20:09 +00:00
|
|
|
VBoxContainer *vbox;
|
2024-05-27 11:48:08 +00:00
|
|
|
PanelContainer *tab_bar_panel;
|
|
|
|
HBoxContainer *tab_bar_container;
|
2024-05-30 13:55:49 +00:00
|
|
|
LinkButton *version_btn;
|
2024-05-27 11:48:08 +00:00
|
|
|
TabBar *tab_bar;
|
2024-05-27 14:53:44 +00:00
|
|
|
PopupMenu *tab_menu;
|
2024-05-28 15:21:35 +00:00
|
|
|
OwnerPicker *owner_picker;
|
2022-09-06 11:28:25 +00:00
|
|
|
HSplitContainer *hsc;
|
2022-09-01 22:20:37 +00:00
|
|
|
TaskTree *task_tree;
|
2023-08-22 10:20:09 +00:00
|
|
|
VBoxContainer *banners;
|
2022-09-05 19:57:24 +00:00
|
|
|
Panel *usage_hint;
|
2022-09-01 22:20:37 +00:00
|
|
|
PopupMenu *menu;
|
2023-09-25 16:07:26 +00:00
|
|
|
HBoxContainer *fav_tasks_hbox;
|
|
|
|
TaskPalette *task_palette;
|
|
|
|
|
|
|
|
PopupPanel *probability_popup;
|
|
|
|
EditorSpinSlider *probability_edit;
|
2023-09-25 20:36:37 +00:00
|
|
|
Button *weight_mode;
|
|
|
|
Button *percent_mode;
|
2023-09-25 16:07:26 +00:00
|
|
|
|
2023-12-14 22:18:44 +00:00
|
|
|
PopupPanel *change_type_popup;
|
|
|
|
TaskPalette *change_type_palette;
|
|
|
|
|
2022-09-01 22:20:37 +00:00
|
|
|
FileDialog *save_dialog;
|
|
|
|
FileDialog *load_dialog;
|
2023-12-17 14:24:38 +00:00
|
|
|
FileDialog *extract_dialog;
|
2022-09-01 22:20:37 +00:00
|
|
|
|
2023-08-16 09:19:51 +00:00
|
|
|
Button *new_btn;
|
|
|
|
Button *load_btn;
|
|
|
|
Button *save_btn;
|
|
|
|
Button *new_script_btn;
|
2023-08-20 09:34:13 +00:00
|
|
|
MenuButton *misc_btn;
|
2023-08-16 09:19:51 +00:00
|
|
|
|
2022-11-23 15:25:32 +00:00
|
|
|
ConfirmationDialog *rename_dialog;
|
|
|
|
LineEdit *rename_edit;
|
|
|
|
|
2022-11-22 20:00:08 +00:00
|
|
|
ConfirmationDialog *disk_changed;
|
|
|
|
Tree *disk_changed_list;
|
2022-12-15 07:26:52 +00:00
|
|
|
HashSet<String> disk_changed_files;
|
2022-11-22 20:00:08 +00:00
|
|
|
|
2024-01-17 14:17:22 +00:00
|
|
|
AcceptDialog *info_dialog;
|
|
|
|
|
2024-02-08 16:10:31 +00:00
|
|
|
void _add_task(const Ref<BTTask> &p_task, bool p_as_sibling);
|
|
|
|
void _add_task_with_prototype(const Ref<BTTask> &p_prototype);
|
2023-12-14 22:18:44 +00:00
|
|
|
Ref<BTTask> _create_task_by_class_or_path(const String &p_class_or_path) const;
|
|
|
|
void _add_task_by_class_or_path(const String &p_class_or_path);
|
2022-12-22 12:19:39 +00:00
|
|
|
void _remove_task(const Ref<BTTask> &p_task);
|
2023-08-18 10:12:55 +00:00
|
|
|
void _update_favorite_tasks();
|
2023-08-21 11:46:35 +00:00
|
|
|
void _update_misc_menu();
|
2023-08-22 10:20:09 +00:00
|
|
|
void _update_banners();
|
2022-09-01 22:20:37 +00:00
|
|
|
void _new_bt();
|
|
|
|
void _save_bt(String p_path);
|
|
|
|
void _load_bt(String p_path);
|
2024-05-27 11:48:08 +00:00
|
|
|
void _disable_editing();
|
2022-09-03 12:01:13 +00:00
|
|
|
void _mark_as_dirty(bool p_dirty);
|
2023-08-21 16:17:34 +00:00
|
|
|
void _create_user_task_dir();
|
2023-08-22 12:43:45 +00:00
|
|
|
void _remove_task_from_favorite(const String &p_task);
|
2024-07-06 07:18:50 +00:00
|
|
|
void _save_and_restart();
|
2023-12-17 14:24:38 +00:00
|
|
|
void _extract_subtree(const String &p_path);
|
2024-01-09 12:34:24 +00:00
|
|
|
void _replace_task(const Ref<BTTask> &p_task, const Ref<BTTask> &p_by_task);
|
2022-09-01 22:20:37 +00:00
|
|
|
|
2024-05-27 11:48:08 +00:00
|
|
|
void _tab_clicked(int p_tab);
|
|
|
|
void _tab_closed(int p_tab);
|
|
|
|
void _update_tabs();
|
|
|
|
void _move_active_tab(int p_to_index);
|
2024-05-27 14:53:44 +00:00
|
|
|
void _tab_input(const Ref<InputEvent> &p_input);
|
|
|
|
void _show_tab_context_menu();
|
|
|
|
void _tab_menu_option_selected(int p_id);
|
2024-05-28 09:16:37 +00:00
|
|
|
void _tab_plan_edited(int p_tab);
|
2024-05-27 11:48:08 +00:00
|
|
|
|
2022-11-22 20:00:08 +00:00
|
|
|
void _reload_modified();
|
|
|
|
void _resave_modified(String _str = "");
|
2024-01-09 12:34:24 +00:00
|
|
|
void _popup_file_dialog(FileDialog *p_dialog) { p_dialog->popup_centered_clamped(Size2i(700, 500), 0.8f); }
|
2024-01-17 14:17:22 +00:00
|
|
|
void _popup_info_dialog(const String &p_text);
|
2022-11-22 20:00:08 +00:00
|
|
|
|
2022-12-17 12:39:37 +00:00
|
|
|
void _rename_task_confirmed();
|
2022-09-01 22:20:37 +00:00
|
|
|
void _on_tree_rmb(const Vector2 &p_menu_pos);
|
2023-08-16 14:07:04 +00:00
|
|
|
void _action_selected(int p_id);
|
2023-08-20 09:34:13 +00:00
|
|
|
void _misc_option_selected(int p_id);
|
2023-09-25 16:07:26 +00:00
|
|
|
void _on_probability_edited(double p_value);
|
2023-09-25 20:36:37 +00:00
|
|
|
void _update_probability_edit();
|
|
|
|
void _probability_popup_closed();
|
2022-12-15 07:26:52 +00:00
|
|
|
void _on_tree_task_selected(const Ref<BTTask> &p_task);
|
2024-08-05 14:34:54 +00:00
|
|
|
void _on_tree_task_activated();
|
2022-12-15 07:26:52 +00:00
|
|
|
void _on_visibility_changed();
|
|
|
|
void _on_header_pressed();
|
2022-09-01 22:20:37 +00:00
|
|
|
void _on_save_pressed();
|
2022-09-02 13:43:54 +00:00
|
|
|
void _on_history_back();
|
|
|
|
void _on_history_forward();
|
2022-09-03 15:00:20 +00:00
|
|
|
void _on_task_dragged(Ref<BTTask> p_task, Ref<BTTask> p_to_task, int p_type);
|
2024-01-09 12:34:24 +00:00
|
|
|
void _on_resources_reload(const PackedStringArray &p_resources);
|
2024-07-10 16:15:35 +00:00
|
|
|
void _on_new_script_pressed();
|
2023-12-14 22:18:44 +00:00
|
|
|
void _task_type_selected(const String &p_class_or_path);
|
2024-05-30 13:55:49 +00:00
|
|
|
void _copy_version_info();
|
2023-12-14 22:18:44 +00:00
|
|
|
|
2024-01-09 12:34:24 +00:00
|
|
|
void _edit_project_settings();
|
|
|
|
void _process_shortcut_input(const Ref<InputEvent> &p_event);
|
|
|
|
|
|
|
|
#ifdef LIMBOAI_MODULE
|
|
|
|
virtual void shortcut_input(const Ref<InputEvent> &p_event) override { _process_shortcut_input(p_event); }
|
|
|
|
#endif // LIMBOAI_MODULE
|
2023-08-16 14:07:04 +00:00
|
|
|
|
2022-09-01 22:20:37 +00:00
|
|
|
protected:
|
2024-01-09 12:34:24 +00:00
|
|
|
virtual void _do_update_theme_item_cache();
|
2022-09-01 22:20:37 +00:00
|
|
|
|
2022-09-06 11:28:25 +00:00
|
|
|
void _notification(int p_what);
|
2023-08-29 09:47:48 +00:00
|
|
|
static void _bind_methods();
|
2022-09-06 11:28:25 +00:00
|
|
|
|
2022-09-01 22:20:37 +00:00
|
|
|
public:
|
2024-01-09 12:34:24 +00:00
|
|
|
void set_plugin(EditorPlugin *p_plugin) { plugin = p_plugin; };
|
2022-11-22 20:00:08 +00:00
|
|
|
void edit_bt(Ref<BehaviorTree> p_behavior_tree, bool p_force_refresh = false);
|
2024-01-28 16:49:38 +00:00
|
|
|
Ref<BlackboardPlan> get_edited_blackboard_plan();
|
2022-09-05 19:57:24 +00:00
|
|
|
|
2022-09-03 12:01:13 +00:00
|
|
|
void apply_changes();
|
|
|
|
|
2024-01-09 12:34:24 +00:00
|
|
|
#ifdef LIMBOAI_GDEXTENSION
|
2024-02-07 11:36:59 +00:00
|
|
|
virtual void _shortcut_input(const Ref<InputEvent> &p_event) override { _process_shortcut_input(p_event); }
|
2024-01-13 16:10:42 +00:00
|
|
|
#endif
|
2024-01-09 12:34:24 +00:00
|
|
|
|
2022-12-15 07:26:52 +00:00
|
|
|
LimboAIEditor();
|
2022-09-01 22:20:37 +00:00
|
|
|
~LimboAIEditor();
|
|
|
|
};
|
|
|
|
|
|
|
|
class LimboAIEditorPlugin : public EditorPlugin {
|
|
|
|
GDCLASS(LimboAIEditorPlugin, EditorPlugin);
|
|
|
|
|
|
|
|
private:
|
|
|
|
LimboAIEditor *limbo_ai_editor;
|
|
|
|
|
|
|
|
protected:
|
2024-01-09 20:47:22 +00:00
|
|
|
static void _bind_methods();
|
2022-09-01 22:20:37 +00:00
|
|
|
void _notification(int p_notification);
|
|
|
|
|
|
|
|
public:
|
2024-01-09 12:34:24 +00:00
|
|
|
#ifdef LIMBOAI_MODULE
|
2022-12-15 07:26:52 +00:00
|
|
|
bool has_main_screen() const override { return true; }
|
2024-01-09 12:34:24 +00:00
|
|
|
|
|
|
|
virtual String get_name() const override { return "LimboAI"; }
|
2022-12-15 07:26:52 +00:00
|
|
|
virtual void make_visible(bool p_visible) override;
|
|
|
|
virtual void apply_changes() override;
|
|
|
|
virtual void edit(Object *p_object) override;
|
|
|
|
virtual bool handles(Object *p_object) const override;
|
2024-01-09 12:34:24 +00:00
|
|
|
|
2024-01-13 16:10:42 +00:00
|
|
|
#elif LIMBOAI_GDEXTENSION
|
2024-01-09 12:34:24 +00:00
|
|
|
bool _has_main_screen() const override { return true; }
|
|
|
|
|
|
|
|
virtual String _get_plugin_name() const override { return "LimboAI"; }
|
|
|
|
virtual void _make_visible(bool p_visible) override;
|
|
|
|
virtual void _apply_changes() override;
|
|
|
|
virtual void _edit(Object *p_object) override;
|
|
|
|
virtual bool _handles(Object *p_object) const override;
|
2024-01-10 00:17:09 +00:00
|
|
|
virtual Ref<Texture2D> _get_plugin_icon() const override;
|
2024-01-13 16:10:42 +00:00
|
|
|
#endif // LIMBOAI_MODULE & LIMBOAI_GDEXTENSION
|
2022-12-15 07:26:52 +00:00
|
|
|
|
|
|
|
LimboAIEditorPlugin();
|
2022-09-01 22:20:37 +00:00
|
|
|
~LimboAIEditorPlugin();
|
|
|
|
};
|
|
|
|
|
2024-01-13 16:10:42 +00:00
|
|
|
#endif // LIMBO_AI_EDITOR_PLUGIN_H
|
2022-09-01 22:20:37 +00:00
|
|
|
|
2024-01-11 10:22:02 +00:00
|
|
|
#endif // ! TOOLS_ENABLED
|