From 40acd04eb9ce35052068283515d12bed2211b09b Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Sat, 6 Jul 2024 12:33:08 +0200 Subject: [PATCH 1/4] Fix tooltip popup too small --- editor/task_palette.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/editor/task_palette.cpp b/editor/task_palette.cpp index f49bb93..f094e0a 100644 --- a/editor/task_palette.cpp +++ b/editor/task_palette.cpp @@ -24,8 +24,8 @@ #include "editor/editor_help.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" -#include "editor/themes/editor_scale.h" #include "editor/plugins/script_editor_plugin.h" +#include "editor/themes/editor_scale.h" #include "scene/gui/check_box.h" #endif // LIMBO_MODULE @@ -70,8 +70,8 @@ Control *TaskButton::_do_make_tooltip(const String &p_text) const { } help_bit->set_custom_text(String(), String(), help_text); - - return help_bit; + EditorHelpBitTooltip::show_tooltip(help_bit, const_cast(this)); + return memnew(Control); // Make the standard tooltip invisible. #endif // LIMBOAI_MODULE #ifdef LIMBOAI_GDEXTENSION From 800bc8f16d9f7d381da5c979f70d3116319c0c88 Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Sat, 6 Jul 2024 16:46:55 +0200 Subject: [PATCH 2/4] Tooltip improvements - Fix tooltip not shown for scripted tasks in TaskPalette - Allow following links in the tooltip text - If help data cannot be found, an empty tooltip is shown instead --- editor/task_palette.cpp | 96 +++++++++++++++++++++++------------------ editor/task_palette.h | 17 ++++++-- 2 files changed, 68 insertions(+), 45 deletions(-) diff --git a/editor/task_palette.cpp b/editor/task_palette.cpp index f094e0a..158efaa 100644 --- a/editor/task_palette.cpp +++ b/editor/task_palette.cpp @@ -57,19 +57,26 @@ using namespace godot; void TaskButton::_bind_methods() { } -Control *TaskButton::_do_make_tooltip(const String &p_text) const { +Control *TaskButton::_do_make_tooltip() const { #ifdef LIMBOAI_MODULE - EditorHelpBit *help_bit = memnew(EditorHelpBit); - help_bit->set_content_height_limits(1, 360 * EDSCALE); - - String help_text; - if (!p_text.is_empty()) { - help_text = p_text; + String help_symbol; + if (task_meta.begins_with("res://")) { + help_symbol = "class|\"" + task_meta.lstrip("res://") + "\"|"; } else { - help_text = "[i]" + TTR("No description.") + "[/i]"; + help_symbol = "class|" + task_meta + "|"; + } + + EditorHelpBit *help_bit = memnew(EditorHelpBit(help_symbol)); + help_bit->set_content_height_limits(1, 360 * EDSCALE); + + String desc = _module_get_help_description(task_meta); + if (desc.is_empty() && help_bit->get_description().is_empty()) { + desc = "[i]" + TTR("No description.") + "[/i]"; + } + if (!desc.is_empty()) { + help_bit->set_description(desc); } - help_bit->set_custom_text(String(), String(), help_text); EditorHelpBitTooltip::show_tooltip(help_bit, const_cast(this)); return memnew(Control); // Make the standard tooltip invisible. #endif // LIMBOAI_MODULE @@ -81,6 +88,40 @@ Control *TaskButton::_do_make_tooltip(const String &p_text) const { return nullptr; } +#ifdef LIMBOAI_MODULE + +String TaskButton::_module_get_help_description(const String &p_class_or_script_path) const { + String descr; + + DocTools *dd = EditorHelp::get_doc_data(); + HashMap::Iterator E; + // Try to find core class. + E = dd->class_list.find(p_class_or_script_path); + if (!E) { + // Try to find by script path. + E = dd->class_list.find(vformat("\"%s\"", p_class_or_script_path.trim_prefix("res://"))); + } + if (!E) { + // Try to guess global script class from filename. + String maybe_class_name = p_class_or_script_path.get_file().get_basename().to_pascal_case(); + E = dd->class_list.find(maybe_class_name); + } + + if (E) { + if (E->value.description.is_empty()) { + descr = DTR(E->value.brief_description); + } else { + descr = DTR(E->value.description); + } + } + + // TODO: Documentation tooltips are only available in the module variant. Find a way to show em in GDExtension. + + return descr; +} + +#endif // LIMBOAI_MODULE + TaskButton::TaskButton() { set_focus_mode(FOCUS_NONE); } @@ -125,11 +166,12 @@ void TaskPaletteSection::set_filter(String p_filter_text) { } } -void TaskPaletteSection::add_task_button(const String &p_name, const Ref &icon, const String &p_tooltip, Variant p_meta) { +void TaskPaletteSection::add_task_button(const String &p_name, const Ref &icon, const String &p_meta) { TaskButton *btn = memnew(TaskButton); btn->set_text(p_name); BUTTON_SET_ICON(btn, icon); - btn->set_tooltip_text(p_tooltip); + btn->set_tooltip_text("dummy_text"); // Force tooltip to be shown. + btn->set_task_meta(p_meta); btn->add_theme_constant_override(LW_NAME(icon_max_width), 16 * EDSCALE); // Force user icons to be of the proper size. btn->connect(LW_NAME(pressed), callable_mp(this, &TaskPaletteSection::_on_task_button_pressed).bind(p_meta)); btn->connect(LW_NAME(gui_input), callable_mp(this, &TaskPaletteSection::_on_task_button_gui_input).bind(p_meta)); @@ -422,11 +464,10 @@ void TaskPalette::refresh() { TaskPaletteSection *sec = memnew(TaskPaletteSection()); sec->set_category_name(cat); - for (String task_meta : tasks) { + for (const String &task_meta : tasks) { Ref icon = LimboUtility::get_singleton()->get_task_icon(task_meta); String tname; - String descr; if (task_meta.begins_with("res:")) { if (filter_settings.type_filter == FilterSettings::TYPE_CORE) { @@ -440,34 +481,7 @@ void TaskPalette::refresh() { tname = task_meta.trim_prefix("BT"); } -#ifdef LIMBOAI_MODULE - // Get documentation. - DocTools *dd = EditorHelp::get_doc_data(); - HashMap::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->value.description.is_empty() || E->value.description.length() > 1400) { - descr = DTR(E->value.brief_description); - } else { - 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, task_meta); } sec->set_filter(""); sec->connect(LW_NAME(task_button_pressed), callable_mp(this, &TaskPalette::_on_task_button_pressed)); diff --git a/editor/task_palette.h b/editor/task_palette.h index d6c02d6..4ff3da5 100644 --- a/editor/task_palette.h +++ b/editor/task_palette.h @@ -42,18 +42,27 @@ class TaskButton : public Button { GDCLASS(TaskButton, Button); private: - Control *_do_make_tooltip(const String &p_text) const; + String task_meta; + + Control *_do_make_tooltip() const; + +#ifdef LIMBOAI_MODULE + String _module_get_help_description(const String &p_class_or_script_path) const; +#endif protected: static void _bind_methods(); public: #ifdef LIMBOAI_MODULE - virtual Control *make_custom_tooltip(const String &p_text) const override { return _do_make_tooltip(p_text); } + virtual Control *make_custom_tooltip(const String &p_text) const override { return _do_make_tooltip(); } #elif LIMBOAI_GDEXTENSION - virtual Object *_make_custom_tooltip(const String &p_text) const override { return _do_make_tooltip(p_text); } + virtual Object *_make_custom_tooltip(const String &p_text) const override { return _do_make_tooltip(); } #endif + String get_task_meta() const { return task_meta; } + void set_task_meta(const String &p_task_meta) { task_meta = p_task_meta; } + TaskButton(); }; @@ -82,7 +91,7 @@ protected: public: void set_filter(String p_filter); - void add_task_button(const String &p_name, const Ref &icon, const String &p_tooltip, Variant p_meta); + void add_task_button(const String &p_name, const Ref &icon, const String &p_meta); void set_collapsed(bool p_collapsed); bool is_collapsed() const; From 5f40d38f8d73a4d8d816c4031eff63ef4b6b306b Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Sun, 7 Jul 2024 12:11:23 +0200 Subject: [PATCH 3/4] Add a hack to force documentation parsing on user scripts As things currently stand in Godot Engine, documentation comments are not loaded from user scripts into help system when the project is started. This leads to empty tooltips for user tasks in LimboAI, unless such a script is resaved. This hack forces script documentation to be added to help system, when the editor needs it to show a tooltip. --- editor/task_palette.cpp | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/editor/task_palette.cpp b/editor/task_palette.cpp index 158efaa..1262671 100644 --- a/editor/task_palette.cpp +++ b/editor/task_palette.cpp @@ -60,7 +60,9 @@ void TaskButton::_bind_methods() { Control *TaskButton::_do_make_tooltip() const { #ifdef LIMBOAI_MODULE String help_symbol; - if (task_meta.begins_with("res://")) { + bool is_resource = task_meta.begins_with("res://"); + + if (is_resource) { help_symbol = "class|\"" + task_meta.lstrip("res://") + "\"|"; } else { help_symbol = "class|" + task_meta + "|"; @@ -70,6 +72,18 @@ Control *TaskButton::_do_make_tooltip() const { help_bit->set_content_height_limits(1, 360 * EDSCALE); String desc = _module_get_help_description(task_meta); + if (desc.is_empty() && is_resource) { + // ! HACK: Force documentation parsing. + Ref