Skip to content

Commit

Permalink
Refactor EditorNode get icon.
Browse files Browse the repository at this point in the history
Co-authored-by: Tomasz Chabora <[email protected]>
  • Loading branch information
YYF233333 and KoBeWi committed Jan 27, 2025
1 parent e549802 commit 30cf85b
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 44 deletions.
4 changes: 3 additions & 1 deletion editor/debugger/editor_debugger_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,12 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int
} else {
item->set_tooltip_text(0, node.name + "\n" + TTR("Instance:") + " " + node.scene_file_path + "\n" + TTR("Type:") + " " + node.type_name);
}
Ref<Texture2D> icon = EditorNode::get_singleton()->get_class_icon(node.type_name, "");

Ref<Texture2D> icon = EditorNode::get_singleton()->get_class_icon(node.type_name);
if (icon.is_valid()) {
item->set_icon(0, icon);
}

item->set_metadata(0, node.id);

String current_path;
Expand Down
102 changes: 60 additions & 42 deletions editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4805,34 +4805,38 @@ void EditorNode::_pick_main_scene_custom_action(const String &p_custom_action_na
}
}

Ref<Texture2D> EditorNode::_get_class_or_script_icon(const String &p_class, const Ref<Script> &p_script, const String &p_fallback, bool p_fallback_script_to_theme) {
ERR_FAIL_COND_V_MSG(p_class.is_empty(), nullptr, "Class name cannot be empty.");
EditorData &ed = EditorNode::get_editor_data();

// Check for a script icon first.
if (p_script.is_valid()) {
Ref<Texture2D> script_icon = ed.get_script_icon(p_script);
if (script_icon.is_valid()) {
return script_icon;
}

if (p_fallback_script_to_theme) {
// Look for the native base type in the editor theme. This is relevant for
// scripts extending other scripts and for built-in classes.
String script_class_name = p_script->get_language()->get_global_class_name(p_script->get_path());
String base_type;
if (script_class_name.is_empty()) {
base_type = p_script->get_instance_base_type();
} else {
base_type = ScriptServer::get_global_class_native_base(script_class_name);
}
Ref<Texture2D> EditorNode::_get_script_icon(const Ref<Script> &p_script, bool p_fallback_script_to_theme) {
ERR_FAIL_COND_V_MSG(p_script.is_null(), nullptr, "Script should be valid.");
EditorData &ed = get_editor_data();

Ref<Texture2D> script_icon = ed.get_script_icon(p_script);
if (script_icon.is_valid()) {
return script_icon;
}

if (p_fallback_script_to_theme) {
// Look for the native base type in the editor theme. This is relevant for
// scripts extending other scripts and for built-in classes.
String script_class_name = p_script->get_language()->get_global_class_name(p_script->get_path());
String base_type;
if (script_class_name.is_empty()) {
base_type = p_script->get_instance_base_type();
} else {
base_type = ScriptServer::get_global_class_native_base(script_class_name);
}

if (theme.is_valid() && theme->has_icon(base_type, EditorStringName(EditorIcons))) {
return theme->get_icon(base_type, EditorStringName(EditorIcons));
}
if (theme.is_valid() && theme->has_icon(base_type, EditorStringName(EditorIcons))) {
return theme->get_icon(base_type, EditorStringName(EditorIcons));
}
}

return nullptr;
}

Ref<Texture2D> EditorNode::_get_class_icon(const String &p_class, const String &p_fallback) {
ERR_FAIL_COND_V_MSG(p_class.is_empty(), nullptr, "Class name cannot be empty.");
EditorData &ed = get_editor_data();

// Script was not valid or didn't yield any useful values, try the class name
// directly.

Expand Down Expand Up @@ -4879,41 +4883,55 @@ Ref<Texture2D> EditorNode::get_object_icon(const Object *p_object, const String

Ref<Script> scr = p_object->get_script();

if (Object::cast_to<EditorDebuggerRemoteObject>(p_object)) {
String class_name;
if (scr.is_valid()) {
class_name = scr->get_global_name();
if (scr.is_null() && p_object->is_class("Script")) {
scr = p_object;
}

if (class_name.is_empty()) {
// If there is no class_name in this script we just take the script path.
class_name = scr->get_path();
}
if (scr.is_valid()) {
Ref<Texture2D> icon = _get_script_icon(scr, true);
if (icon.is_valid()) {
return icon;
}
return get_class_icon(class_name.is_empty() ? Object::cast_to<EditorDebuggerRemoteObject>(p_object)->type_name : class_name, p_fallback);
}

if (scr.is_null() && p_object->is_class("Script")) {
scr = p_object;
// Script was not valid or didn't yield any useful values, try the class name
// directly.

if (Object::cast_to<EditorDebuggerRemoteObject>(p_object)) {
return get_class_icon(Object::cast_to<EditorDebuggerRemoteObject>(p_object)->type_name, p_fallback);
}

if (Object::cast_to<MultiNodeEdit>(p_object)) {
return get_class_icon(Object::cast_to<MultiNodeEdit>(p_object)->get_edited_class_name(), p_fallback);
} else {
return _get_class_or_script_icon(p_object->get_class(), scr, p_fallback);
}

return _get_class_icon(p_object->get_class(), p_fallback);
}

Ref<Texture2D> EditorNode::get_class_icon(const String &p_class, const String &p_fallback) {
ERR_FAIL_COND_V_MSG(p_class.is_empty(), nullptr, "Class name cannot be empty.");

Ref<Script> scr;
// If p_class is a resource path, try to load the resource and get icon from it.
if (!p_class.get_extension().is_empty() && ResourceLoader::exists(p_class)) {
Ref<Script> scr = ResourceLoader::load(p_class);
Ref<Texture2D> icon = _get_script_icon(scr, true);
if (icon.is_valid()) {
return icon;
}
}

// Check user defined global classes.
if (ScriptServer::is_global_class(p_class)) {
scr = EditorNode::get_editor_data().script_class_load_script(p_class);
} else if (ResourceLoader::exists(p_class)) { // If the script is not a class_name we check if the script resource exists.
scr = ResourceLoader::load(p_class);
Ref<Script> scr = EditorNode::get_editor_data().script_class_load_script(p_class);
if (scr.is_valid()) {
Ref<Texture2D> icon = _get_script_icon(scr, true);
if (icon.is_valid()) {
return icon;
}
}
}

return _get_class_or_script_icon(p_class, scr, p_fallback, true);
return _get_class_icon(p_class, p_fallback);
}

bool EditorNode::is_object_of_custom_type(const Object *p_object, const StringName &p_class) {
Expand Down
3 changes: 2 additions & 1 deletion editor/editor_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,8 @@ class EditorNode : public Node {
void _feature_profile_changed();
bool _is_class_editor_disabled_by_feature_profile(const StringName &p_class);

Ref<Texture2D> _get_class_or_script_icon(const String &p_class, const Ref<Script> &p_script, const String &p_fallback = "Object", bool p_fallback_script_to_theme = false);
Ref<Texture2D> _get_script_icon(const Ref<Script> &p_script, bool p_fallback_script_to_theme = false);
Ref<Texture2D> _get_class_icon(const String &p_class, const String &p_fallback = "Object");

void _pick_main_scene_custom_action(const String &p_custom_action_name);

Expand Down

0 comments on commit 30cf85b

Please sign in to comment.