From ee2cc347c6fb9dbf6ba096961b335fb8b4319553 Mon Sep 17 00:00:00 2001 From: Yuri Sizov Date: Fri, 31 Mar 2023 21:17:59 +0200 Subject: [PATCH] Add support for icons in GDExtension classes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: RĂ©mi Verschelde --- core/extension/gdextension.cpp | 9 +++++++++ core/extension/gdextension.h | 2 ++ core/extension/gdextension_manager.cpp | 23 +++++++++++++++++++++++ core/extension/gdextension_manager.h | 4 ++++ editor/editor_data.cpp | 12 ++++++++++++ editor/editor_data.h | 2 ++ editor/editor_node.cpp | 26 +++++++++++++++++++------- 7 files changed, 71 insertions(+), 7 deletions(-) diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp index 829e1d8e5bb..f158755a856 100644 --- a/core/extension/gdextension.cpp +++ b/core/extension/gdextension.cpp @@ -549,6 +549,15 @@ Ref GDExtensionResourceLoader::load(const String &p_path, const String return Ref(); } + // Handle icons if any are specified. + if (config->has_section("icons")) { + List keys; + config->get_section_keys("icons", &keys); + for (const String &key : keys) { + lib->class_icon_paths[key] = config->get_value("icons", key); + } + } + return lib; } diff --git a/core/extension/gdextension.h b/core/extension/gdextension.h index 39523a142f7..9d946ca7ba5 100644 --- a/core/extension/gdextension.h +++ b/core/extension/gdextension.h @@ -67,6 +67,8 @@ protected: static void _bind_methods(); public: + HashMap class_icon_paths; + static String get_extension_list_config_file(); static String find_extension_library(const String &p_path, Ref p_config, std::function p_has_feature, PackedStringArray *r_tags = nullptr); diff --git a/core/extension/gdextension_manager.cpp b/core/extension/gdextension_manager.cpp index 8701e6d77b2..63e809bc7c3 100644 --- a/core/extension/gdextension_manager.cpp +++ b/core/extension/gdextension_manager.cpp @@ -50,6 +50,11 @@ GDExtensionManager::LoadStatus GDExtensionManager::load_extension(const String & extension->initialize_library(GDExtension::InitializationLevel(i)); } } + + for (const KeyValue &kv : extension->class_icon_paths) { + gdextension_class_icon_paths[kv.key] = kv.value; + } + gdextension_map[p_path] = extension; return LOAD_STATUS_OK; } @@ -74,6 +79,11 @@ GDExtensionManager::LoadStatus GDExtensionManager::unload_extension(const String extension->deinitialize_library(GDExtension::InitializationLevel(i)); } } + + for (const KeyValue &kv : extension->class_icon_paths) { + gdextension_class_icon_paths.erase(kv.key); + } + gdextension_map.erase(p_path); return LOAD_STATUS_OK; } @@ -95,6 +105,19 @@ Ref GDExtensionManager::get_extension(const String &p_path) { return E->value; } +bool GDExtensionManager::class_has_icon_path(const String &p_class) const { + // TODO: Check that the icon belongs to a registered class somehow. + return gdextension_class_icon_paths.has(p_class); +} + +String GDExtensionManager::class_get_icon_path(const String &p_class) const { + // TODO: Check that the icon belongs to a registered class somehow. + if (gdextension_class_icon_paths.has(p_class)) { + return gdextension_class_icon_paths[p_class]; + } + return ""; +} + void GDExtensionManager::initialize_extensions(GDExtension::InitializationLevel p_level) { ERR_FAIL_COND(int32_t(p_level) - 1 != level); for (KeyValue> &E : gdextension_map) { diff --git a/core/extension/gdextension_manager.h b/core/extension/gdextension_manager.h index 456942af0de..3643f043d80 100644 --- a/core/extension/gdextension_manager.h +++ b/core/extension/gdextension_manager.h @@ -38,6 +38,7 @@ class GDExtensionManager : public Object { int32_t level = -1; HashMap> gdextension_map; + HashMap gdextension_class_icon_paths; static void _bind_methods(); @@ -59,6 +60,9 @@ public: Vector get_loaded_extensions() const; Ref get_extension(const String &p_path); + bool class_has_icon_path(const String &p_class) const; + String class_get_icon_path(const String &p_class) const; + void initialize_extensions(GDExtension::InitializationLevel p_level); void deinitialize_extensions(GDExtension::InitializationLevel p_level); diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index 2d095d2dc77..c381c8c322a 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -31,6 +31,7 @@ #include "editor_data.h" #include "core/config/project_settings.h" +#include "core/extension/gdextension_manager.h" #include "core/io/file_access.h" #include "core/io/image_loader.h" #include "core/io/resource_loader.h" @@ -1030,6 +1031,17 @@ void EditorData::script_class_load_icon_paths() { } } +Ref EditorData::extension_class_get_icon(const String &p_class) const { + if (GDExtensionManager::get_singleton()->class_has_icon_path(p_class)) { + String icon_path = GDExtensionManager::get_singleton()->class_get_icon_path(p_class); + Ref icon = _load_script_icon(icon_path); + if (icon.is_valid()) { + return icon; + } + } + return nullptr; +} + Ref EditorData::_load_script_icon(const String &p_path) const { if (!p_path.is_empty() && ResourceLoader::exists(p_path)) { Ref icon = ResourceLoader::load(p_path); diff --git a/editor/editor_data.h b/editor/editor_data.h index fcf43e72f09..370963074c5 100644 --- a/editor/editor_data.h +++ b/editor/editor_data.h @@ -243,6 +243,8 @@ public: void script_class_save_icon_paths(); void script_class_load_icon_paths(); + Ref extension_class_get_icon(const String &p_class) const; + Ref get_script_icon(const Ref