├── .github
└── FUNDING.yml
├── .gitignore
├── DocEditorSettings.md
├── LICENSE
├── README.md
├── addons
└── script_spliter
│ ├── assets
│ ├── File.svg
│ ├── File.svg.import
│ ├── dd.png
│ ├── dd.png.import
│ ├── github_CodeNameTwister.png
│ ├── github_CodeNameTwister.png.import
│ ├── placeholder.png
│ └── placeholder.png.import
│ ├── context
│ ├── _POPGDScript_.gd
│ ├── _POPGDScript_.gd.uid
│ ├── btn_callback.gd
│ ├── btn_callback.gd.uid
│ ├── context_window.gd
│ ├── context_window.gd.uid
│ ├── custom_options.gd
│ ├── custom_options.gd.uid
│ ├── flying_script.gd
│ ├── flying_script.gd.uid
│ ├── flying_script.tscn
│ ├── flying_script_font.tres
│ ├── icons
│ │ ├── atop.png
│ │ ├── atop.png.import
│ │ ├── expand.svg
│ │ ├── expand.svg.import
│ │ ├── sp_2H.png
│ │ ├── sp_2H.png.import
│ │ ├── sp_2V.png
│ │ ├── sp_2V.png.import
│ │ ├── sp_3H.png
│ │ ├── sp_3H.png.import
│ │ ├── sp_3V.png
│ │ ├── sp_3V.png.import
│ │ ├── sp_4S.png
│ │ ├── sp_4S.png.import
│ │ ├── sp_custom.png
│ │ ├── sp_custom.png.import
│ │ ├── sp_disable.png
│ │ ├── sp_disable.png.import
│ │ ├── split_cminus.svg
│ │ ├── split_cminus.svg.import
│ │ ├── split_cplus.svg
│ │ ├── split_cplus.svg.import
│ │ ├── split_rminus.svg
│ │ ├── split_rminus.svg.import
│ │ ├── split_rplus.svg
│ │ └── split_rplus.svg.import
│ ├── menu_tool.gd
│ ├── menu_tool.gd.uid
│ ├── menu_tool.tscn
│ ├── panel_preview.tscn
│ ├── split_type_button.gd
│ ├── split_type_button.gd.uid
│ └── tab_preview.tscn
│ ├── core
│ ├── DDContainer.gd
│ ├── DDContainer.gd.uid
│ ├── DDItem.gd
│ ├── DDItem.gd.uid
│ ├── DDTAB.gd
│ ├── DDTAB.gd.uid
│ ├── DaemonChaser.gd
│ ├── DaemonChaser.gd.uid
│ ├── EditorContainer.gd
│ ├── EditorContainer.gd.uid
│ ├── builder.gd
│ ├── builder.gd.uid
│ └── ui
│ │ ├── dd.gd
│ │ ├── dd.gd.uid
│ │ ├── dd.tscn
│ │ ├── icon
│ │ ├── MultiSpliter.svg
│ │ ├── MultiSpliter.svg.import
│ │ ├── MultiSpliterButton.svg
│ │ ├── MultiSpliterButton.svg.import
│ │ ├── MultiSpliterItem.svg
│ │ └── MultiSpliterItem.svg.import
│ │ ├── multi_split_container.gd
│ │ ├── multi_split_container.gd.uid
│ │ ├── split_container_item.gd
│ │ └── split_container_item.gd.uid
│ ├── io
│ ├── backward_key_button.tres
│ ├── backward_mouse_button.tres
│ ├── forward_key_button.tres
│ └── forward_mouse_button.tres
│ ├── plugin.cfg
│ ├── plugin.gd
│ └── plugin.gd.uid
└── images
├── img0.png
├── img1.png
├── img2.png
└── img3.png
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | ko_fi: cntwister
4 | buy_me_a_coffee: twister
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Godot 4+ specific ignores
2 | .godot/
3 |
4 | # Godot-specific ignores
5 | .import/
6 | export.cfg
7 | export_credentials.cfg
8 |
9 | # Imported translations (automatically generated from CSV files)
10 | *.translation
11 |
12 | # Mono-specific ignores
13 | .mono/
14 | data_*/
15 | mono_crash.*.json
16 |
17 | # User IO ignores
18 | addons/script_spliter/io/*_button.tres
19 |
--------------------------------------------------------------------------------
/DocEditorSettings.md:
--------------------------------------------------------------------------------
1 | # Script Spliter in Editor Settings
2 | Each plugin configuration parameter is documented here.
3 |
4 | **Root of EditorSettings**: *plugin/script_spliter/**
5 |
6 | | Setting | Description |
7 | | ------------ | ------------ |
8 | | Row | (Work on start/Managed by Plugin) Initial rows, if it is zero it will be equal to 1 |
9 | | Column | (Work on start/Managed by Plugin) Initial columns, if it is zero it will be equal to 1 |
10 | | Save Rows Columns Count on exit | Save the current columns and rows you split before exiting to open them on next startup |
11 |
12 | ### Behaviour
13 | | Setting | Description |
14 | | ------------ | ------------ |
15 | | Refresh Warnings On Save | Check on save if all scripts has new errors/warnings|
16 |
17 | ### Window
18 | | Setting | Description |
19 | | ------------ | ------------ |
20 | | Use Highlight Selected | Show fade color when focus a window|
21 | | Highlight Selected Color | Color of the fader when focus |
22 |
23 | ### Editor
24 | | Setting | Description |
25 | | ------------ | ------------ |
26 | | Minimap for unfocus window | Hide minimap of the script when focus another window |
27 | | Out Focus Color Enabled | Enable set a modulate color when focus another window |
28 | | Out Focus Color Value | Modulate color when focus another window |
29 |
30 | ### Editor/Behaviour
31 | | Setting | Description |
32 | | ------------ | ------------ |
33 | | Expand on focus | Enable expand when focus a split window shrunk |
34 | | Can expand on same focus | Force Expand if the window current focused is shrunk |
35 | | Smooth expand | Enable Smooth when expand the window shrunk |
36 | | Smooth expand time| Total time for complete expand the window shrunk|
37 | | Swap by double click separator button | Enable swap between windows when double click in separator button |
38 |
39 | ### Editor/Behaviour/Back And Forward
40 | | Setting | Description |
41 | | ------------ | ------------ |
42 | | Handle Back And Forward | Enable handler event of back and forward by internal function addon |
43 | | History Size | Max buffer size history of scripts/documents recent opened by the window split (Are stored independently by window)
44 | | Using As Next And Back Tab| Change Behaviour and use back and forward as next or back aviable tab |
45 | | Backward Key Button Path| Path of resource setting of backward key button |
46 | | Forward Key Button Path| Path of resource setting of forward key button |
47 | | Backward Mouse Button Path| Path of resource setting of backward mouse button |
48 | | Forward Mouse Button Path| Path of resource setting of forward mouse button |
49 | | Use Native Handler When There Are No More Tabs| Enable leave to godot handle the back and forward when not exist more tabs in the focused window |
50 |
51 | ### Editor/Split
52 | This section work only when you add new split/s.
53 | in old versions < 0.3 was more useful.
54 |
55 | | Setting | Description |
56 | | ------------ | ------------ |
57 | | Reopen Last Closed Editor On Add Split | Enable open a script recent used and closed (Only for script / unless you make a request on github and change your mind)|
58 | | Remember Last Used Editor Buffer Size | Max last scripts for remember, maybe you want increase if you usually work with more than 4 windows |
59 |
60 |
61 | ### Line
62 | | Setting | Description |
63 | | ------------ | ------------ |
64 | | Size | Line width |
65 | | Color | Color of the Line, magenta is default that mean use editor color |
66 | | Draggable | Allow drag the Line pressing the primary mouse button |
67 | | Expand by Double Click | When you press with mouse (double click) the line back to initial position |
68 |
69 | ### Button
70 | | Setting | Description |
71 | | ------------ | ------------ |
72 | | Size | Button width |
73 | | Modulate | Modulate Button Color |
74 | | Icon Path | Texture path for the button |
75 | #
76 | Script Spliter tool plugin for Community Of Godot 4, created by Twister.
77 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2025 Twister
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Script-Spliter
2 | Tool addon for Godot 4, this addon allow split the script editor window.
3 |
4 | [](https://godotengine.org/)  
5 |
6 |
7 | ## Table of contents
8 |
9 | - [Preview](#preview-)
10 | - [News](#news-)
11 | - [Features](#features-)
12 | - [Roadmap](#roadmap)
13 | - [How-Work](#how-work)
14 | - [Know Issues](#know-issues-)
15 | - [Special Thanks](#special-thanks-)
16 |
17 |
18 | # Preview [↑](#table-of-contents)
19 |
20 | ### V0.2 Video Preview
21 | [](https://youtu.be/ISSu45qzWWw)
22 |
23 | ### V0.1 Image Preview
24 | 
25 |
26 | # NEWS [↑](#table-of-contents)
27 |
28 | ### V0.3
29 |
30 |
31 |
32 | Introduction to using tabs
33 |
34 | * Tabs can be dragged to another window, now you can move one document from a window split to another window split.
35 | * Backward and Forward has an internal function with the plugin. (Thanks to [@adancau](https://github.com/adancau))
36 |
37 | >*I had initially planned to create a Notepad++ like functionality as a reference for version 0.3, but it has been decided to maintain the functionality and backward compatibility to avoid confusion for those using the plugin since version 0.1.*
38 |
39 | ### Drag and Drop
40 | You can use tabs to drag and drop into another split window to switch between editors or you can drag directly from the script list and drop into the split window.
41 |
42 | ### Modify Backward and Forward buttons
43 | You can modify the buttons by input resources in "script_spliter/io" folder,
44 | seen in [Backward/Forward Request](https://github.com/CodeNameTwister/Script-Spliter/issues/9#issuecomment-2917555511)
45 |
46 | ### Using Backward/Forward
47 | It is per-window history, this means that if you've navigated through three different scripts within the window, moving back will only move between those three. The same happens when moving forward, and it's not affected by any other movements you've made in another window.
48 | >[!TIP]
49 | >In editor settings you have the checkbox: "using_as_next_and_back_tab" if you want use Backward/Forward move like Back/Next Tab.
50 | #
51 |
52 | ### V0.2
53 |
54 |
55 |
56 | The internal workflow has been modified, but the functionality of its predecessor version has been maintained.
57 |
58 | This has been done to maintain compatibility when using shorteners like Ctrl + [1, 2, 3, 4] to change the split style, this might be broken in version 0.3, see the roadmap for details.
59 |
60 | ### Differences with version 0.1
61 | * It more closely resembles the default editor window.
62 | * Reduces window switching time.
63 | * Allows you to zoom in on all windows.
64 | * You may have a separate script documentation help window.
65 | * Some visual aspects and configurable parameters in Editor Settings.
66 | * More Features and Split Options.
67 |
68 | >[!NOTE]
69 | >This plugin uses another built-in plugin created by me called [Multi Split Container](https://github.com/CodeNameTwister/Multi-Split-Container)
70 |
71 |
72 | # Features [↑](#table-of-contents)
73 | * Split Window of Document Files Like Script/Document Helper Window.
74 | * Split Two Window Horizontal/Vertical.
75 | * Split Three Window Horizontal/Vertical.
76 | * Split Four Window Squared.
77 | * Split Custom Window defined by you. *(using RMB context menu or Tool Menu)*
78 | * Plugins Setting in Editor Settings. *(In the section Plugin, you can see with advance option enabled!)*
79 | * Pop Script: Make Floating Script in Separate Window using RMB context menu.
80 | * Refresh Warnings changes in all opened windows when project is saved *(Errors/Warning Script)*
81 | * Reopen recently closed/changed scripts when adding a split. (Suggestion: [#5](https://github.com/CodeNameTwister/Script-Spliter/issues/5))
82 | * Swap between windows by double-clicking the draggable button. (Suggestion: [#8](https://github.com/CodeNameTwister/Script-Spliter/issues/8]))
83 | * Back and Forward between script opened by the window splited. (Suggestion: [#9](https://github.com/CodeNameTwister/Script-Spliter/issues/9]))
84 | * Drag and Drop tabs between windows.
85 |
86 | >[!WARNING]
87 | >Experimental Refresh Warnings *(This option can be disabled on Editor Settings)*
88 |
89 | >[!NOTE]
90 | >In [DocEditorSettings.md](DocEditorSettings.md) you can see the description of the settings.
91 |
92 |
93 |
94 | # ROADMAP
95 | * Version >= 0.2.3: ~Flying scripts; Allow split in separate windows.~
96 | * Version >= 0.3:
97 | * ~Change logo/colors: Currently the pet I use on github is placed and it is planned to change it to one more suitable for the plugin.~
98 | * ~Using tabs for drag and drop between windows.~ *~(WARNING! : Some features offered in previous versions may change)~*
99 | * Version >= 0.4: Revisit Pop Scripts Issues.
100 |
101 | # How Work
102 |
103 | >[!TIP]
104 | > Now you can add or remove split with using context menu, the popup menu appear using the RMB (Right mouse button) in the editor.
105 | >
106 | > * Use Add/Remove split if you want increase or decrease the auto split window function.
107 |
108 | >[!NOTE]
109 | > Keep in mind, the style when appear new window (As Column or Row) depend of you configuration split style!
110 | >
111 | > *This may change in future releases.*
112 |
113 | ### Enable by shortcut [↑](#table-of-contents)
114 | * Press shortcut (**Ctrl + 1**) for set one window.
115 | * Press shortcut (**Ctrl + 2**) for set one split of two windows: Horizontal.
116 | * Press shortcut (**Ctrl + 3**) for set one split of two windows: Vertical.
117 | * Press shortcut (**Ctrl + 4**) for set two split of three windows: Horizontal.
118 | * Press shortcut (**Ctrl + 5**) for set two split of three windows: Vertical.
119 | * Press shortcut (**Ctrl + 6**) for set three split of four windows: Squared split.
120 |
121 | ### Enable by Tool Menu [↑](#table-of-contents)
122 | For enable the Script spliter menu go to **Project > Tools > Script Spliter**.
123 |
124 | 
125 |
126 | You can select split type and disabled, see the image.
127 |
128 | 
129 |
130 | Once activated, you'll see a draggable line like the one in the image, indicating that the plugin is active.
131 |
132 | >[!IMPORTANT]
133 | >This section will automatically expand when you open **two scripts**.
134 |
135 | The position of the line will vary depending on the selection of horizontal or vertical.
136 |
137 | 
138 |
139 | # Know Issues [↑](#table-of-contents)
140 | ### Version 0.2.3
141 | The **PopScripts** (Floating Scripts)
142 | It still has some issues related to the editor focus, which means that if you switch scenes, some features like the search engine within the PopScript may be affected and become unresponsive.
143 |
144 | # Special Thanks 📜
145 | This section lists users who have contributed to improving the quality of this project.
146 |
147 | [@adancau](https://github.com/adancau)
148 |
149 | #
150 | Copyrights (c) CodeNameTwister. See [LICENSE](LICENSE) for details.
151 |
152 | [godot engine]: https://godotengine.org/
153 |
--------------------------------------------------------------------------------
/addons/script_spliter/assets/File.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/addons/script_spliter/assets/File.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://ljki8k8ckjtt"
6 | path="res://.godot/imported/File.svg-8fbfaa1520af51e8b790d847f68ee557.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://addons/script_spliter/assets/File.svg"
14 | dest_files=["res://.godot/imported/File.svg-8fbfaa1520af51e8b790d847f68ee557.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=1.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/addons/script_spliter/assets/dd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeNameTwister/Script-Spliter/8312d5b0eb2b24c85c669d5f9b4092ae518dc8da/addons/script_spliter/assets/dd.png
--------------------------------------------------------------------------------
/addons/script_spliter/assets/dd.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://cxds5tr6aq5v3"
6 | path="res://.godot/imported/dd.png-3704eaaffe380d5ad414e6e7fce28e96.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://addons/script_spliter/assets/dd.png"
14 | dest_files=["res://.godot/imported/dd.png-3704eaaffe380d5ad414e6e7fce28e96.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 |
--------------------------------------------------------------------------------
/addons/script_spliter/assets/github_CodeNameTwister.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeNameTwister/Script-Spliter/8312d5b0eb2b24c85c669d5f9b4092ae518dc8da/addons/script_spliter/assets/github_CodeNameTwister.png
--------------------------------------------------------------------------------
/addons/script_spliter/assets/github_CodeNameTwister.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://tgaoyybc2iji"
6 | path="res://.godot/imported/github_CodeNameTwister.png-88287e5d04f5b5c67334953a8a4ce6f2.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://addons/script_spliter/assets/github_CodeNameTwister.png"
14 | dest_files=["res://.godot/imported/github_CodeNameTwister.png-88287e5d04f5b5c67334953a8a4ce6f2.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 |
--------------------------------------------------------------------------------
/addons/script_spliter/assets/placeholder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeNameTwister/Script-Spliter/8312d5b0eb2b24c85c669d5f9b4092ae518dc8da/addons/script_spliter/assets/placeholder.png
--------------------------------------------------------------------------------
/addons/script_spliter/assets/placeholder.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://b4vaut1t0ox3c"
6 | path="res://.godot/imported/placeholder.png-fc12f7043a3f8f5693de9ceb8fdb24a0.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://addons/script_spliter/assets/placeholder.png"
14 | dest_files=["res://.godot/imported/placeholder.png-fc12f7043a3f8f5693de9ceb8fdb24a0.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/_POPGDScript_.gd:
--------------------------------------------------------------------------------
1 | @warning_ignore("empty_file")
2 | # This script is only placeholder for handle pop script input.
3 |
4 | # This should closed and removed after closing the pop-up.
5 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/_POPGDScript_.gd.uid:
--------------------------------------------------------------------------------
1 | uid://bkfdswehvs8sf
2 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/btn_callback.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | extends Button
3 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
4 | # Script Spliter
5 | # https://github.com/CodeNameTwister/Script-Spliter
6 | #
7 | # Script Spliter addon for godot 4
8 | # author: "Twister"
9 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
10 |
11 | func _pressed() -> void:
12 | var parent : Node = owner
13 | if parent == null:
14 | parent = get_parent()
15 | if parent:
16 | if parent.has_method(name):
17 | parent.call(name)
18 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/btn_callback.gd.uid:
--------------------------------------------------------------------------------
1 | uid://bo38caobn2x7a
2 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/context_window.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | extends EditorContextMenuPlugin
3 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
4 | # Script Spliter
5 | # https://github.com/CodeNameTwister/Script-Spliter
6 | #
7 | # Script Spliter addon for godot 4
8 | # author: "Twister"
9 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
10 | var CONTEXT : String = "CUSTOM"
11 | var ICON : Texture = null
12 | var SHORTCUT : Shortcut = null
13 | var CALLABLE : Callable
14 | var VALIDATOR : Callable
15 |
16 | func _init(context : String, handle : Callable, validator : Callable, icon : Texture, input_key : Array[InputEvent] = []):
17 | CONTEXT = context
18 | CALLABLE = handle
19 | ICON = icon
20 | VALIDATOR = validator
21 | if input_key.size() > 0:
22 | SHORTCUT = Shortcut.new()
23 | SHORTCUT.events = input_key
24 | add_menu_shortcut(SHORTCUT, handle)
25 |
26 | func _popup_menu(paths : PackedStringArray):
27 | if VALIDATOR.is_valid():
28 | if !VALIDATOR.call(paths):
29 | return
30 | if SHORTCUT:
31 | add_context_menu_item_from_shortcut(CONTEXT, SHORTCUT, ICON)
32 | else:
33 | if CALLABLE.is_valid():
34 | add_context_menu_item(CONTEXT, CALLABLE, ICON)
35 | else:
36 | push_error("Not valid callaback!")
37 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/context_window.gd.uid:
--------------------------------------------------------------------------------
1 | uid://dmf7coyb6hgbe
2 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/custom_options.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | extends Control
3 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
4 | # Script Spliter
5 | # https://github.com/CodeNameTwister/Script-Spliter
6 | #
7 | # Script Spliter addon for godot 4
8 | # author: "Twister"
9 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
10 |
11 | @export var columns : SpinBox
12 | @export var rows : SpinBox
13 |
14 | func set_values(_columns : int, _rows : int) -> void:
15 | columns.value = _columns
16 | rows.value = _rows
17 |
18 | func get_columns_value() -> int:
19 | return max(columns.value, 1)
20 |
21 | func get_rows_value() -> int:
22 | return max(rows.value, 1)
23 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/custom_options.gd.uid:
--------------------------------------------------------------------------------
1 | uid://y3jbguu2nw5c
2 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/flying_script.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | extends Window
3 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
4 | # Script Spliter
5 | # https://github.com/CodeNameTwister/Script-Spliter
6 | #
7 | # Script Spliter addon for godot 4f
8 | # author: "Twister"
9 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
10 | signal on_close(window : Window)
11 |
12 | @export var _container : Control = null
13 | @export var _base_control : TabContainer = null
14 | @export var _always_top : Button = null
15 | @export var _close : Button = null
16 | @export var _root : Control = null
17 |
18 | var proxy : Control = null
19 | var replacer : Node = null
20 | var controller : Object = null
21 |
22 | func set_base_control(node : Node) -> void:
23 | if _base_control:
24 | _base_control.queue_sort()
25 | _base_control = node
26 | if _container:
27 | _container.add_child(node)
28 | return
29 | add_child(node)
30 |
31 | if node is Control:
32 | node.size = node.get_parent().size
33 |
34 | func get_base_control() -> TabContainer:
35 | return _base_control
36 |
37 | func _init() -> void:
38 | visible = false
39 | close_requested.connect(_on_close)
40 | visibility_changed.connect(_on_visibility)
41 | focus_entered.connect(_on_focus)
42 | focus_exited.connect(_on_focus_exited)
43 |
44 | func _get_edit(n : Node) -> CodeEdit:
45 | if n is CodeEdit:
46 | return n
47 | for x : Node in n.get_children():
48 | return _get_edit(x)
49 | return null
50 |
51 | func _on_focus() -> void:
52 | if replacer == null:
53 | var script_editor: ScriptEditor = EditorInterface.get_script_editor()
54 | var root : Node = script_editor.get_child(0).get_child(1).get_child(1)
55 | if root.get_child_count() > 2:
56 | replacer = root.get_child(2)
57 | if "FindReplaceBar" in replacer.name:
58 | replacer.get_parent().remove_child(replacer)
59 |
60 | if is_instance_valid(_root):
61 | _root.add_child(replacer)
62 | else:
63 | add_child(replacer)
64 |
65 | if is_instance_valid(controller):
66 | controller.emit_signal.call_deferred(&"focus", controller)
67 |
68 | func _update_name() -> void:
69 | if is_queued_for_deletion():
70 | return
71 | if is_instance_valid(_base_control):
72 | if _base_control.current_tab > -1:
73 | title = "Script-Spliter: {0}".format([_base_control.get_tab_title(_base_control.current_tab)])
74 | return
75 | title = "Script-Spliter: Pop Script"
76 |
77 | func _on_tabity(__ : int) -> void:
78 | _update_name.call_deferred()
79 |
80 | func _on_always_top() -> void:
81 | if transient:
82 | return
83 | always_on_top = !always_on_top
84 |
85 | func _shortcut_input(event: InputEvent) -> void:
86 | if is_instance_valid(proxy):
87 | var vp : Viewport = proxy.get_viewport()
88 | if vp and vp != get_viewport():
89 | vp.push_input(event)
90 |
91 | func _ready() -> void:
92 | set_process_shortcut_input(true)
93 | if _always_top:
94 | if !_always_top.pressed.is_connected(_on_always_top):
95 | _always_top.pressed.connect(_on_always_top)
96 | if _close:
97 | if !_close.pressed.is_connected(_on_close):
98 | _close.pressed.connect(_on_close)
99 | if _base_control:
100 | if !_base_control.tab_changed.is_connected(_on_tabity):
101 | _base_control.tab_changed.connect(_on_tabity)
102 | if !_base_control.child_entered_tree.is_connected(_on_child):
103 | _base_control.child_entered_tree.connect(_on_child)
104 | if !_base_control.child_exiting_tree.is_connected(_out_child):
105 | _base_control.child_exiting_tree.connect(_out_child)
106 |
107 | var root : Control = EditorInterface.get_base_control()
108 | if root:
109 | add_theme_stylebox_override(&"Panel",root.get_theme_stylebox("panel", "PanelContainer"))
110 |
111 | func _connect(n : Node, e : bool) -> void:
112 | if n is CodeEdit:
113 | if e:
114 | if !n.focus_entered.is_connected(_on_focus):
115 | n.focus_entered.connect(_on_focus)
116 | else:
117 | if n.focus_entered.is_connected(_on_focus):
118 | n.focus_entered.disconnect(_on_focus)
119 | return
120 | for x : Node in n.get_children():
121 | _connect(x, e)
122 |
123 | func _on_child(n : Node) -> void:
124 | if n is Control:
125 | _connect(n, true)
126 |
127 | func _out_child(n : Node) -> void:
128 | if n is Control:
129 | _connect(n, false)
130 |
131 | func _on_visibility() -> void:
132 | if !visible:
133 | _on_focus_exited()
134 | _on_close()
135 | return
136 | set_deferred(&"always_top", false)
137 | set_process(true)
138 | _update_name.call_deferred()
139 |
140 | func _on_close() -> void:
141 | on_close.emit(self)
142 |
143 | if _base_control and _base_control.get_child_count() < 1:
144 | queue_free()
145 |
146 | func _on_focus_exited() -> void:
147 | if replacer != null:
148 | var script_editor: ScriptEditor = EditorInterface.get_script_editor()
149 | var root : Node = script_editor.get_child(0).get_child(1).get_child(1)
150 |
151 | var parent : Node = replacer.get_parent()
152 | if parent != root:
153 | if is_instance_valid(parent):
154 | parent.remove_child(replacer)
155 | root.add_child(replacer)
156 | replacer = null
157 |
158 | func _notification(what: int) -> void:
159 | if what == NOTIFICATION_PREDELETE:
160 | if is_instance_valid(replacer):
161 | var script_editor: ScriptEditor = EditorInterface.get_script_editor()
162 | var root : Node = script_editor.get_child(0).get_child(1).get_child(1)
163 |
164 | var parent : Node = replacer.get_parent()
165 | if parent != root:
166 | if is_instance_valid(parent):
167 | parent.remove_child(replacer)
168 | root.add_child(replacer)
169 | replacer = null
170 | if is_instance_valid(controller):
171 | controller.call(&"reset")
172 |
173 | func _move_to_center() -> void:
174 | move_to_center()
175 |
176 | func _alpha_value(v : float) -> void:
177 | get_child(0).modulate.a = v
178 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/flying_script.gd.uid:
--------------------------------------------------------------------------------
1 | uid://dbkyfe5ri2p73
2 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/flying_script.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=5 format=3 uid="uid://cr2xovtt6uo7s"]
2 |
3 | [ext_resource type="Script" uid="uid://dbkyfe5ri2p73" path="res://addons/script_spliter/context/flying_script.gd" id="1_wfm3d"]
4 | [ext_resource type="Texture2D" uid="uid://r6u1jtnbr4eg" path="res://addons/script_spliter/context/icons/atop.png" id="2_q3d74"]
5 | [ext_resource type="Script" uid="uid://bo38caobn2x7a" path="res://addons/script_spliter/context/btn_callback.gd" id="3_1p1sv"]
6 |
7 | [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_q3d74"]
8 | content_margin_left = 3.0
9 | content_margin_top = 3.0
10 | content_margin_right = 3.0
11 | content_margin_bottom = 3.0
12 | bg_color = Color(0.1155, 0.132, 0.1595, 1)
13 | corner_detail = 1
14 | anti_aliasing = false
15 |
16 | [node name="FlyingScript" type="Window" node_paths=PackedStringArray("_container", "_always_top", "_close", "_root")]
17 | title = "Script-Spliter: Pop Script"
18 | initial_position = 4
19 | size = Vector2i(805, 512)
20 | visible = false
21 | wrap_controls = true
22 | script = ExtResource("1_wfm3d")
23 | _container = NodePath("PanelContainer/VC")
24 | _always_top = NodePath("PanelContainer/VC/HB/AlwaysTop")
25 | _close = NodePath("PanelContainer/VC/HB/Close")
26 | _root = NodePath("PanelContainer/VC")
27 |
28 | [node name="PanelContainer" type="PanelContainer" parent="."]
29 | anchors_preset = 15
30 | anchor_right = 1.0
31 | anchor_bottom = 1.0
32 | grow_horizontal = 2
33 | grow_vertical = 2
34 | theme_override_styles/panel = SubResource("StyleBoxFlat_q3d74")
35 |
36 | [node name="VC" type="VBoxContainer" parent="PanelContainer"]
37 | layout_mode = 2
38 | size_flags_horizontal = 3
39 | size_flags_vertical = 3
40 |
41 | [node name="HB" type="HBoxContainer" parent="PanelContainer/VC"]
42 | layout_mode = 2
43 | theme_override_constants/separation = 8
44 |
45 | [node name="AlwaysTop" type="Button" parent="PanelContainer/VC/HB"]
46 | layout_mode = 2
47 | tooltip_text = "Set always front visible the current window"
48 | theme_override_font_sizes/font_size = 12
49 | toggle_mode = true
50 | text = "Always Top"
51 | icon = ExtResource("2_q3d74")
52 | flat = true
53 |
54 | [node name="_move_to_center" type="Button" parent="PanelContainer/VC/HB"]
55 | layout_mode = 2
56 | tooltip_text = "Move the window to center"
57 | theme_override_font_sizes/font_size = 12
58 | toggle_mode = true
59 | text = "Move To Center"
60 | flat = true
61 | script = ExtResource("3_1p1sv")
62 |
63 | [node name="Close" type="Button" parent="PanelContainer/VC/HB"]
64 | visible = false
65 | custom_minimum_size = Vector2(32, 0)
66 | layout_mode = 2
67 | size_flags_horizontal = 10
68 | tooltip_text = "Close the window"
69 | text = "X"
70 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/flying_script_font.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="LabelSettings" format=3 uid="uid://cdrt4b0qrb77v"]
2 |
3 | [resource]
4 | font_size = 12
5 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/atop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeNameTwister/Script-Spliter/8312d5b0eb2b24c85c669d5f9b4092ae518dc8da/addons/script_spliter/context/icons/atop.png
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/atop.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://r6u1jtnbr4eg"
6 | path="res://.godot/imported/atop.png-1d61cb69aae60a076cd60a0a3f1cc72c.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://addons/script_spliter/context/icons/atop.png"
14 | dest_files=["res://.godot/imported/atop.png-1d61cb69aae60a076cd60a0a3f1cc72c.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/expand.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/expand.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://cractge21enk"
6 | path="res://.godot/imported/expand.svg-963ea7d55c7ac4362bba429ef9c40e46.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://addons/script_spliter/context/icons/expand.svg"
14 | dest_files=["res://.godot/imported/expand.svg-963ea7d55c7ac4362bba429ef9c40e46.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=1.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/sp_2H.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeNameTwister/Script-Spliter/8312d5b0eb2b24c85c669d5f9b4092ae518dc8da/addons/script_spliter/context/icons/sp_2H.png
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/sp_2H.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://c1kjfqirfexvp"
6 | path="res://.godot/imported/sp_2H.png-c589a7f8579a9ee26d2875c35e52e183.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://addons/script_spliter/context/icons/sp_2H.png"
14 | dest_files=["res://.godot/imported/sp_2H.png-c589a7f8579a9ee26d2875c35e52e183.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/sp_2V.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeNameTwister/Script-Spliter/8312d5b0eb2b24c85c669d5f9b4092ae518dc8da/addons/script_spliter/context/icons/sp_2V.png
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/sp_2V.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://d1r72ixdgbwl6"
6 | path="res://.godot/imported/sp_2V.png-39915ece37e791e8d9a130c4c3240f49.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://addons/script_spliter/context/icons/sp_2V.png"
14 | dest_files=["res://.godot/imported/sp_2V.png-39915ece37e791e8d9a130c4c3240f49.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/sp_3H.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeNameTwister/Script-Spliter/8312d5b0eb2b24c85c669d5f9b4092ae518dc8da/addons/script_spliter/context/icons/sp_3H.png
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/sp_3H.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://32xnl4cu46pj"
6 | path="res://.godot/imported/sp_3H.png-09e8b9f9a346f328495f443e565ad878.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://addons/script_spliter/context/icons/sp_3H.png"
14 | dest_files=["res://.godot/imported/sp_3H.png-09e8b9f9a346f328495f443e565ad878.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/sp_3V.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeNameTwister/Script-Spliter/8312d5b0eb2b24c85c669d5f9b4092ae518dc8da/addons/script_spliter/context/icons/sp_3V.png
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/sp_3V.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://b4cmfno0ixqnm"
6 | path="res://.godot/imported/sp_3V.png-6984dd1b3c8e11f26b5964981b46a4b8.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://addons/script_spliter/context/icons/sp_3V.png"
14 | dest_files=["res://.godot/imported/sp_3V.png-6984dd1b3c8e11f26b5964981b46a4b8.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/sp_4S.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeNameTwister/Script-Spliter/8312d5b0eb2b24c85c669d5f9b4092ae518dc8da/addons/script_spliter/context/icons/sp_4S.png
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/sp_4S.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://bf2bjkoock7re"
6 | path="res://.godot/imported/sp_4S.png-38dbb9b7da5a9846aab652bf564a4249.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://addons/script_spliter/context/icons/sp_4S.png"
14 | dest_files=["res://.godot/imported/sp_4S.png-38dbb9b7da5a9846aab652bf564a4249.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/sp_custom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeNameTwister/Script-Spliter/8312d5b0eb2b24c85c669d5f9b4092ae518dc8da/addons/script_spliter/context/icons/sp_custom.png
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/sp_custom.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://bdxvp5dyj8y0r"
6 | path="res://.godot/imported/sp_custom.png-91b7ef0ad7d63ebf7700a2047739db70.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://addons/script_spliter/context/icons/sp_custom.png"
14 | dest_files=["res://.godot/imported/sp_custom.png-91b7ef0ad7d63ebf7700a2047739db70.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/sp_disable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeNameTwister/Script-Spliter/8312d5b0eb2b24c85c669d5f9b4092ae518dc8da/addons/script_spliter/context/icons/sp_disable.png
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/sp_disable.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://dmvcijsjhb5pc"
6 | path="res://.godot/imported/sp_disable.png-d75c06feba36dd2af819e235b22c2ea6.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://addons/script_spliter/context/icons/sp_disable.png"
14 | dest_files=["res://.godot/imported/sp_disable.png-d75c06feba36dd2af819e235b22c2ea6.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/split_cminus.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
23 |
41 |
49 |
50 |
52 |
54 |
55 | split-screen
57 |
61 |
65 |
74 |
76 |
77 |
79 | split-screen
80 |
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/split_cminus.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://c1b7aoplxr0x7"
6 | path="res://.godot/imported/split_cminus.svg-3d236e355acd272b8108cca3f8e1c7f3.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://addons/script_spliter/context/icons/split_cminus.svg"
14 | dest_files=["res://.godot/imported/split_cminus.svg-3d236e355acd272b8108cca3f8e1c7f3.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=8.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/split_cplus.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
23 |
41 |
49 |
50 |
52 |
54 |
55 | split-screen
57 |
61 |
65 |
74 |
83 |
85 |
86 |
88 | split-screen
89 |
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/split_cplus.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://bvyjqo1dus1xu"
6 | path="res://.godot/imported/split_cplus.svg-5f233626ec643447e303aa2d98ed8d14.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://addons/script_spliter/context/icons/split_cplus.svg"
14 | dest_files=["res://.godot/imported/split_cplus.svg-5f233626ec643447e303aa2d98ed8d14.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=8.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/split_rminus.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
23 |
41 |
49 |
50 |
52 |
54 |
55 | split-screen
57 |
61 |
65 |
74 |
76 |
77 |
79 | split-screen
80 |
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/split_rminus.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://bvjk4po8w2m2j"
6 | path="res://.godot/imported/split_rminus.svg-6f9fc75a64032d6fe5bdcc9bc3bf399d.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://addons/script_spliter/context/icons/split_rminus.svg"
14 | dest_files=["res://.godot/imported/split_rminus.svg-6f9fc75a64032d6fe5bdcc9bc3bf399d.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=8.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/split_rplus.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
23 |
41 |
49 |
50 |
52 |
54 |
55 | split-screen
57 |
61 |
65 |
74 |
83 |
85 |
86 |
88 | split-screen
89 |
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/icons/split_rplus.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://1sqajw0mikdj"
6 | path="res://.godot/imported/split_rplus.svg-a26b8d20ca41f0ec060d5e021092eced.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://addons/script_spliter/context/icons/split_rplus.svg"
14 | dest_files=["res://.godot/imported/split_rplus.svg-a26b8d20ca41f0ec060d5e021092eced.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=8.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/menu_tool.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | extends Window
3 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
4 | # Script Spliter
5 | # https://github.com/CodeNameTwister/Script-Spliter
6 | #
7 | # Script Spliter addon for godot 4
8 | # author: "Twister"
9 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
10 | @export var _container : Node
11 | @export var _custom_options : Control
12 |
13 | var _plugin : Object = null
14 |
15 | func _init_1() -> void:
16 | if _container and _plugin:
17 | var columns : int = _plugin.call(&"get_split_columns")
18 | var rows : int = _plugin.call(&"get_split_rows")
19 | set_split_value(columns, rows)
20 |
21 | func _ready() -> void:
22 | if _custom_options:
23 | _custom_options.visible = false
24 |
25 | if !visibility_changed.is_connected(_on_visibility_change):
26 | visibility_changed.connect(_on_visibility_change)
27 |
28 | _init_1()
29 |
30 | func set_plugin(current_plugin : Object) -> void:
31 | _plugin = current_plugin
32 |
33 | func _on_visibility_change() -> void:
34 | if !visible: return
35 | if !_plugin:
36 | return
37 |
38 | _init_1()
39 |
40 | func enable_options() -> void:
41 | var custom : CheckBox = _container.get_child(_container.get_child_count() - 1)
42 | for c : Node in _container.get_children():
43 | if c is CheckBox:
44 | c.button_pressed = false
45 |
46 | _custom_options.visible = true
47 | custom.button_pressed = true
48 |
49 | func set_split_value(columns : int, rows : int) -> void:
50 | var current : Node = null
51 | var custom : CheckBox = _container.get_child(_container.get_child_count() - 1)
52 | for c : Node in _container.get_children():
53 | if c is CheckBox:
54 | if c.columns == columns and c.rows == rows:
55 | current = c
56 | c.button_pressed = true
57 | continue
58 | c.button_pressed = false
59 |
60 | if columns < 2 and rows < 2:
61 | current = _container.get_child(0)
62 | if current is CheckBox:
63 | current.button_pressed = true
64 | else:
65 | current = null
66 |
67 | _custom_options.visible = current == null
68 | custom.button_pressed = _custom_options.visible
69 | _custom_options.set_values(columns, rows)
70 |
71 | func _on_ok_pressed() -> void:
72 | var columns : int = _custom_options.get_columns_value()
73 | var rows : int = _custom_options.get_rows_value()
74 | if !_plugin:
75 | push_error("[ERROR] Can not set split type!")
76 | else:
77 | _plugin.call(&"set_type_split", columns, rows)
78 | hide()
79 |
80 | func _on_cancel_pressed() -> void:
81 | hide()
82 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/menu_tool.gd.uid:
--------------------------------------------------------------------------------
1 | uid://4wllvh127dwh
2 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/menu_tool.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=15 format=3 uid="uid://csu7djr8m1mgb"]
2 |
3 | [ext_resource type="Script" uid="uid://4wllvh127dwh" path="res://addons/script_spliter/context/menu_tool.gd" id="1_00j1l"]
4 | [ext_resource type="Texture2D" uid="uid://tgaoyybc2iji" path="res://addons/script_spliter/assets/github_CodeNameTwister.png" id="2_bi1if"]
5 | [ext_resource type="Texture2D" uid="uid://dmvcijsjhb5pc" path="res://addons/script_spliter/context/icons/sp_disable.png" id="2_le2a0"]
6 | [ext_resource type="Script" uid="uid://bobw4q6hrbbox" path="res://addons/script_spliter/context/split_type_button.gd" id="3_h7rbp"]
7 | [ext_resource type="Texture2D" uid="uid://c1kjfqirfexvp" path="res://addons/script_spliter/context/icons/sp_2H.png" id="3_o7fne"]
8 | [ext_resource type="Texture2D" uid="uid://d1r72ixdgbwl6" path="res://addons/script_spliter/context/icons/sp_2V.png" id="4_js2dr"]
9 | [ext_resource type="Texture2D" uid="uid://32xnl4cu46pj" path="res://addons/script_spliter/context/icons/sp_3H.png" id="5_h32ac"]
10 | [ext_resource type="Texture2D" uid="uid://b4cmfno0ixqnm" path="res://addons/script_spliter/context/icons/sp_3V.png" id="6_h7rbp"]
11 | [ext_resource type="Texture2D" uid="uid://bf2bjkoock7re" path="res://addons/script_spliter/context/icons/sp_4S.png" id="7_bi1if"]
12 | [ext_resource type="Texture2D" uid="uid://bdxvp5dyj8y0r" path="res://addons/script_spliter/context/icons/sp_custom.png" id="10_0n25h"]
13 | [ext_resource type="Script" uid="uid://y3jbguu2nw5c" path="res://addons/script_spliter/context/custom_options.gd" id="11_2o3ku"]
14 |
15 | [sub_resource type="LabelSettings" id="LabelSettings_00j1l"]
16 | font_size = 28
17 | outline_size = 4
18 | outline_color = Color(0, 0, 0, 1)
19 |
20 | [sub_resource type="LabelSettings" id="LabelSettings_2o3ku"]
21 | font_size = 12
22 | font_color = Color(1, 1, 1, 0.4)
23 |
24 | [sub_resource type="LabelSettings" id="LabelSettings_0n25h"]
25 | font_size = 12
26 |
27 | [node name="MenuTool" type="PopupPanel" node_paths=PackedStringArray("_container", "_custom_options")]
28 | title = "Script Splitter Menu"
29 | position = Vector2i(0, 36)
30 | size = Vector2i(602, 382)
31 | visible = true
32 | script = ExtResource("1_00j1l")
33 | _container = NodePath("MarginContainer/MenContainer/Body")
34 | _custom_options = NodePath("MarginContainer/MenContainer/COptions")
35 |
36 | [node name="BG" type="ColorRect" parent="."]
37 | anchors_preset = 15
38 | anchor_right = 1.0
39 | anchor_bottom = 1.0
40 | offset_left = 4.0
41 | offset_top = 4.0
42 | offset_right = -4.0
43 | offset_bottom = -4.0
44 | grow_horizontal = 2
45 | grow_vertical = 2
46 | color = Color(0.249011, 0.114569, 0.435571, 1)
47 |
48 | [node name="BGTX" type="TextureRect" parent="."]
49 | modulate = Color(1, 1, 1, 0.34902)
50 | anchors_preset = 15
51 | anchor_right = 1.0
52 | anchor_bottom = 1.0
53 | offset_left = 4.0
54 | offset_top = 4.0
55 | offset_right = -4.0
56 | offset_bottom = -4.0
57 | grow_horizontal = 2
58 | grow_vertical = 2
59 | texture = ExtResource("2_bi1if")
60 | stretch_mode = 3
61 |
62 | [node name="MarginContainer" type="MarginContainer" parent="."]
63 | anchors_preset = 15
64 | anchor_right = 1.0
65 | anchor_bottom = 1.0
66 | offset_left = 4.0
67 | offset_top = 4.0
68 | offset_right = -4.0
69 | offset_bottom = -4.0
70 | grow_horizontal = 2
71 | grow_vertical = 2
72 | theme_override_constants/margin_left = 4
73 | theme_override_constants/margin_top = 4
74 | theme_override_constants/margin_right = 4
75 | theme_override_constants/margin_bottom = 4
76 |
77 | [node name="MenContainer" type="VBoxContainer" parent="MarginContainer"]
78 | layout_mode = 2
79 |
80 | [node name="PanelContainer2" type="PanelContainer" parent="MarginContainer/MenContainer"]
81 | layout_mode = 2
82 |
83 | [node name="Tittle" type="Label" parent="MarginContainer/MenContainer/PanelContainer2"]
84 | layout_mode = 2
85 | text = "Menu Split Selection"
86 | label_settings = SubResource("LabelSettings_00j1l")
87 | horizontal_alignment = 1
88 | uppercase = true
89 |
90 | [node name="Label" type="Label" parent="MarginContainer/MenContainer"]
91 | visible = false
92 | layout_mode = 2
93 | text = "Version 0.2
94 | Rows are created based on the maximum number of columns reached.
95 | Example: If you want two vertical scripts, you must define a maximum of one column."
96 | label_settings = SubResource("LabelSettings_2o3ku")
97 | horizontal_alignment = 1
98 | vertical_alignment = 1
99 |
100 | [node name="Body" type="GridContainer" parent="MarginContainer/MenContainer"]
101 | layout_mode = 2
102 | size_flags_horizontal = 4
103 | size_flags_vertical = 6
104 | theme_override_constants/h_separation = 8
105 | theme_override_constants/v_separation = 8
106 | columns = 2
107 |
108 | [node name="splited_off" type="CheckBox" parent="MarginContainer/MenContainer/Body"]
109 | layout_mode = 2
110 | tooltip_text = "Disabled Splited"
111 | button_pressed = true
112 | text = "Disabled"
113 | icon = ExtResource("2_le2a0")
114 | script = ExtResource("3_h7rbp")
115 |
116 | [node name="splited_two_horizontal" type="CheckBox" parent="MarginContainer/MenContainer/Body"]
117 | layout_mode = 2
118 | tooltip_text = "Two Horizontal Splited"
119 | text = "Two Horizontal"
120 | icon = ExtResource("3_o7fne")
121 | script = ExtResource("3_h7rbp")
122 | columns = 2
123 | rows = 1
124 |
125 | [node name="splited_two_vertical" type="CheckBox" parent="MarginContainer/MenContainer/Body"]
126 | layout_mode = 2
127 | tooltip_text = "Two Vertical Splited"
128 | text = "Two Vertical"
129 | icon = ExtResource("4_js2dr")
130 | script = ExtResource("3_h7rbp")
131 | columns = 1
132 | rows = 2
133 |
134 | [node name="splited_three_horizontal" type="CheckBox" parent="MarginContainer/MenContainer/Body"]
135 | layout_mode = 2
136 | tooltip_text = "Three Horizontal Splited"
137 | text = "Three Horizontal"
138 | icon = ExtResource("5_h32ac")
139 | script = ExtResource("3_h7rbp")
140 | columns = 3
141 | rows = 1
142 |
143 | [node name="splited_three_vertical" type="CheckBox" parent="MarginContainer/MenContainer/Body"]
144 | layout_mode = 2
145 | tooltip_text = "Three Vertical Splited"
146 | text = "Three Vertical"
147 | icon = ExtResource("6_h7rbp")
148 | script = ExtResource("3_h7rbp")
149 | columns = 1
150 | rows = 3
151 |
152 | [node name="splited_four_square" type="CheckBox" parent="MarginContainer/MenContainer/Body"]
153 | layout_mode = 2
154 | tooltip_text = "Square Splited"
155 | text = "Four Squared"
156 | icon = ExtResource("7_bi1if")
157 | script = ExtResource("3_h7rbp")
158 | columns = 2
159 | rows = 2
160 |
161 | [node name="CheckBox" type="CheckBox" parent="MarginContainer/MenContainer/Body"]
162 | layout_mode = 2
163 | text = "Custom Split"
164 | icon = ExtResource("10_0n25h")
165 | script = ExtResource("3_h7rbp")
166 | is_custom = true
167 |
168 | [node name="COptions" type="VBoxContainer" parent="MarginContainer/MenContainer" node_paths=PackedStringArray("columns", "rows")]
169 | visible = false
170 | layout_mode = 2
171 | script = ExtResource("11_2o3ku")
172 | columns = NodePath("ValueOptions/ColumnsValue")
173 | rows = NodePath("ValueOptions/RowsValue")
174 |
175 | [node name="Label" type="Label" parent="MarginContainer/MenContainer/COptions"]
176 | layout_mode = 2
177 | text = "Custom Split Options"
178 | label_settings = SubResource("LabelSettings_0n25h")
179 | horizontal_alignment = 1
180 |
181 | [node name="TextureRect" type="TextureRect" parent="MarginContainer/MenContainer/COptions"]
182 | layout_mode = 2
183 | texture = ExtResource("10_0n25h")
184 | expand_mode = 1
185 | stretch_mode = 5
186 |
187 | [node name="ValueOptions" type="HBoxContainer" parent="MarginContainer/MenContainer/COptions"]
188 | layout_mode = 2
189 |
190 | [node name="ColumnsValue" type="SpinBox" parent="MarginContainer/MenContainer/COptions/ValueOptions"]
191 | layout_mode = 2
192 | size_flags_horizontal = 3
193 | min_value = 1.0
194 | max_value = 30.0
195 | value = 1.0
196 | alignment = 1
197 | prefix = "Columns"
198 |
199 | [node name="RowsValue" type="SpinBox" parent="MarginContainer/MenContainer/COptions/ValueOptions"]
200 | layout_mode = 2
201 | size_flags_horizontal = 3
202 | min_value = 1.0
203 | max_value = 30.0
204 | value = 1.0
205 | alignment = 1
206 | prefix = "Rows"
207 |
208 | [node name="Separator" type="HSeparator" parent="MarginContainer/MenContainer"]
209 | layout_mode = 2
210 | size_flags_vertical = 8
211 |
212 | [node name="Footer" type="HBoxContainer" parent="MarginContainer/MenContainer"]
213 | layout_mode = 2
214 |
215 | [node name="OK" type="Button" parent="MarginContainer/MenContainer/Footer"]
216 | layout_mode = 2
217 | size_flags_horizontal = 3
218 | text = "Accept"
219 |
220 | [node name="Cancel" type="Button" parent="MarginContainer/MenContainer/Footer"]
221 | layout_mode = 2
222 | size_flags_horizontal = 3
223 | text = "Exit"
224 |
225 | [connection signal="pressed" from="MarginContainer/MenContainer/Footer/OK" to="." method="_on_ok_pressed"]
226 | [connection signal="pressed" from="MarginContainer/MenContainer/Footer/Cancel" to="." method="_on_cancel_pressed"]
227 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/panel_preview.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene format=3 uid="uid://di83u5ac2jww6"]
2 |
3 | [node name="PanelPreview" type="ColorRect"]
4 | anchors_preset = 15
5 | anchor_right = 1.0
6 | anchor_bottom = 1.0
7 | grow_horizontal = 2
8 | grow_vertical = 2
9 | color = Color(1.27546e-06, 0.644043, 0.17534, 0.4)
10 |
11 | [node name="Label" type="Label" parent="."]
12 | layout_mode = 1
13 | anchors_preset = 8
14 | anchor_left = 0.5
15 | anchor_top = 0.5
16 | anchor_right = 0.5
17 | anchor_bottom = 0.5
18 | offset_left = -44.5
19 | offset_top = -11.5
20 | offset_right = 44.5
21 | offset_bottom = 11.5
22 | grow_horizontal = 2
23 | grow_vertical = 2
24 | text = "DROP HERE"
25 | horizontal_alignment = 1
26 | vertical_alignment = 1
27 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/split_type_button.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | extends CheckBox
3 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
4 | # Script Spliter
5 | # https://github.com/CodeNameTwister/Script-Spliter
6 | #
7 | # Script Spliter addon for godot 4
8 | # author: "Twister"
9 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
10 |
11 | ## V0.2 Used now as max columns by row!, 0 as infinite horizontal.
12 | @export var columns : int = 0
13 | ## V0.2: Used now only as extra container if row > 1
14 | @export var rows : int = 0
15 |
16 | @export var is_custom : bool = false
17 |
18 | func _pressed() -> void:
19 | if is_custom:
20 | if owner.has_method(&"enable_options"):
21 | owner.call(&"enable_options")
22 | else:
23 | if owner.has_method(&"set_split_value"):
24 | owner.call(&"set_split_value", columns, rows)
25 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/split_type_button.gd.uid:
--------------------------------------------------------------------------------
1 | uid://bobw4q6hrbbox
2 |
--------------------------------------------------------------------------------
/addons/script_spliter/context/tab_preview.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=3 uid="uid://od0wse8oyuwn"]
2 |
3 | [ext_resource type="Texture2D" uid="uid://ljki8k8ckjtt" path="res://addons/script_spliter/assets/File.svg" id="1_obfxw"]
4 |
5 | [node name="preview_tab" type="Control"]
6 | layout_mode = 3
7 | anchors_preset = 0
8 |
9 | [node name="TabPreview" type="TextureRect" parent="."]
10 | layout_mode = 1
11 | anchors_preset = 15
12 | anchor_right = 1.0
13 | anchor_bottom = 1.0
14 | offset_left = -8.0
15 | offset_top = -8.0
16 | offset_right = -8.0
17 | offset_bottom = -8.0
18 | grow_horizontal = 2
19 | grow_vertical = 2
20 | texture = ExtResource("1_obfxw")
21 | expand_mode = 1
22 | stretch_mode = 2
23 |
24 | [node name="Label" type="Label" parent="."]
25 | layout_mode = 1
26 | anchors_preset = 5
27 | anchor_left = 0.5
28 | anchor_right = 0.5
29 | offset_left = -20.0
30 | offset_top = 4.0
31 | offset_right = 20.0
32 | offset_bottom = 27.0
33 | grow_horizontal = 2
34 | text = "FILE"
35 | horizontal_alignment = 1
36 | vertical_alignment = 1
37 |
--------------------------------------------------------------------------------
/addons/script_spliter/core/DDContainer.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | extends TabContainer
3 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
4 | # Script Spliter
5 | # https://github.com/CodeNameTwister/Script-Spliter
6 | #
7 | # Script Spliter addon for godot 4
8 | # author: "Twister"
9 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
10 |
11 | @warning_ignore("unused_signal")
12 | signal on_dragging(e : Control)
13 | signal out_dragging(e : Control)
14 |
15 | const DDTAB : Script = preload("res://addons/script_spliter/core/DDTAB.gd")
16 |
17 | var _buffer_editors : Array[Object] = []
18 |
19 | #static var _tab_focus : StyleBox = null
20 | #static var _tab_disabled : StyleBox = null
21 | #static var _tab_selected : StyleBox = null
22 | #static var _tab_hovered : StyleBox = null
23 | #static var _tab_unselected : StyleBox = null
24 |
25 | func _config_tab(_tab : StyleBox) -> void:
26 | if _tab is StyleBoxFlat:
27 | _tab.skew.x = 0.5
28 | _tab.border_color = Color.AQUA
29 | #_tab.border_width_left = 0.0
30 | #_tab.border_width_right = 0.0
31 | #_tab.border_width_top = 0.0
32 | #_tab.border_width_bottom = 0.1
33 |
34 | func _ready() -> void:
35 | pass
36 | #var root : Control = EditorInterface.get_base_control()
37 | #if root:
38 | #if _tab_focus == null:
39 | #_tab_focus = root.get_theme_stylebox(&"panel", &"tab_focus")
40 | #if _tab_focus is StyleBoxFlat:
41 | #_tab_focus = _tab_focus.duplicate()
42 | #_config_tab(_tab_focus)
43 | #if _tab_disabled == null:
44 | #_tab_disabled = root.get_theme_stylebox(&"panel", &"tab_disabled")
45 | #if _tab_disabled is StyleBoxFlat:
46 | #_tab_disabled = _tab_disabled.duplicate()
47 | #_config_tab(_tab_disabled)
48 | #if _tab_selected == null:
49 | #_tab_selected = root.get_theme_stylebox(&"panel", &"tab_selected")
50 | #if _tab_selected is StyleBoxFlat:
51 | #_tab_selected = _tab_selected.duplicate()
52 | #_config_tab(_tab_selected)
53 | #if _tab_hovered == null:
54 | #_tab_hovered = root.get_theme_stylebox(&"panel", &"tab_hovered")
55 | #if _tab_hovered is StyleBoxFlat:
56 | #_tab_hovered = _tab_hovered.duplicate()
57 | #_config_tab(_tab_hovered)
58 | #if _tab_unselected == null:
59 | #_tab_unselected = root.get_theme_stylebox(&"panel", &"tab_unselected")
60 | #if _tab_unselected is StyleBoxFlat:
61 | #_tab_unselected = _tab_unselected.duplicate()
62 | #_config_tab(_tab_unselected)
63 | #set(&"theme_override_styles/tab_focus", _tab_focus)
64 | #set(&"theme_override_styles/tab_disabled", _tab_disabled)
65 | #set(&"theme_override_styles/tab_selected", _tab_selected)
66 | #set(&"theme_override_styles/tab_hovered", _tab_hovered)
67 | #set(&"theme_override_styles/tab_unselected", _tab_unselected)
68 |
69 | func reset() -> void:
70 | for x : Node in get_children(true):
71 | if x is TabBar:
72 | if x.get_script() == DDTAB:
73 | x.reset()
74 |
75 | func clear_editors() -> void:
76 | _buffer_editors.clear()
77 |
78 | func add_editor(o : Object, limit : int) -> Object:
79 | if is_instance_valid(o):
80 | if limit > 0:
81 | var i : int = _buffer_editors.find(o)
82 | if i > -1:
83 | _buffer_editors.remove_at(i)
84 | _buffer_editors.append(o)
85 | if limit > -1:
86 | while _buffer_editors.size() > limit:
87 | _buffer_editors.remove_at(0)
88 | return o
89 |
90 | func remove_editor(o : Object) -> void:
91 | _buffer_editors.erase(o)
92 |
93 | func backward_editor() -> Object:
94 | if _buffer_editors.size() > 1:
95 | var o : Variant = _buffer_editors.pop_back()
96 | while !is_instance_valid(o) and _buffer_editors.size() > 0:
97 | o = _buffer_editors.pop_back()
98 | if is_instance_valid(o):
99 | _buffer_editors.push_front(o)
100 | return o
101 | return null
102 |
103 | func forward_editor() -> Object:
104 | if _buffer_editors.size() > 1:
105 | var o : Object = _buffer_editors.pop_front()
106 | while !is_instance_valid(o) and _buffer_editors.size() > 0:
107 | o = _buffer_editors.pop_front()
108 | if is_instance_valid(o):
109 | _buffer_editors.push_back(o)
110 | return o
111 | return null
112 |
113 |
114 | func _on_child(n : Node) -> void:
115 | if n is TabBar:
116 | if n.get_script() != DDTAB:
117 | n.set_script(DDTAB)
118 |
119 | if !n.on_start_drag.is_connected(_on_start_drag):
120 | n.on_start_drag.connect(_on_start_drag)
121 | if !n.on_stop_drag.is_connected(_on_stop_drag):
122 | n.on_stop_drag.connect(_on_stop_drag)
123 |
124 | func _out_child(n : Node) -> void:
125 | if n is TabBar:
126 |
127 | if n.on_start_drag.is_connected(_on_start_drag):
128 | n.on_start_drag.disconnect(_on_start_drag)
129 | if n.on_stop_drag.is_connected(_on_stop_drag):
130 | n.on_stop_drag.disconnect(_on_stop_drag)
131 | if n.get_script() == DDTAB:
132 | n.set_script(null)
133 |
134 | func _on_stop_drag(tab : TabBar) -> void:
135 | out_dragging.emit(tab)
136 |
137 | func _on_start_drag(tab : TabBar) -> void:
138 | on_dragging.emit(tab)
139 | #
140 | func _init() -> void:
141 | child_entered_tree.connect(_on_child)
142 | child_exiting_tree.connect(_out_child)
143 |
--------------------------------------------------------------------------------
/addons/script_spliter/core/DDContainer.gd.uid:
--------------------------------------------------------------------------------
1 | uid://chk1nts3d41v8
2 |
--------------------------------------------------------------------------------
/addons/script_spliter/core/DDItem.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | extends ItemList
3 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
4 | # Script Spliter
5 | # https://github.com/CodeNameTwister/Script-Spliter
6 | #
7 | # Script Spliter addon for godot 4
8 | # author: "Twister"
9 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
10 |
11 |
12 | signal on_start_drag(t : ItemList)
13 | signal on_stop_drag(t : ItemList)
14 |
15 | const PREVIEW : PackedScene = preload("res://addons/script_spliter/context/tab_preview.tscn")
16 |
17 | var is_drag : bool = false:
18 | set(e):
19 | is_drag = e
20 | if is_drag:
21 | Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
22 | else:
23 | Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
24 |
25 | var _fms : float = 0.0
26 |
27 | func _init() -> void:
28 | if is_node_ready():
29 | _ready()
30 |
31 | func _ready() -> void:
32 | set_process(false)
33 | setup()
34 |
35 | func _process(delta: float) -> void:
36 | _fms += delta
37 | if _fms > 0.24:
38 | if is_drag:
39 | if !Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
40 | set_process(false)
41 | is_drag = false
42 | on_stop_drag.emit(self)
43 | else:
44 | on_start_drag.emit(self)
45 | is_drag = true
46 |
47 | func setup() -> void:
48 | if !gui_input.is_connected(_on_input):
49 | gui_input.connect(_on_input)
50 |
51 | func _on_input(e : InputEvent) -> void:
52 | if e is InputEventMouseButton:
53 | if e.button_index == 1:
54 | if e.pressed:
55 | _fms = 0.0
56 | is_drag = false
57 | set_process(true)
58 | else:
59 | set_process(false)
60 | if _fms >= 0.24:
61 | on_stop_drag.emit(self)
62 |
--------------------------------------------------------------------------------
/addons/script_spliter/core/DDItem.gd.uid:
--------------------------------------------------------------------------------
1 | uid://ci8kq81lonwua
2 |
--------------------------------------------------------------------------------
/addons/script_spliter/core/DDTAB.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | extends TabBar
3 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
4 | # Script Spliter
5 | # https://github.com/CodeNameTwister/Script-Spliter
6 | #
7 | # Script Spliter addon for godot 4
8 | # author: "Twister"
9 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
10 |
11 |
12 | signal on_start_drag(t : TabBar)
13 | signal on_stop_drag(t : TabBar)
14 |
15 | const PREVIEW : PackedScene = preload("res://addons/script_spliter/context/tab_preview.tscn")
16 |
17 | var is_drag : bool = false:
18 | set(e):
19 | is_drag = e
20 | if is_drag:
21 | Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
22 | else:
23 | Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
24 |
25 | var _fms : float = 0.0
26 |
27 | func reset() -> void:
28 | if is_drag:
29 | set_process(false)
30 | is_drag = false
31 | if is_inside_tree():
32 | on_stop_drag.emit(null)
33 |
34 | func _init() -> void:
35 | if is_node_ready():
36 | _ready()
37 |
38 | func _ready() -> void:
39 | set_process(false)
40 | setup()
41 |
42 | func _process(delta: float) -> void:
43 | _fms += delta
44 | if _fms > 0.24:
45 | if is_drag:
46 | if !Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
47 | set_process(false)
48 | is_drag = false
49 | on_stop_drag.emit(self)
50 | else:
51 | on_start_drag.emit(self)
52 | is_drag = true
53 |
54 | func setup() -> void:
55 | if !gui_input.is_connected(_on_input):
56 | gui_input.connect(_on_input)
57 |
58 | func _on_input(e : InputEvent) -> void:
59 | if e is InputEventMouseButton:
60 | if e.button_index == 1:
61 | is_drag = false
62 | if e.pressed:
63 | _fms = 0.0
64 | set_process(true)
65 | else:
66 | set_process(false)
67 | if _fms >= 0.24:
68 | on_stop_drag.emit(self)
69 |
--------------------------------------------------------------------------------
/addons/script_spliter/core/DDTAB.gd.uid:
--------------------------------------------------------------------------------
1 | uid://cma5va5lbj5it
2 |
--------------------------------------------------------------------------------
/addons/script_spliter/core/DaemonChaser.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | extends Node
3 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
4 | # Script Spliter
5 | # https://github.com/CodeNameTwister/Script-Spliter
6 | #
7 | # Script Spliter addon for godot 4
8 | # author: "Twister"
9 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
10 | var callback : Callable
11 | var end_callback : Callable
12 | var index : int = 0
13 | var back_to : int = 0
14 | var buffer : Dictionary
15 |
16 | func set_current_index(current : int) -> void:
17 | back_to = current
18 |
19 | func run(new_callback : Callable, new_end_callback : Callable) -> void:
20 | callback = new_callback
21 | end_callback = new_end_callback
22 | index = 0
23 | set_process(true)
24 |
25 | func _ready() -> void:
26 | set_process(false)
27 |
28 | func _back() -> void:
29 | if callback.is_valid():
30 | callback.call(back_to)
31 |
32 | func _process(__: float) -> void:
33 | if !callback.is_valid() or !callback.call(index):
34 | set_process(false)
35 | _back()
36 | if end_callback.is_valid():
37 | end_callback.call(buffer)
38 | buffer = {}
39 | return
40 | index += 1
41 |
--------------------------------------------------------------------------------
/addons/script_spliter/core/DaemonChaser.gd.uid:
--------------------------------------------------------------------------------
1 | uid://dbiugbnirptj8
2 |
--------------------------------------------------------------------------------
/addons/script_spliter/core/EditorContainer.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
3 | # Script Spliter
4 | # https://github.com/CodeNameTwister/Script-Spliter
5 | #
6 | # Script Spliter addon for godot 4
7 | # author: "Twister"
8 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
9 |
10 | extends "res://addons/script_spliter/core/ui/multi_split_container.gd"
11 |
12 | const PREVIEW : PackedScene = preload("res://addons/script_spliter/context/panel_preview.tscn")
13 |
14 | var preview : Control = null
15 |
16 | func get_total_containers() -> int:
17 | var total : int = 0
18 | for x : Node in get_children():
19 | if x is SplitContainerItem:
20 | if x.get_child_count() > 0:
21 | total += 1
22 | return total
23 |
24 | func _notification(what: int) -> void:
25 | if what == NOTIFICATION_PREDELETE:
26 | if is_instance_valid(preview) and !preview.is_queued_for_deletion():
27 | preview.queue_free()
28 |
29 | func make_split_container_item() -> Control:
30 | var x : SplitContainerItem = SplitContainerItem.new()
31 | x.size_flags_horizontal = Control.SIZE_FILL
32 | x.size_flags_vertical = Control.SIZE_FILL
33 | x.custom_minimum_size = Vector2.ZERO
34 | x.clip_contents = true
35 | x.visible = false
36 | return x
37 |
38 | func has_items() -> bool:
39 | return get_child_count() > 0
40 |
41 | func is_split_container_item(x : Object) -> bool:
42 | return x is SplitContainerItem
43 |
44 |
--------------------------------------------------------------------------------
/addons/script_spliter/core/EditorContainer.gd.uid:
--------------------------------------------------------------------------------
1 | uid://ds3bvm7nwsq2s
2 |
--------------------------------------------------------------------------------
/addons/script_spliter/core/builder.gd.uid:
--------------------------------------------------------------------------------
1 | uid://dpje5up34xbux
2 |
--------------------------------------------------------------------------------
/addons/script_spliter/core/ui/dd.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | extends Control
3 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
4 | # Script Spliter
5 | # https://github.com/CodeNameTwister/Script-Spliter
6 | #
7 | # Script Spliter addon for godot 4
8 | # author: "Twister"
9 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
10 | @export var lbl : Control
11 |
12 | var _0x0001 : float = 0.0
13 | var _0x0002 : float= 0.5
14 |
15 | func _ready() -> void:
16 | if !is_inside_tree():
17 | set_process(false)
18 |
19 | func _process(delta: float) -> void:
20 | if !visible:
21 | return
22 | var p : Control = get_parent()
23 | if !p:
24 | return
25 | _0x0001 += delta * 2.0
26 | if _0x0001 >= 1.0:
27 | _0x0001 = 0.0
28 | if _0x0002 == 1.0:
29 | _0x0002 = 0.5
30 | else:
31 | _0x0002 = 1.0
32 | modulate.a = lerp(modulate.a, _0x0002, _0x0001)
33 | lbl.pivot_offset = (lbl.size + Vector2.ONE) / 2.0
34 | lbl.scale = lerp(lbl.scale, Vector2.ONE * _0x0002 , _0x0001 * 0.24)
35 |
36 | func _enter_tree() -> void:
37 | set_process(true)
38 |
39 | func _exit_tree() -> void:
40 | set_process(false)
41 |
--------------------------------------------------------------------------------
/addons/script_spliter/core/ui/dd.gd.uid:
--------------------------------------------------------------------------------
1 | uid://prv0v0r500g6
2 |
--------------------------------------------------------------------------------
/addons/script_spliter/core/ui/dd.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=3 format=3 uid="uid://bd4fb42jjkgr0"]
2 |
3 | [ext_resource type="Script" uid="uid://prv0v0r500g6" path="res://addons/script_spliter/core/ui/dd.gd" id="1_1ryr1"]
4 | [ext_resource type="Texture2D" uid="uid://cxds5tr6aq5v3" path="res://addons/script_spliter/assets/dd.png" id="2_pid5b"]
5 |
6 | [node name="Dd" type="ColorRect" node_paths=PackedStringArray("lbl")]
7 | modulate = Color(0.8, 0.8, 0.8, 0.501533)
8 | self_modulate = Color(1, 1, 1, 0.4)
9 | size_flags_horizontal = 4
10 | size_flags_vertical = 4
11 | tooltip_text = "Drop the current dragged tab for change window!"
12 | color = Color(1.3236e-07, 0.348188, 0.0242278, 1)
13 | script = ExtResource("1_1ryr1")
14 | lbl = NodePath("Label")
15 |
16 | [node name="Label" type="TextureRect" parent="."]
17 | show_behind_parent = true
18 | layout_mode = 1
19 | anchors_preset = 15
20 | anchor_right = 1.0
21 | anchor_bottom = 1.0
22 | grow_horizontal = 2
23 | grow_vertical = 2
24 | size_flags_horizontal = 4
25 | size_flags_vertical = 4
26 | texture = ExtResource("2_pid5b")
27 | stretch_mode = 3
28 |
--------------------------------------------------------------------------------
/addons/script_spliter/core/ui/icon/MultiSpliter.svg:
--------------------------------------------------------------------------------
1 |
2 |
15 |
17 |
26 |
34 |
35 |
43 |
44 |
--------------------------------------------------------------------------------
/addons/script_spliter/core/ui/icon/MultiSpliter.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://bslfeut6hh5yo"
6 | path="res://.godot/imported/MultiSpliter.svg-ba196a92a18cd9aeefd856cd4e65a016.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://addons/script_spliter/core/ui/icon/MultiSpliter.svg"
14 | dest_files=["res://.godot/imported/MultiSpliter.svg-ba196a92a18cd9aeefd856cd4e65a016.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=8.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/addons/script_spliter/core/ui/icon/MultiSpliterButton.svg:
--------------------------------------------------------------------------------
1 |
2 |
16 |
18 |
36 |
44 |
45 |
53 |
59 |
65 |
71 |
77 |
83 |
89 |
90 |
--------------------------------------------------------------------------------
/addons/script_spliter/core/ui/icon/MultiSpliterButton.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://151hs5hrois7"
6 | path="res://.godot/imported/MultiSpliterButton.svg-f2ca8d7d3b41369a9fe8ce79d9fcb1df.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://addons/script_spliter/core/ui/icon/MultiSpliterButton.svg"
14 | dest_files=["res://.godot/imported/MultiSpliterButton.svg-f2ca8d7d3b41369a9fe8ce79d9fcb1df.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=8.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/addons/script_spliter/core/ui/icon/MultiSpliterItem.svg:
--------------------------------------------------------------------------------
1 |
2 |
15 |
17 |
26 |
34 |
35 |
43 |
49 |
54 |
59 |
64 |
69 |
70 |
--------------------------------------------------------------------------------
/addons/script_spliter/core/ui/icon/MultiSpliterItem.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://bd3tnqhyiny6o"
6 | path="res://.godot/imported/MultiSpliterItem.svg-73b989ef018da2301c61b6f59ef99931.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://addons/script_spliter/core/ui/icon/MultiSpliterItem.svg"
14 | dest_files=["res://.godot/imported/MultiSpliterItem.svg-73b989ef018da2301c61b6f59ef99931.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 | svg/scale=8.0
36 | editor/scale_with_editor_scale=false
37 | editor/convert_colors_with_editor_theme=false
38 |
--------------------------------------------------------------------------------
/addons/script_spliter/core/ui/multi_split_container.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | @icon("icon/MultiSpliter.svg")
3 | extends Container
4 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
5 | # https://github.com/CodeNameTwister/Multi-Split-Container
6 | #
7 | # Multi-Split-Container addon for godot 4
8 | # author: "Twister"
9 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
10 |
11 | const SplitContainerItem : Script = preload("res://addons/script_spliter/core/ui/split_container_item.gd")
12 | const SplitButton : Texture = preload("res://addons/script_spliter/core/ui/icon/MultiSpliterButton.svg")
13 |
14 | @export_category("Multi-Split Settings")
15 | ## Max columns by rows, after added childs this is eparated by row group by columns size!
16 | ## [br][br]
17 | ## if this value is 0, will not create rows spliters.
18 | @export_range(0.0, 1000.0, 1.0) var max_columns : int = 0:
19 | set(e):
20 | max_columns = maxi(0, e)
21 |
22 | if Engine.is_editor_hint():
23 | for x : int in range(separators_line_offsets.size()):
24 | separators_line_offsets[x] = 0.0
25 | for x : LineSep in _separators:
26 | x.queue_free()
27 |
28 | _separators.clear()
29 | _first = true
30 | update()
31 |
32 | @export_group("Line Separator", "separator_line")
33 | ## Line separator size.
34 | @export var separator_line_size : float = 4.0:
35 | set(e):
36 | separator_line_size = max(e, 0.0)
37 | update()
38 |
39 | ## Separator line color.
40 | @export var separator_line_color : Color = Color.MAGENTA:
41 | set(e):
42 | separator_line_color = e
43 | if separator_line_color == Color.MAGENTA: # That color reminds me of texture not found errors.
44 | var root = EditorInterface.get_base_control()
45 | separator_line_color = root.get_theme_color("base_color", "Editor")
46 | update()
47 |
48 | ## Separator line visibility.
49 | @export var separator_line_visible : bool = true:
50 | set(e):
51 | separator_line_visible = e
52 | for l : LineSep in _separators:
53 | l.visible = separator_line_visible
54 |
55 | @export_subgroup("Behaviour", "behaviour_")
56 | ## Enable function for auto expand lines container on inside focus.
57 | @export var behaviour_expand_on_focus : bool = true
58 |
59 | ## Enable function for auto expand lines container on double click in the line.
60 | @export var behaviour_expand_on_double_click : bool = true:
61 | set(e):
62 | behaviour_expand_on_double_click = e
63 | for l : LineSep in _separators:
64 | l.double_click_handler = behaviour_expand_on_double_click
65 |
66 | ## Enable movement by touching line.
67 | @export var behaviour_can_move_by_line : bool = true:
68 | set(e):
69 | behaviour_can_move_by_line = e
70 | for l : LineSep in _separators:
71 | l.draggable = behaviour_can_move_by_line
72 |
73 | ## This allow expand you current focused container if you shrunk it.
74 | @export var behaviour_can_expand_focus_same_container : bool = false
75 |
76 | ## Enable smooth when expand container.
77 | @export var behaviour_expand_smoothed : bool = true:
78 | set(e):
79 | behaviour_expand_smoothed = e
80 | if !e:
81 | if _tween and _tween.is_running():
82 | _tween.kill()
83 | _tween = null
84 |
85 | ## Time speed duration for reset expand container.
86 | @export_range(0.01, 1000.0, 0.01) var behaviour_expand_smoothed_time : float = 0.24:
87 | set(e):
88 | behaviour_expand_smoothed_time = maxf(0.01, e)
89 | if _tween and _tween.is_running():
90 | _tween.kill()
91 | _tween = null
92 |
93 | ## Custom initial offset for separator lines. (TODO: Still Working here!)
94 | @export var separators_line_offsets : Array[float] :
95 | set(e):
96 | separators_line_offsets = e
97 |
98 | if Engine.is_editor_hint():
99 | if separators_line_offsets.size() != _separators.size():
100 | separators_line_offsets.resize(_separators.size())
101 | update()
102 |
103 | @export_subgroup("Drag Button", "drag_button")
104 |
105 | ## Set if drag button always be visible (Useful for test button size)
106 | @export var drag_button_always_visible : bool = false:
107 | set(e):
108 | drag_button_always_visible = e
109 |
110 | var min_visible_drag_button : float = 0.0
111 | if drag_button_always_visible:
112 | min_visible_drag_button = 0.4
113 |
114 | for l : LineSep in _separators:
115 | if l.button:
116 | l.button.modulate.a = 0.0
117 | l.button.min_no_focus_transparense = min_visible_drag_button
118 |
119 | ## Min size for drag button visible on split lines.
120 | @export_range(1.0, 200.0, 0.1) var drag_button_size : float = 24.0:
121 | set(e):
122 | drag_button_size = e
123 | update()
124 |
125 | ## Modulate color for the drag button.
126 | @export var drag_button_modulate : Color = Color.MAGENTA:
127 | set(e):
128 | drag_button_modulate = e
129 | if drag_button_modulate == Color.MAGENTA:
130 | if Engine.is_editor_hint():
131 | var root : Control = EditorInterface.get_base_control()
132 | drag_button_modulate = root.get_theme_color("base_color", "Editor").lightened(0.5)
133 | update()
134 |
135 | ## Change default drag button icon.
136 | @export var drag_button_icon : Texture = null:
137 | set(e):
138 | drag_button_icon = e
139 | update()
140 |
141 | var _separators : Array[LineSep] = []
142 | var _last_container_focus : Node = null
143 | var _frame : int = 1
144 | var _first : bool = true
145 | var _tween : Tween = null
146 |
147 | func get_separators() -> Array[LineSep]:
148 | return _separators
149 |
150 | ## Get line begin offset limit.
151 | func get_line_seperator_left_offset_limit(index : int) -> float:
152 | if index < _separators.size():
153 | var line_sep : LineSep = _separators[index]
154 | if !line_sep.is_vertical:
155 | if index < 1:
156 | return -_separators[index].initial_position.x
157 | var next : LineSep = _separators[index - 1]
158 | return (next.initial_position.x + (next.size.x/2.0)) - _separators[index].initial_position.x
159 | else:
160 | if index < 1:
161 | return -_separators[index].initial_position.y
162 | var next : LineSep = _separators[index - 1]
163 | return (next.initial_position.y + (next.size.y/2.0)) - _separators[index].initial_position.y
164 | push_warning("[PLUGIN] Not valid index for line separator!")
165 | return 0.0
166 |
167 | ## Get line end offset limit.
168 | func get_line_seperator_right_offset_limit(index : int) -> float:
169 | if index < _separators.size():
170 | var line_sep : LineSep = _separators[index]
171 | if !line_sep.is_vertical:
172 | if index + 1 == _separators.size():
173 | return (size.x/2.0) -_separators[index].initial_position.x
174 | var current : LineSep = _separators[index]
175 | return (_separators[index + 1].initial_position.x - current.initial_position.x + (current.size.x/2.0))
176 | else:
177 | if index + 1 == _separators.size():
178 | return size.x -_separators[index].initial_position.y
179 | var current : LineSep = _separators[index]
180 | return (_separators[index + 1].initial_position.y - current.initial_position.y + (current.size.y/2.0))
181 | push_warning("[PLUGIN] Not valid index for line separator!")
182 | return 0.0
183 |
184 | # This is function is util when you want expand or constraint manualy offset.
185 | ## Update offset of the line
186 | func update_line_separator_offset(index : int, offset : float) -> void:
187 | var line_sep : LineSep = _separators[index]
188 | line_sep.offset = offset
189 | line_sep.force_update()
190 |
191 | ## Get total line count.
192 | func get_line_separator_count() -> int:
193 | return _separators.size()
194 |
195 | ## Get Line reference by index, see get_line_separator_count()
196 | func get_line_separator(index : int) -> LineSep:
197 | return _separators[index]
198 |
199 | ## Get if line separator is vertical.
200 | func is_vertical_line_separator(index : int) -> bool:
201 | if index < _separators.size():
202 | return _separators[index].is_vertical
203 | push_warning("[PLUGIN] Not valid index for line separator!")
204 | return false
205 |
206 | ## Expand splited container by index container.
207 | func expand_splited_container(node : Node) -> void:
208 | var same : bool = _last_container_focus == node
209 |
210 | if same and !behaviour_can_expand_focus_same_container:
211 | return
212 |
213 | _last_container_focus = node
214 |
215 | if !behaviour_expand_on_focus:
216 | return
217 |
218 | if _tween and _tween.is_running():
219 | if same:
220 | return
221 | _tween.kill()
222 | _tween = null
223 |
224 | var top_lines : Array[LineSep] = []
225 | var bottom_lines : Array[LineSep] = []
226 |
227 | var update_required : bool = false
228 |
229 | for line : LineSep in _separators:
230 | if node in line.top_items:
231 | update_required = update_required or line.offset < 0.0
232 | top_lines.append(line)
233 | elif node in line.bottom_items:
234 | update_required = update_required or line.offset > 0.0
235 | bottom_lines.append(line)
236 |
237 | if update_required:
238 | if behaviour_expand_smoothed:
239 | _tween = get_tree().create_tween()
240 | _tween.tween_method(_reset_expanded_lines.bind(top_lines, bottom_lines), 0.0, 1.0, behaviour_expand_smoothed_time)
241 | else:
242 | _reset_expanded_lines(1.0, top_lines, bottom_lines)
243 |
244 | func _reset_expanded_lines(_lerp : float, top_lines : Array[LineSep], bottom_lines : Array[LineSep]) -> void:
245 | for iline : int in range(top_lines.size() - 1, -1, -1):
246 | var line : LineSep = top_lines[iline]
247 | if is_instance_valid(line):
248 | if line.offset < 0.0:
249 | line.offset = lerp(line.offset, 0.0, _lerp)
250 | else:
251 | top_lines.remove_at(iline)
252 |
253 | for iline : int in range(bottom_lines.size() - 1, -1, -1):
254 | var line : LineSep = bottom_lines[iline]
255 | if is_instance_valid(line):
256 | if line.offset > 0.0:
257 | line.offset = lerp(line.offset, 0.0, _lerp)
258 | else:
259 | bottom_lines.remove_at(iline)
260 |
261 | for line : LineSep in top_lines:
262 | line.force_update()
263 | for line : LineSep in bottom_lines:
264 | line.force_update()
265 |
266 | ## Get initial position of a separator line.
267 | func get_line_separator_initial_position(index : int) -> Vector2:
268 | if index < _separators.size():
269 | return _separators[index].initial_position
270 | push_warning("[PLUGIN] Not valid index for line separator!")
271 | return Vector2.ZERO
272 |
273 | class DragButton extends Button:
274 | var _frm : float = 0.0
275 | var _line_sep : LineSep = null
276 | var _is_pressed : bool = false
277 |
278 | var is_hover : bool = false
279 |
280 | var _hover : Array[bool] = [false, false]
281 |
282 | var min_no_focus_transparense : float = 0.0:
283 | set(e):
284 | min_no_focus_transparense = e
285 | modulate.a = maxf(modulate.a, min_no_focus_transparense)
286 |
287 | static var DEFAULT_STYLE : StyleBox = null
288 |
289 | func set_drag_icon(new_icon : Texture) -> void:
290 | if icon != new_icon:
291 | if new_icon == null:
292 | icon = SplitButton
293 | return
294 | icon = new_icon
295 |
296 | func update_gui() -> void:
297 | if !_line_sep:
298 | return
299 |
300 | if _line_sep.is_vertical:
301 | _line_sep.mouse_default_cursor_shape = Control.CURSOR_VSPLIT
302 | mouse_default_cursor_shape = Control.CURSOR_VSPLIT
303 | else:
304 | _line_sep.mouse_default_cursor_shape = Control.CURSOR_HSPLIT
305 | mouse_default_cursor_shape = Control.CURSOR_HSPLIT
306 |
307 | func set_line(line_sep : LineSep) -> void:
308 | if _line_sep:
309 | if _line_sep.mouse_entered.is_connected(_on_enter):
310 | _line_sep.mouse_entered.disconnect(_on_enter)
311 | if _line_sep.mouse_exited.is_connected(_on_exit):
312 | _line_sep.mouse_exited.disconnect(_on_exit)
313 | if _line_sep.gui_input.is_connected(_on_input):
314 | _line_sep.gui_input.disconnect(_on_input)
315 |
316 | _line_sep = line_sep
317 |
318 | if _line_sep:
319 | if !_line_sep.mouse_entered.is_connected(_on_enter):
320 | _line_sep.mouse_entered.connect(_on_enter.bind(1))
321 | if !_line_sep.mouse_exited.is_connected(_on_exit):
322 | _line_sep.mouse_exited.connect(_on_exit.bind(1))
323 | if !_line_sep.gui_input.is_connected(_on_input):
324 | _line_sep.gui_input.connect(_on_input)
325 |
326 |
327 | func _init(line_sep : LineSep = null) -> void:
328 | modulate.a = 0.0
329 |
330 | set_line(line_sep)
331 |
332 | button_down.connect(_on_press)
333 | button_up.connect(_out_press)
334 | mouse_entered.connect(_on_enter.bind(0))
335 | mouse_exited.connect(_on_exit.bind(0))
336 |
337 | gui_input.connect(_custom_input)
338 |
339 | icon = SplitButton
340 | icon_alignment = HORIZONTAL_ALIGNMENT_CENTER
341 | vertical_icon_alignment = VERTICAL_ALIGNMENT_CENTER
342 | expand_icon = true
343 |
344 | if null != icon:
345 | flat = true
346 |
347 | if DEFAULT_STYLE == null:
348 | DEFAULT_STYLE = StyleBoxEmpty.new()
349 |
350 | focus_mode = Control.FOCUS_CLICK
351 |
352 | set(&"theme_override_styles/focus", DEFAULT_STYLE)
353 | set(&"theme_override_styles/disabled_mirrored", DEFAULT_STYLE)
354 | set(&"theme_override_styles/disabled", DEFAULT_STYLE)
355 | set(&"theme_override_styles/hover_pressed_mirrored", DEFAULT_STYLE)
356 | set(&"theme_override_styles/hover_pressed", DEFAULT_STYLE)
357 | set(&"theme_override_styles/hover_mirrored", DEFAULT_STYLE)
358 | set(&"theme_override_styles/hover", DEFAULT_STYLE)
359 | set(&"theme_override_styles/pressed_mirrored", DEFAULT_STYLE)
360 | set(&"theme_override_styles/pressed", DEFAULT_STYLE)
361 | set(&"theme_override_styles/normal_mirrored", DEFAULT_STYLE)
362 | set(&"theme_override_styles/normal", DEFAULT_STYLE)
363 |
364 | z_as_relative = true
365 | z_index = 2000
366 |
367 | update_gui()
368 |
369 | func _custom_input(e : InputEvent) -> void:
370 | if e is InputEventMouseButton:
371 | if e.pressed and e.double_click:
372 | get_tree().call_group(&"ScriptSpliter", &"swap", get_parent())
373 |
374 | func _on_input(e : InputEvent) -> void:
375 | if e is InputEventMouseButton:
376 | if e.pressed and e.double_click:
377 | if _line_sep and _line_sep.double_click_handler:
378 | _line_sep.offset = 0.0
379 | _line_sep.offset_updated.emit()
380 | elif e.pressed and _line_sep.draggable and e.button_index == 1:
381 | button_down.emit()
382 | elif !e.pressed and _line_sep.draggable and e.button_index == 1:
383 | button_up.emit()
384 |
385 | func set_line_sep_reference(ref : LineSep) -> void:
386 | _line_sep = ref
387 |
388 | func _ready() -> void:
389 | set_process(false)
390 |
391 | func _on_enter(x : int = 0) -> void:
392 | _hover[x] = true
393 |
394 | _frm = 0.0
395 | modulate.a = 1.0
396 | is_hover = true
397 | set_process(true)
398 |
399 | func _on_exit(x : int = 0) -> void:
400 | _hover[x] = false
401 |
402 | for h : bool in _hover:
403 | if h != false:
404 | return
405 |
406 | _frm = 0.0
407 | modulate.a = 1.0
408 | is_hover = false
409 | set_process(true)
410 |
411 | func _on_press() -> void:
412 | _is_pressed = true
413 | _frm = 0.0
414 | modulate.a = 1.0
415 | set_process(true)
416 |
417 | func _out_press() -> void:
418 | _is_pressed = false
419 | set_process(true)
420 |
421 | func _process(delta : float) -> void:
422 | if !has_focus() and !is_hover:
423 | _frm += delta * 0.4
424 | if _frm >= 1.0:
425 | _frm = 1.0
426 | set_process(false)
427 | modulate.a = lerp(modulate.a, min_no_focus_transparense, _frm)
428 | if _is_pressed:
429 | var mpos : Vector2 = _line_sep.get_parent().get_local_mouse_position()
430 | if mpos != get_rect().get_center():
431 | _line_sep.update_offset_by_position(mpos)
432 |
433 | class UndoredoSplit extends RefCounted:
434 | var object : SplitContainerItem = null
435 | var c_objects : Array[Node] = []
436 |
437 | class LineSep extends ColorRect:
438 | signal offset_updated()
439 |
440 | var top_lines : Array[LineSep] = []
441 | var bottom_lines : Array[LineSep] = []
442 |
443 | var top_items : Array[Control] = []
444 | var bottom_items : Array[Control] = []
445 |
446 | var is_vertical : bool = false:
447 | set(e):
448 | is_vertical = e
449 |
450 | if button:
451 | button.update_gui()
452 |
453 | var row : int = 0
454 |
455 | var initial_position : Vector2 = Vector2.ZERO
456 | var offset : float = 0.0
457 |
458 | var min_size_offset : float = 0.0
459 |
460 | var prev_line : LineSep = null
461 | var next_line : LineSep = null
462 |
463 | var button : DragButton = null
464 |
465 | var double_click_handler : bool = true
466 | var draggable : bool = true
467 |
468 | func set_next_line(next : LineSep = null) -> void:
469 | next_line = next
470 | next.prev_line = self
471 |
472 | func clear() -> void:
473 | top_items.clear()
474 | bottom_items.clear()
475 | top_lines.clear()
476 | bottom_lines.clear()
477 |
478 | func reset() -> void:
479 | position = initial_position
480 | update_items()
481 |
482 | func update_items() -> void:
483 | if is_vertical:
484 | for item : Control in top_items:
485 | item.size.y = position.y - item.position.y
486 | if !prev_line:
487 | item.position.y = 0.0
488 |
489 | for item : Control in bottom_items:
490 | item.position.y = position.y + size.y
491 |
492 | if next_line:
493 | item.size.y = next_line.position.y - item.position.y
494 | else:
495 | item.size.y = get_parent().size.y - item.position.y
496 | else:
497 | for item : Control in top_items:
498 | item.size.x = position.x - item.position.x + (size.x / 2.0) - 2.0
499 | if !prev_line:
500 | item.position.x = 0.0
501 |
502 | for item : Control in bottom_items:
503 | var diff : float = position.x + (size.x / 2.0) + 2.0
504 | item.position.x = diff
505 |
506 | if next_line:
507 | item.size.x = next_line.position.x - item.position.x
508 | else:
509 | item.size.x = get_parent().size.x - item.position.x
510 |
511 | func force_update() -> void:
512 | update_offset_by_position(initial_position + Vector2(offset * int(!is_vertical), offset * int(is_vertical)))
513 |
514 | func get_current_position() -> Vector2:
515 | return initial_position + Vector2(offset * int(!is_vertical), offset * int(is_vertical))
516 |
517 | func update_offset_by_position(vpos : Vector2) -> void:
518 | if is_vertical:
519 | min_size_offset = 0.0
520 | for x : Control in top_items:
521 | min_size_offset = maxf(min_size_offset, x.get_minimum_size().y)
522 | if prev_line:
523 | prev_line.min_size_offset = 0.0
524 | for x : Control in prev_line.bottom_items:
525 | prev_line.min_size_offset = maxf(prev_line.min_size_offset, x.get_minimum_size().y)
526 |
527 | offset = vpos.y - initial_position.y
528 | offset = minf(offset, get_parent().size.y - (initial_position.y + size.y + min_size_offset))
529 | offset = maxf(offset, -(initial_position.y - min_size_offset))
530 |
531 | if next_line:
532 | var val : float = next_line.position.y - (initial_position.y + size.y + min_size_offset)
533 | if offset > val:
534 | offset = val
535 | else:
536 | var val : float = get_parent().size.y - (initial_position.y + (size.y / 2.0) + min_size_offset)
537 | if offset > val:
538 | offset = val
539 | if prev_line:
540 | var val : float = -(initial_position.y - (prev_line.position.y + prev_line.size.y + prev_line.min_size_offset))
541 |
542 | if offset < val:
543 | offset = val
544 | else:
545 | var top_size_offset : float = 0.0
546 | for x : Control in top_items:
547 | top_size_offset = maxf(top_size_offset, x.get_minimum_size().y)
548 | offset = maxf(offset, top_size_offset-initial_position.y)
549 |
550 | position.y = initial_position.y + offset
551 |
552 | for line : LineSep in top_lines:
553 | line.size.y = position.y - line.position.y
554 |
555 | for line : LineSep in bottom_lines:
556 | line.position.y = position.y + size.y
557 |
558 | if next_line:
559 | line.size.y = next_line.position.y - line.position.y
560 | else:
561 | line.size.y = get_parent().size.y - line.position.y
562 | else:
563 | min_size_offset = 0.0
564 | for x : Control in bottom_items:
565 | min_size_offset = maxf(min_size_offset, x.get_minimum_size().x)
566 |
567 | if prev_line:
568 | prev_line.min_size_offset = 0.0
569 | for x : Control in prev_line.bottom_items:
570 | prev_line.min_size_offset = maxf(prev_line.min_size_offset, x.get_minimum_size().x)
571 |
572 | offset = vpos.x - initial_position.x
573 | offset = minf(offset, get_parent().size.x - (initial_position.x + size.x + min_size_offset))
574 | offset = maxf(offset, -initial_position.x)
575 |
576 | if next_line:
577 | var val : float = next_line.position.x - (initial_position.x + size.x + min_size_offset)
578 | if offset > val:
579 | offset = val
580 | else:
581 | var val : float = get_parent().size.x - (initial_position.x + (size.x/2.0) + min_size_offset)
582 | if offset > val:
583 | offset = val
584 | if prev_line:
585 | var val : float = -(initial_position.x - (prev_line.position.x + prev_line.size.x + prev_line.min_size_offset))
586 |
587 | if offset < val:
588 | offset = val
589 | else:
590 | var top_size_offset : float = 0.0
591 | for x : Control in top_items:
592 | top_size_offset = maxf(top_size_offset, x.get_minimum_size().x)
593 | offset = maxf(offset, top_size_offset-initial_position.x)
594 |
595 | position.x = initial_position.x + offset
596 | update_items()
597 |
598 | func _draw() -> void:
599 | update()
600 |
601 | func update() -> void:
602 | button.rotation_degrees = 90.0 * int(is_vertical)
603 | button.pivot_offset = button.size / 2.0
604 | button.position = size / 2.0 - button.pivot_offset
605 |
606 |
607 |
608 | func _init() -> void:
609 | color = Color.RED
610 |
611 | func _ready() -> void:
612 | name = "SplitLine"
613 | if button == null:
614 | button = DragButton.new(self)
615 | add_child(button, false, Node.INTERNAL_MODE_BACK)
616 |
617 | func _test() -> void:
618 | queue_redraw()
619 |
620 | func _init() -> void:
621 | child_entered_tree.connect(_on_enter)
622 | child_exiting_tree.connect(_on_exiting)
623 |
624 | func update() -> void:
625 | set_process(true)
626 |
627 | func _create_separator() -> Control:
628 | var line_sep : LineSep = LineSep.new()
629 | line_sep.offset_updated.connect(update)
630 | return line_sep
631 |
632 | func _undoredo_undo(ur : UndoredoSplit) -> void:
633 | if !is_instance_valid(ur):
634 | return
635 |
636 | var split : SplitContainerItem = ur.object
637 | if is_instance_valid(split):
638 | if split.get_parent() == self:
639 | ur.c_objects = split.get_children()
640 | for x : Node in ur.c_objects:
641 | split.remove_child(x)
642 | if x is Control:
643 | x.visible = false
644 | add_child(x)
645 | if is_instance_valid(split) and split.get_parent() == self:
646 | remove_child(split)
647 |
648 | func _update() -> void:
649 | var items : Array[Control] = []
650 | for x : Node in get_children():
651 | if is_instance_valid(x) and x is Control:
652 | if x.visible and !x.is_queued_for_deletion():
653 | if x is SplitContainerItem:
654 | if x.get_child_count() > 0:
655 | var _is_visible : bool = false
656 | for y : Node in x.get_children():
657 | if y is Control and y.visible:
658 | _is_visible = true
659 | break
660 | if !_is_visible:
661 | continue
662 | else:
663 | x.queue_free()
664 | continue
665 | elif x is DragButton or x is LineSep:
666 | x.queue_free()
667 | continue
668 | else:
669 | var container : SplitContainerItem = SplitContainerItem.new()
670 |
671 | add_child(container, true)
672 |
673 | x.reparent(container)
674 | x = container
675 |
676 |
677 | x.size_flags_horizontal = Control.SIZE_FILL
678 | x.size_flags_vertical = Control.SIZE_FILL
679 | x.clip_contents = true
680 | x.custom_minimum_size = Vector2.ZERO
681 | items.append(x)
682 |
683 | var totals : int = items.size()
684 | var rows : int = 0
685 |
686 | if max_columns > 0:
687 | var _totals : int = totals
688 | rows = 0
689 | while _totals > max_columns:
690 | _totals -= max_columns
691 | rows += 1
692 | totals -= rows
693 |
694 | if totals < 1:
695 | for x : int in range(0, _separators.size(), 1):
696 | _separators[x].queue_free()
697 | _separators[x] = null
698 | _separators.clear()
699 |
700 | for x : Control in items:
701 | x.position = Vector2.ZERO
702 | x.size = get_rect().size
703 | return
704 | else:
705 | if separator_line_size <= 0.0:
706 | for x : int in range(0, _separators.size(), 1):
707 | _separators[x].queue_free()
708 | _separators[x] = null
709 | _separators.clear()
710 | else:
711 | var sep : int = totals - 1 + rows
712 | for x : int in range(sep, _separators.size(), 1):
713 | _separators[x].queue_free()
714 | _separators[x] = null
715 | _separators.resize(sep)
716 | for x : int in range(0, _separators.size(), 1):
717 | if _separators[x] == null:
718 | _separators[x] = _create_separator()
719 |
720 | rows += 1
721 | if max_columns > 1:
722 | if totals > max_columns:
723 | totals = max_columns
724 |
725 | var rect_size : Vector2 = get_rect().size
726 | var start_position : Vector2 = Vector2.ZERO
727 |
728 | var size_split : Vector2 = (rect_size / Vector2(totals, rows))
729 |
730 | var size_sep : Vector2 = Vector2.ONE * separator_line_size
731 |
732 | if totals > 1:
733 | size_sep = (size_sep / (totals - 1))
734 |
735 | var item_size : Vector2 = Vector2(size_split.x, size_split.y)
736 | var line_size : Vector2 = Vector2(separator_line_size, item_size.y)
737 |
738 | var total_items : int = items.size()
739 |
740 | var vpos : Vector2 = Vector2.ZERO
741 | var current_row : int = 0
742 |
743 | var item_index : int = 0
744 |
745 | var last_vline : LineSep = null
746 | var last_hline : LineSep = null
747 |
748 | for x : Control in items:
749 | x.position = Vector2.ZERO
750 | x.size = x.get_minimum_size()
751 |
752 | for z : int in range(_separators.size()):
753 | var x : LineSep = _separators[z]
754 |
755 | x.clear()
756 |
757 | start_position.x += 1
758 |
759 | if 0 < max_columns and start_position.x + 1 > max_columns:
760 | total_items -= max_columns
761 | start_position.x = 0.0
762 | start_position.y += 1.0
763 | current_row += 1
764 | if total_items <= max_columns and total_items > 0:
765 | size_split = (rect_size / Vector2(total_items, rows))
766 | if total_items == 1:
767 | size_sep = Vector2.ONE * separator_line_size
768 | else:
769 | size_sep = ((Vector2.ONE * separator_line_size) / (total_items - 1))
770 | item_size = Vector2(size_split.x, size_split.y)
771 | line_size = Vector2(separator_line_size, rect_size.y - x.position.y)
772 |
773 | vpos = Vector2(0.0, start_position.y) * item_size
774 | x.is_vertical = true
775 |
776 | if x.get_parent() == null:
777 | add_child(x, false, Node.INTERNAL_MODE_BACK)
778 |
779 |
780 | x.row = current_row
781 |
782 | if items.size() > 0:
783 | var it : int = mini(item_index, items.size() - 1)
784 | var min_size : float = 0.0
785 |
786 | var _has : bool = false
787 |
788 | for y : int in range(z - 1, -1, -1):
789 | if it > -1:
790 | var item : Control = items[it]
791 | x.top_items.append(item)
792 | min_size = maxf(item.get_minimum_size().y, min_size)
793 | it -= 1
794 |
795 | var ln : LineSep = _separators[y]
796 | if ln.is_vertical:
797 | _has = true
798 | break
799 | x.top_lines.append(ln)
800 | if !_has:
801 | for _it : int in range(it, -1, -1):
802 | var item : Control = items[it]
803 | x.top_items.append(item)
804 |
805 | if item_index + 1 < items.size():
806 | it = item_index + 1
807 | _has = false
808 | for y : int in range(z + 1, _separators.size(), 1):
809 | if it < items.size():
810 | var item : Control = items[it]
811 | x.bottom_items.append(item)
812 | it += 1
813 |
814 | var ln : LineSep = _separators[y]
815 | if ln.is_vertical:
816 | _has = true
817 | break
818 | x.bottom_lines.append(ln)
819 | if !_has:
820 | for _it : int in range(it, items.size(), 1):
821 | var item : Control = items[_it]
822 | x.bottom_items.append(item)
823 |
824 | var vline_size : Vector2 = Vector2(rect_size.x, separator_line_size)
825 |
826 | x.initial_position = vpos
827 | x.initial_position.y -= (vline_size.y) / 2.0
828 | x.position = x.initial_position
829 |
830 | x.button.size = Vector2(drag_button_size, drag_button_size)
831 |
832 | x.set(&"size", vline_size)
833 | x.update()
834 |
835 | if last_vline:
836 | last_vline.set_next_line(x)
837 |
838 | last_vline = x
839 | last_hline = null
840 | item_index += 1
841 | continue
842 |
843 | vpos = start_position * item_size
844 |
845 | if x.get_parent() == null:
846 | add_child(x, false, Node.INTERNAL_MODE_BACK)
847 |
848 |
849 | if item_index < items.size():
850 | var item : Control = items[item_index]
851 | x.top_items.append(item)
852 | item_index += 1
853 | if item_index < items.size():
854 | if z + 1 < _separators.size():
855 | if !_separators[z].is_vertical:
856 | x.bottom_items.append(items[item_index])
857 | else:
858 | x.bottom_items.append(items[item_index])
859 |
860 | x.initial_position = vpos
861 | x.initial_position.x -= (line_size.x) / 2.0
862 |
863 | x.button.size = Vector2(drag_button_size, drag_button_size)
864 |
865 | x.row = current_row
866 | x.position = x.initial_position
867 |
868 | x.set(&"size", line_size)
869 | x.update()
870 |
871 | if last_hline:
872 | last_hline.set_next_line(x)
873 | last_hline = x
874 |
875 | for x : Control in items:
876 | x.size = size
877 |
878 | var min_visible_drag_button : float = 0.0
879 | if drag_button_always_visible:
880 | min_visible_drag_button = 0.4
881 |
882 | if _first:
883 | for l : LineSep in _separators:
884 | l.visible = separator_line_visible
885 | l.color = separator_line_color
886 | l.double_click_handler = behaviour_expand_on_double_click
887 | l.button.self_modulate = drag_button_modulate
888 | l.button.min_no_focus_transparense = min_visible_drag_button
889 | l.button.set_drag_icon(drag_button_icon)
890 | l.draggable = behaviour_can_move_by_line
891 |
892 | l.reset()
893 |
894 | else:
895 | if separators_line_offsets.size() > 0:
896 | for l : int in range(0, _separators.size(), 1):
897 | if l < separators_line_offsets.size():
898 | _separators[l].offset = separators_line_offsets[l]
899 | continue
900 | break
901 |
902 | for l : LineSep in _separators:
903 | l.visible = separator_line_visible
904 | l.color = separator_line_color
905 | l.double_click_handler = behaviour_expand_on_double_click
906 | l.button.self_modulate = drag_button_modulate
907 | l.button.min_no_focus_transparense = min_visible_drag_button
908 | l.button.set_drag_icon(drag_button_icon)
909 | l.draggable = behaviour_can_move_by_line
910 |
911 | l.force_update()
912 |
913 | if !Engine.is_editor_hint():
914 | separators_line_offsets.clear()
915 | else:
916 | for l : int in range(0, _separators.size(), 1):
917 | if l < separators_line_offsets.size():
918 | separators_line_offsets[l] = _separators[l].offset
919 | continue
920 | break
921 |
922 | func _on_enter(n : Node) -> void:
923 | n.is_inside_tree()
924 | if n is SplitContainerItem or (n is Control and !Engine.is_editor_hint()):
925 | if !n.visibility_changed.is_connected(_on_visible):
926 | n.visibility_changed.connect(_on_visible)
927 | if is_node_ready():
928 | for x : int in range(separators_line_offsets.size()):
929 | separators_line_offsets[x] = 0.0
930 | update()
931 |
932 | func _on_visible() -> void:
933 | update()
934 |
935 | func _on_exiting(n : Node) -> void:
936 | if n is SplitContainerItem or (n is Control and !Engine.is_editor_hint()):
937 | if is_node_ready():
938 | for x : int in range(separators_line_offsets.size()):
939 | separators_line_offsets[x] = 0.0
940 | for x : LineSep in _separators:
941 | x.offset = 0.0
942 | if n.visibility_changed.is_connected(_on_visible):
943 | n.visibility_changed.disconnect(_on_visible)
944 | update()
945 |
946 | func _process(__ : float) -> void:
947 | if is_node_ready():
948 | if _frame > 0:
949 | _frame -= 1
950 | return
951 | _update()
952 | if _first:
953 | _first = false
954 | else:
955 | set_process(false)
956 |
957 | func _on_exiting_tree() -> void:
958 | var vp : Viewport = get_viewport()
959 | if vp and vp.size_changed.is_connected(update):
960 | vp.size_changed.disconnect(update)
961 |
962 | var parent : Node = get_parent()
963 | if parent is Control:
964 | if parent.item_rect_changed.is_connected(update):
965 | parent.item_rect_changed.disconnect(update)
966 |
967 | func _enter_tree() -> void:
968 | var vp : Viewport = get_viewport()
969 | if vp and !vp.size_changed.is_connected(update):
970 | vp.size_changed.connect(update)
971 |
972 | var parent : Node = get_parent()
973 | if parent is Control:
974 | if !parent.item_rect_changed.is_connected(update):
975 | parent.item_rect_changed.connect(update)
976 |
977 | if !tree_exiting.is_connected(_on_exiting_tree):
978 | tree_exiting.connect(_on_exiting_tree)
979 |
980 | func _on_draw() -> void:
981 | update()
982 |
983 | func _ready() -> void:
984 | separator_line_color = separator_line_color
985 | drag_button_modulate = drag_button_modulate
986 |
987 | size_flags_horizontal = Control.SIZE_EXPAND_FILL
988 | size_flags_vertical =Control.SIZE_EXPAND_FILL
989 |
990 | set_deferred(&"anchor_left", 0.0)
991 | set_deferred(&"anchor_top", 0.0)
992 | set_deferred(&"anchor_bottom", 1.0)
993 | set_deferred(&"anchor_right", 1.0)
994 |
995 | if Engine.is_editor_hint():
996 | draw.connect(_on_draw)
997 |
998 | if _first:
999 | update()
1000 |
--------------------------------------------------------------------------------
/addons/script_spliter/core/ui/multi_split_container.gd.uid:
--------------------------------------------------------------------------------
1 | uid://cbd7egxjurkl4
2 |
--------------------------------------------------------------------------------
/addons/script_spliter/core/ui/split_container_item.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | @icon("icon/MultiSpliterItem.svg")
3 | extends Control
4 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
5 | # https://github.com/CodeNameTwister/Multi-Split-Container
6 | #
7 | # Multi-Split-Container addon for godot 4
8 | # author: "Twister"
9 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
10 |
11 | var focus_handler : bool = false
12 |
13 | ## Expand if tight by spliter
14 | func show_splited_container() -> void:
15 | var parent : Node = get_parent()
16 | if parent.has_method(&"expand_splited_container"):
17 | parent.call(&"expand_splited_container", self)
18 |
19 |
20 | func _ready() -> void:
21 | set_process(false)
22 |
23 | size_flags_horizontal = Control.SIZE_FILL
24 | size_flags_vertical = Control.SIZE_FILL
25 |
26 | set_deferred(&"anchor_left", 0.0)
27 | set_deferred(&"anchor_top", 0.0)
28 | set_deferred(&"anchor_bottom", 1.0)
29 | set_deferred(&"anchor_right", 1.0)
30 |
31 | func _init() -> void:
32 | name = "SplitContainerItem"
33 |
34 | child_exiting_tree.connect(_on_child_exiting_tree)
35 | child_entered_tree.connect(_on_child_entered_tree)
36 |
37 | func _on_visible() -> void:
38 | var _visible : bool = false
39 | for x : Node in get_children():
40 | if x is Control:
41 | if x.visible:
42 | _visible = true
43 | break
44 | visible = _visible
45 |
46 | func _on_child_entered_tree(n : Node) -> void:
47 | if n is Control:
48 | n.size = size
49 | n.set_anchor(SIDE_LEFT, 0.0)
50 | n.set_anchor(SIDE_RIGHT, 1.0)
51 | n.set_anchor(SIDE_TOP, 0.0)
52 | n.set_anchor(SIDE_BOTTOM, 1.0)
53 | if !n.visibility_changed.is_connected(_on_visible):
54 | n.visibility_changed.connect(_on_visible)
55 |
56 | func _disconnect(n : Node) -> void:
57 | if n is Control:
58 | if n.visibility_changed.is_connected(_on_visible):
59 | n.visibility_changed.disconnect(_on_visible)
60 | for x : Node in n.get_children():
61 | _disconnect(x)
62 |
63 | func _on_child_exiting_tree(n : Node) -> void:
64 | _disconnect(n)
65 |
66 | func _enter_tree() -> void:
67 | var c : Node = get_parent()
68 | if c is Control:
69 | size = c.size
70 |
--------------------------------------------------------------------------------
/addons/script_spliter/core/ui/split_container_item.gd.uid:
--------------------------------------------------------------------------------
1 | uid://buerhchaby30c
2 |
--------------------------------------------------------------------------------
/addons/script_spliter/io/backward_key_button.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="InputEventKey" format=3 uid="uid://p4o5dw6yauu"]
2 |
3 | [resource]
4 | alt_pressed = true
5 | key_label = 4194319
6 |
--------------------------------------------------------------------------------
/addons/script_spliter/io/backward_mouse_button.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="InputEventMouseButton" format=3 uid="uid://bwpahdvr80ivr"]
2 |
3 | [resource]
4 | device = -1
5 | button_index = 8
6 |
--------------------------------------------------------------------------------
/addons/script_spliter/io/forward_key_button.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="InputEventKey" format=3 uid="uid://b43ac78k4ox2a"]
2 |
3 | [resource]
4 | alt_pressed = true
5 | physical_keycode = 4194321
6 |
--------------------------------------------------------------------------------
/addons/script_spliter/io/forward_mouse_button.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="InputEventMouseButton" format=3 uid="uid://bs1lk5ids0s01"]
2 |
3 | [resource]
4 | button_index = 9
5 |
--------------------------------------------------------------------------------
/addons/script_spliter/plugin.cfg:
--------------------------------------------------------------------------------
1 | [plugin]
2 |
3 | name="Script Spliter"
4 | description="Tool Addon for godot 4
5 | Allow split script window."
6 | author="Twister"
7 | version="0.3.5.4"
8 | github="https://github.com/CodeNameTwister/Script-Spliter"
9 | script="plugin.gd"
10 |
--------------------------------------------------------------------------------
/addons/script_spliter/plugin.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | extends EditorPlugin
3 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
4 | # Script Spliter
5 | # https://github.com/CodeNameTwister/Script-Spliter
6 | #
7 | # Script Spliter addon for godot 4
8 | # author: "Twister"
9 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
10 |
11 | const BUILDER : Script = preload("res://addons/script_spliter/core/builder.gd")
12 | const CONTEXT : Script = preload("res://addons/script_spliter/context/context_window.gd")
13 |
14 | const CMD_MENU_TOOL : String = "Script Spliter"
15 |
16 | #CONTEXT
17 | const ICON_ADD_COLUMN : Texture = preload("res://addons/script_spliter/context/icons/split_cplus.svg")
18 | const ICON_REMOVE_COLUMN : Texture = preload("res://addons/script_spliter/context/icons/split_cminus.svg")
19 | const ICON_ADD_ROW : Texture = preload("res://addons/script_spliter/context/icons/split_rplus.svg")
20 | const ICON_REMOVE_ROW : Texture = preload("res://addons/script_spliter/context/icons/split_rminus.svg")
21 | const ICON_FLOATING : Texture = preload("res://addons/script_spliter/context/icons/atop.png")
22 |
23 | var _rmb_editor_add_split : EditorContextMenuPlugin = null
24 | var _rmb_editor_remove_split: EditorContextMenuPlugin = null
25 | var _rmb_editor_code_add_split : EditorContextMenuPlugin = null
26 | var _rmb_editor_code_remove_split : EditorContextMenuPlugin = null
27 | var _rmb_editor_pop_script : EditorContextMenuPlugin = null
28 | var _rmb_editor_code_pop_script : EditorContextMenuPlugin = null
29 |
30 | var _menu_split_selector : Window = null
31 | var _builder : Object = null
32 |
33 | var _daemon_chaser : Node = null
34 |
35 | #region _REF_
36 | var _tab_container : Node = null:
37 | get:
38 | if !is_instance_valid(_tab_container):
39 | var script_editor: ScriptEditor = EditorInterface.get_script_editor()
40 | _tab_container = find(script_editor, "*", "TabContainer")
41 | return _tab_container
42 |
43 | var _item_list : Node = null:
44 | get:
45 | if !is_instance_valid(_item_list):
46 | var script_editor: ScriptEditor = EditorInterface.get_script_editor()
47 | _item_list = find(script_editor, "*", "ItemList")
48 | return _item_list
49 | #endregion
50 |
51 | #region _USER_BUFFER_
52 | var _rows : int = 0:
53 | set(e):
54 | _rows = maxi(e, 0)
55 | var _columns : int = 0:
56 | set(e):
57 | _columns = maxi(e, 0)
58 | var _refresh_warnings_on_save : bool = true
59 | #endregion
60 |
61 | var _frm : int = 0
62 | var _d_chase : bool = false
63 |
64 | func get_builder() -> Object:
65 | return _builder
66 |
67 | func find(root : Node, pattern : String, type : String) -> Node:
68 | var e : Array[Node] = root.find_children(pattern, type, true, false)
69 | if e.size() > 0:
70 | return e[0]
71 | return null
72 |
73 | func get_split_rows() -> int:
74 | return _rows
75 |
76 | func get_split_columns() -> int:
77 | return _columns
78 |
79 | func _on_save(res : Resource) -> void:
80 | if res is Script:
81 | _save_external_data()
82 |
83 | func _save_external_data() -> void:
84 | if _d_chase == true:
85 | return
86 | _d_chase = true
87 | if _refresh_warnings_on_save and is_instance_valid(_builder):
88 | if _daemon_chaser == null:
89 | _daemon_chaser = ResourceLoader.load("res://addons/script_spliter/core/DaemonChaser.gd").new()
90 | add_child(_daemon_chaser)
91 | _daemon_chaser.set_current_index(_builder.get_current_focus_index())
92 | _daemon_chaser.buffer = _builder.get_focus_config()
93 | _builder.enable_focus_highlight(false)
94 | _daemon_chaser.run(_builder.focus_by_index, _builder.set_focus_config)
95 | set_deferred(&"_d_chase", false)
96 |
97 | func _process(__: float) -> void:
98 | if _frm < 2:
99 | _frm += 1
100 | return
101 | _frm = 0
102 | set_process(false)
103 | if is_instance_valid(_builder):
104 | _builder.update()
105 |
106 | func _on_change_settings() -> void:
107 | if is_instance_valid(_builder):
108 | _builder.update_config()
109 | var settings : EditorSettings = EditorInterface.get_editor_settings()
110 | var changes : PackedStringArray = settings.get_changed_settings()
111 |
112 | if &"plugin/script_spliter/behaviour/refresh_warnings_on_save" in changes:
113 | _refresh_warnings_on_save = settings.get_setting(&"plugin/script_spliter/behaviour/refresh_warnings_on_save")
114 |
115 | func _init() -> void:
116 | var o : Object = _tab_container
117 | if o == null:
118 | #push_warning("[Script-Spliter] 0x000A")
119 | return
120 | o = _item_list
121 | if o == null:
122 | #push_warning("[Script-Spliter] 0x000B")
123 | return
124 |
125 | func _run() -> void:
126 | if is_instance_valid(_builder):
127 | var settings : EditorSettings = EditorInterface.get_editor_settings()
128 | var scripts_tab_container : Node = _tab_container
129 |
130 | if !scripts_tab_container:
131 | push_warning("[Script-Spliter] 0x000A Error can not find editor reference!")
132 | return
133 |
134 | var il : Node = _item_list
135 | if null != il:
136 | _builder.set_item_list(il)
137 | else:
138 | push_warning("[Script-Spliter] 0x000B Error can not find editor reference!")
139 | return
140 |
141 | if !scripts_tab_container.is_node_ready():
142 | await scripts_tab_container.ready
143 | if !is_instance_valid(scripts_tab_container):
144 | push_error("Unspected error reference be replace or free it, can not run plugin!")
145 | return
146 |
147 | settings.settings_changed.connect(_on_change_settings)
148 |
149 | _builder.init_1()
150 | _builder.build(scripts_tab_container, _columns, _rows)
151 | set_process_input(true)
152 |
153 | func set_type_split(columns : int, rows : int) -> void:
154 | _columns = columns
155 | _rows = rows
156 |
157 | var str_columns : String = str(maxi(_columns, 1))
158 | var str_rows : String = str(maxi(rows, 1))
159 |
160 | print("[{0}] {1} {2}: > {3} {5} - {4} {6}".format(
161 | [
162 | _get_translated_text("INFO"),
163 | _get_translated_text("Setting"),
164 | _get_translated_text("To"),
165 | _get_translated_text("Columns"),
166 | _get_translated_text("Rows"),
167 | str_columns,
168 | str_rows
169 | ]) )
170 |
171 | if is_instance_valid(_builder):
172 | _builder.update_build(columns, rows)
173 |
174 | func _exit_tree() -> void:
175 | remove_tool_menu_item(CMD_MENU_TOOL)
176 | _setup(0)
177 |
178 | if is_instance_valid(_builder):
179 | _builder.init_0()
180 | _builder.free.call_deferred()
181 |
182 | var settings : EditorSettings = EditorInterface.get_editor_settings()
183 | if settings.settings_changed.is_connected(_on_change_settings):
184 | settings.settings_changed.disconnect(_on_change_settings)
185 |
186 | if is_instance_valid(_daemon_chaser) and !_daemon_chaser.is_queued_for_deletion():
187 | _daemon_chaser.queue_free()
188 |
189 | func _get_translated_text(text : String) -> String:
190 | # TODO: Translation
191 | return text
192 |
193 | func swap(caller : Object) -> void:
194 | if is_instance_valid(_builder):
195 | _builder.swap(caller)
196 |
197 | func _setup(input : int) -> void:
198 | var settings : EditorSettings = EditorInterface.get_editor_settings()
199 |
200 | if input != 0:
201 | add_to_group(&"ScriptSpliter")
202 |
203 | main_screen_changed.connect(_on_change)
204 | resource_saved.connect(_on_save)
205 |
206 | var ctx_add_column : String = _get_translated_text("ADD_SPLIT").capitalize()
207 | var ctx_remove_split : String = _get_translated_text("REMOVE_SPLIT").capitalize()
208 | var ctx_pop_script : String = _get_translated_text("MAKE_FLOATING_SCRIPT").capitalize()
209 |
210 | #SETUP
211 | _rmb_editor_add_split = CONTEXT.new(ctx_add_column, _add_window_split, _can_add_split, ICON_ADD_COLUMN)
212 | _rmb_editor_remove_split = CONTEXT.new(ctx_remove_split, _remove_window_split, _can_remove_split, ICON_REMOVE_COLUMN)
213 |
214 | _rmb_editor_code_add_split = CONTEXT.new(ctx_add_column, _add_window_split, _can_add_split, ICON_ADD_COLUMN)
215 | _rmb_editor_code_remove_split = CONTEXT.new(ctx_remove_split, _remove_window_split, _can_remove_split, ICON_REMOVE_COLUMN)
216 |
217 | _rmb_editor_pop_script = CONTEXT.new(ctx_pop_script, _make_pop_script, _can_make_pop_script, ICON_FLOATING)
218 | _rmb_editor_code_pop_script = CONTEXT.new(ctx_pop_script, _make_pop_script, _can_make_pop_script, ICON_FLOATING)
219 |
220 | add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR, _rmb_editor_add_split)
221 | add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR, _rmb_editor_remove_split)
222 |
223 | add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR_CODE, _rmb_editor_code_add_split)
224 | add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR_CODE, _rmb_editor_code_remove_split)
225 |
226 | add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR, _rmb_editor_pop_script)
227 | add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR_CODE, _rmb_editor_code_pop_script)
228 |
229 | if !settings.has_setting(&"plugin/script_spliter/rows"):
230 | settings.set_setting(&"plugin/script_spliter/rows", _rows)
231 | else:
232 | _rows = settings.get_setting(&"plugin/script_spliter/rows")
233 | if !settings.has_setting(&"plugin/script_spliter/columns"):
234 | settings.set_setting(&"plugin/script_spliter/columns", _columns)
235 | else:
236 | _columns = settings.get_setting(&"plugin/script_spliter/columns")
237 | if !settings.has_setting(&"plugin/script_spliter/save_rows_columns_count_on_exit"):
238 | settings.set_setting(&"plugin/script_spliter/save_rows_columns_count_on_exit", false)
239 | if !settings.has_setting(&"plugin/script_spliter/behaviour/refresh_warnings_on_save"):
240 | settings.set_setting(&"plugin/script_spliter/behaviour/refresh_warnings_on_save", _refresh_warnings_on_save)
241 | else:
242 | _refresh_warnings_on_save = settings.get_setting(&"plugin/script_spliter/behaviour/refresh_warnings_on_save")
243 | else:
244 | if is_in_group(&"ScriptSpliter"):
245 | remove_from_group(&"ScriptSpliter")
246 |
247 | main_screen_changed.disconnect(_on_change)
248 | resource_saved.disconnect(_on_save)
249 |
250 | if is_instance_valid(_rmb_editor_add_split):
251 | remove_context_menu_plugin(_rmb_editor_add_split)
252 | if is_instance_valid(_rmb_editor_remove_split):
253 | remove_context_menu_plugin(_rmb_editor_remove_split)
254 | if is_instance_valid(_rmb_editor_code_add_split):
255 | remove_context_menu_plugin(_rmb_editor_code_add_split)
256 | if is_instance_valid(_rmb_editor_code_remove_split):
257 | remove_context_menu_plugin(_rmb_editor_code_remove_split)
258 | if is_instance_valid(_rmb_editor_pop_script):
259 | remove_context_menu_plugin(_rmb_editor_pop_script)
260 | if is_instance_valid(_rmb_editor_code_pop_script):
261 | remove_context_menu_plugin(_rmb_editor_code_pop_script)
262 |
263 |
264 | if settings.has_setting(&"plugin/script_spliter/save_rows_columns_count_on_exit"):
265 | if settings.get_setting(&"plugin/script_spliter/save_rows_columns_count_on_exit") == true:
266 | settings.set_setting(&"plugin/script_spliter/rows", _rows)
267 | settings.set_setting(&"plugin/script_spliter/columns", _columns)
268 |
269 | func _can_add_split(path : PackedStringArray) -> bool:
270 | if !is_instance_valid(_builder):
271 | return false
272 | if path.size() == 0:
273 | return _builder.can_add_split(null)
274 | else:
275 | for x : String in path:
276 | if x.begins_with("res://"):
277 | var sc : ScriptEditor = EditorInterface.get_script_editor()
278 | return _builder.can_add_split(sc.get_current_editor().get_base_editor())
279 | else:
280 | var node : Node = get_node_or_null(x)
281 | if node:
282 | return _builder.can_add_split(node)
283 | else:
284 | var sc : ScriptEditor = EditorInterface.get_script_editor()
285 | return _builder.can_add_split(sc.get_current_editor().get_base_editor())
286 | return false
287 |
288 | func _can_remove_split(path : PackedStringArray) -> bool:
289 | if !is_instance_valid(_builder):
290 | return false
291 | if path.size() == 0:
292 | return _builder.can_remove_split(null)
293 | else:
294 | for x : String in path:
295 | if x.begins_with("res://"):
296 | var sc : ScriptEditor = EditorInterface.get_script_editor()
297 | return _builder.can_remove_split(sc.get_current_editor().get_base_editor())
298 | else:
299 | var node : Node = get_node_or_null(x)
300 | if node:
301 | return _builder.can_remove_split(node)
302 | else:
303 | var sc : ScriptEditor = EditorInterface.get_script_editor()
304 | return _builder.can_remove_split(sc.get_current_editor().get_base_editor())
305 | return false
306 |
307 | func _add_window_split(variant : Variant) -> void:
308 | var control : Control = null
309 | if variant is Script:
310 | var sc : ScriptEditor = EditorInterface.get_script_editor()
311 | if variant == sc.get_current_script():
312 | control = sc.get_current_editor().get_base_editor()
313 | else:
314 | var c : ScriptEditorBase = sc.get_current_editor()
315 | if c:
316 | control = c.get_base_editor()
317 | elif variant is CodeEdit:
318 | control = variant
319 | if is_instance_valid(control):
320 | _builder.add_split(control)
321 |
322 | func _remove_window_split(variant : Variant) -> void:
323 | var control : Control = null
324 | if variant is Script:
325 | var sc : ScriptEditor = EditorInterface.get_script_editor()
326 | if variant == sc.get_current_script():
327 | control = sc.get_current_editor().get_base_editor()
328 | else:
329 | var c : ScriptEditorBase = sc.get_current_editor()
330 | if c:
331 | control = c.get_base_editor()
332 | elif variant is CodeEdit:
333 | control = variant
334 | if is_instance_valid(control):
335 | _builder.remove_split(control)
336 |
337 | func _make_pop_script(variant : Variant) -> void:
338 | var control : Control = null
339 | if variant is Script:
340 | var sc : ScriptEditor = EditorInterface.get_script_editor()
341 | var arr : Array[ScriptEditorBase] = sc.get_open_script_editors()
342 | var scs : Array[Script] = sc.get_open_scripts()
343 | if arr.size() == scs.size():
344 | for y : int in range(0, scs.size(), 1):
345 | if scs[y] == variant:
346 | control = arr[y].get_base_editor()
347 | break
348 | if variant is CodeEdit:
349 | control = variant
350 | if is_instance_valid(control):
351 | _builder.make_pop_script(control)
352 |
353 | func _can_make_pop_script(path : PackedStringArray) -> bool:
354 | if !is_instance_valid(_builder):
355 | return false
356 | for x : String in path:
357 | var node : Node = get_node_or_null(x)
358 | if node:
359 | return !_builder.is_pop_script(node)
360 | return false
361 |
362 | func _on_change(screen_name : String) -> void:
363 | if screen_name == "Script":
364 | if is_instance_valid(_builder):
365 | _builder.update_rect.call_deferred()
366 |
367 |
368 | func _enter_tree() -> void:
369 | _setup(1)
370 | if !is_instance_valid(_builder):
371 | _builder = BUILDER.new(self)
372 | add_tool_menu_item(CMD_MENU_TOOL, _on_tool_command)
373 |
374 | func _on_tool_command() -> void:
375 | if is_instance_valid(_builder):
376 | var data : Array[int] = _builder.get_current_columns_and_rows()
377 | _columns = data[0]
378 | _rows = data[1]
379 |
380 | if !is_instance_valid(_menu_split_selector):
381 | _menu_split_selector = (ResourceLoader.load("res://addons/script_spliter/context/menu_tool.tscn") as PackedScene).instantiate()
382 | _menu_split_selector.set_plugin(self)
383 | _menu_split_selector.visible = false
384 | add_child(_menu_split_selector)
385 | _menu_split_selector.popup_centered.call_deferred()
386 |
387 | func _ready() -> void:
388 | set_process(false)
389 | set_process_input(false)
390 | if !get_tree().root.is_node_ready():
391 | await get_tree().root.ready
392 | for __ : int in range(2):
393 | await get_tree().process_frame
394 | _run()
395 |
396 | func _notification(what: int) -> void:
397 | if what == NOTIFICATION_PREDELETE:
398 | if is_instance_valid(_builder) and !_builder.is_queued_for_deletion():
399 | _builder.init_0()
400 | _builder.free()
401 |
402 | func _input(event: InputEvent) -> void:
403 | if event is InputEventKey:
404 | if event.pressed and event.ctrl_pressed:
405 | if event.keycode == 49:
406 | set_type_split(0, 0)
407 | elif event.keycode == 50:
408 | set_type_split(2, 1)
409 | elif event.keycode == 51:
410 | set_type_split(1, 2)
411 | elif event.keycode == 52:
412 | set_type_split(3, 1)
413 | elif event.keycode == 53:
414 | set_type_split(1, 3)
415 | elif event.keycode == 54:
416 | set_type_split(2, 2)
417 |
--------------------------------------------------------------------------------
/addons/script_spliter/plugin.gd.uid:
--------------------------------------------------------------------------------
1 | uid://dwmaoslxt1uop
2 |
--------------------------------------------------------------------------------
/images/img0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeNameTwister/Script-Spliter/8312d5b0eb2b24c85c669d5f9b4092ae518dc8da/images/img0.png
--------------------------------------------------------------------------------
/images/img1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeNameTwister/Script-Spliter/8312d5b0eb2b24c85c669d5f9b4092ae518dc8da/images/img1.png
--------------------------------------------------------------------------------
/images/img2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeNameTwister/Script-Spliter/8312d5b0eb2b24c85c669d5f9b4092ae518dc8da/images/img2.png
--------------------------------------------------------------------------------
/images/img3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CodeNameTwister/Script-Spliter/8312d5b0eb2b24c85c669d5f9b4092ae518dc8da/images/img3.png
--------------------------------------------------------------------------------