Skip to content

Commit

Permalink
PoC for GDExtension class icons
Browse files Browse the repository at this point in the history
  • Loading branch information
akien-mga committed Mar 29, 2023
1 parent 249028e commit 242ce09
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 3 deletions.
9 changes: 9 additions & 0 deletions core/extension/gdextension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,15 @@ Ref<Resource> GDExtensionResourceLoader::load(const String &p_path, const String
return Ref<Resource>();
}

// Handle icons if any are specified.
if (config->has_section("icons")) {
List<String> keys;
config->get_section_keys("icons", &keys);
for (const String &key : keys) {
lib->class_icon_paths[key] = config->get_value("icons", key);
}
}

return lib;
}

Expand Down
2 changes: 2 additions & 0 deletions core/extension/gdextension.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ class GDExtension : public Resource {
static void _bind_methods();

public:
HashMap<String, String> class_icon_paths;

static String get_extension_list_config_file();
static String find_extension_library(const String &p_path, Ref<ConfigFile> p_config, std::function<bool(String)> p_has_feature, PackedStringArray *r_tags = nullptr);

Expand Down
16 changes: 16 additions & 0 deletions core/extension/gdextension_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ GDExtensionManager::LoadStatus GDExtensionManager::load_extension(const String &
extension->initialize_library(GDExtension::InitializationLevel(i));
}
}

for (const KeyValue<String, String> &kv : extension->class_icon_paths) {
gdextension_class_icon_paths[kv.key] = kv.value;
}

gdextension_map[p_path] = extension;
return LOAD_STATUS_OK;
}
Expand Down Expand Up @@ -95,6 +100,17 @@ Ref<GDExtension> GDExtensionManager::get_extension(const String &p_path) {
return E->value;
}

bool GDExtensionManager::class_has_icon_path(const String &p_class) const {
return gdextension_class_icon_paths.has(p_class);
}

String GDExtensionManager::class_get_icon_path(const String &p_class) const {
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<String, Ref<GDExtension>> &E : gdextension_map) {
Expand Down
4 changes: 4 additions & 0 deletions core/extension/gdextension_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class GDExtensionManager : public Object {

int32_t level = -1;
HashMap<String, Ref<GDExtension>> gdextension_map;
HashMap<String, String> gdextension_class_icon_paths;

static void _bind_methods();

Expand All @@ -59,6 +60,9 @@ class GDExtensionManager : public Object {
Vector<String> get_loaded_extensions() const;
Ref<GDExtension> 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);

Expand Down
25 changes: 22 additions & 3 deletions editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "editor_node.h"

#include "core/config/project_settings.h"
#include "core/extension/gdextension_manager.h"
#include "core/input/input.h"
#include "core/io/config_file.h"
#include "core/io/file_access.h"
Expand Down Expand Up @@ -4493,14 +4494,24 @@ Ref<Texture2D> EditorNode::get_object_icon(const Object *p_object, const String
while (base_scr.is_valid()) {
StringName name = EditorNode::get_editor_data().script_class_get_name(base_scr->get_path());
String icon_path = EditorNode::get_editor_data().script_class_get_icon_path(name);
Ref<ImageTexture> icon = _load_custom_class_icon(icon_path);
Ref<Texture2D> icon = _load_custom_class_icon(icon_path);
if (icon.is_valid()) {
script_icon_cache[scr] = icon;
return icon;
}

// TODO: should probably be deprecated in 4.x
StringName base = base_scr->get_instance_base_type();
// If not a script class, might be GDExtension.
if (base != StringName() && GDExtensionManager::get_singleton()->class_has_icon_path(base)) {
icon_path = GDExtensionManager::get_singleton()->class_get_icon_path(base);
icon = _load_custom_class_icon(icon_path);
if (icon.is_valid()) {
script_icon_cache[scr] = icon;
return icon;
}
}

// TODO: should probably be deprecated in 4.x
if (base != StringName() && EditorNode::get_editor_data().get_custom_types().has(base)) {
const Vector<EditorData::CustomType> &types = EditorNode::get_editor_data().get_custom_types()[base];
for (int i = 0; i < types.size(); ++i) {
Expand Down Expand Up @@ -4544,7 +4555,7 @@ Ref<Texture2D> EditorNode::get_class_icon(const String &p_class, const String &p

while (true) {
String icon_path = EditorNode::get_editor_data().script_class_get_icon_path(class_name);
Ref<Texture> icon = _load_custom_class_icon(icon_path);
Ref<Texture2D> icon = _load_custom_class_icon(icon_path);
if (icon.is_valid()) {
return icon; // Current global class has icon.
}
Expand All @@ -4571,6 +4582,14 @@ Ref<Texture2D> EditorNode::get_class_icon(const String &p_class, const String &p
return ctype->icon;
}

if (GDExtensionManager::get_singleton()->class_has_icon_path(p_class)) {
String icon_path = GDExtensionManager::get_singleton()->class_get_icon_path(p_class);
Ref<Texture2D> icon = _load_custom_class_icon(icon_path);
if (icon.is_valid()) {
return icon;
}
}

if (gui_base->has_theme_icon(p_class, SNAME("EditorIcons"))) {
return gui_base->get_theme_icon(p_class, SNAME("EditorIcons"));
}
Expand Down

0 comments on commit 242ce09

Please sign in to comment.