first commit

This commit is contained in:
2025-07-20 10:34:21 +02:00
commit a5634c4619
812 changed files with 61126 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cxds5tr6aq5v3"
path="res://.godot/imported/dd.png-3704eaaffe380d5ad414e6e7fce28e96.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/script_spliter/assets/dd.png"
dest_files=["res://.godot/imported/dd.png-3704eaaffe380d5ad414e6e7fce28e96.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://tgaoyybc2iji"
path="res://.godot/imported/github_CodeNameTwister.png-88287e5d04f5b5c67334953a8a4ce6f2.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/script_spliter/assets/github_CodeNameTwister.png"
dest_files=["res://.godot/imported/github_CodeNameTwister.png-88287e5d04f5b5c67334953a8a4ce6f2.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#e0e0e0" d="M4 1 3 3l1 2v4H2v3.5a2.5 2.5 0 0 0 5 0V9H5V5l1-2-1-2zm6 .174a3 3 0 0 0 0 5.652V14a1 1 0 0 0 2 0V6.824a3 3 0 0 0 0-5.648V4a1 1 0 0 1-2 0z"/></svg>

After

Width:  |  Height:  |  Size: 233 B

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bmhixx87f787y"
path="res://.godot/imported/tab_icon.svg-1187d0207b55f861d54b7b960e0aafec.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/script_spliter/assets/tab_icon.svg"
dest_files=["res://.godot/imported/tab_icon.svg-1187d0207b55f861d54b7b960e0aafec.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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,4 @@
@warning_ignore("empty_file")
# This script is only placeholder for handle pop script input.
# This should closed and removed after closing the pop-up.

View File

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

View File

@@ -0,0 +1,17 @@
@tool
extends Button
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Script Spliter
# https://github.com/CodeNameTwister/Script-Spliter
#
# Script Spliter addon for godot 4
# author: "Twister"
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
func _pressed() -> void:
var parent : Node = owner
if parent == null:
parent = get_parent()
if parent:
if parent.has_method(name):
parent.call(name)

View File

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

View File

@@ -0,0 +1,36 @@
@tool
extends EditorContextMenuPlugin
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Script Spliter
# https://github.com/CodeNameTwister/Script-Spliter
#
# Script Spliter addon for godot 4
# author: "Twister"
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
var CONTEXT : String = "CUSTOM"
var ICON : Texture = null
var SHORTCUT : Shortcut = null
var CALLABLE : Callable
var VALIDATOR : Callable
func _init(context : String, handle : Callable, validator : Callable, icon : Texture, input_key : Array[InputEvent] = []):
CONTEXT = context
CALLABLE = handle
ICON = icon
VALIDATOR = validator
if input_key.size() > 0:
SHORTCUT = Shortcut.new()
SHORTCUT.events = input_key
add_menu_shortcut(SHORTCUT, handle)
func _popup_menu(paths : PackedStringArray):
if VALIDATOR.is_valid():
if !VALIDATOR.call(paths):
return
if SHORTCUT:
add_context_menu_item_from_shortcut(CONTEXT, SHORTCUT, ICON)
else:
if CALLABLE.is_valid():
add_context_menu_item(CONTEXT, CALLABLE, ICON)
else:
push_error("Not valid callaback!")

View File

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

View File

@@ -0,0 +1,22 @@
@tool
extends Control
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Script Spliter
# https://github.com/CodeNameTwister/Script-Spliter
#
# Script Spliter addon for godot 4
# author: "Twister"
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@export var columns : SpinBox
@export var rows : SpinBox
func set_values(_columns : int, _rows : int) -> void:
columns.value = _columns
rows.value = _rows
func get_columns_value() -> int:
return max(columns.value, 1)
func get_rows_value() -> int:
return max(rows.value, 1)

View File

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

View File

@@ -0,0 +1,177 @@
@tool
extends Window
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Script Spliter
# https://github.com/CodeNameTwister/Script-Spliter
#
# Script Spliter addon for godot 4f
# author: "Twister"
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
signal on_close(window : Window)
@export var _container : Control = null
@export var _base_control : TabContainer = null
@export var _always_top : Button = null
@export var _close : Button = null
@export var _root : Control = null
var proxy : Control = null
var replacer : Node = null
var controller : Object = null
func set_base_control(node : Node) -> void:
if _base_control:
_base_control.queue_sort()
_base_control = node
if _container:
_container.add_child(node)
return
add_child(node)
if node is Control:
node.size = node.get_parent().size
func get_base_control() -> TabContainer:
return _base_control
func _init() -> void:
visible = false
close_requested.connect(_on_close)
visibility_changed.connect(_on_visibility)
focus_entered.connect(_on_focus)
focus_exited.connect(_on_focus_exited)
func _get_edit(n : Node) -> CodeEdit:
if n is CodeEdit:
return n
for x : Node in n.get_children():
return _get_edit(x)
return null
func _on_focus() -> void:
if replacer == null:
var script_editor: ScriptEditor = EditorInterface.get_script_editor()
var root : Node = script_editor.get_child(0).get_child(1).get_child(1)
if root.get_child_count() > 2:
replacer = root.get_child(2)
if "FindReplaceBar" in replacer.name:
replacer.get_parent().remove_child(replacer)
if is_instance_valid(_root):
_root.add_child(replacer)
else:
add_child(replacer)
if is_instance_valid(controller):
controller.emit_signal.call_deferred(&"focus", controller)
func _update_name() -> void:
if is_queued_for_deletion():
return
if is_instance_valid(_base_control):
if _base_control.current_tab > -1:
title = "Script-Spliter: {0}".format([_base_control.get_tab_title(_base_control.current_tab)])
return
title = "Script-Spliter: Pop Script"
func _on_tabity(__ : int) -> void:
_update_name.call_deferred()
func _on_always_top() -> void:
if transient:
return
always_on_top = !always_on_top
func _shortcut_input(event: InputEvent) -> void:
if is_instance_valid(proxy):
var vp : Viewport = proxy.get_viewport()
if vp and vp != get_viewport():
vp.push_input(event)
func _ready() -> void:
set_process_shortcut_input(true)
if _always_top:
if !_always_top.pressed.is_connected(_on_always_top):
_always_top.pressed.connect(_on_always_top)
if _close:
if !_close.pressed.is_connected(_on_close):
_close.pressed.connect(_on_close)
if _base_control:
if !_base_control.tab_changed.is_connected(_on_tabity):
_base_control.tab_changed.connect(_on_tabity)
if !_base_control.child_entered_tree.is_connected(_on_child):
_base_control.child_entered_tree.connect(_on_child)
if !_base_control.child_exiting_tree.is_connected(_out_child):
_base_control.child_exiting_tree.connect(_out_child)
var root : Control = EditorInterface.get_base_control()
if root:
add_theme_stylebox_override(&"Panel",root.get_theme_stylebox("panel", "PanelContainer"))
func _connect(n : Node, e : bool) -> void:
if n is CodeEdit:
if e:
if !n.focus_entered.is_connected(_on_focus):
n.focus_entered.connect(_on_focus)
else:
if n.focus_entered.is_connected(_on_focus):
n.focus_entered.disconnect(_on_focus)
return
for x : Node in n.get_children():
_connect(x, e)
func _on_child(n : Node) -> void:
if n is Control:
_connect(n, true)
func _out_child(n : Node) -> void:
if n is Control:
_connect(n, false)
func _on_visibility() -> void:
if !visible:
_on_focus_exited()
_on_close()
return
set_deferred(&"always_top", false)
set_process(true)
_update_name.call_deferred()
func _on_close() -> void:
on_close.emit(self)
if _base_control and _base_control.get_child_count() < 1:
queue_free()
func _on_focus_exited() -> void:
if replacer != null:
var script_editor: ScriptEditor = EditorInterface.get_script_editor()
var root : Node = script_editor.get_child(0).get_child(1).get_child(1)
var parent : Node = replacer.get_parent()
if parent != root:
if is_instance_valid(parent):
parent.remove_child(replacer)
root.add_child(replacer)
replacer = null
func _notification(what: int) -> void:
if what == NOTIFICATION_PREDELETE:
if is_instance_valid(replacer):
var script_editor: ScriptEditor = EditorInterface.get_script_editor()
var root : Node = script_editor.get_child(0).get_child(1).get_child(1)
var parent : Node = replacer.get_parent()
if parent != root:
if is_instance_valid(parent):
parent.remove_child(replacer)
root.add_child(replacer)
replacer = null
if is_instance_valid(controller):
controller.call(&"reset")
func _move_to_center() -> void:
move_to_center()
func _alpha_value(v : float) -> void:
get_child(0).modulate.a = v

View File

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

View File

@@ -0,0 +1,69 @@
[gd_scene load_steps=5 format=3 uid="uid://cr2xovtt6uo7s"]
[ext_resource type="Script" uid="uid://dbkyfe5ri2p73" path="res://addons/script_spliter/context/flying_script.gd" id="1_wfm3d"]
[ext_resource type="Texture2D" uid="uid://r6u1jtnbr4eg" path="res://addons/script_spliter/context/icons/atop.png" id="2_q3d74"]
[ext_resource type="Script" uid="uid://bo38caobn2x7a" path="res://addons/script_spliter/context/btn_callback.gd" id="3_1p1sv"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_q3d74"]
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="FlyingScript" type="Window" node_paths=PackedStringArray("_container", "_always_top", "_close", "_root")]
title = "Script-Spliter: Pop Script"
initial_position = 4
size = Vector2i(805, 512)
visible = false
wrap_controls = true
script = ExtResource("1_wfm3d")
_container = NodePath("PanelContainer/VC")
_always_top = NodePath("PanelContainer/VC/HB/AlwaysTop")
_close = NodePath("PanelContainer/VC/HB/Close")
_root = NodePath("PanelContainer/VC")
[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_q3d74")
[node name="VC" type="VBoxContainer" parent="PanelContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="HB" type="HBoxContainer" parent="PanelContainer/VC"]
layout_mode = 2
theme_override_constants/separation = 8
[node name="AlwaysTop" type="Button" parent="PanelContainer/VC/HB"]
layout_mode = 2
tooltip_text = "Set always front visible the current window"
theme_override_font_sizes/font_size = 12
toggle_mode = true
text = "Always Top"
icon = ExtResource("2_q3d74")
flat = true
[node name="_move_to_center" type="Button" parent="PanelContainer/VC/HB"]
layout_mode = 2
tooltip_text = "Move the window to center"
theme_override_font_sizes/font_size = 12
toggle_mode = true
text = "Move To Center"
flat = true
script = ExtResource("3_1p1sv")
[node name="Close" type="Button" parent="PanelContainer/VC/HB"]
visible = false
custom_minimum_size = Vector2(32, 0)
layout_mode = 2
size_flags_horizontal = 10
tooltip_text = "Close the window"
text = "X"

View File

@@ -0,0 +1,4 @@
[gd_resource type="LabelSettings" format=3 uid="uid://cdrt4b0qrb77v"]
[resource]
font_size = 12

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://r6u1jtnbr4eg"
path="res://.godot/imported/atop.png-1d61cb69aae60a076cd60a0a3f1cc72c.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/script_spliter/context/icons/atop.png"
dest_files=["res://.godot/imported/atop.png-1d61cb69aae60a076cd60a0a3f1cc72c.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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

View File

@@ -0,0 +1,9 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
<svg fill="#ffffff" width="64px" height="64px" viewBox="0 0 24.00 24.00" xmlns="http://www.w3.org/2000/svg" stroke="#ffffff" stroke-width="0.00024000000000000003" transform="rotate(0)">
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>

After

Width:  |  Height:  |  Size: 591 B

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cractge21enk"
path="res://.godot/imported/expand.svg-963ea7d55c7ac4362bba429ef9c40e46.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/script_spliter/context/icons/expand.svg"
dest_files=["res://.godot/imported/expand.svg-963ea7d55c7ac4362bba429ef9c40e46.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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

Binary file not shown.

After

Width:  |  Height:  |  Size: 584 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c1kjfqirfexvp"
path="res://.godot/imported/sp_2H.png-c589a7f8579a9ee26d2875c35e52e183.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/script_spliter/context/icons/sp_2H.png"
dest_files=["res://.godot/imported/sp_2H.png-c589a7f8579a9ee26d2875c35e52e183.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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

Binary file not shown.

After

Width:  |  Height:  |  Size: 640 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://d1r72ixdgbwl6"
path="res://.godot/imported/sp_2V.png-39915ece37e791e8d9a130c4c3240f49.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/script_spliter/context/icons/sp_2V.png"
dest_files=["res://.godot/imported/sp_2V.png-39915ece37e791e8d9a130c4c3240f49.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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

Binary file not shown.

After

Width:  |  Height:  |  Size: 637 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://32xnl4cu46pj"
path="res://.godot/imported/sp_3H.png-09e8b9f9a346f328495f443e565ad878.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/script_spliter/context/icons/sp_3H.png"
dest_files=["res://.godot/imported/sp_3H.png-09e8b9f9a346f328495f443e565ad878.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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

Binary file not shown.

After

Width:  |  Height:  |  Size: 687 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b4cmfno0ixqnm"
path="res://.godot/imported/sp_3V.png-6984dd1b3c8e11f26b5964981b46a4b8.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/script_spliter/context/icons/sp_3V.png"
dest_files=["res://.godot/imported/sp_3V.png-6984dd1b3c8e11f26b5964981b46a4b8.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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

Binary file not shown.

After

Width:  |  Height:  |  Size: 572 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bf2bjkoock7re"
path="res://.godot/imported/sp_4S.png-38dbb9b7da5a9846aab652bf564a4249.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/script_spliter/context/icons/sp_4S.png"
dest_files=["res://.godot/imported/sp_4S.png-38dbb9b7da5a9846aab652bf564a4249.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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

Binary file not shown.

After

Width:  |  Height:  |  Size: 847 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bdxvp5dyj8y0r"
path="res://.godot/imported/sp_custom.png-91b7ef0ad7d63ebf7700a2047739db70.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/script_spliter/context/icons/sp_custom.png"
dest_files=["res://.godot/imported/sp_custom.png-91b7ef0ad7d63ebf7700a2047739db70.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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

Binary file not shown.

After

Width:  |  Height:  |  Size: 755 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dmvcijsjhb5pc"
path="res://.godot/imported/sp_disable.png-d75c06feba36dd2af819e235b22c2ea6.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/script_spliter/context/icons/sp_disable.png"
dest_files=["res://.godot/imported/sp_disable.png-d75c06feba36dd2af819e235b22c2ea6.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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

View File

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg
fill="#000000"
width="16"
height="16"
viewBox="0 0 0.64 0.64"
id="icon"
version="1.1"
sodipodi:docname="split_minus.svg"
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
inkscape:export-filename="split_rminus.svg"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<sodipodi:namedview
id="namedview2"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:zoom="2"
inkscape:cx="35.5"
inkscape:cy="58.25"
inkscape:window-width="1287"
inkscape:window-height="745"
inkscape:window-x="65"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="icon">
<inkscape:page
x="0"
y="0"
width="0.63999999"
height="0.63999999"
id="page2"
margin="0"
bleed="0" />
</sodipodi:namedview>
<defs
id="defs1">
<style
id="style1">.cls-1{fill:none;}</style>
</defs>
<title
id="title1">split-screen</title>
<path
d="M 0.18934054,0.07454552 V 0.5654545 H 0.06233516 V 0.07454552 h 0.12700536 m 0,-0.0545455 H 0.06233516 A 0.04233513,0.05454544 0 0 0 0.02000003,0.07454552 V 0.5654545 A 0.04233513,0.05454544 0 0 0 0.06233515,0.62 H 0.18934049 A 0.04233513,0.05454544 0 0 0 0.23167569,0.5654545 V 0.07454552 a 0.04233513,0.05454544 0 0 0 -0.0423352,-0.0545455 z"
id="path1"
style="fill:#00ffff;fill-opacity:1;stroke-width:0.0255591;stroke-dasharray:none" />
<path
d="M 0.57766491,0.07454552 V 0.5654545 H 0.45065951 V 0.07454552 h 0.12700538 m 0,-0.0545455 H 0.45065951 a 0.04233513,0.05454544 0 0 0 -0.0423351,0.0545455 V 0.5654545 A 0.04233513,0.05454544 0 0 0 0.45065951,0.62 H 0.57766488 A 0.04233513,0.05454544 0 0 0 0.61999998,0.5654545 V 0.07454552 a 0.04233513,0.05454544 0 0 0 -0.0423351,-0.0545455 z"
id="path2"
style="fill:#00ffff;stroke-width:0.0240271" />
<rect
x="-0.38090447"
y="0.050016876"
width="0.11920302"
height="0.53915524"
id="rect1-9-5"
style="fill:#ff0000;stroke-width:0.0416635"
ry="0.066325948"
transform="rotate(-90)" />
<metadata
id="metadata2">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:title>split-screen</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c1b7aoplxr0x7"
path="res://.godot/imported/split_cminus.svg-3d236e355acd272b8108cca3f8e1c7f3.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/script_spliter/context/icons/split_cminus.svg"
dest_files=["res://.godot/imported/split_cminus.svg-3d236e355acd272b8108cca3f8e1c7f3.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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=8.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg
fill="#000000"
width="16"
height="16"
viewBox="0 0 0.64 0.64"
id="icon"
version="1.1"
sodipodi:docname="split_minus.svg"
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
inkscape:export-filename="split_cminus.svg"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<sodipodi:namedview
id="namedview2"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:zoom="2"
inkscape:cx="35.5"
inkscape:cy="58.25"
inkscape:window-width="1287"
inkscape:window-height="745"
inkscape:window-x="65"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="icon">
<inkscape:page
x="0"
y="0"
width="0.63999999"
height="0.63999999"
id="page2"
margin="0"
bleed="0" />
</sodipodi:namedview>
<defs
id="defs1">
<style
id="style1">.cls-1{fill:none;}</style>
</defs>
<title
id="title1">split-screen</title>
<path
d="M 0.18934054,0.07454552 V 0.5654545 H 0.06233516 V 0.07454552 h 0.12700536 m 0,-0.0545455 H 0.06233516 A 0.04233513,0.05454544 0 0 0 0.02000003,0.07454552 V 0.5654545 A 0.04233513,0.05454544 0 0 0 0.06233515,0.62 H 0.18934049 A 0.04233513,0.05454544 0 0 0 0.23167569,0.5654545 V 0.07454552 a 0.04233513,0.05454544 0 0 0 -0.0423352,-0.0545455 z"
id="path1"
style="fill:#00ffff;fill-opacity:1;stroke-width:0.0255591;stroke-dasharray:none" />
<path
d="M 0.57766491,0.07454552 V 0.5654545 H 0.45065951 V 0.07454552 h 0.12700538 m 0,-0.0545455 H 0.45065951 a 0.04233513,0.05454544 0 0 0 -0.0423351,0.0545455 V 0.5654545 A 0.04233513,0.05454544 0 0 0 0.45065951,0.62 H 0.57766488 A 0.04233513,0.05454544 0 0 0 0.61999998,0.5654545 V 0.07454552 a 0.04233513,0.05454544 0 0 0 -0.0423351,-0.0545455 z"
id="path2"
style="fill:#00ffff;stroke-width:0.0240271" />
<rect
x="-0.38090447"
y="0.050016876"
width="0.11920302"
height="0.53915524"
id="rect1-9-5"
style="fill:#00ff00;stroke-width:0.0416635"
ry="0.066325948"
transform="rotate(-90)" />
<rect
x="0.26039848"
y="-0.60000002"
width="0.11920302"
height="0.53915524"
id="rect1-9-5-1"
style="fill:#00ff00;stroke-width:0.0416635"
ry="0.066325948"
transform="scale(1,-1)" />
<metadata
id="metadata2">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:title>split-screen</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bvyjqo1dus1xu"
path="res://.godot/imported/split_cplus.svg-5f233626ec643447e303aa2d98ed8d14.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/script_spliter/context/icons/split_cplus.svg"
dest_files=["res://.godot/imported/split_cplus.svg-5f233626ec643447e303aa2d98ed8d14.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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=8.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg
fill="#000000"
width="16"
height="16"
viewBox="0 0 0.64 0.64"
id="icon"
version="1.1"
sodipodi:docname="split_minus.svg"
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
inkscape:export-filename="split_rminus.svg"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<sodipodi:namedview
id="namedview2"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:zoom="2"
inkscape:cx="35.5"
inkscape:cy="58.25"
inkscape:window-width="1287"
inkscape:window-height="745"
inkscape:window-x="65"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="icon">
<inkscape:page
x="0"
y="0"
width="0.63999999"
height="0.63999999"
id="page2"
margin="0"
bleed="0" />
</sodipodi:namedview>
<defs
id="defs1">
<style
id="style1">.cls-1{fill:none;}</style>
</defs>
<title
id="title1">split-screen</title>
<path
d="M 0.56545451,0.18934056 H 0.07454553 V 0.06233518 h 0.49090898 v 0.12700536 m 0.0545455,0 V 0.06233518 A 0.05454544,0.04233513 0 0 0 0.56545451,0.02000005 H 0.07454553 A 0.05454544,0.04233513 0 0 0 0.02,0.06233517 v 0.12700534 a 0.05454544,0.04233513 0 0 0 0.05454553,0.0423352 h 0.49090898 a 0.05454544,0.04233513 0 0 0 0.0545455,-0.0423352 z"
id="path1"
style="fill:#00ffff;fill-opacity:1;stroke-width:0.0255591;stroke-dasharray:none" />
<path
d="M 0.56545451,0.57766493 H 0.07454553 v -0.1270054 h 0.49090898 v 0.12700538 m 0.0545455,0 V 0.45065953 A 0.05454544,0.04233513 0 0 0 0.56545451,0.40832438 H 0.07454553 A 0.05454544,0.04233513 0 0 0 0.02,0.45065953 V 0.5776649 A 0.05454544,0.04233513 0 0 0 0.07454553,0.62 h 0.49090898 a 0.05454544,0.04233513 0 0 0 0.0545455,-0.0423351 z"
id="path2"
style="fill:#00ffff;stroke-width:0.0240271" />
<rect
x="-0.38090447"
y="0.050016876"
width="0.11920302"
height="0.53915524"
id="rect1-9-5"
style="fill:#ff0000;stroke-width:0.0416635"
ry="0.066325948"
transform="rotate(-90)" />
<metadata
id="metadata2">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:title>split-screen</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bvjk4po8w2m2j"
path="res://.godot/imported/split_rminus.svg-6f9fc75a64032d6fe5bdcc9bc3bf399d.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/script_spliter/context/icons/split_rminus.svg"
dest_files=["res://.godot/imported/split_rminus.svg-6f9fc75a64032d6fe5bdcc9bc3bf399d.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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=8.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg
fill="#000000"
width="16"
height="16"
viewBox="0 0 0.64 0.64"
id="icon"
version="1.1"
sodipodi:docname="split_minus.svg"
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
inkscape:export-filename="split_cplus.svg"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<sodipodi:namedview
id="namedview2"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:zoom="2"
inkscape:cx="35.5"
inkscape:cy="58.25"
inkscape:window-width="1287"
inkscape:window-height="745"
inkscape:window-x="65"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="icon">
<inkscape:page
x="0"
y="0"
width="0.63999999"
height="0.63999999"
id="page2"
margin="0"
bleed="0" />
</sodipodi:namedview>
<defs
id="defs1">
<style
id="style1">.cls-1{fill:none;}</style>
</defs>
<title
id="title1">split-screen</title>
<path
d="M 0.5654545,0.18934055 H 0.07454552 V 0.06233517 H 0.5654545 v 0.12700536 m 0.0545455,0 V 0.06233517 A 0.05454544,0.04233513 0 0 0 0.5654545,0.02000004 H 0.07454552 A 0.05454544,0.04233513 0 0 0 0.02000002,0.06233516 V 0.1893405 a 0.05454544,0.04233513 0 0 0 0.0545455,0.0423352 H 0.5654545 A 0.05454544,0.04233513 0 0 0 0.62,0.18934053 Z"
id="path1"
style="fill:#00ffff;fill-opacity:1;stroke-width:0.0255591;stroke-dasharray:none" />
<path
d="M 0.5654545,0.57766492 H 0.07454552 V 0.45065952 H 0.5654545 V 0.5776649 m 0.0545455,0 V 0.45065952 A 0.05454544,0.04233513 0 0 0 0.5654545,0.40832442 H 0.07454552 a 0.05454544,0.04233513 0 0 0 -0.0545455,0.0423351 v 0.12700537 a 0.05454544,0.04233513 0 0 0 0.0545455,0.0423351 H 0.5654545 A 0.05454544,0.04233513 0 0 0 0.62,0.5776649 Z"
id="path2"
style="fill:#00ffff;stroke-width:0.0240271" />
<rect
x="-0.38090447"
y="0.050016876"
width="0.11920302"
height="0.53915524"
id="rect1-9-5"
style="fill:#00ff00;stroke-width:0.0416635"
ry="0.066325948"
transform="rotate(-90)" />
<rect
x="0.26039848"
y="-0.60000002"
width="0.11920302"
height="0.53915524"
id="rect1-9-5-1"
style="fill:#00ff00;stroke-width:0.0416635"
ry="0.066325948"
transform="scale(1,-1)" />
<metadata
id="metadata2">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:title>split-screen</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://1sqajw0mikdj"
path="res://.godot/imported/split_rplus.svg-a26b8d20ca41f0ec060d5e021092eced.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/script_spliter/context/icons/split_rplus.svg"
dest_files=["res://.godot/imported/split_rplus.svg-a26b8d20ca41f0ec060d5e021092eced.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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=8.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1,81 @@
@tool
extends Window
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Script Spliter
# https://github.com/CodeNameTwister/Script-Spliter
#
# Script Spliter addon for godot 4
# author: "Twister"
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@export var _container : Node
@export var _custom_options : Control
var _plugin : Object = null
func _init_1() -> void:
if _container and _plugin:
var columns : int = _plugin.call(&"get_split_columns")
var rows : int = _plugin.call(&"get_split_rows")
set_split_value(columns, rows)
func _ready() -> void:
if _custom_options:
_custom_options.visible = false
if !visibility_changed.is_connected(_on_visibility_change):
visibility_changed.connect(_on_visibility_change)
_init_1()
func set_plugin(current_plugin : Object) -> void:
_plugin = current_plugin
func _on_visibility_change() -> void:
if !visible: return
if !_plugin:
return
_init_1()
func enable_options() -> void:
var custom : CheckBox = _container.get_child(_container.get_child_count() - 1)
for c : Node in _container.get_children():
if c is CheckBox:
c.button_pressed = false
_custom_options.visible = true
custom.button_pressed = true
func set_split_value(columns : int, rows : int) -> void:
var current : Node = null
var custom : CheckBox = _container.get_child(_container.get_child_count() - 1)
for c : Node in _container.get_children():
if c is CheckBox:
if c.columns == columns and c.rows == rows:
current = c
c.button_pressed = true
continue
c.button_pressed = false
if columns < 2 and rows < 2:
current = _container.get_child(0)
if current is CheckBox:
current.button_pressed = true
else:
current = null
_custom_options.visible = current == null
custom.button_pressed = _custom_options.visible
_custom_options.set_values(columns, rows)
func _on_ok_pressed() -> void:
var columns : int = _custom_options.get_columns_value()
var rows : int = _custom_options.get_rows_value()
if !_plugin:
push_error("[ERROR] Can not set split type!")
else:
_plugin.call(&"set_type_split", columns, rows)
hide()
func _on_cancel_pressed() -> void:
hide()

View File

@@ -0,0 +1 @@
uid://4wllvh127dwh

View File

@@ -0,0 +1,226 @@
[gd_scene load_steps=15 format=3 uid="uid://csu7djr8m1mgb"]
[ext_resource type="Script" uid="uid://4wllvh127dwh" path="res://addons/script_spliter/context/menu_tool.gd" id="1_00j1l"]
[ext_resource type="Texture2D" uid="uid://tgaoyybc2iji" path="res://addons/script_spliter/assets/github_CodeNameTwister.png" id="2_bi1if"]
[ext_resource type="Texture2D" uid="uid://dmvcijsjhb5pc" path="res://addons/script_spliter/context/icons/sp_disable.png" id="2_le2a0"]
[ext_resource type="Script" uid="uid://bobw4q6hrbbox" path="res://addons/script_spliter/context/split_type_button.gd" id="3_h7rbp"]
[ext_resource type="Texture2D" uid="uid://c1kjfqirfexvp" path="res://addons/script_spliter/context/icons/sp_2H.png" id="3_o7fne"]
[ext_resource type="Texture2D" uid="uid://d1r72ixdgbwl6" path="res://addons/script_spliter/context/icons/sp_2V.png" id="4_js2dr"]
[ext_resource type="Texture2D" uid="uid://32xnl4cu46pj" path="res://addons/script_spliter/context/icons/sp_3H.png" id="5_h32ac"]
[ext_resource type="Texture2D" uid="uid://b4cmfno0ixqnm" path="res://addons/script_spliter/context/icons/sp_3V.png" id="6_h7rbp"]
[ext_resource type="Texture2D" uid="uid://bf2bjkoock7re" path="res://addons/script_spliter/context/icons/sp_4S.png" id="7_bi1if"]
[ext_resource type="Texture2D" uid="uid://bdxvp5dyj8y0r" path="res://addons/script_spliter/context/icons/sp_custom.png" id="10_0n25h"]
[ext_resource type="Script" uid="uid://y3jbguu2nw5c" path="res://addons/script_spliter/context/custom_options.gd" id="11_2o3ku"]
[sub_resource type="LabelSettings" id="LabelSettings_00j1l"]
font_size = 28
outline_size = 4
outline_color = Color(0, 0, 0, 1)
[sub_resource type="LabelSettings" id="LabelSettings_2o3ku"]
font_size = 12
font_color = Color(1, 1, 1, 0.4)
[sub_resource type="LabelSettings" id="LabelSettings_0n25h"]
font_size = 12
[node name="MenuTool" type="PopupPanel" node_paths=PackedStringArray("_container", "_custom_options")]
title = "Script Splitter Menu"
position = Vector2i(0, 36)
size = Vector2i(602, 382)
visible = true
script = ExtResource("1_00j1l")
_container = NodePath("MarginContainer/MenContainer/Body")
_custom_options = NodePath("MarginContainer/MenContainer/COptions")
[node name="BG" type="ColorRect" parent="."]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 4.0
offset_top = 4.0
offset_right = -4.0
offset_bottom = -4.0
grow_horizontal = 2
grow_vertical = 2
color = Color(0.249011, 0.114569, 0.435571, 1)
[node name="BGTX" type="TextureRect" parent="."]
modulate = Color(1, 1, 1, 0.34902)
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 4.0
offset_top = 4.0
offset_right = -4.0
offset_bottom = -4.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("2_bi1if")
stretch_mode = 3
[node name="MarginContainer" type="MarginContainer" parent="."]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 4.0
offset_top = 4.0
offset_right = -4.0
offset_bottom = -4.0
grow_horizontal = 2
grow_vertical = 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="MenContainer" type="VBoxContainer" parent="MarginContainer"]
layout_mode = 2
[node name="PanelContainer2" type="PanelContainer" parent="MarginContainer/MenContainer"]
layout_mode = 2
[node name="Tittle" type="Label" parent="MarginContainer/MenContainer/PanelContainer2"]
layout_mode = 2
text = "Menu Split Selection"
label_settings = SubResource("LabelSettings_00j1l")
horizontal_alignment = 1
uppercase = true
[node name="Label" type="Label" parent="MarginContainer/MenContainer"]
visible = false
layout_mode = 2
text = "Version 0.2
Rows are created based on the maximum number of columns reached.
Example: If you want two vertical scripts, you must define a maximum of one column."
label_settings = SubResource("LabelSettings_2o3ku")
horizontal_alignment = 1
vertical_alignment = 1
[node name="Body" type="GridContainer" parent="MarginContainer/MenContainer"]
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 6
theme_override_constants/h_separation = 8
theme_override_constants/v_separation = 8
columns = 2
[node name="splited_off" type="CheckBox" parent="MarginContainer/MenContainer/Body"]
layout_mode = 2
tooltip_text = "Disabled Splited"
button_pressed = true
text = "Disabled"
icon = ExtResource("2_le2a0")
script = ExtResource("3_h7rbp")
[node name="splited_two_horizontal" type="CheckBox" parent="MarginContainer/MenContainer/Body"]
layout_mode = 2
tooltip_text = "Two Horizontal Splited"
text = "Two Horizontal"
icon = ExtResource("3_o7fne")
script = ExtResource("3_h7rbp")
columns = 2
rows = 1
[node name="splited_two_vertical" type="CheckBox" parent="MarginContainer/MenContainer/Body"]
layout_mode = 2
tooltip_text = "Two Vertical Splited"
text = "Two Vertical"
icon = ExtResource("4_js2dr")
script = ExtResource("3_h7rbp")
columns = 1
rows = 2
[node name="splited_three_horizontal" type="CheckBox" parent="MarginContainer/MenContainer/Body"]
layout_mode = 2
tooltip_text = "Three Horizontal Splited"
text = "Three Horizontal"
icon = ExtResource("5_h32ac")
script = ExtResource("3_h7rbp")
columns = 3
rows = 1
[node name="splited_three_vertical" type="CheckBox" parent="MarginContainer/MenContainer/Body"]
layout_mode = 2
tooltip_text = "Three Vertical Splited"
text = "Three Vertical"
icon = ExtResource("6_h7rbp")
script = ExtResource("3_h7rbp")
columns = 1
rows = 3
[node name="splited_four_square" type="CheckBox" parent="MarginContainer/MenContainer/Body"]
layout_mode = 2
tooltip_text = "Square Splited"
text = "Four Squared"
icon = ExtResource("7_bi1if")
script = ExtResource("3_h7rbp")
columns = 2
rows = 2
[node name="CheckBox" type="CheckBox" parent="MarginContainer/MenContainer/Body"]
layout_mode = 2
text = "Custom Split"
icon = ExtResource("10_0n25h")
script = ExtResource("3_h7rbp")
is_custom = true
[node name="COptions" type="VBoxContainer" parent="MarginContainer/MenContainer" node_paths=PackedStringArray("columns", "rows")]
visible = false
layout_mode = 2
script = ExtResource("11_2o3ku")
columns = NodePath("ValueOptions/ColumnsValue")
rows = NodePath("ValueOptions/RowsValue")
[node name="Label" type="Label" parent="MarginContainer/MenContainer/COptions"]
layout_mode = 2
text = "Custom Split Options"
label_settings = SubResource("LabelSettings_0n25h")
horizontal_alignment = 1
[node name="TextureRect" type="TextureRect" parent="MarginContainer/MenContainer/COptions"]
layout_mode = 2
texture = ExtResource("10_0n25h")
expand_mode = 1
stretch_mode = 5
[node name="ValueOptions" type="HBoxContainer" parent="MarginContainer/MenContainer/COptions"]
layout_mode = 2
[node name="ColumnsValue" type="SpinBox" parent="MarginContainer/MenContainer/COptions/ValueOptions"]
layout_mode = 2
size_flags_horizontal = 3
min_value = 1.0
max_value = 30.0
value = 1.0
alignment = 1
prefix = "Columns"
[node name="RowsValue" type="SpinBox" parent="MarginContainer/MenContainer/COptions/ValueOptions"]
layout_mode = 2
size_flags_horizontal = 3
min_value = 1.0
max_value = 30.0
value = 1.0
alignment = 1
prefix = "Rows"
[node name="Separator" type="HSeparator" parent="MarginContainer/MenContainer"]
layout_mode = 2
size_flags_vertical = 8
[node name="Footer" type="HBoxContainer" parent="MarginContainer/MenContainer"]
layout_mode = 2
[node name="OK" type="Button" parent="MarginContainer/MenContainer/Footer"]
layout_mode = 2
size_flags_horizontal = 3
text = "Accept"
[node name="Cancel" type="Button" parent="MarginContainer/MenContainer/Footer"]
layout_mode = 2
size_flags_horizontal = 3
text = "Exit"
[connection signal="pressed" from="MarginContainer/MenContainer/Footer/OK" to="." method="_on_ok_pressed"]
[connection signal="pressed" from="MarginContainer/MenContainer/Footer/Cancel" to="." method="_on_cancel_pressed"]

View File

@@ -0,0 +1,26 @@
[gd_scene format=3 uid="uid://di83u5ac2jww6"]
[node name="PanelPreview" type="ColorRect"]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
color = Color(1.27546e-06, 0.644043, 0.17534, 0.4)
[node name="Label" type="Label" parent="."]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -44.5
offset_top = -11.5
offset_right = 44.5
offset_bottom = 11.5
grow_horizontal = 2
grow_vertical = 2
text = "DROP HERE"
horizontal_alignment = 1
vertical_alignment = 1

View File

@@ -0,0 +1,24 @@
@tool
extends CheckBox
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Script Spliter
# https://github.com/CodeNameTwister/Script-Spliter
#
# Script Spliter addon for godot 4
# author: "Twister"
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
## V0.2 Used now as max columns by row!, 0 as infinite horizontal.
@export var columns : int = 0
## V0.2: Used now only as extra container if row > 1
@export var rows : int = 0
@export var is_custom : bool = false
func _pressed() -> void:
if is_custom:
if owner.has_method(&"enable_options"):
owner.call(&"enable_options")
else:
if owner.has_method(&"set_split_value"):
owner.call(&"set_split_value", columns, rows)

View File

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

View File

@@ -0,0 +1,142 @@
@tool
extends TabContainer
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Script Spliter
# https://github.com/CodeNameTwister/Script-Spliter
#
# Script Spliter addon for godot 4
# author: "Twister"
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@warning_ignore("unused_signal")
signal on_dragging(e : Control)
signal out_dragging(e : Control)
const DDTAB : Script = preload("res://addons/script_spliter/core/DDTAB.gd")
var _buffer_editors : Array[Object] = []
#static var _tab_focus : StyleBox = null
#static var _tab_disabled : StyleBox = null
#static var _tab_selected : StyleBox = null
#static var _tab_hovered : StyleBox = null
#static var _tab_unselected : StyleBox = null
func _config_tab(_tab : StyleBox) -> void:
if _tab is StyleBoxFlat:
_tab.skew.x = 0.5
_tab.border_color = Color.AQUA
#_tab.border_width_left = 0.0
#_tab.border_width_right = 0.0
#_tab.border_width_top = 0.0
#_tab.border_width_bottom = 0.1
func _ready() -> void:
pass
#var root : Control = EditorInterface.get_base_control()
#if root:
#if _tab_focus == null:
#_tab_focus = root.get_theme_stylebox(&"panel", &"tab_focus")
#if _tab_focus is StyleBoxFlat:
#_tab_focus = _tab_focus.duplicate()
#_config_tab(_tab_focus)
#if _tab_disabled == null:
#_tab_disabled = root.get_theme_stylebox(&"panel", &"tab_disabled")
#if _tab_disabled is StyleBoxFlat:
#_tab_disabled = _tab_disabled.duplicate()
#_config_tab(_tab_disabled)
#if _tab_selected == null:
#_tab_selected = root.get_theme_stylebox(&"panel", &"tab_selected")
#if _tab_selected is StyleBoxFlat:
#_tab_selected = _tab_selected.duplicate()
#_config_tab(_tab_selected)
#if _tab_hovered == null:
#_tab_hovered = root.get_theme_stylebox(&"panel", &"tab_hovered")
#if _tab_hovered is StyleBoxFlat:
#_tab_hovered = _tab_hovered.duplicate()
#_config_tab(_tab_hovered)
#if _tab_unselected == null:
#_tab_unselected = root.get_theme_stylebox(&"panel", &"tab_unselected")
#if _tab_unselected is StyleBoxFlat:
#_tab_unselected = _tab_unselected.duplicate()
#_config_tab(_tab_unselected)
#set(&"theme_override_styles/tab_focus", _tab_focus)
#set(&"theme_override_styles/tab_disabled", _tab_disabled)
#set(&"theme_override_styles/tab_selected", _tab_selected)
#set(&"theme_override_styles/tab_hovered", _tab_hovered)
#set(&"theme_override_styles/tab_unselected", _tab_unselected)
func reset() -> void:
for x : Node in get_children(true):
if x is TabBar:
if x.get_script() == DDTAB:
x.reset()
func clear_editors() -> void:
_buffer_editors.clear()
func add_editor(o : Object, limit : int) -> Object:
if is_instance_valid(o):
if limit > 0:
var i : int = _buffer_editors.find(o)
if i > -1:
_buffer_editors.remove_at(i)
_buffer_editors.append(o)
if limit > -1:
while _buffer_editors.size() > limit:
_buffer_editors.remove_at(0)
return o
func remove_editor(o : Object) -> void:
_buffer_editors.erase(o)
func backward_editor() -> Object:
if _buffer_editors.size() > 1:
var o : Variant = _buffer_editors.pop_back()
while !is_instance_valid(o) and _buffer_editors.size() > 0:
o = _buffer_editors.pop_back()
if is_instance_valid(o):
_buffer_editors.push_front(o)
return o
return null
func forward_editor() -> Object:
if _buffer_editors.size() > 1:
var o : Object = _buffer_editors.pop_front()
while !is_instance_valid(o) and _buffer_editors.size() > 0:
o = _buffer_editors.pop_front()
if is_instance_valid(o):
_buffer_editors.push_back(o)
return o
return null
func _on_child(n : Node) -> void:
if n is TabBar:
if n.get_script() != DDTAB:
n.set_script(DDTAB)
if !n.on_start_drag.is_connected(_on_start_drag):
n.on_start_drag.connect(_on_start_drag)
if !n.on_stop_drag.is_connected(_on_stop_drag):
n.on_stop_drag.connect(_on_stop_drag)
func _out_child(n : Node) -> void:
if n is TabBar:
if n.on_start_drag.is_connected(_on_start_drag):
n.on_start_drag.disconnect(_on_start_drag)
if n.on_stop_drag.is_connected(_on_stop_drag):
n.on_stop_drag.disconnect(_on_stop_drag)
if n.get_script() == DDTAB:
n.set_script(null)
func _on_stop_drag(tab : TabBar) -> void:
out_dragging.emit(tab)
func _on_start_drag(tab : TabBar) -> void:
on_dragging.emit(tab)
func _init() -> void:
child_entered_tree.connect(_on_child)
child_exiting_tree.connect(_out_child)

View File

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

View File

@@ -0,0 +1,59 @@
@tool
extends ItemList
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Script Spliter
# https://github.com/CodeNameTwister/Script-Spliter
#
# Script Spliter addon for godot 4
# author: "Twister"
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
signal on_start_drag(t : ItemList)
signal on_stop_drag(t : ItemList)
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 _init() -> void:
if is_node_ready():
_ready()
func _ready() -> void:
set_process(false)
setup()
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)
func _on_input(e : InputEvent) -> void:
if e is InputEventMouseButton:
if e.button_index == 1:
if e.pressed:
_fms = 0.0
is_drag = false
set_process(true)
else:
set_process(false)
if _fms >= 0.24:
on_stop_drag.emit(self)

View File

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

View File

@@ -0,0 +1,76 @@
@tool
extends TabBar
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Script Spliter
# https://github.com/CodeNameTwister/Script-Spliter
#
# Script Spliter 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()
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 == 1:
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)

View File

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

View File

@@ -0,0 +1,44 @@
@tool
extends Node
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Script Spliter
# https://github.com/CodeNameTwister/Script-Spliter
#
# Script Spliter addon for godot 4
# author: "Twister"
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
var callback : Callable
var end_callback : Callable
var index : int = 0
var back_to : int = 0
var buffer : Dictionary
func set_current_index(current : int) -> void:
back_to = current
func run(new_callback : Callable, new_end_callback : Callable) -> void:
callback = new_callback
end_callback = new_end_callback
index = 0
set_process(true)
func _ready() -> void:
set_process(false)
func _back() -> void:
if callback.is_valid():
callback.call(back_to, false)
func update_index() -> int:
index = callback.call(index, true)
return index
func _process(__: float) -> void:
if !callback.is_valid() or 0 > update_index():
set_process(false)
_back()
if end_callback.is_valid():
end_callback.call(buffer)
buffer = {}
return
index += 1

View File

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

View File

@@ -0,0 +1,43 @@
@tool
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Script Spliter
# https://github.com/CodeNameTwister/Script-Spliter
#
# Script Spliter addon for godot 4
# author: "Twister"
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
extends "res://addons/script_spliter/core/ui/multi_split_container.gd"
const PREVIEW : PackedScene = preload("res://addons/script_spliter/context/panel_preview.tscn")
var preview : Control = null
func get_total_containers() -> int:
var total : int = 0
for x : Node in get_children():
if x is SplitContainerItem:
if x.get_child_count() > 0:
total += 1
return total
func _notification(what: int) -> void:
if what == NOTIFICATION_PREDELETE:
if is_instance_valid(preview) and !preview.is_queued_for_deletion():
preview.queue_free()
func make_split_container_item() -> Control:
var x : SplitContainerItem = SplitContainerItem.new()
x.size_flags_horizontal = Control.SIZE_FILL
x.size_flags_vertical = Control.SIZE_FILL
x.custom_minimum_size = Vector2.ZERO
x.clip_contents = true
x.visible = false
return x
func has_items() -> bool:
return get_child_count() > 0
func is_split_container_item(x : Object) -> bool:
return x is SplitContainerItem

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -0,0 +1,40 @@
@tool
extends Control
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Script Spliter
# https://github.com/CodeNameTwister/Script-Spliter
#
# Script Spliter addon for godot 4
# author: "Twister"
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@export var lbl : Control
var _0x0001 : float = 0.0
var _0x0002 : float= 0.5
func _ready() -> void:
if !is_inside_tree():
set_process(false)
func _process(delta: float) -> void:
if !visible:
return
var p : Control = get_parent()
if !p:
return
_0x0001 += delta * 2.0
if _0x0001 >= 1.0:
_0x0001 = 0.0
if _0x0002 == 1.0:
_0x0002 = 0.5
else:
_0x0002 = 1.0
modulate.a = lerp(modulate.a, _0x0002, _0x0001)
lbl.pivot_offset = (lbl.size + Vector2.ONE) / 2.0
lbl.scale = lerp(lbl.scale, Vector2.ONE * _0x0002 , _0x0001 * 0.24)
func _enter_tree() -> void:
set_process(true)
func _exit_tree() -> void:
set_process(false)

View File

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

View File

@@ -0,0 +1,27 @@
[gd_scene load_steps=3 format=3 uid="uid://bd4fb42jjkgr0"]
[ext_resource type="Script" uid="uid://prv0v0r500g6" path="res://addons/script_spliter/core/ui/dd.gd" id="1_1ryr1"]
[ext_resource type="Texture2D" uid="uid://cxds5tr6aq5v3" path="res://addons/script_spliter/assets/dd.png" id="2_pid5b"]
[node name="Dd" type="ColorRect" node_paths=PackedStringArray("lbl")]
modulate = Color(0.8, 0.8, 0.8, 0.501533)
self_modulate = Color(1, 1, 1, 0.4)
size_flags_horizontal = 4
size_flags_vertical = 4
tooltip_text = "Drop the current dragged tab for change window!"
color = Color(1.3236e-07, 0.348188, 0.0242278, 1)
script = ExtResource("1_1ryr1")
lbl = NodePath("Label")
[node name="Label" type="TextureRect" parent="."]
show_behind_parent = true
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 4
size_flags_vertical = 4
texture = ExtResource("2_pid5b")
stretch_mode = 3

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="16"
height="16"
version="1.1"
id="svg1"
sodipodi:docname="Container.svg"
inkscape:export-filename="..\GODOT\ToShare\favoritedock\addons\script-ide\split_gui\icon\MultiSpliter.svg"
inkscape:export-xdpi="877.71429"
inkscape:export-ydpi="877.71429"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050">
<inkscape:page
x="0"
y="0"
width="16"
height="16"
id="page2"
margin="0"
bleed="0" />
</sodipodi:namedview>
<path
fill="#8eef97"
d="M 1,1 V 5 H 5 V 1 Z m 9,0 v 4 h 5 V 1 Z m -9,9 v 5 h 4 v -5 z m 9,0 v 5 h 5 V 10 Z M 8,15 7,9 1,8 H 15 L 9,7 8,1 Z"
id="path1"
sodipodi:nodetypes="ccccccccccccccccccccccccccc"
inkscape:export-filename="..\GODOT\ToShare\favoritedock\addons\script-ide\split_gui\GODOT\ToShare\favoritedock\addons\script-ide\split_gui\icon\MultiSpliter.svg"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96" />
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bslfeut6hh5yo"
path="res://.godot/imported/MultiSpliter.svg-ba196a92a18cd9aeefd856cd4e65a016.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/script_spliter/core/ui/icon/MultiSpliter.svg"
dest_files=["res://.godot/imported/MultiSpliter.svg-ba196a92a18cd9aeefd856cd4e65a016.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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=8.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="16"
height="16"
version="1.1"
id="svg1"
sodipodi:docname="ControlItemButton.svg"
inkscape:export-filename="ToShare\favoritedock\addons\script-ide\split_gui\icon\MultiSpliterButton.svg"
inkscape:export-xdpi="768"
inkscape:export-ydpi="768"
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:zoom="15.999999"
inkscape:cx="4.4375002"
inkscape:cy="8.5937504"
inkscape:window-width="1287"
inkscape:window-height="745"
inkscape:window-x="65"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1">
<inkscape:page
x="0"
y="0"
width="16"
height="16"
id="page2"
margin="0"
bleed="0" />
</sodipodi:namedview>
<rect
style="fill:#bfbfbf;fill-opacity:1;stroke:#757575;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;paint-order:stroke markers fill"
id="rect1"
width="12"
height="15"
x="2"
y="0.45580584"
ry="2" />
<circle
style="fill:#ffffff;fill-opacity:1;stroke:#bbbbbb;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill"
id="path1"
cy="2.8863502"
cx="5.3863502"
r="1.8863502" />
<circle
style="fill:#ffffff;fill-opacity:1;stroke:#bbbbbb;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill"
id="path1-1"
cy="7.965826"
cx="5.3863502"
r="1.8863502" />
<circle
style="fill:#ffffff;fill-opacity:1;stroke:#bbbbbb;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill"
id="path1-1-7"
cy="7.965826"
cx="10.465826"
r="1.8863502" />
<circle
style="fill:#ffffff;fill-opacity:1;stroke:#bbbbbb;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill"
id="path1-1-7-2"
cy="13.0453"
cx="5.3863502"
r="1.8863502" />
<circle
style="fill:#ffffff;fill-opacity:1;stroke:#bbbbbb;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill"
id="path1-1-7-2-7"
cy="13.0453"
cx="10.465826"
r="1.8863502" />
<circle
style="fill:#ffffff;fill-opacity:1;stroke:#bbbbbb;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill"
id="path1-5"
cy="2.8863502"
cx="10.465826"
r="1.8863502" />
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://151hs5hrois7"
path="res://.godot/imported/MultiSpliterButton.svg-f2ca8d7d3b41369a9fe8ce79d9fcb1df.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/script_spliter/core/ui/icon/MultiSpliterButton.svg"
dest_files=["res://.godot/imported/MultiSpliterButton.svg-f2ca8d7d3b41369a9fe8ce79d9fcb1df.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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=8.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="16"
height="16"
version="1.1"
id="svg1"
sodipodi:docname="Control.svg"
inkscape:export-filename="..\GODOT\ToShare\favoritedock\addons\script-ide\split_gui\icon\MultiSplitItem.png"
inkscape:export-xdpi="768"
inkscape:export-ydpi="768"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050">
<inkscape:page
x="0"
y="0"
width="16"
height="16"
id="page2"
margin="0"
bleed="0" />
</sodipodi:namedview>
<circle
cx="8"
cy="8"
fill="none"
stroke="#8eef97"
stroke-width="2"
id="circle1"
r="5" />
<circle
style="fill:none;fill-opacity:1;stroke:#8eef97;stroke-width:0.933;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill"
id="path2"
cx="7.9897118"
cy="7.9897118"
r="2.1256859" />
<path
style="fill:#8eef97;fill-opacity:1;stroke:none;stroke-width:0.933;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill"
d="M 1,5 5,1 H 1 M 1,5 5,1 H 1"
id="path7"
sodipodi:nodetypes="ccc" />
<path
style="fill:#8eef97;fill-opacity:1;stroke:none;stroke-width:0.933;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill"
d="M 15,5 V 1 h -5"
id="path7-8"
sodipodi:nodetypes="ccc" />
<path
style="fill:#8eef97;fill-opacity:1;stroke:none;stroke-width:0.933;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill"
d="m 10,15 h 5 m -5,0 h 5 v -5"
id="path7-8-5"
sodipodi:nodetypes="ccccc" />
<path
style="fill:#8eef97;fill-opacity:1;stroke:none;stroke-width:0.933;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill"
d="m 1,10 4,5 H 1 m 0,0 H 5 1"
id="path7-8-5-1"
sodipodi:nodetypes="cccccc" />
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bd3tnqhyiny6o"
path="res://.godot/imported/MultiSpliterItem.svg-73b989ef018da2301c61b6f59ef99931.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/script_spliter/core/ui/icon/MultiSpliterItem.svg"
dest_files=["res://.godot/imported/MultiSpliterItem.svg-73b989ef018da2301c61b6f59ef99931.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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=8.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1,999 @@
@tool
@icon("icon/MultiSpliter.svg")
extends Container
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# https://github.com/CodeNameTwister/Multi-Split-Container
#
# Multi-Split-Container addon for godot 4
# author: "Twister"
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
const SplitContainerItem : Script = preload("res://addons/script_spliter/core/ui/split_container_item.gd")
const SplitButton : Texture = preload("res://addons/script_spliter/core/ui/icon/MultiSpliterButton.svg")
@export_category("Multi-Split Settings")
## Max columns by rows, after added childs this is eparated by row group by columns size!
## [br][br]
## if this value is 0, will not create rows spliters.
@export_range(0.0, 1000.0, 1.0) var max_columns : int = 0:
set(e):
max_columns = maxi(0, e)
if Engine.is_editor_hint():
for x : int in range(separators_line_offsets.size()):
separators_line_offsets[x] = 0.0
for x : LineSep in _separators:
x.queue_free()
_separators.clear()
_first = true
update()
@export_group("Line Separator", "separator_line")
## Line separator size.
@export var separator_line_size : float = 4.0:
set(e):
separator_line_size = max(e, 0.0)
update()
## Separator line color.
@export var separator_line_color : Color = Color.MAGENTA:
set(e):
separator_line_color = e
if separator_line_color == Color.MAGENTA: # That color reminds me of texture not found errors.
var root = EditorInterface.get_base_control()
separator_line_color = root.get_theme_color("base_color", "Editor")
update()
## Separator line visibility.
@export var separator_line_visible : bool = true:
set(e):
separator_line_visible = e
for l : LineSep in _separators:
l.visible = separator_line_visible
@export_subgroup("Behaviour", "behaviour_")
## Enable function for auto expand lines container on inside focus.
@export var behaviour_expand_on_focus : bool = true
## Enable function for auto expand lines container on double click in the line.
@export var behaviour_expand_on_double_click : bool = true:
set(e):
behaviour_expand_on_double_click = e
for l : LineSep in _separators:
l.double_click_handler = behaviour_expand_on_double_click
## Enable movement by touching line.
@export var behaviour_can_move_by_line : bool = true:
set(e):
behaviour_can_move_by_line = e
for l : LineSep in _separators:
l.draggable = behaviour_can_move_by_line
## This allow expand you current focused container if you shrunk it.
@export var behaviour_can_expand_focus_same_container : bool = false
## Enable smooth when expand container.
@export var behaviour_expand_smoothed : bool = true:
set(e):
behaviour_expand_smoothed = e
if !e:
if _tween and _tween.is_running():
_tween.kill()
_tween = null
## Time speed duration for reset expand container.
@export_range(0.01, 1000.0, 0.01) var behaviour_expand_smoothed_time : float = 0.24:
set(e):
behaviour_expand_smoothed_time = maxf(0.01, e)
if _tween and _tween.is_running():
_tween.kill()
_tween = null
## Custom initial offset for separator lines. (TODO: Still Working here!)
@export var separators_line_offsets : Array[float] :
set(e):
separators_line_offsets = e
if Engine.is_editor_hint():
if separators_line_offsets.size() != _separators.size():
separators_line_offsets.resize(_separators.size())
update()
@export_subgroup("Drag Button", "drag_button")
## Set if drag button always be visible (Useful for test button size)
@export var drag_button_always_visible : bool = false:
set(e):
drag_button_always_visible = e
var min_visible_drag_button : float = 0.0
if drag_button_always_visible:
min_visible_drag_button = 0.4
for l : LineSep in _separators:
if l.button:
l.button.modulate.a = 0.0
l.button.min_no_focus_transparense = min_visible_drag_button
## Min size for drag button visible on split lines.
@export_range(1.0, 200.0, 0.1) var drag_button_size : float = 24.0:
set(e):
drag_button_size = e
update()
## Modulate color for the drag button.
@export var drag_button_modulate : Color = Color.MAGENTA:
set(e):
drag_button_modulate = e
if drag_button_modulate == Color.MAGENTA:
if Engine.is_editor_hint():
var root : Control = EditorInterface.get_base_control()
drag_button_modulate = root.get_theme_color("base_color", "Editor").lightened(0.5)
update()
## Change default drag button icon.
@export var drag_button_icon : Texture = null:
set(e):
drag_button_icon = e
update()
var _separators : Array[LineSep] = []
var _last_container_focus : Node = null
var _frame : int = 1
var _first : bool = true
var _tween : Tween = null
func get_separators() -> Array[LineSep]:
return _separators
## Get line begin offset limit.
func get_line_seperator_left_offset_limit(index : int) -> float:
if index < _separators.size():
var line_sep : LineSep = _separators[index]
if !line_sep.is_vertical:
if index < 1:
return -_separators[index].initial_position.x
var next : LineSep = _separators[index - 1]
return (next.initial_position.x + (next.size.x/2.0)) - _separators[index].initial_position.x
else:
if index < 1:
return -_separators[index].initial_position.y
var next : LineSep = _separators[index - 1]
return (next.initial_position.y + (next.size.y/2.0)) - _separators[index].initial_position.y
push_warning("[PLUGIN] Not valid index for line separator!")
return 0.0
## Get line end offset limit.
func get_line_seperator_right_offset_limit(index : int) -> float:
if index < _separators.size():
var line_sep : LineSep = _separators[index]
if !line_sep.is_vertical:
if index + 1 == _separators.size():
return (size.x/2.0) -_separators[index].initial_position.x
var current : LineSep = _separators[index]
return (_separators[index + 1].initial_position.x - current.initial_position.x + (current.size.x/2.0))
else:
if index + 1 == _separators.size():
return size.x -_separators[index].initial_position.y
var current : LineSep = _separators[index]
return (_separators[index + 1].initial_position.y - current.initial_position.y + (current.size.y/2.0))
push_warning("[PLUGIN] Not valid index for line separator!")
return 0.0
# This is function is util when you want expand or constraint manualy offset.
## Update offset of the line
func update_line_separator_offset(index : int, offset : float) -> void:
var line_sep : LineSep = _separators[index]
line_sep.offset = offset
line_sep.force_update()
## Get total line count.
func get_line_separator_count() -> int:
return _separators.size()
## Get Line reference by index, see get_line_separator_count()
func get_line_separator(index : int) -> LineSep:
return _separators[index]
## Get if line separator is vertical.
func is_vertical_line_separator(index : int) -> bool:
if index < _separators.size():
return _separators[index].is_vertical
push_warning("[PLUGIN] Not valid index for line separator!")
return false
## Expand splited container by index container.
func expand_splited_container(node : Node) -> void:
var same : bool = _last_container_focus == node
if same and !behaviour_can_expand_focus_same_container:
return
_last_container_focus = node
if !behaviour_expand_on_focus:
return
if _tween and _tween.is_running():
if same:
return
_tween.kill()
_tween = null
var top_lines : Array[LineSep] = []
var bottom_lines : Array[LineSep] = []
var update_required : bool = false
for line : LineSep in _separators:
if node in line.top_items:
update_required = update_required or line.offset < 0.0
top_lines.append(line)
elif node in line.bottom_items:
update_required = update_required or line.offset > 0.0
bottom_lines.append(line)
if update_required:
if behaviour_expand_smoothed:
_tween = get_tree().create_tween()
_tween.tween_method(_reset_expanded_lines.bind(top_lines, bottom_lines), 0.0, 1.0, behaviour_expand_smoothed_time)
else:
_reset_expanded_lines(1.0, top_lines, bottom_lines)
func _reset_expanded_lines(_lerp : float, top_lines : Array[LineSep], bottom_lines : Array[LineSep]) -> void:
for iline : int in range(top_lines.size() - 1, -1, -1):
var line : LineSep = top_lines[iline]
if is_instance_valid(line):
if line.offset < 0.0:
line.offset = lerp(line.offset, 0.0, _lerp)
else:
top_lines.remove_at(iline)
for iline : int in range(bottom_lines.size() - 1, -1, -1):
var line : LineSep = bottom_lines[iline]
if is_instance_valid(line):
if line.offset > 0.0:
line.offset = lerp(line.offset, 0.0, _lerp)
else:
bottom_lines.remove_at(iline)
for line : LineSep in top_lines:
line.force_update()
for line : LineSep in bottom_lines:
line.force_update()
## Get initial position of a separator line.
func get_line_separator_initial_position(index : int) -> Vector2:
if index < _separators.size():
return _separators[index].initial_position
push_warning("[PLUGIN] Not valid index for line separator!")
return Vector2.ZERO
class DragButton extends Button:
var _frm : float = 0.0
var _line_sep : LineSep = null
var _is_pressed : bool = false
var is_hover : bool = false
var _hover : Array[bool] = [false, false]
var min_no_focus_transparense : float = 0.0:
set(e):
min_no_focus_transparense = e
modulate.a = maxf(modulate.a, min_no_focus_transparense)
static var DEFAULT_STYLE : StyleBox = null
func set_drag_icon(new_icon : Texture) -> void:
if icon != new_icon:
if new_icon == null:
icon = SplitButton
return
icon = new_icon
func update_gui() -> void:
if !_line_sep:
return
if _line_sep.is_vertical:
_line_sep.mouse_default_cursor_shape = Control.CURSOR_VSPLIT
mouse_default_cursor_shape = Control.CURSOR_VSPLIT
else:
_line_sep.mouse_default_cursor_shape = Control.CURSOR_HSPLIT
mouse_default_cursor_shape = Control.CURSOR_HSPLIT
func set_line(line_sep : LineSep) -> void:
if _line_sep:
if _line_sep.mouse_entered.is_connected(_on_enter):
_line_sep.mouse_entered.disconnect(_on_enter)
if _line_sep.mouse_exited.is_connected(_on_exit):
_line_sep.mouse_exited.disconnect(_on_exit)
if _line_sep.gui_input.is_connected(_on_input):
_line_sep.gui_input.disconnect(_on_input)
_line_sep = line_sep
if _line_sep:
if !_line_sep.mouse_entered.is_connected(_on_enter):
_line_sep.mouse_entered.connect(_on_enter.bind(1))
if !_line_sep.mouse_exited.is_connected(_on_exit):
_line_sep.mouse_exited.connect(_on_exit.bind(1))
if !_line_sep.gui_input.is_connected(_on_input):
_line_sep.gui_input.connect(_on_input)
func _init(line_sep : LineSep = null) -> void:
modulate.a = 0.0
set_line(line_sep)
button_down.connect(_on_press)
button_up.connect(_out_press)
mouse_entered.connect(_on_enter.bind(0))
mouse_exited.connect(_on_exit.bind(0))
gui_input.connect(_custom_input)
icon = SplitButton
icon_alignment = HORIZONTAL_ALIGNMENT_CENTER
vertical_icon_alignment = VERTICAL_ALIGNMENT_CENTER
expand_icon = true
if null != icon:
flat = true
if DEFAULT_STYLE == null:
DEFAULT_STYLE = StyleBoxEmpty.new()
focus_mode = Control.FOCUS_CLICK
set(&"theme_override_styles/focus", DEFAULT_STYLE)
set(&"theme_override_styles/disabled_mirrored", DEFAULT_STYLE)
set(&"theme_override_styles/disabled", DEFAULT_STYLE)
set(&"theme_override_styles/hover_pressed_mirrored", DEFAULT_STYLE)
set(&"theme_override_styles/hover_pressed", DEFAULT_STYLE)
set(&"theme_override_styles/hover_mirrored", DEFAULT_STYLE)
set(&"theme_override_styles/hover", DEFAULT_STYLE)
set(&"theme_override_styles/pressed_mirrored", DEFAULT_STYLE)
set(&"theme_override_styles/pressed", DEFAULT_STYLE)
set(&"theme_override_styles/normal_mirrored", DEFAULT_STYLE)
set(&"theme_override_styles/normal", DEFAULT_STYLE)
z_as_relative = true
z_index = 2000
update_gui()
func _custom_input(e : InputEvent) -> void:
if e is InputEventMouseButton:
if e.pressed and e.double_click:
get_tree().call_group(&"ScriptSpliter", &"swap", get_parent())
func _on_input(e : InputEvent) -> void:
if e is InputEventMouseButton:
if e.pressed and e.double_click:
if _line_sep and _line_sep.double_click_handler:
_line_sep.offset = 0.0
_line_sep.offset_updated.emit()
elif e.pressed and _line_sep.draggable and e.button_index == 1:
button_down.emit()
elif !e.pressed and _line_sep.draggable and e.button_index == 1:
button_up.emit()
func set_line_sep_reference(ref : LineSep) -> void:
_line_sep = ref
func _ready() -> void:
set_process(false)
func _on_enter(x : int = 0) -> void:
_hover[x] = true
_frm = 0.0
modulate.a = 1.0
is_hover = true
set_process(true)
func _on_exit(x : int = 0) -> void:
_hover[x] = false
for h : bool in _hover:
if h != false:
return
_frm = 0.0
modulate.a = 1.0
is_hover = false
set_process(true)
func _on_press() -> void:
_is_pressed = true
_frm = 0.0
modulate.a = 1.0
set_process(true)
func _out_press() -> void:
_is_pressed = false
set_process(true)
func _process(delta : float) -> void:
if !has_focus() and !is_hover:
_frm += delta * 0.4
if _frm >= 1.0:
_frm = 1.0
set_process(false)
modulate.a = lerp(modulate.a, min_no_focus_transparense, _frm)
if _is_pressed:
var mpos : Vector2 = _line_sep.get_parent().get_local_mouse_position()
if mpos != get_rect().get_center():
_line_sep.update_offset_by_position(mpos)
class UndoredoSplit extends RefCounted:
var object : SplitContainerItem = null
var c_objects : Array[Node] = []
class LineSep extends ColorRect:
signal offset_updated()
var top_lines : Array[LineSep] = []
var bottom_lines : Array[LineSep] = []
var top_items : Array[Control] = []
var bottom_items : Array[Control] = []
var is_vertical : bool = false:
set(e):
is_vertical = e
if button:
button.update_gui()
var row : int = 0
var initial_position : Vector2 = Vector2.ZERO
var offset : float = 0.0
var min_size_offset : float = 0.0
var prev_line : LineSep = null
var next_line : LineSep = null
var button : DragButton = null
var double_click_handler : bool = true
var draggable : bool = true
func set_next_line(next : LineSep = null) -> void:
next_line = next
next.prev_line = self
func clear() -> void:
top_items.clear()
bottom_items.clear()
top_lines.clear()
bottom_lines.clear()
func reset() -> void:
position = initial_position
update_items()
func update_items() -> void:
if is_vertical:
for item : Control in top_items:
item.size.y = position.y - item.position.y
if !prev_line:
item.position.y = 0.0
for item : Control in bottom_items:
item.position.y = position.y + size.y
if next_line:
item.size.y = next_line.position.y - item.position.y
else:
item.size.y = get_parent().size.y - item.position.y
else:
for item : Control in top_items:
item.size.x = position.x - item.position.x + (size.x / 2.0) - 2.0
if !prev_line:
item.position.x = 0.0
for item : Control in bottom_items:
var diff : float = position.x + (size.x / 2.0) + 2.0
item.position.x = diff
if next_line:
item.size.x = next_line.position.x - item.position.x
else:
item.size.x = get_parent().size.x - item.position.x
func force_update() -> void:
update_offset_by_position(initial_position + Vector2(offset * int(!is_vertical), offset * int(is_vertical)))
func get_current_position() -> Vector2:
return initial_position + Vector2(offset * int(!is_vertical), offset * int(is_vertical))
func update_offset_by_position(vpos : Vector2) -> void:
if is_vertical:
min_size_offset = 0.0
for x : Control in top_items:
min_size_offset = maxf(min_size_offset, x.get_minimum_size().y)
if prev_line:
prev_line.min_size_offset = 0.0
for x : Control in prev_line.bottom_items:
prev_line.min_size_offset = maxf(prev_line.min_size_offset, x.get_minimum_size().y)
offset = vpos.y - initial_position.y
offset = minf(offset, get_parent().size.y - (initial_position.y + size.y + min_size_offset))
offset = maxf(offset, -(initial_position.y - min_size_offset))
if next_line:
var val : float = next_line.position.y - (initial_position.y + size.y + min_size_offset)
if offset > val:
offset = val
else:
var val : float = get_parent().size.y - (initial_position.y + (size.y / 2.0) + min_size_offset)
if offset > val:
offset = val
if prev_line:
var val : float = -(initial_position.y - (prev_line.position.y + prev_line.size.y + prev_line.min_size_offset))
if offset < val:
offset = val
else:
var top_size_offset : float = 0.0
for x : Control in top_items:
top_size_offset = maxf(top_size_offset, x.get_minimum_size().y)
offset = maxf(offset, top_size_offset-initial_position.y)
position.y = initial_position.y + offset
for line : LineSep in top_lines:
line.size.y = position.y - line.position.y
for line : LineSep in bottom_lines:
line.position.y = position.y + size.y
if next_line:
line.size.y = next_line.position.y - line.position.y
else:
line.size.y = get_parent().size.y - line.position.y
else:
min_size_offset = 0.0
for x : Control in bottom_items:
min_size_offset = maxf(min_size_offset, x.get_minimum_size().x)
if prev_line:
prev_line.min_size_offset = 0.0
for x : Control in prev_line.bottom_items:
prev_line.min_size_offset = maxf(prev_line.min_size_offset, x.get_minimum_size().x)
offset = vpos.x - initial_position.x
offset = minf(offset, get_parent().size.x - (initial_position.x + size.x + min_size_offset))
offset = maxf(offset, -initial_position.x)
if next_line:
var val : float = next_line.position.x - (initial_position.x + size.x + min_size_offset)
if offset > val:
offset = val
else:
var val : float = get_parent().size.x - (initial_position.x + (size.x/2.0) + min_size_offset)
if offset > val:
offset = val
if prev_line:
var val : float = -(initial_position.x - (prev_line.position.x + prev_line.size.x + prev_line.min_size_offset))
if offset < val:
offset = val
else:
var top_size_offset : float = 0.0
for x : Control in top_items:
top_size_offset = maxf(top_size_offset, x.get_minimum_size().x)
offset = maxf(offset, top_size_offset-initial_position.x)
position.x = initial_position.x + offset
update_items()
func _draw() -> void:
update()
func update() -> void:
button.rotation_degrees = 90.0 * int(is_vertical)
button.pivot_offset = button.size / 2.0
button.position = size / 2.0 - button.pivot_offset
func _init() -> void:
color = Color.RED
func _ready() -> void:
name = "SplitLine"
if button == null:
button = DragButton.new(self)
add_child(button, false, Node.INTERNAL_MODE_BACK)
func _test() -> void:
queue_redraw()
func _init() -> void:
child_entered_tree.connect(_on_enter)
child_exiting_tree.connect(_on_exiting)
func update() -> void:
set_process(true)
func _create_separator() -> Control:
var line_sep : LineSep = LineSep.new()
line_sep.offset_updated.connect(update)
return line_sep
func _undoredo_undo(ur : UndoredoSplit) -> void:
if !is_instance_valid(ur):
return
var split : SplitContainerItem = ur.object
if is_instance_valid(split):
if split.get_parent() == self:
ur.c_objects = split.get_children()
for x : Node in ur.c_objects:
split.remove_child(x)
if x is Control:
x.visible = false
add_child(x)
if is_instance_valid(split) and split.get_parent() == self:
remove_child(split)
func _update() -> void:
var items : Array[Control] = []
for x : Node in get_children():
if is_instance_valid(x) and x is Control:
if x.visible and !x.is_queued_for_deletion():
if x is SplitContainerItem:
if x.get_child_count() > 0:
var _is_visible : bool = false
for y : Node in x.get_children():
if y is Control and y.visible:
_is_visible = true
break
if !_is_visible:
continue
else:
x.queue_free()
continue
elif x is DragButton or x is LineSep:
x.queue_free()
continue
else:
var container : SplitContainerItem = SplitContainerItem.new()
add_child(container, true)
x.reparent(container)
x = container
x.size_flags_horizontal = Control.SIZE_FILL
x.size_flags_vertical = Control.SIZE_FILL
x.clip_contents = true
x.custom_minimum_size = Vector2.ZERO
items.append(x)
var totals : int = items.size()
var rows : int = 0
if max_columns > 0:
var _totals : int = totals
rows = 0
while _totals > max_columns:
_totals -= max_columns
rows += 1
totals -= rows
if totals < 1:
for x : int in range(0, _separators.size(), 1):
_separators[x].queue_free()
_separators[x] = null
_separators.clear()
for x : Control in items:
x.position = Vector2.ZERO
x.size = get_rect().size
return
else:
if separator_line_size <= 0.0:
for x : int in range(0, _separators.size(), 1):
_separators[x].queue_free()
_separators[x] = null
_separators.clear()
else:
var sep : int = totals - 1 + rows
for x : int in range(sep, _separators.size(), 1):
_separators[x].queue_free()
_separators[x] = null
_separators.resize(sep)
for x : int in range(0, _separators.size(), 1):
if _separators[x] == null:
_separators[x] = _create_separator()
rows += 1
if max_columns > 1:
if totals > max_columns:
totals = max_columns
var rect_size : Vector2 = get_rect().size
var start_position : Vector2 = Vector2.ZERO
var size_split : Vector2 = (rect_size / Vector2(totals, rows))
var size_sep : Vector2 = Vector2.ONE * separator_line_size
if totals > 1:
size_sep = (size_sep / (totals - 1))
var item_size : Vector2 = Vector2(size_split.x, size_split.y)
var line_size : Vector2 = Vector2(separator_line_size, item_size.y)
var total_items : int = items.size()
var vpos : Vector2 = Vector2.ZERO
var current_row : int = 0
var item_index : int = 0
var last_vline : LineSep = null
var last_hline : LineSep = null
for x : Control in items:
x.position = Vector2.ZERO
x.size = x.get_minimum_size()
for z : int in range(_separators.size()):
var x : LineSep = _separators[z]
x.clear()
start_position.x += 1
if 0 < max_columns and start_position.x + 1 > max_columns:
total_items -= max_columns
start_position.x = 0.0
start_position.y += 1.0
current_row += 1
if total_items <= max_columns and total_items > 0:
size_split = (rect_size / Vector2(total_items, rows))
if total_items == 1:
size_sep = Vector2.ONE * separator_line_size
else:
size_sep = ((Vector2.ONE * separator_line_size) / (total_items - 1))
item_size = Vector2(size_split.x, size_split.y)
line_size = Vector2(separator_line_size, rect_size.y - x.position.y)
vpos = Vector2(0.0, start_position.y) * item_size
x.is_vertical = true
if x.get_parent() == null:
add_child(x, false, Node.INTERNAL_MODE_BACK)
x.row = current_row
if items.size() > 0:
var it : int = mini(item_index, items.size() - 1)
var min_size : float = 0.0
var _has : bool = false
for y : int in range(z - 1, -1, -1):
if it > -1:
var item : Control = items[it]
x.top_items.append(item)
min_size = maxf(item.get_minimum_size().y, min_size)
it -= 1
var ln : LineSep = _separators[y]
if ln.is_vertical:
_has = true
break
x.top_lines.append(ln)
if !_has:
for _it : int in range(it, -1, -1):
var item : Control = items[it]
x.top_items.append(item)
if item_index + 1 < items.size():
it = item_index + 1
_has = false
for y : int in range(z + 1, _separators.size(), 1):
if it < items.size():
var item : Control = items[it]
x.bottom_items.append(item)
it += 1
var ln : LineSep = _separators[y]
if ln.is_vertical:
_has = true
break
x.bottom_lines.append(ln)
if !_has:
for _it : int in range(it, items.size(), 1):
var item : Control = items[_it]
x.bottom_items.append(item)
var vline_size : Vector2 = Vector2(rect_size.x, separator_line_size)
x.initial_position = vpos
x.initial_position.y -= (vline_size.y) / 2.0
x.position = x.initial_position
x.button.size = Vector2(drag_button_size, drag_button_size)
x.set(&"size", vline_size)
x.update()
if last_vline:
last_vline.set_next_line(x)
last_vline = x
last_hline = null
item_index += 1
continue
vpos = start_position * item_size
if x.get_parent() == null:
add_child(x, false, Node.INTERNAL_MODE_BACK)
if item_index < items.size():
var item : Control = items[item_index]
x.top_items.append(item)
item_index += 1
if item_index < items.size():
if z + 1 < _separators.size():
if !_separators[z].is_vertical:
x.bottom_items.append(items[item_index])
else:
x.bottom_items.append(items[item_index])
x.initial_position = vpos
x.initial_position.x -= (line_size.x) / 2.0
x.button.size = Vector2(drag_button_size, drag_button_size)
x.row = current_row
x.position = x.initial_position
x.set(&"size", line_size)
x.update()
if last_hline:
last_hline.set_next_line(x)
last_hline = x
for x : Control in items:
x.size = size
var min_visible_drag_button : float = 0.0
if drag_button_always_visible:
min_visible_drag_button = 0.4
if _first:
for l : LineSep in _separators:
l.visible = separator_line_visible
l.color = separator_line_color
l.double_click_handler = behaviour_expand_on_double_click
l.button.self_modulate = drag_button_modulate
l.button.min_no_focus_transparense = min_visible_drag_button
l.button.set_drag_icon(drag_button_icon)
l.draggable = behaviour_can_move_by_line
l.reset()
else:
if separators_line_offsets.size() > 0:
for l : int in range(0, _separators.size(), 1):
if l < separators_line_offsets.size():
_separators[l].offset = separators_line_offsets[l]
continue
break
for l : LineSep in _separators:
l.visible = separator_line_visible
l.color = separator_line_color
l.double_click_handler = behaviour_expand_on_double_click
l.button.self_modulate = drag_button_modulate
l.button.min_no_focus_transparense = min_visible_drag_button
l.button.set_drag_icon(drag_button_icon)
l.draggable = behaviour_can_move_by_line
l.force_update()
if !Engine.is_editor_hint():
separators_line_offsets.clear()
else:
for l : int in range(0, _separators.size(), 1):
if l < separators_line_offsets.size():
separators_line_offsets[l] = _separators[l].offset
continue
break
func _on_enter(n : Node) -> void:
n.is_inside_tree()
if n is SplitContainerItem or (n is Control and !Engine.is_editor_hint()):
if !n.visibility_changed.is_connected(_on_visible):
n.visibility_changed.connect(_on_visible)
if is_node_ready():
for x : int in range(separators_line_offsets.size()):
separators_line_offsets[x] = 0.0
update()
func _on_visible() -> void:
update()
func _on_exiting(n : Node) -> void:
if n is SplitContainerItem or (n is Control and !Engine.is_editor_hint()):
if is_node_ready():
for x : int in range(separators_line_offsets.size()):
separators_line_offsets[x] = 0.0
for x : LineSep in _separators:
x.offset = 0.0
if n.visibility_changed.is_connected(_on_visible):
n.visibility_changed.disconnect(_on_visible)
update()
func _process(__ : float) -> void:
if is_node_ready():
if _frame > 0:
_frame -= 1
return
_update()
if _first:
_first = false
else:
set_process(false)
func _on_exiting_tree() -> void:
var vp : Viewport = get_viewport()
if vp and vp.size_changed.is_connected(update):
vp.size_changed.disconnect(update)
var parent : Node = get_parent()
if parent is Control:
if parent.item_rect_changed.is_connected(update):
parent.item_rect_changed.disconnect(update)
func _enter_tree() -> void:
var vp : Viewport = get_viewport()
if vp and !vp.size_changed.is_connected(update):
vp.size_changed.connect(update)
var parent : Node = get_parent()
if parent is Control:
if !parent.item_rect_changed.is_connected(update):
parent.item_rect_changed.connect(update)
if !tree_exiting.is_connected(_on_exiting_tree):
tree_exiting.connect(_on_exiting_tree)
func _on_draw() -> void:
update()
func _ready() -> void:
separator_line_color = separator_line_color
drag_button_modulate = drag_button_modulate
size_flags_horizontal = Control.SIZE_EXPAND_FILL
size_flags_vertical =Control.SIZE_EXPAND_FILL
set_deferred(&"anchor_left", 0.0)
set_deferred(&"anchor_top", 0.0)
set_deferred(&"anchor_bottom", 1.0)
set_deferred(&"anchor_right", 1.0)
if Engine.is_editor_hint():
draw.connect(_on_draw)
if _first:
update()

View File

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

View File

@@ -0,0 +1,69 @@
@tool
@icon("icon/MultiSpliterItem.svg")
extends Control
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# https://github.com/CodeNameTwister/Multi-Split-Container
#
# Multi-Split-Container addon for godot 4
# author: "Twister"
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
var focus_handler : bool = false
## Expand if tight by spliter
func show_splited_container() -> void:
var parent : Node = get_parent()
if parent.has_method(&"expand_splited_container"):
parent.call(&"expand_splited_container", self)
func _ready() -> void:
set_process(false)
size_flags_horizontal = Control.SIZE_FILL
size_flags_vertical = Control.SIZE_FILL
set_deferred(&"anchor_left", 0.0)
set_deferred(&"anchor_top", 0.0)
set_deferred(&"anchor_bottom", 1.0)
set_deferred(&"anchor_right", 1.0)
func _init() -> void:
name = "SplitContainerItem"
child_exiting_tree.connect(_on_child_exiting_tree)
child_entered_tree.connect(_on_child_entered_tree)
func _on_visible() -> void:
var _visible : bool = false
for x : Node in get_children():
if x is Control:
if x.visible:
_visible = true
break
visible = _visible
func _on_child_entered_tree(n : Node) -> void:
if n is Control:
n.size = size
n.set_anchor(SIDE_LEFT, 0.0)
n.set_anchor(SIDE_RIGHT, 1.0)
n.set_anchor(SIDE_TOP, 0.0)
n.set_anchor(SIDE_BOTTOM, 1.0)
if !n.visibility_changed.is_connected(_on_visible):
n.visibility_changed.connect(_on_visible)
func _disconnect(n : Node) -> void:
if n is Control:
if n.visibility_changed.is_connected(_on_visible):
n.visibility_changed.disconnect(_on_visible)
for x : Node in n.get_children():
_disconnect(x)
func _on_child_exiting_tree(n : Node) -> void:
_disconnect(n)
func _enter_tree() -> void:
var c : Node = get_parent()
if c is Control:
size = c.size

View File

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

View File

@@ -0,0 +1,5 @@
[gd_resource type="InputEventKey" format=3 uid="uid://p4o5dw6yauu"]
[resource]
alt_pressed = true
key_label = 4194319

View File

@@ -0,0 +1,5 @@
[gd_resource type="InputEventMouseButton" format=3 uid="uid://bwpahdvr80ivr"]
[resource]
device = -1
button_index = 8

View File

@@ -0,0 +1,5 @@
[gd_resource type="InputEventKey" format=3 uid="uid://b43ac78k4ox2a"]
[resource]
alt_pressed = true
physical_keycode = 4194321

View File

@@ -0,0 +1,4 @@
[gd_resource type="InputEventMouseButton" format=3 uid="uid://bs1lk5ids0s01"]
[resource]
button_index = 9

View File

@@ -0,0 +1,9 @@
[plugin]
name="Script Spliter"
description="Tool Addon for godot 4
Allow split script window."
author="Twister"
version="0.3.6"
github="https://github.com/CodeNameTwister/Script-Spliter"
script="plugin.gd"

View 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)

View File

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