MagicNStuff/source/addons/bbcode_edit.editor/editor_interface_scraper.gd
2025-02-25 22:07:11 +01:00

127 lines
3.8 KiB
GDScript

extends Object
## This singleton has utility methods to scrap the Editor's interface
static func get_icon(icon: StringName) -> Texture2D:
return EditorInterface.get_base_control().get_theme_icon(icon, &"EditorIcons")
static func get_color_icon() -> Texture2D:
return get_icon(&"Color")
static func get_reference_icon() -> Texture2D:
return get_icon(&"Help")
static func try_get_icon(icon: StringName, fallback: StringName) -> Texture2D:
var result: Texture2D = get_icon(icon)
if result == get_icon(&"za86e81czxe1s89az6ee7s1"): # Random
return get_icon(fallback)
return result
static func get_builtin_class_icon(class_name_: StringName) -> Texture2D:
var result: Texture2D = get_icon(class_name_)
var file_broken: Texture2D = get_icon(&"za86e81czxe1s89az6ee7s1") # Random
while result == file_broken and class_name_ != &"":
class_name_ = ClassDB.get_parent_class(class_name_)
result = get_icon(class_name_)
return result
static func get_class_icon(name: StringName, fallback: StringName) -> Texture2D:
if ClassDB.class_exists(name):
return get_builtin_class_icon(name)
var base_name = name
var global_class_list := ProjectSettings.get_global_class_list()
var found: bool = true
while found:
found = false
for class_ in global_class_list:
if class_["class"] == name:
if class_["icon"]:
return load(class_["icon"])
else:
name = class_["base"]
if ClassDB.class_exists(name):
return get_builtin_class_icon(name)
found = true
break
# This can happen for type union (ex: CanvasItemMaterial,ShaderMaterial)
return get_icon(fallback)
## [b]Note:[/b] Return the Variant icon for [constant @GlobalScope.TYPE_NIL].
static func get_builtin_type_icon(type: Variant.Type, fallback: StringName) -> Texture2D:
if type == TYPE_NIL:
return get_icon(&"Variant")
if 0 <= type and type < TYPE_MAX:
return get_icon(type_string(type))
return get_icon(fallback)
static func get_type_icon(value: Variant, fallback: StringName) -> Texture2D:
var type: int = typeof(value)
if type == TYPE_OBJECT:
if value is Script:
var to_check: Script = value
while true:
if to_check.get_global_name():
return get_class_icon(to_check.get_global_name(), fallback)
# TODO MAYBE Read first line for @icon
if to_check.get_base_script():
to_check = to_check.get_base_script()
else:
return get_builtin_class_icon(to_check.get_instance_base_type())
var script: Script = value.get_script()
if script:
var search_for: Script = script
while true:
for class_ in ProjectSettings.get_global_class_list():
if class_["path"] == search_for.resource_path:
return get_class_icon(class_["class"], fallback)
if search_for.get_base_script():
search_for = search_for.get_base_script()
else:
return get_builtin_class_icon(search_for.get_instance_base_type())
return get_builtin_class_icon(value.get_class())
return get_builtin_type_icon(type, fallback)
## Scrap the Editor tree to find if it's unsaved.
static func is_current_script_unsaved() -> bool:
# Reference path: $"../../../../../../@VSplitContainer@9820/@VBoxContainer@9821/@ItemList@9824"
var current_editor := EditorInterface.get_script_editor().get_current_editor().get_base_editor()
if current_editor is not CodeEdit:
return false
var pointer: Node = current_editor.get_node(^"../../../../../..")
if pointer == null:
return false
for node_type: String in ["VSplitContainer", "VBoxContainer", "ItemList"]:
pointer = _fetch_node(pointer, node_type)
if pointer == null:
return false
var item_list: ItemList = pointer
return item_list.get_item_text(item_list.get_selected_items()[0]).ends_with("(*)")
static func _fetch_node(parent: Node, type: String) -> Node:
type = "@" + type
for child in parent.get_children():
if child.name.begins_with(type):
return child
return null