diff --git a/data_manager/LICENSE b/data_manager/LICENSE new file mode 100644 index 0000000..386f030 --- /dev/null +++ b/data_manager/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Péter Magyar + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/data_manager/README.md b/data_manager/README.md new file mode 100644 index 0000000..025d3bb --- /dev/null +++ b/data_manager/README.md @@ -0,0 +1,7 @@ +# ESS Data + +This is an addon for https://github.com/Relintai/entity_spell_system, to help with editing, and managing all game related the data in the project. + +Looks like this: + +![ess_data screenshot](screenshots/ess_data.png) diff --git a/data_manager/_data/settings.tres b/data_manager/_data/settings.tres new file mode 100644 index 0000000..12c3095 --- /dev/null +++ b/data_manager/_data/settings.tres @@ -0,0 +1,107 @@ +[gd_resource type="Resource" load_steps=2 format=2] + +[ext_resource path="res://addons/data_manager/resources/data_manager_addon_settings.gd" type="Script" id=1] + +[resource] +script = ExtResource( 1 ) +folder_count = 25 +folders/0/folder = "." +folders/0/header = "" +folders/0/name = "Root" +folders/0/type = "Resource" +folders/1/folder = "entity_skills" +folders/1/header = "" +folders/1/name = "Skills" +folders/1/type = "EntitySkillData" +folders/2/folder = "entities" +folders/2/header = "" +folders/2/name = "Entities" +folders/2/type = "EntityData" +folders/3/folder = "player_character_data" +folders/3/header = "" +folders/3/name = "Player Characters" +folders/3/type = "EntityData" +folders/4/folder = "entity_classes" +folders/4/header = "" +folders/4/name = "Classes" +folders/4/type = "EntityClassData" +folders/5/folder = "ai" +folders/5/header = "" +folders/5/name = "AI" +folders/5/type = "AIAction" +folders/6/folder = "character_models" +folders/6/header = "Models" +folders/6/name = "Models" +folders/6/type = "MeshDataResource" +folders/7/folder = "character_textures" +folders/7/header = "" +folders/7/name = "Textures" +folders/7/type = "Texture" +folders/8/folder = "spells" +folders/8/header = "Spells" +folders/8/name = "Spells" +folders/8/type = "Spell" +folders/9/folder = "aura_groups" +folders/9/header = "" +folders/9/name = "Aura Groups" +folders/9/type = "AuraGroup" +folders/10/folder = "character_specs" +folders/10/header = "" +folders/10/name = "Specs" +folders/10/type = "CharacterSpec" +folders/11/folder = "effect_data" +folders/11/header = "" +folders/11/name = "Effect Datas" +folders/11/type = "SpellEffectVisual" +folders/12/folder = "world_spells" +folders/12/header = "" +folders/12/name = "World Spells" +folders/12/type = "WorldSpellData" +folders/13/folder = "item_templates" +folders/13/header = "Items" +folders/13/name = "Items" +folders/13/type = "ItemTemplate" +folders/14/folder = "crafting" +folders/14/header = "" +folders/14/name = "Craft Recipes" +folders/14/type = "CraftRecipe" +folders/15/folder = "item_visuals" +folders/15/header = "" +folders/15/name = "Item Visuals" +folders/15/type = "ItemVisual" +folders/16/folder = "planets" +folders/16/header = "World" +folders/16/name = "World" +folders/16/type = "World" +folders/17/folder = "continents" +folders/17/header = "" +folders/17/name = "Continents" +folders/17/type = "Continent" +folders/18/folder = "zones" +folders/18/header = "" +folders/18/name = "Zones" +folders/18/type = "Zone" +folders/19/folder = "sub_zones" +folders/19/header = "" +folders/19/name = "SubZones" +folders/19/type = "SubZone" +folders/20/folder = "dungeons" +folders/20/header = "" +folders/20/name = "Dungeons" +folders/20/type = "DungeonData" +folders/21/folder = "dungeon_rooms" +folders/21/header = "" +folders/21/name = "Dungeon Rooms" +folders/21/type = "DungeonRoomData" +folders/22/folder = "basic_models" +folders/22/header = "" +folders/22/name = "Basic Models" +folders/22/type = "MeshDataResource" +folders/23/folder = "prop_models" +folders/23/header = "" +folders/23/name = "Prop Models" +folders/23/type = "PackedScene" +folders/24/folder = "entity_resources" +folders/24/header = "Entities" +folders/24/name = "Entity Resources" +folders/24/type = "EntityResourceData" diff --git a/data_manager/icons/empty.png b/data_manager/icons/empty.png new file mode 100644 index 0000000..2504386 Binary files /dev/null and b/data_manager/icons/empty.png differ diff --git a/data_manager/icons/empty.png.import b/data_manager/icons/empty.png.import new file mode 100644 index 0000000..e10f7bf --- /dev/null +++ b/data_manager/icons/empty.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/empty.png-7c3c16235e874062c86c346ae86f27bd.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/data_manager/icons/empty.png" +dest_files=[ "res://.import/empty.png-7c3c16235e874062c86c346ae86f27bd.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/data_manager/icons/gom.png b/data_manager/icons/gom.png new file mode 100644 index 0000000..ca3781a Binary files /dev/null and b/data_manager/icons/gom.png differ diff --git a/data_manager/icons/gom.png.import b/data_manager/icons/gom.png.import new file mode 100644 index 0000000..56610df --- /dev/null +++ b/data_manager/icons/gom.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/gom.png-7336a5cc19ade9f52daca73cd870ca75.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/data_manager/icons/gom.png" +dest_files=[ "res://.import/gom.png-7336a5cc19ade9f52daca73cd870ca75.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/data_manager/icons/icon_add.png b/data_manager/icons/icon_add.png new file mode 100644 index 0000000..297be14 Binary files /dev/null and b/data_manager/icons/icon_add.png differ diff --git a/data_manager/icons/icon_add.png.import b/data_manager/icons/icon_add.png.import new file mode 100644 index 0000000..5406689 --- /dev/null +++ b/data_manager/icons/icon_add.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_add.png-4936253aec6c83c328ecfe2f83f4abdb.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/data_manager/icons/icon_add.png" +dest_files=[ "res://.import/icon_add.png-4936253aec6c83c328ecfe2f83f4abdb.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/data_manager/icons/icon_copy.png b/data_manager/icons/icon_copy.png new file mode 100644 index 0000000..d777f13 Binary files /dev/null and b/data_manager/icons/icon_copy.png differ diff --git a/data_manager/icons/icon_copy.png.import b/data_manager/icons/icon_copy.png.import new file mode 100644 index 0000000..687fd49 --- /dev/null +++ b/data_manager/icons/icon_copy.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_copy.png-b8adcf38019b53173acfa7e965fd19ce.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/data_manager/icons/icon_copy.png" +dest_files=[ "res://.import/icon_copy.png-b8adcf38019b53173acfa7e965fd19ce.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/data_manager/icons/icon_display-name.png b/data_manager/icons/icon_display-name.png new file mode 100644 index 0000000..7c44933 Binary files /dev/null and b/data_manager/icons/icon_display-name.png differ diff --git a/data_manager/icons/icon_display-name.png.import b/data_manager/icons/icon_display-name.png.import new file mode 100644 index 0000000..9bc5dc9 --- /dev/null +++ b/data_manager/icons/icon_display-name.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_display-name.png-eed428a00d84c6a84e6b1b924bf6b5a5.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/data_manager/icons/icon_display-name.png" +dest_files=[ "res://.import/icon_display-name.png-eed428a00d84c6a84e6b1b924bf6b5a5.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/data_manager/icons/icon_duplicate.png b/data_manager/icons/icon_duplicate.png new file mode 100644 index 0000000..320b365 Binary files /dev/null and b/data_manager/icons/icon_duplicate.png differ diff --git a/data_manager/icons/icon_duplicate.png.import b/data_manager/icons/icon_duplicate.png.import new file mode 100644 index 0000000..0a8641b --- /dev/null +++ b/data_manager/icons/icon_duplicate.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_duplicate.png-bc9124161be2304f34e2e5292fc9bb72.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/data_manager/icons/icon_duplicate.png" +dest_files=[ "res://.import/icon_duplicate.png-bc9124161be2304f34e2e5292fc9bb72.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/data_manager/icons/icon_edit.png b/data_manager/icons/icon_edit.png new file mode 100644 index 0000000..c114d2f Binary files /dev/null and b/data_manager/icons/icon_edit.png differ diff --git a/data_manager/icons/icon_edit.png.import b/data_manager/icons/icon_edit.png.import new file mode 100644 index 0000000..5b5fb1c --- /dev/null +++ b/data_manager/icons/icon_edit.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_edit.png-8dda7283a7e3e9d8bcd70055bb4af86b.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/data_manager/icons/icon_edit.png" +dest_files=[ "res://.import/icon_edit.png-8dda7283a7e3e9d8bcd70055bb4af86b.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/data_manager/icons/icon_empty.png b/data_manager/icons/icon_empty.png new file mode 100644 index 0000000..da163ba Binary files /dev/null and b/data_manager/icons/icon_empty.png differ diff --git a/data_manager/icons/icon_empty.png.import b/data_manager/icons/icon_empty.png.import new file mode 100644 index 0000000..0470e39 --- /dev/null +++ b/data_manager/icons/icon_empty.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_empty.png-41310ee5e2b51754d7fdd9ccd55dd8bb.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/data_manager/icons/icon_empty.png" +dest_files=[ "res://.import/icon_empty.png-41310ee5e2b51754d7fdd9ccd55dd8bb.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/data_manager/icons/icon_load.png b/data_manager/icons/icon_load.png new file mode 100644 index 0000000..cc05e98 Binary files /dev/null and b/data_manager/icons/icon_load.png differ diff --git a/data_manager/icons/icon_load.png.import b/data_manager/icons/icon_load.png.import new file mode 100644 index 0000000..0766edc --- /dev/null +++ b/data_manager/icons/icon_load.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_load.png-27103febef60080a6acff2120a3b5382.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/data_manager/icons/icon_load.png" +dest_files=[ "res://.import/icon_load.png-27103febef60080a6acff2120a3b5382.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/data_manager/icons/icon_move_down.png b/data_manager/icons/icon_move_down.png new file mode 100644 index 0000000..3934310 Binary files /dev/null and b/data_manager/icons/icon_move_down.png differ diff --git a/data_manager/icons/icon_move_down.png.import b/data_manager/icons/icon_move_down.png.import new file mode 100644 index 0000000..a1ce6de --- /dev/null +++ b/data_manager/icons/icon_move_down.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_move_down.png-0a5c510c5cd06b571858d1b2cf7a95cf.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/data_manager/icons/icon_move_down.png" +dest_files=[ "res://.import/icon_move_down.png-0a5c510c5cd06b571858d1b2cf7a95cf.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/data_manager/icons/icon_move_up.png b/data_manager/icons/icon_move_up.png new file mode 100644 index 0000000..684013d Binary files /dev/null and b/data_manager/icons/icon_move_up.png differ diff --git a/data_manager/icons/icon_move_up.png.import b/data_manager/icons/icon_move_up.png.import new file mode 100644 index 0000000..ac214cc --- /dev/null +++ b/data_manager/icons/icon_move_up.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_move_up.png-8bbd78f84e89d3ab25e3b699f6e3ba8d.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/data_manager/icons/icon_move_up.png" +dest_files=[ "res://.import/icon_move_up.png-8bbd78f84e89d3ab25e3b699f6e3ba8d.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/data_manager/icons/icon_multi_line.png b/data_manager/icons/icon_multi_line.png new file mode 100644 index 0000000..95a029c Binary files /dev/null and b/data_manager/icons/icon_multi_line.png differ diff --git a/data_manager/icons/icon_multi_line.png.import b/data_manager/icons/icon_multi_line.png.import new file mode 100644 index 0000000..47a3452 --- /dev/null +++ b/data_manager/icons/icon_multi_line.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_multi_line.png-f2116803bfa2e69309bda042fe09ca22.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/data_manager/icons/icon_multi_line.png" +dest_files=[ "res://.import/icon_multi_line.png-f2116803bfa2e69309bda042fe09ca22.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/data_manager/icons/icon_options.png b/data_manager/icons/icon_options.png new file mode 100644 index 0000000..4db4c53 Binary files /dev/null and b/data_manager/icons/icon_options.png differ diff --git a/data_manager/icons/icon_options.png.import b/data_manager/icons/icon_options.png.import new file mode 100644 index 0000000..ad9614e --- /dev/null +++ b/data_manager/icons/icon_options.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_options.png-8a05079b2f7e729dae53ff1568b6536e.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/data_manager/icons/icon_options.png" +dest_files=[ "res://.import/icon_options.png-8a05079b2f7e729dae53ff1568b6536e.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/data_manager/icons/icon_reload_small.png b/data_manager/icons/icon_reload_small.png new file mode 100644 index 0000000..1397ac6 Binary files /dev/null and b/data_manager/icons/icon_reload_small.png differ diff --git a/data_manager/icons/icon_reload_small.png.import b/data_manager/icons/icon_reload_small.png.import new file mode 100644 index 0000000..936150f --- /dev/null +++ b/data_manager/icons/icon_reload_small.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_reload_small.png-5cfe0f7b7e56d4c9649ddbe472105e0a.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/data_manager/icons/icon_reload_small.png" +dest_files=[ "res://.import/icon_reload_small.png-5cfe0f7b7e56d4c9649ddbe472105e0a.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/data_manager/icons/icon_remove.png b/data_manager/icons/icon_remove.png new file mode 100644 index 0000000..289db46 Binary files /dev/null and b/data_manager/icons/icon_remove.png differ diff --git a/data_manager/icons/icon_remove.png.import b/data_manager/icons/icon_remove.png.import new file mode 100644 index 0000000..39118c6 --- /dev/null +++ b/data_manager/icons/icon_remove.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_remove.png-cd07d5c1378356af560353bd7a42f342.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/data_manager/icons/icon_remove.png" +dest_files=[ "res://.import/icon_remove.png-cd07d5c1378356af560353bd7a42f342.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/data_manager/icons/icon_rename.png b/data_manager/icons/icon_rename.png new file mode 100644 index 0000000..2df503f Binary files /dev/null and b/data_manager/icons/icon_rename.png differ diff --git a/data_manager/icons/icon_rename.png.import b/data_manager/icons/icon_rename.png.import new file mode 100644 index 0000000..2e70835 --- /dev/null +++ b/data_manager/icons/icon_rename.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_rename.png-057eb6051ce4bfd5326de785a2ce0780.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/data_manager/icons/icon_rename.png" +dest_files=[ "res://.import/icon_rename.png-057eb6051ce4bfd5326de785a2ce0780.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/data_manager/icons/icon_save.png b/data_manager/icons/icon_save.png new file mode 100644 index 0000000..8695b78 Binary files /dev/null and b/data_manager/icons/icon_save.png differ diff --git a/data_manager/icons/icon_save.png.import b/data_manager/icons/icon_save.png.import new file mode 100644 index 0000000..ed2c249 --- /dev/null +++ b/data_manager/icons/icon_save.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_save.png-65939defe113bdfb6174e9451d3fb596.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/data_manager/icons/icon_save.png" +dest_files=[ "res://.import/icon_save.png-65939defe113bdfb6174e9451d3fb596.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/data_manager/icons/icon_script.png b/data_manager/icons/icon_script.png new file mode 100644 index 0000000..5aa673f Binary files /dev/null and b/data_manager/icons/icon_script.png differ diff --git a/data_manager/icons/icon_script.png.import b/data_manager/icons/icon_script.png.import new file mode 100644 index 0000000..f6154cd --- /dev/null +++ b/data_manager/icons/icon_script.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_script.png-02675c4ec5dd1554ae0ce28638df6a48.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/data_manager/icons/icon_script.png" +dest_files=[ "res://.import/icon_script.png-02675c4ec5dd1554ae0ce28638df6a48.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/data_manager/panels/AddFolderDialog.gd b/data_manager/panels/AddFolderDialog.gd new file mode 100644 index 0000000..608c714 --- /dev/null +++ b/data_manager/panels/AddFolderDialog.gd @@ -0,0 +1,74 @@ +tool +extends ConfirmationDialog + +const DataManagerAddonSettings = preload("res://addons/data_manager/resources/data_manager_addon_settings.gd") + +var _settings : DataManagerAddonSettings = null +var _module = null + +signal folders_created + +func _enter_tree(): + if !is_connected("confirmed", self, "on_confirmed"): + connect("confirmed", self, "on_confirmed") + +func setup() -> void: + var entry_container : Control = $ScrollContainer/VBoxContainer + + for ch in entry_container.get_children(): + ch.queue_free() + + var dir : Directory = Directory.new() + + var label_str : String = "= " + get_module_label_text(_module) + " =" + window_title = "Add folder(s) for " + label_str + + var module_dir_base : String = _module.resource_path.get_base_dir() + + for f in _settings.folders: + if dir.dir_exists(module_dir_base + "/" + f.folder): + continue + + var ecb : CheckBox = CheckBox.new() + ecb.text = f.folder + " (" + f.type + ")" + ecb.set_meta("folder", f.folder) + entry_container.add_child(ecb) + +func on_confirmed() -> void: + var entry_container : Control = $ScrollContainer/VBoxContainer + + var dir : Directory = Directory.new() + var module_dir_base : String = _module.resource_path.get_base_dir() + + for c in entry_container.get_children(): + if !(c is CheckBox): + continue + + if !c.pressed: + continue + + var folder : String = c.get_meta("folder") + var d : String = module_dir_base + "/" + folder + if !dir.dir_exists(d): + dir.make_dir(d) + + emit_signal("folders_created") + +func set_module(module, settings : DataManagerAddonSettings) -> void: + _module = module + _settings = settings + setup() + #popup_centered() + + popup_centered() + +func get_module_label_text(module) -> String: + var label_str : String = module.resource_name + + if label_str == "": + label_str = module.resource_path + label_str = label_str.replace("res://", "") + label_str = label_str.replace("/game_module.tres", "") + label_str = label_str.replace("game_module.tres", "") + + return label_str diff --git a/data_manager/panels/CreateNamePopup.gd b/data_manager/panels/CreateNamePopup.gd new file mode 100644 index 0000000..b8a6bf7 --- /dev/null +++ b/data_manager/panels/CreateNamePopup.gd @@ -0,0 +1,64 @@ +tool +extends ConfirmationDialog + +signal ok_pressed + +export(NodePath) var line_edit_path : NodePath +export(NodePath) var option_button_path : NodePath + +var _resource_type : String + +var _line_edit : LineEdit +var _option_button : OptionButton + +func _ready(): + _line_edit = get_node(line_edit_path) as LineEdit + _option_button = get_node(option_button_path) as OptionButton + + connect("confirmed", self, "_on_OK_pressed") + connect("about_to_show", self, "about_to_show") + +func set_resource_type(resource_type : String) -> void: + _resource_type = resource_type + + +func about_to_show(): + _option_button.clear() + + if not ClassDB.class_exists(_resource_type): + return + + var arr : PoolStringArray = PoolStringArray() + arr.append(_resource_type) + arr.append_array(ClassDB.get_inheriters_from_class(_resource_type)) + + var gsc : Array = ProjectSettings.get("_global_script_classes") + + var l : int = arr.size() - 1 + + while (arr.size() != l): + l = arr.size() + + for i in range(gsc.size()): + var d : Dictionary = gsc[i] as Dictionary + + var found = false + for j in range(arr.size()): + if arr[j] == d["class"]: + found = true + break + + if found: + continue + + for j in range(arr.size()): + if arr[j] == d["base"]: + arr.append(d["class"]) + + for a in arr: + _option_button.add_item(a) + + +func _on_OK_pressed(): + emit_signal("ok_pressed", _line_edit.text, _option_button.get_item_text(_option_button.selected)) + hide() diff --git a/data_manager/panels/CreateNamePopup.tscn b/data_manager/panels/CreateNamePopup.tscn new file mode 100644 index 0000000..03129d6 --- /dev/null +++ b/data_manager/panels/CreateNamePopup.tscn @@ -0,0 +1,58 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://addons/data_manager/panels/CreateNamePopup.gd" type="Script" id=1] + + +[node name="CreateNamePopup" type="ConfirmationDialog"] +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +margin_left = -245.5 +margin_top = -125.5 +margin_right = 245.5 +margin_bottom = 125.5 +window_title = "Create New Resource" +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} +line_edit_path = NodePath("VBoxContainer/LineEdit") +option_button_path = NodePath("VBoxContainer/OptionButton") + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +margin_left = 8.0 +margin_top = 8.0 +margin_right = 483.0 +margin_bottom = 215.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Label2" type="Label" parent="VBoxContainer"] +margin_right = 449.0 +margin_bottom = 25.0 +size_flags_horizontal = 3 +text = "Type" + +[node name="OptionButton" type="OptionButton" parent="VBoxContainer"] +margin_top = 33.0 +margin_right = 449.0 +margin_bottom = 70.0 +size_flags_horizontal = 3 + +[node name="Label" type="Label" parent="VBoxContainer"] +margin_top = 78.0 +margin_right = 449.0 +margin_bottom = 103.0 +size_flags_horizontal = 3 +text = "Name" + +[node name="LineEdit" type="LineEdit" parent="VBoxContainer"] +margin_top = 111.0 +margin_right = 449.0 +margin_bottom = 156.0 +size_flags_horizontal = 3 +caret_blink = true diff --git a/data_manager/panels/EntryButton.gd b/data_manager/panels/EntryButton.gd new file mode 100644 index 0000000..80913e3 --- /dev/null +++ b/data_manager/panels/EntryButton.gd @@ -0,0 +1,93 @@ +tool +extends Control + +signal inspect_data +signal duplicate +signal delete + +export(PackedScene) var spatial_preview : PackedScene +export(PackedScene) var node2d_preview : PackedScene +export(PackedScene) var control_preview : PackedScene +export(PackedScene) var texture_preview : PackedScene + +export(NodePath) var main_button_path : NodePath + +var _main_button : Button + +var _preview : Node +var _data : Resource + +func _ready(): + _main_button = get_node(main_button_path) as Button + +func set_resource(data : Resource) -> void: + _data = data + + _main_button.set_resource(data) + + var name_text : String = "" + + if data.has_method("get_id"): + name_text += str(data.get_id()) + " - " + + if data.has_method("get_text_name"): + name_text += str(data.get_text_name()) + else: + if data.resource_name != "": + name_text += data.resource_name + else: + name_text += data.resource_path + + if data.has_method("get_rank"): + name_text += " - Rank " + str(data.get_rank()) + + if data is Texture: + _preview = texture_preview.instance() + add_child(_preview) + _preview.owner = self + move_child(_preview, 0) + + _preview.set_texture(data as Texture) + elif data is PackedScene: + var n : Node = data.instance() + + if _preview != null: + _preview.queue_free() + + if n is Spatial: + _preview = spatial_preview.instance() + add_child(_preview) + _preview.owner = self + move_child(_preview, 0) + + _preview.preview(n as Spatial) + elif n is Node2D: + _preview = node2d_preview.instance() + add_child(_preview) + _preview.owner = self + move_child(_preview, 0) + + _preview.preview(n as Node2D) + elif n is Control: + _preview = control_preview.instance() + add_child(_preview) + _preview.owner = self + move_child(_preview, 0) + + _preview.preview(n as Control) + else: + n.queue_free() + + _main_button.text = name_text + +func can_drop_data(position, data): + return false + +func inspect(): + emit_signal("inspect_data", _data) + +func duplicate_data(): + emit_signal("duplicate", _data) + +func delete(): + emit_signal("delete", _data) diff --git a/data_manager/panels/HistoryEntry.gd b/data_manager/panels/HistoryEntry.gd new file mode 100644 index 0000000..a60afea --- /dev/null +++ b/data_manager/panels/HistoryEntry.gd @@ -0,0 +1,41 @@ +tool +extends Button + +signal history_entry_selected + +var data : Resource setget set_data#, get_data + +func _pressed() -> void: + emit_signal("history_entry_selected", data) + +func set_data(pdata: Resource) -> void: + data = pdata + + var s : String = "(" + data.get_class() + ") " + + if data.has_method("get_id"): + s += str(data.get_id()) + " - " + + if data.has_method("get_text_name"): + s += str(data.get_text_name()) + elif data.has_method("get_name"): + s += str(data.get_name()) + + if data.has_method("get_rank"): + s += " (R " + str(data.get_rank()) + ")" + + text = s + +func get_data() -> Resource: + return data + +func get_drag_data(position): + if data == null: + return null + + var d : Dictionary = Dictionary() + d["type"] = "resource" + d["resource"] = data + d["from"] = self + + return d diff --git a/data_manager/panels/HistoryEntry.tscn b/data_manager/panels/HistoryEntry.tscn new file mode 100644 index 0000000..8bc48dc --- /dev/null +++ b/data_manager/panels/HistoryEntry.tscn @@ -0,0 +1,11 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://addons/data_manager/panels/HistoryEntry.gd" type="Script" id=1] + +[node name="HistoryEntry" type="Button"] +margin_right = 236.0 +margin_bottom = 37.0 +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} diff --git a/data_manager/panels/MainPanel.gd b/data_manager/panels/MainPanel.gd new file mode 100644 index 0000000..969ca52 --- /dev/null +++ b/data_manager/panels/MainPanel.gd @@ -0,0 +1,216 @@ +tool +extends Control + +const DataManagerAddonSettings = preload("res://addons/data_manager/resources/data_manager_addon_settings.gd") +const add_icon = preload("res://addons/data_manager/icons/icon_add.png") + +signal inspect_data + +export(PackedScene) var resource_scene : PackedScene +export(String) var base_folder : String = "res://" +export(NodePath) var main_container : NodePath +export(NodePath) var module_entry_container_path : NodePath +export(NodePath) var folder_entry_container_path : NodePath + +var _main_container : Node +var _resource_scene : Node +var _module_entry_container : Node +var _folder_entry_container : Node + +var _modules : Array = Array() +var _active_modules : Array = Array() +var _settings : DataManagerAddonSettings = null + +var _initialized : bool = false +var _plugin : EditorPlugin = null + +func _enter_tree(): + if !is_connected("visibility_changed", self, "on_visibility_changed"): + connect("visibility_changed", self, "on_visibility_changed") + + if !$Popups/AddFolderDialog.is_connected("folders_created", self, "on_folders_created"): + $Popups/AddFolderDialog.connect("folders_created", self, "on_folders_created") + +func on_visibility_changed(): + if _plugin && is_visible_in_tree() && !_initialized: + _initialized = true + load_data() + +func load_data(): + var dir : Directory = Directory.new() + + _settings = _plugin.settings + + _main_container = get_node(main_container) + + _resource_scene = resource_scene.instance() + _main_container.add_child(_resource_scene) + _resource_scene.owner = _main_container + _resource_scene.connect("inspect_data", self, "inspect_data") + + _module_entry_container = get_node(module_entry_container_path) + _folder_entry_container = get_node(folder_entry_container_path) + + generate_module_entry_list() + +func generate_module_entry_list() -> void: + for ch in _folder_entry_container.get_children(): + ch.queue_free() + + load_modules() + + for m in _modules: + var label_str : String = get_module_label_text(m) + + var b : Button = Button.new() + b.toggle_mode = true + b.text = label_str + b.set_h_size_flags(SIZE_EXPAND_FILL) + b.connect("toggled", self, "on_module_entry_button_toggled", [ m ]) + _module_entry_container.add_child(b) + +func generate_folder_entry_list() -> void: + for ch in _folder_entry_container.get_children(): + ch.queue_free() + + var dir : Directory = Directory.new() + + for i in range(_active_modules.size()): + var module = _active_modules[i] + + if i > 0: + _folder_entry_container.add_child(HSeparator.new()) + + var label_str : String = "= " + get_module_label_text(module) + " =" + var mlabel : Label = Label.new() + mlabel.text = label_str + mlabel.align = HALIGN_CENTER + mlabel.valign = VALIGN_CENTER + _folder_entry_container.add_child(mlabel) + var module_dir_base : String = module.resource_path.get_base_dir() + + var index = 0 + for j in range(_settings.get_folder_count()): + var f = _settings.folder_get(j) + var full_folder_path : String = module_dir_base + "/" + f.folder + + if !dir.dir_exists(full_folder_path): + continue + + if f.header != "": + var h : Label = Label.new() + + _folder_entry_container.add_child(h) + h.text = f.header + + var fe : Button = Button.new() + fe.text = f.name + fe.connect("pressed", self, "on_folder_entry_button_pressed", [ module, full_folder_path, j ]) + _folder_entry_container.add_child(fe) + + index += 1 + + var bsep : Label = Label.new() + bsep.text = "Actions" + _folder_entry_container.add_child(bsep) + + var add_folder_button : Button = Button.new() + add_folder_button.text = "Add Folder" + add_folder_button.icon = add_icon + _folder_entry_container.add_child(add_folder_button) + add_folder_button.connect("pressed", self, "on_add_folder_button_pressed", [ module ]) + + #set_tab(0) + +func on_folder_entry_button_pressed(module, full_folder_path : String, folder_index : int) -> void: + #_resource_scene.show() + _resource_scene.set_resource_type(full_folder_path, _settings.folder_get_type(folder_index)) + +func on_module_entry_button_toggled(on : bool, module) -> void: + if on: + for m in _active_modules: + if m == module: + return + + _active_modules.push_back(module) + generate_folder_entry_list() + else: + for i in range(_active_modules.size()): + if _active_modules[i] == module: + _active_modules.remove(i) + generate_folder_entry_list() + return + +func on_add_folder_button_pressed(module) -> void: + $Popups/AddFolderDialog.set_module(module, _settings) + +func load_modules() -> void: + _modules.clear() + load_modules_at("res://") + _modules.sort_custom(ModulePathSorter, "sort_ascending") + +func load_modules_at(path : String) -> void: + var dir = Directory.new() + if dir.open(path) == OK: + dir.list_dir_begin() + var file_name = dir.get_next() + while file_name != "": + if file_name == "." or file_name == "..": + file_name = dir.get_next() + continue + + if dir.current_is_dir(): + if path == "res://": + load_modules_at(path + file_name) + else: + load_modules_at(path + "/" + file_name) + else: + if file_name == "game_module.tres": + var res : Resource = null + + if path == "res://": + res = ResourceLoader.load(path + file_name) + else: + res = ResourceLoader.load(path + "/" + file_name) + + if res.enabled: + _modules.append(res) + + file_name = dir.get_next() + else: + print("An error occurred when trying to access the path: " + path) + +class ModulePathSorter: + static func sort_ascending(a, b): + if a.resource_path < b.resource_path: + return true + return false + +func set_tab(tab_index : int) -> void: + hide_all() + + _resource_scene.show() + _resource_scene.set_resource_type(_settings.folder_get_folder(tab_index), _settings.folder_get_type(tab_index)) + +func hide_all() -> void: + _resource_scene.hide() + +func inspect_data(var data : Resource) -> void: + emit_signal("inspect_data", data) + +func set_plugin(plugin : EditorPlugin) -> void: + _plugin = plugin + +func get_module_label_text(module) -> String: + var label_str : String = module.resource_name + + if label_str == "": + label_str = module.resource_path + label_str = label_str.replace("res://", "") + label_str = label_str.replace("/game_module.tres", "") + label_str = label_str.replace("game_module.tres", "") + + return label_str + +func on_folders_created() -> void: + generate_folder_entry_list() diff --git a/data_manager/panels/MainPanel.tscn b/data_manager/panels/MainPanel.tscn new file mode 100644 index 0000000..9b6c718 --- /dev/null +++ b/data_manager/panels/MainPanel.tscn @@ -0,0 +1,101 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://addons/data_manager/panels/MainPanel.gd" type="Script" id=1] +[ext_resource path="res://addons/data_manager/panels/ResourcePanel.tscn" type="PackedScene" id=3] +[ext_resource path="res://addons/data_manager/panels/AddFolderDialog.gd" type="Script" id=4] + +[node name="Panel" type="MarginContainer"] +anchor_right = 1.0 +anchor_bottom = 1.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} +resource_scene = ExtResource( 3 ) +base_folder = "res://data/" +main_container = NodePath("HSplitContainer/MarginContainer") +module_entry_container_path = NodePath("HSplitContainer/TabContainer/Modules/VBoxContainer") +folder_entry_container_path = NodePath("HSplitContainer/TabContainer/Folders/VBoxContainer") + +[node name="HSplitContainer" type="HSplitContainer" parent="."] +margin_right = 1024.0 +margin_bottom = 600.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 +split_offset = 210 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="TabContainer" type="TabContainer" parent="HSplitContainer"] +margin_right = 218.0 +margin_bottom = 600.0 + +[node name="Modules" type="ScrollContainer" parent="HSplitContainer/TabContainer"] +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_left = 4.0 +margin_top = 32.0 +margin_right = -4.0 +margin_bottom = -4.0 +size_flags_vertical = 3 +scroll_horizontal_enabled = false + +[node name="VBoxContainer" type="VBoxContainer" parent="HSplitContainer/TabContainer/Modules"] +margin_right = 210.0 +size_flags_horizontal = 3 + +[node name="Folders" type="ScrollContainer" parent="HSplitContainer/TabContainer"] +visible = false +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_left = 4.0 +margin_top = 32.0 +margin_right = -4.0 +margin_bottom = -4.0 +size_flags_vertical = 3 +scroll_horizontal_enabled = false + +[node name="VBoxContainer" type="VBoxContainer" parent="HSplitContainer/TabContainer/Folders"] +margin_right = 210.0 +size_flags_horizontal = 3 + +[node name="MarginContainer" type="MarginContainer" parent="HSplitContainer"] +margin_left = 230.0 +margin_right = 1024.0 +margin_bottom = 600.0 + +[node name="Popups" type="Control" parent="."] +margin_right = 1024.0 +margin_bottom = 600.0 +mouse_filter = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +__meta__ = { +"_edit_lock_": true +} + +[node name="AddFolderDialog" type="ConfirmationDialog" parent="Popups"] +margin_left = 287.0 +margin_top = 100.0 +margin_right = 751.0 +margin_bottom = 447.0 +window_title = "Add folder(s)" +resizable = true +script = ExtResource( 4 ) + +[node name="ScrollContainer" type="ScrollContainer" parent="Popups/AddFolderDialog"] +margin_left = 8.0 +margin_top = 8.0 +margin_right = 456.0 +margin_bottom = 311.0 +scroll_horizontal_enabled = false +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="VBoxContainer" type="VBoxContainer" parent="Popups/AddFolderDialog/ScrollContainer"] +margin_right = 448.0 +size_flags_horizontal = 3 diff --git a/data_manager/panels/ResourcePanel.gd b/data_manager/panels/ResourcePanel.gd new file mode 100644 index 0000000..707e14a --- /dev/null +++ b/data_manager/panels/ResourcePanel.gd @@ -0,0 +1,294 @@ +tool +extends Control + +signal inspect_data + +export(PackedScene) var resource_row_scene : PackedScene +export(PackedScene) var history_row_scene : PackedScene + +export(NodePath) var entry_container_path : NodePath + +export(NodePath) var name_popup_path : NodePath +export(NodePath) var create_popup_path : NodePath +export(NodePath) var delete_popup_path : NodePath + +export(NodePath) var history_container_path : NodePath + +var _filter_term : String + +var _entry_container : Node +var _name_popup : Node +var _create_popup : ConfirmationDialog +var _delete_popup : ConfirmationDialog + +var _history_container : Node + +var _folder : String +var _resource_type : String + +var _queue_deleted : Resource + +var _state : Dictionary +var _states : Dictionary + +func _ready(): + _history_container = get_node(history_container_path) + + _entry_container = get_node(entry_container_path) + _name_popup = get_node(name_popup_path) + _name_popup.connect("ok_pressed", self, "ok_pressed") + + _create_popup = get_node(create_popup_path) + _delete_popup = get_node(delete_popup_path) + +func set_resource_type(folder : String, resource_type : String) -> void: + if !folder.ends_with("/"): + folder += "/" + + if folder == _folder and _resource_type == resource_type: + return + + _states[_folder + "," + _resource_type] = _state + + if _states.has(folder + "," + resource_type): + _state = _states[folder + "," + resource_type] + else: + _state = Dictionary() + + _folder = folder + _resource_type = resource_type + +# _filter_term = "" + + _create_popup.set_resource_type(resource_type) + + refresh() + +func refresh() -> void: + for ch in _entry_container.get_children(): + ch.queue_free() + + var dir : Directory = Directory.new() + + if dir.open(_folder) == OK: + dir.list_dir_begin() + var data_array : Array = Array() + + var file_name = dir.get_next() + + while (file_name != ""): + if not dir.current_is_dir(): + + if ResourceLoader.exists(_folder + file_name, _resource_type): + + var res = ResourceLoader.load(_folder + file_name, _resource_type) + + if _filter_term != "": + var ftext : String = "" + + if res.has_method("get_text_name"): + ftext = res.get_text_name() + + if ftext == "": + if res.resource_name != "": + ftext = res.resource_name + else: + ftext = res.resource_path + + ftext = ftext.to_lower() + + if ftext.find(_filter_term) == -1: + file_name = dir.get_next() + continue + + var id : int = 0 + + if res.has_method("get_id"): + id = res.get_id() + + data_array.append({ + "id": id, + "resource": res + }) + + file_name = dir.get_next() + + data_array.sort_custom(self, "sort_entries") + + for d in data_array: + + var resn : Node = resource_row_scene.instance() + + _entry_container.add_child(resn) + resn.owner = _entry_container + resn.set_resource(d["resource"]) + resn.connect("inspect_data", self, "inspect_data") + resn.connect("duplicate", self, "duplicate_data") + resn.connect("delete", self, "delete") + +func inspect_data(var data : Resource) -> void: + var found : bool = false + + for ch in _history_container.get_children(): + if ch.data == data: + found = true + + _history_container.move_child(ch, 0) + + break + + if not found: + var n : Node = history_row_scene.instance() + + _history_container.add_child(n) + _history_container.move_child(n, 0) + n.owner = _history_container + + n.data = data + n.connect("history_entry_selected", self, "inspect_data") + + if _history_container.get_child_count() > 20: + var ch : Node = _history_container.get_child(_history_container.get_child_count() - 1) + + ch.queue_free() + + emit_signal("inspect_data", data) + +func ok_pressed(res_name: String, pclass_name: String) -> void: + + var d : Directory = Directory.new() + + if d.open(_folder) == OK: + d.list_dir_begin() + + var file_name = d.get_next() + + var max_ind : int = 0 + + while (file_name != ""): + + if not d.current_is_dir(): + + var curr_ind : int = int(file_name.split("_")[0]) + + if curr_ind > max_ind: + max_ind = curr_ind + + file_name = d.get_next() + + max_ind += 1 + + var newfname : String = str(res_name) + newfname = newfname.replace(" ", "_") + newfname = newfname.to_lower() + newfname = str(max_ind) + "_" + newfname + ".tres" + + var res : Resource = null + + if ClassDB.class_exists(pclass_name) and ClassDB.can_instance(pclass_name): + res = ClassDB.instance(pclass_name) + else: + var gsc : Array = ProjectSettings.get("_global_script_classes") + + for i in range(gsc.size()): + var gsce : Dictionary = gsc[i] as Dictionary + + if gsce["class"] == pclass_name: + var script : Script = load(gsce["path"]) + + res = script.new() + + break + + if res == null: + print("ESSData: Error in creating resource type " + pclass_name) + return + + if res.has_method("set_id"): + res.set_id(max_ind) + + if res.has_method("set_text_name"): + res.set_text_name(str(res_name)) + + ResourceSaver.save(_folder + newfname, res) + + refresh() + +func duplicate_data(data): + if not data is Resource: + return + + var d : Directory = Directory.new() + + if d.open(_folder) == OK: + d.list_dir_begin() + + var file_name = d.get_next() + + var max_ind : int = 0 + + while (file_name != ""): + + if not d.current_is_dir(): + + var curr_ind : int = int(file_name.split("_")[0]) + + if curr_ind > max_ind: + max_ind = curr_ind + + file_name = d.get_next() + + max_ind += 1 + + var res_name : String = "" + + if data.has_method("get_text_name"): + res_name = data.get_text_name() + + var newfname : String = res_name + newfname = newfname.replace(" ", "_") + newfname = newfname.to_lower() + newfname = str(max_ind) + "_" + newfname + ".tres" + + var res : Resource = data.duplicate() + + if res.has_method("set_id"): + res.set_id(max_ind) + + if res.has_method("set_text_name"): + res.set_text_name(str(res_name)) + + ResourceSaver.save(_folder + newfname, res) + + refresh() + +func delete(data): + if data == null or data as Resource == null: + return + + _queue_deleted = data as Resource + + _delete_popup.popup_centered() + +func delete_confirm(): + if _queue_deleted == null: + return + + var d : Directory = Directory.new() + d.remove(_queue_deleted.resource_path) + + _queue_deleted = null + + refresh() + +func clear_history() -> void: + for ch in _history_container.get_children(): + ch.queue_free() + +func search(text : String) -> void: + _filter_term = text.to_lower() + + refresh() + +func sort_entries(a, b): + return a["id"] < b["id"] diff --git a/data_manager/panels/ResourcePanel.tscn b/data_manager/panels/ResourcePanel.tscn new file mode 100644 index 0000000..45fea9a --- /dev/null +++ b/data_manager/panels/ResourcePanel.tscn @@ -0,0 +1,118 @@ +[gd_scene load_steps=8 format=2] + +[ext_resource path="res://addons/data_manager/panels/CreateNamePopup.tscn" type="PackedScene" id=1] +[ext_resource path="res://addons/data_manager/panels/ResourceRow.tscn" type="PackedScene" id=2] +[ext_resource path="res://addons/data_manager/panels/HistoryEntry.tscn" type="PackedScene" id=3] +[ext_resource path="res://addons/data_manager/icons/icon_add.png" type="Texture" id=4] +[ext_resource path="res://addons/data_manager/panels/ResourcePanel.gd" type="Script" id=5] +[ext_resource path="res://addons/data_manager/icons/icon_empty.png" type="Texture" id=6] +[ext_resource path="res://addons/data_manager/icons/icon_reload_small.png" type="Texture" id=7] + +[node name="Panel" type="Control"] +anchor_right = 1.0 +anchor_bottom = 1.0 +script = ExtResource( 5 ) +__meta__ = { +"_edit_use_anchors_": false +} +resource_row_scene = ExtResource( 2 ) +history_row_scene = ExtResource( 3 ) +entry_container_path = NodePath("ResourcePanel/VBoxContainer2/ScrollContainer2/VBoxContainer") +name_popup_path = NodePath("CreateNamePopup") +create_popup_path = NodePath("CreateNamePopup") +delete_popup_path = NodePath("DeletePopup") +history_container_path = NodePath("ResourcePanel/VBoxContainer/ScrollContainer/VBoxContainer") + +[node name="ResourcePanel" type="HSplitContainer" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +split_offset = 500 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="VBoxContainer2" type="VBoxContainer" parent="ResourcePanel"] +margin_right = 600.0 +margin_bottom = 600.0 + +[node name="LineEdit" type="LineEdit" parent="ResourcePanel/VBoxContainer2"] +margin_right = 600.0 +margin_bottom = 26.0 +right_icon = ExtResource( 6 ) +placeholder_text = "Filter" +caret_blink = true + +[node name="CreateButton" type="Button" parent="ResourcePanel/VBoxContainer2"] +margin_top = 30.0 +margin_right = 600.0 +margin_bottom = 50.0 +rect_min_size = Vector2( 100, 0 ) +text = "Create" +icon = ExtResource( 4 ) +expand_icon = true + +[node name="HSeparator" type="HSeparator" parent="ResourcePanel/VBoxContainer2"] +margin_top = 54.0 +margin_right = 600.0 +margin_bottom = 58.0 +size_flags_horizontal = 3 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="ScrollContainer2" type="ScrollContainer" parent="ResourcePanel/VBoxContainer2"] +margin_top = 62.0 +margin_right = 600.0 +margin_bottom = 600.0 +size_flags_vertical = 3 + +[node name="VBoxContainer" type="VBoxContainer" parent="ResourcePanel/VBoxContainer2/ScrollContainer2"] +margin_right = 600.0 +size_flags_horizontal = 3 + +[node name="VBoxContainer" type="VBoxContainer" parent="ResourcePanel"] +margin_left = 612.0 +margin_right = 1024.0 +margin_bottom = 600.0 + +[node name="Button" type="Button" parent="ResourcePanel/VBoxContainer"] +margin_right = 412.0 +margin_bottom = 20.0 +size_flags_horizontal = 3 +text = "Clear History" +icon = ExtResource( 7 ) + +[node name="HSeparator" type="HSeparator" parent="ResourcePanel/VBoxContainer"] +margin_top = 24.0 +margin_right = 412.0 +margin_bottom = 28.0 +size_flags_horizontal = 3 + +[node name="ScrollContainer" type="ScrollContainer" parent="ResourcePanel/VBoxContainer"] +margin_top = 32.0 +margin_right = 412.0 +margin_bottom = 600.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 + +[node name="VBoxContainer" type="VBoxContainer" parent="ResourcePanel/VBoxContainer/ScrollContainer"] +margin_right = 412.0 +size_flags_horizontal = 3 + +[node name="CreateNamePopup" parent="." instance=ExtResource( 1 )] + +[node name="DeletePopup" type="ConfirmationDialog" parent="."] +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +margin_left = -139.0 +margin_top = -55.0 +margin_right = 139.0 +margin_bottom = 55.0 +dialog_text = "Delete?" + +[connection signal="text_entered" from="ResourcePanel/VBoxContainer2/LineEdit" to="." method="search"] +[connection signal="pressed" from="ResourcePanel/VBoxContainer2/CreateButton" to="CreateNamePopup" method="popup"] +[connection signal="pressed" from="ResourcePanel/VBoxContainer/Button" to="." method="clear_history"] +[connection signal="confirmed" from="DeletePopup" to="." method="delete_confirm"] diff --git a/data_manager/panels/ResourceRow.tscn b/data_manager/panels/ResourceRow.tscn new file mode 100644 index 0000000..801367c --- /dev/null +++ b/data_manager/panels/ResourceRow.tscn @@ -0,0 +1,47 @@ +[gd_scene load_steps=9 format=2] + +[ext_resource path="res://addons/data_manager/previews/TexturePreview.tscn" type="PackedScene" id=1] +[ext_resource path="res://addons/data_manager/previews/ControlPreview.tscn" type="PackedScene" id=2] +[ext_resource path="res://addons/data_manager/previews/Node2DPreview.tscn" type="PackedScene" id=3] +[ext_resource path="res://addons/data_manager/previews/SpatialPreview.tscn" type="PackedScene" id=4] +[ext_resource path="res://addons/data_manager/panels/ResourceRowMainButton.gd" type="Script" id=5] +[ext_resource path="res://addons/data_manager/panels/EntryButton.gd" type="Script" id=6] +[ext_resource path="res://addons/data_manager/icons/icon_duplicate.png" type="Texture" id=7] +[ext_resource path="res://addons/data_manager/icons/icon_remove.png" type="Texture" id=8] + + +[node name="ResourceRow" type="HBoxContainer"] +margin_right = 634.0 +margin_bottom = 37.0 +rect_min_size = Vector2( 100, 0 ) +size_flags_horizontal = 3 +script = ExtResource( 6 ) +__meta__ = { +"_edit_use_anchors_": false +} +spatial_preview = ExtResource( 4 ) +node2d_preview = ExtResource( 3 ) +control_preview = ExtResource( 2 ) +texture_preview = ExtResource( 1 ) +main_button_path = NodePath("ResourceRowMainButton") + +[node name="ResourceRowMainButton" type="Button" parent="."] +margin_right = 570.0 +margin_bottom = 37.0 +size_flags_horizontal = 3 +script = ExtResource( 5 ) + +[node name="Button2" type="Button" parent="."] +margin_left = 574.0 +margin_right = 602.0 +margin_bottom = 37.0 +icon = ExtResource( 7 ) + +[node name="Button3" type="Button" parent="."] +margin_left = 606.0 +margin_right = 634.0 +margin_bottom = 37.0 +icon = ExtResource( 8 ) +[connection signal="pressed" from="ResourceRowMainButton" to="." method="inspect"] +[connection signal="pressed" from="Button2" to="." method="duplicate_data"] +[connection signal="pressed" from="Button3" to="." method="delete"] diff --git a/data_manager/panels/ResourceRowMainButton.gd b/data_manager/panels/ResourceRowMainButton.gd new file mode 100644 index 0000000..37177fc --- /dev/null +++ b/data_manager/panels/ResourceRowMainButton.gd @@ -0,0 +1,18 @@ +tool +extends Button + +var _data : Resource + +func get_drag_data(position): + if _data == null: + return null + + var d : Dictionary = Dictionary() + d["type"] = "resource" + d["resource"] = _data + d["from"] = self + + return d + +func set_resource(data : Resource) -> void: + _data = data diff --git a/data_manager/plugin.cfg b/data_manager/plugin.cfg new file mode 100644 index 0000000..fae3f87 --- /dev/null +++ b/data_manager/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="Data Manager" +description="" +author="Relintai" +version="1.0" +script="plugin.gd" diff --git a/data_manager/plugin.gd b/data_manager/plugin.gd new file mode 100644 index 0000000..4b3a338 --- /dev/null +++ b/data_manager/plugin.gd @@ -0,0 +1,61 @@ +tool +extends EditorPlugin + +const DataManagerAddonSettings = preload("res://addons/data_manager/resources/data_manager_addon_settings.gd") + +const _main_panel : PackedScene = preload("res://addons/data_manager/panels/MainPanel.tscn") +const _script_icon : Texture = preload("res://addons/data_manager/icons/icon_multi_line.png") + +var settings : DataManagerAddonSettings = null + +var _main_panel_instance : Control + +func _enter_tree(): + load_settings() + + _main_panel_instance = _main_panel.instance() as Control + _main_panel_instance.set_plugin(self) + _main_panel_instance.connect("inspect_data", self, "inspect_data") + + get_editor_interface().get_editor_viewport().add_child(_main_panel_instance) + + make_visible(false) + +func _exit_tree(): + _main_panel_instance.queue_free() + +func has_main_screen(): + return true + +func make_visible(visible): + if visible: + _main_panel_instance.show() + else: + _main_panel_instance.hide() + +func get_plugin_icon(): + return _script_icon + +func get_plugin_name(): + return "Data" + +func inspect_data(var data : Resource) -> void: + get_editor_interface().inspect_object(data) + +func ensure_data_dir_exists() -> void: + var dir : Directory = Directory.new() + + if !dir.dir_exists("res://addons/data_manager/_data/"): + dir.make_dir("res://addons/data_manager/_data/") + +func load_settings() -> void: + ensure_data_dir_exists() + + var dir : Directory = Directory.new() + + if !dir.file_exists("res://addons/data_manager/_data/settings.tres"): + settings = DataManagerAddonSettings.new() + + ResourceSaver.save("res://addons/data_manager/_data/settings.tres", settings) + else: + settings = ResourceLoader.load("res://addons/data_manager/_data/settings.tres") diff --git a/data_manager/previews/ControlPreview.gd b/data_manager/previews/ControlPreview.gd new file mode 100644 index 0000000..0758c3e --- /dev/null +++ b/data_manager/previews/ControlPreview.gd @@ -0,0 +1,14 @@ +tool +extends ViewportContainer + +export(NodePath) var container_path : NodePath + +var _container : Node + +func _ready() -> void: + _container = get_node(container_path) + +func preview(n: Control) -> void: + _container.add_child(n) + n.owner = _container + diff --git a/data_manager/previews/ControlPreview.tscn b/data_manager/previews/ControlPreview.tscn new file mode 100644 index 0000000..fb2d460 --- /dev/null +++ b/data_manager/previews/ControlPreview.tscn @@ -0,0 +1,22 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://addons/data_manager/previews/ControlPreview.gd" type="Script" id=1] + + +[node name="ControlPreview" type="ViewportContainer"] +margin_right = 60.0 +margin_bottom = 60.0 +rect_min_size = Vector2( 60, 60 ) +rect_pivot_offset = Vector2( -198.876, -96.6558 ) +stretch = true +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} +container_path = NodePath("Viewport") + +[node name="Viewport" type="Viewport" parent="."] +size = Vector2( 500, 500 ) +own_world = true +handle_input_locally = false +render_target_update_mode = 3 diff --git a/data_manager/previews/Node2DPreview.gd b/data_manager/previews/Node2DPreview.gd new file mode 100644 index 0000000..586b8d9 --- /dev/null +++ b/data_manager/previews/Node2DPreview.gd @@ -0,0 +1,14 @@ +tool +extends ViewportContainer + +export(NodePath) var container_path : NodePath + +var _container : Node + +func _ready() -> void: + _container = get_node(container_path) + +func preview(n: Node2D) -> void: + _container.add_child(n) + n.owner = _container + diff --git a/data_manager/previews/Node2DPreview.tscn b/data_manager/previews/Node2DPreview.tscn new file mode 100644 index 0000000..563a1c3 --- /dev/null +++ b/data_manager/previews/Node2DPreview.tscn @@ -0,0 +1,25 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://addons/data_manager/previews/Node2DPreview.gd" type="Script" id=1] + + +[node name="Node2DPreview" type="ViewportContainer"] +margin_right = 60.0 +margin_bottom = 60.0 +rect_min_size = Vector2( 60, 60 ) +rect_pivot_offset = Vector2( -198.876, -96.6558 ) +stretch = true +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} +container_path = NodePath("Viewport") + +[node name="Viewport" type="Viewport" parent="."] +size = Vector2( 500, 500 ) +own_world = true +handle_input_locally = false +render_target_update_mode = 3 + +[node name="Camera2D" type="Camera2D" parent="Viewport"] +current = true diff --git a/data_manager/previews/SpatialPreview.gd b/data_manager/previews/SpatialPreview.gd new file mode 100644 index 0000000..565cb9d --- /dev/null +++ b/data_manager/previews/SpatialPreview.gd @@ -0,0 +1,14 @@ +tool +extends ViewportContainer + +export(NodePath) var container_path : NodePath + +var _container : Node + +func _ready() -> void: + _container = get_node(container_path) + +func preview(n: Spatial) -> void: + _container.add_child(n) + n.owner = _container + diff --git a/data_manager/previews/SpatialPreview.tscn b/data_manager/previews/SpatialPreview.tscn new file mode 100644 index 0000000..018e5d5 --- /dev/null +++ b/data_manager/previews/SpatialPreview.tscn @@ -0,0 +1,29 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://addons/data_manager/previews/SpatialPreview.gd" type="Script" id=1] + + +[node name="SpatialPreview" type="ViewportContainer"] +margin_right = 60.0 +margin_bottom = 60.0 +rect_min_size = Vector2( 60, 60 ) +rect_pivot_offset = Vector2( -198.876, -96.6558 ) +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} +container_path = NodePath("Viewport") + +[node name="Viewport" type="Viewport" parent="."] +size = Vector2( 60, 60 ) +size_override_stretch = true +own_world = true +handle_input_locally = false +render_target_update_mode = 3 + +[node name="Camera" type="Camera" parent="Viewport"] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10.9828 ) +current = true + +[node name="DirectionalLight" type="DirectionalLight" parent="Viewport"] +transform = Transform( 0.276929, 0, -0.96089, 0, 1, 0, 0.96089, 0, 0.276929, -13.093, 0, 6.67786 ) diff --git a/data_manager/previews/TexturePreview.gd b/data_manager/previews/TexturePreview.gd new file mode 100644 index 0000000..5b50e16 --- /dev/null +++ b/data_manager/previews/TexturePreview.gd @@ -0,0 +1,12 @@ +tool +extends TextureRect + +func set_texture(tex: Texture)-> void: + texture = tex + + if tex is PackerImageResource: + var t : ImageTexture = ImageTexture.new() + + t.create_from_image(tex.data, 0) + + texture = t diff --git a/data_manager/previews/TexturePreview.tscn b/data_manager/previews/TexturePreview.tscn new file mode 100644 index 0000000..1dabb99 --- /dev/null +++ b/data_manager/previews/TexturePreview.tscn @@ -0,0 +1,13 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://addons/data_manager/previews/TexturePreview.gd" type="Script" id=1] + + +[node name="TexturePreview" type="TextureRect"] +margin_bottom = 37.0 +rect_min_size = Vector2( 50, 50 ) +expand = true +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} diff --git a/data_manager/resources/data_manager_addon_settings.gd b/data_manager/resources/data_manager_addon_settings.gd new file mode 100644 index 0000000..dab1575 --- /dev/null +++ b/data_manager/resources/data_manager_addon_settings.gd @@ -0,0 +1,139 @@ +tool +extends Resource + +class SettingEntry: + var folder : String = "" + var header : String = "" + var name : String = "" + var type : String = "" + +var folders : Array = Array() + +func get_folder_count() -> int: + return folders.size() + +func folder_get(index : int) -> SettingEntry: + return folders[index] + +func folder_get_folder(index : int) -> String: + return folders[index].folder + +func folder_get_header(index : int) -> String: + return folders[index].header + +func folder_get_name(index : int) -> String: + return folders[index].name + +func folder_get_type(index : int) -> String: + return folders[index].type + +func _get(property : StringName): + var sprop : String = property + + if sprop == "folder_count": + return folders.size() + + if sprop.begins_with("folders/"): + var sindex : String = sprop.get_slice("/", 1) + + if sindex == "": + return null + + var index : int = sindex.to_int() + + if index < 0 || index >= folders.size(): + return null + + var p : String = sprop.get_slice("/", 2) + + if p == "folder": + return folders[index].folder + elif p == "header": + return folders[index].header + elif p == "name": + return folders[index].name + elif p == "type": + return folders[index].type + else: + return null + + return null + +func _set(property : StringName, val) -> bool: + var sprop : String = property + + if property == "folder_count": + set_folder_count(val) + return true + + if sprop.begins_with("folders/"): + var sindex : String = sprop.get_slice("/", 1) + + if sindex == "": + return false + + var index : int = sindex.to_int() + + if index < 0: + return false + + if index >= folders.size(): + return false + + var p : String = sprop.get_slice("/", 2) + + if p == "folder": + folders[index].folder = val + return true + elif p == "header": + folders[index].header = val + return true + elif p == "name": + folders[index].name = val + return true + elif p == "type": + folders[index].type = val + return true + + return false + +func _get_property_list() -> Array: + var props : Array = Array() + + props.append({ + "name": "folder_count", + "type": TYPE_INT, + }) + + for i in range(folders.size()): + props.append({ + "name": "folders/" + str(i) + "/folder", + "type": TYPE_STRING, + }) + props.append({ + "name": "folders/" + str(i) + "/header", + "type": TYPE_STRING, + }) + props.append({ + "name": "folders/" + str(i) + "/name", + "type": TYPE_STRING, + }) + props.append({ + "name": "folders/" + str(i) + "/type", + "type": TYPE_STRING, + }) + + return props + +func apply_folder_size(val : int) -> void: + folders.resize(val) + + for i in range(folders.size()): + if !folders[i]: + folders[i] = SettingEntry.new() + +func set_folder_count(val : int) -> void: + apply_folder_size(val) + + emit_changed() + property_list_changed_notify()