Port TaskPalette
Not even sure if it works, since I need other bits before I test it.
This commit is contained in:
parent
73497b1908
commit
97daa29eda
|
@ -11,9 +11,12 @@
|
||||||
|
|
||||||
#include "task_palette.h"
|
#include "task_palette.h"
|
||||||
|
|
||||||
#include "modules/limboai/util/limbo_task_db.h"
|
#include "../util/limbo_def.h"
|
||||||
#include "modules/limboai/util/limbo_utility.h"
|
#include "../util/limbo_string_names.h"
|
||||||
|
#include "../util/limbo_task_db.h"
|
||||||
|
#include "../util/limbo_utility.h"
|
||||||
|
|
||||||
|
#ifdef LIMBO_MODULE
|
||||||
#include "core/config/project_settings.h"
|
#include "core/config/project_settings.h"
|
||||||
#include "core/error/error_macros.h"
|
#include "core/error/error_macros.h"
|
||||||
#include "editor/editor_help.h"
|
#include "editor/editor_help.h"
|
||||||
|
@ -23,9 +26,38 @@
|
||||||
#include "editor/plugins/script_editor_plugin.h"
|
#include "editor/plugins/script_editor_plugin.h"
|
||||||
#include "scene/gui/check_box.h"
|
#include "scene/gui/check_box.h"
|
||||||
|
|
||||||
|
#endif // LIMBO_MODULE
|
||||||
|
|
||||||
|
#ifdef LIMBOAI_GDEXTENSION
|
||||||
|
#include <godot_cpp/classes/button_group.hpp>
|
||||||
|
#include <godot_cpp/classes/check_box.hpp>
|
||||||
|
#include <godot_cpp/classes/config_file.hpp>
|
||||||
|
#include <godot_cpp/classes/control.hpp>
|
||||||
|
#include <godot_cpp/classes/editor_interface.hpp>
|
||||||
|
#include <godot_cpp/classes/editor_paths.hpp>
|
||||||
|
#include <godot_cpp/classes/font.hpp>
|
||||||
|
#include <godot_cpp/classes/global_constants.hpp>
|
||||||
|
#include <godot_cpp/classes/h_box_container.hpp>
|
||||||
|
#include <godot_cpp/classes/h_flow_container.hpp>
|
||||||
|
#include <godot_cpp/classes/input_event_mouse_button.hpp>
|
||||||
|
#include <godot_cpp/classes/label.hpp>
|
||||||
|
#include <godot_cpp/classes/popup_menu.hpp>
|
||||||
|
#include <godot_cpp/classes/project_settings.hpp>
|
||||||
|
#include <godot_cpp/classes/resource_loader.hpp>
|
||||||
|
#include <godot_cpp/classes/script_editor.hpp>
|
||||||
|
#include <godot_cpp/classes/script_editor_base.hpp>
|
||||||
|
#include <godot_cpp/classes/style_box.hpp>
|
||||||
|
|
||||||
|
using namespace godot;
|
||||||
|
#endif // LIMBOAI_GDEXTENSION
|
||||||
|
|
||||||
//**** TaskButton
|
//**** TaskButton
|
||||||
|
|
||||||
Control *TaskButton::make_custom_tooltip(const String &p_text) const {
|
void TaskButton::_bind_methods() {
|
||||||
|
}
|
||||||
|
|
||||||
|
Control *TaskButton::_do_make_tooltip(const String &p_text) const {
|
||||||
|
#ifdef LIMBOAI_MODULE
|
||||||
EditorHelpBit *help_bit = memnew(EditorHelpBit);
|
EditorHelpBit *help_bit = memnew(EditorHelpBit);
|
||||||
help_bit->get_rich_text()->set_custom_minimum_size(Size2(360 * EDSCALE, 1));
|
help_bit->get_rich_text()->set_custom_minimum_size(Size2(360 * EDSCALE, 1));
|
||||||
|
|
||||||
|
@ -39,6 +71,13 @@ Control *TaskButton::make_custom_tooltip(const String &p_text) const {
|
||||||
help_bit->set_text(help_text);
|
help_bit->set_text(help_text);
|
||||||
|
|
||||||
return help_bit;
|
return help_bit;
|
||||||
|
#endif // LIMBOAI_MODULE
|
||||||
|
|
||||||
|
#ifdef LIMBOAI_GDEXTENSION
|
||||||
|
// TODO: When we figure out how to retrieve documentation in GDEXTENSION, should add a tooltip control here.
|
||||||
|
#endif // LIMBOAI_GDEXTENSION
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskButton::TaskButton() {
|
TaskButton::TaskButton() {
|
||||||
|
@ -50,7 +89,7 @@ TaskButton::TaskButton() {
|
||||||
//**** TaskPaletteSection
|
//**** TaskPaletteSection
|
||||||
|
|
||||||
void TaskPaletteSection::_on_task_button_pressed(const String &p_task) {
|
void TaskPaletteSection::_on_task_button_pressed(const String &p_task) {
|
||||||
emit_signal(SNAME("task_button_pressed"), p_task);
|
emit_signal(LSNAME(task_button_pressed), p_task);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskPaletteSection::_on_task_button_gui_input(const Ref<InputEvent> &p_event, const String &p_task) {
|
void TaskPaletteSection::_on_task_button_gui_input(const Ref<InputEvent> &p_event, const String &p_task) {
|
||||||
|
@ -59,8 +98,8 @@ void TaskPaletteSection::_on_task_button_gui_input(const Ref<InputEvent> &p_even
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<InputEventMouseButton> mb = p_event;
|
Ref<InputEventMouseButton> mb = p_event;
|
||||||
if (mb.is_valid() && mb->get_button_index() == MouseButton::RIGHT) {
|
if (mb.is_valid() && mb->get_button_index() == MBTN_RIGHT) {
|
||||||
emit_signal(SNAME("task_button_rmb"), p_task);
|
emit_signal(LSNAME(task_button_rmb), p_task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,34 +127,33 @@ void TaskPaletteSection::set_filter(String p_filter_text) {
|
||||||
void TaskPaletteSection::add_task_button(const String &p_name, const Ref<Texture> &icon, const String &p_tooltip, Variant p_meta) {
|
void TaskPaletteSection::add_task_button(const String &p_name, const Ref<Texture> &icon, const String &p_tooltip, Variant p_meta) {
|
||||||
TaskButton *btn = memnew(TaskButton);
|
TaskButton *btn = memnew(TaskButton);
|
||||||
btn->set_text(p_name);
|
btn->set_text(p_name);
|
||||||
btn->set_icon(icon);
|
BUTTON_SET_ICON(btn, icon);
|
||||||
btn->set_tooltip_text(p_tooltip);
|
btn->set_tooltip_text(p_tooltip);
|
||||||
btn->add_theme_constant_override(SNAME("icon_max_width"), 16 * EDSCALE); // Force user icons to be of the proper size.
|
btn->add_theme_constant_override(LSNAME(icon_max_width), 16 * EDSCALE); // Force user icons to be of the proper size.
|
||||||
btn->connect(SNAME("pressed"), callable_mp(this, &TaskPaletteSection::_on_task_button_pressed).bind(p_meta));
|
btn->connect(LSNAME(pressed), callable_mp(this, &TaskPaletteSection::_on_task_button_pressed).bind(p_meta));
|
||||||
btn->connect(SNAME("gui_input"), callable_mp(this, &TaskPaletteSection::_on_task_button_gui_input).bind(p_meta));
|
btn->connect(LSNAME(gui_input), callable_mp(this, &TaskPaletteSection::_on_task_button_gui_input).bind(p_meta));
|
||||||
tasks_container->add_child(btn);
|
tasks_container->add_child(btn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskPaletteSection::set_collapsed(bool p_collapsed) {
|
void TaskPaletteSection::set_collapsed(bool p_collapsed) {
|
||||||
tasks_container->set_visible(!p_collapsed);
|
tasks_container->set_visible(!p_collapsed);
|
||||||
section_header->set_icon(p_collapsed ? theme_cache.arrow_right_icon : theme_cache.arrow_down_icon);
|
BUTTON_SET_ICON(section_header, (p_collapsed ? theme_cache.arrow_right_icon : theme_cache.arrow_down_icon));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TaskPaletteSection::is_collapsed() const {
|
bool TaskPaletteSection::is_collapsed() const {
|
||||||
return !tasks_container->is_visible();
|
return !tasks_container->is_visible();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskPaletteSection::_update_theme_item_cache() {
|
void TaskPaletteSection::_do_update_theme_item_cache() {
|
||||||
VBoxContainer::_update_theme_item_cache();
|
theme_cache.arrow_down_icon = get_theme_icon(LSNAME(GuiTreeArrowDown), LSNAME(EditorIcons));
|
||||||
|
theme_cache.arrow_right_icon = get_theme_icon(LSNAME(GuiTreeArrowRight), LSNAME(EditorIcons));
|
||||||
theme_cache.arrow_down_icon = get_theme_icon(SNAME("GuiTreeArrowDown"), SNAME("EditorIcons"));
|
|
||||||
theme_cache.arrow_right_icon = get_theme_icon(SNAME("GuiTreeArrowRight"), SNAME("EditorIcons"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskPaletteSection::_notification(int p_what) {
|
void TaskPaletteSection::_notification(int p_what) {
|
||||||
if (p_what == NOTIFICATION_THEME_CHANGED) {
|
if (p_what == NOTIFICATION_THEME_CHANGED) {
|
||||||
section_header->set_icon(is_collapsed() ? theme_cache.arrow_right_icon : theme_cache.arrow_down_icon);
|
_do_update_theme_item_cache();
|
||||||
section_header->add_theme_font_override(SNAME("font"), get_theme_font(SNAME("bold"), SNAME("EditorFonts")));
|
BUTTON_SET_ICON(section_header, (is_collapsed() ? theme_cache.arrow_right_icon : theme_cache.arrow_down_icon));
|
||||||
|
section_header->add_theme_font_override(LSNAME(font), get_theme_font(LSNAME(bold), LSNAME(EditorFonts)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +167,7 @@ TaskPaletteSection::TaskPaletteSection(String p_category_name) {
|
||||||
add_child(section_header);
|
add_child(section_header);
|
||||||
section_header->set_text(p_category_name);
|
section_header->set_text(p_category_name);
|
||||||
section_header->set_focus_mode(FOCUS_NONE);
|
section_header->set_focus_mode(FOCUS_NONE);
|
||||||
section_header->connect("pressed", callable_mp(this, &TaskPaletteSection::_on_header_pressed));
|
section_header->connect(LSNAME(pressed), callable_mp(this, &TaskPaletteSection::_on_header_pressed));
|
||||||
|
|
||||||
tasks_container = memnew(HFlowContainer);
|
tasks_container = memnew(HFlowContainer);
|
||||||
add_child(tasks_container);
|
add_child(tasks_container);
|
||||||
|
@ -148,38 +186,36 @@ void TaskPalette::_menu_action_selected(int p_id) {
|
||||||
case MENU_OPEN_DOC: {
|
case MENU_OPEN_DOC: {
|
||||||
String help_class;
|
String help_class;
|
||||||
if (context_task.begins_with("res://")) {
|
if (context_task.begins_with("res://")) {
|
||||||
Ref<Script> s = ResourceLoader::load(context_task, "Script");
|
help_class = "\"" + context_task.get_basename().to_pascal_case() + "\"";
|
||||||
help_class = s->get_language()->get_global_class_name(context_task);
|
} else {
|
||||||
}
|
|
||||||
if (help_class.is_empty()) {
|
|
||||||
// Assuming context task is core class.
|
// Assuming context task is core class.
|
||||||
help_class = context_task;
|
help_class = context_task;
|
||||||
}
|
}
|
||||||
ScriptEditor::get_singleton()->goto_help("class_name:" + help_class);
|
SHOW_DOC("class_name:" + help_class);
|
||||||
EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT);
|
|
||||||
} break;
|
} break;
|
||||||
case MENU_EDIT_SCRIPT: {
|
case MENU_EDIT_SCRIPT: {
|
||||||
ERR_FAIL_COND(!context_task.begins_with("res://"));
|
ERR_FAIL_COND(!context_task.begins_with("res://"));
|
||||||
Ref<Resource> res = ScriptEditor::get_singleton()->open_file(context_task);
|
EDIT_SCRIPT(context_task);
|
||||||
ERR_FAIL_COND_MSG(res.is_null(), "Failed to load script: " + context_task);
|
|
||||||
EditorNode::get_singleton()->edit_resource(res);
|
|
||||||
} break;
|
} break;
|
||||||
case MENU_FAVORITE: {
|
case MENU_FAVORITE: {
|
||||||
PackedStringArray favorite_tasks = GLOBAL_GET("limbo_ai/behavior_tree/favorite_tasks");
|
PackedStringArray favorite_tasks = GLOBAL_GET("limbo_ai/behavior_tree/favorite_tasks");
|
||||||
if (favorite_tasks.has(context_task)) {
|
if (favorite_tasks.has(context_task)) {
|
||||||
favorite_tasks.erase(context_task);
|
int idx = favorite_tasks.find(context_task);
|
||||||
|
if (idx >= 0) {
|
||||||
|
favorite_tasks.remove_at(idx);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
favorite_tasks.append(context_task);
|
favorite_tasks.append(context_task);
|
||||||
}
|
}
|
||||||
ProjectSettings::get_singleton()->set_setting("limbo_ai/behavior_tree/favorite_tasks", favorite_tasks);
|
ProjectSettings::get_singleton()->set_setting("limbo_ai/behavior_tree/favorite_tasks", favorite_tasks);
|
||||||
ProjectSettings::get_singleton()->save();
|
ProjectSettings::get_singleton()->save();
|
||||||
emit_signal(SNAME("favorite_tasks_changed"));
|
emit_signal(LSNAME(favorite_tasks_changed));
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskPalette::_on_task_button_pressed(const String &p_task) {
|
void TaskPalette::_on_task_button_pressed(const String &p_task) {
|
||||||
emit_signal(SNAME("task_selected"), p_task);
|
emit_signal(LSNAME(task_selected), p_task);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskPalette::_on_task_button_rmb(const String &p_task) {
|
void TaskPalette::_on_task_button_rmb(const String &p_task) {
|
||||||
|
@ -254,7 +290,7 @@ void TaskPalette::_update_filter_popup() {
|
||||||
category_item->set_pressed_no_signal(LOGICAL_XOR(
|
category_item->set_pressed_no_signal(LOGICAL_XOR(
|
||||||
filter_settings.excluded_categories.has(cat),
|
filter_settings.excluded_categories.has(cat),
|
||||||
filter_settings.category_filter == FilterSettings::CategoryFilter::CATEGORY_INCLUDE));
|
filter_settings.category_filter == FilterSettings::CategoryFilter::CATEGORY_INCLUDE));
|
||||||
category_item->connect(SNAME("toggled"), callable_mp(this, &TaskPalette::_category_item_toggled).bind(cat));
|
category_item->connect(LSNAME(toggled), callable_mp(this, &TaskPalette::_category_item_toggled).bind(cat));
|
||||||
category_list->add_child(category_item);
|
category_list->add_child(category_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,7 +308,9 @@ void TaskPalette::_show_filter_popup() {
|
||||||
|
|
||||||
tool_filters->set_pressed_no_signal(true);
|
tool_filters->set_pressed_no_signal(true);
|
||||||
|
|
||||||
Rect2i rect = tool_filters->get_screen_rect();
|
Transform2D xform = tool_filters->get_screen_transform();
|
||||||
|
Rect2i rect = Rect2(xform.get_origin(), xform.get_scale() * tool_filters->get_size());
|
||||||
|
|
||||||
rect.position.y += rect.size.height;
|
rect.position.y += rect.size.height;
|
||||||
rect.size.height = 0;
|
rect.size.height = 0;
|
||||||
filter_popup->reset_size();
|
filter_popup->reset_size();
|
||||||
|
@ -328,7 +366,7 @@ void TaskPalette::_category_item_toggled(bool p_pressed, const String &p_categor
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskPalette::_filter_data_changed() {
|
void TaskPalette::_filter_data_changed() {
|
||||||
call_deferred(SNAME("refresh"));
|
call_deferred(LSNAME(refresh));
|
||||||
_update_filter_button();
|
_update_filter_button();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,10 +386,10 @@ void TaskPalette::refresh() {
|
||||||
// Restore collapsed state from config.
|
// Restore collapsed state from config.
|
||||||
Ref<ConfigFile> cf;
|
Ref<ConfigFile> cf;
|
||||||
cf.instantiate();
|
cf.instantiate();
|
||||||
String conf_path = EditorPaths::get_singleton()->get_project_settings_dir().path_join("limbo_ai.cfg");
|
String conf_path = GET_PROJECT_SETTINGS_DIR().path_join("limbo_ai.cfg");
|
||||||
if (cf->load(conf_path) == OK) {
|
if (cf->load(conf_path) == OK) {
|
||||||
Variant value = cf->get_value("task_palette", "collapsed_sections", Array());
|
Variant value = cf->get_value("task_palette", "collapsed_sections", Array());
|
||||||
if (value.is_array()) {
|
if (VARIANT_IS_ARRAY(value)) {
|
||||||
Array arr = value;
|
Array arr = value;
|
||||||
for (int i = 0; i < arr.size(); i++) {
|
for (int i = 0; i < arr.size(); i++) {
|
||||||
if (arr[i].get_type() == Variant::STRING) {
|
if (arr[i].get_type() == Variant::STRING) {
|
||||||
|
@ -389,26 +427,36 @@ void TaskPalette::refresh() {
|
||||||
Ref<Texture2D> icon = LimboUtility::get_singleton()->get_task_icon(task_meta);
|
Ref<Texture2D> icon = LimboUtility::get_singleton()->get_task_icon(task_meta);
|
||||||
|
|
||||||
String tname;
|
String tname;
|
||||||
DocTools *dd = EditorHelp::get_doc_data();
|
String descr;
|
||||||
HashMap<String, DocData::ClassDoc>::Iterator E;
|
|
||||||
if (task_meta.begins_with("res:")) {
|
if (task_meta.begins_with("res:")) {
|
||||||
if (filter_settings.type_filter == FilterSettings::TYPE_CORE) {
|
if (filter_settings.type_filter == FilterSettings::TYPE_CORE) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
tname = task_meta.get_file().get_basename().trim_prefix("BT").to_pascal_case();
|
tname = task_meta.get_file().get_basename().trim_prefix("BT").to_pascal_case();
|
||||||
E = dd->class_list.find(vformat("\"%s\"", task_meta.trim_prefix("res://")));
|
|
||||||
if (!E) {
|
|
||||||
E = dd->class_list.find(tname);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (filter_settings.type_filter == FilterSettings::TYPE_USER) {
|
if (filter_settings.type_filter == FilterSettings::TYPE_USER) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
tname = task_meta.trim_prefix("BT");
|
tname = task_meta.trim_prefix("BT");
|
||||||
E = dd->class_list.find(task_meta);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String descr;
|
#ifdef LIMBOAI_MODULE
|
||||||
|
// Get documentation.
|
||||||
|
DocTools *dd = EditorHelp::get_doc_data();
|
||||||
|
HashMap<String, DocData::ClassDoc>::Iterator E;
|
||||||
|
// Try-find core class.
|
||||||
|
E = dd->class_list.find(task_meta);
|
||||||
|
if (!E) {
|
||||||
|
// Try to find by script filename.
|
||||||
|
E = dd->class_list.find(vformat("\"%s\"", task_meta.trim_prefix("res://")));
|
||||||
|
}
|
||||||
|
if (!E) {
|
||||||
|
// Try-find global script class.
|
||||||
|
String maybe_class_name = task_meta.get_file().get_basename().to_pascal_case();
|
||||||
|
E = dd->class_list.find(maybe_class_name);
|
||||||
|
}
|
||||||
|
|
||||||
if (E) {
|
if (E) {
|
||||||
if (E->value.description.is_empty() || E->value.description.length() > 1400) {
|
if (E->value.description.is_empty() || E->value.description.length() > 1400) {
|
||||||
descr = DTR(E->value.brief_description);
|
descr = DTR(E->value.brief_description);
|
||||||
|
@ -416,12 +464,15 @@ void TaskPalette::refresh() {
|
||||||
descr = DTR(E->value.description);
|
descr = DTR(E->value.description);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // LIMBOAI_MODULE
|
||||||
|
|
||||||
|
// TODO: Documentation tooltips are only available in the module. Find a way to show em in GDExtension.
|
||||||
|
|
||||||
sec->add_task_button(tname, icon, descr, task_meta);
|
sec->add_task_button(tname, icon, descr, task_meta);
|
||||||
}
|
}
|
||||||
sec->set_filter("");
|
sec->set_filter("");
|
||||||
sec->connect(SNAME("task_button_pressed"), callable_mp(this, &TaskPalette::_on_task_button_pressed));
|
sec->connect(LSNAME(task_button_pressed), callable_mp(this, &TaskPalette::_on_task_button_pressed));
|
||||||
sec->connect(SNAME("task_button_rmb"), callable_mp(this, &TaskPalette::_on_task_button_rmb));
|
sec->connect(LSNAME(task_button_rmb), callable_mp(this, &TaskPalette::_on_task_button_rmb));
|
||||||
sections->add_child(sec);
|
sections->add_child(sec);
|
||||||
sec->set_collapsed(!dialog_mode && collapsed_sections.has(cat));
|
sec->set_collapsed(!dialog_mode && collapsed_sections.has(cat));
|
||||||
}
|
}
|
||||||
|
@ -437,15 +488,13 @@ void TaskPalette::use_dialog_mode() {
|
||||||
dialog_mode = true;
|
dialog_mode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskPalette::_update_theme_item_cache() {
|
void TaskPalette::_do_update_theme_item_cache() {
|
||||||
PanelContainer::_update_theme_item_cache();
|
theme_cache.add_to_favorites_icon = get_theme_icon(LSNAME(Favorites), LSNAME(EditorIcons));
|
||||||
|
theme_cache.edit_script_icon = get_theme_icon(LSNAME(Script), LSNAME(EditorIcons));
|
||||||
|
theme_cache.open_doc_icon = get_theme_icon(LSNAME(Help), LSNAME(EditorIcons));
|
||||||
|
theme_cache.remove_from_favorites_icon = get_theme_icon(LSNAME(NonFavorite), LSNAME(EditorIcons));
|
||||||
|
|
||||||
theme_cache.add_to_favorites_icon = get_theme_icon(SNAME("Favorites"), SNAME("EditorIcons"));
|
theme_cache.category_choice_background = get_theme_stylebox(LSNAME(normal), LSNAME(LineEdit));
|
||||||
theme_cache.edit_script_icon = get_theme_icon(SNAME("Script"), SNAME("EditorIcons"));
|
|
||||||
theme_cache.open_doc_icon = get_theme_icon(SNAME("Help"), SNAME("EditorIcons"));
|
|
||||||
theme_cache.remove_from_favorites_icon = get_theme_icon(SNAME("NonFavorite"), SNAME("EditorIcons"));
|
|
||||||
|
|
||||||
theme_cache.category_choice_background = get_theme_stylebox(SNAME("normal"), SNAME("LineEdit"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskPalette::_notification(int p_what) {
|
void TaskPalette::_notification(int p_what) {
|
||||||
|
@ -453,20 +502,20 @@ void TaskPalette::_notification(int p_what) {
|
||||||
case NOTIFICATION_ENTER_TREE: {
|
case NOTIFICATION_ENTER_TREE: {
|
||||||
Ref<ConfigFile> cf;
|
Ref<ConfigFile> cf;
|
||||||
cf.instantiate();
|
cf.instantiate();
|
||||||
String conf_path = EditorPaths::get_singleton()->get_project_settings_dir().path_join("limbo_ai.cfg");
|
String conf_path = GET_PROJECT_SETTINGS_DIR().path_join("limbo_ai.cfg");
|
||||||
if (cf->load(conf_path) == OK) {
|
if (cf->load(conf_path) == OK) {
|
||||||
Variant value = cf->get_value("task_palette", "type_filter", FilterSettings::TypeFilter(0));
|
Variant value = cf->get_value("task_palette", "type_filter", FilterSettings::TypeFilter(0));
|
||||||
if (value.is_num()) {
|
if (VARIANT_IS_NUM(value)) {
|
||||||
filter_settings.type_filter = (FilterSettings::TypeFilter)(int)value;
|
filter_settings.type_filter = (FilterSettings::TypeFilter)(int)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
value = cf->get_value("task_palette", "category_filter", FilterSettings::CategoryFilter(0));
|
value = cf->get_value("task_palette", "category_filter", FilterSettings::CategoryFilter(0));
|
||||||
if (value.is_num()) {
|
if (VARIANT_IS_NUM(value)) {
|
||||||
filter_settings.category_filter = (FilterSettings::CategoryFilter)(int)value;
|
filter_settings.category_filter = (FilterSettings::CategoryFilter)(int)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
value = cf->get_value("task_palette", "excluded_categories", Array());
|
value = cf->get_value("task_palette", "excluded_categories", Array());
|
||||||
if (value.is_array()) {
|
if (VARIANT_IS_ARRAY(value)) {
|
||||||
Array arr = value;
|
Array arr = value;
|
||||||
for (int i = 0; i < arr.size(); i++) {
|
for (int i = 0; i < arr.size(); i++) {
|
||||||
if (arr[i].get_type() == Variant::STRING) {
|
if (arr[i].get_type() == Variant::STRING) {
|
||||||
|
@ -480,7 +529,7 @@ void TaskPalette::_notification(int p_what) {
|
||||||
case NOTIFICATION_EXIT_TREE: {
|
case NOTIFICATION_EXIT_TREE: {
|
||||||
Ref<ConfigFile> cf;
|
Ref<ConfigFile> cf;
|
||||||
cf.instantiate();
|
cf.instantiate();
|
||||||
String conf_path = EditorPaths::get_singleton()->get_project_settings_dir().path_join("limbo_ai.cfg");
|
String conf_path = GET_PROJECT_SETTINGS_DIR().path_join("limbo_ai.cfg");
|
||||||
cf->load(conf_path);
|
cf->load(conf_path);
|
||||||
|
|
||||||
Array collapsed_sections;
|
Array collapsed_sections;
|
||||||
|
@ -504,12 +553,14 @@ void TaskPalette::_notification(int p_what) {
|
||||||
cf->save(conf_path);
|
cf->save(conf_path);
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_THEME_CHANGED: {
|
case NOTIFICATION_THEME_CHANGED: {
|
||||||
tool_filters->set_icon(get_theme_icon(SNAME("AnimationFilter"), SNAME("EditorIcons")));
|
_do_update_theme_item_cache();
|
||||||
tool_refresh->set_icon(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")));
|
|
||||||
select_all->set_icon(get_theme_icon(SNAME("LimboSelectAll"), SNAME("EditorIcons")));
|
|
||||||
deselect_all->set_icon(get_theme_icon(SNAME("LimboDeselectAll"), SNAME("EditorIcons")));
|
|
||||||
|
|
||||||
filter_edit->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
|
BUTTON_SET_ICON(tool_filters, get_theme_icon(LSNAME(AnimationFilter), LSNAME(EditorIcons)));
|
||||||
|
BUTTON_SET_ICON(tool_refresh, get_theme_icon(LSNAME(Reload), LSNAME(EditorIcons)));
|
||||||
|
BUTTON_SET_ICON(select_all, get_theme_icon(LSNAME(LimboSelectAll), LSNAME(EditorIcons)));
|
||||||
|
BUTTON_SET_ICON(deselect_all, get_theme_icon(LSNAME(LimboDeselectAll), LSNAME(EditorIcons)));
|
||||||
|
|
||||||
|
filter_edit->set_right_icon(get_theme_icon(LSNAME(Search), LSNAME(EditorIcons)));
|
||||||
|
|
||||||
category_choice->queue_redraw();
|
category_choice->queue_redraw();
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#ifndef TASK_PALETTE_H
|
#ifndef TASK_PALETTE_H
|
||||||
#define TASK_PALETTE_H
|
#define TASK_PALETTE_H
|
||||||
|
|
||||||
|
#ifdef LIMBOAI_MODULE
|
||||||
#include "scene/gui/panel_container.h"
|
#include "scene/gui/panel_container.h"
|
||||||
|
|
||||||
#include "scene/gui/box_container.h"
|
#include "scene/gui/box_container.h"
|
||||||
|
@ -19,12 +20,39 @@
|
||||||
#include "scene/gui/flow_container.h"
|
#include "scene/gui/flow_container.h"
|
||||||
#include "scene/gui/line_edit.h"
|
#include "scene/gui/line_edit.h"
|
||||||
#include "scene/gui/popup.h"
|
#include "scene/gui/popup.h"
|
||||||
|
#endif // LIMBOAI_MODULE
|
||||||
|
|
||||||
|
#ifdef LIMBOAI_GDEXTENSION
|
||||||
|
#include <godot_cpp/classes/button.hpp>
|
||||||
|
#include <godot_cpp/classes/control.hpp>
|
||||||
|
#include <godot_cpp/classes/flow_container.hpp>
|
||||||
|
#include <godot_cpp/classes/line_edit.hpp>
|
||||||
|
#include <godot_cpp/classes/panel_container.hpp>
|
||||||
|
#include <godot_cpp/classes/popup_panel.hpp>
|
||||||
|
#include <godot_cpp/classes/scroll_container.hpp>
|
||||||
|
#include <godot_cpp/classes/texture2d.hpp>
|
||||||
|
#include <godot_cpp/classes/v_box_container.hpp>
|
||||||
|
#include <godot_cpp/templates/hash_set.hpp>
|
||||||
|
|
||||||
|
using namespace godot;
|
||||||
|
#endif // LIMBOAI_GDEXTENSION
|
||||||
|
|
||||||
class TaskButton : public Button {
|
class TaskButton : public Button {
|
||||||
GDCLASS(TaskButton, Button);
|
GDCLASS(TaskButton, Button);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Control *_do_make_tooltip(const String &p_text) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static void _bind_methods();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual Control *make_custom_tooltip(const String &p_text) const override;
|
#ifdef LIMBOAI_MODULE
|
||||||
|
virtual Control *make_custom_tooltip(const String &p_text) const override { return _do_make_tooltip(p_text); }
|
||||||
|
#endif // LIMBOAI_MODULE
|
||||||
|
#ifdef LIMBOAI_GDEXTENSION
|
||||||
|
virtual Object *_make_custom_tooltip(const String &p_text) const override { return _do_make_tooltip(p_text); }
|
||||||
|
#endif // LIMBOAI_GDEXTENSION
|
||||||
|
|
||||||
TaskButton();
|
TaskButton();
|
||||||
};
|
};
|
||||||
|
@ -46,7 +74,7 @@ private:
|
||||||
void _on_header_pressed();
|
void _on_header_pressed();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void _update_theme_item_cache() override;
|
virtual void _do_update_theme_item_cache();
|
||||||
|
|
||||||
void _notification(int p_what);
|
void _notification(int p_what);
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
@ -60,6 +88,8 @@ public:
|
||||||
|
|
||||||
String get_category_name() const { return section_header->get_text(); }
|
String get_category_name() const { return section_header->get_text(); }
|
||||||
|
|
||||||
|
TaskPaletteSection() :
|
||||||
|
TaskPaletteSection("") {}
|
||||||
TaskPaletteSection(String p_category_name);
|
TaskPaletteSection(String p_category_name);
|
||||||
~TaskPaletteSection();
|
~TaskPaletteSection();
|
||||||
};
|
};
|
||||||
|
@ -145,7 +175,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void _update_theme_item_cache() override;
|
virtual void _do_update_theme_item_cache();
|
||||||
|
|
||||||
void _notification(int p_what);
|
void _notification(int p_what);
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
|
@ -10,11 +10,23 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "limbo_def.h"
|
#include "limbo_def.h"
|
||||||
#include "godot_cpp/classes/editor_interface.hpp"
|
|
||||||
|
#ifdef LIMBOAI_MODULE
|
||||||
|
|
||||||
|
void EDIT_SCRIPT(const String &p_path) {
|
||||||
|
Ref<Resource> res = ScriptEditor::get_singleton()->open_file(p_path);
|
||||||
|
ERR_FAIL_COND_MSG(res.is_null(), "Failed to load script: " + p_path);
|
||||||
|
EditorNode::get_singleton()->edit_resource(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // LIMBOAI_MODULE
|
||||||
|
|
||||||
#ifdef LIMBOAI_GDEXTENSION
|
#ifdef LIMBOAI_GDEXTENSION
|
||||||
|
|
||||||
|
#include "godot_cpp/classes/editor_interface.hpp"
|
||||||
#include <godot_cpp/classes/editor_settings.hpp>
|
#include <godot_cpp/classes/editor_settings.hpp>
|
||||||
|
#include <godot_cpp/classes/resource_loader.hpp>
|
||||||
|
#include <godot_cpp/classes/script.hpp>
|
||||||
#include <godot_cpp/classes/translation_server.hpp>
|
#include <godot_cpp/classes/translation_server.hpp>
|
||||||
|
|
||||||
using namespace godot;
|
using namespace godot;
|
||||||
|
@ -33,4 +45,10 @@ String TTR(const String &p_text, const String &p_context) {
|
||||||
return p_text;
|
return p_text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EDIT_SCRIPT(const String &p_path) {
|
||||||
|
Ref<Script> res = RESOURCE_LOAD(p_path, "Script");
|
||||||
|
ERR_FAIL_COND_MSG(res.is_null(), "Failed to load script: " + p_path);
|
||||||
|
EditorInterface::get_singleton()->edit_script(res);
|
||||||
|
}
|
||||||
|
|
||||||
#endif // LIMBOAI_GDEXTENSION
|
#endif // LIMBOAI_GDEXTENSION
|
||||||
|
|
|
@ -24,6 +24,15 @@
|
||||||
#define GET_SCENE_TREE() (SceneTree::get_singleton())
|
#define GET_SCENE_TREE() (SceneTree::get_singleton())
|
||||||
#define VCALL(m_method) (GDVIRTUAL_CALL(method))
|
#define VCALL(m_method) (GDVIRTUAL_CALL(method))
|
||||||
#define VCALL_ARGS(method, ...) (call(LSNAME(method), __VA_ARGS__))
|
#define VCALL_ARGS(method, ...) (call(LSNAME(method), __VA_ARGS__))
|
||||||
|
#define BUTTON_SET_ICON(m_btn, m_icon) m_btn->set_icon(m_icon)
|
||||||
|
#define RESOURCE_LOAD(m_path, m_hint) ResourceLoader::load(m_path, m_hint)
|
||||||
|
#define GET_PROJECT_SETTINGS_DIR() EditorPaths::get_singleton()->get_project_settings_dir()
|
||||||
|
|
||||||
|
#define SHOW_DOC(m_doc) ( \
|
||||||
|
ScriptEditor::get_singleton()->goto_help(m_doc); \
|
||||||
|
EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT);)
|
||||||
|
|
||||||
|
#define MBTN_RIGHT MouseButton::RIGHT
|
||||||
|
|
||||||
#endif // LIMBOAI_MODULE
|
#endif // LIMBOAI_MODULE
|
||||||
|
|
||||||
|
@ -43,14 +52,32 @@ using namespace godot;
|
||||||
#define GET_SCENE_TREE() ((SceneTree *)(Engine::get_singleton()->get_main_loop()))
|
#define GET_SCENE_TREE() ((SceneTree *)(Engine::get_singleton()->get_main_loop()))
|
||||||
#define VCALL(m_name) (call(LSNAME(m_name)))
|
#define VCALL(m_name) (call(LSNAME(m_name)))
|
||||||
#define VCALL_ARGS(m_name, ...) (call(LSNAME(m_name), __VA_ARGS__))
|
#define VCALL_ARGS(m_name, ...) (call(LSNAME(m_name), __VA_ARGS__))
|
||||||
|
#define BUTTON_SET_ICON(m_btn, m_icon) m_btn->set_button_icon(m_icon)
|
||||||
|
#define RESOURCE_LOAD(m_path, m_hint) ResourceLoader::get_singleton()->load(m_path, m_hint)
|
||||||
|
#define GET_PROJECT_SETTINGS_DIR() EditorInterface::get_singleton()->get_editor_paths()->get_project_settings_dir()
|
||||||
|
|
||||||
|
#define SHOW_DOC(m_doc) EditorInterface::get_singleton()->get_script_editor()->get_current_editor()->emit_signal("go_to_help", m_doc)
|
||||||
|
|
||||||
|
#define MBTN_RIGHT MouseButton::MOUSE_BUTTON_RIGHT
|
||||||
|
|
||||||
|
// Missing definitions
|
||||||
|
|
||||||
#define EDITOR_GET(m_var) _EDITOR_GET(m_var)
|
#define EDITOR_GET(m_var) _EDITOR_GET(m_var)
|
||||||
Variant _EDITOR_GET(const String &p_setting);
|
Variant _EDITOR_GET(const String &p_setting);
|
||||||
|
|
||||||
|
#define GLOBAL_GET(m_var) ProjectSettings::get_singleton()->get_setting_with_override(m_var)
|
||||||
|
|
||||||
#define EDSCALE ((int)EDITOR_GET("interface/editor/display_scale"))
|
#define EDSCALE ((int)EDITOR_GET("interface/editor/display_scale"))
|
||||||
|
|
||||||
String TTR(const String &p_text, const String &p_context = "");
|
String TTR(const String &p_text, const String &p_context = "");
|
||||||
|
|
||||||
#endif // LIMBOAI_GDEXTENSION
|
#endif // LIMBOAI_GDEXTENSION
|
||||||
|
|
||||||
|
// ! Shared definitions.
|
||||||
|
|
||||||
|
void EDIT_SCRIPT(const String &p_path);
|
||||||
|
|
||||||
|
#define VARIANT_IS_ARRAY(m_variant) (m_variant.get_type() >= Variant::ARRAY)
|
||||||
|
#define VARIANT_IS_NUM(m_variant) (m_variant.get_type() == Variant::INT || m_variant.get_type() == Variant::FLOAT)
|
||||||
|
|
||||||
#endif // LIMBO_DEF_H
|
#endif // LIMBO_DEF_H
|
||||||
|
|
|
@ -55,6 +55,28 @@ LimboStringNames::LimboStringNames() {
|
||||||
StatusWarning = SN("StatusWarning");
|
StatusWarning = SN("StatusWarning");
|
||||||
mode_changed = SN("mode_changed");
|
mode_changed = SN("mode_changed");
|
||||||
connect = SN("connect");
|
connect = SN("connect");
|
||||||
|
task_button_pressed = SN("task_button_pressed");
|
||||||
|
gui_input = SN("gui_input");
|
||||||
|
icon_max_width = SN("icon_max_width");
|
||||||
|
GuiTreeArrowDown = SN("GuiTreeArrowDown");
|
||||||
|
GuiTreeArrowRight = SN("GuiTreeArrowRight");
|
||||||
|
font = SN("font");
|
||||||
|
task_button_rmb = SN("task_button_rmb");
|
||||||
|
favorite_tasks_changed = SN("favorite_tasks_changed");
|
||||||
|
task_selected = SN("task_selected");
|
||||||
|
toggled = SN("toggled");
|
||||||
|
Favorites = SN("Favorites");
|
||||||
|
Script = SN("Script");
|
||||||
|
Help = SN("Help");
|
||||||
|
NonFavorite = SN("NonFavorite");
|
||||||
|
normal = SN("normal");
|
||||||
|
LineEdit = SN("LineEdit");
|
||||||
|
AnimationFilter = SN("AnimationFilter");
|
||||||
|
Reload = SN("Reload");
|
||||||
|
LimboSelectAll = SN("LimboSelectAll");
|
||||||
|
LimboDeselectAll = SN("LimboDeselectAll");
|
||||||
|
Search = SN("Search");
|
||||||
|
refresh = SN("refresh");
|
||||||
|
|
||||||
EVENT_FINISHED = "finished";
|
EVENT_FINISHED = "finished";
|
||||||
repeat_forever.parse_utf8("Repeat ∞");
|
repeat_forever.parse_utf8("Repeat ∞");
|
||||||
|
|
|
@ -74,6 +74,28 @@ public:
|
||||||
StringName StatusWarning;
|
StringName StatusWarning;
|
||||||
StringName mode_changed;
|
StringName mode_changed;
|
||||||
StringName connect;
|
StringName connect;
|
||||||
|
StringName task_button_pressed;
|
||||||
|
StringName gui_input;
|
||||||
|
StringName icon_max_width;
|
||||||
|
StringName GuiTreeArrowDown;
|
||||||
|
StringName GuiTreeArrowRight;
|
||||||
|
StringName font;
|
||||||
|
StringName task_button_rmb;
|
||||||
|
StringName favorite_tasks_changed;
|
||||||
|
StringName task_selected;
|
||||||
|
StringName toggled;
|
||||||
|
StringName Favorites;
|
||||||
|
StringName Script;
|
||||||
|
StringName Help;
|
||||||
|
StringName NonFavorite;
|
||||||
|
StringName normal;
|
||||||
|
StringName LineEdit;
|
||||||
|
StringName AnimationFilter;
|
||||||
|
StringName Reload;
|
||||||
|
StringName LimboSelectAll;
|
||||||
|
StringName LimboDeselectAll;
|
||||||
|
StringName Search;
|
||||||
|
StringName refresh;
|
||||||
|
|
||||||
String EVENT_FINISHED;
|
String EVENT_FINISHED;
|
||||||
String repeat_forever;
|
String repeat_forever;
|
||||||
|
|
Loading…
Reference in New Issue