Added Godot-IDE plugin.

This commit is contained in:
Tanner van Teeffelen 2026-01-27 13:00:27 -05:00
parent 5da58e4c98
commit 455697778c
345 changed files with 22062 additions and 1 deletions

1
.godot_ide/.gdignore Normal file
View file

@ -0,0 +1 @@
IDE CONFIG

12
.godot_ide/config.ini Normal file
View file

@ -0,0 +1,12 @@
[config]
plugin={
"res://addons/_Godot-IDE_/plugins/fancy_filters_script/plugin.gd": true,
"res://addons/_Godot-IDE_/plugins/fancy_search_class/plugin.gd": true,
"res://addons/_Godot-IDE_/plugins/fancy_search_files/plugin.gd": true,
"res://addons/_Godot-IDE_/plugins/gd_override_functions/plugin.gd": true,
"res://addons/_Godot-IDE_/plugins/macro-n/plugin.gd": true,
"res://addons/_Godot-IDE_/plugins/quick_folds/plugin.gd": true,
"res://addons/_Godot-IDE_/plugins/script_splitter/plugin.gd": true,
"res://addons/_Godot-IDE_/plugins/symbol_navigator/plugin.gd": true
}

683
addons/_Godot-IDE_/IDE.gd Normal file
View file

@ -0,0 +1,683 @@
@tool
class_name IDE extends EditorPlugin
# =============================================================================
# Author: Twister
# Godot-IDE Extension
#
# ./plugins: Folder for extensions.
# ./shared_resources: Free use for any purposes.
# =============================================================================
const EDITOR_CONFIG_PATH : String = "plugin/godot_ide/"
const PATH_CONFIG : String = "res://.ide/"
static var _ref : Dictionary[String, Object] = {}
static var _safe_ref : Dictionary[String, Node] = {}
static var debug : bool = true
static var PRIVATE_METHODS : String = "__"
static var VIRTUAL_METHODS : String = "_"
static var _menu : MenuButton = null
#region DEV_API
## Get current editor container for edit/view scripts.
static func get_script_editor_container() -> TabContainer:
var script_editor: ScriptEditor = EditorInterface.get_script_editor()
var out : Variant = _get_reference("script_editor_container", script_editor, "*", "TabContainer", 0)
if out is TabContainer:
return out
return null
## Get current script/documents opened list.
static func get_script_list() -> ItemList:
var script_editor: ScriptEditor = EditorInterface.get_script_editor()
var out : Variant = _get_reference("script_list", script_editor, "*", "ItemList", 0)
if out is ItemList:
return out
return null
## Get search bar native of script list.
static func get_script_list_search_bar() -> LineEdit:
var script_editor: ScriptEditor = EditorInterface.get_script_editor()
var out : Variant = _get_reference("script_list_search_bar", script_editor, "*", "LineEdit", 0)
if out is LineEdit:
return out
return null
## Get label of the script list
static func get_script_list_current_label() -> Label:
var script_editor: ScriptEditor = EditorInterface.get_script_editor()
var out : Variant = _get_reference("script_list_current_label", script_editor, "*", "Label", 2)
if out is Label:
return out
return null
## Get the bottom panel of filter side by script list.
static func get_filter_methods() -> ItemList:
var script_editor: ScriptEditor = EditorInterface.get_script_editor()
var out : Variant = _get_reference("filter_methods", script_editor, "*", "ItemList", 1)
if out is ItemList:
return out
return null
## Get the search bar of the filters method panel.
static func get_filter_methods_search_bar() -> LineEdit:
var script_editor: ScriptEditor = EditorInterface.get_script_editor()
var out : Variant = _get_reference("filter_methods_search_bar", script_editor, "*", "LineEdit", 1)
if out is LineEdit:
return out
return null
## Get the file on top menu bar.
static func get_file_menu_button() -> MenuButton:
var script_editor: ScriptEditor = EditorInterface.get_script_editor()
var out : Variant = _get_reference("file_menu_button", script_editor, "*", "MenuButton", 0)
if out is MenuButton:
return out
return null
## Get the edit on top menu bar.
static func get_edit_menu_button() -> MenuButton:
var script_editor: ScriptEditor = EditorInterface.get_script_editor()
var out : Variant = _get_reference("edit_menu_button", script_editor, "*", "MenuButton", 1)
if out is MenuButton:
return out
return null
## Get the search on top menu bar.
static func get_search_menu_button() -> MenuButton:
var script_editor: ScriptEditor = EditorInterface.get_script_editor()
var out : Variant = _get_reference("search_menu_button", script_editor, "*", "MenuButton", 2)
if out is MenuButton:
return out
return null
## Get the got to menu on top menu bar.
static func get_go_to_menu_button() -> MenuButton:
var script_editor: ScriptEditor = EditorInterface.get_script_editor()
var out : Variant = _get_reference("get_go_to_menu_button", script_editor, "*", "MenuButton", 3)
if out is MenuButton:
return out
return null
## Get the debug on top menu bar.
static func get_debug_menu_button() -> MenuButton:
var script_editor: ScriptEditor = EditorInterface.get_script_editor()
var out : Variant = _get_reference("debug_menu_button", script_editor, "*", "MenuButton", 17)
if out is MenuButton:
return out
return null
## Get the container of scripts list.
static func get_script_list_container() -> VSplitContainer:
var script_editor: ScriptEditor = EditorInterface.get_script_editor()
var out : Variant = _get_reference("script_list_container", script_editor, "*", "VSplitContainer", 0)
if out is VSplitContainer:
return out
return null
## Get the container of the editor.
static func get_editor_container() -> HSplitContainer:
var script_editor: ScriptEditor = EditorInterface.get_script_editor()
var out : Variant = _get_reference("editor_container", script_editor, "*", "HSplitContainer", 0)
if out is HSplitContainer:
return out
return null
## Get native screen size. Raito must be 0.1 - 1.0
static func get_screen_size(ratio : float = 1.0) -> Vector2:
var screen : Vector2 = DisplayServer.screen_get_size()
return screen * ratio
## Clamp native screen size.
static func clamp_screen_size(current_size : Vector2, min_ratio : float = 0.0, max_ratio : float = 1.0) -> Vector2:
var screen : Vector2 = DisplayServer.screen_get_size()
var max_screen : Vector2 = screen * max_ratio
var min_screen : Vector2 = screen * min_ratio
return Vector2(max(min(current_size.x, max_screen.x), min_screen.x), max(min(current_size.y, max_screen.y), min_screen.y))
## Get full properties headers of a script.
static func get_script_properties_list(script : Script, full : bool = true, check_is_native : bool = true) -> Dictionary:
if script == null:
return {}
var nname : String = get_name_script(script)
if check_is_native and ClassDB.class_exists(nname):
return _generate_native(nname)
if full:
var data : Dictionary = _generate(script)
return _generate_native(script.get_instance_base_type(), data, data.size()-1)
else:
return _generate(script)
## Get editor menu of godot-ide-extension from editor container.
static func get_menu_button() -> MenuButton:
return _menu
#endregion
# =============================================================================
#region DEV_CONFIG
static func set_config(plugin_name : String, config_name : String, value : Variant) -> void:
var editor : EditorSettings = EditorInterface.get_editor_settings()
if editor:
if config_name.is_empty():
printerr("Config name can not be empty!")
return
if plugin_name.is_empty():
printerr("Plugin name can not be empty")
return
editor.set_setting(EDITOR_CONFIG_PATH.path_join(plugin_name).path_join(config_name), value)
static func add_property_config_info(plugin_name : String, config_name : String, type : Variant.Type, hint : int, hint_string : String):
var editor : EditorSettings = EditorInterface.get_editor_settings()
if editor:
if config_name.is_empty():
printerr("Config name can not be empty!")
return
if plugin_name.is_empty():
printerr("Plugin name can not be empty")
return
editor.add_property_info({
"name": EDITOR_CONFIG_PATH.path_join(plugin_name).path_join(config_name),
"type": type,
"hint": hint,
"hint_string": hint_string
})
static func get_config(addon_name : String, config_name : String) -> Variant:
var editor : EditorSettings = EditorInterface.get_editor_settings()
if editor:
var setting : String = EDITOR_CONFIG_PATH.path_join(addon_name).path_join(config_name)
if editor.has_setting(setting):
return editor.get_setting(setting)
return null
static func set_file_config_value(section : String, key : String, value : Variant) -> int:
if !DirAccess.dir_exists_absolute(PATH_CONFIG):
if OK != DirAccess.make_dir_recursive_absolute(PATH_CONFIG):
push_warning("Can not creates config dir!")
return 1
if FileAccess.file_exists(PATH_CONFIG.path_join(".gdignore")):
var file : FileAccess = FileAccess.open(PATH_CONFIG.path_join(".gdignore"), FileAccess.WRITE)
file.store_string("FOLDER Godot-IDE CONFIG")
file.close()
var cfg_path : String = PATH_CONFIG.path_join("config.ini")
var cfg : ConfigFile = ConfigFile.new()
if FileAccess.file_exists(cfg_path):
cfg.load(cfg_path)
cfg.set_value(section, key, value)
return cfg.save(cfg_path)
static func get_file_config_value(section : String, key : String) -> Variant:
var cfg_path : String = PATH_CONFIG.path_join("config.ini")
if !FileAccess.file_exists(cfg_path):
return null
var cfg : ConfigFile = ConfigFile.new()
var err : int = cfg.load(cfg_path)
if OK != err:
return null
return cfg.get_value(section, key, "")
#endregion
#region utils
static func get_type(_typeof : int) -> String:
var txt : String = ""
match _typeof:
TYPE_BOOL : txt = "bool"
TYPE_INT : txt = "int"
TYPE_FLOAT: txt = "float"
TYPE_STRING : txt = "String"
TYPE_VECTOR2 : txt = "Vector2"
TYPE_VECTOR2I : txt = "Vector2i"
TYPE_RECT2 : txt = "Rect2"
TYPE_RECT2I : txt = "Rect2i"
TYPE_VECTOR3 : txt = "Vector3"
TYPE_VECTOR3I : txt = "Vector3i"
TYPE_TRANSFORM2D : txt = "Tranform2D"
TYPE_VECTOR4 : txt = "Vector4"
TYPE_VECTOR4I : txt = "Vector4i"
TYPE_PLANE : txt = "Plane"
TYPE_QUATERNION : txt = "Quaternion"
TYPE_AABB : txt = "AABB"
TYPE_BASIS : txt = "Basis"
TYPE_TRANSFORM3D : txt = "Transform3D"
TYPE_PROJECTION : txt = "Projection"
TYPE_COLOR : txt = "Color"
TYPE_STRING_NAME : txt = "StringName"
TYPE_NODE_PATH : txt = "NodePath"
TYPE_RID : txt = "RID"
TYPE_OBJECT : txt = "Object"
TYPE_CALLABLE : txt = "Callable"
TYPE_SIGNAL : txt = "Signal"
TYPE_DICTIONARY : txt = "Dictionary"
TYPE_ARRAY : txt = "Array"
TYPE_PACKED_BYTE_ARRAY : txt = "PackedByteArray"
TYPE_PACKED_INT32_ARRAY : txt = "PackedInt32Array"
TYPE_PACKED_INT64_ARRAY : txt = "PackedInt64Array"
TYPE_PACKED_FLOAT32_ARRAY : txt = "PackedFloat32Array"
TYPE_PACKED_FLOAT64_ARRAY : txt = "PackedFloat64Array"
TYPE_PACKED_STRING_ARRAY : txt = "PackedStringArray"
TYPE_PACKED_VECTOR2_ARRAY : txt = "PackedVector2Array"
TYPE_PACKED_VECTOR3_ARRAY : txt = "PackedVector3Array"
TYPE_PACKED_COLOR_ARRAY : txt = "PackedColorArray"
TYPE_PACKED_VECTOR4_ARRAY : txt = "PackedVector4Array"
_:
txt = "Variant"
return txt
static func _generate(script : Script, data : Dictionary = {}, index : int = -1) -> Dictionary:
if script == null:
return data
var funcs : Dictionary = {}
var props : Dictionary = {}
var signals : Dictionary = {}
var constants : Dictionary = {}
var base : Dictionary = {
"name" : &"GDScript"
,"functions" : funcs
,"properties" : props
,"signals" : signals
,"constants" : constants
,"type": 1
,"custom": false
,"path" : script.resource_path
,"tool" : script.is_tool()
,"abstract" : script.is_abstract()
,"built_in" : script.is_built_in()
}
var base_name : String = get_name_script(script, base)
base["name"] = base_name
index += 1
data[index] = base
for dict: Dictionary in script.get_script_method_list():
var func_name: StringName = dict.name
if func_name.begins_with("@"):continue
funcs[func_name] =_get_header_virtual(dict)
if dict.has("flags"):
if dict["flags"] & METHOD_FLAG_STATIC:
funcs[func_name] += "||static"
elif dict["flags"] & METHOD_FLAG_CONST:
funcs[func_name] += "||const"
for dict : Dictionary in script.get_script_property_list():
var pro_name: StringName = dict.name
var as_exporrt : bool = false
if !pro_name.get_extension().is_empty():
continue
if dict.has("usage"):
var usage : int = dict["usage"]
if !(usage & PROPERTY_USAGE_SCRIPT_VARIABLE):
continue
for x : int in [PROPERTY_USAGE_STORAGE, PROPERTY_USAGE_EDITOR, PROPERTY_USAGE_CHECKABLE, PROPERTY_USAGE_CHECKED, PROPERTY_USAGE_GROUP]:
if usage & x:
as_exporrt = true
break
props[pro_name] =_get_header_virtual(dict)
if as_exporrt:
props[pro_name] += "||export"
else:
if dict.has("flags"):
if dict["flags"] & METHOD_FLAG_STATIC:
props[pro_name] += "||static"
elif dict["flags"] & METHOD_FLAG_CONST:
props[pro_name] += "||const"
for dict : Dictionary in script.get_property_list():
var pro_name: StringName = dict.name
if !pro_name.get_extension().is_empty():
continue
if dict.has("usage"):
var usage : int = dict["usage"]
if !(usage & PROPERTY_USAGE_SCRIPT_VARIABLE):
continue
props[pro_name] =_get_header_virtual(dict)
props[pro_name] += "||static"
for dict : Dictionary in script.get_script_signal_list():
var pro_name: StringName = dict.name
signals[pro_name] =_get_header_virtual(dict)
for dict : Variant in script.get_script_constant_map():
if dict is StringName:
var variant : Variant = script.get(dict)
constants[dict] = "{0}||{1}".format([dict, get_type(typeof(variant))])
elif dict is Dictionary:
var pro_name: StringName = dict.name
constants[pro_name] =_get_header_virtual(dict)
if data.size() > 0:
var start : int = 0
while !data.has(start) and start < index:
start += 1
for x : int in range(start, index, 1):
var clazz : Dictionary = data[x]["functions"]
for k : Variant in funcs.keys():
if clazz.has(k):
if !"||overrided" in clazz[k]:
clazz[k] += "||overrided"
for x : int in range(start, index, 1):
var clazz : Dictionary = data[x]["properties"]
for k : Variant in props.keys():
if clazz.has(k):
if !"||overrided" in clazz[k]:
clazz[k] += "||overrided"
for x : int in range(start, index, 1):
var clazz : Dictionary = data[x]["signals"]
for k : Variant in signals.keys():
if clazz.has(k):
if !"||overrided" in clazz[k]:
clazz[k] += "||overrided"
for x : int in range(start, index, 1):
var clazz : Dictionary = data[x]["constants"]
for k : Variant in constants.keys():
if clazz.has(k):
if !"||overrided" in clazz[k]:
clazz[k] += "||overrided"
else:
clazz[k] = constants[k] + "||overrided"
return _generate(script.get_base_script(), data, index)
static func _generate_native(native : StringName, data : Dictionary = {}, index : int = 0) -> Dictionary:
if native.is_empty() or !ClassDB.class_exists(native):
return data
var funcs : Dictionary = {}
var props : Dictionary = {}
var signals : Dictionary = {}
var constants : Dictionary = {}
var api_type : int = ClassDB.class_get_api_type(native)
var base : Dictionary = {
"name" : native
,"functions" : funcs
,"properties" : props
,"signals" : signals
,"constants" : constants
,"type" : 0
,"custom": false
,"path" : "NativeScript"
,"tool" : api_type == ClassDB.APIType.API_EDITOR or api_type == ClassDB.APIType.API_EDITOR_EXTENSION
,"abstract" : false #!
,"built_in" : false
}
index += 1
data[index] = base
for dict: Dictionary in ClassDB.class_get_method_list(native, true):
funcs[dict.name] =_get_header_virtual(dict)
for dict : Dictionary in ClassDB.class_get_property_list(native, true):
var pro_name: StringName = dict.name
if !pro_name.get_extension().is_empty():
continue
props[pro_name] =_get_header_virtual(dict)
for dict : Dictionary in ClassDB.class_get_signal_list(native, true):
var pro_name: StringName = dict.name
signals[pro_name] =_get_header_virtual(dict)
for dict : String in ClassDB.class_get_enum_list(native, true):
var pro_name: StringName = dict
constants[pro_name] = "{0}||enum||void".format([dict])
for dict : String in ClassDB.class_get_integer_constant_list(native, true):
var pro_name: StringName = dict
constants[pro_name] = "{0}||int||void".format([dict])
if data.size() > 0:
var start : int = 0
while !data.has(start) and start < index:
start += 1
for x : int in range(start, index, 1):
var clazz : Dictionary = data[x]["functions"]
for k : Variant in funcs.keys():
if clazz.has(k):
if !"||overrided" in clazz[k]:
clazz[k] += "||overrided"
for x : int in range(start, index, 1):
var clazz : Dictionary = data[x]["properties"]
for k : Variant in props.keys():
if clazz.has(k):
if !"||overrided" in clazz[k]:
clazz[k] += "||overrided"
for x : int in range(start, index, 1):
var clazz : Dictionary = data[x]["signals"]
for k : Variant in signals.keys():
if clazz.has(k):
if !"||overrided" in clazz[k]:
clazz[k] += "||overrided"
for x : int in range(start, index, 1):
var clazz : Dictionary = data[x]["constants"]
for k : Variant in constants.keys():
if clazz.has(k):
if !"||overrided" in clazz[k]:
clazz[k] += "||overrided"
return _generate_native(ClassDB.get_parent_class(native), data, index)
static func clamp_rect_to_screen(to_clamp_rect: Rect2, max_aviable_rect : Rect2) -> Rect2:
if to_clamp_rect.position.x < max_aviable_rect.position.x:
to_clamp_rect.position.x = max_aviable_rect.position.x
elif to_clamp_rect.position.x + to_clamp_rect.size.x > max_aviable_rect.position.x + max_aviable_rect.size.x:
to_clamp_rect.position.x = max_aviable_rect.position.x + max_aviable_rect.size.x - to_clamp_rect.size.x
if to_clamp_rect.position.y < max_aviable_rect.position.y:
to_clamp_rect.position.y = max_aviable_rect.position.y
elif to_clamp_rect.position.y + to_clamp_rect.size.y > max_aviable_rect.position.y + max_aviable_rect.size.y:
to_clamp_rect.position.y = max_aviable_rect.position.y + max_aviable_rect.size.y - to_clamp_rect.size.y
if to_clamp_rect.size.x > max_aviable_rect.size.x:
to_clamp_rect.position.x = max_aviable_rect.position.x + (max_aviable_rect.size.x - to_clamp_rect.size.x) / 2
if to_clamp_rect.size.y > max_aviable_rect.size.y:
to_clamp_rect.position.y = max_aviable_rect.position.y + (max_aviable_rect.size.y - to_clamp_rect.size.y) / 2
return to_clamp_rect
static func get_header_function(dict : Dictionary) -> String:
var params : String = ""
var args : Array = dict["args"]
var separator : String = ""
var default_args : Array = dict["default_args"]
var _default_index : int = default_args.size()
for y : int in range(args.size() - 1, -1, -1):
var arg : Dictionary = args[y]
var txt : String = arg["name"]
if !(arg["class_name"]).is_empty():
txt += str(" : ", arg["class_name"] as String)
else:
var _typeof : int = arg["type"]
txt += str(" : ", IDE.get_type(_typeof))
if _default_index > 0:
_default_index -= 1
var def : Variant = default_args[_default_index]
var _type : int = typeof(def)
if def == null or _type < 1:
txt += str(' = null')
elif _type < 5:
if def is String:
txt += str(' = "', def, '"')
elif def is StringName:
txt += str(' = &"', def, '"')
else:
txt += str(" = ", def)
else:
txt += str(" = ", IDE.get_type(typeof(def)), def)
params = str(txt, separator, params)
separator = ", "
var return_dic : Dictionary = dict["return"]
var return_type : String = "void"
var return_value : String = "pass"
if !return_dic["class_name"].is_empty():
return_type = (return_dic["class_name"] as String)
return_value = "return null"
else:
var _type : int = return_dic["type"]
if _type < 1:
var func_name : String = str(dict["name"]).to_lower()
if func_name == "get" or __is_variant(func_name):
return_type = "Variant"
return_value = "return null"
else:
return_type = "void"
else:
return_type = IDE.get_type(return_dic["type"])
if _type == TYPE_INT:
return_value = "return 0"
elif _type == TYPE_BOOL:
return_value = "return false"
elif _type == TYPE_FLOAT:
return_value = "return 0.0"
elif _type == TYPE_STRING:
return_value = 'return ""'
elif _type == TYPE_ARRAY:
return_value = "return []"
else:
return_value = str("return ", return_type,"()")
return "func {0}({1}) -> {2}:\n\t#TODO: code here :)\n\t{3}".format([dict["name"], params, return_type, return_value])
static func _get_header_virtual(dict : Dictionary, include_paremeters : bool = true) -> String:
var params : String = ""
var separator : String = ""
if dict.has("args"):
var args : Array = dict["args"]
var default_args : Array = dict["default_args"]
var _default_index : int = default_args.size()
for y : int in range(args.size() - 1, -1, -1):
var arg : Dictionary = args[y]
var txt : String = "" #arg["name"]
if !(arg["class_name"]).is_empty():
txt += str(arg["class_name"] as String)
else:
var _typeof : int = arg["type"]
txt += str(IDE.get_type(_typeof))
if include_paremeters and _default_index > 0:
_default_index -= 1
var def : Variant = default_args[_default_index]
var _type : int = typeof(def)
if def == null or _type < 1:
txt += str(' = null')
elif _type < 5:
if def is String:
txt += str(' = "', def, '"')
elif def is StringName:
txt += str(' = &"', def, '"')
else:
txt += str(" = ", def)
else:
txt += str(" = ",IDE.get_type(typeof(def)), def)
params = str(txt, separator, params)
separator = ", "
if dict.has("return"):
var return_dic : Dictionary = dict["return"]
var return_type : String = "void"
if !return_dic["class_name"].is_empty():
return_type = (return_dic["class_name"] as String)
else:
var _type : int = return_dic["type"]
if _type < 1:
var func_name : String = str(dict["name"]).to_lower()
if func_name == "get" or __is_variant(func_name):
return_type = "Variant"
else:
return_type = "void"
else:
return_type = get_type(return_dic["type"])
#if params.is_empty():
#params = "-"
return "{0}||{1}||{2}".format([dict["name"], params, return_type]) #Replace x more space.
elif dict.has("class_name"):
var classname : String = dict["class_name"]
if classname.is_empty() and dict.has("type"):
classname = get_type(dict["type"])
params = classname
return "{0}||{1}||void".format([dict["name"], params])
static func __is_variant(func_name : String) -> bool:
const FUNC_GET : Array[String] = ["get_", "_get"]
for x : String in FUNC_GET:
if func_name.begins_with(x) or func_name.ends_with(x):
return true
return func_name.contains("_get_")
static func get_name_script(script : Script, ref_data : Dictionary = {}) -> StringName:
var base_name : StringName = script.get_global_name()
if base_name.is_empty():
var path : String = script.resource_name
if path.is_empty():
path = script.resource_path
if !path.is_empty():
var _name : String = path.get_file()
_name = _name.trim_suffix("." + _name.get_extension())
base_name = _name
else:
base_name = &"CustomScript"
ref_data["custom"] = true
else:
base_name = path
return base_name
static func _reset() -> void:
for x : String in _ref.keys():
var object : Variant = _ref[x]
if is_instance_valid(object) and object is Node:
if _safe_ref.has(x):
var parent : Node = _safe_ref[x]
if is_instance_valid(parent) and !parent.is_queued_for_deletion():
var current : Node = object.get_parent()
if current != parent:
if is_instance_valid(current):
object.reparent(parent)
else:
parent.add_child(object)
static func _get_reference(container_name : String, root_container : Node, pattern : String, type : String, index : int) -> Variant:
if !is_instance_valid(root_container):
if debug:
# If you recieved this message, try reset the engine with this addon enabled.
# | If the problem persist, make a issue on "https://github.com/CodeNameTwister/godot_ide"
push_warning("Caution!, not root reference setted!!")
return null
elif _ref.has(container_name):
var object : Variant = _ref[container_name]
if is_instance_valid(object):
if object is Node:
if !_safe_ref.has(container_name):
_safe_ref[container_name] = object.get_parent()
return object
var new_object : Variant = _find(root_container, pattern, type, index)
if is_instance_valid(new_object):
_ref[container_name] = new_object
return new_object
if debug:
# If you recieved this message, try reset the engine with this addon enabled.
# | If the problem persist, make a issue on "https://github.com/CodeNameTwister/godot_ide"
push_warning("Caution!, can not found: {0}!!".format([container_name]))
return null
static func _find(root : Node, pattern : String, type : String, index : int = 0) -> Node:
var e : Array[Node] = root.find_children(pattern, type, true, false)
if e.size() > index:
return e[index]
return null
#endregion

View file

@ -0,0 +1 @@
uid://d270rwyekls6t

128
addons/_Godot-IDE_/icon.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://brfrp6r0fiwl2"
path="res://.godot/imported/icon.svg-b579c8a7bc6a03fedff183ec85fa8cc5.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/_Godot-IDE_/icon.svg"
dest_files=["res://.godot/imported/icon.svg-b579c8a7bc6a03fedff183ec85fa8cc5.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View file

@ -0,0 +1,8 @@
[plugin]
name="Godot-IDE"
description="GODOT-IDE"
author="Twister"
version="0.5.5"
script="plugin.gd"
github="https://github.com/CodeNameTwister/Godot-IDE"

View file

@ -0,0 +1,299 @@
@tool
extends IDE
# =============================================================================
# Author: Twister
# Godot-IDE Extension
#
# ./plugins: Folder for extensions.
# ./shared_resources: Free use for any purposes.
# =============================================================================
var _plugins : Array[EditorPlugin] = []
var _enable_plugins : Dictionary = {}
func _ready() -> void:
debug = false
main_screen_changed.connect(_on_main_screen_changed)
resource_saved.connect(_on_resource_saved)
scene_closed.connect(_on_scene_closed)
scene_changed.connect(_on_scene_changed)
scene_saved.connect(_on_scene_saved)
_initialize()
func _on_resource_saved(resource : Resource) -> void:
for x : EditorPlugin in _plugins:
x.resource_saved.emit(resource)
func _on_scene_closed(filepath: String) -> void:
for x : EditorPlugin in _plugins:
x.scene_closed.emit(filepath)
func _on_scene_changed(scene_root: Node) -> void:
for x : EditorPlugin in _plugins:
x.scene_changed.emit(scene_root)
func _on_scene_saved(filepath: String) -> void:
for x : EditorPlugin in _plugins:
x.scene_saved.emit(filepath)
func _on_main_screen_changed(screen_name : String) -> void:
for x : EditorPlugin in _plugins:
x.main_screen_changed.emit(screen_name)
func _enter_tree() -> void:
set_process(true)
func _process(_delta: float) -> void:
var editor : EditorFileSystem = EditorInterface.get_resource_filesystem()
if !editor:
return
if editor.is_scanning():
return
set_process(false)
#Self-Secure All Loaded
_initialize()
var base : String = get_script().resource_path.get_base_dir()
var path : String = base.path_join("plugins")
_init_config(1)
_load_plugins(path)
_sugar_godot(path)
_sugar_godot(base.path_join("shared_resources"), "teal")
func _init_config(init : int) -> void:
const PATH : String = "res://.godot_ide/"
var cfg_path : String = PATH.path_join("config.ini")
if !DirAccess.dir_exists_absolute(PATH):
DirAccess.make_dir_absolute(PATH)
var file : FileAccess = FileAccess.open(PATH.path_join(".gdignore"), FileAccess.WRITE)
if file:
file.store_string("IDE CONFIG")
file.close()
if init == 1:
if FileAccess.file_exists(cfg_path):
var cfg : ConfigFile = ConfigFile.new()
if cfg.load(cfg_path) == OK:
var value : Variant = cfg.get_value("config", "plugin", {})
if value is Dictionary:
_enable_plugins = value
else:
var cfg : ConfigFile = ConfigFile.new()
cfg.set_value("config", "plugin", _enable_plugins)
if cfg.save(cfg_path) != OK:
push_warning("Can not save plugin changes!")
#if Engine.get_version_info().minor > 4:
#_enable_plugins["res://addons/_Godot-IDE_/plugins/script_spliter/plugin.gd"] = false
#region __PRX__
func _apply_changes() -> void:
_callback(&"_apply_changes")
func _set_window_layout(configuration: ConfigFile) -> void:
for plugin : EditorPlugin in _plugins:
if plugin.has_method(&"_set_window_layout"):
plugin.call(&"_set_window_layout", configuration)
func _build() -> bool:
for plugin : EditorPlugin in _plugins:
if plugin.has_method(&"_build"):
if !plugin.call(&"_build"):
return false
return true
func _clear() -> void:
_callback(&"_build")
func _disable_plugin() -> void:
_callback(&"_disable_plugin")
func _edit(object: Object) -> void:
for plugin : EditorPlugin in _plugins:
if plugin.has_method(&"_edit"):
plugin.call(&"_edit", object)
func _forward_3d_draw_over_viewport(viewport_control: Control) -> void:
for plugin : EditorPlugin in _plugins:
if plugin.has_method(&"_forward_3d_draw_over_viewport"):
plugin.call(&"_forward_3d_draw_over_viewport", viewport_control)
func _forward_3d_force_draw_over_viewport(viewport_control: Control) -> void:
for plugin : EditorPlugin in _plugins:
if plugin.has_method(&"_forward_3d_force_draw_over_viewport"):
plugin.call(&"_forward_3d_force_draw_over_viewport", viewport_control)
func _forward_canvas_draw_over_viewport(viewport_control: Control) -> void:
for plugin : EditorPlugin in _plugins:
if plugin.has_method(&"_forward_canvas_draw_over_viewport"):
plugin.call(&"_forward_canvas_draw_over_viewport", viewport_control)
func _forward_canvas_force_draw_over_viewport(viewport_control: Control) -> void:
for plugin : EditorPlugin in _plugins:
if plugin.has_method(&"_forward_canvas_force_draw_over_viewport"):
plugin.call(&"_forward_canvas_force_draw_over_viewport", viewport_control)
func _forward_canvas_gui_input(event: InputEvent) -> bool:
var out : bool = false
for plugin : EditorPlugin in _plugins:
if plugin.has_method(&"_forward_canvas_gui_input"):
out = plugin.call(&"_forward_canvas_gui_input", event) or out
return out
#endregion
func _callback(method : StringName) -> void:
for plugin : EditorPlugin in _plugins:
if plugin.has_method(method):
plugin.call(method)
func _exit_tree() -> void:
for x : Node in _plugins:
if is_instance_valid(x):
if !x.is_queued_for_deletion():
x.queue_free()
_plugins.clear()
_init_config(0)
var editor : EditorSettings = EditorInterface.get_editor_settings()
if editor:
if editor.settings_changed.is_connected(_on_changes):
editor.settings_changed.disconnect(_on_changes)
if is_instance_valid(IDE._menu):
IDE._menu.queue_free()
IDE._menu = null
func _load_plugins(path : String) -> void:
if !is_instance_valid(IDE._menu):
var file : MenuButton = get_file_menu_button()
if is_instance_valid(file):
var root : Node = file.get_parent()
IDE._menu = MenuButton.new()
IDE._menu.text = "Godot-IDE"
root.add_child(_menu)
root.move_child(_menu, mini(1, root.get_child_count() - 1))
if !DirAccess.dir_exists_absolute(path):
path = path.get_base_dir().get_file()
if EditorInterface.is_plugin_enabled(path):
EditorInterface.set_plugin_enabled(path, false)
printerr("{0}: Error, can not find 'plugins' folder! [0x00000003]".format([path.capitalize().to_upper()]))
return
var dir :DirAccess = DirAccess.open(path)
var plugins_dir : Array = []
var plugins_file : Array = []
var authors : PackedStringArray = []
if dir:
dir.list_dir_begin()
var file_name : String = dir.get_next()
while !file_name.is_empty():
if dir.current_is_dir():
plugins_dir.append(path.path_join(file_name))
file_name = dir.get_next()
dir.list_dir_end()
else:
printerr("{0}:error, can not open 'plugins' folder! [0x00000005]".format([path.get_base_dir().get_file().capitalize().to_upper()]))
while plugins_dir.size() > 0:
var current_path : String = plugins_dir.pop_back()
var plugin_path : String = current_path.path_join("plugin.gd")
var plugin_cfg : String = current_path.path_join("plugin.cfg")
if FileAccess.file_exists(plugin_cfg):
var cfg : ConfigFile = ConfigFile.new()
if cfg.load(plugin_cfg) == OK:
if cfg.has_section_key("plugin", "script"):
plugin_path = current_path.path_join(str(cfg.get_value("plugin", "script")))
if cfg.has_section_key("plugin", "author"):
var value : String = str(cfg.get_value("plugin", "author"))
if !value.is_empty() and !authors.has(value):
authors.append(value)
if !FileAccess.file_exists(plugin_path):
plugin_path = current_path.path_join(current_path.get_file())
if !FileAccess.file_exists(plugin_path):
printerr("{0}:error, can not open 'plugin/{1}' folder! [0x00000005]".format([path.get_base_dir().get_file().capitalize().to_upper(), current_path.get_file()]))
continue
plugins_file.append(plugin_path)
var current_plugins : Dictionary = {}
for plugin : String in plugins_file:
if _enable_plugins.has(plugin):
if _enable_plugins[plugin] == false:
continue
var variant : Variant = ResourceLoader.load(plugin)
if variant is Script:
if variant.can_instantiate():
if !variant.is_tool():
push_warning("Plugin script is not tool: {0}".format([plugin]))
variant = variant.new()
if variant is EditorPlugin:
_plugins.append(variant)
current_plugins[plugin] = true
_enable_plugins = current_plugins
for plugin : EditorPlugin in _plugins:
get_parent().add_child(plugin)
if plugin.has_method(&"_enable_plugin"):
plugin.call(&"_enable_plugin")
print("[Godot-IDE Extension]")
if authors.size() > 0:
print("> Plugin Contributors: {0}".format([", ".join(authors)]))
func _sugar_godot(dir : String, col : String = "blue") -> void:
if !ProjectSettings.has_setting("file_customization/folder_colors"):
ProjectSettings.set_setting("file_customization/folder_colors", {dir: col})
else:
if !dir.ends_with("/"):
dir += "/"
var data : Dictionary = ProjectSettings.get_setting("file_customization/folder_colors", {})
if !data.has(dir):
data[dir] = col
ProjectSettings.set_setting("file_customization/folder_colors", data)
else:
return
var editor : EditorFileSystem = EditorInterface.get_resource_filesystem()
if editor:
editor.scan.call_deferred()
func _on_changes() -> void:
var editor : EditorSettings = EditorInterface.get_editor_settings()
if editor:
var changes : PackedStringArray = editor.get_changed_settings()
if "plugin/gd_override_functions/inheritance/virtual_functions_begins_with" in changes:
IDE.VIRTUAL_METHODS = editor.get_setting("plugin/gd_override_functions/inheritance/virtual_functions_begins_with")
if "plugin/gd_override_functions/inheritance/private_functions_begins_with" in changes:
IDE.PRIVATE_METHODS = editor.get_setting("plugin/gd_override_functions/inheritance/private_functions_begins_with")
func _initialize() -> void:
var dirt : Dictionary = {}
var dat : Array[Dictionary] = (get_script() as Script).get_script_method_list()
for dct : Dictionary in dat:
var key : String = dct["name"]
if dirt.has(key):
continue
dirt[key] = true
if has_method(key):
if key.begins_with("get_"):
if !dct.has("args") or dct["args"].size() == 0:
call(key)
var editor : EditorSettings = EditorInterface.get_editor_settings()
if editor:
if editor.has_setting("plugin/gd_override_functions/inheritance/virtual_functions_begins_with"):
IDE.VIRTUAL_METHODS = editor.get_setting("plugin/gd_override_functions/inheritance/virtual_functions_begins_with")
if editor.has_setting("plugin/gd_override_functions/inheritance/private_functions_begins_with"):
IDE.PRIVATE_METHODS = editor.get_setting("plugin/gd_override_functions/inheritance/private_functions_begins_with")
if !editor.settings_changed.is_connected(_on_changes):
editor.settings_changed.connect(_on_changes)

View file

@ -0,0 +1 @@
uid://bqmc0vi754ifc

View file

@ -0,0 +1,5 @@
[gd_resource type="StyleBoxEmpty" format=3 uid="uid://dwpkbhgi7dk8"]
[resource]
content_margin_left = 8.0
content_margin_right = 8.0

View file

@ -0,0 +1,14 @@
@tool
extends Button
# =============================================================================
# Author: Twister
# Fancy Filter Script
#
# Addon for Godot
# =============================================================================
func _pressed() -> void:
if owner:
if owner.has_method(name):
owner.call(name)

View file

@ -0,0 +1 @@
uid://b1v225muollg5

View file

@ -0,0 +1,35 @@
@tool
extends Button
# =============================================================================
# Author: Twister
# Fancy Filter Script
#
# Addon for Godot
# =============================================================================
func update_settings() -> void:
var variant : Variant = owner.get(name)
if variant is bool:
button_pressed = variant
visual()
func _ready() -> void:
update_settings()
func _pressed() -> void:
if owner.has_method(&"enable_filter"):
owner.call(&"enable_filter", name, button_pressed)
visual()
func visual() -> void:
if button_pressed:
var value : Variant = owner.get(str(name, "_color"))
if value is Color:
modulate = value
else:
modulate = Color.WHITE
else:
modulate = Color.DARK_GRAY
modulate.a = 0.7

View file

@ -0,0 +1 @@
uid://gct2x12uf8jj

View file

@ -0,0 +1,36 @@
@tool
extends Control
# =============================================================================
# Author: Twister
# Fancy Filter Script
#
# Addon for Godot
# =============================================================================
@export var container : Control = null
func _ready() -> void:
var p : Node = get_parent()
if !p.child_entered_tree.is_connected(_on_child):
p.child_entered_tree.connect(_on_child)
visibility_changed.connect(_on_visible)
func _on_child(n : Node) -> void:
var p : Node = get_parent()
if is_instance_valid(p) and !p.is_queued_for_deletion():
if p.get_child_count() > 0:
p.move_child.call_deferred(self, p.get_child_count() - 1)
func _on_visible() -> void:
if visible:
var packed : PackedScene = ResourceLoader.load("res://addons/_Godot-IDE_/plugins/fancy_filters_script/components/settings.tscn")
if packed:
var c : Control = packed.instantiate()
container.add_child(c)
c.size_flags_horizontal = Control.SIZE_EXPAND_FILL
c.size_flags_vertical = Control.SIZE_EXPAND_FILL
else:
for x : Node in container.get_children():
x.queue_free()

View file

@ -0,0 +1 @@
uid://cbvs583dwh5o

View file

@ -0,0 +1,142 @@
@tool
extends Control
# =============================================================================
# Author: Twister
# Fancy Filter Script
#
# Addon for Godot
# =============================================================================
@export var _type_members : TabContainer
@export var _accessibility : TabContainer
@export var sorty_name_enabled : CheckBox
@export var order_name_check : CheckBox
@export var order_name_button : Button
@export var background_color : Button
@export var use_dots : Button
@export var flat_mode_button : Button
@export var separate_script_list_button : Button
const NORMAL_ICON : Texture2D = preload("res://addons/_Godot-IDE_/shared_resources/up.svg")
const INVERT_ICON : Texture2D = preload("res://addons/_Godot-IDE_/shared_resources/down.svg")
signal on_update_order(data : Dictionary)
enum TYPE_ORDER{
NONE = 0,
NORMAL = 1,
INVERT = 2
}
var name_order : TYPE_ORDER = TYPE_ORDER.NORMAL
func use_background_color_in_script_info() -> void:
IDE.set_config("fancy_filters_script", "use_background_color_in_script_info", background_color.button_pressed)
func use_dots_as_item_icons() -> void:
IDE.set_config("fancy_filters_script", "use_dots_as_item_icons", use_dots.button_pressed)
func flat_mode() -> void:
IDE.set_config("fancy_filters_script", "flat_mode", flat_mode_button.button_pressed)
func separate_script_list() -> void:
IDE.set_config("fancy_filters_script", "separate_container_list", separate_script_list_button.button_pressed)
func update_settings() -> void:
var order : Variant = IDE.get_config("fancy_filters_script", "members_order_by")
var name_type : Variant = IDE.get_config("fancy_filters_script", "name_order_by")
var background_pressed : Variant = IDE.get_config("fancy_filters_script", "use_background_color_in_script_info")
var use_dots_pressed: Variant = IDE.get_config("fancy_filters_script", "use_dots_as_item_icons")
var flat_mode_pressed : Variant = IDE.get_config("fancy_filters_script", "flat_mode")
var separate_script_list_pressed : Variant = IDE.get_config("fancy_filters_script", "separate_container_list")
if !(separate_script_list_pressed is bool):
separate_script_list_pressed = false
if !(order is Array):
order = []
if !(name_type is int):
name_type = 0
if !(background_pressed is bool):
background_pressed = false
if !(use_dots_pressed is bool):
use_dots_pressed = false
if !(flat_mode_pressed is bool):
flat_mode_pressed = false
use_dots.button_pressed = use_dots_pressed
background_color.button_pressed = background_pressed
flat_mode_button.button_pressed = flat_mode_pressed
separate_script_list_button.button_pressed = separate_script_list_pressed
name_order = name_type
order_name_check.button_pressed = name_order != 0
if name_order == TYPE_ORDER.INVERT:
order_name_button.icon = INVERT_ICON
else:
order_name_button.icon = NORMAL_ICON
for x : Node in _type_members.get_children():
match x.name:
&"Properties":
for z : int in range(order.size()):
if order[z] == 0:
_type_members.move_child(x, z)
&"Methods":
for z : int in range(order.size()):
if order[z] == 1:
_type_members.move_child(x, z)
&"Signals":
for z : int in range(order.size()):
if order[z] == 2:
_type_members.move_child(x, z)
&"Constant":
for z : int in range(order.size()):
if order[z] == 3:
_type_members.move_child(x, z)
order_name_button.disabled = !order_name_check.button_pressed
func _ready() -> void:
update_settings()
func order_name_check_button() -> void:
order_name_button.disabled = !order_name_check.button_pressed
if order_name_check.button_pressed == false:
IDE.set_config("fancy_filters_script", "name_order_by", 0)
else:
if order_name_button.icon == INVERT_ICON:
name_order = TYPE_ORDER.INVERT
else:
name_order = TYPE_ORDER.NORMAL
IDE.set_config("fancy_filters_script", "name_order_by", name_order)
func order_name() -> void:
if name_order == TYPE_ORDER.NORMAL:
name_order = TYPE_ORDER.INVERT
order_name_button.icon = INVERT_ICON
else:
name_order = TYPE_ORDER.NORMAL
order_name_button.icon = NORMAL_ICON
if order_name_check.button_pressed == false:
IDE.set_config("fancy_filters_script", "name_order_by", 0)
else:
IDE.set_config("fancy_filters_script", "name_order_by", name_order)
func set_settings() -> void:
var new_order : Array[int] = []
for x : Node in _type_members.get_children():
match x.name:
&"Properties":
new_order.append(0)
&"Methods":
new_order.append(1)
&"Signals":
new_order.append(2)
&"Constant":
new_order.append(3)
IDE.set_config("fancy_filters_script", "members_order_by", new_order)

View file

@ -0,0 +1 @@
uid://blc70goak5ixm

View file

@ -0,0 +1,158 @@
[gd_scene load_steps=6 format=3 uid="uid://bhrieo2dhroxj"]
[ext_resource type="Script" uid="uid://blc70goak5ixm" path="res://addons/_Godot-IDE_/plugins/fancy_filters_script/components/settings.gd" id="1_8gu0h"]
[ext_resource type="StyleBox" uid="uid://dwpkbhgi7dk8" path="res://addons/_Godot-IDE_/plugins/fancy_filters_script/assets/flatbox.tres" id="1_e4fgx"]
[ext_resource type="Texture2D" uid="uid://bgjo43cuidob1" path="res://addons/_Godot-IDE_/shared_resources/up.svg" id="3_f6f5j"]
[ext_resource type="Script" uid="uid://drngb2pss3dtj" path="res://addons/_Godot-IDE_/plugins/fancy_filters_script/components/tab_container.gd" id="3_g0drt"]
[ext_resource type="Script" uid="uid://b1v225muollg5" path="res://addons/_Godot-IDE_/plugins/fancy_filters_script/button.gd" id="4_f6f5j"]
[node name="Settings" type="VBoxContainer" node_paths=PackedStringArray("_type_members", "_accessibility", "sorty_name_enabled", "order_name_check", "order_name_button", "background_color", "use_dots", "flat_mode_button", "separate_script_list_button")]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_8gu0h")
_type_members = NodePath("Type")
_accessibility = NodePath("Accessibility")
sorty_name_enabled = NodePath("order_name_check_button")
order_name_check = NodePath("order_name_check_button")
order_name_button = NodePath("order_name")
background_color = NodePath("use_background_color_in_script_info")
use_dots = NodePath("use_dots_as_item_icons")
flat_mode_button = NodePath("flat_mode")
separate_script_list_button = NodePath("separate_script_list")
[node name="order_name_check_button" type="CheckBox" parent="."]
layout_mode = 2
size_flags_horizontal = 0
button_pressed = true
text = "Enable Order By Name"
script = ExtResource("4_f6f5j")
[node name="order_name" type="Button" parent="."]
custom_minimum_size = Vector2(200, 0)
layout_mode = 2
size_flags_horizontal = 3
tooltip_text = "Make sorty by using the name member."
text = "Sort Name"
icon = ExtResource("3_f6f5j")
icon_alignment = 2
script = ExtResource("4_f6f5j")
[node name="Sep3" type="HSeparator" parent="."]
layout_mode = 2
[node name="Label6" type="Label" parent="."]
layout_mode = 2
size_flags_horizontal = 0
text = "Order By Members (Drag and Drop)"
[node name="Type" type="TabContainer" parent="."]
layout_mode = 2
size_flags_horizontal = 3
tooltip_text = "Change order by drag values."
theme_override_styles/panel = ExtResource("1_e4fgx")
theme_override_styles/tabbar_background = ExtResource("1_e4fgx")
theme_override_styles/tab_unselected = ExtResource("1_e4fgx")
theme_override_styles/tab_hovered = ExtResource("1_e4fgx")
theme_override_styles/tab_selected = ExtResource("1_e4fgx")
theme_override_styles/tab_disabled = ExtResource("1_e4fgx")
theme_override_styles/tab_focus = ExtResource("1_e4fgx")
current_tab = 0
drag_to_rearrange_enabled = true
script = ExtResource("3_g0drt")
[node name="Properties" type="Control" parent="Type"]
layout_mode = 2
metadata/_tab_index = 0
[node name="Methods" type="Control" parent="Type"]
visible = false
layout_mode = 2
metadata/_tab_index = 1
[node name="Signals" type="Control" parent="Type"]
visible = false
layout_mode = 2
metadata/_tab_index = 2
[node name="Constant" type="Control" parent="Type"]
visible = false
layout_mode = 2
metadata/_tab_index = 3
[node name="Sep" type="HSeparator" parent="."]
visible = false
layout_mode = 2
[node name="accessibility2" type="Label" parent="."]
visible = false
layout_mode = 2
text = "Order By Accesibility (Drag and Drop)"
[node name="Accessibility" type="TabContainer" parent="."]
visible = false
layout_mode = 2
size_flags_horizontal = 3
theme_override_styles/panel = ExtResource("1_e4fgx")
theme_override_styles/tabbar_background = ExtResource("1_e4fgx")
theme_override_styles/tab_unselected = ExtResource("1_e4fgx")
theme_override_styles/tab_hovered = ExtResource("1_e4fgx")
theme_override_styles/tab_selected = ExtResource("1_e4fgx")
theme_override_styles/tab_disabled = ExtResource("1_e4fgx")
theme_override_styles/tab_focus = ExtResource("1_e4fgx")
current_tab = 0
drag_to_rearrange_enabled = true
script = ExtResource("3_g0drt")
[node name="Export" type="Control" parent="Accessibility"]
layout_mode = 2
metadata/_tab_index = 0
[node name="Static" type="Control" parent="Accessibility"]
visible = false
layout_mode = 2
metadata/_tab_index = 1
[node name="Public" type="Control" parent="Accessibility"]
visible = false
layout_mode = 2
metadata/_tab_index = 2
[node name="Virtual" type="Control" parent="Accessibility"]
visible = false
layout_mode = 2
metadata/_tab_index = 3
[node name="Private" type="Control" parent="Accessibility"]
visible = false
layout_mode = 2
metadata/_tab_index = 4
[node name="Sep2" type="HSeparator" parent="."]
layout_mode = 2
[node name="use_dots_as_item_icons" type="CheckBox" parent="."]
layout_mode = 2
size_flags_horizontal = 0
text = "Use Dots As Script Info Items Icons"
script = ExtResource("4_f6f5j")
[node name="use_background_color_in_script_info" type="CheckBox" parent="."]
layout_mode = 2
size_flags_horizontal = 0
text = "Use Background Colors in Script Info Items"
script = ExtResource("4_f6f5j")
[node name="flat_mode" type="CheckBox" parent="."]
layout_mode = 2
size_flags_horizontal = 0
text = "Flat Mode"
script = ExtResource("4_f6f5j")
[node name="separate_script_list" type="CheckBox" parent="."]
layout_mode = 2
size_flags_horizontal = 0
text = "Separate Script List"
script = ExtResource("4_f6f5j")

View file

@ -0,0 +1,13 @@
@tool
extends TabContainer
# =============================================================================
# Author: Twister
# Fancy Filter Script
#
# Addon for Godot
# =============================================================================
func _notification(what: int) -> void:
if what == NOTIFICATION_DRAG_END:
if owner.has_method(&"set_settings"):
owner.call(&"set_settings")

View file

@ -0,0 +1 @@
uid://drngb2pss3dtj

View file

@ -0,0 +1,179 @@
[gd_scene load_steps=14 format=3 uid="uid://dhlxe0qj82e8y"]
[ext_resource type="Script" uid="uid://bwtq1pkujrb1d" path="res://addons/_Godot-IDE_/plugins/fancy_filters_script/script_info.gd" id="1_5gq01"]
[ext_resource type="Script" uid="uid://gct2x12uf8jj" path="res://addons/_Godot-IDE_/plugins/fancy_filters_script/button_filter.gd" id="2_djmkv"]
[ext_resource type="Script" uid="uid://dpkvcqsih4i8w" path="res://addons/_Godot-IDE_/plugins/fancy_filters_script/filters_container.gd" id="2_u1yuj"]
[ext_resource type="Texture2D" uid="uid://cjpyaeqxjujsy" path="res://addons/_Godot-IDE_/shared_resources/MethodOverride.svg" id="3_7xcf1"]
[ext_resource type="Texture2D" uid="uid://dqfn3tghaer0y" path="res://addons/_Godot-IDE_/shared_resources/ScriptExtend.svg" id="3_nynvq"]
[ext_resource type="Texture2D" uid="uid://ouml4wypk5bq" path="res://addons/_Godot-IDE_/shared_resources/MemberConstant.svg" id="4_7xcf1"]
[ext_resource type="Texture2D" uid="uid://bu2y52as0gijo" path="res://addons/_Godot-IDE_/shared_resources/MemberSignal.svg" id="5_2xgjc"]
[ext_resource type="Texture2D" uid="uid://cec6jsyssk4ys" path="res://addons/_Godot-IDE_/shared_resources/MemberProperty.svg" id="5_nynvq"]
[ext_resource type="Texture2D" uid="uid://cgdceyfng83st" path="res://addons/_Godot-IDE_/shared_resources/MemberMethod.svg" id="6_ndpn6"]
[ext_resource type="Texture2D" uid="uid://bjmtfc58y1sbs" path="res://addons/_Godot-IDE_/shared_resources/InterfaceScript.svg" id="8_goajo"]
[ext_resource type="Texture2D" uid="uid://816fejewtbfj" path="res://addons/_Godot-IDE_/shared_resources/search.svg" id="10_2xgjc"]
[ext_resource type="Script" uid="uid://bbbdyhh8lhw4a" path="res://addons/_Godot-IDE_/plugins/fancy_filters_script/line_edit.gd" id="11_1yamo"]
[ext_resource type="Script" uid="uid://cbvs583dwh5o" path="res://addons/_Godot-IDE_/plugins/fancy_filters_script/components/order_settings.gd" id="12_u1yuj"]
[node name="Container" type="TabContainer" node_paths=PackedStringArray("button_container", "tree_container")]
custom_minimum_size = Vector2(64, 64)
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
size_flags_vertical = 3
current_tab = 0
script = ExtResource("1_5gq01")
button_container = NodePath("Script Info/VContainer/SContainer/SHContainer")
tree_container = NodePath("Script Info/SContainer/Tree")
[node name="Script Info" type="VBoxContainer" parent="."]
layout_mode = 2
metadata/_tab_index = 0
[node name="VContainer" type="VBoxContainer" parent="Script Info"]
layout_mode = 2
[node name="SContainer" type="ScrollContainer" parent="Script Info/VContainer"]
custom_minimum_size = Vector2(0, 38)
layout_mode = 2
size_flags_vertical = 3
horizontal_scroll_mode = 3
vertical_scroll_mode = 3
script = ExtResource("2_u1yuj")
[node name="SHContainer" type="HBoxContainer" parent="Script Info/VContainer/SContainer"]
custom_minimum_size = Vector2(0, 32)
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="show_all" type="Button" parent="Script Info/VContainer/SContainer/SHContainer"]
custom_minimum_size = Vector2(32, 0)
layout_mode = 2
toggle_mode = true
button_pressed = true
text = "All"
icon_alignment = 1
script = ExtResource("2_djmkv")
[node name="show_inheritance" type="Button" parent="Script Info/VContainer/SContainer/SHContainer"]
modulate = Color(0.960784, 0.960784, 0.960784, 1)
custom_minimum_size = Vector2(32, 0)
layout_mode = 2
tooltip_text = "Show inheritance"
toggle_mode = true
icon = ExtResource("3_7xcf1")
icon_alignment = 1
script = ExtResource("2_djmkv")
[node name="show_functions" type="Button" parent="Script Info/VContainer/SContainer/SHContainer"]
custom_minimum_size = Vector2(32, 0)
layout_mode = 2
tooltip_text = "Show Properties"
toggle_mode = true
button_pressed = true
icon = ExtResource("6_ndpn6")
icon_alignment = 1
script = ExtResource("2_djmkv")
[node name="show_properties" type="Button" parent="Script Info/VContainer/SContainer/SHContainer"]
modulate = Color(0.7372549, 0.8784314, 1, 1)
custom_minimum_size = Vector2(32, 0)
layout_mode = 2
tooltip_text = "Show Properties"
toggle_mode = true
button_pressed = true
icon = ExtResource("5_nynvq")
icon_alignment = 1
script = ExtResource("2_djmkv")
[node name="show_signals" type="Button" parent="Script Info/VContainer/SContainer/SHContainer"]
modulate = Color(0.89998645, 0.817927, 1, 1)
custom_minimum_size = Vector2(32, 0)
layout_mode = 2
tooltip_text = "Show Signals"
toggle_mode = true
button_pressed = true
icon = ExtResource("5_2xgjc")
icon_alignment = 1
script = ExtResource("2_djmkv")
[node name="show_constants" type="Button" parent="Script Info/VContainer/SContainer/SHContainer"]
modulate = Color(0, 1, 1, 1)
custom_minimum_size = Vector2(32, 0)
layout_mode = 2
tooltip_text = "Show Constants"
toggle_mode = true
button_pressed = true
icon = ExtResource("4_7xcf1")
icon_alignment = 1
script = ExtResource("2_djmkv")
[node name="show_parent_class" type="Button" parent="Script Info/VContainer/SContainer/SHContainer"]
modulate = Color(0.4627451, 0.8117647, 0.70980394, 1)
custom_minimum_size = Vector2(32, 0)
layout_mode = 2
tooltip_text = "Show parent classes"
toggle_mode = true
button_pressed = true
icon = ExtResource("3_nynvq")
icon_alignment = 1
script = ExtResource("2_djmkv")
[node name="show_native_class" type="Button" parent="Script Info/VContainer/SContainer/SHContainer"]
modulate = Color(0.4627451, 0.8117647, 0.70980394, 1)
custom_minimum_size = Vector2(32, 0)
layout_mode = 2
tooltip_text = "Show native classes"
toggle_mode = true
icon = ExtResource("8_goajo")
icon_alignment = 1
script = ExtResource("2_djmkv")
[node name="LineEdit" type="LineEdit" parent="Script Info/VContainer" node_paths=PackedStringArray("tree")]
layout_mode = 2
placeholder_text = "Search Bar"
clear_button_enabled = true
right_icon = ExtResource("10_2xgjc")
script = ExtResource("11_1yamo")
tree = NodePath("../../SContainer/Tree")
[node name="SContainer" type="ScrollContainer" parent="Script Info"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="Tree" type="Tree" parent="Script Info/SContainer"]
auto_translate_mode = 2
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
theme_override_constants/h_separation = 0
theme_override_constants/item_margin = 6
columns = 2
allow_rmb_select = true
[node name="Settings" type="VBoxContainer" parent="." node_paths=PackedStringArray("container")]
visible = false
layout_mode = 2
script = ExtResource("12_u1yuj")
container = NodePath("VBoxContainer/MarginContainer")
metadata/_tab_index = 1
[node name="VBoxContainer" type="VBoxContainer" parent="Settings"]
layout_mode = 2
size_flags_vertical = 3
[node name="Label" type="Label" parent="Settings/VBoxContainer"]
layout_mode = 2
text = "Filter Settings"
horizontal_alignment = 1
[node name="HSeparator" type="HSeparator" parent="Settings/VBoxContainer"]
layout_mode = 2
[node name="MarginContainer" type="ScrollContainer" parent="Settings/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3

View file

@ -0,0 +1,22 @@
@tool
extends ScrollContainer
func _ready() -> void:
mouse_entered.connect(_on_mouse)
_out_mouse()
func _process(_delta: float) -> void:
if is_inside_tree():
if get_global_rect().has_point(get_global_mouse_position()):
return
_out_mouse()
func _on_mouse() -> void:
horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_AUTO
vertical_scroll_mode = ScrollContainer.SCROLL_MODE_AUTO
set_process(true)
func _out_mouse() -> void:
horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_SHOW_NEVER
vertical_scroll_mode = ScrollContainer.SCROLL_MODE_SHOW_NEVER
set_process(false)

View file

@ -0,0 +1 @@
uid://dpkvcqsih4i8w

View file

@ -0,0 +1,85 @@
@tool
extends LineEdit
# =============================================================================
# Author: Twister
# Fancy Filter Script
#
# Addon for Godot
# =============================================================================
@export var tree : Tree = null
func _enter_tree() -> void:
if !is_in_group(&"UPDATE_ON_SAVE"):
add_to_group(&"UPDATE_ON_SAVE")
func _exit_tree() -> void:
if is_in_group(&"UPDATE_ON_SAVE"):
remove_from_group(&"UPDATE_ON_SAVE")
func _process(_delta: float) -> void:
set_process(false)
if text.is_empty():
return
sxrch.call_deferred(text)
func update() -> void:
set_process(true)
func _ready() -> void:
set_process(false)
text_changed.connect(sxrch)
func reset() -> void:
if tree:
var root : TreeItem = tree.get_root()
if !root:
return
_reset(root)
func _reset(root : TreeItem) -> void:
root.visible = true
for c : TreeItem in root.get_children():
_reset(c)
func sxrch(txt : String) -> void:
reset()
if txt.is_empty():
return
if tree:
var root : TreeItem = tree.get_root()
if !root:
return
var rgx0 : RegEx = RegEx.create_from_string("(?i)\\b{0}\\b".format([txt]))
var rgx1 : RegEx = RegEx.create_from_string("(?i).*{0}.*".format([txt]))
var d0 : Array[TreeItem] = []
var d1 : Array[TreeItem] = []
for x : RegEx in [rgx0, rgx1]:
if !is_instance_valid(x) or !x.is_valid():
return
_sxrch(root, rgx0, rgx1, d0, d1)
root.visible = true
for t : TreeItem in d0:
_visible(t)
for t : TreeItem in d1:
_visible(t)
func _visible(root : TreeItem) -> void:
if root:
root.visible = true
_visible(root.get_parent())
func _sxrch(root : TreeItem, rgx0 : RegEx, rgx1 : RegEx, d0 : Array[TreeItem], d1 : Array[TreeItem]) -> void:
var txt : String = root.get_text(0)
root.visible = false
if rgx0.search(txt) != null:
d0.append(root)
elif d0.size() == 0 and rgx1.search(txt) != null:
d1.append(root)
for x : TreeItem in root.get_children():
_sxrch(x, rgx0, rgx1, d0, d1)

View file

@ -0,0 +1 @@
uid://bbbdyhh8lhw4a

View file

@ -0,0 +1,8 @@
[plugin]
name="Fance Editor Filters"
description="Tool Addon for godot 4."
author="Twister"
version="1.1.5"
github="https://github.com/CodeNameTwister"
script="plugin.gd"

View file

@ -0,0 +1,272 @@
@tool
extends EditorPlugin
# =============================================================================
# Author: Twister
# Fancy Filter Script
#
# Addon for Godot
# =============================================================================
var TAB : PackedScene = preload("res://addons/_Godot-IDE_/plugins/fancy_filters_script/filter_scene.tscn")
var _parent : Control = null
var _container : Control = null
var _script_info : Control = null
var _placeholder : Control = null
var _id_show_hide_tool : int = -1
var _id_toggle_position_tool : int = -1
var _id_switch_panels : int = -1
var _c_input_show_hide : InputEventKey = null
var _c_input_switch_panels : InputEventKey = null
var _as_separate_container : bool = false
var _input_defined : bool = false
func _on_changes() -> void:
var settings : EditorSettings = EditorInterface.get_editor_settings()
if settings:
for x : String in settings.get_changed_settings():
if "separate_container_list" in x:
var value : Variant = IDE.get_config("fancy_filters_script", "separate_container_list")
if value is bool and value != _as_separate_container:
_as_separate_container = value
_exit_tree()
_enter_tree()
break
func _init() -> void:
var input0 : Variant = IDE.get_config("fancy_filters_script", "show_hide")
var input1 : Variant = IDE.get_config("fancy_filters_script", "switch_panels")
var as_separate_container : Variant = IDE.get_config("fancy_filters_script", "separate_container_list")
var settings : EditorSettings = EditorInterface.get_editor_settings()
if settings:
# 0.5.1
if settings.has_setting("plugin/godot_ide/fancy_filter_script/script_list_and_filter_to_right"):
settings.set_setting("plugin/godot_ide/fancy_filters_script/script_list_and_filter_to_right", settings.get_setting("plugin/godot_ide/fancy_filter_script/script_list_and_filter_to_right"))
settings.set_setting("plugin/godot_ide/fancy_filter_script/script_list_and_filter_to_right", null)
if !settings.settings_changed.is_connected(_on_changes):
settings.settings_changed.connect(_on_changes)
if as_separate_container is bool:
_as_separate_container = _as_separate_container
else:
IDE.set_config("fancy_filters_script", "separate_container_list", _as_separate_container)
if input0 is InputEventKey:
_c_input_show_hide = input0
else:
_c_input_show_hide = InputEventKey.new()
_c_input_show_hide.pressed = true
_c_input_show_hide.ctrl_pressed = true
_c_input_show_hide.keycode = KEY_T
IDE.set_config("fancy_filters_script", "show_hide", _c_input_show_hide)
if input1 is InputEventKey:
_c_input_switch_panels = input1
else:
_c_input_switch_panels = InputEventKey.new()
_c_input_switch_panels.pressed = true
_c_input_switch_panels.ctrl_pressed = true
_c_input_switch_panels.keycode = KEY_G
IDE.set_config("fancy_filters_script", "switch_panels", _c_input_switch_panels)
func _get_traduce(msg : String) -> String:
return msg
func _on_pop_pressed(index : int) -> void:
if index > -1:
if index == _id_show_hide_tool:
_container.visible = !_container.visible
elif index == _id_toggle_position_tool:
toggle_position()
elif index == _id_switch_panels:
if !_script_info.visible:
var tab : Variant = _script_info.get_parent()
if tab is TabContainer:
tab.current_tab = _script_info.get_index()
else:
var script_list : Control = IDE.get_script_list_container()
if is_instance_valid(script_list):#
var tab : Variant = script_list.get_parent()
if tab is TabContainer:
tab.current_tab = script_list.get_index()
func _apply_changes() -> void:
if _container:
if _container.has_method(&"force_update"):
_container.call_deferred(&"force_update")
get_tree().call_group(&"UPDATE_ON_SAVE", &"update")
func _enter_tree() -> void:
var container : VSplitContainer = IDE.get_script_list_container()
if container:
var variant : Variant = IDE.get_config("fancy_filters_script", "script_list_and_filter_to_right")
var expected_index : int = 0
if variant is bool:
if variant == true:
expected_index = 1
container.name = "Script List"
_container = TAB.instantiate()
if _container.get_child_count() > 0:
_script_info = _container.get_child(0)
var parent : Control = container.get_parent()
_parent = parent
if !_as_separate_container:
var x : int = container.get_child_count()
if x > 1:
var cntl : Node = container.get_child(x - 1)
if cntl is Control:
if _placeholder == null:
_placeholder = Control.new()
_placeholder.visible = false
cntl.reparent(_placeholder)
container.add_child(_container)
container.move_child(_container, 0)
container.split_offset = 100
container.clamp_split_offset()
else:
container.add_child(_container)
else:
parent.add_child(_container)
container.reparent(_container)
toggle_position()
var cnt : Control = _container
if !_as_separate_container:
cnt = _container.get_parent()
if cnt.get_index() != expected_index:
toggle_position()
var menu : MenuButton = IDE.get_menu_button()
if is_instance_valid(menu):
if _input_defined:
return
_input_defined = true
var pop : PopupMenu = menu.get_popup()
var total : int = pop.item_count
var msg : String = _get_traduce("Show/Hide Scripts and Filters Panel")
if !pop.index_pressed.is_connected(_on_pop_pressed):
pop.index_pressed.connect(_on_pop_pressed)
_add_input(pop, msg, _c_input_show_hide)
_id_show_hide_tool = total
total = pop.item_count
msg = _get_traduce("Toggle Script Info/Script List Panel (Only if the separated option enabled)")
_add_input(pop, msg, _c_input_switch_panels)
_id_switch_panels = total
total = pop.item_count
msg = _get_traduce("Toggle Position Script and Filters Panel")
pop.add_item(msg, -1) #, KEY_MASK_CTRL | KEY_NOT_DEFINED_YET
_id_toggle_position_tool =total
func _add_input(pop : PopupMenu, msg : String, input : InputEventKey) -> void:
if null != input:
if input.ctrl_pressed and input.alt_pressed:
pop.add_item(msg, -1, KEY_MASK_CTRL | KEY_MASK_ALT | input.keycode)
elif input.ctrl_pressed:
pop.add_item(msg, -1, KEY_MASK_CTRL | input.keycode)
elif input.alt_pressed:
pop.add_item(msg, -1, KEY_MASK_ALT | input.keycode)
else:
pop.add_item(msg, -1, input.keycode)
else:
pop.add_item(msg, -1, input.keycode) #, KEY_MASK_CTRL | KEY_NOT_DEFINED_YET) #, KEY_MASK_CTRL | KEY_NOT_DEFINED_YET
func _ready() -> void:
if !Engine.get_main_loop().root.is_node_ready():
await Engine.get_main_loop().root.ready
for __ : int in range(30):
var scene : SceneTree = get_tree()
if !is_instance_valid(scene):
return
await scene.process_frame
func _input(event: InputEvent) -> void:
if event.is_pressed() and event.is_match(_c_input_switch_panels):
_on_pop_pressed(_id_switch_panels)
func toggle_position() -> void:
var container : Control = _container
if container:
if !_as_separate_container:
container = container.get_parent()
if null == container:
return
var parent : Control = container.get_parent()
if parent is HSplitContainer and parent.get_child_count() > 1:
if container.get_index() != 0:
var size : float = (parent.get_child(0) as Control).size.x
parent.move_child(container, 0)
parent.split_offset = -size
parent.clamp_split_offset.call_deferred()
var settings : EditorSettings = EditorInterface.get_editor_settings()
if is_instance_valid(settings):
settings.set_setting("plugin/godot_ide/fancy_filters_script/script_list_and_filter_to_right", false)
else:
var size : float = (parent.get_child(1) as Control).size.x
parent.move_child(container, parent.get_child_count() - 1)
parent.split_offset = size
parent.clamp_split_offset.call_deferred()
var settings : EditorSettings = EditorInterface.get_editor_settings()
if is_instance_valid(settings):
settings.set_setting("plugin/godot_ide/fancy_filters_script/script_list_and_filter_to_right", true)
func _exit_tree() -> void:
var container : VSplitContainer = IDE.get_script_list_container()
if is_instance_valid(_container) and _container.is_inside_tree():
IDE.set_config("fancy_filters_script", "script_list_and_filter_to_right", _container.get_index() > 0)
if container:
var current_parent : Node = container.get_parent()
if _placeholder:
for x : Node in _placeholder.get_children():
x.reparent(container)
_placeholder.queue_free()
_placeholder = null
if current_parent != _parent:
if current_parent == null:
_parent.add_child(container)
else:
container.reparent(_parent)
for x : Node in container.get_children():
if x is Control:
x.visible = true
if is_instance_valid(_container):
_container.queue_free()
_container = null
container.visible = true
var parent : Control = container.get_parent()
if parent is HSplitContainer:
if container.get_index() != 0:
var size : float = (parent.get_child(1) as Control).size.x
parent.move_child(container, 0)
parent.split_offset = -size
parent.clamp_split_offset.call_deferred()
#TODO: Remove new menu buttons

View file

@ -0,0 +1 @@
uid://bh2804ipay0ks

View file

@ -0,0 +1,49 @@
@tool
extends Popup
# =============================================================================
# Author: Twister
# Fancy Filter Script
#
# Addon for Godot
# =============================================================================
@export var override_copy_button : Button
var callback : Callable
func _ready() -> void:
var control : Control = EditorInterface.get_base_control()
if !control:
return
get_child(0). add_theme_stylebox_override(&"panel", control.get_theme_stylebox(&"panel", &""))
func enable_copy_override(e : bool) -> void:
override_copy_button.disabled = !e
func override_copy() -> void:
if callback.is_valid():
callback.call(&"override_copy")
close()
func copy() -> void:
if callback.is_valid():
callback.call(&"copy")
close()
func close() -> void:
hide()
queue_free()
func goto() -> void:
if callback.is_valid():
callback.call(&"goto")
func _on_popup_hide() -> void:
close()
func _on_close_requested() -> void:
close()

View file

@ -0,0 +1 @@
uid://cmcd05m1t5hwr

View file

@ -0,0 +1,76 @@
[gd_scene load_steps=4 format=3 uid="uid://d1v4xxafti6nw"]
[ext_resource type="Script" uid="uid://cmcd05m1t5hwr" path="res://addons/_Godot-IDE_/plugins/fancy_filters_script/pop_tree.gd" id="1_x40uf"]
[ext_resource type="Script" uid="uid://b1v225muollg5" path="res://addons/_Godot-IDE_/plugins/fancy_filters_script/button.gd" id="2_l7727"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_l7727"]
content_margin_left = 5.0
content_margin_top = 5.0
content_margin_right = 5.0
content_margin_bottom = 5.0
bg_color = Color(0.115499996, 0.132, 0.15949999, 1)
corner_detail = 1
anti_aliasing = false
[node name="PopTree" type="Popup" node_paths=PackedStringArray("override_copy_button")]
oversampling_override = 1.0
title = "Member Selected"
position = Vector2i(496, 231)
size = Vector2i(161, 189)
visible = true
content_scale_aspect = 4
script = ExtResource("1_x40uf")
override_copy_button = NodePath("PanelContainer/MarginContainer/VBoxContainer/override_copy")
[node name="PanelContainer" type="PanelContainer" parent="."]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_l7727")
[node name="MarginContainer" type="MarginContainer" parent="PanelContainer"]
layout_mode = 2
theme_override_constants/margin_left = 4
theme_override_constants/margin_top = 4
theme_override_constants/margin_right = 4
theme_override_constants/margin_bottom = 4
[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/MarginContainer"]
layout_mode = 2
[node name="Label" type="Label" parent="PanelContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
text = "Select Option"
horizontal_alignment = 1
[node name="HSeparator" type="HSeparator" parent="PanelContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
[node name="copy" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 8
text = "Copy"
script = ExtResource("2_l7727")
[node name="override_copy" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 8
text = "Copy for override"
script = ExtResource("2_l7727")
[node name="goto" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 8
text = "Go to member"
script = ExtResource("2_l7727")
[node name="close" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 10
text = "Close"
script = ExtResource("2_l7727")
[connection signal="close_requested" from="." to="." method="_on_close_requested"]
[connection signal="popup_hide" from="." to="." method="_on_popup_hide"]

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1 @@
uid://bwtq1pkujrb1d

View file

@ -0,0 +1,13 @@
@tool
extends Button
# =============================================================================
# Author: Twister
# Fancy Search Class
#
# Addon for Godot
# =============================================================================
func _pressed() -> void:
if owner.has_method(name):
owner.call(name)

View file

@ -0,0 +1 @@
uid://c6pfvkgkabvt6

View file

@ -0,0 +1,66 @@
@tool
extends LineEdit
# =============================================================================
# Author: Twister
# Fancy Search Class
#
# Addon for Godot
# =============================================================================
@export var tree : Tree = null
func _ready() -> void:
text_changed.connect(sxrch)
func reset() -> void:
if tree:
var root : TreeItem = tree.get_root()
if !root:
return
_reset(root)
func _reset(root : TreeItem) -> void:
root.visible = true
for c : TreeItem in root.get_children():
_reset(c)
func sxrch(txt : String) -> void:
reset()
if txt.is_empty():
return
if tree:
var root : TreeItem = tree.get_root()
if !root:
return
var rgx0 : RegEx = RegEx.create_from_string("(?i)\\b{0}\\b".format([txt]))
var rgx1 : RegEx = RegEx.create_from_string("(?i).*{0}.*".format([txt]))
var d0 : Array[TreeItem] = []
var d1 : Array[TreeItem] = []
for x : RegEx in [rgx0, rgx1]:
if !is_instance_valid(x) or !x.is_valid():
return
_sxrch(root, rgx0, rgx1, d0, d1)
root.visible = true
for t : TreeItem in d0:
_visible(t)
for t : TreeItem in d1:
_visible(t)
func _visible(root : TreeItem) -> void:
if root:
root.visible = true
_visible(root.get_parent())
func _sxrch(root : TreeItem, rgx0 : RegEx, rgx1 : RegEx, d0 : Array[TreeItem], d1 : Array[TreeItem]) -> void:
var txt : String = root.get_text(0)
root.visible = false
if rgx0.search(txt) != null:
d0.append(root)
elif d0.size() == 0 and rgx1.search(txt) != null:
d1.append(root)
for x : TreeItem in root.get_children():
_sxrch(x, rgx0, rgx1, d0, d1)

View file

@ -0,0 +1 @@
uid://blmveofp20cm1

View file

@ -0,0 +1,383 @@
@tool
extends Window
# =============================================================================
# Author: Twister
# Fancy Search Class
#
# Addon for Godot
# =============================================================================
@export var _container : TabContainer = null
@export var _tree : Tree = null
@export var _tree_recents : Tree = null
#var files : Dictionary[StringName, Dictionary] = {}
const CUTE_ICON : Texture2D = preload("res://addons/_Godot-IDE_/shared_resources/Script.svg")
var _first_time : bool = false
var _recents : PackedStringArray = []
var _default_tx : Texture2D = null
var _collapsed : bool = false
func _enter_tree() -> void:
_first_time = true
var screen : Vector2 = DisplayServer.screen_get_size()
var value : Variant = IDE.get_config("fancy_search_class", "size")
if value is Vector2 or value is Vector2i:
screen = value
else:
screen = screen * 0.6
IDE.clamp_screen_size(screen, 0.3, 1.0)
size = screen
func _ready() -> void:
update()
for x : int in range(1, _container.get_child_count(), 1):
_container.get_child(x).queue_free()
visibility_changed.connect(_on_visible)
_container.tab_changed.connect(_on_change)
_tree.item_activated.connect(_on_activate.bind(_tree))
_tree_recents.item_activated.connect(_on_activate.bind(_tree_recents))
var result : Variant = IDE.get_file_config_value("fancy_search_class", "recents")
if result is PackedStringArray:
_recents = result
var control : Control = EditorInterface.get_base_control()
if !control:
return
get_child(0). add_theme_stylebox_override(&"panel", control.get_theme_stylebox(&"panel", &""))
func _save() -> void:
IDE.set_file_config_value("fancy_search_class", "recents", _recents)
func _on_visible() -> void:
if visible:
update()
else:
_save()
queue_free()
func clear() -> void:
_recents.clear()
_tree_recents.clear()
func _on_activate(tree : Tree) -> void:
if !tree:
return
var item : TreeItem = tree.get_selected()
if !item:
return
var value : Variant = item.get_metadata(0)
if value is String:
if FileAccess.file_exists(value):
EditorInterface.select_file(value)
if ResourceLoader.exists(value):
var res : Resource = ResourceLoader.load(value)
if !(value in _recents):
while _recents.size() > 30:
_recents.remove_at(0)
_recents.append(value)
if res is Resource:
if res is PackedScene:
EditorInterface.open_scene_from_path(value)
elif res is Script:
EditorInterface.edit_script(res)
else:
EditorInterface.edit_resource(res)
hide()
func _on_change(_tab_changed : int) -> void:
var control : Control = _container.get_current_tab_control()
if control:
_update_tree(control.name)
func _exit_tree() -> void:
if is_instance_valid(_tree):
_tree.clear()
IDE.set_config("fancy_search_class", "size", size)
func close() -> void:
hide()
func get_icon(type : String) -> Texture2D:
var control : Control = EditorInterface.get_base_control()
if !control:
return null
return control.get_theme_icon(type, "EditorIcons")
func _make_tree(root : TreeItem, key : StringName, dat : Dictionary, buff : Dictionary) -> void:
if buff.has(key):
return
var tree : TreeItem = root.create_child()
buff[key] = tree
tree.set_text(0, key)
for k : StringName in dat.keys():
var packed : PackedStringArray = dat["class"]
for p : String in packed:
var t : TreeItem = tree.create_child()
t.set_text(0, p)
buff[p] = t
var pumpking : Pumpking = null
class Pumpking extends RefCounted:
var cute_name : StringName = ""
var next : Array[Pumpking] = []
var back : Pumpking = null
var witchies : PackedStringArray = []
func born_pumpking() -> Pumpking:
var borned_pumpking : Pumpking = Pumpking.new()
next.append(borned_pumpking)
return borned_pumpking
func merge_pumpking(pumpking : Pumpking) -> void:
if !(next in next) and back != pumpking:
if pumpking in next:
return
next.append(pumpking)
func get_pumpking(check_cute_name : StringName) -> Pumpking:
if check_cute_name == cute_name:
return self
for x : Pumpking in next:
var y : Pumpking = x.get_pumpking(check_cute_name)
if y:
return y
return null
func _update_tree(filter : StringName) -> void:
_tree.clear()
if pumpking:
if filter == &"All":
_collapsed = true
var root : TreeItem = _tree.create_item()
root.set_text(0, pumpking.cute_name)
for x : Pumpking in pumpking.next:
_fill_tree(root, x)
else:
_collapsed = false
var current : Pumpking = pumpking.get_pumpking(filter)
if current != pumpking:
var root : TreeItem = _tree.create_item()
root.set_text(0, current.cute_name)
_fill_tree(root, current)
else:
_update_tree(&"All")
func _process(_delta: float) -> void:
var fs : EditorFileSystem = EditorInterface.get_resource_filesystem()
if !fs:
return
if fs.is_scanning():
return
set_process(false)
_update()
func update() -> void:
set_process(true)
func _update() -> void:
var fs : EditorFileSystem = EditorInterface.get_resource_filesystem()
if fs:
var fd : EditorFileSystemDirectory = fs.get_filesystem()
if fd:
for x : int in range(1, _container.get_child_count(), 1):
var node : Node = _container.get_child(x)
node.name = node.name + "_queue"
node.queue_free()
pumpking = Pumpking.new()
search(fd)
if _default_tx == null:
_default_tx = get_icon("DEFAULT_NOT_FOUND")
for p : Pumpking in pumpking.next:
_fill_tab(p)
if _first_time:
_first_time = false
_update_tree.call_deferred(&"All")
_update_recents()
func _fill_tab(pump : Pumpking) -> void:
var control : Control = Control.new()
var index : int = -1
var nname : StringName = pump.cute_name
control.set_deferred(&"name", nname)
_container.add_child(control)
index = control.get_index()
if _container.get_tab_count() > index:
var icon : Texture2D = get_icon(nname)
if icon == _default_tx:
icon = CUTE_ICON
_container.set_tab_icon(index, icon)
for p : Pumpking in pump.next:
_fill_tab(p)
func _fill_tree(root : TreeItem, pump : Pumpking) -> void:
var tree : TreeItem = root.create_child()
var nname : StringName = pump.cute_name
tree.set_text(0, nname)
var icon : Texture2D = get_icon(nname)
if icon == _default_tx:
icon = CUTE_ICON
tree.set_icon(0, icon)
tree.set_selectable(0, false)
tree.collapsed = _collapsed
for w : String in pump.witchies:
var witch : TreeItem = tree.create_child()
var text : String = w
var slice : int = w.get_slice_count("/")
if slice > 6:
text = w.get_file()
for x : int in range(slice - 1, slice - 4, -1):
text = w.get_slice("/", x).path_join(text)
text = "...".path_join(text)
witch.set_text(0, text)
witch.set_icon(0, icon)
witch.set_custom_color(0, Color.DARK_GRAY)
witch.set_icon_modulate(0, Color.DARK_GRAY)
witch.set_metadata(0, w)
witch.set_tooltip_text(0, w)
for x : Pumpking in pump.next:
_fill_tree(tree, x)
func _update_recents() -> void:
_tree_recents.clear()
var fs : EditorFileSystem = EditorInterface.get_resource_filesystem()
if fs:
var data : Dictionary[String, PackedStringArray] = {}
var exist : PackedStringArray = []
for x : String in _recents:
if FileAccess.file_exists(x):
var type : StringName = "File"
var fe : EditorFileSystemDirectory = fs.get_filesystem_path(x.get_base_dir())
if fe:
for f : int in fe.get_file_count():
if fe.get_file_path(f) == x:
type = fe.get_file_script_class_name(f)
if type.is_empty():
type = fe.get_file_script_class_extends(f)
break
if type.is_empty():
type = fs.get_file_type(x)
if !data.has(type):
var packed : PackedStringArray = []
data[type] = packed
data[type].append(x)
exist.append(x)
_recents = exist
var root : TreeItem = _tree_recents.create_item()
root.set_text(0, "Recents Files")
root.set_selectable(0, false)
root.set_custom_color(0, Color.WHITE)
for k : String in data.keys():
var item : TreeItem = root.create_child()
var icon : Texture2D = get_icon(k)
item.set_text(0, k)
item.set_selectable(0, false)
item.set_custom_color(0, Color.GRAY)
item.set_icon_modulate(0, Color.GRAY)
if icon == _default_tx:
icon = CUTE_ICON
item.set_icon(0, icon)
for y : String in data[k]:
var fitem : TreeItem = item.create_child()
fitem.set_text(0, y.get_file())
fitem.set_icon(0, icon)
fitem.set_tooltip_text(0, y)
fitem.set_custom_color(0, Color.DARK_GRAY)
fitem.set_icon_modulate(0, Color.DARK_GRAY)
fitem.set_metadata(0, y)
func search(fd : EditorFileSystemDirectory) -> void:
if pumpking == null:
pumpking = Pumpking.new()
pumpking.cute_name = "Found Files"
for f : int in fd.get_file_count():
var extension : StringName = fd.get_file_script_class_extends(f)
var type : StringName = fd.get_file_script_class_name(f)
var ee : bool = extension.is_empty()
var te : bool = type.is_empty()
if ee and te:
continue
var path : String = fd.get_file_path(f)
if !ee:
var grand_pumpking : Pumpking = pumpking.get_pumpking(extension)
if grand_pumpking == null:
grand_pumpking = pumpking.born_pumpking()
grand_pumpking.cute_name = extension
if !te:
var newer_pumpking : Pumpking = grand_pumpking.get_pumpking(type)
if newer_pumpking == null:
newer_pumpking = grand_pumpking.born_pumpking()
newer_pumpking.cute_name = type
newer_pumpking.witchies.append(path)
else:
grand_pumpking.witchies.append(path)
elif !te:
var new_pumpking : Pumpking = pumpking.get_pumpking(type)
if new_pumpking == null:
new_pumpking = pumpking.born_pumpking()
new_pumpking.cute_name = type
new_pumpking.witchies.append(path)
#if !ee:
#if !files.has(extension):
#var current_files : PackedStringArray = []
#var classes : PackedStringArray = []
#files[extension] = {
#"files" : current_files,
#"class" : classes,
#"parent" : ""
#}
#var data : Dictionary = files[extension]
#var packed : PackedStringArray = data["files"]
#
#if te:
#if !(path in packed):
#packed.append(path)
#
#if !te:
#if !files.has(type):
#var current_files : PackedStringArray = []
#var classes : PackedStringArray = []
#files[type] = {
#"files" : current_files,
#"class" : classes,
#"parent" : extension
#}
#var data : Dictionary = files[type]
#var packed : PackedStringArray = data["files"]
#if !(path in packed):
#packed.append(path)
for x : int in fd.get_subdir_count():
search(fd.get_subdir(x))

View file

@ -0,0 +1 @@
uid://dalllwmyh2v5m

View file

@ -0,0 +1,126 @@
[gd_scene load_steps=6 format=3 uid="uid://cfwi81ii6ww5b"]
[ext_resource type="Script" uid="uid://dalllwmyh2v5m" path="res://addons/_Godot-IDE_/plugins/fancy_search_class/gui/main.gd" id="1_v5iyo"]
[ext_resource type="Script" uid="uid://c6pfvkgkabvt6" path="res://addons/_Godot-IDE_/plugins/fancy_search_class/gui/button.gd" id="2_bnpnb"]
[ext_resource type="Texture2D" uid="uid://816fejewtbfj" path="res://addons/_Godot-IDE_/shared_resources/search.svg" id="2_nf02n"]
[ext_resource type="Script" uid="uid://blmveofp20cm1" path="res://addons/_Godot-IDE_/plugins/fancy_search_class/gui/line_edit.gd" id="3_m1yal"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_nf02n"]
content_margin_left = 5.0
content_margin_top = 5.0
content_margin_right = 5.0
content_margin_bottom = 5.0
bg_color = Color(0.1155, 0.132, 0.1595, 1)
corner_detail = 1
anti_aliasing = false
[node name="Window" type="Popup" node_paths=PackedStringArray("_container", "_tree", "_tree_recents")]
title = "Fancy Search Class"
initial_position = 4
size = Vector2i(816, 500)
visible = true
script = ExtResource("1_v5iyo")
_container = NodePath("Main/MainContainer/HBoxContainer/BoxContainer/Container")
_tree = NodePath("Main/MainContainer/HBoxContainer/BoxContainer/Resource/Tree")
_tree_recents = NodePath("Main/MainContainer/HBoxContainer/RecentsContainer/SCroll/Recents")
[node name="Main" type="PanelContainer" parent="."]
custom_minimum_size = Vector2(200, 500)
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_nf02n")
[node name="MainContainer" type="MarginContainer" parent="Main"]
layout_mode = 2
theme_override_constants/margin_left = 4
theme_override_constants/margin_top = 4
theme_override_constants/margin_right = 4
theme_override_constants/margin_bottom = 4
[node name="HBoxContainer" type="HBoxContainer" parent="Main/MainContainer"]
layout_mode = 2
[node name="BoxContainer" type="VBoxContainer" parent="Main/MainContainer/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="Tittle" type="Label" parent="Main/MainContainer/HBoxContainer/BoxContainer"]
layout_mode = 2
text = "Search Files By Class"
horizontal_alignment = 1
vertical_alignment = 1
[node name="Separator" type="HSeparator" parent="Main/MainContainer/HBoxContainer/BoxContainer"]
layout_mode = 2
[node name="Container" type="TabContainer" parent="Main/MainContainer/HBoxContainer/BoxContainer"]
layout_mode = 2
current_tab = 0
[node name="All" type="Control" parent="Main/MainContainer/HBoxContainer/BoxContainer/Container"]
layout_mode = 2
metadata/_tab_index = 0
[node name="LineEdit" type="LineEdit" parent="Main/MainContainer/HBoxContainer/BoxContainer" node_paths=PackedStringArray("tree")]
layout_mode = 2
placeholder_text = "File Search"
alignment = 1
clear_button_enabled = true
right_icon = ExtResource("2_nf02n")
script = ExtResource("3_m1yal")
tree = NodePath("../Resource/Tree")
[node name="Resource" type="ScrollContainer" parent="Main/MainContainer/HBoxContainer/BoxContainer"]
layout_mode = 2
size_flags_vertical = 3
[node name="Tree" type="Tree" parent="Main/MainContainer/HBoxContainer/BoxContainer/Resource"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="Bottom" type="HSeparator" parent="Main/MainContainer/HBoxContainer/BoxContainer"]
layout_mode = 2
[node name="close" type="Button" parent="Main/MainContainer/HBoxContainer/BoxContainer"]
layout_mode = 2
text = "Close"
script = ExtResource("2_bnpnb")
[node name="RecentsContainer" type="VBoxContainer" parent="Main/MainContainer/HBoxContainer"]
custom_minimum_size = Vector2(120, 0)
layout_mode = 2
[node name="Tittle" type="Label" parent="Main/MainContainer/HBoxContainer/RecentsContainer"]
layout_mode = 2
text = "Recents"
horizontal_alignment = 1
[node name="Sep" type="HSeparator" parent="Main/MainContainer/HBoxContainer/RecentsContainer"]
layout_mode = 2
[node name="LineEdit2" type="LineEdit" parent="Main/MainContainer/HBoxContainer/RecentsContainer" node_paths=PackedStringArray("tree")]
layout_mode = 2
placeholder_text = "Recent Search"
alignment = 1
clear_button_enabled = true
right_icon = ExtResource("2_nf02n")
script = ExtResource("3_m1yal")
tree = NodePath("../SCroll/Recents")
[node name="SCroll" type="ScrollContainer" parent="Main/MainContainer/HBoxContainer/RecentsContainer"]
layout_mode = 2
size_flags_vertical = 3
[node name="Recents" type="Tree" parent="Main/MainContainer/HBoxContainer/RecentsContainer/SCroll"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="clear" type="Button" parent="Main/MainContainer/HBoxContainer/RecentsContainer"]
layout_mode = 2
text = "Clear"
script = ExtResource("2_bnpnb")

View file

@ -0,0 +1,7 @@
[plugin]
name="Fancy Search Class"
description="Allow easy search class files"
author="Twister"
version=""
script="plugin.gd"

View file

@ -0,0 +1,33 @@
@tool
extends EditorPlugin
# =============================================================================
# Author: Twister
# Fancy Search Class
#
# Addon for Godot
# =============================================================================
const FANCY_SEARCH : PackedScene = preload("res://addons/_Godot-IDE_/plugins/fancy_search_class/gui/main.tscn")
var pop : Window = null
var _c_input : InputEvent = null
func _init() -> void:
var input : Variant = IDE.get_config("fancy_search_class", "invoke_input")
if input is InputEvent:
_c_input = input
else:
_c_input = InputEventKey.new()
_c_input.pressed = true
_c_input.alt_pressed = true
_c_input.keycode = KEY_DELETE
IDE.set_config("fancy_search_class", "invoke_input", _c_input)
func _input(event: InputEvent) -> void:
if event.is_pressed() and event.is_match(_c_input):
if !is_instance_valid(pop):
pop = FANCY_SEARCH.instantiate()
add_child(pop)
pop.popup_centered()

View file

@ -0,0 +1 @@
uid://dhvs8xuxenk2y

View file

@ -0,0 +1,13 @@
@tool
extends Button
# =============================================================================
# Author: Twister
# Fancy Search Files
#
# Addon for Godot
# =============================================================================
func _pressed() -> void:
if owner.has_method(name):
owner.call(name)

View file

@ -0,0 +1 @@
uid://cpdqmdfvgpxmv

View file

@ -0,0 +1,66 @@
@tool
extends LineEdit
# =============================================================================
# Author: Twister
# Fancy Search Files
#
# Addon for Godot
# =============================================================================
@export var tree : Tree = null
func _ready() -> void:
text_changed.connect(sxrch)
func reset() -> void:
if tree:
var root : TreeItem = tree.get_root()
if !root:
return
_reset(root)
func _reset(root : TreeItem) -> void:
root.visible = true
for c : TreeItem in root.get_children():
_reset(c)
func sxrch(txt : String) -> void:
reset()
if txt.is_empty():
return
if tree:
var root : TreeItem = tree.get_root()
if !root:
return
var rgx0 : RegEx = RegEx.create_from_string("(?i)\\b{0}\\b".format([txt]))
var rgx1 : RegEx = RegEx.create_from_string("(?i).*{0}.*".format([txt]))
var d0 : Array[TreeItem] = []
var d1 : Array[TreeItem] = []
for x : RegEx in [rgx0, rgx1]:
if !is_instance_valid(x) or !x.is_valid():
return
_sxrch(root, rgx0, rgx1, d0, d1)
root.visible = false
for t : TreeItem in d0:
_visible(t)
for t : TreeItem in d1:
_visible(t)
func _visible(root : TreeItem) -> void:
if root:
root.visible = true
_visible(root.get_parent())
func _sxrch(root : TreeItem, rgx0 : RegEx, rgx1 : RegEx, d0 : Array[TreeItem], d1 : Array[TreeItem]) -> void:
var txt : String = root.get_text(0)
root.visible = false
if rgx0.search(txt) != null:
d0.append(root)
elif d0.size() == 0 and rgx1.search(txt) != null:
d1.append(root)
for x : TreeItem in root.get_children():
_sxrch(x, rgx0, rgx1, d0, d1)

View file

@ -0,0 +1 @@
uid://bx6ivdaldbcf8

View file

@ -0,0 +1,253 @@
@tool
extends Window
# =============================================================================
# Author: Twister
# Fancy Search Files
#
# Addon for Godot
# =============================================================================
@export var _container : TabContainer = null
@export var _tree : Tree = null
@export var _tree_recents : Tree = null
var files : Dictionary[StringName, PackedStringArray] = {}
var _first_time : bool = false
var _recents : PackedStringArray = []
var _default_tx : Texture2D = null
func _enter_tree() -> void:
_first_time = true
var screen : Vector2 = DisplayServer.screen_get_size()
var value : Variant = IDE.get_config("fancy_search_files", "size")
if value is Vector2 or value is Vector2i:
screen = value
else:
screen = screen * 0.6
IDE.clamp_screen_size(screen, 0.3, 1.0)
size = screen
func _ready() -> void:
update()
for x : int in range(1, _container.get_child_count(), 1):
_container.get_child(x).queue_free()
visibility_changed.connect(_on_visible)
_container.tab_changed.connect(_on_change)
_tree.item_activated.connect(_on_activate.bind(_tree))
_tree_recents.item_activated.connect(_on_activate.bind(_tree_recents))
var result : Variant = IDE.get_file_config_value("fancy_search_files", "recents")
if result is PackedStringArray:
_recents = result
var control : Control = EditorInterface.get_base_control()
if !control:
return
get_child(0). add_theme_stylebox_override(&"panel", control.get_theme_stylebox(&"panel", &""))
func _save() -> void:
IDE.set_file_config_value("fancy_search_files", "recents", _recents)
func _on_visible() -> void:
if visible:
update()
else:
_save()
queue_free()
func clear() -> void:
_recents.clear()
_tree_recents.clear()
func _on_activate(tree : Tree) -> void:
if !tree:
return
var item : TreeItem = tree.get_selected()
if !item:
return
var value : Variant = item.get_metadata(0)
if value is String:
if FileAccess.file_exists(value):
EditorInterface.select_file(value)
if ResourceLoader.exists(value):
var res : Resource = ResourceLoader.load(value)
if !(value in _recents):
while _recents.size() > 30:
_recents.remove_at(0)
_recents.append(value)
if res is Resource:
if res is PackedScene:
EditorInterface.open_scene_from_path(value)
elif res is Script:
EditorInterface.edit_script(res)
else:
EditorInterface.edit_resource(res)
hide()
func _on_change(_tab_changed : int) -> void:
var control : Control = _container.get_current_tab_control()
if control:
_update_tree(control.name)
func _exit_tree() -> void:
if is_instance_valid(_tree):
_tree.clear()
IDE.set_config("fancy_search_files", "size", size)
func close() -> void:
hide()
func get_icon(type : String) -> Texture2D:
var control : Control = EditorInterface.get_base_control()
if !control:
return null
var icon : Texture2D = control.get_theme_icon(type, "EditorIcons")
if icon == _default_tx:
icon = control.get_theme_icon("File", "EditorIcons")
return icon
func _update_tree(filter : StringName) -> void:
_tree.clear()
if files.size() == 0:
return
if filter == &"All":
var root : TreeItem = _tree.create_item()
root.set_selectable(0, false)
for k : StringName in files.keys():
var item : TreeItem = root.create_child()
var icon : Texture2D = get_icon(k)
item.set_text(0, k)
item.set_icon_modulate(0, Color.WHITE)
item.set_selectable(0, false)
item.collapsed = true
item.set_icon(0, icon)
for f : String in files[k]:
var fitem : TreeItem = item.create_child()
var slice : int = f.get_slice_count("/")
if slice > 5:
var txt : String = ""
for x : int in range(slice - 1, 3, -1):
txt = f.get_slice("/", x).path_join(txt)
txt = "...".path_join(txt)
fitem.set_text(0, txt)
else:
fitem.set_text(0, f)
fitem.set_icon(0, icon)
fitem.set_metadata(0, f)
fitem.set_icon_modulate(0, Color.GRAY)
fitem.set_custom_color(0, Color.GRAY)
fitem.set_tooltip_text(0, f)
elif files.has(filter):
var root : TreeItem = _tree.create_item()
var item : TreeItem = root.create_child()
var icon : Texture2D = get_icon(filter)
item.set_text(0, filter)
item.set_icon_modulate(0, Color.WHITE)
item.set_selectable(0, false)
item.collapsed = false
item.set_icon(0, icon)
for f : String in files[filter]:
var fitem : TreeItem = item.create_child()
fitem.set_text(0, f.get_file())
fitem.set_icon(0, icon)
fitem.set_metadata(0, f)
fitem.set_icon_modulate(0, Color.GRAY)
fitem.set_custom_color(0, Color.GRAY)
fitem.set_tooltip_text(0, f)
else:
push_warning("Not valid type!")
func _process(_delta: float) -> void:
var fs : EditorFileSystem = EditorInterface.get_resource_filesystem()
if !fs:
return
if fs.is_scanning():
return
set_process(false)
_update()
func update() -> void:
set_process(true)
func _update() -> void:
var fs : EditorFileSystem = EditorInterface.get_resource_filesystem()
if fs:
var fd : EditorFileSystemDirectory = fs.get_filesystem()
if fd:
for x : int in range(1, _container.get_child_count(), 1):
var node : Node = _container.get_child(x)
node.name = node.name + "_queue"
node.queue_free()
files.clear()
search(fd)
if _default_tx == null:
_default_tx = get_icon("DEFAULT_NOT_FOUND")
for x : StringName in files.keys():
var control : Control = Control.new()
var index : int = -1
control.set_deferred(&"name", x)
_container.add_child(control)
index = control.get_index()
if _container.get_tab_count() > index:
_container.set_tab_icon(index, get_icon(x))
if _first_time:
_first_time = false
_update_tree.call_deferred(&"All")
_update_recents()
func _update_recents() -> void:
_tree_recents.clear()
var fs : EditorFileSystem = EditorInterface.get_resource_filesystem()
if fs:
var data : Dictionary[String, PackedStringArray] = {}
for x : String in _recents:
if FileAccess.file_exists(x):
var type : String = fs.get_file_type(x)
if !data.has(type):
var packed : PackedStringArray = []
data[type] = packed
data[type].append(x)
var root : TreeItem = _tree_recents.create_item()
root.set_text(0, "Recents Files")
root.set_selectable(0, false)
root.set_custom_color(0, Color.WHITE)
for k : String in data.keys():
var item : TreeItem = root.create_child()
var icon : Texture2D = get_icon(k)
item.set_text(0, k)
item.set_icon(0, icon)
item.set_selectable(0, false)
item.set_custom_color(0, Color.GRAY)
item.set_icon_modulate(0, Color.GRAY)
for y : String in data[k]:
var fitem : TreeItem = item.create_child()
fitem.set_text(0, y.get_file())
fitem.set_icon(0, icon)
fitem.set_tooltip_text(0, y)
fitem.set_custom_color(0, Color.DARK_GRAY)
fitem.set_icon_modulate(0, Color.DARK_GRAY)
fitem.set_metadata(0, y)
func search(fd : EditorFileSystemDirectory) -> void:
for f : int in fd.get_file_count():
var type : StringName = fd.get_file_type(f)
if !files.has(type):
var _packed : PackedStringArray = []
files[type] = _packed
files[type].append(fd.get_file_path(f))
for x : int in fd.get_subdir_count():
search(fd.get_subdir(x))

View file

@ -0,0 +1 @@
uid://dvsbvurbdecex

View file

@ -0,0 +1,126 @@
[gd_scene load_steps=6 format=3 uid="uid://cddiai7iiut3l"]
[ext_resource type="Script" uid="uid://dvsbvurbdecex" path="res://addons/_Godot-IDE_/plugins/fancy_search_files/gui/main.gd" id="1_0f0lw"]
[ext_resource type="Texture2D" uid="uid://816fejewtbfj" path="res://addons/_Godot-IDE_/shared_resources/search.svg" id="2_fowvl"]
[ext_resource type="Script" uid="uid://cpdqmdfvgpxmv" path="res://addons/_Godot-IDE_/plugins/fancy_search_files/gui/button.gd" id="2_ydlx0"]
[ext_resource type="Script" uid="uid://bx6ivdaldbcf8" path="res://addons/_Godot-IDE_/plugins/fancy_search_files/gui/line_edit.gd" id="3_5ntm4"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_fowvl"]
content_margin_left = 3.0
content_margin_top = 3.0
content_margin_right = 3.0
content_margin_bottom = 3.0
bg_color = Color(0.1155, 0.132, 0.1595, 1)
corner_detail = 1
anti_aliasing = false
[node name="Window" type="Popup" node_paths=PackedStringArray("_container", "_tree", "_tree_recents")]
title = "Fancy Search Files"
initial_position = 4
size = Vector2i(816, 500)
visible = true
script = ExtResource("1_0f0lw")
_container = NodePath("Main/MainContainer/HBoxContainer/BoxContainer/Container")
_tree = NodePath("Main/MainContainer/HBoxContainer/BoxContainer/Resource/Tree")
_tree_recents = NodePath("Main/MainContainer/HBoxContainer/RecentsContainer/SCroll/Recents")
[node name="Main" type="PanelContainer" parent="."]
custom_minimum_size = Vector2(200, 500)
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_fowvl")
[node name="MainContainer" type="MarginContainer" parent="Main"]
layout_mode = 2
theme_override_constants/margin_left = 4
theme_override_constants/margin_top = 4
theme_override_constants/margin_right = 4
theme_override_constants/margin_bottom = 4
[node name="HBoxContainer" type="HBoxContainer" parent="Main/MainContainer"]
layout_mode = 2
[node name="BoxContainer" type="VBoxContainer" parent="Main/MainContainer/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="Tittle" type="Label" parent="Main/MainContainer/HBoxContainer/BoxContainer"]
layout_mode = 2
text = "Search Files By Type"
horizontal_alignment = 1
vertical_alignment = 1
[node name="Separator" type="HSeparator" parent="Main/MainContainer/HBoxContainer/BoxContainer"]
layout_mode = 2
[node name="Container" type="TabContainer" parent="Main/MainContainer/HBoxContainer/BoxContainer"]
layout_mode = 2
current_tab = 0
[node name="All" type="Control" parent="Main/MainContainer/HBoxContainer/BoxContainer/Container"]
layout_mode = 2
metadata/_tab_index = 0
[node name="LineEdit" type="LineEdit" parent="Main/MainContainer/HBoxContainer/BoxContainer" node_paths=PackedStringArray("tree")]
layout_mode = 2
placeholder_text = "File Search"
alignment = 1
clear_button_enabled = true
right_icon = ExtResource("2_fowvl")
script = ExtResource("3_5ntm4")
tree = NodePath("../Resource/Tree")
[node name="Resource" type="ScrollContainer" parent="Main/MainContainer/HBoxContainer/BoxContainer"]
layout_mode = 2
size_flags_vertical = 3
[node name="Tree" type="Tree" parent="Main/MainContainer/HBoxContainer/BoxContainer/Resource"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="Bottom" type="HSeparator" parent="Main/MainContainer/HBoxContainer/BoxContainer"]
layout_mode = 2
[node name="close" type="Button" parent="Main/MainContainer/HBoxContainer/BoxContainer"]
layout_mode = 2
text = "Close"
script = ExtResource("2_ydlx0")
[node name="RecentsContainer" type="VBoxContainer" parent="Main/MainContainer/HBoxContainer"]
custom_minimum_size = Vector2(120, 0)
layout_mode = 2
[node name="Tittle" type="Label" parent="Main/MainContainer/HBoxContainer/RecentsContainer"]
layout_mode = 2
text = "Recents"
horizontal_alignment = 1
[node name="Sep" type="HSeparator" parent="Main/MainContainer/HBoxContainer/RecentsContainer"]
layout_mode = 2
[node name="LineEdit2" type="LineEdit" parent="Main/MainContainer/HBoxContainer/RecentsContainer" node_paths=PackedStringArray("tree")]
layout_mode = 2
placeholder_text = "Recent Search"
alignment = 1
clear_button_enabled = true
right_icon = ExtResource("2_fowvl")
script = ExtResource("3_5ntm4")
tree = NodePath("../SCroll/Recents")
[node name="SCroll" type="ScrollContainer" parent="Main/MainContainer/HBoxContainer/RecentsContainer"]
layout_mode = 2
size_flags_vertical = 3
[node name="Recents" type="Tree" parent="Main/MainContainer/HBoxContainer/RecentsContainer/SCroll"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="clear" type="Button" parent="Main/MainContainer/HBoxContainer/RecentsContainer"]
layout_mode = 2
text = "Clear"
script = ExtResource("2_ydlx0")

View file

@ -0,0 +1,7 @@
[plugin]
name="Fancy Search Files"
description="Allow easy search files by type"
author="Twister"
version=""
script="plugin.gd"

View file

@ -0,0 +1,33 @@
@tool
extends EditorPlugin
# =============================================================================
# Author: Twister
# Fancy Search Files
#
# Addon for Godot
# =============================================================================
const FANCY_SEARCH : PackedScene = preload("res://addons/_Godot-IDE_/plugins/fancy_search_files/gui/main.tscn")
var pop : Window = null
var _c_input : InputEvent = null
func _init() -> void:
var input : Variant = IDE.get_config("fancy_search_files", "invoke_input")
if input is InputEvent:
_c_input = input
else:
_c_input = InputEventKey.new()
_c_input.pressed = true
_c_input.ctrl_pressed = true
_c_input.alt_pressed = true
_c_input.keycode = KEY_SPACE
IDE.set_config("fancy_search_files", "invoke_input", _c_input)
func _input(event: InputEvent) -> void:
if event.is_pressed() and event.is_match(_c_input):
if !is_instance_valid(pop):
pop = FANCY_SEARCH.instantiate()
add_child(pop)
pop.popup_centered()

View file

@ -0,0 +1 @@
uid://8e7vxkrhsi2j

View file

@ -0,0 +1,7 @@
[plugin]
name="GDOverrideFunctions"
description="Allow select virtual functions for override/implement."
author="Twister"
version="0.3"
script="plugin.gd"

View file

@ -0,0 +1,54 @@
@tool
extends EditorPlugin
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# GD Override Functions
#
# Virtual Popups override functions. godot 4
# author: "Twister"
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
var RES : Script = preload("res://addons/_Godot-IDE_/plugins/gd_override_functions/popup/virtuals_popup_context.gd")
#region extension_features
var popup_virtual_functions : RefCounted = null
var popup_virtual_functions_code : RefCounted = null
#endregion
var _c_input : InputEvent = null
func _init() -> void:
var editor : EditorSettings = EditorInterface.get_editor_settings()
if editor:
var input : Variant = editor.get_setting("plugin/gd_override_functions/invoke_input")
if input is InputEvent:
_c_input = input
else:
_c_input = InputEventKey.new()
_c_input.pressed = true
_c_input.alt_pressed = true
_c_input.keycode = KEY_INSERT
editor.set_setting("plugin/gd_override_functions/invoke_input", _c_input)
func _enter_tree() -> void:
popup_virtual_functions = RES.new()
popup_virtual_functions_code = RES.new()
add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR, popup_virtual_functions)
add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR_CODE, popup_virtual_functions_code)
func _exit_tree() -> void:
remove_context_menu_plugin(popup_virtual_functions)
remove_context_menu_plugin(popup_virtual_functions_code)
popup_virtual_functions = null
popup_virtual_functions_code = null
#Input because the dev can be change buttons ( >.>)
func _input(event: InputEvent) -> void:
if event.is_pressed() and event.is_match(_c_input, true):
var editor : ScriptEditor = EditorInterface.get_script_editor()
if editor:
var sc : Script = editor.get_current_script()
if sc:
if popup_virtual_functions and popup_virtual_functions.has_method(&"callback"):
popup_virtual_functions_code.call(&"callback", sc)

View file

@ -0,0 +1 @@
uid://bo3i5csexlcoe

View file

@ -0,0 +1,14 @@
[gd_resource type="StyleBoxFlat" format=3 uid="uid://daq1bri8pp6lp"]
[resource]
bg_color = Color(0.352941, 0.12549, 0.352941, 0.25098)
border_width_left = 4
border_width_top = 4
border_width_right = 4
border_width_bottom = 4
border_color = Color(0.631373, 0.270588, 0.631373, 1)
border_blend = true
corner_radius_top_left = 4
corner_radius_top_right = 4
corner_radius_bottom_right = 4
corner_radius_bottom_left = 4

View file

@ -0,0 +1,2 @@
ICONS
https://www.flaticon.com/free-icons

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1 @@
uid://bnbi70ajc0nbg

View file

@ -0,0 +1,196 @@
[gd_scene load_steps=10 format=3 uid="uid://hxjjupcjoat8"]
[ext_resource type="Script" uid="uid://bnbi70ajc0nbg" path="res://addons/_Godot-IDE_/plugins/gd_override_functions/popup/virtuals_popup.gd" id="1_afp4m"]
[ext_resource type="Texture2D" uid="uid://bgjo43cuidob1" path="res://addons/_Godot-IDE_/shared_resources/up.svg" id="2_v42ap"]
[ext_resource type="Texture2D" uid="uid://dg7rdmg80x4jv" path="res://addons/_Godot-IDE_/shared_resources/func_virtual.svg" id="3_t5ujg"]
[ext_resource type="Texture2D" uid="uid://bjmtfc58y1sbs" path="res://addons/_Godot-IDE_/shared_resources/InterfaceScript.svg" id="4_yees5"]
[ext_resource type="StyleBox" uid="uid://daq1bri8pp6lp" path="res://addons/_Godot-IDE_/plugins/gd_override_functions/popup/button/pressed.tres" id="5_obeej"]
[ext_resource type="Texture2D" uid="uid://ckc3yk6f8y3ob" path="res://addons/_Godot-IDE_/shared_resources/func_public.svg" id="6_kuyjr"]
[ext_resource type="Texture2D" uid="uid://do4gmovks0mn6" path="res://addons/_Godot-IDE_/shared_resources/func_private.svg" id="7_edrjb"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_iq5ej"]
bg_color = Color(0.352765, 0.124129, 0.353458, 1)
border_width_left = 4
border_width_top = 4
border_width_right = 4
border_color = Color(0.631373, 0.270588, 0.631373, 1)
corner_radius_top_left = 2
corner_radius_top_right = 2
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_knkse"]
bg_color = Color(0.196078, 0.392157, 0.588235, 1)
[node name="Virtuals" type="PopupPanel" node_paths=PackedStringArray("tree", "accept_button", "cancel_button", "check_generate_at_line", "interface_generate_button", "virtual_generate_button", "order_button", "public_button", "protected_button", "private_button", "interface_button")]
title = "GD Override Functions"
initial_position = 4
size = Vector2i(1024, 512)
visible = true
transient_to_focused = true
unresizable = false
borderless = false
script = ExtResource("1_afp4m")
tree = NodePath("Container/Tree")
accept_button = NodePath("Container/FooterContainer/OkButton")
cancel_button = NodePath("Container/FooterContainer/CancelButton")
check_generate_at_line = NodePath("Container/CheckConfig0")
interface_generate_button = NodePath("Container/HBoxContainer/interface_generate_btn")
virtual_generate_button = NodePath("Container/HBoxContainer/virtual_generate_btn")
order_button = NodePath("Container/HBoxContainer/order")
public_button = NodePath("Container/HBoxContainer/public_btn")
protected_button = NodePath("Container/HBoxContainer/protected_btn")
private_button = NodePath("Container/HBoxContainer/private_btn")
interface_button = NodePath("Container/HBoxContainer/interface_btn")
[node name="Container" type="VBoxContainer" parent="."]
offset_left = 4.0
offset_top = 4.0
offset_right = 1020.0
offset_bottom = 508.0
[node name="TittleContainer" type="PanelContainer" parent="Container"]
custom_minimum_size = Vector2(24, 24)
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_iq5ej")
[node name="Tittle" type="Label" parent="Container/TittleContainer"]
layout_mode = 2
size_flags_horizontal = 6
text = "Select Methods to Override/Implement"
horizontal_alignment = 1
vertical_alignment = 1
[node name="TextureRect" type="TextureRect" parent="Container/TittleContainer"]
custom_minimum_size = Vector2(16, 16)
layout_mode = 2
size_flags_horizontal = 8
expand_mode = 1
stretch_mode = 3
[node name="HBoxContainer" type="HBoxContainer" parent="Container"]
layout_mode = 2
[node name="order" type="Button" parent="Container/HBoxContainer"]
layout_mode = 2
tooltip_text = "Order by class inherited."
text = "Order"
icon = ExtResource("2_v42ap")
[node name="virtual_generate_btn" type="Button" parent="Container/HBoxContainer"]
layout_mode = 2
tooltip_text = "Implement all custom virtual methods.
(Only custom virtuals methods!)"
disabled = true
text = "Generate"
icon = ExtResource("3_t5ujg")
[node name="interface_generate_btn" type="Button" parent="Container/HBoxContainer"]
layout_mode = 2
tooltip_text = "Implement all interface methods."
disabled = true
text = "Generate"
icon = ExtResource("4_yees5")
[node name="Label" type="Label" parent="Container/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 10
text = "Filters Methods"
[node name="public_btn" type="Button" parent="Container/HBoxContainer"]
custom_minimum_size = Vector2(16, 16)
layout_mode = 2
tooltip_text = "Public methods.
Example:
func public_method()
func my_method()
func foo()"
theme_override_font_sizes/font_size = 16
theme_override_styles/pressed = ExtResource("5_obeej")
toggle_mode = true
icon = ExtResource("6_kuyjr")
icon_alignment = 1
[node name="protected_btn" type="Button" parent="Container/HBoxContainer"]
custom_minimum_size = Vector2(16, 16)
layout_mode = 2
tooltip_text = "Protected/Virtual Methods.
Example:
func _virtual_method()
func _my_virtual_method()
func _ready()"
theme_override_styles/pressed = ExtResource("5_obeej")
toggle_mode = true
button_pressed = true
icon = ExtResource("3_t5ujg")
icon_alignment = 1
[node name="private_btn" type="Button" parent="Container/HBoxContainer"]
custom_minimum_size = Vector2(16, 16)
layout_mode = 2
tooltip_text = "Private Methods.
Example:
func __private_method()
func __my_private_method
func __foo()"
theme_override_styles/pressed = ExtResource("5_obeej")
toggle_mode = true
icon = ExtResource("7_edrjb")
icon_alignment = 1
[node name="interface_btn" type="Button" parent="Container/HBoxContainer"]
custom_minimum_size = Vector2(16, 16)
layout_mode = 2
tooltip_text = "Interfaces.
This include all interface methods.
Interfaces are the \"custom classes\" begin with \"I\" character.
Example:
class_name IMyClass
class_name IDummy_Class
class_name Ifoo_class
Files without class_name but begin with \"I\" also work!
Example:
IMyInterface.gd
IDummy_Script.gd
Ifoo_script.gd"
theme_override_styles/pressed = ExtResource("5_obeej")
toggle_mode = true
button_pressed = true
icon = ExtResource("4_yees5")
icon_alignment = 1
[node name="Tree" type="Tree" parent="Container"]
custom_minimum_size = Vector2(128, 256)
layout_mode = 2
size_flags_vertical = 3
columns = 3
column_titles_visible = true
hide_root = true
select_mode = 2
[node name="CheckConfig0" type="CheckBox" parent="Container"]
layout_mode = 2
button_pressed = true
text = "Generate at end of line"
[node name="FooterContainer" type="HBoxContainer" parent="Container"]
layout_mode = 2
[node name="OkButton" type="Button" parent="Container/FooterContainer"]
custom_minimum_size = Vector2(64, 0)
layout_mode = 2
size_flags_horizontal = 3
theme_override_styles/normal = SubResource("StyleBoxFlat_knkse")
disabled = true
text = "Create"
[node name="CancelButton" type="Button" parent="Container/FooterContainer"]
custom_minimum_size = Vector2(64, 0)
layout_mode = 2
size_flags_horizontal = 3
text = "Cancel"

View file

@ -0,0 +1,52 @@
@tool
extends EditorContextMenuPlugin
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# script-ide: Virtual Popups
#
# Virtual Popups for script-ide addon.godot 4
# author: "Twister"
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
const SCENE : PackedScene = preload("res://addons/_Godot-IDE_/plugins/gd_override_functions/popup/virtuals_popup.tscn")
const ICON : Texture = preload("res://addons/_Godot-IDE_/shared_resources/func_virtual.svg")
func _notification(what: int) -> void:
if what == NOTIFICATION_PREDELETE:
var root : Node = Engine.get_main_loop().root
var virtual_popup : Popup = root.get_node_or_null("_VPOPUP_")
if is_instance_valid(virtual_popup) and !virtual_popup.is_queued_for_deletion():
virtual_popup.config_update(true)
virtual_popup.queue_free()
func callback(input : Object) -> void:
var input_script : Script = null
if input is Script:
input_script = input
elif input is CodeEdit:
var script_editor: ScriptEditor = EditorInterface.get_script_editor()
var scripts_editors : Array[ScriptEditorBase] = script_editor.get_open_script_editors()
var scripts : Array[Script] = script_editor.get_open_scripts()
var iscript : int = -1
for x : int in range(scripts_editors.size()):
if scripts_editors[x].get_base_editor() == input:
iscript = x
pass
if iscript > -1 and iscript < scripts.size():
input_script = scripts[iscript]
if null == input_script:
push_error("[PLUGIN] Error, can`t get current script - not valid!")
return
var root : Node = Engine.get_main_loop().root
var virtual_popup : Popup = root.get_node_or_null("_VPOPUP_")
if virtual_popup == null:
virtual_popup = SCENE.instantiate()
virtual_popup.set(&"name", &"_VPOPUP_")
root.add_child(virtual_popup)
virtual_popup.make_tree(input_script)
virtual_popup.popup_centered.call_deferred()
func _popup_menu(_paths : PackedStringArray) -> void:
add_context_menu_item("Override Virtual Functions", callback, ICON)

View file

@ -0,0 +1 @@
uid://bcfsicur2au8j

View file

@ -0,0 +1,65 @@
extends EditorContextMenuPlugin
# =============================================================================
# Author: Twister
# Godot-IDE Extension
#
# Macro-N
# =============================================================================
const INTERFACE_SCRIPT = preload("res://addons/_Godot-IDE_/shared_resources/InterfaceScript.svg")
var _helper : Object = null
var _fragments : Window = null
var controller : Object = null
func _init(helper : Object) -> void:
_helper = helper
#Override EditorContextMenuPlugin virtual function.
func _popup_menu(_paths : PackedStringArray) -> void:
if controller == null:
controller = ResourceLoader.load("res://addons/_Godot-IDE_/plugins/macro-n/src/gui/controller/ShowTextController.gd").new()
var txt : String = controller.execute()
if txt.is_empty():
return
add_context_menu_item("Macro-N", _on_save.bind(txt), INTERFACE_SCRIPT)
func _on_save(_variant : Variant, text : String) -> void:
_helper.call(&"half_life", text, -1)
func show_macros() -> void:
if !is_instance_valid(_fragments):
var fragment : PackedScene = ResourceLoader.load("res://addons/_Godot-IDE_/plugins/macro-n/src/gui/Fragments/Fragments.tscn")
_fragments = fragment.instantiate()
_helper.add_child(_fragments)
var db : Object = ResourceLoader.load("res://addons/_Godot-IDE_/plugins/macro-n/src/repo/configurator.gd").new()
_fragments.set_dependencies(
[
ResourceLoader.load("res://addons/_Godot-IDE_/plugins/macro-n/src/app/remove_fragment.gd").new(db),
ResourceLoader.load("res://addons/_Godot-IDE_/plugins/macro-n/src/app/get_all_fragments.gd").new(db),
ResourceLoader.load("res://addons/_Godot-IDE_/plugins/macro-n/src/app/save_fragment.gd").new(db)
]
)
_fragments.on_create.connect(_helper.create_new)
_fragments.popup_centered()
func invoke_macron_bypass() -> void:
if controller == null:
controller = ResourceLoader.load("res://addons/_Godot-IDE_/plugins/macro-n/src/gui/controller/ShowTextController.gd").new()
var txt : String = controller.execute()
txt = txt.strip_edges()
if txt.is_empty():
return
_helper.call(&"half_life", txt, 1)
func invoke_macron() -> void:
if controller == null:
controller = ResourceLoader.load("res://addons/_Godot-IDE_/plugins/macro-n/src/gui/controller/ShowTextController.gd").new()
var txt : String = controller.execute()
txt = txt.strip_edges()
if txt.is_empty():
return
_helper.call(&"half_life", txt, 0)

View file

@ -0,0 +1 @@
uid://cstqqmdlwkth

View file

@ -0,0 +1,112 @@
extends RefCounted
# =============================================================================
# Author: Twister
# Godot-IDE Extension
#
# Macro-N
# =============================================================================
var user_path : String = ""
var templates_path : String = ""
var _pop_warn : ConfirmationDialog
var _helper : Node = null
func _init(helper : Node) -> void:
assert(helper != null)
_helper = helper
func _get_pop() -> Object:
var packed : PackedScene = ResourceLoader.load("res://addons/_Godot-IDE_/plugins/macro-n/context/Macro-N.tscn")
return packed.instantiate()
func feed() -> void:
var edit : ScriptEditor = EditorInterface.get_script_editor()
if edit:
var base : ScriptEditorBase = edit.get_current_editor()
if base:
var be : Control = base.get_base_editor()
if be is CodeEdit:
pipe_pop_in(be.text)
#NO SYTNAX
return
func pipe_pop_in(txt : String) -> void:
txt = parse_text(txt)
if txt.is_empty():
print("[Macro-N] Error!, empty syntax!")
return
var pop : Node = _get_pop()
if !pop.is_inside_tree():
_helper.add_child(pop)
pop.callback = pipe_save
pop.call(&"show_feed", txt)
func pipe_save(path : String, txt : String) -> void:
if !DirAccess.dir_exists_absolute(path):
print("[Macro-N]: Can not find dir save path!")
return
path = path.strip_edges()
if path.is_empty():
path = "My Macro File"
txt = parse_text(txt)
var end : String = user_path.path_join(path + ".mn")
if !FileAccess.file_exists(end):
if !_save(end, txt):
print("[Macro-N] Can not save syntax! ", end)
else:
print("[Macron-N] Saved syntax: ", end)
return
_save_warn(end, txt)
func _save(end : String, txt : String) -> bool:
var file : FileAccess = FileAccess.open(end, FileAccess.WRITE)
if !file:
return false
return file.store_string(txt)
func _save_warn(end : String, txt : String) -> void:
if !is_instance_valid(_pop_warn):
_pop_warn = ConfirmationDialog.new()
_pop_warn.title = "Already Exist File, Ovewrite?"
_pop_warn.canceled.connect(func():_pop_warn.queue_free())
_pop_warn.confirmed.connect(
func():
_save(end, txt)
_pop_warn.queue_free()
)
_helper.add_child(_pop_warn)
_pop_warn.popup_centered()
func parse_text(txt : String) -> String:
var split : PackedStringArray = txt.split("\n", true, 0)
var maxt : Array[int] = [0, 0]
while split.size() > 0 and split[0].strip_edges().length() == 0:
split.remove_at(0)
if split.size() == 0:
return ""
for xline : int in range(split.size()):
var line : String = split[xline]
var indx : int = 0
var cline : int = mini(xline, 1)
while line.length() > indx and (line[indx] == '\t' or line[indx] == ' '):
indx += 1
maxt[cline] = maxi(maxt[cline], indx)
if maxt[0] < maxt[1]:
var st : int = maxt[0]
for xline : int in range(split.size()):
split[xline] = split[xline].substr(st, -1)
return "\n".join(split)

View file

@ -0,0 +1 @@
uid://burhkdjv1q8bu

View file

@ -0,0 +1,7 @@
[plugin]
name="Macro-N"
description="Allow generate code by shortcut"
author="Twister"
version="Alpha-1.0"
script="plugin.gd"

View file

@ -0,0 +1,77 @@
@tool
extends EditorPlugin
# =============================================================================
# Author: Twister
# Godot-IDE Extension
#
# Macro-N
# =============================================================================
const CONTEXT := preload("res://addons/_Godot-IDE_/plugins/macro-n/context.gd")
var ctx_macron_n : EditorContextMenuPlugin = null
var macron_n : RefCounted = null
var _c_input : InputEvent = null
var _g_input : InputEvent = null
var _cb_input : InputEvent = null
func _enter_tree() -> void:
ctx_macron_n = CONTEXT.new(self)
add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR_CODE, ctx_macron_n)
func _exit_tree() -> void:
macron_n = null
remove_context_menu_plugin(ctx_macron_n)
func half_life(txt : String, type : int) -> void:
if !is_instance_valid(macron_n):
macron_n = ResourceLoader.load("res://addons/_Godot-IDE_/plugins/macro-n/src/main.gd").new(self)
macron_n.execute(txt, type)
func create_new() -> void:
if !is_instance_valid(macron_n):
macron_n = ResourceLoader.load("res://addons/_Godot-IDE_/plugins/macro-n/src/main.gd").new(self)
macron_n.execute("# CODE HERE", 2)
func _init() -> void:
var input : Variant = IDE.get_config("macro_n", "invoke_input")
if input is InputEvent:
_c_input = input
else:
_c_input = InputEventKey.new()
_c_input.pressed = true
_c_input.ctrl_pressed = true
_c_input.keycode = KEY_E
IDE.set_config("macro_n", "invoke_macro", _c_input)
input = IDE.get_config("macro_n", "invoke_macro_by_pass")
if input is InputEvent:
_cb_input = input
else:
_cb_input = InputEventKey.new()
_cb_input.pressed = true
_cb_input.ctrl_pressed = true
_cb_input.shift_pressed = true
_cb_input.keycode = KEY_E
IDE.set_config("macro_n", "invoke_macro_by_pass", input)
input = IDE.get_config("macro_n", "show_all_macro")
if input is InputEvent:
_g_input = input
else:
_g_input = InputEventKey.new()
_g_input.pressed = true
_g_input.alt_pressed = true
_g_input.keycode = KEY_END
IDE.set_config("macro_n", "show_all_macro", _g_input)
func _input(event: InputEvent) -> void:
if event.is_pressed():
if event.is_match(_c_input):
ctx_macron_n.invoke_macron()
elif event.is_match(_cb_input):
ctx_macron_n.invoke_macron_bypass()
elif event.is_match(_g_input):
ctx_macron_n.show_macros()

View file

@ -0,0 +1 @@
uid://dx71kxr16b0k5

View file

@ -0,0 +1,23 @@
@tool
extends "res://addons/_Godot-IDE_/plugins/macro-n/src/app/in/IGetAllFragments.gd"
# =============================================================================
# Author: Twister
# Godot-IDE Extension
#
# Macro-N
# =============================================================================
const IFragmentDB := preload("res://addons/_Godot-IDE_/plugins/macro-n/src/app/out/IFragmentDB.gd")
var _fragment_db : IFragmentDB = null
func _init(fragment_db : IFragmentDB) -> void:
_fragment_db = fragment_db
#Implement IGetAllFragments function.
func execute() -> Array[Dictionary]:
return _fragment_db.get_all_fragments()
#Implement IGetAllFragments function.
func get_keys() -> PackedStringArray:
return _fragment_db.get_data_keys()

View file

@ -0,0 +1 @@
uid://ccqfm0nk400vq

View file

@ -0,0 +1,21 @@
@tool
extends "res://addons/_Godot-IDE_/plugins/macro-n/src/app/in/IGetFragment.gd"
# =============================================================================
# Author: Twister
# Godot-IDE Extension
#
# Macro-N
# =============================================================================
const IFragmentDB := preload("res://addons/_Godot-IDE_/plugins/macro-n/src/app/out/IFragmentDB.gd")
var _fragment_db : IFragmentDB = null
func _init(fragment_db : IFragmentDB) -> void:
_fragment_db = fragment_db
#Implement IGetFragment function.
func execute(shortcut : String) -> Dictionary:
return _fragment_db.get_fragment(shortcut)

View file

@ -0,0 +1 @@
uid://cpk8peml78tct

View file

@ -0,0 +1,17 @@
@tool
extends RefCounted
# =============================================================================
# Author: Twister
# Godot-IDE Extension
#
# Macro-N
# =============================================================================
func get_keys() -> PackedStringArray:
push_error("Not supported!")
return []
func execute() -> Array[Dictionary]:
push_error("Not supported!")
return []

View file

@ -0,0 +1 @@
uid://b00jdghts8a6b

View file

@ -0,0 +1,13 @@
@tool
extends RefCounted
# =============================================================================
# Author: Twister
# Godot-IDE Extension
#
# Macro-N
# =============================================================================
func execute(shortcut : String) -> Dictionary:
push_error("Not supported!")
return {}

View file

@ -0,0 +1 @@
uid://br4bwcq3fxweb

View file

@ -0,0 +1,13 @@
@tool
extends RefCounted
# =============================================================================
# Author: Twister
# Godot-IDE Extension
#
# Macro-N
# =============================================================================
func execute(txt : String) -> String:
push_error("Not supported!")
return ""

View file

@ -0,0 +1 @@
uid://d4dlryhpw7hev

View file

@ -0,0 +1,13 @@
@tool
extends RefCounted
# =============================================================================
# Author: Twister
# Godot-IDE Extension
#
# Macro-N
# =============================================================================
func execute(txt : String) -> int:
push_error("Not supported!")
return -1

View file

@ -0,0 +1 @@
uid://rtemrp027x42

View file

@ -0,0 +1,13 @@
@tool
extends RefCounted
# =============================================================================
# Author: Twister
# Godot-IDE Extension
#
# Macro-N
# =============================================================================
func execute(shortcut : String, description : String, content : String) -> int:
push_error("Not supported!")
return -1

View file

@ -0,0 +1 @@
uid://dwci52n45a278

View file

@ -0,0 +1,54 @@
@tool
extends "res://addons/_Godot-IDE_/plugins/macro-n/src/app/in/IMacro.gd"
# =============================================================================
# Author: Twister
# Godot-IDE Extension
#
# Macro-N
# =============================================================================
const IFragmentDB = preload("res://addons/_Godot-IDE_/plugins/macro-n/src/app/out/IFragmentDB.gd")
var _db : IFragmentDB
func _init(db : IFragmentDB) -> void:
_db = db
#Implement IMacro function.
func execute(txt : String) -> String:
var values : Array[Dictionary] = _db.get_all_fragments()
if values.size() == 0:
return ""
var rgx : RegEx = RegEx.create_from_string("\\barg(\\d+)\\b")
for v : Dictionary in values:
var val : String = v["shortcut"]
var _rgx : RegEx = null
_rgx = RegEx.create_from_string(str("(?m)^",rgx.sub(val, "(.*?)", true, 0, -1),"$"))
if !is_instance_valid(_rgx) or !_rgx.is_valid():
continue
if null != _rgx.search(txt):
var input : Array = []
var out : Dictionary = {}
for x : RegExMatch in rgx.search_all(val, 0, -1):
if x.strings.size() > 1:
out[x.strings[0]] = x.strings[0]
input.append(x.strings[0])
var indx : int = 0
for x : RegExMatch in _rgx.search_all(txt, 0, -1):
for y : int in range(1, x.strings.size(), 1):
var ctnt : String = x.strings[y]
while indx >= input.size():
input.append(ctnt)
out[input[indx]] = ctnt
indx += 1
var nrgx : RegEx = RegEx.create_from_string("\\barg(\\d+)\\b")
var defnrgx : RegEx = RegEx.create_from_string("\\{(\\barg\\d+\\b)\\}")
var content : String = nrgx.sub(v["content"], "{$0}", true)
return defnrgx.sub(content.format(out), "$1", true)
return ""

View file

@ -0,0 +1 @@
uid://b7jauusersf4r

View file

@ -0,0 +1,66 @@
@tool
extends "res://addons/_Godot-IDE_/plugins/macro-n/src/app/in/IMacro.gd"
# =============================================================================
# Author: Twister
# Godot-IDE Extension
#
# Macro-N
# =============================================================================
const LIMIT : int = 100
const IFragmentDB = preload("res://addons/_Godot-IDE_/plugins/macro-n/src/app/out/IFragmentDB.gd")
var _db : IFragmentDB
func _init(db : IFragmentDB) -> void:
_db = db
#Implement IMacro function.
func execute(txt : String) -> String:
var values : Array[Dictionary] = _db.get_all_fragments()
if values.size() == 0:
return ""
var rgx : RegEx = RegEx.create_from_string("\\barg(\\d+)\\b")
for v : Dictionary in values:
var val : String = v["shortcut"]
var _rgx : RegEx = null
_rgx = RegEx.create_from_string(str("\\s*",rgx.sub(val, "(.*?)", true, 0, -1),"\\s*"))
if !is_instance_valid(_rgx) or !_rgx.is_valid():
continue
if null != _rgx.search(txt):
var input : Array = []
var out : Dictionary = {}
for x : RegExMatch in rgx.search_all(val, 0, -1):
if x.strings.size() > 1:
out[x.strings[0]] = x.strings[0]
input.append(x.strings[0])
var indx : int = 0
for x : RegExMatch in _rgx.search_all(txt, 0, -1):
for y : int in range(1, x.strings.size(), 1):
var ctnt : String = x.strings[y]
while indx >= input.size():
input.append(ctnt)
out[input[indx]] = ctnt
indx += 1
var nrgx : RegEx = RegEx.create_from_string("\\barg(\\d+)\\b")
var defnrgx : RegEx = RegEx.create_from_string("\\{(\\barg\\d+\\b)\\}")
var content : String = nrgx.sub(v["content"], "{$0}", true)
var result : String = _rgx.sub(txt, defnrgx.sub(content.format(out), "$1", true), true)
var new_result : String = execute(result)
var _out : int = LIMIT
while !new_result.is_empty() and result != new_result and _out > 0:
result = new_result
new_result = execute(new_result)
_out -= 1
if _out == 0:
printerr("Macro overflow error!")
return result
return ""

View file

@ -0,0 +1 @@
uid://curvq1o31f5cx

View file

@ -0,0 +1,28 @@
@tool
extends RefCounted
# =============================================================================
# Author: Twister
# Godot-IDE Extension
#
# Macro-N
# =============================================================================
func save_fragment(shortcut : String, description : String, full_text : String) -> int:
push_error("Not supported!")
return -1
func get_fragment(shortcut : String) -> Dictionary:
push_error("Not supported!")
return {}
func get_all_fragments() -> Array[Dictionary]:
push_error("Not supported!")
return []
func get_data_keys() -> PackedStringArray:
push_error("Not supported!")
return []
func remove(shortcut : String) -> int:
push_error("Not supported!")
return -1

View file

@ -0,0 +1 @@
uid://bqt2ahh581vvv

View file

@ -0,0 +1,19 @@
@tool
extends "res://addons/_Godot-IDE_/plugins/macro-n/src/app/in/IRemoveFragment.gd"
# =============================================================================
# Author: Twister
# Godot-IDE Extension
#
# Macro-N
# =============================================================================
const IFragmentDB := preload("res://addons/_Godot-IDE_/plugins/macro-n/src/app/out/IFragmentDB.gd")
var _fragment_db : IFragmentDB = null
func _init(fragment_db : IFragmentDB) -> void:
_fragment_db = fragment_db
#Implement IRemoveFragment function.
func execute(txt : String) -> int:
return _fragment_db.remove(txt)

View file

@ -0,0 +1 @@
uid://cts7bspkw8xjg

View file

@ -0,0 +1,27 @@
@tool
extends "res://addons/_Godot-IDE_/plugins/macro-n/src/app/in/ISerializerFragments.gd"
# =============================================================================
# Author: Twister
# Godot-IDE Extension
#
# Macro-N
# =============================================================================
const IFragmentDB := preload("res://addons/_Godot-IDE_/plugins/macro-n/src/app/out/IFragmentDB.gd")
var _fragment_db : IFragmentDB = null
func _init(fragment_db : IFragmentDB) -> void:
_fragment_db = fragment_db
#Implement ISerializerFragments function.
func execute(shortcut : String, description : String, content : String) -> int:
description = description.strip_edges()
shortcut = shortcut.strip_edges()
var result : int = _fragment_db.save_fragment(shortcut, description, content)
if OK != result:
push_error("On error on try save macro fragment!")
return result

View file

@ -0,0 +1 @@
uid://duou0e0hh4e7t

View file

@ -0,0 +1,13 @@
@tool
extends RefCounted
# =============================================================================
# Author: Twister
# Godot-IDE Extension
#
# Macro-N
# =============================================================================
var shortcut : String
var tittle : String
var description : String
var text : String

View file

@ -0,0 +1 @@
uid://dwmbc85wlymty

View file

@ -0,0 +1,81 @@
[gd_scene load_steps=5 format=3 uid="uid://ckn2qdpg5fs5y"]
[ext_resource type="Script" uid="uid://bio4l72bwqcsi" path="res://addons/_Godot-IDE_/plugins/macro-n/src/gui/Fragments/fragments.gd" id="1_4jc8e"]
[ext_resource type="Script" uid="uid://b4ypyfc1c0ybj" path="res://addons/_Godot-IDE_/plugins/macro-n/src/gui/util/Button.gd" id="2_k3ugs"]
[ext_resource type="Texture2D" uid="uid://ckc3yk6f8y3ob" path="res://addons/_Godot-IDE_/shared_resources/func_public.svg" id="2_r7fa2"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_r7fa2"]
content_margin_left = 5.0
content_margin_top = 5.0
content_margin_right = 5.0
content_margin_bottom = 5.0
bg_color = Color(0.1155, 0.132, 0.1595, 1)
corner_detail = 1
anti_aliasing = false
[node name="Fragments" type="Window" node_paths=PackedStringArray("container")]
title = "Show All Macros"
initial_position = 4
size = Vector2i(1536, 864)
wrap_controls = true
transient = true
transient_to_focused = true
exclusive = true
script = ExtResource("1_4jc8e")
container = NodePath("PanelContainer/MarginContainer/VBoxContainer/ScrollContainer/GridContainer")
[node name="PanelContainer" type="PanelContainer" parent="."]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_r7fa2")
[node name="MarginContainer" type="MarginContainer" parent="PanelContainer"]
layout_mode = 2
theme_override_constants/margin_left = 8
theme_override_constants/margin_top = 8
theme_override_constants/margin_right = 8
theme_override_constants/margin_bottom = 8
[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/MarginContainer"]
layout_mode = 2
[node name="Label" type="Label" parent="PanelContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
text = "All Shortucts"
horizontal_alignment = 1
uppercase = true
[node name="HSeparator2" type="HSeparator" parent="PanelContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
[node name="ScrollContainer" type="ScrollContainer" parent="PanelContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
[node name="GridContainer" type="GridContainer" parent="PanelContainer/MarginContainer/VBoxContainer/ScrollContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
columns = 7
[node name="HSeparator" type="HSeparator" parent="PanelContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
[node name="HBoxContainer" type="HBoxContainer" parent="PanelContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
theme_override_constants/separation = 16
[node name="create" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer/HBoxContainer"]
layout_mode = 2
text = "Create New"
icon = ExtResource("2_r7fa2")
script = ExtResource("2_k3ugs")
[node name="close" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
text = "Close"
script = ExtResource("2_k3ugs")

View file

@ -0,0 +1,83 @@
[gd_scene load_steps=5 format=3 uid="uid://dt1pjig5ml6we"]
[ext_resource type="Script" uid="uid://ctoxe1fxxiuc1" path="res://addons/_Godot-IDE_/plugins/macro-n/src/gui/Fragments/component/edit.gd" id="1_0vdlq"]
[ext_resource type="Script" uid="uid://b4ypyfc1c0ybj" path="res://addons/_Godot-IDE_/plugins/macro-n/src/gui/util/Button.gd" id="2_h73ec"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_leugs"]
content_margin_left = 5.0
content_margin_top = 5.0
content_margin_right = 5.0
content_margin_bottom = 5.0
bg_color = Color(0.1155, 0.132, 0.1595, 1)
corner_detail = 1
anti_aliasing = false
[sub_resource type="GDScriptSyntaxHighlighter" id="GDScriptSyntaxHighlighter_h73ec"]
[node name="Edit" type="Window" node_paths=PackedStringArray("update_btn", "base_edit", "container")]
position = Vector2i(0, 36)
size = Vector2i(500, 500)
transient = true
transient_to_focused = true
exclusive = true
script = ExtResource("1_0vdlq")
update_btn = NodePath("MarginContainer/MarginContainer/VBoxContainer/HBoxContainer/update")
base_edit = NodePath("MarginContainer/MarginContainer/CodeEdit")
container = NodePath("MarginContainer/MarginContainer/VBoxContainer/ScrollContainer")
[node name="MarginContainer" type="PanelContainer" parent="."]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_leugs")
[node name="MarginContainer" type="MarginContainer" parent="MarginContainer"]
layout_mode = 2
theme_override_constants/margin_left = 4
theme_override_constants/margin_top = 4
theme_override_constants/margin_right = 4
theme_override_constants/margin_bottom = 4
[node name="CodeEdit" type="CodeEdit" parent="MarginContainer/MarginContainer"]
visible = false
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
syntax_highlighter = SubResource("GDScriptSyntaxHighlighter_h73ec")
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/MarginContainer"]
layout_mode = 2
[node name="Label" type="Label" parent="MarginContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
text = "Edit Content"
horizontal_alignment = 1
[node name="HSeparator" type="HSeparator" parent="MarginContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
[node name="ScrollContainer" type="ScrollContainer" parent="MarginContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
[node name="HSeparator2" type="HSeparator" parent="MarginContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 8
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
theme_override_constants/separation = 12
[node name="close" type="Button" parent="MarginContainer/MarginContainer/VBoxContainer/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
text = "Close"
script = ExtResource("2_h73ec")
[node name="update" type="Button" parent="MarginContainer/MarginContainer/VBoxContainer/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
text = "Update"
script = ExtResource("2_h73ec")

View file

@ -0,0 +1,100 @@
@tool
extends Window
# =============================================================================
# Author: Twister
# Godot-IDE Extension
#
# Macro-N
# =============================================================================
@export var update_btn : Button
@export var base_edit : CodeEdit
@export var code_edit : CodeEdit
@export var container : Control
var _origin : Object = null
var _code : String = ""
func _get_edit() -> CodeEdit:
var editor : ScriptEditor = EditorInterface.get_script_editor()
if editor:
var _editor : Control = editor.get_current_editor().get_base_editor()
if _editor is CodeEdit:
return _editor.duplicate(0)
return CodeEdit.new()
func _on_change_txt() -> void:
base_edit.text = code_edit.text
func _ready() -> void:
close_requested.connect(close)
var res : CodeHighlighter = ResourceLoader.load("uid://cyenwroye7tue").new()
res.set_base(base_edit.syntax_highlighter)
res.set_rgx(RegEx.create_from_string("\\barg\\d+\\b"))
if code_edit == null:
code_edit = _get_edit()
container.add_child(code_edit)
code_edit.size_flags_horizontal = Control.SIZE_EXPAND_FILL
code_edit.size_flags_vertical = Control.SIZE_EXPAND_FILL
code_edit.syntax_highlighter = res
code_edit.text_changed.connect(_on_change_txt)
var control : Control = EditorInterface.get_base_control()
if !control:
return
get_child(0). add_theme_stylebox_override(&"panel", control.get_theme_stylebox(&"panel", &""))
func set_origin(o : Object) -> void:
_origin = o
func close() -> void:
queue_free()
func update() -> void:
var pop : ConfirmationDialog = ConfirmationDialog.new()
pop.title = "Macro-N"
pop.size.x = 350
pop.dialog_text = "Are you sure update?"
for x : Node in pop.get_children(true):
if x is Label:
x.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
pop.confirmed.connect(_on_confirm)
EditorInterface.popup_dialog_centered(pop)
func _on_confirm() -> void:
_origin.set_meta(&"content", code_edit.text)
var pop : AcceptDialog = AcceptDialog.new()
pop.title = "Macro-N"
pop.size.x = 350
pop.dialog_text = "Macro content update!\nRemember press 'UPDATE' button for save!"
for x : Node in pop.get_children(true):
if x is Label:
x.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
pop.close_requested.connect(close)
pop.confirmed.connect(close)
EditorInterface.popup_dialog_centered(pop)
func _on_change() -> void:
update_btn.disabled = _code == code_edit.text
func set_code(code : String) -> void:
_code = code
base_edit.text = _code
code_edit.text = _code
code_edit.text_changed.connect(_on_change)
update_btn.disabled = true

Some files were not shown because too many files have changed in this diff Show more