Initial Commit
This commit is contained in:
commit
48a5e71e00
1136 changed files with 64347 additions and 0 deletions
41
addons/script_splitter/core/ui/splitter/editor/ssp_editor.gd
Normal file
41
addons/script_splitter/core/ui/splitter/editor/ssp_editor.gd
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
@tool
|
||||
extends CodeEdit
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Script Splitter
|
||||
# https://github.com/CodeNameTwister/Script-Splitter
|
||||
#
|
||||
# Script Splitter addon for godot 4f
|
||||
# author: "Twister"
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
|
||||
const UPDATE_TIME : float = 0.25
|
||||
|
||||
var _dlt : float = 0.0
|
||||
var _text : String = ""
|
||||
var _dlt_update : float = UPDATE_TIME
|
||||
|
||||
func set_text_reference(txt : String) -> void:
|
||||
if _text == txt:
|
||||
return
|
||||
_text = txt
|
||||
_dlt = 0.0
|
||||
_dlt_update = UPDATE_TIME + (txt.length() * 0.00001)
|
||||
|
||||
set_process(true)
|
||||
|
||||
func _init() -> void:
|
||||
if is_node_ready():
|
||||
_ready()
|
||||
|
||||
func _ready() -> void:
|
||||
set_process(false)
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
_dlt += delta
|
||||
if _dlt > _dlt_update:
|
||||
set_process(false)
|
||||
var sv : float = scroll_vertical
|
||||
var sh : int = scroll_horizontal
|
||||
text = _text
|
||||
scroll_vertical = sv
|
||||
scroll_horizontal = sh
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://bec3qea1dh8xe
|
||||
110
addons/script_splitter/core/ui/splitter/editor_container.gd
Normal file
110
addons/script_splitter/core/ui/splitter/editor_container.gd
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
@tool
|
||||
extends TabContainer
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Script Splitter
|
||||
# https://github.com/CodeNameTwister/Script-Splitter
|
||||
#
|
||||
# Script Splitter addon for godot 4
|
||||
# author: "Twister"
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
const Dottab = preload("./../../../core/ui/splitter/taby/dottab.gd")
|
||||
const CLOSE = preload("./../../../assets/Close.svg")
|
||||
|
||||
const GLOBALS : PackedStringArray = ["_GlobalScope", "_GDScript"]
|
||||
|
||||
#
|
||||
signal focus(o : TabContainer, index : int)
|
||||
signal remove(o : TabContainer, index : int)
|
||||
|
||||
var _new_tab_settings : bool = false
|
||||
var _tab_queue : int = -1
|
||||
var _last_selected : int = -1
|
||||
|
||||
func _enter_tree() -> void:
|
||||
add_to_group(&"__SC_SPLITTER__")
|
||||
|
||||
func _exit_tree() -> void:
|
||||
if is_in_group(&"__SC_SPLITTER__"):
|
||||
remove_from_group(&"__SC_SPLITTER__")
|
||||
|
||||
func _ready() -> void:
|
||||
size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
|
||||
|
||||
auto_translate_mode = Node.AUTO_TRANSLATE_MODE_DISABLED
|
||||
|
||||
var tb : TabBar = get_tab_bar()
|
||||
if tb:
|
||||
tb.auto_translate_mode = auto_translate_mode
|
||||
|
||||
|
||||
drag_to_rearrange_enabled = true
|
||||
|
||||
#CONNECT
|
||||
var tab : TabBar = get_tab_bar()
|
||||
tab.set_script(Dottab)
|
||||
tab.tab_selected.connect(_on_selected)
|
||||
tab.active_tab_rearranged.connect(_on_rearranged)
|
||||
|
||||
tab.tab_close_display_policy = TabBar.CLOSE_BUTTON_SHOW_ACTIVE_ONLY
|
||||
tab.tab_close_pressed.connect(_on_remove)
|
||||
tab.select_with_rmb = true
|
||||
tab.on_start_drag.connect(on_drag)
|
||||
tab.on_stop_drag.connect(out_drag)
|
||||
|
||||
func _on_rearranged(t : int) -> void:
|
||||
if _last_selected == t or t < 0:
|
||||
return
|
||||
|
||||
for x : int in [_last_selected, t]:
|
||||
if x < 0 or x >= get_tab_count():
|
||||
return
|
||||
|
||||
var sc : SceneTree = Engine.get_main_loop()
|
||||
if sc:
|
||||
for x : Node in sc.get_nodes_in_group(&"__SCRIPT_SPLITTER__"):
|
||||
x.call(&"move_item_container", self, _last_selected, t)
|
||||
|
||||
func _set_tab() -> void:
|
||||
if current_tab != _tab_queue and _tab_queue > -1 and _tab_queue < get_tab_count():
|
||||
current_tab = _tab_queue
|
||||
_new_tab_settings = false
|
||||
|
||||
func set_tab(index : int) -> void:
|
||||
if index > -1 and index < get_tab_count():
|
||||
_tab_queue = index
|
||||
|
||||
if _new_tab_settings:
|
||||
return
|
||||
|
||||
_new_tab_settings = true
|
||||
_set_tab.call_deferred()
|
||||
|
||||
func on_drag(tab : TabBar) -> void:
|
||||
for x : Node in tab.get_tree().get_nodes_in_group(&"ScriptSplitter"):
|
||||
if x.has_method(&"dragged"):
|
||||
x.call(&"dragged", tab, true)
|
||||
|
||||
func out_drag(tab : TabBar) -> void:
|
||||
for x : Node in tab.get_tree().get_nodes_in_group(&"ScriptSplitter"):
|
||||
if x.has_method(&"dragged"):
|
||||
x.call(&"dragged", tab, false)
|
||||
|
||||
func _on_remove(index : int) -> void:
|
||||
remove.emit(self, index)
|
||||
|
||||
func _on_selected(value : int) -> void:
|
||||
_last_selected = value
|
||||
focus.emit(self, value)
|
||||
|
||||
func get_root() -> Node:
|
||||
return self
|
||||
|
||||
func set_item_tooltip(idx : int, txt : String) -> void:
|
||||
if idx > -1 and get_tab_count() > idx:
|
||||
set_tab_tooltip(idx, txt)
|
||||
|
||||
func set_item_text(idx : int, txt : String) -> void:
|
||||
if idx > -1 and get_tab_count() > idx:
|
||||
set_tab_title(idx, txt)
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://b45owls32pkxk
|
||||
122
addons/script_splitter/core/ui/splitter/io/io_bar.gd
Normal file
122
addons/script_splitter/core/ui/splitter/io/io_bar.gd
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
@tool
|
||||
extends ScrollContainer
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Script Splitter
|
||||
# https://github.com/CodeNameTwister/Script-Splitter
|
||||
#
|
||||
# Script Splitter addon for godot 4
|
||||
# author: "Twister"
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
const PIN = preload("./../../../../assets/pin.svg")
|
||||
const FILL_EXPAND = preload("./../../../../assets/fill_expand.svg")
|
||||
const SPLIT_CPLUS_TOOL = preload("./../../../../assets/split_cplus_tool.svg")
|
||||
const SPLIT_MINUS_TOOL = preload("./../../../../assets/split_minus_tool.svg")
|
||||
const SPLIT_PLUS_TOOL = preload("./../../../../assets/split_plus_tool.svg")
|
||||
const SPLIT_RMINUS_TOOL = preload("./../../../../assets/split_rminus_tool.svg")
|
||||
const SPLIT_RPLUS_TOOL = preload("./../../../../assets/split_rplus_tool.svg")
|
||||
const SPLIT_CMINUS_TOOL = preload("./../../../../assets/split_cminus_tool.svg")
|
||||
const ATOP = preload("./../../../../assets/atop.png")
|
||||
|
||||
|
||||
const PAD : float = 12.0
|
||||
|
||||
#CFG
|
||||
var enable_expand : bool = true
|
||||
var enable_horizontal_split : bool = true
|
||||
var enable_vertical_split : bool = true
|
||||
var enable_pop_script : bool = true
|
||||
var enable_sub_split : bool = true
|
||||
|
||||
var _root : VBoxContainer = null
|
||||
var _min_size : float = 0.0
|
||||
|
||||
@warning_ignore("unused_private_class_variable")
|
||||
var _pin_root : Control = null
|
||||
|
||||
func _ready() -> void:
|
||||
if _root == null:
|
||||
_root = VBoxContainer.new()
|
||||
_root.alignment = BoxContainer.ALIGNMENT_BEGIN
|
||||
_root.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
_root.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
add_child(_root)
|
||||
clear()
|
||||
_setup()
|
||||
|
||||
custom_minimum_size.x = _min_size + PAD
|
||||
horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
|
||||
vertical_scroll_mode = ScrollContainer.SCROLL_MODE_SHOW_NEVER
|
||||
|
||||
func get_root() -> Node:
|
||||
return _root
|
||||
|
||||
func _enter_tree() -> void:
|
||||
add_to_group(&"__script_splitter__IO__")
|
||||
|
||||
func _exit_tree() -> void:
|
||||
remove_from_group(&"__script_splitter__IO__")
|
||||
|
||||
# Traduction?
|
||||
func _tr(st : String) -> String:
|
||||
# ...
|
||||
return st.capitalize()
|
||||
|
||||
func clear() -> void:
|
||||
if _root:
|
||||
if is_inside_tree():
|
||||
for x : Node in _root.get_children():
|
||||
x.queue_free()
|
||||
else:
|
||||
for x : Node in _root.get_children():
|
||||
x.free()
|
||||
|
||||
|
||||
func setup() -> void:
|
||||
clear()
|
||||
_setup()
|
||||
|
||||
func _setup() -> void:
|
||||
if !_root:
|
||||
return
|
||||
if enable_expand:
|
||||
make_function(&"EXPAND", FILL_EXPAND, _tr("Expand/Unexpand current tab container"))
|
||||
if enable_horizontal_split:
|
||||
make_function(&"SPLIT_COLUMN", SPLIT_CPLUS_TOOL, _tr("Split to new column"))
|
||||
make_function(&"MERGE_COLUMN", SPLIT_CMINUS_TOOL, _tr("Merge current column"))
|
||||
if enable_vertical_split:
|
||||
make_function(&"SPLIT_ROW", SPLIT_RPLUS_TOOL, _tr("Split to new row"))
|
||||
make_function(&"MERGE_ROW", SPLIT_RMINUS_TOOL, _tr("Merge current row"))
|
||||
if enable_sub_split:
|
||||
make_function(&"SPLIT_SUB", SPLIT_PLUS_TOOL, _tr("Sub Split current editor"))
|
||||
make_function(&"MERGE_SPLIT_SUB", SPLIT_MINUS_TOOL, _tr("Merge sub split of current editor"))
|
||||
if enable_pop_script:
|
||||
make_function(&"MAKE_FLOATING", ATOP, _tr("Make separate window"))
|
||||
|
||||
func enable(id : StringName, e : bool) -> void:
|
||||
for x : Node in _root.get_children():
|
||||
if x.name == id:
|
||||
x.set(&"disabled", !e)
|
||||
|
||||
func get_button(id : String) -> Button:
|
||||
if _root.has_node(id):
|
||||
var node : Node = _root.get_node(id)
|
||||
if node is Button:
|
||||
return node
|
||||
return null
|
||||
|
||||
func make_function(id : StringName, icon : Texture2D = null, txt : String = "") -> void:
|
||||
var btn : Button = Button.new()
|
||||
btn.name = id
|
||||
|
||||
btn.pressed.connect(_call.bind(id))
|
||||
btn.icon = icon
|
||||
btn.alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
btn.tooltip_text = txt
|
||||
btn.flat = is_instance_valid(icon)
|
||||
_min_size = maxf(icon.get_size().x, _min_size)
|
||||
_root.add_child(btn)
|
||||
|
||||
func _call(id : StringName) -> void:
|
||||
for x : Node in get_tree().get_nodes_in_group(&"__SCRIPT_SPLITTER__"):
|
||||
if x.has_method(&"_io_call"):
|
||||
x.call(&"_io_call", id)
|
||||
1
addons/script_splitter/core/ui/splitter/io/io_bar.gd.uid
Normal file
1
addons/script_splitter/core/ui/splitter/io/io_bar.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://b817wwia7hrqd
|
||||
307
addons/script_splitter/core/ui/splitter/splitter_container.gd
Normal file
307
addons/script_splitter/core/ui/splitter/splitter_container.gd
Normal file
|
|
@ -0,0 +1,307 @@
|
|||
@tool
|
||||
extends MarginContainer
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Script Splitter
|
||||
# https://github.com/CodeNameTwister/Script-Splitter
|
||||
#
|
||||
# Script Splitter addon for godot 4
|
||||
# author: "Twister"
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
const SplitterRoot = preload("./../../../core/ui/splitter/splitter_root.gd")
|
||||
const HandlerContainer = preload("./../../../core/base/container.gd")
|
||||
const BaseContainerItem = preload("splitter_item.gd")
|
||||
|
||||
const SplitterEditorContainer = preload("./../../../core/ui/splitter/splitter_editor_container.gd")
|
||||
|
||||
const Overlay = preload("./../../../core/ui/splitter/taby/overlay.gd")
|
||||
const CODE_NAME_TWISTER = preload("./../../../assets/github_CodeNameTwister.svg")
|
||||
|
||||
var _handler_container : HandlerContainer = null
|
||||
var _base_container : TabContainer = null
|
||||
|
||||
var _root : Container = null
|
||||
var _root_container : SplitterRoot = null
|
||||
|
||||
var _last_editor_container : SplitterEditorContainer.Editor = null
|
||||
|
||||
var _overlay : Overlay = null
|
||||
|
||||
var swap_by_button : bool = true
|
||||
|
||||
func get_root() -> SplitterRoot:
|
||||
return _root_container
|
||||
|
||||
func get_base_editors() -> Array[Node]:
|
||||
if is_instance_valid(_base_container):
|
||||
return _base_container.get_children()
|
||||
return []
|
||||
|
||||
func initialize(container : TabContainer, handler_container : HandlerContainer) -> void:
|
||||
_setup()
|
||||
|
||||
_handler_container = handler_container
|
||||
_base_container = container
|
||||
|
||||
_root = self
|
||||
|
||||
var credits : TextureRect = TextureRect.new()
|
||||
add_child(credits)
|
||||
|
||||
credits.texture = CODE_NAME_TWISTER
|
||||
credits.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
|
||||
credits.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
credits.expand_mode = TextureRect.EXPAND_KEEP_SIZE
|
||||
credits.stretch_mode = TextureRect.STRETCH_KEEP_CENTERED
|
||||
credits.modulate.a = 0.25
|
||||
|
||||
if is_instance_valid(_base_container):
|
||||
var root : Node = _base_container.get_parent()
|
||||
root.add_child(_root)
|
||||
root.move_child(_root, mini(_base_container.get_index(), 0))
|
||||
|
||||
#_root.add_child(_root_container)
|
||||
|
||||
_root.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
_root.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
|
||||
var vspl : HBoxContainer = HBoxContainer.new()
|
||||
|
||||
_root.add_child(vspl)
|
||||
vspl.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
vspl.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
|
||||
var base : SplitterRoot = create_base_container(vspl, false)
|
||||
base.max_columns = 1
|
||||
_root_container = base
|
||||
|
||||
var io : Node = _handler_container.get_io_bar()
|
||||
if io.get_parent() == null:
|
||||
vspl.add_child(io)
|
||||
else:
|
||||
io = HandlerContainer.IoBar.new()
|
||||
io.enable_vertical_split = false
|
||||
vspl.add_child(io)
|
||||
|
||||
initialize_editor_contianer()
|
||||
|
||||
_overlay = Overlay.new()
|
||||
add_child(_overlay)
|
||||
|
||||
func _on_change() -> void:
|
||||
var dt : Array = ["plugin/script_splitter/editor/behaviour/swap_by_double_click_separator_button"]
|
||||
|
||||
var settings : EditorSettings = EditorInterface.get_editor_settings()
|
||||
var changes : PackedStringArray = settings.get_changed_settings()
|
||||
|
||||
for c in changes:
|
||||
if c in dt:
|
||||
_setup()
|
||||
break
|
||||
|
||||
func _setup() -> void:
|
||||
var settings : EditorSettings = EditorInterface.get_editor_settings()
|
||||
if !settings.settings_changed.is_connected(_on_change):
|
||||
settings.settings_changed.connect(_on_change)
|
||||
|
||||
for x : Array in [
|
||||
["swap_by_button", "plugin/script_splitter/editor/behaviour/swap_by_double_click_separator_button"]
|
||||
]:
|
||||
if settings.has_setting(x[1]):
|
||||
set(x[0], settings.get_setting(x[1]))
|
||||
else:
|
||||
settings.set_setting(x[1], get(x[0]))
|
||||
|
||||
func initialize_editor_contianer() -> void:
|
||||
if _root_container.get_child_count() > 0:
|
||||
for x : Node in _root_container.get_children():
|
||||
x.queue_free()
|
||||
_last_editor_container = create_new_editor_container(_root_container, true)
|
||||
|
||||
func swap(value : Variant) -> void:
|
||||
if !swap_by_button:
|
||||
return
|
||||
|
||||
if !is_instance_valid(value):
|
||||
return
|
||||
|
||||
elif !is_instance_valid(_root_container) or _root_container.get_child_count() == 0:
|
||||
return
|
||||
|
||||
elif !value is SplitterRoot.LineSep:
|
||||
return
|
||||
|
||||
var caller : SplitterRoot.LineSep = value
|
||||
|
||||
var _main : SplitterRoot = caller.get_parent()
|
||||
|
||||
if !is_instance_valid(_main):
|
||||
return
|
||||
|
||||
var separators : Array = _main.get_separators()
|
||||
if separators.size() == 0:
|
||||
return
|
||||
|
||||
var index : int = 0
|
||||
var linesep : Object = null
|
||||
for x : Object in separators:
|
||||
if x == caller:
|
||||
linesep =x
|
||||
break
|
||||
index += 1
|
||||
|
||||
if linesep:
|
||||
if linesep.is_vertical:
|
||||
var atotal : int = 1
|
||||
var btotal : int = 1
|
||||
var nodes : Array[Node] = []
|
||||
|
||||
for x : int in range(index + 1, separators.size(), 1):
|
||||
var clinesep : Object = separators[x]
|
||||
if clinesep.is_vertical:
|
||||
break
|
||||
atotal += 1
|
||||
for x : int in range(index - 1, -1, -1):
|
||||
var clinesep : Object = separators[x]
|
||||
if clinesep.is_vertical:
|
||||
break
|
||||
btotal += 1
|
||||
|
||||
var cindex : int = index
|
||||
while atotal > 0:
|
||||
cindex += 1
|
||||
atotal -= 1
|
||||
if cindex < _main.get_child_count():
|
||||
nodes.append(_main.get_child(cindex))
|
||||
continue
|
||||
break
|
||||
|
||||
for x : Node in nodes:
|
||||
cindex = btotal
|
||||
while cindex > 0:
|
||||
cindex -= 1
|
||||
var idx : int = x.get_index() - 1
|
||||
if _main.get_child_count() > idx:
|
||||
_main.move_child(x, idx)
|
||||
else:
|
||||
index += 1
|
||||
if _main.get_child_count() > index:
|
||||
var child : Node = _main.get_child(index - 1)
|
||||
_main.move_child(child, index)
|
||||
|
||||
func _enter_tree() -> void:
|
||||
add_to_group(&"ScriptSplitter")
|
||||
|
||||
func _exit_tree() -> void:
|
||||
remove_from_group(&"ScriptSplitter")
|
||||
|
||||
var settings : EditorSettings = EditorInterface.get_editor_settings()
|
||||
if settings.settings_changed.is_connected(_on_change):
|
||||
settings.settings_changed.disconnect(_on_change)
|
||||
|
||||
|
||||
func dragged(tab : TabBar, is_drag : bool) -> void:
|
||||
if is_instance_valid(_overlay):
|
||||
if is_drag:
|
||||
_overlay.start(tab)
|
||||
else:
|
||||
if _overlay.stop(tab):
|
||||
var container : Node = _overlay.get_container()
|
||||
var from : Container = tab.get_parent()
|
||||
if is_instance_valid(container) and is_instance_valid(from):
|
||||
if from != container:
|
||||
_handler_container.swap_tab.emit(from, tab.current_tab, container)
|
||||
else:
|
||||
var type : StringName = _overlay.get_type_split()
|
||||
if !type.is_empty():
|
||||
_handler_container.same_swap_tab.emit(from, tab.current_tab, type)
|
||||
|
||||
func create_new_column() -> SplitterEditorContainer.Editor:
|
||||
var item : BaseContainerItem = get_base_container_item(_last_editor_container)
|
||||
var root : Container = get_base_container(_last_editor_container)
|
||||
var index : int = item.get_index()
|
||||
var custom_position : bool = index >= 0 and index < item.get_parent().get_child_count() - 1
|
||||
_last_editor_container = create_editor_container(create_base_container_item(root))
|
||||
if custom_position:
|
||||
root.move_child(get_base_container_item(_last_editor_container), index + 1)
|
||||
return _last_editor_container
|
||||
|
||||
func create_new_row() -> SplitterEditorContainer.Editor:
|
||||
var root : Container = get_base_container(_last_editor_container)
|
||||
var index : int = root.get_index()
|
||||
var custom_position : bool = index >= 0 and index < root.get_parent().get_child_count() - 1
|
||||
_last_editor_container = create_new_editor_container(_root_container)# create_editor_container(create_base_container_item(create_base_container(_root_container)))
|
||||
if custom_position:
|
||||
_root_container.move_child(get_base_container(_last_editor_container).get_parent(), index + 1)
|
||||
return _last_editor_container
|
||||
|
||||
|
||||
func set_current_editor(container : Node) -> bool:
|
||||
if container is SplitterEditorContainer.Editor:
|
||||
_last_editor_container = container
|
||||
return true
|
||||
return false
|
||||
|
||||
func get_base_container(editor : SplitterEditorContainer.Editor) -> Container:
|
||||
return editor.get_node("./../../../")
|
||||
|
||||
func get_base_container_item(editor : SplitterEditorContainer.Editor) -> BaseContainerItem:
|
||||
return editor.get_node("./../../")
|
||||
|
||||
func create_base_container(c_root : Node, _add_to_group : bool = true) -> Container:
|
||||
var b_root : Container = SplitterRoot.new()
|
||||
b_root.max_columns = 0
|
||||
c_root.add_child(b_root)
|
||||
b_root.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
b_root.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
|
||||
if _add_to_group:
|
||||
b_root.add_to_group(&"__SP_BR__")
|
||||
|
||||
return b_root
|
||||
|
||||
|
||||
func create_base_container_item(c_root : Container) -> BaseContainerItem:
|
||||
var b_item : BaseContainerItem = BaseContainerItem.new()
|
||||
c_root.add_child(b_item)
|
||||
|
||||
b_item.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
b_item.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
|
||||
return b_item
|
||||
|
||||
func create_editor_container(c_root : BaseContainerItem) -> SplitterEditorContainer.Editor:
|
||||
var b_editor : SplitterEditorContainer = SplitterEditorContainer.new()
|
||||
|
||||
c_root.add_child(b_editor)
|
||||
b_editor.get_editor()
|
||||
|
||||
var editor : SplitterEditorContainer.Editor = b_editor.get_editor()
|
||||
|
||||
editor.focus.connect(_handler_container.on_focus)
|
||||
editor.remove.connect(_handler_container.on_remove)
|
||||
|
||||
editor.get_tab_bar().tab_rmb_clicked.connect(_on_rmb_clicked.bind(editor))
|
||||
return editor
|
||||
|
||||
func _on_rmb_clicked(index : int, tab : Variant) -> void:
|
||||
if tab is SplitterEditorContainer.Editor:
|
||||
_handler_container.rmb_click.emit(index, tab)
|
||||
|
||||
func create_new_editor_container(c_root : Node, _add_to_group : bool = true) -> SplitterEditorContainer.Editor:
|
||||
return create_editor_container(create_base_container_item(create_base_container(c_root, _add_to_group)))
|
||||
|
||||
func get_current_editor() -> SplitterEditorContainer.Editor:
|
||||
return _last_editor_container
|
||||
|
||||
func reset() -> void:
|
||||
_root.queue_free()
|
||||
if is_instance_valid(_base_container):
|
||||
_base_container.visible = true
|
||||
|
||||
var settings : EditorSettings = EditorInterface.get_editor_settings()
|
||||
if settings.settings_changed.is_connected(_on_change):
|
||||
settings.settings_changed.disconnect(_on_change)
|
||||
|
||||
func notify_creation() -> void:
|
||||
if is_instance_valid(_base_container) and _base_container.visible:
|
||||
_base_container.visible = false
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://dyo7c2g4uwn0g
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
@tool
|
||||
extends VBoxContainer
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Script Splitter
|
||||
# https://github.com/CodeNameTwister/Script-Splitter
|
||||
#
|
||||
# Script Splitter addon for godot 4
|
||||
# author: "Twister"
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
const Editor = preload("./../../../core/ui/splitter/editor_container.gd")
|
||||
const CONTAINER = preload("./../../../core/ui/multi_split_container/taby/container.tscn")
|
||||
|
||||
var _editor : Editor = null
|
||||
var _tab_old_behaviour : bool = false:
|
||||
set = _on_behaviour_changed
|
||||
var tab : Node = null
|
||||
|
||||
func _on_behaviour_changed(e) -> void:
|
||||
_tab_old_behaviour = e
|
||||
if is_instance_valid(tab):
|
||||
tab.set_enable(!_tab_old_behaviour)
|
||||
_editor.tabs_visible = _tab_old_behaviour
|
||||
|
||||
func _on_change() -> void:
|
||||
var dt : Array = ["plugin/script_splitter/editor/tabs/use_old_behaviour"]
|
||||
|
||||
var settings : EditorSettings = EditorInterface.get_editor_settings()
|
||||
var changes : PackedStringArray = settings.get_changed_settings()
|
||||
|
||||
for c in changes:
|
||||
if c in dt:
|
||||
_setup()
|
||||
break
|
||||
|
||||
func _setup() -> void:
|
||||
var settings : EditorSettings = EditorInterface.get_editor_settings()
|
||||
if !settings.settings_changed.is_connected(_on_change):
|
||||
settings.settings_changed.connect(_on_change)
|
||||
|
||||
for x : Array in [
|
||||
["_tab_old_behaviour", "plugin/script_splitter/editor/tabs/use_old_behaviour"]
|
||||
]:
|
||||
if settings.has_setting(x[1]):
|
||||
set(x[0], settings.get_setting(x[1]))
|
||||
else:
|
||||
settings.set_setting(x[1], get(x[0]))
|
||||
|
||||
func _ready() -> void:
|
||||
_editor = Editor.new()
|
||||
|
||||
var iscale : int = -8
|
||||
set(&"theme_override_constants/separation", iscale)
|
||||
|
||||
tab = CONTAINER.instantiate()
|
||||
tab.set_ref(_editor.get_tab_bar())
|
||||
tab.set_enable(!_tab_old_behaviour)
|
||||
_editor.tabs_visible = _tab_old_behaviour
|
||||
|
||||
add_child(tab)
|
||||
add_child(_editor)
|
||||
|
||||
size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
|
||||
func _enter_tree() -> void:
|
||||
add_to_group(&"__SP_EC__")
|
||||
_setup()
|
||||
|
||||
func _exit_tree() -> void:
|
||||
remove_from_group(&"__SP_EC__")
|
||||
|
||||
var settings : EditorSettings = EditorInterface.get_editor_settings()
|
||||
if settings.settings_changed.is_connected(_on_change):
|
||||
settings.settings_changed.disconnect(_on_change)
|
||||
|
||||
func get_editor() -> Editor:
|
||||
return _editor
|
||||
|
||||
func update() -> void:
|
||||
if !is_instance_valid(tab):
|
||||
return
|
||||
tab.update()
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://dlqgddtcsov1m
|
||||
67
addons/script_splitter/core/ui/splitter/splitter_item.gd
Normal file
67
addons/script_splitter/core/ui/splitter/splitter_item.gd
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
@tool
|
||||
extends "./../../../core/ui/multi_split_container/split_container_item.gd"
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Script Splitter
|
||||
# https://github.com/CodeNameTwister/Script-Splitter
|
||||
#
|
||||
# Script Splitter addon for godot 4
|
||||
# author: "Twister"
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
|
||||
var _fms : float = 0.0
|
||||
|
||||
func _ready() -> void:
|
||||
super()
|
||||
modulate = Color.DARK_GRAY
|
||||
set_physics_process(modulate != Color.WHITE)
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
_fms += delta * 0.24
|
||||
if _fms >= 1.0:
|
||||
_fms = 1.0
|
||||
set_physics_process(false)
|
||||
modulate = lerp(modulate, Color.WHITE, _fms)
|
||||
|
||||
func _enter_tree() -> void:
|
||||
super()
|
||||
|
||||
add_to_group(&"__SP_IC__")
|
||||
var parent : Node = get_parent()
|
||||
if parent.has_method(&"expand_splited_container"):
|
||||
_on_child(self)
|
||||
|
||||
func _exit_tree() -> void:
|
||||
add_to_group(&"__SP_IC__")
|
||||
|
||||
func _on_child(n : Node) -> void:
|
||||
if n is Control:
|
||||
var parent : Node = get_parent()
|
||||
if !n.child_entered_tree.is_connected(_on_child):
|
||||
n.child_entered_tree.connect(_on_child)
|
||||
|
||||
if !n.child_exiting_tree.is_connected(_out_child):
|
||||
n.child_exiting_tree.connect(_out_child)
|
||||
|
||||
if n.focus_mode != Control.FOCUS_NONE:
|
||||
if !n.focus_entered.is_connected(parent.expand_splited_container):
|
||||
n.focus_entered.connect(parent.expand_splited_container.bind(self))
|
||||
|
||||
for x : Node in n.get_children():
|
||||
_on_child(x)
|
||||
|
||||
func _out_child(n : Node) -> void:
|
||||
if n is Control:
|
||||
var parent : Node = get_parent()
|
||||
if n.child_entered_tree.is_connected(_on_child):
|
||||
n.child_entered_tree.disconnect(_on_child)
|
||||
|
||||
if n.child_exiting_tree.is_connected(_out_child):
|
||||
n.child_exiting_tree.disconnect(_out_child)
|
||||
|
||||
if n.focus_mode != Control.FOCUS_NONE:
|
||||
if n.focus_entered.is_connected(parent.expand_splited_container):
|
||||
n.focus_entered.disconnect(parent.expand_splited_container)
|
||||
for x : Node in n.get_children():
|
||||
_out_child(x)
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://b2kiv55ed0aj
|
||||
106
addons/script_splitter/core/ui/splitter/splitter_list.gd
Normal file
106
addons/script_splitter/core/ui/splitter/splitter_list.gd
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
@tool
|
||||
extends ItemList
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Script Splitter
|
||||
# https://github.com/CodeNameTwister/Script-Splitter
|
||||
#
|
||||
# Script Splitter addon for godot 4
|
||||
# author: "Twister"
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
|
||||
signal move_item_by_index(from : int, to : int)
|
||||
|
||||
var _ss: Callable
|
||||
var _delta : int = 0
|
||||
var _list : ItemList = null
|
||||
var _dragged_item_index: int = -1
|
||||
|
||||
func _ready() -> void:
|
||||
set_process(false)
|
||||
set_physics_process(false)
|
||||
|
||||
func update() -> void:
|
||||
_delta = 0
|
||||
set_physics_process(true)
|
||||
|
||||
func set_list(item : ItemList) -> void:
|
||||
_list = item
|
||||
|
||||
func set_reference(scall : Callable) -> void:
|
||||
_ss = scall
|
||||
|
||||
func changes(list : ItemList) -> bool:
|
||||
if list.item_count != item_count:
|
||||
return true
|
||||
|
||||
for x : int in list.item_count:
|
||||
if is_selected(x) != is_selected(x) or \
|
||||
get_item_text(x) != list.get_item_text(x) or\
|
||||
get_item_icon(x) != list.get_item_icon(x) or \
|
||||
get_item_icon_modulate(x) != list.get_item_icon_modulate(x) or \
|
||||
get_item_tooltip(x) != list.get_item_tooltip(x):
|
||||
return true
|
||||
|
||||
return false
|
||||
|
||||
func _physics_process(__ : float) -> void:
|
||||
_delta += 1
|
||||
if _delta < 10:
|
||||
return
|
||||
set_physics_process(false)
|
||||
if !_ss.is_valid():
|
||||
return
|
||||
if !changes(_list):
|
||||
return
|
||||
_ss.call()
|
||||
|
||||
func _get_drag_data(at_position: Vector2) -> Variant:
|
||||
var item_index : int = get_item_at_position(at_position)
|
||||
|
||||
if item_index != -1:
|
||||
_dragged_item_index = item_index
|
||||
|
||||
var drag_preview : HBoxContainer = HBoxContainer.new()
|
||||
var icon : TextureRect = TextureRect.new()
|
||||
var label : Label = Label.new()
|
||||
|
||||
drag_preview.set(&"theme_override_constants/separation", 0)
|
||||
icon.texture = get_item_icon(0)
|
||||
icon.modulate = get_item_icon_modulate(0)
|
||||
icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
||||
label.text = get_item_text(item_index)
|
||||
drag_preview.add_child(icon)
|
||||
drag_preview.add_child(label)
|
||||
|
||||
set_drag_preview(drag_preview)
|
||||
var tp : String = get_item_tooltip(item_index)
|
||||
|
||||
for x : Node in Engine.get_main_loop().get_nodes_in_group(&"SP_TAB_BUTTON"):
|
||||
if x is Control:
|
||||
if tp == x.tooltip_text and x.has_method(&"_on_input"):
|
||||
var ip : InputEventMouseButton = InputEventMouseButton.new()
|
||||
ip.button_index = MOUSE_BUTTON_LEFT
|
||||
ip.pressed = true
|
||||
x.call(&"_on_input", ip)
|
||||
|
||||
return item_index
|
||||
return null
|
||||
|
||||
func _can_drop_data(at_position: Vector2, data: Variant) -> bool:
|
||||
if typeof(data) == TYPE_INT and data > -1 and data == _dragged_item_index:
|
||||
var drop_index : int = get_item_at_position(at_position)
|
||||
|
||||
return drop_index != -1 and drop_index != data
|
||||
|
||||
return false
|
||||
|
||||
func _drop_data(at_position: Vector2, data: Variant) -> void:
|
||||
if typeof(data) != TYPE_INT or data < 0 or data != _dragged_item_index:
|
||||
return
|
||||
var from_index : int = data as int
|
||||
var to_index : int = get_item_at_position(at_position)
|
||||
|
||||
if from_index != -1 and to_index != -1:
|
||||
move_item_by_index.emit(from_index, to_index)
|
||||
|
||||
_dragged_item_index = -1
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://c12gyjf2qmasp
|
||||
108
addons/script_splitter/core/ui/splitter/splitter_root.gd
Normal file
108
addons/script_splitter/core/ui/splitter/splitter_root.gd
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
@tool
|
||||
extends "./../../../core/ui/multi_split_container/multi_split_container.gd"
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Script Splitter
|
||||
# https://github.com/CodeNameTwister/Script-Splitter
|
||||
#
|
||||
# Script Splitter addon for godot 4
|
||||
# author: "Twister"
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
const EXPAND = preload("./../../../assets/expand.svg")
|
||||
|
||||
var __setup : bool = false
|
||||
var _delta : float = 0.0
|
||||
|
||||
func _init() -> void:
|
||||
super()
|
||||
|
||||
drag_button_icon = EXPAND
|
||||
drag_button_size = 24.0
|
||||
behaviour_expand_on_focus = true
|
||||
behaviour_can_expand_focus_same_container = false
|
||||
behaviour_expand_smoothed = true
|
||||
drag_button_always_visible = false
|
||||
drag_button_modulate = Color.WHITE
|
||||
behaviour_expand_on_double_click = true
|
||||
behaviour_can_move_by_line = true
|
||||
|
||||
_setup()
|
||||
|
||||
func _ready() -> void:
|
||||
super()
|
||||
modulate.a = 0.0
|
||||
set_physics_process(true)
|
||||
|
||||
func _physics_process(delta : float) -> void:
|
||||
_delta += delta * 2.0
|
||||
if _delta >= 1.0:
|
||||
_delta = 1.0
|
||||
set_physics_process(false)
|
||||
modulate.a = _delta
|
||||
|
||||
|
||||
func _on_change() -> void:
|
||||
var dt : Array = ["plugin/script_splitter/editor/behaviour/expand_on_focus"
|
||||
,"plugin/script_splitter/editor/behaviour/can_expand_on_same_focus"
|
||||
,"plugin/script_splitter/editor/behaviour/smooth_expand"
|
||||
,"plugin/script_splitter/editor/behaviour/smooth_expand_time"
|
||||
,"plugin/script_splitter/line/size"
|
||||
,"plugin/script_splitter/line/color"
|
||||
,"plugin/script_splitter/line/draggable"
|
||||
,"plugin/script_splitter/line/expand_by_double_click"
|
||||
,"plugin/script_splitter/line/button/size"
|
||||
,"plugin/script_splitter/line/button/modulate"
|
||||
,"plugin/script_splitter/line/button/always_visible"
|
||||
]
|
||||
|
||||
var settings : EditorSettings = EditorInterface.get_editor_settings()
|
||||
var changes : PackedStringArray = settings.get_changed_settings()
|
||||
|
||||
for c in changes:
|
||||
if c in dt:
|
||||
_setup()
|
||||
update()
|
||||
break
|
||||
|
||||
func _setup() -> void:
|
||||
|
||||
var settings : EditorSettings = EditorInterface.get_editor_settings()
|
||||
if !settings.settings_changed.is_connected(_on_change):
|
||||
settings.settings_changed.connect(_on_change)
|
||||
|
||||
for x : Array in [
|
||||
["behaviour_expand_on_focus", "plugin/script_splitter/editor/behaviour/expand_on_focus"]
|
||||
,["behaviour_can_expand_focus_same_container", "plugin/script_splitter/editor/behaviour/can_expand_on_same_focus"]
|
||||
,["behaviour_expand_smoothed", "plugin/script_splitter/editor/behaviour/smooth_expand"]
|
||||
,["drag_button_size", "plugin/script_splitter/editor/behaviour/smooth_expand_time"]
|
||||
,["separator_line_size", "plugin/script_splitter/line/size"]
|
||||
,["separator_line_color", "plugin/script_splitter/line/color"]
|
||||
,["behaviour_can_move_by_line", "plugin/script_splitter/line/draggable"]
|
||||
,["behaviour_expand_on_double_click", "plugin/script_splitter/line/expand_by_double_click"]
|
||||
,["drag_button_size", "plugin/script_splitter/line/button/size"]
|
||||
,["drag_button_modulate", "plugin/script_splitter/line/button/modulate"]
|
||||
,["drag_button_always_visible", "plugin/script_splitter/line/button/always_visible"]
|
||||
]:
|
||||
if settings.has_setting(x[1]):
|
||||
set(x[0], settings.get_setting(x[1]))
|
||||
else:
|
||||
settings.set_setting(x[1], get(x[0]))
|
||||
|
||||
|
||||
func _enter_tree() -> void:
|
||||
add_to_group(&"__ST_CS__")
|
||||
super()
|
||||
|
||||
if __setup:
|
||||
return
|
||||
|
||||
__setup = true
|
||||
|
||||
_setup()
|
||||
|
||||
func _exit_tree() -> void:
|
||||
remove_from_group(&"__ST_CS__")
|
||||
|
||||
var settings : EditorSettings = EditorInterface.get_editor_settings()
|
||||
if settings.settings_changed.is_connected(_on_change):
|
||||
settings.settings_changed.disconnect(_on_change)
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://cl2dnbvuovoro
|
||||
78
addons/script_splitter/core/ui/splitter/taby/dottab.gd
Normal file
78
addons/script_splitter/core/ui/splitter/taby/dottab.gd
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
@tool
|
||||
extends TabBar
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Script Splitter
|
||||
# https://github.com/CodeNameTwister/Script-Splitter
|
||||
#
|
||||
# Script Splitter addon for godot 4
|
||||
# author: "Twister"
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
|
||||
|
||||
signal on_start_drag(t : TabBar)
|
||||
signal on_stop_drag(t : TabBar)
|
||||
|
||||
var is_drag : bool = false:
|
||||
set(e):
|
||||
is_drag = e
|
||||
if is_drag:
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
|
||||
else:
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
||||
|
||||
var _fms : float = 0.0
|
||||
|
||||
func reset() -> void:
|
||||
if is_drag:
|
||||
set_process(false)
|
||||
is_drag = false
|
||||
if is_inside_tree():
|
||||
on_stop_drag.emit(null)
|
||||
|
||||
func _init() -> void:
|
||||
if is_node_ready():
|
||||
_ready()
|
||||
|
||||
func _ready() -> void:
|
||||
set_process(false)
|
||||
setup()
|
||||
|
||||
select_with_rmb = true
|
||||
|
||||
func _enter_tree() -> void:
|
||||
if !is_in_group(&"__SPLITER_TAB__"):
|
||||
add_to_group(&"__SPLITER_TAB__")
|
||||
|
||||
func _exit_tree() -> void:
|
||||
if is_in_group(&"__SPLITER_TAB__"):
|
||||
remove_from_group(&"__SPLITER_TAB__")
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
_fms += delta
|
||||
if _fms > 0.24:
|
||||
if is_drag:
|
||||
if !Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
|
||||
set_process(false)
|
||||
is_drag = false
|
||||
on_stop_drag.emit(self)
|
||||
else:
|
||||
on_start_drag.emit(self)
|
||||
is_drag = true
|
||||
|
||||
func setup() -> void:
|
||||
if !gui_input.is_connected(_on_input):
|
||||
gui_input.connect(_on_input)
|
||||
if !is_in_group(&"__SPLITER_TAB__"):
|
||||
add_to_group(&"__SPLITER_TAB__")
|
||||
|
||||
func _on_input(e : InputEvent) -> void:
|
||||
if e is InputEventMouseButton:
|
||||
if e.button_index == MOUSE_BUTTON_LEFT:
|
||||
is_drag = false
|
||||
if e.pressed:
|
||||
_fms = 0.0
|
||||
set_process(true)
|
||||
else:
|
||||
set_process(false)
|
||||
if _fms >= 0.24:
|
||||
on_stop_drag.emit(self)
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://bbwrffwhmepvw
|
||||
208
addons/script_splitter/core/ui/splitter/taby/overlay.gd
Normal file
208
addons/script_splitter/core/ui/splitter/taby/overlay.gd
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
@tool
|
||||
extends ColorRect
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Script Splitter
|
||||
# https://github.com/CodeNameTwister/Script-Splitter
|
||||
#
|
||||
# Script Splitter addon for godot 4
|
||||
# author: "Twister"
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
const FILE_IN = preload("./../../../../assets/file_in.png")
|
||||
const SPLIT_SELECTION = preload("./../../../../core/ui/splitter/taby/split_selection/SplitSelection.tscn")
|
||||
|
||||
const NORMAL : float = 0.4
|
||||
const FILL : float = 0.65
|
||||
|
||||
var _dt : float = 0.0
|
||||
var _fc : float = 0.0
|
||||
var _ec : float = 1.0
|
||||
|
||||
var _ref : TabBar = null
|
||||
var _container : Control = null
|
||||
var _target : Control = null
|
||||
|
||||
var _split_selection : Control = null
|
||||
|
||||
var _type_split : StringName = &""
|
||||
|
||||
static var _busy : bool = false
|
||||
|
||||
func get_type_split() -> StringName:
|
||||
return _type_split
|
||||
|
||||
func _init() -> void:
|
||||
visible = false
|
||||
mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
z_as_relative = false
|
||||
z_index = RenderingServer.CANVAS_ITEM_Z_MAX - 1
|
||||
|
||||
func start(ref : TabBar) -> void:
|
||||
_fc = NORMAL
|
||||
_ec = FILL
|
||||
_dt = 0.0
|
||||
_ref = ref
|
||||
modulate.a = _fc
|
||||
_target = null
|
||||
|
||||
if is_instance_valid(ref):
|
||||
_container = ref.get_parent()
|
||||
else:
|
||||
_container = null
|
||||
|
||||
_update()
|
||||
set_process(true)
|
||||
|
||||
func _reset() -> void:
|
||||
for x : Node in Engine.get_main_loop().get_nodes_in_group(&"__SCRIPT_SPLITTER__"):
|
||||
if get_parent() != x:
|
||||
reparent(x)
|
||||
break
|
||||
|
||||
static func _free() -> void:
|
||||
var sc : SceneTree = Engine.get_main_loop()
|
||||
if sc:
|
||||
for __ : int in range(0, 5, 1):
|
||||
await sc.process_frame
|
||||
if !is_instance_valid(sc):
|
||||
return
|
||||
_busy = false
|
||||
|
||||
func stop(tab : TabBar = null) -> bool:
|
||||
set_process(false)
|
||||
var out : bool = false
|
||||
if !_busy and mouse_over(_target):
|
||||
set_physics_process(true)
|
||||
_busy = true
|
||||
_type_split = &""
|
||||
_free.call_deferred()
|
||||
if is_instance_valid(tab) and tab == _ref:
|
||||
var container : Node = _ref.get_parent()
|
||||
if is_instance_valid(_container) and _container == container:
|
||||
out = get_global_rect().has_point(get_global_mouse_position())
|
||||
|
||||
for b : Node in _split_selection.get_buttons():
|
||||
if b is Control:
|
||||
if !b.visible:
|
||||
continue
|
||||
if b.get_global_rect().has_point(get_global_mouse_position()):
|
||||
_type_split = b.name
|
||||
break
|
||||
|
||||
visible = false
|
||||
_container = null
|
||||
_target = null
|
||||
return out
|
||||
|
||||
func get_container(ignore_self : bool = true) -> Node:
|
||||
for x : Node in get_tree().get_nodes_in_group(&"__SC_SPLITTER__"):
|
||||
if ignore_self and x == _container:
|
||||
continue
|
||||
var root : Node = x.get_parent()
|
||||
if root is Control:
|
||||
var rect : Rect2 = root.get_global_rect()
|
||||
if rect.has_point(get_global_mouse_position()):
|
||||
return x
|
||||
return null
|
||||
|
||||
func _ready() -> void:
|
||||
color = Color.DARK_GREEN
|
||||
|
||||
set_process(false)
|
||||
set_physics_process(false)
|
||||
visible = false
|
||||
|
||||
set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
|
||||
var cnt : Control = SPLIT_SELECTION.instantiate()
|
||||
|
||||
add_child(cnt)
|
||||
|
||||
cnt.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
cnt.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
cnt.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
|
||||
_split_selection = cnt
|
||||
|
||||
func mouse_over(control: Control) -> bool:
|
||||
if null == control or !control.is_visible_in_tree():
|
||||
return false
|
||||
|
||||
var control_window : Window = control.get_window()
|
||||
|
||||
if control_window.get_window_id() != get_window().get_window_id():
|
||||
return false
|
||||
|
||||
var mp : Vector2i = DisplayServer.mouse_get_position()
|
||||
var mouse_window_id = DisplayServer.get_window_at_screen_position(mp)
|
||||
|
||||
if mouse_window_id != control_window.get_window_id():
|
||||
return false
|
||||
|
||||
return control.get_global_rect().has_point(control.get_global_mouse_position())#mp)
|
||||
|
||||
func _update() -> void:
|
||||
if is_instance_valid(_container):
|
||||
var sc : SceneTree = Engine.get_main_loop()
|
||||
if sc:
|
||||
for x : Node in sc.get_nodes_in_group(&"__SC_SPLITTER__"):
|
||||
if x is Control and mouse_over(x):
|
||||
var same : bool = x == _container
|
||||
|
||||
if same and (!(x is TabContainer) or x.get_child_count() < 2):
|
||||
continue
|
||||
|
||||
if !visible:
|
||||
modulate.a = 0.0
|
||||
_fc = NORMAL
|
||||
_ec = FILL
|
||||
_dt = 0.0
|
||||
visible = true
|
||||
|
||||
size = x.size
|
||||
global_position = x.global_position
|
||||
|
||||
|
||||
for y : Control in _split_selection.get_buttons():
|
||||
y.visible = same
|
||||
|
||||
if _split_selection.file_texture:
|
||||
_split_selection.file_texture.modulate.a = float(!same)
|
||||
|
||||
_target = x
|
||||
return
|
||||
|
||||
_fc = NORMAL
|
||||
_ec = FILL
|
||||
_dt = 0.0
|
||||
modulate.a = _fc
|
||||
_target = null
|
||||
visible = false
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
_update()
|
||||
|
||||
if !visible:
|
||||
return
|
||||
|
||||
_dt += delta * 2.0
|
||||
if _dt >= 1.0:
|
||||
modulate.a = _ec
|
||||
if _ec == FILL:
|
||||
_ec = NORMAL
|
||||
_fc = FILL
|
||||
else:
|
||||
_ec = FILL
|
||||
_fc = NORMAL
|
||||
_dt = 0.0
|
||||
return
|
||||
modulate.a = lerpf(_fc, _ec, _dt)
|
||||
|
||||
func resize() -> void:
|
||||
if !is_inside_tree():
|
||||
await tree_entered
|
||||
|
||||
position = Vector2.ZERO
|
||||
reset_size()
|
||||
size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
#set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://lo116b5bry0t
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
[gd_scene load_steps=10 format=3 uid="uid://8468n431hc6u"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://cffqinddvan8k" path="res://addons/script_splitter/assets/sep_up.svg" id="1_jygbp"]
|
||||
[ext_resource type="Script" uid="uid://bcf6213bhffkm" path="res://addons/script_splitter/core/ui/splitter/taby/split_selection/split_selection.gd" id="1_tifrm"]
|
||||
[ext_resource type="Script" uid="uid://b2jjpfip8pcsf" path="res://addons/script_splitter/core/ui/splitter/taby/split_selection/btn.gd" id="2_tifrm"]
|
||||
[ext_resource type="Texture2D" uid="uid://wp32fwv4flno" path="res://addons/script_splitter/assets/sep_left.svg" id="2_ttdhj"]
|
||||
[ext_resource type="Texture2D" uid="uid://cxds5tr6aq5v3" path="res://addons/script_splitter/assets/file_in.png" id="2_w45p2"]
|
||||
[ext_resource type="Texture2D" uid="uid://d1ee2fk3y8n83" path="res://addons/script_splitter/assets/sep_right.svg" id="3_tifrm"]
|
||||
[ext_resource type="Texture2D" uid="uid://dt830c42xmul5" path="res://addons/script_splitter/assets/sep_bottom.svg" id="4_jevbt"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_w45p2"]
|
||||
bg_color = Color(0.09320182, 0.57214785, 0.68215865, 0.5)
|
||||
border_width_left = 2
|
||||
border_width_top = 2
|
||||
border_width_right = 2
|
||||
border_width_bottom = 8
|
||||
border_color = Color(0.047066845, 0.37056562, 0.44495192, 0.5019608)
|
||||
border_blend = true
|
||||
corner_radius_top_left = 16
|
||||
corner_radius_top_right = 16
|
||||
corner_radius_bottom_right = 16
|
||||
corner_radius_bottom_left = 16
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_2cbhf"]
|
||||
content_margin_left = 4.0
|
||||
content_margin_top = 4.0
|
||||
content_margin_right = 4.0
|
||||
content_margin_bottom = 4.0
|
||||
bg_color = Color(0, 0.91349006, 0.47941613, 0.5019608)
|
||||
border_color = Color(4.813075e-07, 0.57995814, 0.19868338, 0.5019608)
|
||||
corner_radius_top_left = 8
|
||||
corner_radius_top_right = 8
|
||||
corner_radius_bottom_right = 8
|
||||
corner_radius_bottom_left = 8
|
||||
|
||||
[node name="SplitSelection" type="AspectRatioContainer" node_paths=PackedStringArray("file_texture")]
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -108.0
|
||||
offset_top = -108.0
|
||||
offset_right = 108.0
|
||||
offset_bottom = 108.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_tifrm")
|
||||
file_texture = NodePath("VB/HB/TextureRect")
|
||||
|
||||
[node name="VB" type="VBoxContainer" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
theme_override_constants/separation = 12
|
||||
|
||||
[node name="TOP" type="Button" parent="VB"]
|
||||
custom_minimum_size = Vector2(64, 64)
|
||||
layout_mode = 2
|
||||
focus_mode = 0
|
||||
theme_override_styles/normal = SubResource("StyleBoxFlat_w45p2")
|
||||
theme_override_styles/hover = SubResource("StyleBoxFlat_2cbhf")
|
||||
icon = ExtResource("1_jygbp")
|
||||
icon_alignment = 1
|
||||
script = ExtResource("2_tifrm")
|
||||
|
||||
[node name="HB" type="HBoxContainer" parent="VB"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 12
|
||||
|
||||
[node name="LEFT" type="Button" parent="VB/HB"]
|
||||
custom_minimum_size = Vector2(64, 64)
|
||||
layout_mode = 2
|
||||
focus_mode = 0
|
||||
theme_override_styles/normal = SubResource("StyleBoxFlat_w45p2")
|
||||
theme_override_styles/hover = SubResource("StyleBoxFlat_2cbhf")
|
||||
icon = ExtResource("2_ttdhj")
|
||||
icon_alignment = 1
|
||||
script = ExtResource("2_tifrm")
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="VB/HB"]
|
||||
custom_minimum_size = Vector2(64, 64)
|
||||
layout_mode = 2
|
||||
texture = ExtResource("2_w45p2")
|
||||
expand_mode = 3
|
||||
stretch_mode = 5
|
||||
|
||||
[node name="RIGHT" type="Button" parent="VB/HB"]
|
||||
custom_minimum_size = Vector2(64, 64)
|
||||
layout_mode = 2
|
||||
focus_mode = 0
|
||||
theme_override_styles/normal = SubResource("StyleBoxFlat_w45p2")
|
||||
theme_override_styles/hover = SubResource("StyleBoxFlat_2cbhf")
|
||||
icon = ExtResource("3_tifrm")
|
||||
icon_alignment = 1
|
||||
script = ExtResource("2_tifrm")
|
||||
|
||||
[node name="BOTTOM" type="Button" parent="VB"]
|
||||
custom_minimum_size = Vector2(64, 64)
|
||||
layout_mode = 2
|
||||
focus_mode = 0
|
||||
theme_override_styles/normal = SubResource("StyleBoxFlat_w45p2")
|
||||
theme_override_styles/hover = SubResource("StyleBoxFlat_2cbhf")
|
||||
icon = ExtResource("4_jevbt")
|
||||
icon_alignment = 1
|
||||
script = ExtResource("2_tifrm")
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
@tool
|
||||
extends Button
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Script Splitter
|
||||
# https://github.com/CodeNameTwister/Script-Splitter
|
||||
#
|
||||
# Script Splitter addon for godot 4
|
||||
# author: "Twister"
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
|
||||
func _ready() -> void:
|
||||
owner.add_button(self)
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://b2jjpfip8pcsf
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
[gd_resource type="StyleBoxFlat" format=3 uid="uid://cv7c0vox6s5ug"]
|
||||
|
||||
[resource]
|
||||
content_margin_left = 4.0
|
||||
content_margin_top = 4.0
|
||||
content_margin_right = 4.0
|
||||
content_margin_bottom = 4.0
|
||||
bg_color = Color(0, 0, 0, 0.6)
|
||||
corner_radius_top_left = 3
|
||||
corner_radius_top_right = 3
|
||||
corner_radius_bottom_right = 3
|
||||
corner_radius_bottom_left = 3
|
||||
corner_detail = 5
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
@tool
|
||||
extends Control
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Script Splitter
|
||||
# https://github.com/CodeNameTwister/Script-Splitter
|
||||
#
|
||||
# Script Splitter addon for godot 4
|
||||
# author: "Twister"
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
@export var file_texture : TextureRect = null
|
||||
var _btns : Array[Button] = []
|
||||
|
||||
func get_buttons() -> Array[Button]:
|
||||
return _btns
|
||||
|
||||
func add_button(b : Button) -> void:
|
||||
_btns.append(b)
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://bcf6213bhffkm
|
||||
Loading…
Add table
Add a link
Reference in a new issue