first commit
This commit is contained in:
458
addons/script_spliter/plugin.gd
Normal file
458
addons/script_spliter/plugin.gd
Normal file
@@ -0,0 +1,458 @@
|
||||
@tool
|
||||
extends EditorPlugin
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Script Spliter
|
||||
# https://github.com/CodeNameTwister/Script-Spliter
|
||||
#
|
||||
# Script Spliter addon for godot 4
|
||||
# author: "Twister"
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
|
||||
const BUILDER : Script = preload("res://addons/script_spliter/core/builder.gd")
|
||||
const CONTEXT : Script = preload("res://addons/script_spliter/context/context_window.gd")
|
||||
|
||||
const CMD_MENU_TOOL : String = "Script Spliter"
|
||||
|
||||
#CONTEXT
|
||||
const ICON_ADD_COLUMN : Texture = preload("res://addons/script_spliter/context/icons/split_cplus.svg")
|
||||
const ICON_REMOVE_COLUMN : Texture = preload("res://addons/script_spliter/context/icons/split_cminus.svg")
|
||||
const ICON_ADD_ROW : Texture = preload("res://addons/script_spliter/context/icons/split_rplus.svg")
|
||||
const ICON_REMOVE_ROW : Texture = preload("res://addons/script_spliter/context/icons/split_rminus.svg")
|
||||
const ICON_FLOATING : Texture = preload("res://addons/script_spliter/context/icons/atop.png")
|
||||
const ICON_TAB : Texture = preload("res://addons/script_spliter/assets/tab_icon.svg")
|
||||
|
||||
var _rmb_editor_add_split : EditorContextMenuPlugin = null
|
||||
var _rmb_editor_remove_split: EditorContextMenuPlugin = null
|
||||
var _rmb_editor_code_add_split : EditorContextMenuPlugin = null
|
||||
var _rmb_editor_code_remove_split : EditorContextMenuPlugin = null
|
||||
var _rmb_editor_pop_script : EditorContextMenuPlugin = null
|
||||
var _rmb_editor_code_pop_script : EditorContextMenuPlugin = null
|
||||
|
||||
var _rmb_close_all_tab_in_split : EditorContextMenuPlugin = null
|
||||
var _rmb_close_all_tab_in_split_right : EditorContextMenuPlugin = null
|
||||
var _rmb_close_all_tab_in_split_left : EditorContextMenuPlugin = null
|
||||
|
||||
var _menu_split_selector : Window = null
|
||||
var _builder : Object = null
|
||||
|
||||
var _daemon_chaser : Node = null
|
||||
|
||||
#region _REF_
|
||||
var _tab_container : Node = null:
|
||||
get:
|
||||
if !is_instance_valid(_tab_container):
|
||||
var script_editor: ScriptEditor = EditorInterface.get_script_editor()
|
||||
_tab_container = find(script_editor, "*", "TabContainer")
|
||||
return _tab_container
|
||||
|
||||
var _item_list : Node = null:
|
||||
get:
|
||||
if !is_instance_valid(_item_list):
|
||||
var script_editor: ScriptEditor = EditorInterface.get_script_editor()
|
||||
_item_list = find(script_editor, "*", "ItemList")
|
||||
return _item_list
|
||||
#endregion
|
||||
|
||||
#region _USER_BUFFER_
|
||||
var _rows : int = 0:
|
||||
set(e):
|
||||
_rows = maxi(e, 0)
|
||||
var _columns : int = 0:
|
||||
set(e):
|
||||
_columns = maxi(e, 0)
|
||||
var _refresh_warnings_on_save : bool = true
|
||||
#endregion
|
||||
|
||||
var _frm : int = 0
|
||||
var _d_chase : bool = false
|
||||
|
||||
func get_builder() -> Object:
|
||||
return _builder
|
||||
|
||||
func find(root : Node, pattern : String, type : String) -> Node:
|
||||
var e : Array[Node] = root.find_children(pattern, type, true, false)
|
||||
if e.size() > 0:
|
||||
return e[0]
|
||||
return null
|
||||
|
||||
func get_split_rows() -> int:
|
||||
return _rows
|
||||
|
||||
func get_split_columns() -> int:
|
||||
return _columns
|
||||
|
||||
func _on_save(res : Resource) -> void:
|
||||
if res is Script:
|
||||
_save_external_data()
|
||||
|
||||
func _save_external_data() -> void:
|
||||
if _d_chase == true:
|
||||
return
|
||||
_d_chase = true
|
||||
if _refresh_warnings_on_save and is_instance_valid(_builder):
|
||||
if _daemon_chaser == null:
|
||||
_daemon_chaser = ResourceLoader.load("res://addons/script_spliter/core/DaemonChaser.gd").new()
|
||||
add_child(_daemon_chaser)
|
||||
_daemon_chaser.set_current_index(_builder.get_current_focus_index())
|
||||
_daemon_chaser.buffer = _builder.get_focus_config()
|
||||
_builder.enable_focus_highlight(false)
|
||||
_daemon_chaser.run(_builder.focus_by_index, _builder.set_focus_config)
|
||||
set_deferred(&"_d_chase", false)
|
||||
|
||||
func _process(__: float) -> void:
|
||||
if _frm < 2:
|
||||
_frm += 1
|
||||
return
|
||||
_frm = 0
|
||||
set_process(false)
|
||||
if is_instance_valid(_builder):
|
||||
_builder.update()
|
||||
|
||||
func _on_change_settings() -> void:
|
||||
if is_instance_valid(_builder):
|
||||
_builder.update_config()
|
||||
var settings : EditorSettings = EditorInterface.get_editor_settings()
|
||||
var changes : PackedStringArray = settings.get_changed_settings()
|
||||
|
||||
if &"plugin/script_spliter/behaviour/refresh_warnings_on_save" in changes:
|
||||
_refresh_warnings_on_save = settings.get_setting(&"plugin/script_spliter/behaviour/refresh_warnings_on_save")
|
||||
|
||||
func _init() -> void:
|
||||
var o : Object = _tab_container
|
||||
if o == null:
|
||||
#push_warning("[Script-Spliter] 0x000A")
|
||||
return
|
||||
o = _item_list
|
||||
if o == null:
|
||||
#push_warning("[Script-Spliter] 0x000B")
|
||||
return
|
||||
|
||||
func _run() -> void:
|
||||
if is_instance_valid(_builder):
|
||||
var settings : EditorSettings = EditorInterface.get_editor_settings()
|
||||
var scripts_tab_container : Node = _tab_container
|
||||
|
||||
if !scripts_tab_container:
|
||||
push_warning("[Script-Spliter] 0x000A Error can not find editor reference!")
|
||||
return
|
||||
|
||||
var il : Node = _item_list
|
||||
if null != il:
|
||||
_builder.set_item_list(il)
|
||||
else:
|
||||
push_warning("[Script-Spliter] 0x000B Error can not find editor reference!")
|
||||
return
|
||||
|
||||
if !scripts_tab_container.is_node_ready():
|
||||
await scripts_tab_container.ready
|
||||
if !is_instance_valid(scripts_tab_container):
|
||||
push_error("Unspected error reference be replace or free it, can not run plugin!")
|
||||
return
|
||||
|
||||
settings.settings_changed.connect(_on_change_settings)
|
||||
|
||||
_builder.init_1()
|
||||
_builder.build(scripts_tab_container, _columns, _rows)
|
||||
set_process_input(true)
|
||||
|
||||
func set_type_split(columns : int, rows : int) -> void:
|
||||
_columns = columns
|
||||
_rows = rows
|
||||
|
||||
var str_columns : String = str(maxi(_columns, 1))
|
||||
var str_rows : String = str(maxi(rows, 1))
|
||||
|
||||
print("[{0}] {1} {2}: > {3} {5} - {4} {6}".format(
|
||||
[
|
||||
_get_translated_text("INFO"),
|
||||
_get_translated_text("Setting"),
|
||||
_get_translated_text("To"),
|
||||
_get_translated_text("Columns"),
|
||||
_get_translated_text("Rows"),
|
||||
str_columns,
|
||||
str_rows
|
||||
]) )
|
||||
|
||||
if is_instance_valid(_builder):
|
||||
_builder.update_build(columns, rows)
|
||||
|
||||
func _exit_tree() -> void:
|
||||
remove_tool_menu_item(CMD_MENU_TOOL)
|
||||
_setup(0)
|
||||
|
||||
if is_instance_valid(_builder):
|
||||
_builder.init_0()
|
||||
_builder.free.call_deferred()
|
||||
|
||||
var settings : EditorSettings = EditorInterface.get_editor_settings()
|
||||
if settings.settings_changed.is_connected(_on_change_settings):
|
||||
settings.settings_changed.disconnect(_on_change_settings)
|
||||
|
||||
if is_instance_valid(_daemon_chaser) and !_daemon_chaser.is_queued_for_deletion():
|
||||
_daemon_chaser.queue_free()
|
||||
|
||||
func _get_translated_text(text : String) -> String:
|
||||
# TODO: Translation
|
||||
return text
|
||||
|
||||
func swap(caller : Object) -> void:
|
||||
if is_instance_valid(_builder):
|
||||
_builder.swap(caller)
|
||||
|
||||
func _setup(input : int) -> void:
|
||||
var settings : EditorSettings = EditorInterface.get_editor_settings()
|
||||
|
||||
if input != 0:
|
||||
add_to_group(&"ScriptSpliter")
|
||||
|
||||
main_screen_changed.connect(_on_change)
|
||||
resource_saved.connect(_on_save)
|
||||
|
||||
var ctx_add_column : String = _get_translated_text("ADD_SPLIT").capitalize()
|
||||
var ctx_remove_split : String = _get_translated_text("REMOVE_SPLIT").capitalize()
|
||||
var ctx_pop_script : String = _get_translated_text("MAKE_FLOATING_SCRIPT").capitalize()
|
||||
var ctx_close_tabs : String = _get_translated_text("CLOSE_OTHERS_TABS_IN_SPLIT").capitalize()
|
||||
var ctx_close_tabs_right : String = _get_translated_text("CLOSE_RIGHT_TABS_IN_SPLIT").capitalize()
|
||||
var ctx_close_tabs_left : String = _get_translated_text("CLOSE_LEFT_TABS_IN_SPLIT").capitalize()
|
||||
|
||||
#SETUP
|
||||
_rmb_editor_add_split = CONTEXT.new(ctx_add_column, _add_window_split, _can_add_split, ICON_ADD_COLUMN)
|
||||
_rmb_editor_remove_split = CONTEXT.new(ctx_remove_split, _remove_window_split, _can_remove_split, ICON_REMOVE_COLUMN)
|
||||
|
||||
_rmb_editor_code_add_split = CONTEXT.new(ctx_add_column, _add_window_split, _can_add_split, ICON_ADD_COLUMN)
|
||||
_rmb_editor_code_remove_split = CONTEXT.new(ctx_remove_split, _remove_window_split, _can_remove_split, ICON_REMOVE_COLUMN)
|
||||
|
||||
_rmb_editor_pop_script = CONTEXT.new(ctx_pop_script, _make_pop_script, _can_make_pop_script, ICON_FLOATING)
|
||||
_rmb_editor_code_pop_script = CONTEXT.new(ctx_pop_script, _make_pop_script, _can_make_pop_script, ICON_FLOATING)
|
||||
|
||||
_rmb_close_all_tab_in_split = CONTEXT.new(ctx_close_tabs, _close_all_tabs_in_split, _can_close_tab_in_split, ICON_TAB)
|
||||
_rmb_close_all_tab_in_split_left = CONTEXT.new(ctx_close_tabs_left, _close_all_tabs_in_split_left, _can_close_left_tab_in_split, ICON_TAB)
|
||||
_rmb_close_all_tab_in_split_right = CONTEXT.new(ctx_close_tabs_right, _close_all_tabs_in_split_right, _can_close_right_tab_in_split, ICON_TAB)
|
||||
|
||||
add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR, _rmb_close_all_tab_in_split)
|
||||
add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR, _rmb_close_all_tab_in_split_left)
|
||||
add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR, _rmb_close_all_tab_in_split_right)
|
||||
|
||||
|
||||
add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR, _rmb_editor_add_split)
|
||||
add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR, _rmb_editor_remove_split)
|
||||
|
||||
add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR_CODE, _rmb_editor_code_add_split)
|
||||
add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR_CODE, _rmb_editor_code_remove_split)
|
||||
|
||||
add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR, _rmb_editor_pop_script)
|
||||
add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR_CODE, _rmb_editor_code_pop_script)
|
||||
|
||||
if !settings.has_setting(&"plugin/script_spliter/rows"):
|
||||
settings.set_setting(&"plugin/script_spliter/rows", _rows)
|
||||
else:
|
||||
_rows = settings.get_setting(&"plugin/script_spliter/rows")
|
||||
if !settings.has_setting(&"plugin/script_spliter/columns"):
|
||||
settings.set_setting(&"plugin/script_spliter/columns", _columns)
|
||||
else:
|
||||
_columns = settings.get_setting(&"plugin/script_spliter/columns")
|
||||
if !settings.has_setting(&"plugin/script_spliter/save_rows_columns_count_on_exit"):
|
||||
settings.set_setting(&"plugin/script_spliter/save_rows_columns_count_on_exit", false)
|
||||
if !settings.has_setting(&"plugin/script_spliter/behaviour/refresh_warnings_on_save"):
|
||||
settings.set_setting(&"plugin/script_spliter/behaviour/refresh_warnings_on_save", _refresh_warnings_on_save)
|
||||
else:
|
||||
_refresh_warnings_on_save = settings.get_setting(&"plugin/script_spliter/behaviour/refresh_warnings_on_save")
|
||||
else:
|
||||
if is_in_group(&"ScriptSpliter"):
|
||||
remove_from_group(&"ScriptSpliter")
|
||||
|
||||
main_screen_changed.disconnect(_on_change)
|
||||
resource_saved.disconnect(_on_save)
|
||||
|
||||
if is_instance_valid(_rmb_close_all_tab_in_split):
|
||||
remove_context_menu_plugin(_rmb_close_all_tab_in_split)
|
||||
if is_instance_valid(_rmb_close_all_tab_in_split_right):
|
||||
remove_context_menu_plugin(_rmb_close_all_tab_in_split_right)
|
||||
if is_instance_valid(_rmb_close_all_tab_in_split_left):
|
||||
remove_context_menu_plugin(_rmb_close_all_tab_in_split_left)
|
||||
|
||||
if is_instance_valid(_rmb_editor_add_split):
|
||||
remove_context_menu_plugin(_rmb_editor_add_split)
|
||||
if is_instance_valid(_rmb_editor_remove_split):
|
||||
remove_context_menu_plugin(_rmb_editor_remove_split)
|
||||
if is_instance_valid(_rmb_editor_code_add_split):
|
||||
remove_context_menu_plugin(_rmb_editor_code_add_split)
|
||||
if is_instance_valid(_rmb_editor_code_remove_split):
|
||||
remove_context_menu_plugin(_rmb_editor_code_remove_split)
|
||||
if is_instance_valid(_rmb_editor_pop_script):
|
||||
remove_context_menu_plugin(_rmb_editor_pop_script)
|
||||
if is_instance_valid(_rmb_editor_code_pop_script):
|
||||
remove_context_menu_plugin(_rmb_editor_code_pop_script)
|
||||
|
||||
|
||||
if settings.has_setting(&"plugin/script_spliter/save_rows_columns_count_on_exit"):
|
||||
if settings.get_setting(&"plugin/script_spliter/save_rows_columns_count_on_exit") == true:
|
||||
settings.set_setting(&"plugin/script_spliter/rows", _rows)
|
||||
settings.set_setting(&"plugin/script_spliter/columns", _columns)
|
||||
|
||||
func _can_close_tab_in_split(path : PackedStringArray) -> bool:
|
||||
return _builder.has_other_tabs()
|
||||
|
||||
func _can_close_right_tab_in_split(path : PackedStringArray) -> bool:
|
||||
return _builder.has_right_tabs()
|
||||
|
||||
func _can_close_left_tab_in_split(path : PackedStringArray) -> bool:
|
||||
return _builder.has_left_tabs()
|
||||
|
||||
func _close_all_tabs_in_split(__ : Variant) -> void:
|
||||
_builder.close_other_tabs()
|
||||
|
||||
func _close_all_tabs_in_split_right(__ : Variant) -> void:
|
||||
_builder.close_right_tabs()
|
||||
|
||||
func _close_all_tabs_in_split_left(__ : Variant) -> void:
|
||||
_builder.close_left_tabs()
|
||||
|
||||
func _can_add_split(path : PackedStringArray) -> bool:
|
||||
if !is_instance_valid(_builder):
|
||||
return false
|
||||
if path.size() == 0:
|
||||
return _builder.can_add_split(null)
|
||||
else:
|
||||
for x : String in path:
|
||||
if x.begins_with("res://"):
|
||||
var sc : ScriptEditor = EditorInterface.get_script_editor()
|
||||
return _builder.can_add_split(sc.get_current_editor().get_base_editor())
|
||||
else:
|
||||
var node : Node = get_node_or_null(x)
|
||||
if node:
|
||||
return _builder.can_add_split(node)
|
||||
else:
|
||||
var sc : ScriptEditor = EditorInterface.get_script_editor()
|
||||
return _builder.can_add_split(sc.get_current_editor().get_base_editor())
|
||||
return false
|
||||
|
||||
func _can_remove_split(path : PackedStringArray) -> bool:
|
||||
if !is_instance_valid(_builder):
|
||||
return false
|
||||
if path.size() == 0:
|
||||
return _builder.can_remove_split(null)
|
||||
else:
|
||||
for x : String in path:
|
||||
if x.begins_with("res://"):
|
||||
var sc : ScriptEditor = EditorInterface.get_script_editor()
|
||||
return _builder.can_remove_split(sc.get_current_editor().get_base_editor())
|
||||
else:
|
||||
var node : Node = get_node_or_null(x)
|
||||
if node:
|
||||
return _builder.can_remove_split(node)
|
||||
else:
|
||||
var sc : ScriptEditor = EditorInterface.get_script_editor()
|
||||
return _builder.can_remove_split(sc.get_current_editor().get_base_editor())
|
||||
return false
|
||||
|
||||
func _add_window_split(variant : Variant) -> void:
|
||||
var control : Control = null
|
||||
if variant is Script:
|
||||
var sc : ScriptEditor = EditorInterface.get_script_editor()
|
||||
if variant == sc.get_current_script():
|
||||
control = sc.get_current_editor().get_base_editor()
|
||||
else:
|
||||
var c : ScriptEditorBase = sc.get_current_editor()
|
||||
if c:
|
||||
control = c.get_base_editor()
|
||||
elif variant is CodeEdit:
|
||||
control = variant
|
||||
if is_instance_valid(control):
|
||||
_builder.add_split(control)
|
||||
|
||||
func _remove_window_split(variant : Variant) -> void:
|
||||
var control : Control = null
|
||||
if variant is Script:
|
||||
var sc : ScriptEditor = EditorInterface.get_script_editor()
|
||||
if variant == sc.get_current_script():
|
||||
control = sc.get_current_editor().get_base_editor()
|
||||
else:
|
||||
var c : ScriptEditorBase = sc.get_current_editor()
|
||||
if c:
|
||||
control = c.get_base_editor()
|
||||
elif variant is CodeEdit:
|
||||
control = variant
|
||||
if is_instance_valid(control):
|
||||
_builder.remove_split(control)
|
||||
|
||||
func _make_pop_script(variant : Variant) -> void:
|
||||
var control : Control = null
|
||||
if variant is Script:
|
||||
var sc : ScriptEditor = EditorInterface.get_script_editor()
|
||||
var arr : Array[ScriptEditorBase] = sc.get_open_script_editors()
|
||||
var scs : Array[Script] = sc.get_open_scripts()
|
||||
if arr.size() == scs.size():
|
||||
for y : int in range(0, scs.size(), 1):
|
||||
if scs[y] == variant:
|
||||
control = arr[y].get_base_editor()
|
||||
break
|
||||
if variant is CodeEdit:
|
||||
control = variant
|
||||
if is_instance_valid(control):
|
||||
_builder.make_pop_script(control)
|
||||
|
||||
func _can_make_pop_script(path : PackedStringArray) -> bool:
|
||||
if !is_instance_valid(_builder):
|
||||
return false
|
||||
for x : String in path:
|
||||
var node : Node = get_node_or_null(x)
|
||||
if node:
|
||||
return !_builder.is_pop_script(node)
|
||||
return false
|
||||
|
||||
func _on_change(screen_name : String) -> void:
|
||||
if screen_name == "Script":
|
||||
if is_instance_valid(_builder):
|
||||
_builder.update_rect.call_deferred()
|
||||
|
||||
|
||||
func _enter_tree() -> void:
|
||||
_setup(1)
|
||||
if !is_instance_valid(_builder):
|
||||
_builder = BUILDER.new(self)
|
||||
add_tool_menu_item(CMD_MENU_TOOL, _on_tool_command)
|
||||
|
||||
func _on_tool_command() -> void:
|
||||
if is_instance_valid(_builder):
|
||||
var data : Array[int] = _builder.get_current_columns_and_rows()
|
||||
_columns = data[0]
|
||||
_rows = data[1]
|
||||
|
||||
if !is_instance_valid(_menu_split_selector):
|
||||
_menu_split_selector = (ResourceLoader.load("res://addons/script_spliter/context/menu_tool.tscn") as PackedScene).instantiate()
|
||||
_menu_split_selector.set_plugin(self)
|
||||
_menu_split_selector.visible = false
|
||||
add_child(_menu_split_selector)
|
||||
_menu_split_selector.popup_centered.call_deferred()
|
||||
|
||||
func _ready() -> void:
|
||||
set_process(false)
|
||||
set_process_input(false)
|
||||
if !get_tree().root.is_node_ready():
|
||||
await get_tree().root.ready
|
||||
for __ : int in range(2):
|
||||
await get_tree().process_frame
|
||||
_run()
|
||||
|
||||
func _notification(what: int) -> void:
|
||||
if what == NOTIFICATION_PREDELETE:
|
||||
if is_instance_valid(_builder) and !_builder.is_queued_for_deletion():
|
||||
_builder.init_0()
|
||||
_builder.free()
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if event is InputEventKey:
|
||||
if event.pressed and event.ctrl_pressed:
|
||||
if event.keycode == 49:
|
||||
set_type_split(0, 0)
|
||||
elif event.keycode == 50:
|
||||
set_type_split(2, 1)
|
||||
elif event.keycode == 51:
|
||||
set_type_split(1, 2)
|
||||
elif event.keycode == 52:
|
||||
set_type_split(3, 1)
|
||||
elif event.keycode == 53:
|
||||
set_type_split(1, 3)
|
||||
elif event.keycode == 54:
|
||||
set_type_split(2, 2)
|
||||
Reference in New Issue
Block a user