├── addons └── gSheet │ ├── scenes │ ├── assets │ │ ├── iconSource.txt │ │ ├── search.png │ │ ├── arrow-square-up.png │ │ ├── close-rectangle.png │ │ ├── arrow-square-down.png │ │ ├── arrow-square-left .png │ │ ├── arrow-square-right.png │ │ ├── search.svg │ │ ├── arrow-square-up.svg │ │ ├── arrow-square-down.svg │ │ ├── arrow-square-left .svg │ │ ├── arrow-square-right.svg │ │ ├── close-rectangle.svg │ │ ├── search.png.import │ │ ├── search.svg.import │ │ ├── arrow-square-up.png.import │ │ ├── arrow-square-up.svg.import │ │ ├── close-rectangle.png.import │ │ ├── close-rectangle.svg.import │ │ ├── arrow-square-down.png.import │ │ ├── arrow-square-down.svg.import │ │ ├── arrow-square-left .png.import │ │ ├── arrow-square-left .svg.import │ │ ├── arrow-square-right.png.import │ │ └── arrow-square-right.svg.import │ ├── spreadsheet │ │ ├── assets │ │ │ ├── null.png │ │ │ ├── icon_GUI_hsplitter.svg │ │ │ ├── null.png.import │ │ │ ├── icon_play.svg.import │ │ │ ├── icon_GUI_hsplitter.svg.import │ │ │ └── icon_play.svg │ │ ├── full │ │ │ ├── DataFromText.gd │ │ │ ├── scenes │ │ │ │ ├── bottomBar │ │ │ │ │ ├── MenuButtonRow.gd │ │ │ │ │ ├── MoveMenu.gd │ │ │ │ │ ├── MenuButtonCol.gd │ │ │ │ │ ├── menuButton.gd │ │ │ │ │ ├── bottomBar.gd │ │ │ │ │ └── bottomBar.tscn │ │ │ │ └── enumPopup │ │ │ │ │ ├── enumPopup.gd │ │ │ │ │ └── enumPopup.tscn │ │ │ ├── spreadsheetFull.gd │ │ │ ├── top.gd │ │ │ └── spreadsheetFull.tscn │ │ ├── dummyTool.gd │ │ ├── hSplitSignal.gd │ │ ├── resource │ │ │ ├── spreadSheetStyle.gd │ │ │ ├── light.tres │ │ │ ├── dark.tres │ │ │ └── dark2.tres │ │ ├── spreadsheet.tscn │ │ ├── global.gd │ │ ├── parsers │ │ │ └── enumParse.gd │ │ └── mainScript.gd │ ├── typedLineEdit │ │ ├── scenes │ │ │ ├── icon_pause.png │ │ │ ├── audioPreview.gd │ │ │ ├── icon_pause.png.import │ │ │ ├── icon_pause.svg.import │ │ │ ├── audioPreview.tscn │ │ │ └── icon_pause.svg │ │ ├── typedLineEdit.tscn │ │ ├── HTTPRequest.gd │ │ ├── wavLoad.gd │ │ └── typedLineEdit.gd │ └── gsheet.gd │ ├── plugin.cfg │ ├── importPlugin.gd │ ├── highlightHover.gd │ └── plugin.gd ├── .gitignore ├── README.md └── LICENSE /addons/gSheet/scenes/assets/iconSource.txt: -------------------------------------------------------------------------------- 1 | https://jam-icons.com/ -------------------------------------------------------------------------------- /addons/gSheet/plugin.cfg: -------------------------------------------------------------------------------- 1 | [plugin] 2 | 3 | name="gSheet" 4 | description="" 5 | author="" 6 | version="" 7 | script="plugin.gd" 8 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/assets/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataPlusProgram/Godot-Spreadsheet-Plugin/HEAD/addons/gSheet/scenes/assets/search.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Godot-specific ignores 3 | .import/ 4 | export.cfg 5 | export_presets.cfg 6 | 7 | # Mono-specific ignores 8 | .mono/ 9 | data_*/ 10 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/assets/arrow-square-up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataPlusProgram/Godot-Spreadsheet-Plugin/HEAD/addons/gSheet/scenes/assets/arrow-square-up.png -------------------------------------------------------------------------------- /addons/gSheet/scenes/assets/close-rectangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataPlusProgram/Godot-Spreadsheet-Plugin/HEAD/addons/gSheet/scenes/assets/close-rectangle.png -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/assets/null.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataPlusProgram/Godot-Spreadsheet-Plugin/HEAD/addons/gSheet/scenes/spreadsheet/assets/null.png -------------------------------------------------------------------------------- /addons/gSheet/scenes/assets/arrow-square-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataPlusProgram/Godot-Spreadsheet-Plugin/HEAD/addons/gSheet/scenes/assets/arrow-square-down.png -------------------------------------------------------------------------------- /addons/gSheet/scenes/assets/arrow-square-left .png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataPlusProgram/Godot-Spreadsheet-Plugin/HEAD/addons/gSheet/scenes/assets/arrow-square-left .png -------------------------------------------------------------------------------- /addons/gSheet/scenes/assets/arrow-square-right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataPlusProgram/Godot-Spreadsheet-Plugin/HEAD/addons/gSheet/scenes/assets/arrow-square-right.png -------------------------------------------------------------------------------- /addons/gSheet/scenes/typedLineEdit/scenes/icon_pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataPlusProgram/Godot-Spreadsheet-Plugin/HEAD/addons/gSheet/scenes/typedLineEdit/scenes/icon_pause.png -------------------------------------------------------------------------------- /addons/gSheet/scenes/assets/search.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/full/DataFromText.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends ConfirmationDialog 3 | signal confirm 4 | 5 | func _ready(): 6 | connect("confirmed",self,"confirmed") 7 | 8 | 9 | 10 | func confirmed(): 11 | emit_signal("confirm",self,$TextEdit.text) 12 | 13 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/assets/icon_GUI_hsplitter.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/dummyTool.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends Control 3 | 4 | 5 | #func _ready(): 6 | # var curStyle = get("custom_styles/normal").duplicate() 7 | # curStyle.content_margin_top -= 1 8 | # curStyle.content_margin_bottom -= 1 9 | # curStyle.expand_margin_top -= 2 10 | # curStyle.expand_margin_bottom -= 2 11 | # rect_position.y += 2 12 | # set("custom_styles/normal",curStyle) 13 | # set("custom_styles/read_only",curStyle) 14 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/assets/arrow-square-up.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/assets/arrow-square-down.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/assets/arrow-square-left .svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/assets/arrow-square-right.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/full/scenes/bottomBar/MenuButtonRow.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends MenuButton 3 | 4 | 5 | var popup 6 | onready var sheet = $"../../../HBoxContainer/Spreadsheet/Control" 7 | 8 | func _ready(): 9 | popup = get_popup() 10 | popup.connect("id_pressed", self, "_on_item_pressed") 11 | 12 | 13 | func _on_item_pressed(id): 14 | if id == 0: 15 | 16 | sheet.addRow(true,sheet.curRow,true) 17 | sheet.updateSizings() 18 | elif id == 1: 19 | sheet.deleteCurRow() 20 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/assets/close-rectangle.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/full/scenes/bottomBar/MoveMenu.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends MenuButton 3 | 4 | 5 | var popup 6 | onready var sheet = $"../../../HBoxContainer/Spreadsheet/Control" 7 | 8 | func _ready(): 9 | popup = get_popup() 10 | popup.connect("id_pressed", self, "_on_item_pressed") 11 | 12 | 13 | func _on_item_pressed(id): 14 | if id == 0: 15 | sheet.moveColLeft(sheet.curCol) 16 | 17 | if id == 1: 18 | sheet.moveColRight(sheet.curCol) 19 | 20 | if id == 2: 21 | pass 22 | 23 | if id == 3: 24 | pass 25 | 26 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/hSplitSignal.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends HSplitContainer 3 | signal hDraw 4 | signal hDrag 5 | onready var lastAmount = split_offset 6 | 7 | 8 | func _ready(): 9 | connect("draw",self,"draw") 10 | connect("dragged",self,"dragged") 11 | 12 | func draw(): 13 | emit_signal("hDraw",self) 14 | 15 | func dragged(amt): 16 | emit_signal("hDrag",amt,self) 17 | 18 | #func _input(event): 19 | # if event is InputEventMouseButton: 20 | # if event.button_index == BUTTON_LEFT: 21 | # if !event.is_pressed(): 22 | # print("released") 23 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/full/spreadsheetFull.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends Control 3 | signal dictChanged 4 | 5 | export var allowImportTres = false 6 | export var showSaveButton = false 7 | 8 | func _ready(): 9 | if !allowImportTres: 10 | var menu : MenuButton = $VBoxContainer/Panel/HBoxContainer2/ButtonFile 11 | menu.get_popup().remove_item(2) 12 | 13 | if showSaveButton: 14 | $VBoxContainer/Panel/HBoxContainer2/ButtonSave.visible = true 15 | 16 | func dictChanged(dict): 17 | emit_signal("dictChanged",dict) 18 | 19 | func setTitle(text): 20 | $VBoxContainer/Label.text = text 21 | 22 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/typedLineEdit/typedLineEdit.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [ext_resource path="res://addons/gSheet/scenes/typedLineEdit/typedLineEdit.gd" type="Script" id=1] 4 | 5 | [node name="typedLineEdit" type="LineEdit"] 6 | anchor_right = 0.155 7 | anchor_bottom = 0.04 8 | margin_right = 0.279999 9 | caret_blink = true 10 | caret_blink_speed = 0.5 11 | script = ExtResource( 1 ) 12 | 13 | [connection signal="focus_entered" from="." to="." method="_on_typedLineEdit_focus_entered"] 14 | [connection signal="focus_exited" from="." to="." method="_on_typedLineEdit_focus_exited"] 15 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/typedLineEdit/scenes/audioPreview.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends Control 3 | 4 | 5 | func _process(delta): 6 | var sum = 0 7 | 8 | 9 | for i in get_children(): 10 | if "rect_size" in i: 11 | sum += i.rect_size.x 12 | 13 | rect_size.x = sum 14 | 15 | 16 | 17 | func _ready(): 18 | $TextureButton.connect("toggled",self,"toggled") 19 | 20 | func setAudio(stream): 21 | $AudioStreamPlayer.stream = stream 22 | 23 | 24 | func setText(txt): 25 | $LineEdit.text = txt 26 | 27 | 28 | 29 | func toggled(button_pressed): 30 | if button_pressed: 31 | $AudioStreamPlayer.play() 32 | else: 33 | $AudioStreamPlayer.stop() 34 | 35 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/resource/spreadSheetStyle.gd: -------------------------------------------------------------------------------- 1 | extends Resource 2 | class_name spreadSheetStyle 3 | 4 | export(Texture) var customGrabber 5 | 6 | export (Color) var cellColor 7 | export (Color) var cellBorderColor 8 | 9 | export (Color) var headingColor 10 | export (Color) var headingBorderColor 11 | 12 | export (Color) var fontColor = Color.black 13 | export (Color) var cursorColor = Color.black 14 | export (Color) var optionButtonHoverFontColor 15 | 16 | 17 | export (int) var borderThickness = 1 18 | export (int) var marginLeft = 7 19 | export (int) var marginRight = 7 20 | export (int) var marginTop = 3 21 | export (int) var marginBottom = 3 22 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/full/scenes/bottomBar/MenuButtonCol.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends MenuButton 3 | 4 | 5 | var popup 6 | onready var sheet = $"../../../HBoxContainer/Spreadsheet/Control" 7 | 8 | func _ready(): 9 | popup = get_popup() 10 | popup.connect("id_pressed", self, "_on_item_pressed") 11 | 12 | 13 | 14 | func _on_item_pressed(id): 15 | if id == 0: 16 | var curCol = sheet.curCol 17 | sheet.addColumn("",true,curCol,true) 18 | sheet.updateSizings() 19 | elif id == 1: 20 | #var actionDict = {"action":"delectColumn","index":cIdx} 21 | sheet.deleteCurCol() 22 | elif id == 2: 23 | sheet.moveCurColRight() 24 | elif id == 3: 25 | sheet.moveColLeft(sheet.curCol) 26 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/resource/light.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Resource" load_steps=2 format=2] 2 | 3 | [ext_resource path="res://addons/gSheet/scenes/spreadsheet/resource/spreadSheetStyle.gd" type="Script" id=1] 4 | 5 | [resource] 6 | script = ExtResource( 1 ) 7 | cellColor = Color( 1, 1, 1, 1 ) 8 | cellBorderColor = Color( 0.74902, 0.74902, 0.74902, 1 ) 9 | headingColor = Color( 0.831373, 0.831373, 0.831373, 1 ) 10 | headingBorderColor = Color( 0.74902, 0.74902, 0.74902, 1 ) 11 | fontColor = Color( 0, 0, 0, 1 ) 12 | cursorColor = Color( 0, 0, 0, 1 ) 13 | optionButtonHoverFontColor = Color( 0.470588, 0.470588, 0.470588, 1 ) 14 | borderThickness = 1 15 | marginLeft = 7 16 | marginRight = 7 17 | marginTop = 3 18 | marginBottom = 3 19 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/resource/dark.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Resource" load_steps=2 format=2] 2 | 3 | [ext_resource path="res://addons/gSheet/scenes/spreadsheet/resource/spreadSheetStyle.gd" type="Script" id=1] 4 | 5 | [resource] 6 | script = ExtResource( 1 ) 7 | cellColor = Color( 0.254902, 0.286275, 0.376471, 1 ) 8 | cellBorderColor = Color( 0.14902, 0.172549, 0.231373, 1 ) 9 | headingColor = Color( 0.176471, 0.2, 0.266667, 1 ) 10 | headingBorderColor = Color( 0.0784314, 0.0980392, 0.14902, 1 ) 11 | fontColor = Color( 0.886275, 0.886275, 0.886275, 1 ) 12 | cursorColor = Color( 1, 1, 1, 1 ) 13 | optionButtonHoverFontColor = Color( 0.470588, 0.470588, 0.470588, 1 ) 14 | borderThickness = 1 15 | marginLeft = 7 16 | marginRight = 7 17 | marginTop = 3 18 | marginBottom = 3 19 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/resource/dark2.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Resource" load_steps=2 format=2] 2 | 3 | [ext_resource path="res://addons/gSheet/scenes/spreadsheet/resource/spreadSheetStyle.gd" type="Script" id=1] 4 | 5 | [resource] 6 | script = ExtResource( 1 ) 7 | cellColor = Color( 0.254902, 0.286275, 0.376471, 1 ) 8 | cellBorderColor = Color( 0.14902, 0.172549, 0.231373, 1 ) 9 | headingColor = Color( 0.176471, 0.2, 0.266667, 1 ) 10 | headingBorderColor = Color( 0.0784314, 0.0980392, 0.14902, 1 ) 11 | fontColor = Color( 0.886275, 0.886275, 0.886275, 1 ) 12 | cursorColor = Color( 1, 1, 1, 1 ) 13 | optionButtonHoverFontColor = Color( 0.470588, 0.470588, 0.470588, 1 ) 14 | borderThickness = 1 15 | marginLeft = 5 16 | marginRight = 6 17 | marginTop = 2 18 | marginBottom = 2 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Godot-Spreadsheet-Plugin 2 | A custom resource that displays data as a Spreadsheet 3 | 4 | ![image](https://i.imgur.com/MTGfIyX.png) 5 | 6 | This plugin mimics a spreadsheet interface so you easily edit data 7 | 8 | To create a sheet do the following: "New Resource..." -> "gsheet (gsheet.gd)" -> Create 9 | 10 | You can import both CSV files and Dictionaries from Godot from the "import" option in the interface (see video) 11 | Note that the CSV files need to be comma seperated and will start to be slow after 1000 entries 12 | 13 | # Video Guide 14 | 15 | 16 | [Youtube Tutorial](https://www.youtube.com/watch?v=-n15oGyC-mk) 17 | 18 | # Experimental 19 | 20 | You can enter the path to any 2D image and have it display in the spreadsheet. 21 | 22 | ![image](https://user-images.githubusercontent.com/62811101/220430348-a26ae1e9-d6f1-43ba-93f1-4d8308965cd1.png) 23 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/full/scenes/enumPopup/enumPopup.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends Popup 3 | signal selectedItem 4 | 5 | var item 6 | var dict 7 | var dictNames 8 | var forCol 9 | 10 | 11 | func _on_Button2_pressed(): 12 | visible = false 13 | pass # Replace with function body. 14 | 15 | 16 | func _on_ItemList_item_selected(index): 17 | $VBoxContainer/HBoxContainer/select.disabled = false 18 | item = index 19 | pass # Replace with function body. 20 | 21 | 22 | func _on_ItemList_nothing_selected(): 23 | $VBoxContainer/HBoxContainer/select.disabled = true 24 | pass # Replace with function body. 25 | 26 | 27 | func _on_select_pressed(): 28 | var ret = $VBoxContainer/ItemList.get_item_text(item) 29 | visible = false 30 | emit_signal("selectedItem",dict[ret],forCol,dictNames[item]) 31 | 32 | 33 | func _on_ItemList_item_activated(index): 34 | _on_select_pressed() 35 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/assets/search.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/search.png-e3a2b5cc8523862c89eb434cfbc92148.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/gSheet/scenes/assets/search.png" 13 | dest_files=[ "res://.import/search.png-e3a2b5cc8523862c89eb434cfbc92148.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/assets/search.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/search.svg-0266efc87872159e5ac885ec456982d3.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/gSheet/scenes/assets/search.svg" 13 | dest_files=[ "res://.import/search.svg-0266efc87872159e5ac885ec456982d3.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/assets/null.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/null.png-8c9c1c2aa682fc43310997ca63ca7891.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/gSheet/scenes/spreadsheet/assets/null.png" 13 | dest_files=[ "res://.import/null.png-8c9c1c2aa682fc43310997ca63ca7891.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/assets/arrow-square-up.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/arrow-square-up.png-656cd5c6a77d1db4f6ad222014892902.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/gSheet/scenes/assets/arrow-square-up.png" 13 | dest_files=[ "res://.import/arrow-square-up.png-656cd5c6a77d1db4f6ad222014892902.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/assets/arrow-square-up.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/arrow-square-up.svg-07c9850361ac2d65f14916aa02215be6.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/gSheet/scenes/assets/arrow-square-up.svg" 13 | dest_files=[ "res://.import/arrow-square-up.svg-07c9850361ac2d65f14916aa02215be6.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/assets/close-rectangle.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/close-rectangle.png-739baf5400967d778901ca755a6add67.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/gSheet/scenes/assets/close-rectangle.png" 13 | dest_files=[ "res://.import/close-rectangle.png-739baf5400967d778901ca755a6add67.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/assets/close-rectangle.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/close-rectangle.svg-fd9c4403b676d95285b5ba19ab3fe252.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/gSheet/scenes/assets/close-rectangle.svg" 13 | dest_files=[ "res://.import/close-rectangle.svg-fd9c4403b676d95285b5ba19ab3fe252.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/assets/icon_play.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/icon_play.svg-c433a44b5869c9f4e92a5650f2d4d3e0.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/gSheet/scenes/spreadsheet/assets/icon_play.svg" 13 | dest_files=[ "res://.import/icon_play.svg-c433a44b5869c9f4e92a5650f2d4d3e0.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/assets/arrow-square-down.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/arrow-square-down.png-8ea4b69344718a0845a8c1c95def2034.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/gSheet/scenes/assets/arrow-square-down.png" 13 | dest_files=[ "res://.import/arrow-square-down.png-8ea4b69344718a0845a8c1c95def2034.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/assets/arrow-square-down.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/arrow-square-down.svg-4a5e09421ec93b0b3ddf2cb871925d8e.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/gSheet/scenes/assets/arrow-square-down.svg" 13 | dest_files=[ "res://.import/arrow-square-down.svg-4a5e09421ec93b0b3ddf2cb871925d8e.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/typedLineEdit/scenes/icon_pause.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/icon_pause.png-7d561b03a09ca16c1fc0ac784405b680.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/gSheet/scenes/typedLineEdit/scenes/icon_pause.png" 13 | dest_files=[ "res://.import/icon_pause.png-7d561b03a09ca16c1fc0ac784405b680.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/assets/arrow-square-left .png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/arrow-square-left .png-46339292c1f1a79755623709033d728f.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/gSheet/scenes/assets/arrow-square-left .png" 13 | dest_files=[ "res://.import/arrow-square-left .png-46339292c1f1a79755623709033d728f.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/assets/arrow-square-left .svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/arrow-square-left .svg-400fc7894fc7573412fac5a74e252b04.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/gSheet/scenes/assets/arrow-square-left .svg" 13 | dest_files=[ "res://.import/arrow-square-left .svg-400fc7894fc7573412fac5a74e252b04.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/assets/arrow-square-right.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/arrow-square-right.png-827fb8af43c135490809d356107011bf.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/gSheet/scenes/assets/arrow-square-right.png" 13 | dest_files=[ "res://.import/arrow-square-right.png-827fb8af43c135490809d356107011bf.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/assets/arrow-square-right.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/arrow-square-right.svg-314ef5bd863ce53bcae3adf0a8321c2b.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/gSheet/scenes/assets/arrow-square-right.svg" 13 | dest_files=[ "res://.import/arrow-square-right.svg-314ef5bd863ce53bcae3adf0a8321c2b.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/typedLineEdit/scenes/icon_pause.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/icon_pause.svg-bb8416a55367862dddf31b8f0777da89.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/gSheet/scenes/typedLineEdit/scenes/icon_pause.svg" 13 | dest_files=[ "res://.import/icon_pause.svg-bb8416a55367862dddf31b8f0777da89.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=false 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=false 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/assets/icon_GUI_hsplitter.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/icon_GUI_hsplitter.svg-c5f8efc568c70e116f8fdc905e750c1a.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://addons/gSheet/scenes/spreadsheet/assets/icon_GUI_hsplitter.svg" 13 | dest_files=[ "res://.import/icon_GUI_hsplitter.svg-c5f8efc568c70e116f8fdc905e750c1a.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/spreadsheet.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://addons/gSheet/scenes/spreadsheet/mainScript.gd" type="Script" id=1] 4 | [ext_resource path="res://addons/gSheet/scenes/spreadsheet/resource/dark.tres" type="Resource" id=2] 5 | 6 | [node name="Control" type="Control"] 7 | anchor_right = 1.0 8 | anchor_bottom = 1.0 9 | margin_left = 7.0 10 | margin_right = 7.0 11 | rect_min_size = Vector2( 800, 600 ) 12 | size_flags_horizontal = 3 13 | size_flags_vertical = 3 14 | 15 | [node name="Control" type="VBoxContainer" parent="."] 16 | anchor_right = 1.0 17 | anchor_bottom = 1.0 18 | custom_constants/separation = 0 19 | script = ExtResource( 1 ) 20 | sheetStyle = ExtResource( 2 ) 21 | 22 | [node name="ScrollContainer" type="ScrollContainer" parent="Control"] 23 | margin_right = 1024.0 24 | margin_bottom = 600.0 25 | size_flags_horizontal = 3 26 | size_flags_vertical = 3 27 | follow_focus = true 28 | 29 | [connection signal="draw" from="Control" to="Control" method="_on_Control_draw"] 30 | -------------------------------------------------------------------------------- /addons/gSheet/importPlugin.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends EditorImportPlugin 3 | 4 | enum PRESETS { DEFAULT } 5 | 6 | func get_importer_name(): 7 | return "csvToGsheet" 8 | 9 | func get_visible_name():#this is the name that appears in the "Import As:" dropdown 10 | return "gsheet" 11 | 12 | 13 | func get_recognized_extensions(): 14 | return ["csv9"] 15 | 16 | func get_save_extension(): 17 | return "tres" 18 | 19 | func get_resource_type(): 20 | return "Resource" 21 | 22 | func get_preset_count(): 23 | return 1 24 | 25 | func get_preset_name(preset): 26 | #if preset == PRESETS.DEFAULT: 27 | # return 28 | return "Default" 29 | 30 | func get_import_options(preset): 31 | #if preset == PRESETS.DEFAULT: 32 | # return [{}] 33 | return [{"name": "my_option", "default_value": false}] 34 | 35 | func import(source_file, save_path, options, r_platform_variants, r_gen_files): 36 | print("im importing as: ",save_path + ".tres") 37 | var sheet = load("res://addons/gSheet/scenes/gsheet.gd").new() 38 | 39 | return ResourceSaver.save(save_path + ".tres",sheet) 40 | 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 DataPlusProgram 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 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/typedLineEdit/HTTPRequest.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends HTTPRequest 3 | signal gotImage 4 | 5 | var imageType = "" 6 | 7 | func _ready(): 8 | connect("request_completed", self, "_http_request_completed") 9 | 10 | 11 | func fetch(url): 12 | var http_error = request(url) 13 | 14 | imageType = url.get_extension() 15 | if http_error != OK: 16 | print("An error occurred in the HTTP request.") 17 | 18 | 19 | func _http_request_completed(result, response_code, headers, body): 20 | var image = Image.new() 21 | var image_error 22 | 23 | if imageType == "png": image_error =image.load_png_from_buffer(body) 24 | if imageType == "jpg": image_error =image.load_jpg_from_buffer(body) 25 | if imageType == "bmp": image_error =image.load_bmp_from_buffer(body) 26 | if imageType == "tga": image_error =image.load_tga_from_buffer(body) 27 | 28 | 29 | #if imageType == "webp": image_error =image.load_webp_from_buffer(body) 30 | 31 | if image_error != OK: 32 | print("An error occurred while trying to display the image.") 33 | 34 | var textureImg = ImageTexture.new() 35 | textureImg.create_from_image(image) 36 | emit_signal("gotImage",textureImg) 37 | 38 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/global.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | class_name sheetGlobal 3 | 4 | 5 | 6 | 7 | static func saveNodeAsScene(node,path = "res://dbg/"): 8 | 9 | recursiveOwn(node,node) 10 | var packedScene = PackedScene.new() 11 | packedScene.pack(node) 12 | 13 | if path.find(".tscn") != -1: 14 | #print("saving as:",path) 15 | ResourceSaver.save(path,packedScene) 16 | else: 17 | #print("saving as:",path+node.name+".tscn") 18 | ResourceSaver.save(path+node.name+".tscn",packedScene) 19 | 20 | 21 | static func recursiveOwn(node,newOwner): 22 | 23 | # node.get_filename() == "": 24 | 25 | for i in node.get_children(): 26 | recursiveOwn(i,newOwner) 27 | 28 | if node != newOwner:#you get error if you set something as owning itself 29 | node.owner = newOwner 30 | 31 | 32 | 33 | static func getChildOfClass(node,type): 34 | for c in node.get_children(): 35 | if c.get_class() == type: 36 | return c 37 | 38 | return null 39 | 40 | 41 | static func isInternal(string): 42 | var internalTypes = [ 43 | "Vector2", 44 | "Vector3", 45 | "Rect2", 46 | ] 47 | 48 | if internalTypes.has(string): 49 | return true 50 | return false 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/full/scenes/bottomBar/menuButton.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends MenuButton 3 | 4 | var popup 5 | onready var sheet = $"../../../HBoxContainer/Spreadsheet/Control" 6 | 7 | 8 | func _ready(): 9 | popup = get_popup() 10 | popup.connect("id_pressed", self, "_on_item_pressed") 11 | 12 | 13 | func _on_item_pressed(id): 14 | if id == 0: 15 | $"../ButtonFromCSV/FileDialog".popup_centered_ratio(0.5) 16 | elif id == 1: 17 | $"../../../../DataFromText".popup_centered_ratio(0.5) 18 | elif id == 2: 19 | var fileDiag = FileDialog.new() 20 | 21 | fileDiag.filters = ["*.tres"] 22 | fileDiag.mode = FileDialog.MODE_OPEN_FILE 23 | fileDiag.access = FileDialog.ACCESS_FILESYSTEM 24 | fileDiag.connect("file_selected",self,"open") 25 | add_child(fileDiag) 26 | fileDiag.popup_centered_ratio() 27 | #sheet.loadFromFile("res://things.tres") 28 | 29 | 30 | 31 | 32 | func open(path): 33 | var r = load(path) 34 | if !"data" in r: 35 | 36 | var acceptDialog = AcceptDialog.new() 37 | add_child(acceptDialog) 38 | acceptDialog.dialog_text = "Not a gSheet resource" 39 | acceptDialog.popup_centered() 40 | return 41 | 42 | var filePathLabel = $"../../../Label" 43 | filePathLabel.text = path 44 | sheet.loadFromFile(path) 45 | 46 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/typedLineEdit/scenes/audioPreview.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://addons/gSheet/scenes/spreadsheet/assets/icon_play.svg" type="Texture" id=1] 4 | [ext_resource path="res://addons/gSheet/scenes/typedLineEdit/scenes/audioPreview.gd" type="Script" id=2] 5 | [ext_resource path="res://addons/gSheet/scenes/typedLineEdit/scenes/icon_pause.png" type="Texture" id=4] 6 | 7 | [node name="Control" type="Control"] 8 | anchor_right = 1.0 9 | anchor_bottom = 1.0 10 | margin_right = -909.0 11 | margin_bottom = -580.0 12 | size_flags_horizontal = 4 13 | size_flags_vertical = 4 14 | script = ExtResource( 2 ) 15 | 16 | [node name="TextureButton" type="TextureButton" parent="."] 17 | margin_bottom = 20.0 18 | rect_min_size = Vector2( 16, 16 ) 19 | size_flags_horizontal = 0 20 | size_flags_vertical = 4 21 | toggle_mode = true 22 | texture_normal = ExtResource( 1 ) 23 | texture_pressed = ExtResource( 4 ) 24 | expand = true 25 | 26 | [node name="LineEdit" type="Label" parent="."] 27 | margin_left = 16.0 28 | margin_top = 3.0 29 | margin_right = 115.0 30 | margin_bottom = 17.0 31 | size_flags_horizontal = 4 32 | custom_colors/font_color = Color( 0, 0, 0, 1 ) 33 | 34 | [node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."] 35 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/typedLineEdit/scenes/icon_pause.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 38 | 44 | 45 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/assets/icon_play.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 38 | 45 | 46 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/full/scenes/enumPopup/enumPopup.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [ext_resource path="res://addons/gSheet/scenes/spreadsheet/full/scenes/enumPopup/enumPopup.gd" type="Script" id=1] 4 | 5 | [node name="enumPopup" type="WindowDialog"] 6 | anchor_right = 1.0 7 | anchor_bottom = 1.0 8 | margin_right = -783.0 9 | margin_bottom = -330.0 10 | window_title = "select ENUM" 11 | script = ExtResource( 1 ) 12 | 13 | [node name="VBoxContainer" type="VBoxContainer" parent="."] 14 | anchor_left = 0.024 15 | anchor_top = 0.022 16 | anchor_right = 0.961 17 | anchor_bottom = 0.974 18 | margin_left = 0.0799999 19 | margin_top = 0.0599995 20 | margin_right = -0.00500488 21 | margin_bottom = 0.019989 22 | 23 | [node name="ItemList" type="ItemList" parent="VBoxContainer"] 24 | margin_right = 225.0 25 | margin_bottom = 233.0 26 | size_flags_horizontal = 3 27 | size_flags_vertical = 3 28 | 29 | [node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"] 30 | margin_top = 237.0 31 | margin_right = 225.0 32 | margin_bottom = 257.0 33 | alignment = 1 34 | 35 | [node name="select" type="Button" parent="VBoxContainer/HBoxContainer"] 36 | margin_left = 58.0 37 | margin_right = 109.0 38 | margin_bottom = 20.0 39 | disabled = true 40 | text = "select" 41 | 42 | [node name="cancel" type="Button" parent="VBoxContainer/HBoxContainer"] 43 | margin_left = 113.0 44 | margin_right = 166.0 45 | margin_bottom = 20.0 46 | text = "cancel" 47 | 48 | [connection signal="item_activated" from="VBoxContainer/ItemList" to="." method="_on_ItemList_item_activated"] 49 | [connection signal="item_selected" from="VBoxContainer/ItemList" to="." method="_on_ItemList_item_selected"] 50 | [connection signal="nothing_selected" from="VBoxContainer/ItemList" to="." method="_on_ItemList_nothing_selected"] 51 | [connection signal="pressed" from="VBoxContainer/HBoxContainer/select" to="." method="_on_select_pressed"] 52 | [connection signal="pressed" from="VBoxContainer/HBoxContainer/cancel" to="." method="_on_Button2_pressed"] 53 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/full/top.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends HBoxContainer 3 | 4 | 5 | var enumPopupIndex = -1 6 | 7 | func _ready(): 8 | $"../../../FileDialog".connect("file_selected",self,"file_selected") 9 | $"enumPopup".connect("selectedItem",self,"selectedItem") 10 | 11 | 12 | func newChild(node): 13 | if node.menu == null: 14 | return 15 | 16 | 17 | var idx = node.get_meta("index") 18 | enumPopupIndex = node.menu.get_item_count() 19 | node.menu.add_item("set ENUM type") 20 | node.connect("index_pressed",self,"index_pressed") 21 | 22 | 23 | 24 | func index_pressed(called,index,colIdx): 25 | if index == enumPopupIndex: 26 | $"../../../FileDialog".set_meta("forCol",colIdx) 27 | $"../../../FileDialog".popup_centered() 28 | 29 | 30 | func selectedItem(dict,colIdx,enumPrefix): 31 | var data = dict.values()[0] 32 | var t = $"../../../VBoxContainer/HBoxContainer/Spreadsheet/Control" 33 | var col = t.cols[colIdx] 34 | col.set_meta("enum",dict) 35 | col.set_meta("enumPrefix",enumPrefix) 36 | for i in col.get_children(): 37 | i.setData({"type":"enum","data":dict,"enumStr":i.text}) 38 | 39 | t.serializeFlag = true 40 | 41 | 42 | 43 | func file_selected(file): 44 | var coldId = $"../../../FileDialog".get_meta("forCol",null) 45 | $"../../../FileDialog".set_meta("forCol",null) 46 | 47 | if file.get_extension() != "gd": 48 | return 49 | 50 | var values = $enumParse.parse(file) 51 | 52 | values = addDummyEntryToEnumsDict(values) 53 | 54 | if values.empty(): 55 | $AcceptDialog.popup_centered() 56 | return 57 | 58 | var itemList = $enumPopup/VBoxContainer/ItemList 59 | itemList.clear() 60 | 61 | for i in values.keys(): 62 | itemList.add_item(i) 63 | 64 | 65 | 66 | $enumPopup.dict = values 67 | $enumPopup.forCol = coldId 68 | $enumPopup.dictNames = values.keys() 69 | $enumPopup.popup_centered_ratio() 70 | 71 | 72 | func addDummyEntryToEnumsDict(dict): 73 | for keyStr in dict.keys(): 74 | var i = 0 75 | while(true): 76 | if !dict[keyStr].values().has(i): 77 | break 78 | i += 1 79 | dict[keyStr]["@DUMMY"] = i 80 | 81 | return dict 82 | 83 | -------------------------------------------------------------------------------- /addons/gSheet/highlightHover.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends TextureButton 3 | 4 | export var makeDarkToggleTexture = false 5 | export var amt = .4 6 | export var tint = Color(1,1,1) 7 | var normalTexture 8 | var pressedTexture 9 | var normalDark 10 | var normalBright 11 | var pressedBright 12 | var darkBright 13 | 14 | func _ready(): 15 | 16 | 17 | var p = self 18 | while(true): 19 | 20 | p = p.get_parent() 21 | 22 | if p.get_parent() == null: 23 | break 24 | 25 | if p.get("videoPath") != null: 26 | amt=p.iconDarken 27 | 28 | normalTexture = texture_normal 29 | normalBright = brighten(texture_normal,amt) 30 | normalDark = brighten(texture_normal,-amt) 31 | darkBright = brighten(texture_normal,-amt/2.0) 32 | makeDarkToggleTexture 33 | texture_disabled = normalDark 34 | 35 | if texture_pressed != null: 36 | pressedBright = brighten(texture_pressed,amt) 37 | pressedTexture = texture_pressed 38 | 39 | if makeDarkToggleTexture: 40 | pressedTexture = normalDark 41 | texture_pressed = normalDark 42 | 43 | 44 | connect("mouse_entered",self,"mouseIn") 45 | connect("mouse_exited",self,"mouseOut") 46 | 47 | 48 | 49 | 50 | func brighten(texture : Texture,amt : float): 51 | 52 | var image = texture.get_data().duplicate() 53 | 54 | image.lock() 55 | 56 | for x in image.get_width(): 57 | for y in image.get_height(): 58 | var pix = image.get_pixel(x,y) 59 | pix *= tint 60 | var post = pix + Color(amt,amt,amt,0) 61 | image.set_pixel(x,y,post) 62 | 63 | 64 | image.unlock() 65 | 66 | var newTexture = ImageTexture.new() 67 | newTexture.create_from_image(image) 68 | 69 | return newTexture 70 | 71 | 72 | func mouseIn(): 73 | texture_normal = normalBright 74 | if texture_pressed and !makeDarkToggleTexture: 75 | texture_pressed = pressedBright 76 | 77 | if makeDarkToggleTexture: 78 | texture_pressed = darkBright 79 | 80 | 81 | func mouseOut(): 82 | texture_normal = normalTexture 83 | if texture_pressed and !makeDarkToggleTexture: 84 | texture_pressed = pressedTexture 85 | 86 | if makeDarkToggleTexture: 87 | texture_pressed = normalDark 88 | 89 | 90 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/gsheet.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends Resource 3 | class_name gsheet 4 | 5 | 6 | export(Dictionary) var data = {"meta":{"hasId":false,"rowOrder":["0"],"enumColumns":{},"colNames":[],"enumColumnsPrefix":{}},"0":{"0":""}} 7 | 8 | 9 | func get_data(): 10 | var dat = data.duplicate() 11 | dat.pop_front() 12 | return dat 13 | 14 | func getRowKeys(): 15 | return data["meta"]["rowOrder"] 16 | 17 | func getRow(rowKey : String) -> Dictionary: 18 | var retDict = {} 19 | var entry = data[rowKey] 20 | 21 | for key in entry.keys(): 22 | if typeof(entry[key]) == TYPE_STRING: 23 | if entry[key] == "": 24 | continue 25 | 26 | retDict[key] = entry[key] 27 | 28 | return retDict 29 | 30 | 31 | func hasKey(rowKey): 32 | return data.has(rowKey) 33 | 34 | func getColumn(colKey): 35 | var ret = [] 36 | 37 | for key in data.keys(): 38 | if data[key].has(colKey): 39 | if data[key][colKey] != "": 40 | ret.append(data[key][colKey]) 41 | 42 | 43 | return ret 44 | 45 | func getRowsAsArray() -> Array: 46 | var ret = [] 47 | 48 | for key in data.keys(): 49 | if key!="meta": 50 | ret.append(data[key]) 51 | 52 | return ret 53 | 54 | func getRowsAsArrayExcludeEmptyColumns() -> Array: 55 | var ret : Array = [] 56 | 57 | for key in data.keys(): 58 | if key!="meta": 59 | 60 | var line : Dictionary = data[key] 61 | var minDict : Dictionary = {} 62 | 63 | 64 | for value in line: 65 | var d = line[value] 66 | 67 | if d != null: 68 | if typeof(d) == TYPE_STRING: 69 | if line[value].empty(): 70 | continue 71 | 72 | minDict[value] = line[value] 73 | ret.append(minDict) 74 | #ret.append(data[key]) 75 | 76 | 77 | return ret 78 | 79 | func getAsDict() -> Dictionary: 80 | var ret = data.duplicate() 81 | ret.erase("meta") 82 | var ret2 = {} 83 | 84 | for key in ret.keys(): 85 | var retEntry = {} 86 | var empty = true 87 | for value in ret[key]: 88 | if !ret[key][value].empty(): 89 | if !ret2.has(key): 90 | ret2[key] = {} 91 | 92 | ret2[key][value] = ret[key][value] 93 | empty = false 94 | 95 | if empty: 96 | ret.erase(key) 97 | 98 | return ret2 99 | 100 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/parsers/enumParse.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends Node 3 | 4 | 5 | 6 | func parse(path): 7 | var file = File.new() 8 | var err = file.open(path, File.READ) 9 | var content = file.get_as_text() 10 | var ret = {} 11 | var nl = content.split("\n") 12 | 13 | for i in nl.size(): 14 | var line = nl[i] 15 | var idx = line.find("enum ") 16 | if idx != -1 and idx == 0: 17 | var e = enumFound(nl,i) 18 | ret[e[0]] = e[1] 19 | 20 | 21 | 22 | return guessTypes(ret) 23 | 24 | 25 | 26 | 27 | func enumFound(arr,idx): 28 | var enumDict = {} 29 | var token = [] 30 | var enumName = arr[idx].split(" ")[1] 31 | 32 | enumName=enumName.replace("{","") 33 | 34 | for i in range(idx+1,arr.size()): 35 | var string = arr[i] 36 | 37 | 38 | if string == "}": 39 | break 40 | 41 | string = string.replace("\n","") 42 | string = string.replace(" ","") 43 | string = string.replace("\t","") 44 | string = string.replace(",","") 45 | if string != "": 46 | token.append(string) 47 | 48 | 49 | 50 | 51 | 52 | var count = 0 53 | for i in token: 54 | if i.find("=") != -1: 55 | var operands = i.split("=") 56 | enumDict[operands[0]] = operands[1] 57 | else: 58 | enumDict[i] = count 59 | count += 1 60 | 61 | return [enumName,enumDict] 62 | 63 | func guessTypes(dict): 64 | var typeDict = {} 65 | 66 | for i in dict.keys(): 67 | typeDict[i] = {} 68 | for key in dict[i].keys(): 69 | var string = dict[i][key] 70 | if typeof(string) == TYPE_STRING: 71 | typeDict[i][key] = stringToType(string) 72 | else: 73 | typeDict[i][key] = string 74 | 75 | 76 | return typeDict 77 | 78 | func stringToType(string): 79 | var value 80 | 81 | if string.is_valid_integer(): 82 | value = string.to_int() 83 | elif string.is_valid_float(): 84 | value = string.to_float() 85 | elif string.is_valid_html_color(): 86 | value = Color(string) 87 | elif string.to_lower() == "true": 88 | value = true 89 | elif string.to_lower() == "false": 90 | value = false 91 | elif string.is_valid_hex_number(true): 92 | value = string.hex_to_int() 93 | #elif string.is_abs_path(): 94 | # parsePath(string) 95 | else: 96 | value = string 97 | 98 | return value 99 | 100 | -------------------------------------------------------------------------------- /addons/gSheet/plugin.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends EditorPlugin 3 | signal dictChanged 4 | 5 | var interface = preload("res://addons/gSheet/scenes/spreadsheet/full/spreadsheetFull.tscn").instance() 6 | var curObj = null 7 | var objectLastSaved = null 8 | var importPlugin 9 | 10 | 11 | 12 | func get_importer_name(): 13 | return "csv to gsheet" 14 | 15 | 16 | 17 | func _enter_tree(): 18 | interface.connect("dictChanged",self,"dictChanged") 19 | 20 | 21 | get_editor_interface().get_editor_viewport().add_child(interface) 22 | 23 | make_visible(false) 24 | interface.get_parent().connect("draw",self,"draw") 25 | 26 | importPlugin = preload("res://addons/gSheet/importPlugin.gd").new() 27 | add_import_plugin(importPlugin) 28 | 29 | 30 | func get_plugin_name(): 31 | return "Sheet" 32 | 33 | func handles(object): 34 | return object is gsheet 35 | 36 | func _exit_tree(): 37 | if is_instance_valid(interface): 38 | interface.queue_free() 39 | 40 | remove_import_plugin(importPlugin) 41 | importPlugin = null 42 | 43 | func has_main_screen(): 44 | return true 45 | 46 | func edit(object): 47 | curObj = object 48 | interface.setTitle(curObj.get_path()) 49 | 50 | var file = File.new() 51 | objectLastSaved = file.get_modified_time(curObj.get_path()) 52 | 53 | if curObj.data.empty(): 54 | var tmp = gsheet.new() 55 | curObj.data = tmp.data.duplicate() 56 | 57 | 58 | interface.get_node("VBoxContainer/HBoxContainer/Spreadsheet/Control").dataIntoSpreadsheet(curObj.data.duplicate(true)) 59 | 60 | 61 | 62 | func make_visible(visible):#this dictates what type of node will bring you to the toolbar: 63 | if interface: 64 | interface.visible = visible 65 | 66 | func draw(): 67 | interface.rect_size = interface.get_parent().rect_size 68 | 69 | var timer = 0 70 | 71 | func _process(delta): 72 | interface.rect_size = interface.get_parent().rect_size 73 | 74 | func dictChanged(dict): 75 | 76 | if curObj == null: 77 | return 78 | 79 | curObj.data = dict 80 | 81 | 82 | 83 | var counter = 0 84 | 85 | #func _physics_process(delta): 86 | # if curObj == null: 87 | # return 88 | # counter += delta 89 | # 90 | # if counter > 2: 91 | # var file = File.new() 92 | # var saveTime = file.get_modified_time(curObj.get_path()) 93 | # 94 | # print(interface.get_node("VBoxContainer/HBoxContainer/Spreadsheet/Control").needsSaving) 95 | # if saveTime != objectLastSaved and interface.get_node("VBoxContainer/HBoxContainer/Spreadsheet/Control").needsSaving: 96 | # saveTime = objectLastSaved 97 | # interface.get_node("VBoxContainer/HBoxContainer/Spreadsheet/Control").needsSaving = false 98 | # #interface.setTitle("diofj") 99 | # 100 | # counter = 0 101 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/typedLineEdit/wavLoad.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends Node 3 | 4 | var file 5 | var fileDict = {} 6 | 7 | func _ready(): 8 | set_meta("hidden",true) 9 | 10 | func getStreamFromWAV(path): 11 | file = File.new() 12 | var err = file.open(path,File.READ) 13 | 14 | if err != 0: 15 | print("error opening file:",path) 16 | return AudioStreamSample.new() 17 | 18 | fileDict["magic"] = file.get_buffer(4).get_string_from_ascii() 19 | fileDict["chunkSize"] = file.get_32() 20 | fileDict["format"] = file.get_buffer(4).get_string_from_ascii() 21 | 22 | parseFmt() 23 | file.seek(fileDict["dataChunkOffset"]) 24 | parseData() 25 | var stream = createStream() 26 | 27 | 28 | if file.eof_reached(): 29 | return stream 30 | 31 | var cueArr = [] 32 | 33 | while !file.eof_reached(): 34 | var pos = file.get_position() 35 | if (pos + 4) >= file.get_len(): 36 | break 37 | 38 | var chunkId = file.get_buffer(4).get_string_from_ascii() 39 | if chunkId == "LIST": 40 | parseList() 41 | 42 | if chunkId == "CUE ": 43 | cueArr = parseCue() 44 | break 45 | 46 | stream.loop_end = stream.data.size() 47 | 48 | if cueArr.size()>0: 49 | stream.loop_mode = AudioStreamSample.LOOP_FORWARD 50 | stream.loop_begin = cueArr[0] 51 | 52 | if cueArr.size()>1: 53 | stream.loop_end = cueArr[1] 54 | 55 | return stream 56 | 57 | 58 | func parseFmt(): 59 | fileDict["fmtId"] = file.get_32() 60 | fileDict["fmtSize"] = file.get_32() 61 | fileDict["dataChunkOffset"] = fileDict["fmtSize"] + file.get_position() 62 | fileDict["audioFormat"] = file.get_16() 63 | fileDict["numChannels"] = file.get_16() 64 | fileDict["sampleRate"] = file.get_32() 65 | fileDict["byteRate"] = file.get_32() 66 | fileDict["blocksAlign"] = file.get_16() 67 | fileDict["bitsPerSample"] = file.get_16() 68 | 69 | func parseData(): 70 | fileDict["dataId"] = file.get_buffer(4).get_string_from_ascii() 71 | fileDict["dataSize"] = file.get_32() 72 | 73 | func createStream(): 74 | var stream = AudioStreamSample.new() 75 | stream.mix_rate = fileDict["sampleRate"] 76 | if fileDict["numChannels"] > 1: 77 | stream.stereo = true 78 | 79 | if fileDict["bitsPerSample"] == 8: 80 | stream.format = AudioStreamSample.FORMAT_8_BITS 81 | if fileDict["bitsPerSample"] == 16: 82 | stream.format = AudioStreamSample.FORMAT_16_BITS 83 | 84 | var dataSize = fileDict["dataSize"] 85 | var data = [] 86 | var size = fileDict["bitsPerSample"]/8 87 | 88 | if fileDict["bitsPerSample"] == 8: 89 | for i in range(0,dataSize): 90 | 91 | var sample = file.get_8() 92 | sample = (sample - 128)/2.0 93 | data.append(sample) 94 | 95 | if fileDict["bitsPerSample"] == 16: 96 | for i in range(0,dataSize): 97 | var sample = file.get_8() 98 | data.append(sample) 99 | 100 | if !file.eof_reached(): 101 | while(file.get_position())%4 != 0: 102 | file.get_8()#all files that had another chunk after the data chunk had a single byte of padding 103 | if file.eof_reached(): 104 | break 105 | stream.data = data 106 | 107 | var audioOutFile = File.new() 108 | audioOutFile.open("res://dbg/raw.dat", File.WRITE) 109 | 110 | for i in stream.data: 111 | audioOutFile.store_real(i) 112 | 113 | 114 | 115 | audioOutFile.close() 116 | return stream 117 | 118 | func parseList(): 119 | 120 | var listDict = {} 121 | listDict["dataSize"] = file.get_32() 122 | var endPos = file.get_position() + listDict["dataSize"] 123 | listDict["chunkType"] = file.get_buffer(4).get_string_from_ascii() 124 | file.seek(endPos) 125 | 126 | func parseCue(): 127 | var curDict = {} 128 | var cueOffsets = [] 129 | curDict["dataSize"] = file.get_32() 130 | curDict["numCues"] = file.get_32() 131 | 132 | for n in curDict["numCues"]: 133 | curDict["id"] = file.get_32() 134 | curDict["position"] = file.get_32() 135 | curDict["fccChunk"] = file.get_32() 136 | curDict["chunkStart"] = file.get_32() 137 | curDict["blockStart"] = file.get_32() 138 | curDict["sampleOffset"] =file.get_32() 139 | cueOffsets.append(curDict["position"]) 140 | return cueOffsets 141 | 142 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/full/scenes/bottomBar/bottomBar.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends HBoxContainer 3 | 4 | var sheet : Node 5 | 6 | func _on_Save_pressed(): 7 | sheetGlobal.saveNodeAsScene(get_parent()) 8 | 9 | 10 | 11 | func _ready(): 12 | if get_node_or_null("../../HBoxContainer/Spreadsheet/Control") != null: 13 | sheet = $"../../HBoxContainer/Spreadsheet/Control" 14 | 15 | func _on_ButtonFromArray_pressed(): 16 | var t : WindowDialog= $"../../DataFromText" 17 | t.popup_centered_ratio(0.5) 18 | 19 | 20 | var csvPath = "" 21 | 22 | func _on_FileDialog_file_selected(path): 23 | #$ButtonFromCSV/csvHeadings.popup_centered() 24 | $ButtonFromCSV/csvOptions.popup_centered() 25 | 26 | var file = File.new() 27 | file.open(path,File.READ) 28 | var content = file.get_as_text() 29 | var countA = content.count(",") 30 | var countB = content.count(";") 31 | 32 | if countA > countB: 33 | $ButtonFromCSV/csvOptions/VBoxContainer/Delimeter/OptionButton.selected = 0 34 | else: 35 | $ButtonFromCSV/csvOptions/VBoxContainer/Delimeter/OptionButton.selected = 1 36 | 37 | csvPath = path 38 | 39 | 40 | 41 | func _on_ButtonFromCSV_pressed(): 42 | $ButtonFromCSV/FileDialog.popup() 43 | 44 | 45 | func _on_ButtonSave_pressed(): 46 | var dialog = FileDialog.new() 47 | dialog.filters = ["*.tres"] 48 | dialog.access = FileDialog.ACCESS_FILESYSTEM 49 | dialog.mode = FileDialog.MODE_SAVE_FILE 50 | dialog.current_path = $"../../Label".text 51 | #dialog.current_path = $"../../../Label".text 52 | add_child(dialog) 53 | var e = dialog.connect("file_selected",self,"saveSheet") 54 | dialog.rect_size = Vector2(600,600) 55 | dialog.popup_centered_ratio() 56 | 57 | 58 | func saveSheet(string): 59 | var data = sheet.serializeData() 60 | var res = load("res://addons/gSheet/scenes/gsheet.gd").new() 61 | res.data = data 62 | ResourceSaver.save(string,res) 63 | 64 | func _on_ButtonLoad_pressed(): 65 | sheet.loadFromFile("res://dbg/savedFormat2.tres") 66 | sheet.updateSizings() 67 | 68 | 69 | func _on_addCategory_pressed(): 70 | sheet.addColumn("") 71 | sheet.updateSizings() 72 | 73 | 74 | 75 | 76 | 77 | func _on_ButtonDeleteCurSol_pressed(): 78 | sheet.deleteCurRow() 79 | pass # Replace with function body. 80 | 81 | 82 | func _on_ButtonDeleteCurCol_pressed(): 83 | sheet.deleteCurCol() 84 | 85 | 86 | func _on_ButtonAddRow_pressed(): 87 | sheet.addRow() 88 | sheet.updateSizings() 89 | 90 | 91 | 92 | func _on_ButtonUndo_pressed(): 93 | sheet.undo() 94 | pass # Replace with function body. 95 | 96 | 97 | func _on_Button_pressed(): 98 | sheet.serializeData() 99 | 100 | 101 | func _input(event): 102 | if event.get_class() != "InputEventKey": 103 | return 104 | 105 | 106 | 107 | 108 | func _on_ButtonCancel_pressed(): 109 | $ButtonFromCSV/csvOptions.hide() 110 | pass # Replace with function body. 111 | 112 | 113 | func _on_ButtonOk_pressed(): 114 | var optionButton = $ButtonFromCSV/csvOptions/VBoxContainer/Delimeter/OptionButton 115 | var headings = $ButtonFromCSV/csvOptions/VBoxContainer/hasHeadings/CheckBoxHeadings.pressed 116 | var delimeter = optionButton.get_item_text(optionButton.get_selected_id()) 117 | sheet.csvImport(csvPath,headings,delimeter) 118 | $ButtonFromCSV/csvOptions.hide() 119 | 120 | 121 | func _on_ButtonSearch_pressed(): 122 | $SearchDiag/WindowDialog.popup_centered() 123 | $SearchDiag/WindowDialog/MarginContainer/v/h/LineEdit.grab_focus() 124 | 125 | 126 | 127 | 128 | 129 | func _on_ButtonFind_pressed(): 130 | var ret = sheet.grabFocusIfTextFound($SearchDiag/WindowDialog/MarginContainer/v/h/LineEdit.text) 131 | if ret == false: 132 | $SearchDiag/WindowDialog/MarginContainer/v/Label.text = "Match not found" 133 | else: 134 | $SearchDiag/WindowDialog/MarginContainer/v/Label.text = "" 135 | 136 | 137 | 138 | func _on_ButtonAddRowAbove_pressed(): 139 | var idx = sheet.curRow 140 | 141 | #if idx == -1: idx = 0 142 | 143 | var focus = sheet.addRow(true,idx,true,sheet.curCol) 144 | 145 | if focus != null: 146 | focus.grab_focus() 147 | 148 | 149 | 150 | 151 | func _on_ButtonAddRowBelow_pressed(): 152 | var idx = sheet.curRow+1 153 | var focus = sheet.addRow(true,idx,true,sheet.curCol) 154 | 155 | if focus != null: 156 | focus.grab_focus() 157 | 158 | 159 | func _on_TextureButton_pressed(): 160 | var idx = sheet.curCol 161 | var focus = sheet.addColumn("",true,idx) 162 | 163 | if focus != null: 164 | sheet.addColumn("",true,idx).grab_focus() 165 | 166 | 167 | 168 | func _on_TextureButton2_pressed(): 169 | var idx = sheet.curCol+1 170 | var focus = sheet.addColumn("",true,idx) 171 | 172 | if focus != null: 173 | focus.grab_focus() 174 | 175 | 176 | 177 | func _on_TextureButtonColClose_pressed(): 178 | sheet.deleteCurCol() 179 | 180 | 181 | func _on_TextureButtonDeleCurRow_pressed(): 182 | sheet.deleteCurRow() 183 | 184 | 185 | 186 | 187 | 188 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/typedLineEdit/typedLineEdit.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends LineEdit 3 | 4 | signal update 5 | signal updateRowHeight 6 | signal focusEntered 7 | signal focusExit 8 | signal index_pressed 9 | 10 | export var value = "" 11 | 12 | var menu : PopupMenu 13 | var inFocus = false 14 | var preview = null 15 | onready var optionButton : OptionButton = null 16 | var dataFromTexDialog : ConfirmationDialog = null 17 | var hoverColor : Color 18 | var optionMode = false 19 | #var previousText = "" 20 | var sheet = null 21 | var par 22 | 23 | func _ready(): 24 | if has_meta("index"): 25 | for i in get_children(): 26 | if i.get_class() == "PopupMenu": 27 | menu=i 28 | i.connect("index_pressed",self,"index_pressed") 29 | 30 | 31 | 32 | connect("text_changed",self,"_on_typedLineEdit_text_changed") 33 | 34 | 35 | 36 | func getOptionRectSize(): 37 | return optionButton.rect_size 38 | 39 | func activateOptionMode(enumValues,enumStr): 40 | 41 | if is_instance_valid(optionButton): 42 | optionButton.queue_free() 43 | 44 | var valueIndex = {} 45 | 46 | 47 | 48 | optionButton = OptionButton.new() 49 | optionButton.rect_min_size.x = rect_min_size.x 50 | optionButton.anchor_right = 1 51 | optionButton.anchor_bottom = 1 52 | optionButton.visible = true 53 | 54 | optionButton.connect("item_selected",self,"_on_OptionButton_item_selected") 55 | optionButton.connect("focus_entered",self,"_on_typedLineEdit_focus_entered") 56 | optionButton.connect("focus_exited",self,"_on_typedLineEdit_focus_exited") 57 | add_child(optionButton) 58 | 59 | 60 | 61 | var curStyle = get("custom_styles/normal") 62 | optionButton.set("custom_styles/normal",curStyle) 63 | optionButton.set("custom_styles/hover",curStyle) 64 | 65 | var fontColor = get("custom_colors/font_color") 66 | var cursorColor = get("custom_colors/cursor_color") 67 | 68 | 69 | 70 | 71 | optionButton.set("custom_colors/font_color",fontColor) 72 | optionButton.set("custom_colors/font_color_focus",fontColor) 73 | optionButton.set("custom_colors/cursor_color",cursorColor) 74 | optionButton.set("custom_colors/font_color_hover",hoverColor) 75 | 76 | var t = optionButton.get("custom_styles/normal") 77 | 78 | set_meta("enumStrToValue",enumValues) 79 | #var test = values.keys() #values wont get placed in their correct order unless keys is sorted by mapped index instead of alphanumeric order 80 | 81 | var valueSorted = {} 82 | var keysSorted = enumValues.values() 83 | keysSorted.sort() 84 | 85 | #for i in values.values(): 86 | # valueSorted[] 87 | 88 | for i in keysSorted: 89 | for key in enumValues.keys(): 90 | if enumValues[key] == i: 91 | var tuple = [key,i] 92 | 93 | if key != "@DUMMY": 94 | optionButton.add_item(key) 95 | else: 96 | optionButton.add_item("") 97 | 98 | #valueIndex[key] = i 99 | valueIndex[key] = optionButton.get_item_count()-1 100 | 101 | # for i in values.keys(): 102 | # 103 | # var optionButtonItemCount = optionButton.get_item_count() 104 | # 105 | # if i == "@DUMMY": 106 | # valueIndex[i] = optionButtonItemCount 107 | # i = "" 108 | # else: 109 | # valueIndex[i] = optionButtonItemCount 110 | # optionButton.add_item(i) 111 | 112 | 113 | var existingText = enumStr 114 | var keys = enumValues.keys() 115 | text = "" 116 | 117 | if existingText.find(".") == -1: 118 | 119 | if valueIndex.has(existingText): 120 | optionButton.select(valueIndex[existingText]) 121 | value = enumValues[existingText] 122 | 123 | else: 124 | optionButton.select(valueIndex["@DUMMY"]) 125 | value = enumValues["@DUMMY"] 126 | 127 | if existingText.is_valid_integer(): 128 | optionButton.queue_free() 129 | _on_typedLineEdit_text_changed(existingText) 130 | 131 | return 132 | 133 | 134 | var post = existingText.split(".")[1] 135 | 136 | if keys.has(post): 137 | 138 | #var index = keys.find(post) 139 | var index = valueIndex[post] 140 | optionButton.select(index) 141 | text = post 142 | value = enumValues[post] 143 | # print("set indexa to:",index) 144 | 145 | else: 146 | var index = valueIndex["@DUMMY"] 147 | optionButton.select(index) 148 | value = enumValues["@DUMMY"] 149 | 150 | # print("set indexb to:",index) 151 | 152 | 153 | sheet.updateSizingsFlag = true 154 | #breakpoint 155 | 156 | func deactivateOptionMode(): 157 | if is_instance_valid(optionButton): 158 | optionButton.queue_free() 159 | 160 | func createLineEdit(): 161 | var ret = LineEdit.new() 162 | var curStyle = get("custom_styles/normal") 163 | 164 | ret.set("custom_styles/normal",curStyle) 165 | return ret 166 | 167 | 168 | 169 | func _on_typedLineEdit_text_changed(new_text : String) -> void: 170 | # print(new_text) 171 | 172 | #if new_text == previousText: 173 | # text = new_text 174 | # print("boop") 175 | # return 176 | 177 | #previousText = new_text 178 | 179 | if is_instance_valid(preview): 180 | setChildrenVisible(false) 181 | preview.queue_free() 182 | 183 | new_text = new_text.strip_edges() 184 | 185 | var vari = str2var(new_text) 186 | 187 | if typeof(vari) == TYPE_INT: 188 | if(new_text.find(" ") != -1): 189 | vari = new_text 190 | value = vari 191 | 192 | #if new_text.find("deathSounds") != -1: 193 | # breakpoint 194 | 195 | #if typeof(vari) != TYPE_COLOR: 196 | # self_modulate = Color.white 197 | #elif typeof(vari) == TYPE_COLOR: 198 | # self_modulate = value 199 | 200 | 201 | if typeof(vari) == TYPE_STRING: 202 | 203 | if new_text.length() > 1: 204 | if new_text[0] == "{": 205 | parseDict(new_text) 206 | 207 | if new_text.find("http") == 0: 208 | if new_text.count("png") or new_text.count("jpg") or new_text.count("bmp") or new_text.count("tga"): 209 | texturefromURL(new_text) 210 | 211 | elif new_text.is_abs_path(): 212 | parsePath(new_text) 213 | 214 | value = new_text 215 | # if new_text.is_valid_integer(): 216 | # value = new_text.to_int() 217 | # elif new_text.is_valid_float(): 218 | # value = new_text.to_float() 219 | # elif new_text.is_valid_html_color(): 220 | # value = Color(new_text) 221 | # self_modulate = value 222 | # elif new_text.to_lower() == "true": 223 | # value = true 224 | # elif new_text.to_lower() == "false": 225 | # value = false 226 | # #activateOptionMode(["true","false"]) 227 | # elif new_text.is_abs_path(): 228 | # parsePath(new_text) 229 | # elif new_text[0] == "[": 230 | # parseArrayPre(new_text) 231 | # else: 232 | # value = new_text 233 | 234 | 235 | 236 | emit_signal("update",self) 237 | 238 | func gotImage(img): 239 | 240 | var spr = TextureRect.new() 241 | spr.texture = img 242 | spr.visible = true 243 | 244 | add_child(spr) 245 | sheetGlobal.getChildOfClass(self,"HTTPRequest").queue_free() 246 | preview = spr 247 | updateMeta() 248 | 249 | func updateMeta(): 250 | if inFocus: 251 | if has_meta("text"): 252 | text = get_meta("text") 253 | set_meta("text",null) 254 | 255 | setChildrenVisible(false) 256 | else: 257 | if is_instance_valid(preview): 258 | set_meta("text",text) 259 | text = "" 260 | setChildrenVisible(true) 261 | 262 | 263 | if is_instance_valid(par): 264 | par.updateSizingsFlag = true 265 | 266 | func texturefromURL(url): 267 | var http = HTTPRequest.new() 268 | 269 | 270 | http.set_script(load("res://addons/gSheet/scenes/typedLineEdit/HTTPRequest.gd")) 271 | http.connect("gotImage",self,"gotImage") 272 | 273 | add_child(http) 274 | http.fetch(url) 275 | 276 | func parsePath(path): 277 | path = path.replace("\\","/") 278 | 279 | if path.find("res://")!=-1: 280 | parseRes(path,"res://") 281 | elif path.find(":/")!=-1: 282 | parseRes(path,":/") 283 | 284 | func parseRes(path,pre): 285 | var post = path.split(pre)[1] 286 | var extension = post.get_extension() 287 | var fileName = post.get_file() 288 | 289 | if is_instance_valid(preview):#if we already have a preview delete it 290 | setChildrenVisible(false) 291 | preview.queue_free() 292 | 293 | var tex = null 294 | 295 | 296 | # if extension == "gd": 297 | # text = fileName 298 | # tex = createLineEdit() 299 | 300 | if isInternalSupportedImage(extension): 301 | tex = loadImageFromPath(path) 302 | 303 | if isInternalSupportedAudio(extension): 304 | tex = loadAudioFromPath(path) 305 | 306 | 307 | if tex == null: 308 | return false 309 | 310 | 311 | preview = tex 312 | 313 | #if preview.has_method("setText"): 314 | # preview.setText(text) 315 | #elif "text" in preview: 316 | # preview.text = text 317 | 318 | 319 | 320 | add_child(tex) 321 | setChildrenVisible(false) 322 | 323 | func loadImageFromPath(path): 324 | var img = Image.new() 325 | var tex = ImageTexture.new() 326 | 327 | var err = img.load(path) 328 | 329 | if err != 0: 330 | return null 331 | tex.create_from_image(img) 332 | 333 | var spr = TextureRect.new() 334 | spr.texture = tex 335 | spr.visible = true 336 | 337 | return spr 338 | 339 | 340 | func loadAudioFromPath(path): 341 | var stream 342 | var file = File.new() 343 | var err = file.open(path, File.READ) 344 | 345 | if err != 0: 346 | return null 347 | 348 | var data = file.get_buffer(file.get_len()) 349 | var ext = path.get_extension().to_lower() 350 | 351 | file.close() 352 | 353 | if ext == "mp3": 354 | stream = AudioStreamMP3.new() 355 | stream.data = data 356 | elif ext == "ogg": 357 | stream.data = data 358 | stream = AudioStreamOGGVorbis.new() 359 | elif ext == "wav": 360 | var script = load("res://addons/gSheet/scenes/typedLineEdit/wavLoad.gd").new() 361 | stream = script.getStreamFromWAV(path) 362 | else: 363 | return null 364 | 365 | var audioPlayer = load("res://addons/gSheet/scenes/typedLineEdit/scenes/audioPreview.tscn").instance() 366 | audioPlayer.setAudio(stream) 367 | audioPlayer.setText(path) 368 | 369 | 370 | return audioPlayer 371 | 372 | 373 | func _on_typedLineEdit_focus_entered(): 374 | inFocus = true 375 | 376 | updateMeta() 377 | emit_signal("focusEntered",self) 378 | 379 | 380 | func _on_typedLineEdit_focus_exited(): 381 | inFocus = false 382 | updateMeta() 383 | 384 | 385 | 386 | 387 | emit_signal("focusExit",self) 388 | 389 | 390 | func setChildrenVisible(isVisible): 391 | 392 | if is_instance_valid(preview): 393 | if isVisible: 394 | preview.visible = true 395 | var t = preview.rect_size 396 | rect_size = preview.rect_size 397 | rect_min_size = preview.rect_size 398 | else: 399 | preview.visible = false 400 | rect_min_size = Vector2.ZERO 401 | 402 | emit_signal("updateRowHeight",get_meta("cellId"),rect_min_size) 403 | 404 | 405 | 406 | func isInternalSupportedImage(ext): 407 | var fmts = ["png","dds","jpg","jpeg","bmp","svg","svgz","webp","tga","hdr"] 408 | for i in fmts: 409 | if ext == i: 410 | return true 411 | 412 | return false 413 | 414 | func isInternalSupportedAudio(ext): 415 | var fmts = ["wav","mp3","ogg"] 416 | 417 | for i in fmts: 418 | if ext == i: 419 | return true 420 | 421 | return false 422 | 423 | func index_pressed(index): 424 | emit_signal("index_pressed",self,index,get_meta("index")) 425 | 426 | 427 | 428 | func _on_OptionButton_item_selected(index): 429 | var txt = optionButton.get_item_text(index) 430 | var enumStrToValue = get_meta("enumStrToValue") 431 | 432 | print(txt) 433 | 434 | if txt == "": 435 | value = enumStrToValue["@DUMMY"] 436 | text = "" 437 | return 438 | #if enumStrToValue[txt] == index: 439 | # value = "" 440 | text = "" 441 | return 442 | 443 | value = enumStrToValue[txt] 444 | #text = "" 445 | text = txt 446 | par.serializeFlag = true 447 | 448 | 449 | func setData(dict : Dictionary) -> void: 450 | var type : String = dict["type"] 451 | var data = dict["data"] 452 | 453 | if type == "str": 454 | text = data 455 | _on_typedLineEdit_text_changed(text) 456 | 457 | if dict["type"] == "enum": 458 | activateOptionMode(data,dict["enumStr"]) 459 | return 460 | 461 | func getData(dict): 462 | var type 463 | var data = dict["data"] 464 | 465 | 466 | 467 | if type == "str": 468 | text = data 469 | _on_typedLineEdit_text_changed(text) 470 | 471 | if dict["type"] == "enum": 472 | activateOptionMode(data,text) 473 | return 474 | 475 | 476 | func parseDict(dstr): 477 | pass 478 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/full/spreadsheetFull.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=11 format=2] 2 | 3 | [ext_resource path="res://addons/gSheet/scenes/spreadsheet/spreadsheet.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://addons/gSheet/scenes/spreadsheet/dummyTool.gd" type="Script" id=2] 5 | [ext_resource path="res://addons/gSheet/scenes/spreadsheet/full/spreadsheetFull.gd" type="Script" id=3] 6 | [ext_resource path="res://addons/gSheet/scenes/spreadsheet/full/DataFromText.gd" type="Script" id=4] 7 | [ext_resource path="res://addons/gSheet/scenes/spreadsheet/full/scenes/bottomBar/bottomBar.tscn" type="PackedScene" id=5] 8 | [ext_resource path="res://addons/gSheet/scenes/spreadsheet/full/top.gd" type="Script" id=6] 9 | [ext_resource path="res://addons/gSheet/scenes/spreadsheet/parsers/enumParse.gd" type="Script" id=7] 10 | [ext_resource path="res://addons/gSheet/scenes/spreadsheet/full/scenes/enumPopup/enumPopup.tscn" type="PackedScene" id=8] 11 | 12 | [sub_resource type="StyleBoxFlat" id=1] 13 | content_margin_left = 0.0 14 | content_margin_right = 0.0 15 | content_margin_top = 0.0 16 | content_margin_bottom = 0.0 17 | bg_color = Color( 0.176471, 0.2, 0.266667, 1 ) 18 | border_width_right = 1 19 | border_width_bottom = 1 20 | border_color = Color( 0.0784314, 0.0980392, 0.14902, 1 ) 21 | 22 | [sub_resource type="StyleBoxFlat" id=2] 23 | content_margin_left = 7.0 24 | content_margin_right = 7.0 25 | content_margin_top = 2.0 26 | content_margin_bottom = 2.0 27 | bg_color = Color( 0.176471, 0.2, 0.266667, 1 ) 28 | border_width_left = 1 29 | border_width_top = 1 30 | border_width_right = 1 31 | border_width_bottom = 1 32 | border_color = Color( 0.0784314, 0.0980392, 0.14902, 1 ) 33 | expand_margin_left = 7.0 34 | expand_margin_right = 7.0 35 | expand_margin_top = 3.0 36 | expand_margin_bottom = 3.0 37 | 38 | [node name="Main" type="Panel"] 39 | anchor_right = 1.0 40 | anchor_bottom = 1.0 41 | rect_pivot_offset = Vector2( -146, 335 ) 42 | rect_clip_content = true 43 | script = ExtResource( 3 ) 44 | allowImportTres = true 45 | showSaveButton = true 46 | 47 | [node name="VBoxContainer" type="VBoxContainer" parent="."] 48 | anchor_right = 1.0 49 | anchor_bottom = 1.0 50 | size_flags_horizontal = 3 51 | size_flags_vertical = 3 52 | custom_constants/separation = 0 53 | 54 | [node name="Label" type="LineEdit" parent="VBoxContainer"] 55 | margin_right = 1024.0 56 | margin_bottom = 30.0 57 | rect_min_size = Vector2( 0, 30 ) 58 | editable = false 59 | 60 | [node name="Panel" type="Control" parent="VBoxContainer"] 61 | margin_top = 30.0 62 | margin_right = 1024.0 63 | margin_bottom = 55.0 64 | rect_min_size = Vector2( 0, 25 ) 65 | 66 | [node name="HBoxContainer2" parent="VBoxContainer/Panel" instance=ExtResource( 5 )] 67 | margin_left = 9.0 68 | margin_top = 2.0 69 | margin_right = 1033.0 70 | margin_bottom = 21.0 71 | custom_constants/separation = 21 72 | 73 | [node name="TopContainer" type="Control" parent="VBoxContainer"] 74 | margin_top = 55.0 75 | margin_right = 1024.0 76 | margin_bottom = 75.0 77 | rect_min_size = Vector2( 62, 20 ) 78 | rect_clip_content = true 79 | 80 | [node name="top" type="HBoxContainer" parent="VBoxContainer/TopContainer"] 81 | margin_left = 69.0 82 | margin_top = -3.0 83 | margin_right = 431.0 84 | margin_bottom = 72.0 85 | rect_min_size = Vector2( 55, 17 ) 86 | rect_clip_content = true 87 | script = ExtResource( 6 ) 88 | 89 | [node name="enumParse" type="Node" parent="VBoxContainer/TopContainer/top"] 90 | script = ExtResource( 7 ) 91 | 92 | [node name="enumPopup" parent="VBoxContainer/TopContainer/top" instance=ExtResource( 8 )] 93 | anchor_right = 0.0 94 | anchor_bottom = 0.0 95 | margin_right = 130.0 96 | margin_bottom = 75.0 97 | 98 | [node name="AcceptDialog" type="AcceptDialog" parent="VBoxContainer/TopContainer/top"] 99 | margin_right = 162.0 100 | margin_bottom = 75.0 101 | dialog_text = "No enums found in file 102 | " 103 | 104 | [node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"] 105 | margin_top = 75.0 106 | margin_right = 1024.0 107 | margin_bottom = 600.0 108 | rect_clip_content = true 109 | mouse_filter = 0 110 | size_flags_horizontal = 3 111 | size_flags_vertical = 3 112 | custom_constants/separation = 7 113 | 114 | [node name="side" type="Control" parent="VBoxContainer/HBoxContainer"] 115 | margin_right = 62.0 116 | margin_bottom = 525.0 117 | rect_min_size = Vector2( 62, 0 ) 118 | 119 | [node name="Spreadsheet" parent="VBoxContainer/HBoxContainer" instance=ExtResource( 1 )] 120 | anchor_right = 0.0 121 | anchor_bottom = 0.0 122 | margin_left = 69.0 123 | margin_right = 1024.0 124 | margin_bottom = 525.0 125 | rect_min_size = Vector2( 0, 0 ) 126 | 127 | [node name="ScrollContainer" parent="VBoxContainer/HBoxContainer/Spreadsheet/Control" index="0"] 128 | margin_right = 955.0 129 | margin_bottom = 525.0 130 | 131 | [node name="FileDialog" type="FileDialog" parent="."] 132 | anchor_right = 0.724 133 | anchor_bottom = 0.572 134 | margin_right = -0.376038 135 | margin_bottom = -0.200012 136 | window_title = "Open a File" 137 | mode = 0 138 | access = 2 139 | filters = PoolStringArray( "*.gd" ) 140 | 141 | [node name="Corner" type="LineEdit" parent="."] 142 | visible = false 143 | margin_top = 55.0 144 | margin_right = 69.0 145 | margin_bottom = 73.0 146 | rect_min_size = Vector2( 62, 0 ) 147 | custom_styles/read_only = SubResource( 1 ) 148 | custom_styles/normal = SubResource( 2 ) 149 | editable = false 150 | caret_blink = true 151 | caret_blink_speed = 0.5 152 | script = ExtResource( 2 ) 153 | 154 | [node name="DataFromText" type="ConfirmationDialog" parent="."] 155 | anchor_right = 1.0 156 | anchor_bottom = 1.0 157 | window_title = "Enter data as dictionary" 158 | resizable = true 159 | script = ExtResource( 4 ) 160 | 161 | [node name="TextEdit" type="TextEdit" parent="DataFromText"] 162 | margin_left = 8.0 163 | margin_top = 8.0 164 | margin_right = 1016.0 165 | margin_bottom = 564.0 166 | size_flags_horizontal = 3 167 | size_flags_vertical = 3 168 | text = "var thingsDict ={ 169 | 1:{\"shape\":\"square\",\"color\":\"red\",\"size\":\"big\"}, 170 | 2:{\"shape\":\"circle\",\"color\":\"blue\",\"size\":\"small\"}, 171 | 3:{\"shape\":\"triangle\",\"color\":\"red\",\"size\":\"small\"}, 172 | 4:{\"shape\":\"rectangle\",\"color\":\"green\",\"size\":\"big\"}, 173 | }" 174 | 175 | [connection signal="focus_entered" from="VBoxContainer/TopContainer/top/col 0/VBoxContainer/typedLineEdit" to="VBoxContainer/TopContainer/top/col 0/VBoxContainer/typedLineEdit" method="_on_typedLineEdit_focus_entered"] 176 | [connection signal="focus_exited" from="VBoxContainer/TopContainer/top/col 0/VBoxContainer/typedLineEdit" to="VBoxContainer/TopContainer/top/col 0/VBoxContainer/typedLineEdit" method="_on_typedLineEdit_focus_exited"] 177 | [connection signal="focus_entered" from="VBoxContainer/TopContainer/top/col 0/col 1/VBoxContainer/typedLineEdit" to="VBoxContainer/TopContainer/top/col 0/col 1/VBoxContainer/typedLineEdit" method="_on_typedLineEdit_focus_entered"] 178 | [connection signal="focus_exited" from="VBoxContainer/TopContainer/top/col 0/col 1/VBoxContainer/typedLineEdit" to="VBoxContainer/TopContainer/top/col 0/col 1/VBoxContainer/typedLineEdit" method="_on_typedLineEdit_focus_exited"] 179 | [connection signal="focus_entered" from="VBoxContainer/TopContainer/top/col 0/col 1/col 2/VBoxContainer/typedLineEdit" to="VBoxContainer/TopContainer/top/col 0/col 1/col 2/VBoxContainer/typedLineEdit" method="_on_typedLineEdit_focus_entered"] 180 | [connection signal="focus_exited" from="VBoxContainer/TopContainer/top/col 0/col 1/col 2/VBoxContainer/typedLineEdit" to="VBoxContainer/TopContainer/top/col 0/col 1/col 2/VBoxContainer/typedLineEdit" method="_on_typedLineEdit_focus_exited"] 181 | [connection signal="focus_entered" from="VBoxContainer/TopContainer/top/col 0/col 1/col 2/col 3/VBoxContainer/typedLineEdit" to="VBoxContainer/TopContainer/top/col 0/col 1/col 2/col 3/VBoxContainer/typedLineEdit" method="_on_typedLineEdit_focus_entered"] 182 | [connection signal="focus_exited" from="VBoxContainer/TopContainer/top/col 0/col 1/col 2/col 3/VBoxContainer/typedLineEdit" to="VBoxContainer/TopContainer/top/col 0/col 1/col 2/col 3/VBoxContainer/typedLineEdit" method="_on_typedLineEdit_focus_exited"] 183 | [connection signal="focus_entered" from="VBoxContainer/TopContainer/top/col 0/col 1/col 2/col 3/col 4/VBoxContainer/typedLineEdit" to="VBoxContainer/TopContainer/top/col 0/col 1/col 2/col 3/col 4/VBoxContainer/typedLineEdit" method="_on_typedLineEdit_focus_entered"] 184 | [connection signal="focus_exited" from="VBoxContainer/TopContainer/top/col 0/col 1/col 2/col 3/col 4/VBoxContainer/typedLineEdit" to="VBoxContainer/TopContainer/top/col 0/col 1/col 2/col 3/col 4/VBoxContainer/typedLineEdit" method="_on_typedLineEdit_focus_exited"] 185 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/side/VBoxContainer/typedLineEdit" to="VBoxContainer/HBoxContainer/side/VBoxContainer/typedLineEdit" method="_on_typedLineEdit_focus_entered"] 186 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/side/VBoxContainer/typedLineEdit" to="VBoxContainer/HBoxContainer/side/VBoxContainer/typedLineEdit" method="_on_typedLineEdit_focus_exited"] 187 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/side/VBoxContainer/typedLineEdit2" to="VBoxContainer/HBoxContainer/side/VBoxContainer/typedLineEdit2" method="_on_typedLineEdit_focus_entered"] 188 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/side/VBoxContainer/typedLineEdit2" to="VBoxContainer/HBoxContainer/side/VBoxContainer/typedLineEdit2" method="_on_typedLineEdit_focus_exited"] 189 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/side/VBoxContainer/typedLineEdit3" to="VBoxContainer/HBoxContainer/side/VBoxContainer/typedLineEdit3" method="_on_typedLineEdit_focus_entered"] 190 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/side/VBoxContainer/typedLineEdit3" to="VBoxContainer/HBoxContainer/side/VBoxContainer/typedLineEdit3" method="_on_typedLineEdit_focus_exited"] 191 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/side/VBoxContainer/typedLineEdit4" to="VBoxContainer/HBoxContainer/side/VBoxContainer/typedLineEdit4" method="_on_typedLineEdit_focus_entered"] 192 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/side/VBoxContainer/typedLineEdit4" to="VBoxContainer/HBoxContainer/side/VBoxContainer/typedLineEdit4" method="_on_typedLineEdit_focus_exited"] 193 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/side/VBoxContainer/typedLineEdit5" to="VBoxContainer/HBoxContainer/side/VBoxContainer/typedLineEdit5" method="_on_typedLineEdit_focus_entered"] 194 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/side/VBoxContainer/typedLineEdit5" to="VBoxContainer/HBoxContainer/side/VBoxContainer/typedLineEdit5" method="_on_typedLineEdit_focus_exited"] 195 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/VBoxContainer/row 0" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/VBoxContainer/row 0" method="_on_typedLineEdit_focus_entered"] 196 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/VBoxContainer/row 0" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/VBoxContainer/row 0" method="_on_typedLineEdit_focus_exited"] 197 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/VBoxContainer/row 1" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/VBoxContainer/row 1" method="_on_typedLineEdit_focus_entered"] 198 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/VBoxContainer/row 1" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/VBoxContainer/row 1" method="_on_typedLineEdit_focus_exited"] 199 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/VBoxContainer/row 2" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/VBoxContainer/row 2" method="_on_typedLineEdit_focus_entered"] 200 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/VBoxContainer/row 2" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/VBoxContainer/row 2" method="_on_typedLineEdit_focus_exited"] 201 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/VBoxContainer/row 3" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/VBoxContainer/row 3" method="_on_typedLineEdit_focus_entered"] 202 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/VBoxContainer/row 3" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/VBoxContainer/row 3" method="_on_typedLineEdit_focus_exited"] 203 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/VBoxContainer/row 4" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/VBoxContainer/row 4" method="_on_typedLineEdit_focus_entered"] 204 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/VBoxContainer/row 4" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/VBoxContainer/row 4" method="_on_typedLineEdit_focus_exited"] 205 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/VBoxContainer/row 0" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/VBoxContainer/row 0" method="_on_typedLineEdit_focus_entered"] 206 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/VBoxContainer/row 0" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/VBoxContainer/row 0" method="_on_typedLineEdit_focus_exited"] 207 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/VBoxContainer/row 1" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/VBoxContainer/row 1" method="_on_typedLineEdit_focus_entered"] 208 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/VBoxContainer/row 1" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/VBoxContainer/row 1" method="_on_typedLineEdit_focus_exited"] 209 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/VBoxContainer/row 2" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/VBoxContainer/row 2" method="_on_typedLineEdit_focus_entered"] 210 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/VBoxContainer/row 2" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/VBoxContainer/row 2" method="_on_typedLineEdit_focus_exited"] 211 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/VBoxContainer/row 3" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/VBoxContainer/row 3" method="_on_typedLineEdit_focus_entered"] 212 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/VBoxContainer/row 3" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/VBoxContainer/row 3" method="_on_typedLineEdit_focus_exited"] 213 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/VBoxContainer/row 4" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/VBoxContainer/row 4" method="_on_typedLineEdit_focus_entered"] 214 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/VBoxContainer/row 4" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/VBoxContainer/row 4" method="_on_typedLineEdit_focus_exited"] 215 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/VBoxContainer/row 0" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/VBoxContainer/row 0" method="_on_typedLineEdit_focus_entered"] 216 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/VBoxContainer/row 0" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/VBoxContainer/row 0" method="_on_typedLineEdit_focus_exited"] 217 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/VBoxContainer/row 1" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/VBoxContainer/row 1" method="_on_typedLineEdit_focus_entered"] 218 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/VBoxContainer/row 1" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/VBoxContainer/row 1" method="_on_typedLineEdit_focus_exited"] 219 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/VBoxContainer/row 2" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/VBoxContainer/row 2" method="_on_typedLineEdit_focus_entered"] 220 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/VBoxContainer/row 2" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/VBoxContainer/row 2" method="_on_typedLineEdit_focus_exited"] 221 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/VBoxContainer/row 3" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/VBoxContainer/row 3" method="_on_typedLineEdit_focus_entered"] 222 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/VBoxContainer/row 3" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/VBoxContainer/row 3" method="_on_typedLineEdit_focus_exited"] 223 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/VBoxContainer/row 4" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/VBoxContainer/row 4" method="_on_typedLineEdit_focus_entered"] 224 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/VBoxContainer/row 4" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/VBoxContainer/row 4" method="_on_typedLineEdit_focus_exited"] 225 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/VBoxContainer/row 0" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/VBoxContainer/row 0" method="_on_typedLineEdit_focus_entered"] 226 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/VBoxContainer/row 0" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/VBoxContainer/row 0" method="_on_typedLineEdit_focus_exited"] 227 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/VBoxContainer/row 1" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/VBoxContainer/row 1" method="_on_typedLineEdit_focus_entered"] 228 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/VBoxContainer/row 1" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/VBoxContainer/row 1" method="_on_typedLineEdit_focus_exited"] 229 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/VBoxContainer/row 2" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/VBoxContainer/row 2" method="_on_typedLineEdit_focus_entered"] 230 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/VBoxContainer/row 2" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/VBoxContainer/row 2" method="_on_typedLineEdit_focus_exited"] 231 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/VBoxContainer/row 3" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/VBoxContainer/row 3" method="_on_typedLineEdit_focus_entered"] 232 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/VBoxContainer/row 3" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/VBoxContainer/row 3" method="_on_typedLineEdit_focus_exited"] 233 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/VBoxContainer/row 4" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/VBoxContainer/row 4" method="_on_typedLineEdit_focus_entered"] 234 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/VBoxContainer/row 4" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/VBoxContainer/row 4" method="_on_typedLineEdit_focus_exited"] 235 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/col 0/VBoxContainer/row 0" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/col 0/VBoxContainer/row 0" method="_on_typedLineEdit_focus_entered"] 236 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/col 0/VBoxContainer/row 0" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/col 0/VBoxContainer/row 0" method="_on_typedLineEdit_focus_exited"] 237 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/col 0/VBoxContainer/row 1" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/col 0/VBoxContainer/row 1" method="_on_typedLineEdit_focus_entered"] 238 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/col 0/VBoxContainer/row 1" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/col 0/VBoxContainer/row 1" method="_on_typedLineEdit_focus_exited"] 239 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/col 0/VBoxContainer/row 2" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/col 0/VBoxContainer/row 2" method="_on_typedLineEdit_focus_entered"] 240 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/col 0/VBoxContainer/row 2" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/col 0/VBoxContainer/row 2" method="_on_typedLineEdit_focus_exited"] 241 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/col 0/VBoxContainer/row 3" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/col 0/VBoxContainer/row 3" method="_on_typedLineEdit_focus_entered"] 242 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/col 0/VBoxContainer/row 3" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/col 0/VBoxContainer/row 3" method="_on_typedLineEdit_focus_exited"] 243 | [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/col 0/VBoxContainer/row 4" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/col 0/VBoxContainer/row 4" method="_on_typedLineEdit_focus_entered"] 244 | [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/col 0/VBoxContainer/row 4" to="VBoxContainer/HBoxContainer/Spreadsheet/Control/ScrollContainer/col 4/col 3/col 2/col 1/col 0/VBoxContainer/row 4" method="_on_typedLineEdit_focus_exited"] 245 | 246 | [editable path="VBoxContainer/HBoxContainer/Spreadsheet"] 247 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/mainScript.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends Control 3 | signal dictChanged 4 | 5 | export(Resource) var sheetStyle 6 | export var autoGrow = false 7 | 8 | var customStyle = null 9 | var customStyleSide= null 10 | var saveFlag = false 11 | var serializeFlag = true 12 | var updateSizingsFlag = false 13 | var initialColumns =5#12 14 | var initialRows = 5#20 15 | 16 | var numRows = 0 17 | var numCols = 0 18 | var data = {} 19 | var cols = [] 20 | var rows = [] 21 | var cells = [] 22 | var cellW 23 | var cellH 24 | var nodePool = [] 25 | 26 | var core = null 27 | var top = null 28 | var side = null 29 | var corner = null 30 | 31 | var curRow = -1 32 | var curCol = -1 33 | var undoStack = [] 34 | var needsSaving = false 35 | 36 | 37 | onready var initialSpreadSheetX = get_parent().rect_position.x 38 | var initialTopX 39 | onready var marginLeft = sheetStyle.marginLeft 40 | onready var marginRight = sheetStyle.marginRight 41 | onready var marginTop = sheetStyle.marginTop 42 | onready var marginBottom = sheetStyle.marginBottom 43 | 44 | 45 | var colsTop = [] 46 | var rowsSide = [] 47 | var baseSplit : HSplitContainer = null 48 | onready var scrollContainer = $ScrollContainer 49 | func _ready(): 50 | 51 | top = get_node_or_null("../../../TopContainer/top") 52 | side = get_node_or_null("../../side") 53 | corner = get_node_or_null("../../../../Corner") 54 | 55 | 56 | 57 | 58 | if get_node_or_null("../../../../DataFromText") != null: 59 | $"../../../../DataFromText".connect("confirm",self,"textToDataConfirm") 60 | 61 | if get_node_or_null("../../../../../") != null: 62 | core = $"../../../../" 63 | connect("dictChanged",core,"dictChanged") 64 | 65 | get_viewport().connect("size_changed",self,"viewportChanged") 66 | var windowRes = get_viewport().size 67 | instanceStylesFromRes() 68 | 69 | if customStyle != null: 70 | cellW = 48 + marginLeft + marginRight 71 | cellH = 14 + marginTop + marginBottom 72 | else: 73 | cellW = 58 74 | cellH = 24 75 | 76 | 77 | 78 | var neededColumns = ceil(windowRes.x / (cellW+marginLeft+marginRight)) 79 | var neededRows = ceil(windowRes.y / (cellH+marginTop + marginBottom)) 80 | 81 | if !autoGrow: 82 | neededColumns = initialColumns 83 | neededRows = initialRows 84 | 85 | 86 | for i in neededColumns: 87 | if i == 0: 88 | addColumn("",false) 89 | else: 90 | addColumn("",false) 91 | 92 | 93 | 94 | if side != null: 95 | var hSplit = get_node_or_null("../../side") 96 | 97 | if hSplit == null: 98 | return 99 | 100 | 101 | $"../../".set("custom_constants/separation",(marginLeft+marginRight)/2.0) 102 | 103 | var vBox = VBoxContainer.new() 104 | side = vBox 105 | side.set("custom_constants/separation",marginBottom+marginTop-1) 106 | vBox.margin_top 107 | 108 | hSplit.add_child(vBox) 109 | 110 | $"../../side".rect_min_size.x = marginLeft+marginRight+48 111 | 112 | 113 | if top != null: 114 | 115 | initialTopX = top.get_parent().rect_position.x 116 | 117 | var t = top.get_parent().get_parent() 118 | t.set("custom_constants/separation",0) 119 | 120 | #corner.set("custom_styles/normal",customStyleSide) 121 | #corner.visible = true 122 | #corner.rect_min_size = Vector2(cellW,0) 123 | #corner.rect_size = Vector2(cellW,0) 124 | top.get_parent().rect_min_size = Vector2(cellW,cellH) 125 | 126 | 127 | for i in neededRows: 128 | addRow(false,i) 129 | 130 | 131 | func _process(delta): 132 | 133 | 134 | if saveFlag: 135 | data = serializeData() 136 | if core != null: 137 | emit_signal("dictChanged",data) 138 | saveFlag = false 139 | 140 | 141 | if updateSizingsFlag: 142 | updateSizings(false) 143 | updateSizingsFlag = false 144 | 145 | if top == null: 146 | return 147 | 148 | if serializeFlag: 149 | emit_signal("dictChanged",serializeData()) 150 | serializeFlag = false 151 | 152 | top.rect_position.x = -scrollContainer.scroll_horizontal+(1.5*(marginLeft+marginRight)+48) #- 2 153 | $"../../side".rect_position.y = -scrollContainer.scroll_vertical 154 | 155 | call_deferred("poolTick") 156 | 157 | 158 | 159 | func addColumn(title : String,emitSignal : bool = true,idx : int = -1,addToUndoStack : bool= false) -> LineEdit: 160 | var hSplit = HSplitContainer.new() 161 | var vBox = VBoxContainer.new() 162 | var initial = false 163 | var ret = null 164 | if numCols == 0: 165 | initial = true 166 | 167 | 168 | hSplit.set_script(load("res://addons/gSheet/scenes/spreadsheet/hSplitSignal.gd")) 169 | 170 | #hSplit.set_meta("index",numCols) 171 | hSplit.set_meta("index",idx) 172 | hSplit.connect("hDraw",self,"hDrawMain") 173 | hSplit.add_child(vBox) 174 | hSplit.connect("hDrag",self,"hDragged") 175 | hSplit.name = "col " + String(numCols) 176 | hSplit.set("custom_constants/separation",marginLeft+marginRight-1) 177 | vBox.set("custom_constants/separation",marginBottom+marginTop-1) 178 | 179 | 180 | if sheetStyle.customGrabber != null: 181 | hSplit.set("custom_icons/grabber",sheetStyle.customGrabber) 182 | 183 | 184 | if idx == -1: 185 | idx = 0 186 | 187 | if top != null: 188 | if title == "": 189 | if idx == -1: 190 | addHeadingColumn(numCols,numCols) 191 | else: 192 | addHeadingColumn(numCols,numCols) 193 | else: 194 | if idx==-1: 195 | addHeadingColumn(title,numCols) 196 | else: 197 | addHeadingColumn(title,numCols) 198 | 199 | if initial: 200 | baseSplit = hSplit 201 | scrollContainer.add_child(hSplit) 202 | hSplit.show_behind_parent = true 203 | scrollContainer.move_child(hSplit,0) 204 | 205 | 206 | else: 207 | if idx ==-1: 208 | addToLatestHSplit(scrollContainer,hSplit) 209 | else: 210 | addToIdxHSplit(scrollContainer,hSplit,idx-1,0) 211 | 212 | 213 | 214 | if idx == -1: 215 | cols.append(vBox) 216 | cells.append([])#new column so new entry in cells 217 | else: 218 | cols.insert(idx,vBox) 219 | cells.insert(idx,[])#new column so new entry in cells 220 | 221 | 222 | 223 | for i in numRows:#for each row 224 | var cellNode : LineEdit= createRowCell(numCols,i)#create the row cell 225 | ret = cellNode 226 | 227 | if idx == numCols or idx == -1: 228 | cellNode.size_flags_horizontal = 0 229 | 230 | if idx == -1: 231 | cells[numCols].append(cellNode)#add to end of vbox 232 | 233 | else: 234 | cells[idx].append(cellNode)#add to idx +1 of vbox 235 | 236 | vBox.add_child(cellNode)#add vbox to node 237 | 238 | numCols += 1 239 | 240 | if (idx != -1 and idx-1 > 0) or (idx == -1 and numCols > 1): 241 | if idx != -1: 242 | for i in cols[idx-1].get_children(): 243 | i.size_flags_horizontal = 1 244 | if idx == -1: 245 | for i in cols[numCols-2].get_children(): 246 | i.size_flags_horizontal = 1 247 | 248 | 249 | if idx != -1: 250 | for x in range(idx-1,numCols):#for each column 251 | colsTop[x].get_child(0).set_meta("index",x) 252 | 253 | for yIdx in cols[x].get_children().size(): 254 | var y = cols[x].get_children()[yIdx] 255 | y.set_meta("cellId",[x,yIdx]) 256 | 257 | 258 | if addToUndoStack: 259 | undoStack.append({"action":"deleteCol","id":idx }) 260 | 261 | updateSizingsFlag = true 262 | if emitSignal: 263 | serializeFlag = true 264 | #emit_signal("dictChanged",serializeData()) 265 | 266 | return ret 267 | 268 | 269 | func addToLatestHSplit(par,node): 270 | 271 | 272 | 273 | for i in par.get_children(): 274 | if i.get_class() == "HSplitContainer": 275 | if i.get_child_count() == 1:#if we only have one child on hsplit 276 | i.add_child(node) 277 | else: 278 | addToLatestHSplit(i,node) 279 | 280 | func addToIdxHSplit(par,node,idx,count): 281 | 282 | 283 | 284 | 285 | if idx == -1: 286 | #var hs = HSplitContainer.new() 287 | var scroll = baseSplit.get_parent() 288 | scroll.remove_child(baseSplit) 289 | var hs = node 290 | scroll.add_child(hs) 291 | scroll.move_child(hs,0) 292 | hs.add_child(baseSplit) 293 | 294 | 295 | 296 | baseSplit = hs 297 | 298 | #hs.add_child(node) 299 | return 300 | 301 | 302 | for i in par.get_children(): 303 | if i.get_class() == "HSplitContainer": 304 | if i.get_child_count() == 1 or idx == count:#if we only have one child on hsplit 305 | 306 | if i.get_child_count() == 1: 307 | i.add_child(node) 308 | else: 309 | var oldCol = i.get_child(1) 310 | i.remove_child(oldCol) 311 | i.add_child(node) 312 | node.add_child(oldCol) 313 | else: 314 | addToIdxHSplit(i,node,idx,count+1) 315 | 316 | func poolTick(): 317 | if nodePool.size() < 10000: 318 | for i in 5: 319 | nodePool.append(createLineEdit("",true,true)) 320 | 321 | 322 | 323 | func fetchLineEdit(content="",grow=false,editable=false) -> LineEdit: 324 | if !nodePool.empty(): 325 | var node : LineEdit = nodePool.pop_front() 326 | node.text = String(content) 327 | return node 328 | 329 | return createLineEdit(content,grow,editable) 330 | 331 | func createLineEdit(content=null,grow=false,editable=false) -> LineEdit: 332 | 333 | 334 | 335 | var edit : LineEdit = lineEditNew() 336 | edit.sheet = self 337 | 338 | #edit.align = edit.ALIGN_CENTER 339 | 340 | if !grow: 341 | edit.size_flags_horizontal = 0 342 | 343 | edit.expand_to_text_length = true 344 | 345 | if customStyle != null: 346 | edit.set("custom_styles/normal",customStyle) 347 | 348 | 349 | 350 | if content != null: 351 | edit.text = String(content) 352 | 353 | 354 | return edit 355 | 356 | func createColRow(cur): 357 | 358 | var arr = [] 359 | 360 | if cur.get_child_count() == 0: 361 | return arr 362 | 363 | for i in cur.get_children(): 364 | if i.get_class() == "HSplitContainer": 365 | arr.append(i) 366 | 367 | if i.get_class() == null: 368 | pass 369 | pass 370 | 371 | func _on_addCategory_pressed(): 372 | addColumn("") 373 | 374 | 375 | func _on_Button_pressed(): 376 | addRow() 377 | 378 | var lineDuper : LineEdit = load("res://addons/gSheet/scenes/typedLineEdit/typedLineEdit.tscn").instance() 379 | func lineEditNew() -> LineEdit: 380 | 381 | #var line : LineEdit = load("res://addons/gSheet/scenes/typedLineEdit/typedLineEdit.tscn").instance() 382 | var line : LineEdit = lineDuper.duplicate() 383 | 384 | line.connect("update",self,"cellChanged") 385 | line.connect("updateRowHeight",self,"updateRowHeight") 386 | line.connect("focusEntered",self,"focusCell") 387 | line.connect("focusExit",self,"exitFocusCell") 388 | line.set("custom_colors/font_color",sheetStyle.fontColor) 389 | line.set("custom_colors/cursor_color",sheetStyle.cursorColor) 390 | line.hoverColor = sheetStyle.optionButtonHoverFontColor 391 | line.par = self 392 | return line 393 | 394 | func addRow(emitSignal : bool = true,idx : int =-1,addToUndoStack : bool = false,colToGrab :int = 0) -> LineEdit: 395 | 396 | var ret : LineEdit = null 397 | var sideCell : LineEdit 398 | 399 | if side != null:#this creates the side cellth 400 | sideCell = createSideCell(idx) 401 | rowsSide.erase(sideCell) 402 | rowsSide.insert(max(idx,0),sideCell) 403 | sideCell.set_meta("index",max(idx,0)) 404 | side.move_child(sideCell,max(idx,0)) 405 | 406 | for i in side.get_child_count(): 407 | side.get_child(i).set_meta("index",i) 408 | 409 | 410 | if addToUndoStack: 411 | if idx == -1: 412 | undoStack.append({"action":"deleteRow","id":0 }) 413 | else: 414 | undoStack.append({"action":"deleteRow","id":idx}) 415 | 416 | if sideCell != null: 417 | rowsSide.erase(sideCell) 418 | rowsSide.insert(max(idx,0),sideCell) 419 | sideCell.set_meta("index",max(idx,0)) 420 | 421 | for c in cols.size():#for each column vbox 422 | var col : VBoxContainer = cols[c] 423 | var lineEdit : LineEdit = createRowCell(c,numRows) 424 | if c == colToGrab: 425 | ret = lineEdit 426 | 427 | if idx == -1:#we just add lineEdit to vbox 428 | var t = side 429 | col.add_child(lineEdit) 430 | cells[c].insert(0,lineEdit) 431 | col.move_child(lineEdit,0) 432 | 433 | 434 | 435 | else: 436 | col.add_child(lineEdit) 437 | col.move_child(lineEdit,idx) 438 | 439 | cells[c].insert(idx,lineEdit) 440 | 441 | 442 | if c == cols.size()-2: 443 | lineEdit.size_flags_horizontal = 1 444 | 445 | if c == cols.size()-1: 446 | lineEdit.size_flags_horizontal = 0 447 | 448 | if cols[c].has_meta("enum"): 449 | var enumval = cols[c].get_meta("enum") 450 | var enumPrefix = cols[c].get_meta("enumPrefix") 451 | 452 | var enumStr = enumPrefix+"@DUMMY" 453 | lineEdit.setData({"type":"enum","data":enumval,"enumStr":enumStr}) 454 | 455 | 456 | 457 | 458 | 459 | #if idx != -1 and idx != 0: 460 | for cIdx in cols.size(): 461 | var colo = cols[cIdx] 462 | for y in range(max(idx,0),numRows+1): 463 | colo.get_child(y).set_meta("cellId",[cIdx,y]) 464 | 465 | 466 | 467 | numRows += 1 468 | 469 | if emitSignal: 470 | serializeFlag = true 471 | 472 | 473 | if addToUndoStack: 474 | pass 475 | 476 | return ret 477 | func createRowCell(colNum : int,rowNum : int) -> LineEdit: 478 | 479 | var lineEdit : LineEdit = fetchLineEdit("",true,true) 480 | lineEdit.set_meta("cellId",[colNum,rowNum]) 481 | lineEdit.set_name("row " + String(numRows)) 482 | 483 | return lineEdit 484 | 485 | 486 | func hDragged(amt,caller): 487 | var totalSize = rect_size 488 | var wos = getWidthOfCells() 489 | var diff = amt - caller.lastAmount 490 | 491 | baseSplit.rect_min_size.x = max(0,baseSplit.rect_size.x+diff) 492 | 493 | caller.lastAmount = amt 494 | 495 | 496 | for i in colsTop.size()-1:#for each heading cell 497 | var topSize = colsTop[i].rect_size 498 | var cellSize = cols[i].get_child(0).rect_size 499 | 500 | colsTop[i].rect_min_size = cols[i].get_child(0).rect_size 501 | 502 | updateSizingsFlag = true 503 | serializeFlag = true 504 | 505 | 506 | func getWidthOfCells(): 507 | var running = 0 508 | for i in cols.size(): 509 | #if !is_instance_valid(cols[i]): 510 | # print(cols[i].name) 511 | running += cols[i].rect_size.x 512 | 513 | return running 514 | 515 | 516 | 517 | func hDrawMain(caller): 518 | if colsTop.empty(): 519 | return 520 | 521 | 522 | var colIdx = caller.get_meta("index") 523 | 524 | if !colsTop.has(colIdx): 525 | return 526 | 527 | var col = colsTop[colIdx] 528 | col.rect_min_size.x = cols[colIdx].rect_size.x 529 | 530 | func cellChanged(caller): 531 | saveFlag = true 532 | updateSizingsFlag = true 533 | 534 | # if !caller.has_meta("cellId"): 535 | # if rowsSide.has(caller): 536 | # var count = 0 537 | # for i in rowsSide: 538 | # count+=1 539 | # if i!= caller: 540 | # if i.text == caller.text: 541 | # caller.text += "_duplicate" + String(count) 542 | 543 | var id = caller.get_meta("cellId") 544 | 545 | 546 | if id == null: 547 | if get_node("../../").name == "side": 548 | topCellChanged(caller) 549 | return 550 | 551 | 552 | 553 | var col = id[0] 554 | var row = id[1] 555 | 556 | 557 | if col == cols.size()-1: 558 | updateLastColWidth() 559 | 560 | if !autoGrow: 561 | return 562 | 563 | 564 | 565 | if col == cols.size()-1: 566 | addColumn("") 567 | 568 | if row == cells[0].size()-1: 569 | for i in range(0,1): 570 | addRow() 571 | 572 | 573 | 574 | 575 | func topCellChanged(cell): 576 | var col = cell.get_meta("index") 577 | 578 | var a = cell.rect_size.x 579 | var b = cols[col].rect_size.x 580 | 581 | cols[col].rect_min_size = cell.rect_size 582 | 583 | 584 | func focusCell(cell): 585 | 586 | if !cell.has_meta("cellId"): 587 | return 588 | 589 | var id = cell.get_meta("cellId") 590 | 591 | if id == null: 592 | return 593 | 594 | if id[1] > numRows-1: return 595 | if id[0] > numCols-1: return 596 | 597 | curCol = id[0] 598 | curRow = id[1] 599 | 600 | 601 | 602 | if rowsSide.empty(): 603 | return 604 | 605 | rowsSide[curRow].modulate = Color.lightgray 606 | colsTop[curCol].modulate = Color.lightgray 607 | 608 | 609 | 610 | func addHeadingColumn(text,idx=-1): 611 | var hSplit = HSplitContainer.new() 612 | var vBox = VBoxContainer.new() 613 | hSplit.name = "col " + String(colsTop.size()) 614 | var root 615 | 616 | if colsTop.empty(): 617 | root = top 618 | else: 619 | root = colsTop.back().get_parent() 620 | 621 | 622 | if idx != -1: 623 | if idx == 0: 624 | root = top 625 | else: 626 | root = colsTop[idx-1].get_parent() 627 | 628 | hSplit.set_script(load("res://addons/gSheet/scenes/spreadsheet/hSplitSignal.gd")) 629 | hSplit.connect("hDrag",self,"hDragged") 630 | hSplit.set("custom_constants/separation",marginLeft+marginRight-1) 631 | 632 | var heading = fetchLineEdit(text,true,false) 633 | 634 | 635 | heading.set("custom_styles/normal",customStyleSide) 636 | 637 | 638 | heading.set_meta("index",text) 639 | 640 | vBox.add_child(heading) 641 | 642 | if idx == -1: 643 | colsTop.append(vBox) 644 | 645 | hSplit.add_child(vBox) 646 | 647 | if idx !=-1: 648 | var oldChild = sheetGlobal.getChildOfClass(root,"HSplitContainer") 649 | colsTop.insert(idx,vBox) 650 | 651 | if oldChild != null: 652 | root.remove_child(oldChild) 653 | hSplit.add_child(oldChild) 654 | 655 | for i in range(idx+1,colsTop.size()): 656 | colsTop[i].get_child(0).set_meta("index",i+1) 657 | 658 | root.add_child(hSplit) 659 | top.newChild(heading) 660 | root = hSplit 661 | 662 | return hSplit 663 | 664 | 665 | func createSideCell(txt : int,autoAdd : bool = true) -> LineEdit: 666 | var text = String(txt) 667 | 668 | # for i in rowsSide: 669 | # if i.text == text: 670 | # text += "_duplicate" 671 | # break 672 | 673 | var heading : LineEdit = fetchLineEdit(text,true,false) 674 | heading.connect("focus_entered",self,"sideFocusCellFocus") 675 | heading.set("custom_styles/normal",customStyleSide) 676 | heading.set_meta("index",txt) 677 | if autoAdd: 678 | side.add_child(heading) 679 | rowsSide.append(heading) 680 | return heading 681 | 682 | func exitFocusCell(cell): 683 | 684 | if !cell.has_meta("cellId"): 685 | return 686 | 687 | var id = cell.get_meta("cellId") 688 | 689 | if id == null: 690 | return 691 | 692 | var col = id[0] 693 | var row = id[1] 694 | 695 | 696 | if rowsSide.empty(): return 697 | if row < numRows: 698 | rowsSide[row].modulate = Color.white 699 | 700 | if col < numCols: 701 | colsTop[col].modulate = Color.white 702 | 703 | updateSizingsFlag = true 704 | 705 | func updateRowHeight(id,size): 706 | var row = getRow(id[1]) 707 | 708 | for i in row: 709 | i.rect_min_size.y = size.y 710 | 711 | 712 | func updateSizingsSignal(): 713 | updateSizingsFlag = true 714 | 715 | func _on_Save_pressed(): 716 | sheetGlobal.saveNodeAsScene(self) 717 | 718 | func getRow(idx): 719 | var ret = [] 720 | 721 | for i in cells: 722 | ret.append(i[idx]) 723 | 724 | return ret 725 | 726 | 727 | func splitChange(): 728 | pass 729 | 730 | 731 | func instanceStylesFromRes(): 732 | customStyle = StyleBoxFlat.new() 733 | customStyle.bg_color = sheetStyle.cellColor 734 | customStyle.border_color = sheetStyle.cellBorderColor 735 | customStyle.border_width_top = sheetStyle.borderThickness 736 | customStyle.border_width_left = sheetStyle.borderThickness 737 | customStyle.border_width_right = sheetStyle.borderThickness 738 | customStyle.border_width_bottom = sheetStyle.borderThickness 739 | 740 | customStyle.expand_margin_left = sheetStyle.marginLeft 741 | customStyle.expand_margin_right = sheetStyle.marginRight 742 | customStyle.expand_margin_top = sheetStyle.marginTop 743 | customStyle.expand_margin_bottom = sheetStyle.marginBottom 744 | 745 | customStyle.content_margin_left = marginLeft 746 | customStyle.content_margin_right = marginRight 747 | customStyle.content_margin_top = marginTop 748 | customStyle.content_margin_bottom = marginBottom 749 | 750 | 751 | customStyleSide = StyleBoxFlat.new() 752 | 753 | customStyleSide.bg_color = sheetStyle.headingColor 754 | customStyleSide.border_color = sheetStyle.headingBorderColor 755 | customStyleSide.border_width_top = sheetStyle.borderThickness 756 | customStyleSide.border_width_left = sheetStyle.borderThickness 757 | customStyleSide.border_width_right = sheetStyle.borderThickness 758 | customStyleSide.border_width_bottom = sheetStyle.borderThickness 759 | 760 | customStyleSide.expand_margin_left = sheetStyle.marginLeft 761 | customStyleSide.expand_margin_right = sheetStyle.marginRight 762 | customStyleSide.expand_margin_top = sheetStyle.marginTop 763 | customStyleSide.expand_margin_bottom = sheetStyle.marginBottom 764 | 765 | customStyleSide.content_margin_left = sheetStyle.marginLeft 766 | customStyleSide.content_margin_right = sheetStyle.marginRight 767 | customStyleSide.content_margin_top = sheetStyle.marginTop 768 | customStyleSide.content_margin_bottom = sheetStyle.marginBottom 769 | 770 | 771 | func viewportChanged(): 772 | 773 | if !autoGrow: 774 | return 775 | var windowRes = get_viewport().size 776 | var neededColumns = ceil(windowRes.x / (cellW+marginLeft+marginRight)) 777 | var neededRows = ceil(windowRes.y / (cellH+marginTop + marginBottom)) 778 | 779 | 780 | for i in range(0,max(0,neededColumns-numCols+1)): 781 | addHeadingColumn(numCols+i) 782 | 783 | 784 | for i in range(0,max(0,neededColumns-numCols+1)): 785 | addColumn("") 786 | 787 | 788 | for i in range(0,max(0,neededRows-numRows+1)): 789 | addRow() 790 | 791 | updateSizingsFlag = true 792 | 793 | func textToDataConfirm(caller,text): 794 | blankSheet() 795 | #if text[0] == "{": text.erase(0,1) 796 | text = filterComments(text) 797 | text = text.replace("\n","") 798 | text = text.replace("\t","") 799 | 800 | #var x = JSON.parse(text) 801 | 802 | var data = recu2(text) 803 | 804 | 805 | 806 | var cats = getCategories(data) 807 | var values = getValuesForCategories(cats,data) 808 | 809 | var nCols = values.size() 810 | var nRows = values[values.keys()[0]].size() 811 | 812 | setNumCols(nCols) 813 | setNumRows(nRows) 814 | 815 | for i in cats.size(): 816 | colsTop[i].get_child(0).text = cats[i] 817 | 818 | for idx in data.keys().size(): 819 | var stripped = data.keys()[idx] 820 | 821 | while stripped[0] == " ": 822 | stripped = stripped.substr(1,-1) 823 | 824 | rowsSide[idx].text = stripped 825 | 826 | for i in values.size(): 827 | var key = values.keys()[i] 828 | var colDat = values[key] 829 | for j in colDat.size(): 830 | cells[i][j].text = String(colDat[j]) 831 | cells[i][j]._on_typedLineEdit_text_changed(String(colDat[j])) 832 | 833 | 834 | cells[0][0].grab_focus() 835 | updateSizingsFlag = true 836 | undoStack.clear() 837 | 838 | 839 | func getCategories(data): 840 | var cats = [] 841 | for entry in data.keys(): 842 | var entryCats = data[entry].keys() 843 | for i in entryCats: 844 | if !cats.has(i): 845 | cats.append(i) 846 | 847 | for idx in cats.size(): 848 | 849 | if cats[idx][0] == "\"": 850 | cats[idx] = cats[idx].substr(1,-1) 851 | 852 | if cats[idx][cats[idx].length()-1] == "\"": 853 | cats[idx] = cats[idx].substr(0,cats[idx].length()-1) 854 | return cats 855 | 856 | func getValuesForCategories(cats,data): 857 | var dict = {} 858 | var flag = false 859 | #dict["id"] = [] 860 | for i in cats: 861 | dict[i] = [] 862 | 863 | for entry in data.keys(): 864 | 865 | var values = data[entry] 866 | #dict["id"].append(entry) 867 | for i in dict.keys(): 868 | 869 | 870 | var values2 = {} 871 | for keyo in values.keys(): 872 | var key = keyo.replace("\"","") 873 | key = key.replace("'","'") 874 | values2[key]=values[keyo] 875 | 876 | 877 | if i == "id": 878 | continue 879 | if values2.has(i): 880 | dict[i].append(values2[i]) 881 | else: 882 | dict[i].append("") 883 | 884 | 885 | return dict 886 | 887 | 888 | 889 | 890 | func recu2(text): 891 | var find = text.find("{") 892 | var pre = text.substr(0,find) 893 | var post = text.substr(find,-1) 894 | 895 | if post[0] != "{": 896 | return 897 | 898 | return process2(post) 899 | 900 | 901 | 902 | 903 | func process2(text): 904 | #{"type":LTYPE.FLOOR,"str":"stair"} 905 | if text[0] == "{": 906 | var i = 1 907 | var dict = {} 908 | while i < text.length(): 909 | var dividerIdx = text.find(": ",i) 910 | if dividerIdx == -1: 911 | dividerIdx = text.find(":",i) 912 | 913 | var id = text.substr(i,dividerIdx-i) 914 | 915 | if dividerIdx == -1: 916 | return dict 917 | 918 | var remaining = text.substr(dividerIdx+1,-1) 919 | var value 920 | #var idStr = id.replace("\"","") 921 | #idStr = idStr.replace("\"","") 922 | var idStr = id 923 | 924 | if remaining[0] == " ": 925 | remaining = remaining.substr(1,-1) 926 | 927 | if remaining[0] == "{": 928 | value = getOuter(remaining,"{","}") 929 | 930 | 931 | i+=id.length() + value.length()+2 932 | var ret = value 933 | var idStrAgain = id.replace("\"","") 934 | 935 | dict[idStrAgain] = process2(value) 936 | continue 937 | 938 | if remaining[0] == "[": 939 | 940 | value = getOuter(remaining,"[","]") 941 | 942 | 943 | dict[idStr] = value 944 | i+=id.length() + value.length()+2 945 | continue 946 | 947 | if remaining[0] == "\"": 948 | value = getStringOuter(remaining) 949 | 950 | 951 | #value = value.substr(1,-1) 952 | #value = value.substr(1,value.length()-2)#remove first and last \" 953 | dict[idStr] = value 954 | i+=id.length() + value.length()+2 955 | continue 956 | 957 | else: 958 | value = getValue(remaining) 959 | 960 | i+=id.length() + value.length()+2 961 | dict[idStr] = value 962 | 963 | 964 | #return dict 965 | 966 | return dict 967 | 968 | 969 | func getValue(text): 970 | var runningStr = "" 971 | 972 | 973 | 974 | for ii in text.length(): 975 | var i = text[ii] 976 | 977 | if sheetGlobal.isInternal(runningStr): 978 | #if runningStr == "Vector2": 979 | var t = getOuter(text.substr(ii,-1),"(",")") 980 | return runningStr + t 981 | 982 | if i == "}" or i == ",": 983 | return runningStr 984 | 985 | runningStr+= i 986 | 987 | return runningStr 988 | 989 | 990 | func getTuples(text): 991 | 992 | var ret = [] 993 | 994 | var sub = text.split(":","") 995 | 996 | var arr = [] 997 | var content = strToArray(text) 998 | 999 | 1000 | for i in content: 1001 | var split = i.split(":") 1002 | arr.append(split[0]) 1003 | arr.append(split[1]) 1004 | 1005 | # 1006 | if arr.size() % 2 != 0: 1007 | return [] 1008 | # 1009 | for i in arr.size()/2: 1010 | 1011 | var a = arr[(i*2)] 1012 | var b = arr[(i*2)+1] 1013 | 1014 | a = a.replace('"',"") 1015 | a = a.replace("'","") 1016 | b = b.replace("}","") 1017 | ret.append([a,b]) 1018 | 1019 | return ret 1020 | 1021 | func strToArray(txt):#copy input 1022 | var runningArr = [] 1023 | var runningString = "" 1024 | 1025 | if txt.find("Player 2 start") != -1: 1026 | breakpoint 1027 | 1028 | var i = 0 1029 | while i < txt.length(): 1030 | var cur = txt[i] 1031 | 1032 | if cur == "\"": 1033 | var t = getStringOuter(txt.substr(i,-1)) 1034 | runningString += t 1035 | 1036 | i += t.length() 1037 | 1038 | 1039 | continue 1040 | 1041 | 1042 | if cur == ",": 1043 | runningArr.append(runningString) 1044 | runningString = "" 1045 | elif cur == "[": 1046 | var outer = getOuter(txt.substr(i,-1),"[","]") 1047 | runningArr.append(runningString + outer) 1048 | runningString = "" 1049 | i+=outer.length() 1050 | else: 1051 | runningString += cur 1052 | 1053 | i+=1 1054 | 1055 | return runningArr 1056 | pass 1057 | 1058 | 1059 | func getOuter(txt,open,close): 1060 | var count = 0 1061 | var runningTxt = "" 1062 | 1063 | for i in txt: 1064 | if i == open: 1065 | count += 1 1066 | 1067 | 1068 | if i == close: 1069 | count -=1 1070 | 1071 | 1072 | runningTxt += i 1073 | if count == 0: 1074 | return runningTxt 1075 | 1076 | return null 1077 | 1078 | 1079 | 1080 | func getStringOuterSimple(txt): 1081 | var runningTxt = "" 1082 | 1083 | for i in txt.length(): 1084 | var chara = txt[i] 1085 | 1086 | if chara == "\"": 1087 | return runningTxt 1088 | else: 1089 | runningTxt+=chara 1090 | 1091 | return runningTxt 1092 | 1093 | 1094 | func getStringOuter(txt): 1095 | var count = 0 1096 | var runningTxt = "" 1097 | txt = txt.substr(0,txt.find_last("\"")+1) 1098 | 1099 | for i in txt.length(): 1100 | var chara = txt[i] 1101 | if chara == "\"":#we have reached terminator 1102 | if i+1 >= txt.length(): 1103 | runningTxt += chara 1104 | return runningTxt 1105 | 1106 | var nextChar = txt[i+1] 1107 | 1108 | if nextChar != "," and nextChar != ":" and nextChar != "[":#if next char is not , keep string going 1109 | runningTxt += chara 1110 | else: 1111 | runningTxt += chara# 1112 | return runningTxt 1113 | 1114 | 1115 | else: 1116 | runningTxt += chara 1117 | return runningTxt 1118 | 1119 | 1120 | 1121 | func findCloserIndex(txt,opener,closer): 1122 | var count = 1 1123 | for i in txt.length(): 1124 | if txt[i] == closer: 1125 | count -= 1 1126 | 1127 | 1128 | elif txt[i] == opener: 1129 | count += 1 1130 | 1131 | 1132 | if count == 0: 1133 | return i 1134 | 1135 | return -1 1136 | 1137 | var a 1138 | var b 1139 | 1140 | var loadThread 1141 | func csvImport(path,headings=false,delimeter = ","): 1142 | blankSheet() 1143 | a = OS.get_system_time_msecs() 1144 | var file = File.new() 1145 | var cats = [] 1146 | var data = [] 1147 | file.open(path,File.READ) 1148 | 1149 | var i = 0 1150 | 1151 | data = CSVparse(file,delimeter) 1152 | 1153 | 1154 | var numRows : int = data.size() 1155 | var numCols : int = data[0].size() 1156 | 1157 | if headings==true: 1158 | numRows-=1 1159 | cats = data.pop_front() 1160 | 1161 | a = OS.get_system_time_msecs() 1162 | resize(numRows,numCols) 1163 | for idx in cats.size(): 1164 | colsTop[idx].get_child(0).setData({"type":"str","data":cats[idx]}) 1165 | 1166 | for idx in numRows: 1167 | rowsSide[idx].text = String(idx) 1168 | 1169 | #loadThread = Thread.new() 1170 | #loadThread.start(self,"threadAdd",[numRows,numCols,data]) 1171 | 1172 | threadAdd([numRows,numCols,data]) 1173 | #print(b-a) 1174 | undoStack.clear() 1175 | cells[0][0].grab_focus() 1176 | updateSizings() 1177 | 1178 | 1179 | 1180 | 1181 | func CSVparse(file,delimeter = ","): 1182 | var data = [] 1183 | var headingCount = 0 1184 | var input = getLineAlt(file) 1185 | while input!=null: 1186 | var line = input 1187 | var runningString = "" 1188 | var row = [] 1189 | 1190 | 1191 | if line == "": 1192 | input = getLineAlt(file) 1193 | continue 1194 | 1195 | var i = 0 1196 | 1197 | while i < line.length(): 1198 | var chara = line[i] 1199 | 1200 | if chara != delimeter: 1201 | if chara == "\"": 1202 | var outer = getStringOuterSimple(line.substr(i+1,-1)) 1203 | runningString += outer 1204 | i += outer.length()+2 1205 | 1206 | else: 1207 | runningString+=chara 1208 | i+=1 1209 | else: 1210 | row.append(runningString) 1211 | runningString = "" 1212 | i+=1 1213 | 1214 | if runningString != "": 1215 | row.append(runningString) 1216 | 1217 | if data.size() == 0: 1218 | headingCount = row.size() 1219 | 1220 | if row.size() < headingCount: 1221 | for j in headingCount - row.size(): 1222 | row.append("") 1223 | 1224 | data.append(row) 1225 | 1226 | input = getLineAlt(file) 1227 | 1228 | 1229 | 1230 | 1231 | return data 1232 | 1233 | 1234 | func getLineAlt(file:File): 1235 | var runningStr = "" 1236 | 1237 | while true: 1238 | if file.eof_reached() and runningStr != "": 1239 | return runningStr 1240 | elif file.eof_reached(): 1241 | return null 1242 | var c = char(file.get_8()) 1243 | 1244 | if c == "\n": 1245 | break 1246 | breakpoint 1247 | 1248 | runningStr += c 1249 | 1250 | return runningStr 1251 | 1252 | 1253 | func _on_Control_draw(): 1254 | updateSizings() 1255 | 1256 | func threadAdd(arr : Array) -> void: 1257 | resize(arr[0],arr[1]) 1258 | 1259 | var entries : Array = arr[2] 1260 | 1261 | for row in arr[0]: 1262 | for col in arr[1]: 1263 | cells[col][row].setData({"type":"str","data":entries[row][col]}) 1264 | 1265 | 1266 | b = OS.get_system_time_msecs() 1267 | 1268 | 1269 | func updateSizings(var delay = true): 1270 | 1271 | var biggestLast = 0 1272 | for i in cols[numCols-1].get_children(): 1273 | if i.rect_size.x > biggestLast: 1274 | biggestLast = i.rect_size.x 1275 | i.size_flags_horizontal = 0 1276 | 1277 | # for i in cols[numCols-1].get_children(): 1278 | # i.rect_size.x = biggestLast 1279 | # i.rect_min_size.x = biggestLast 1280 | 1281 | for i in colsTop.size(): 1282 | var topSize = colsTop[i].rect_size 1283 | var cellSize = cols[i].get_child(0).rect_size 1284 | top.rect_size.x = getWidthOfCells()# * 2 1285 | # 1286 | # 1287 | for c in colsTop: 1288 | c.get_child(0).expand_to_text_length = false 1289 | colsTop[i].rect_size = cols[i].get_child(0).rect_size 1290 | colsTop[i].rect_min_size = cols[i].get_child(0).rect_size 1291 | 1292 | 1293 | 1294 | var widestSideCell = 0 1295 | 1296 | for rowIdx in rowsSide.size(): 1297 | var x = cells[0][rowIdx].rect_size.y 1298 | rowsSide[rowIdx].rect_size.y = cells[0][rowIdx].rect_size.y 1299 | rowsSide[rowIdx].rect_min_size.y = cells[0][rowIdx].rect_size.y 1300 | 1301 | if rowsSide[rowIdx].rect_size.x > widestSideCell: 1302 | widestSideCell = rowsSide[rowIdx].rect_size.x 1303 | 1304 | if top != null: 1305 | top.get_parent().rect_position.x = initialTopX + widestSideCell - 62#+ widestSideCell#+ widestSideCell 1306 | #corner.rect_size.x = widestSideCell 1307 | get_parent().rect_position.x = widestSideCell+7 1308 | updateLastColWidth() 1309 | 1310 | 1311 | 1312 | func setNumRows(var num : int,changeSingal : bool = true): 1313 | var diff : int= num - numRows 1314 | 1315 | for i in diff: 1316 | addRow(changeSingal) 1317 | 1318 | 1319 | 1320 | 1321 | func setNumCols(var num : int,var changeSignal : bool = true) -> void: 1322 | var diff : int = num - numCols 1323 | 1324 | for i in diff: 1325 | addColumn("",changeSignal) 1326 | 1327 | 1328 | func save(): 1329 | var data = serializeData() 1330 | var file = File.new() 1331 | file.open("res://test.gsheet",File.WRITE) 1332 | file.store_line(to_json(var2str(data))) 1333 | 1334 | func loadFromFile(path:String) -> void: 1335 | 1336 | var filePathLabel = $"../../../Label" 1337 | filePathLabel.text = path 1338 | 1339 | var data = ResourceLoader.load(path).data 1340 | #var numR = data.size()-1 1341 | #var numC = -1#data[0].size() 1342 | 1343 | #for k in data.keys(): 1344 | # if k != "meta": 1345 | # numC = data[k].size() 1346 | # break 1347 | 1348 | 1349 | dataIntoSpreadsheet(data) 1350 | 1351 | func serializeData(): 1352 | var dict = {"meta":{"hasId":false,"rowOrder":[],"enumColumns":{},"enumColumnsPrefix":{}}} 1353 | var heading1 = colsTop[0].get_child(0).text.to_lower() 1354 | 1355 | if heading1 == "id": 1356 | dict["meta"]["hasId"] = true 1357 | for i in numRows: 1358 | dict["meta"]["rowOrder"].append(rowsSide[i].text) 1359 | 1360 | var colNames = [] 1361 | for x in numCols: 1362 | colNames.append(colsTop[x].get_child(0).text) 1363 | 1364 | dict["meta"]["colNames"] = colNames 1365 | dict["meta"]["splitSize"] = {} 1366 | dict["meta"]["sheetWidth"] = baseSplit.rect_size.x 1367 | 1368 | for idx in cols.size(): 1369 | var col = cols[idx] 1370 | if col.has_meta("enum"):#if column is enum 1371 | var enums = col.get_meta("enum") 1372 | var enumPrefix = col.get_meta("enumPrefix") 1373 | dict["meta"]["enumColumns"][idx] = enums 1374 | dict["meta"]["enumColumnsPrefix"][idx] = enumPrefix 1375 | 1376 | 1377 | dict["meta"]["splitSize"][idx] = col.get_parent().split_offset 1378 | 1379 | for y in numRows: 1380 | var rowDict = {} 1381 | for x in numCols: 1382 | var cell =cells[x][y] 1383 | 1384 | var columnName = colsTop[x].get_child(0).text 1385 | rowDict[columnName] = cell.value 1386 | 1387 | var row = rowsSide[y] 1388 | dict[rowsSide[y].text] = rowDict#if there a duplicate row keys a problem will occur here 1389 | 1390 | 1391 | needsSaving = true 1392 | return dict 1393 | 1394 | 1395 | 1396 | func dataIntoSpreadsheet(arr : Dictionary) -> void: 1397 | blankSheet() 1398 | needsSaving = false 1399 | 1400 | var meta : Dictionary = arr["meta"] 1401 | var cat : Array = meta["colNames"]#arr.pop_front()# getCategories(dict) 1402 | 1403 | 1404 | var numCat : int = max(5,cat.size()) 1405 | var numRow : int= max(5,arr.size()-1)#exclude meta 1406 | 1407 | 1408 | resize(numRow,numCat) 1409 | 1410 | var rowOrder : Array = meta["rowOrder"] 1411 | var enumCols : Dictionary = meta["enumColumns"] 1412 | var enumColsPrefix : Dictionary = meta["enumColumnsPrefix"] 1413 | 1414 | setNumCols(numCat,false) 1415 | setNumRows(numRow,false) 1416 | 1417 | 1418 | var a = rowsSide.size() 1419 | var b = rowOrder.size() 1420 | 1421 | 1422 | 1423 | var runningSplit = 0 1424 | 1425 | 1426 | for key in enumCols.keys(): 1427 | cols[key].set_meta("enum",enumCols[key]) 1428 | cols[key].set_meta("enumPrefix",enumColsPrefix[key]) 1429 | #breakpoint 1430 | 1431 | for i in cat.size(): 1432 | colsTop[i].get_child(0).text = String(cat[i]) 1433 | 1434 | for i in rowOrder.size(): 1435 | rowsSide[i].text = rowOrder[i] 1436 | 1437 | 1438 | 1439 | for x in cat.size():#for each category(column) 1440 | 1441 | for y in rowOrder.size(): 1442 | var cell : LineEdit = cells[x][y] 1443 | var t1 = cat[x] 1444 | var t2 = rowOrder[y] 1445 | var vari = arr[t2][t1] 1446 | 1447 | if typeof(vari) != TYPE_STRING: 1448 | vari = var2str(vari) 1449 | 1450 | var oldText = arr[t2][t1] 1451 | var newText 1452 | 1453 | if typeof(vari) == TYPE_STRING: 1454 | newText = vari 1455 | if vari.length() > 0: 1456 | if vari[0] == "\"" and vari[vari.length()-1] == "\"": 1457 | newText = vari.substr(1,vari.length()-2) 1458 | else: 1459 | newText = var2str(oldText) 1460 | 1461 | 1462 | 1463 | 1464 | var wasEnum = false 1465 | 1466 | var textAsEnum = "@DUMMY" 1467 | 1468 | 1469 | 1470 | if enumCols.has(x):#if an enum col 1471 | if newText != "": 1472 | for key in enumCols[x].keys():#for each key of enum 1473 | if enumCols[x][key] == oldText:#if enum for column x of geven key is equal to text 1474 | textAsEnum = enumColsPrefix[x] + "." + key 1475 | break 1476 | 1477 | cell.setData({"type":"enum","data":enumCols[x],"enumStr":textAsEnum}) 1478 | wasEnum = true 1479 | 1480 | 1481 | if !wasEnum: 1482 | cell.setData({"type":"str","data":newText}) 1483 | 1484 | baseSplit.update() 1485 | 1486 | if y == 0: 1487 | if meta["splitSize"].has(x): 1488 | cols[x].get_parent().set_split_offset( meta["splitSize"][x]) 1489 | baseSplit.rect_min_size.x += baseSplit.rect_size.x+meta["splitSize"][x] 1490 | cols[x].get_parent().update() 1491 | else: 1492 | cols[x].get_parent().set_split_offset(0)#temp 1493 | cols[x].get_parent().rect_min_size.x = 0 1494 | cols[x].get_parent().update() 1495 | 1496 | 1497 | if meta.has("sheetWidth"): 1498 | baseSplit.rect_min_size.x = meta["sheetWidth"] 1499 | 1500 | undoStack.clear() 1501 | updateSizingsFlag=true 1502 | serializeFlag = true 1503 | 1504 | 1505 | 1506 | func cellsDebug(): 1507 | for i in cells.size(): 1508 | for j in cells[i].size(): 1509 | #cells[i][j].text = String(i) + "," + String(j) 1510 | cells[i][j].text = String(cells[i][j].get_meta("cellId")) 1511 | 1512 | 1513 | #for i in side.get_child_count(): 1514 | # side.get_child(i).text = String(i) 1515 | # side.get_child(i).text = side.get_child( 1516 | 1517 | for idx in colsTop.size(): 1518 | var cell = colsTop[idx].get_child(0) 1519 | cell.text = var2str(colsTop[idx].get_child(0).get_meta("index"))#String(idx) 1520 | #if colsTop[idx].get_child(0).has_meta("enum"): 1521 | # cell.text = var2str(colsTop[idx].get_child(0).get_meta("enum")) 1522 | 1523 | for idx in rowsSide.size(): 1524 | var cell = rowsSide[idx] 1525 | cell.text = String(idx) + "j" 1526 | 1527 | func deleteCurRow(): 1528 | if curRow != -1: 1529 | cells[curCol][curRow].release_focus() 1530 | deleteRow(curRow,true,true) 1531 | 1532 | 1533 | func deleteCurCol(): 1534 | if curCol != -1: 1535 | deleteCol(curCol) 1536 | 1537 | 1538 | func deleteCol(cIdx,dictChange = true,addToRedoStack = true): 1539 | if numCols <=1: 1540 | return 1541 | 1542 | 1543 | cols[cIdx].queue_free() 1544 | 1545 | var hsplit = cols[cIdx].get_parent() 1546 | var childHsplit 1547 | var parentHsplit =hsplit.get_parent() 1548 | var actionDict = {"action":"addColumn","index":cIdx,"data":[],"name":"","colTitles":[]} 1549 | 1550 | for i in colsTop: 1551 | actionDict["colTitles"].append(i.get_child(0).text) 1552 | 1553 | #var infoArr = [] 1554 | 1555 | actionDict["name"] = colsTop[cIdx].get_child(0).text 1556 | #infoArr.append(infoDict) 1557 | 1558 | 1559 | for c in sheetGlobal.getChildOfClass(hsplit,"VBoxContainer").get_children(): 1560 | actionDict["data"].append(c.text) 1561 | 1562 | popHsplit(hsplit) 1563 | popHsplit(colsTop[cIdx].get_parent()) 1564 | 1565 | 1566 | 1567 | cols.remove(cIdx) 1568 | colsTop.remove(cIdx) 1569 | 1570 | if addToRedoStack: 1571 | undoStack.append(actionDict) 1572 | 1573 | 1574 | for i in cells[cIdx]: 1575 | i.queue_free() 1576 | cells.remove(cIdx) 1577 | 1578 | 1579 | 1580 | for i in range(cIdx,numCols-1): 1581 | var col = cols[i] 1582 | 1583 | colsTop[i].get_child(0).set_meta("index",i) 1584 | 1585 | if i != numCols-2: 1586 | var next = colsTop[i+1].get_child(0).text 1587 | if typeof(str2var(next)) == TYPE_INT: 1588 | colsTop[i].get_child(0).text = String(i) 1589 | else: 1590 | if typeof(str2var(colsTop[i].get_child(0).text)) == TYPE_INT: 1591 | colsTop[i].get_child(0).text = String(i) 1592 | 1593 | for c in col.get_children():#for each row in column 1594 | var oldIdx = c.get_meta("cellId") 1595 | c.set_meta("cellId",[oldIdx[0]-1,oldIdx[1]]) 1596 | 1597 | 1598 | 1599 | 1600 | numCols -=1 1601 | 1602 | 1603 | if numCols == 0: 1604 | return 1605 | 1606 | if curCol == numCols: 1607 | curCol -= 1 1608 | 1609 | curCol=curCol%numCols 1610 | cells[curCol%numCols][curRow].grab_focus() 1611 | 1612 | if dictChange: 1613 | serializeFlag = true 1614 | #emit_signal("dictChanged",serializeData()) 1615 | 1616 | 1617 | func deleteRow(rIdx,dictChange,storeUndo): 1618 | if numRows <= 1: 1619 | return 1620 | 1621 | if rIdx == curRow: 1622 | curRow = max(0,curRow-1) 1623 | elif curRow >= rIdx: 1624 | curRow = max(0,curRow-1) 1625 | 1626 | var actionDict = {"action":"addRow","index":rIdx,"data":[],"name":"","rowTitle":""} 1627 | 1628 | for cIdx in cols.size(): 1629 | var c = cols[cIdx] 1630 | actionDict["data"].append(c.get_child(rIdx).text) 1631 | 1632 | if storeUndo: 1633 | undoStack.append(actionDict) 1634 | 1635 | for cIdx in cols.size(): 1636 | var column :VBoxContainer = cols[cIdx] 1637 | column.get_child(rIdx).queue_free() 1638 | cells[cIdx][rIdx].queue_free() 1639 | cells[cIdx].remove(rIdx) 1640 | 1641 | for i in range(rIdx+1,numRows): 1642 | var oldIdx = column.get_child(i).get_meta("cellId") 1643 | var stro = String(i-1) 1644 | actionDict["rowTitle"] = rowsSide[i].text 1645 | column.get_child(i).set_meta("cellId",[oldIdx[0],oldIdx[1]-1]) 1646 | 1647 | 1648 | numRows -= 1 1649 | rowsSide[rIdx].queue_free() 1650 | rowsSide[rIdx].get_parent().remove_child(rowsSide[rIdx]) 1651 | 1652 | rowsSide.remove(rIdx) 1653 | 1654 | cols[0] 1655 | if numRows == 0: 1656 | return 1657 | 1658 | 1659 | if dictChange: 1660 | serializeFlag = true 1661 | 1662 | cells[curCol][curRow%numRows].grab_focus() 1663 | 1664 | 1665 | func popHsplit(hsplit): 1666 | 1667 | 1668 | var childHsplit 1669 | var parentHsplit =hsplit.get_parent() 1670 | 1671 | for i in hsplit.get_children(): 1672 | if i.get_class() == "HSplitContainer": 1673 | childHsplit = i 1674 | 1675 | 1676 | if childHsplit != null: 1677 | hsplit.remove_child(childHsplit) 1678 | parentHsplit.add_child(childHsplit) 1679 | 1680 | 1681 | if hsplit == baseSplit: 1682 | baseSplit = childHsplit 1683 | 1684 | hsplit.queue_free() 1685 | 1686 | 1687 | 1688 | 1689 | func resize(r : int,c : int) -> void: 1690 | if numCols > c: 1691 | var dif = numCols - c 1692 | 1693 | for i in dif: 1694 | deleteCol(numCols-1,false) 1695 | else: 1696 | setNumCols(c,false) 1697 | 1698 | if numRows > r: 1699 | var dif = numRows - r 1700 | 1701 | for i in dif: 1702 | deleteRow(numRows-1,false,false) 1703 | else: 1704 | setNumRows(r,false) 1705 | 1706 | 1707 | 1708 | func undo(): 1709 | 1710 | if undoStack.empty(): 1711 | return 1712 | 1713 | var actionDict = undoStack.pop_back() 1714 | var actionName = actionDict["action"] 1715 | 1716 | if actionName == "addColumn": 1717 | actionAddColumn(actionDict["name"],actionDict["index"],actionDict["data"],actionDict["colTitles"]) 1718 | if actionName == "addRow": 1719 | actionAddRow(actionDict["index"],actionDict["data"],actionDict["rowTitle"]) 1720 | if actionName == "moveColumnLeft": 1721 | moveColRight(actionDict["from"],false) 1722 | if actionName == "moveColumnRight": 1723 | moveColLeft(actionDict["from"],false) 1724 | if actionName == "deleteRow": 1725 | deleteRow(actionDict["id"],true,false) 1726 | if actionName == "deleteCol": 1727 | deleteCol(actionDict["id"],true,false) 1728 | 1729 | func actionAddColumn(colName,colIdx,oldData,colTitles): 1730 | if oldData.empty(): 1731 | breakpoint 1732 | 1733 | insertColumn(colName,colIdx) 1734 | for i in colTitles.size(): 1735 | colsTop[i].get_child(0).text = colTitles[i] 1736 | 1737 | for cIdx in oldData.size(): 1738 | cols[colIdx].get_child(cIdx).setData({"type":"str","data":oldData[cIdx]}) 1739 | 1740 | 1741 | 1742 | 1743 | func insertColumn(title,id,addToUndoStack=false): 1744 | addColumn(title,false,id,addToUndoStack) 1745 | 1746 | func actionAddRow(index,data,rowTitle): 1747 | addRow(false,index) 1748 | 1749 | for cIdx in cols.size(): 1750 | var c = cols[cIdx] 1751 | c.get_child(index).text = data[cIdx] 1752 | 1753 | 1754 | func filterComments(txt) -> String: 1755 | if txt.find("#") == -1: 1756 | return txt 1757 | 1758 | 1759 | var runningStr : String = "" 1760 | var lines : String = txt.split("\n") 1761 | 1762 | for line in lines: 1763 | runningStr += line.substr(0,line.find("#")) 1764 | 1765 | return runningStr 1766 | 1767 | func moveCurColRight(): 1768 | if curCol == numCols: 1769 | return 1770 | 1771 | moveColRight(curCol) 1772 | 1773 | 1774 | 1775 | func moveColRight(idx,addToUndo = true): 1776 | if idx < 0: 1777 | return 1778 | 1779 | if idx >= numCols-1: 1780 | return 1781 | 1782 | 1783 | 1784 | var tmpTxt = [] 1785 | 1786 | 1787 | if numCols == 1: 1788 | return 1789 | 1790 | 1791 | 1792 | var colNameA = colsTop[idx].get_child(0).text 1793 | var colNameB = colsTop[idx+1].get_child(0).text 1794 | var colsTitles = [] 1795 | 1796 | for i in colsTop: 1797 | colsTitles.append(i.get_child(0).text) 1798 | 1799 | for i in cols[idx+1].get_children():#temporaily store lables of col to be deleted 1800 | tmpTxt.append(i.text) 1801 | 1802 | 1803 | colsTitles[idx] = colNameB #swap titles 1804 | colsTitles[idx+1] = colNameA #swap titles 1805 | 1806 | deleteCol(idx+1,false,false)# delete right column 1807 | 1808 | actionAddColumn(colNameA,idx,tmpTxt,colsTitles)#add it back again 1809 | if addToUndo: 1810 | undoStack.append({"action":"moveColumnLeft","from":curCol}) 1811 | serializeFlag = true 1812 | 1813 | 1814 | func moveColLeft(idx,addToUndo=true): 1815 | if idx <= 0: 1816 | return 1817 | 1818 | 1819 | var tmpTxt = [] 1820 | 1821 | 1822 | if numCols == 1: 1823 | return 1824 | 1825 | 1826 | 1827 | var colNameA = colsTop[idx-1].get_child(0).text 1828 | var colNameB = colsTop[idx].get_child(0).text 1829 | var colsTitles = [] 1830 | 1831 | for i in colsTop: 1832 | colsTitles.append(i.get_child(0).text) 1833 | 1834 | for i in cols[idx].get_children():#temporaily store lables of col to be deleted 1835 | tmpTxt.append(i.text) 1836 | 1837 | 1838 | colsTitles[idx-1] = colNameB #swap titles 1839 | colsTitles[idx] = colNameA #swap titles 1840 | 1841 | deleteCol(idx,false,false)# delete right column 1842 | 1843 | actionAddColumn(colNameA,idx-1,tmpTxt,colsTitles)#add it back again 1844 | 1845 | if addToUndo: 1846 | undoStack.append({"action":"moveColumnRight","from":curCol}) 1847 | serializeFlag = true 1848 | 1849 | func blankSheet(): 1850 | 1851 | 1852 | serializeFlag = false 1853 | 1854 | for colIdx in cols.size(): 1855 | for m in cols[colIdx].get_meta_list(): 1856 | cols[colIdx].set_meta(m,null) 1857 | 1858 | for cell in cells[colIdx]: 1859 | cell.text = "" 1860 | cell.deactivateOptionMode() 1861 | cell.rect_size.y = 0#24 1862 | cell.rect_min_size.y = 0 1863 | 1864 | 1865 | cols[colIdx].get_parent().rect_min_size.x = 0 1866 | cols[colIdx].get_parent().split_offset = 0 1867 | 1868 | cols[colIdx].rect_min_size.x = 0 1869 | colsTop[colIdx].rect_min_size.x = 0 1870 | 1871 | colsTop[colIdx].get_parent().split_offset = 0 1872 | colsTop[colIdx].get_parent().rect_min_size.x = 0 1873 | 1874 | 1875 | for i in rowsSide.size(): 1876 | rowsSide[i].text = String(i) 1877 | 1878 | for i in colsTop.size(): 1879 | colsTop[i].get_child(0).text = String(i) 1880 | 1881 | for y in numRows: 1882 | for x in numCols: 1883 | var cell =cells[x][y] 1884 | cell.text = "" 1885 | cell.value = "" 1886 | 1887 | undoStack.clear() 1888 | 1889 | 1890 | func getWidestColumn(cIdx) -> int: 1891 | var widest = -INF 1892 | 1893 | var lastCol = cols[cIdx].get_children() 1894 | for i in lastCol: 1895 | if i.rect_size.x > widest: 1896 | widest = i.rect_size.x 1897 | 1898 | return widest 1899 | 1900 | func setColumnWidth(cIdx,width): 1901 | var lastCol = cols[cIdx].get_children() 1902 | for i in lastCol: 1903 | i.rect_min_size.x = width 1904 | 1905 | func updateLastColWidth(): 1906 | var w = getWidestColumn(cols.size()-1) 1907 | setColumnWidth(cols.size()-1,w) 1908 | 1909 | func grabFocusIfTextFound(text): 1910 | for x in cells: 1911 | for y in x: 1912 | var txt = y.text 1913 | if txt.find(text) != -1: 1914 | y.grab_focus() 1915 | return true 1916 | 1917 | 1918 | return false 1919 | 1920 | func sideFocusCellFocus(): 1921 | var owner = get_focus_owner() 1922 | 1923 | if !owner.has_meta("index"): 1924 | return 1925 | 1926 | curCol = 0 1927 | curRow = owner.get_meta("index") 1928 | 1929 | func getColData(var colIdx): 1930 | 1931 | var ret : Array = [] 1932 | 1933 | for i in cols[colIdx].get_children(): 1934 | ret.append(i.value) 1935 | 1936 | return ret 1937 | -------------------------------------------------------------------------------- /addons/gSheet/scenes/spreadsheet/full/scenes/bottomBar/bottomBar.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=27 format=2] 2 | 3 | [ext_resource path="res://addons/gSheet/scenes/spreadsheet/full/scenes/bottomBar/menuButton.gd" type="Script" id=1] 4 | [ext_resource path="res://addons/gSheet/scenes/spreadsheet/full/scenes/bottomBar/bottomBar.gd" type="Script" id=2] 5 | [ext_resource path="res://addons/gSheet/scenes/spreadsheet/full/scenes/bottomBar/MenuButtonCol.gd" type="Script" id=3] 6 | [ext_resource path="res://addons/gSheet/scenes/spreadsheet/full/scenes/bottomBar/MenuButtonRow.gd" type="Script" id=4] 7 | [ext_resource path="res://addons/gSheet/scenes/assets/arrow-square-right.png" type="Texture" id=5] 8 | [ext_resource path="res://addons/gSheet/scenes/assets/close-rectangle.png" type="Texture" id=6] 9 | [ext_resource path="res://addons/gSheet/scenes/assets/arrow-square-up.png" type="Texture" id=7] 10 | [ext_resource path="res://addons/gSheet/highlightHover.gd" type="Script" id=8] 11 | [ext_resource path="res://addons/gSheet/scenes/assets/arrow-square-left .png" type="Texture" id=9] 12 | [ext_resource path="res://addons/gSheet/scenes/assets/search.png" type="Texture" id=10] 13 | [ext_resource path="res://addons/gSheet/scenes/assets/arrow-square-down.png" type="Texture" id=11] 14 | [ext_resource path="res://addons/gSheet/scenes/spreadsheet/full/scenes/bottomBar/MoveMenu.gd" type="Script" id=12] 15 | 16 | [sub_resource type="Image" id=1] 17 | data = { 18 | "data": PoolByteArray( 47, 47, 47, 0, 47, 47, 47, 29, 51, 51, 51, 172, 51, 51, 51, 242, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 242, 51, 51, 51, 175, 48, 48, 48, 39, 48, 48, 48, 0, 47, 47, 47, 29, 51, 51, 51, 237, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 238, 47, 47, 47, 29, 51, 51, 51, 172, 51, 51, 51, 255, 51, 51, 51, 180, 49, 49, 49, 27, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 53, 53, 53, 28, 51, 51, 51, 182, 51, 51, 51, 255, 51, 51, 51, 170, 51, 51, 51, 242, 51, 51, 51, 255, 53, 53, 53, 28, 49, 49, 49, 0, 49, 49, 49, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 53, 53, 53, 0, 53, 53, 53, 0, 47, 47, 47, 29, 51, 51, 51, 255, 51, 51, 51, 241, 51, 51, 51, 255, 51, 51, 51, 255, 53, 53, 53, 0, 53, 53, 53, 0, 49, 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 0, 51, 51, 51, 0, 51, 51, 51, 0, 49, 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 0, 53, 53, 53, 0, 53, 53, 53, 0, 47, 47, 47, 0, 47, 47, 47, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 53, 53, 53, 0, 56, 56, 56, 0, 56, 56, 56, 0, 49, 49, 49, 0, 49, 49, 49, 22, 51, 51, 51, 204, 51, 51, 51, 203, 49, 49, 49, 22, 49, 49, 49, 0, 51, 51, 51, 0, 51, 51, 51, 0, 47, 47, 47, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 56, 56, 56, 0, 56, 56, 56, 0, 56, 56, 56, 0, 56, 56, 56, 21, 51, 51, 51, 210, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 215, 51, 51, 51, 25, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 49, 49, 49, 0, 56, 56, 56, 0, 56, 56, 56, 21, 51, 51, 51, 210, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 215, 51, 51, 51, 25, 51, 51, 51, 0, 49, 49, 49, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 49, 49, 49, 0, 49, 49, 49, 22, 51, 51, 51, 211, 51, 51, 51, 255, 51, 51, 51, 211, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 211, 51, 51, 51, 255, 51, 51, 51, 211, 49, 49, 49, 22, 49, 49, 49, 0, 49, 49, 49, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 52, 52, 52, 0, 51, 51, 51, 12, 51, 51, 51, 211, 51, 51, 51, 255, 51, 51, 51, 211, 49, 49, 49, 22, 51, 51, 51, 255, 51, 51, 51, 255, 49, 49, 49, 22, 51, 51, 51, 211, 51, 51, 51, 255, 51, 51, 51, 211, 51, 51, 51, 12, 53, 53, 53, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 52, 52, 52, 0, 52, 52, 52, 43, 51, 51, 51, 254, 51, 51, 51, 211, 49, 49, 49, 22, 49, 49, 49, 0, 51, 51, 51, 255, 51, 51, 51, 255, 49, 49, 49, 0, 49, 49, 49, 22, 51, 51, 51, 211, 51, 51, 51, 254, 53, 53, 53, 41, 53, 53, 53, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 52, 52, 52, 0, 52, 52, 52, 0, 50, 50, 50, 42, 51, 51, 51, 12, 49, 49, 49, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 49, 49, 49, 0, 51, 51, 51, 12, 50, 50, 50, 42, 53, 53, 53, 0, 53, 53, 53, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 0, 49, 49, 49, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 49, 49, 49, 0, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 53, 53, 53, 0, 50, 50, 50, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 191, 52, 52, 52, 191, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 50, 50, 50, 0, 47, 47, 47, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 53, 53, 53, 0, 53, 53, 53, 0, 53, 53, 53, 0, 51, 51, 51, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 51, 51, 51, 0, 47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 242, 51, 51, 51, 255, 53, 53, 53, 28, 53, 53, 53, 0, 53, 53, 53, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 52, 52, 52, 0, 52, 52, 52, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 29, 51, 51, 51, 255, 51, 51, 51, 240, 51, 51, 51, 175, 51, 51, 51, 255, 51, 51, 51, 182, 53, 53, 53, 28, 53, 53, 53, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 47, 47, 47, 0, 47, 47, 47, 29, 51, 51, 51, 183, 51, 51, 51, 255, 50, 50, 50, 169, 48, 48, 48, 39, 51, 51, 51, 238, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 236, 53, 53, 53, 28, 48, 48, 48, 0, 47, 47, 47, 29, 51, 51, 51, 170, 51, 51, 51, 241, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 241, 50, 50, 50, 169, 53, 53, 53, 28, 53, 53, 53, 0 ), 19 | "format": "RGBA8", 20 | "height": 20, 21 | "mipmaps": false, 22 | "width": 20 23 | } 24 | 25 | [sub_resource type="ImageTexture" id=2] 26 | image = SubResource( 1 ) 27 | size = Vector2( 20, 20 ) 28 | 29 | [sub_resource type="Image" id=3] 30 | data = { 31 | "data": PoolByteArray( 47, 47, 47, 0, 47, 47, 47, 29, 51, 51, 51, 172, 51, 51, 51, 242, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 242, 51, 51, 51, 175, 48, 48, 48, 39, 48, 48, 48, 0, 47, 47, 47, 29, 51, 51, 51, 237, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 238, 47, 47, 47, 29, 51, 51, 51, 172, 51, 51, 51, 255, 51, 51, 51, 180, 49, 49, 49, 27, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 53, 53, 53, 28, 51, 51, 51, 182, 51, 51, 51, 255, 51, 51, 51, 170, 51, 51, 51, 242, 51, 51, 51, 255, 53, 53, 53, 28, 49, 49, 49, 0, 49, 49, 49, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 53, 53, 53, 0, 53, 53, 53, 0, 47, 47, 47, 29, 51, 51, 51, 255, 51, 51, 51, 241, 51, 51, 51, 255, 51, 51, 51, 255, 53, 53, 53, 0, 53, 53, 53, 0, 49, 49, 49, 0, 49, 49, 49, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 53, 53, 53, 0, 53, 53, 53, 0, 47, 47, 47, 0, 47, 47, 47, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 53, 53, 53, 0, 52, 52, 52, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 193, 51, 51, 51, 193, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 53, 53, 53, 0, 47, 47, 47, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 53, 53, 53, 0, 53, 53, 53, 0, 53, 53, 53, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 53, 53, 53, 0, 53, 53, 53, 0, 53, 53, 53, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 43, 52, 52, 52, 13, 49, 49, 49, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 49, 49, 49, 0, 53, 53, 53, 12, 53, 53, 53, 33, 53, 53, 53, 0, 49, 49, 49, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 52, 52, 52, 0, 52, 52, 52, 43, 51, 51, 51, 254, 51, 51, 51, 211, 49, 49, 49, 22, 49, 49, 49, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 49, 49, 49, 22, 51, 51, 51, 211, 51, 51, 51, 252, 49, 49, 49, 32, 49, 49, 49, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 52, 52, 52, 0, 52, 52, 52, 12, 51, 51, 51, 211, 51, 51, 51, 255, 51, 51, 51, 211, 49, 49, 49, 22, 51, 51, 51, 255, 51, 51, 51, 255, 49, 49, 49, 22, 51, 51, 51, 211, 51, 51, 51, 255, 51, 51, 51, 211, 49, 49, 49, 11, 49, 49, 49, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 49, 49, 49, 0, 49, 49, 49, 22, 51, 51, 51, 211, 51, 51, 51, 255, 51, 51, 51, 211, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 211, 51, 51, 51, 255, 51, 51, 51, 211, 49, 49, 49, 22, 49, 49, 49, 0, 49, 49, 49, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 49, 49, 49, 0, 49, 49, 49, 0, 56, 56, 56, 21, 51, 51, 51, 210, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 215, 47, 47, 47, 24, 49, 49, 49, 0, 49, 49, 49, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 49, 49, 49, 0, 56, 56, 56, 0, 56, 56, 56, 0, 56, 56, 56, 21, 51, 51, 51, 210, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 215, 47, 47, 47, 24, 47, 47, 47, 0, 47, 47, 47, 0, 49, 49, 49, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 56, 56, 56, 0, 56, 56, 56, 0, 56, 56, 56, 0, 56, 56, 56, 0, 49, 49, 49, 22, 51, 51, 51, 203, 51, 51, 51, 203, 49, 49, 49, 22, 47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 53, 53, 53, 0, 53, 53, 53, 0, 56, 56, 56, 0, 56, 56, 56, 0, 49, 49, 49, 0, 49, 49, 49, 0, 51, 51, 51, 0, 51, 51, 51, 0, 49, 49, 49, 0, 49, 49, 49, 0, 47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 242, 51, 51, 51, 255, 53, 53, 53, 28, 53, 53, 53, 0, 53, 53, 53, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 49, 49, 49, 0, 51, 51, 51, 0, 51, 51, 51, 0, 49, 49, 49, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 29, 51, 51, 51, 255, 51, 51, 51, 240, 51, 51, 51, 175, 51, 51, 51, 255, 51, 51, 51, 182, 53, 53, 53, 28, 53, 53, 53, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 47, 47, 47, 0, 47, 47, 47, 29, 51, 51, 51, 183, 51, 51, 51, 255, 50, 50, 50, 169, 48, 48, 48, 39, 51, 51, 51, 238, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 236, 53, 53, 53, 28, 48, 48, 48, 0, 47, 47, 47, 29, 51, 51, 51, 170, 51, 51, 51, 241, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 241, 50, 50, 50, 169, 53, 53, 53, 28, 53, 53, 53, 0 ), 32 | "format": "RGBA8", 33 | "height": 20, 34 | "mipmaps": false, 35 | "width": 20 36 | } 37 | 38 | [sub_resource type="ImageTexture" id=4] 39 | image = SubResource( 3 ) 40 | size = Vector2( 20, 20 ) 41 | 42 | [sub_resource type="Image" id=5] 43 | data = { 44 | "data": PoolByteArray( 47, 0, 0, 0, 47, 0, 0, 29, 51, 0, 0, 172, 51, 0, 0, 242, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 242, 51, 0, 0, 175, 48, 0, 0, 39, 48, 0, 0, 0, 47, 0, 0, 29, 51, 0, 0, 237, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 238, 47, 0, 0, 29, 51, 0, 0, 172, 51, 0, 0, 255, 51, 0, 0, 180, 49, 0, 0, 27, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 53, 0, 0, 28, 51, 0, 0, 182, 51, 0, 0, 255, 51, 0, 0, 170, 51, 0, 0, 242, 51, 0, 0, 255, 53, 0, 0, 28, 49, 0, 0, 0, 49, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 53, 0, 0, 0, 53, 0, 0, 0, 47, 0, 0, 29, 51, 0, 0, 255, 51, 0, 0, 241, 51, 0, 0, 255, 51, 0, 0, 255, 53, 0, 0, 0, 53, 0, 0, 0, 53, 0, 0, 0, 53, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 0, 51, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 47, 0, 0, 0, 47, 0, 0, 0, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 0, 51, 0, 0, 0, 53, 0, 0, 0, 53, 0, 0, 23, 51, 0, 0, 122, 51, 0, 0, 20, 51, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 21, 51, 0, 0, 122, 49, 0, 0, 22, 49, 0, 0, 0, 49, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 122, 51, 0, 0, 255, 51, 0, 0, 211, 49, 0, 0, 22, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 22, 51, 0, 0, 211, 51, 0, 0, 255, 50, 0, 0, 119, 50, 0, 0, 0, 50, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 0, 51, 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 21, 51, 0, 0, 211, 51, 0, 0, 255, 51, 0, 0, 211, 49, 0, 0, 22, 49, 0, 0, 22, 51, 0, 0, 211, 51, 0, 0, 255, 51, 0, 0, 211, 56, 0, 0, 21, 56, 0, 0, 0, 56, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 0, 51, 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 0, 49, 0, 0, 22, 51, 0, 0, 211, 51, 0, 0, 255, 51, 0, 0, 211, 51, 0, 0, 211, 51, 0, 0, 255, 51, 0, 0, 211, 49, 0, 0, 22, 56, 0, 0, 0, 56, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 0, 51, 0, 0, 0, 56, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 56, 0, 0, 21, 51, 0, 0, 210, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 215, 47, 0, 0, 24, 49, 0, 0, 0, 49, 0, 0, 0, 56, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 0, 51, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 21, 51, 0, 0, 210, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 215, 51, 0, 0, 25, 51, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 0, 51, 0, 0, 0, 56, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 22, 51, 0, 0, 211, 51, 0, 0, 255, 51, 0, 0, 211, 51, 0, 0, 211, 51, 0, 0, 255, 51, 0, 0, 211, 49, 0, 0, 22, 49, 0, 0, 0, 56, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 0, 51, 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 21, 51, 0, 0, 211, 51, 0, 0, 255, 51, 0, 0, 211, 49, 0, 0, 22, 49, 0, 0, 22, 51, 0, 0, 211, 51, 0, 0, 255, 51, 0, 0, 211, 56, 0, 0, 21, 56, 0, 0, 0, 56, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 122, 51, 0, 0, 255, 51, 0, 0, 211, 49, 0, 0, 22, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 22, 51, 0, 0, 211, 51, 0, 0, 255, 51, 0, 0, 122, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 0, 51, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 22, 51, 0, 0, 120, 51, 0, 0, 20, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 51, 0, 0, 20, 51, 0, 0, 122, 51, 0, 0, 25, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 0, 53, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 47, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 242, 51, 0, 0, 255, 53, 0, 0, 28, 53, 0, 0, 0, 53, 0, 0, 0, 49, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 47, 0, 0, 0, 47, 0, 0, 0, 47, 0, 0, 29, 51, 0, 0, 255, 51, 0, 0, 240, 51, 0, 0, 175, 51, 0, 0, 255, 51, 0, 0, 182, 53, 0, 0, 28, 53, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 47, 0, 0, 0, 47, 0, 0, 29, 51, 0, 0, 183, 51, 0, 0, 255, 50, 0, 0, 169, 48, 0, 0, 39, 51, 0, 0, 238, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 236, 53, 0, 0, 28, 48, 0, 0, 0, 47, 0, 0, 29, 51, 0, 0, 170, 51, 0, 0, 241, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 241, 50, 0, 0, 169, 53, 0, 0, 28, 53, 0, 0, 0 ), 45 | "format": "RGBA8", 46 | "height": 20, 47 | "mipmaps": false, 48 | "width": 20 49 | } 50 | 51 | [sub_resource type="ImageTexture" id=6] 52 | image = SubResource( 5 ) 53 | size = Vector2( 20, 20 ) 54 | 55 | [sub_resource type="Image" id=7] 56 | data = { 57 | "data": PoolByteArray( 47, 47, 47, 0, 47, 47, 47, 29, 51, 51, 51, 172, 51, 51, 51, 242, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 242, 51, 51, 51, 175, 48, 48, 48, 39, 48, 48, 48, 0, 47, 47, 47, 29, 51, 51, 51, 237, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 238, 47, 47, 47, 29, 51, 51, 51, 172, 51, 51, 51, 255, 51, 51, 51, 180, 49, 49, 49, 27, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 53, 53, 53, 28, 51, 51, 51, 182, 51, 51, 51, 255, 51, 51, 51, 170, 51, 51, 51, 242, 51, 51, 51, 255, 53, 53, 53, 28, 49, 49, 49, 0, 49, 49, 49, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 53, 53, 53, 0, 53, 53, 53, 0, 47, 47, 47, 29, 51, 51, 51, 255, 51, 51, 51, 241, 51, 51, 51, 255, 51, 51, 51, 255, 53, 53, 53, 0, 53, 53, 53, 0, 49, 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 0, 52, 52, 52, 13, 52, 52, 52, 43, 52, 52, 52, 0, 50, 50, 50, 0, 50, 50, 50, 0, 53, 53, 53, 0, 53, 53, 53, 0, 47, 47, 47, 0, 47, 47, 47, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 53, 53, 53, 0, 49, 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 22, 51, 51, 51, 211, 51, 51, 51, 254, 50, 50, 50, 42, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 0, 47, 47, 47, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 56, 56, 56, 0, 56, 56, 56, 0, 49, 49, 49, 0, 49, 49, 49, 22, 51, 51, 51, 211, 51, 51, 51, 255, 51, 51, 51, 211, 50, 50, 50, 12, 50, 50, 50, 0, 50, 50, 50, 0, 52, 52, 52, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 56, 56, 56, 0, 56, 56, 56, 0, 56, 56, 56, 21, 51, 51, 51, 210, 51, 51, 51, 255, 51, 51, 51, 215, 47, 47, 47, 24, 47, 47, 47, 0, 47, 47, 47, 0, 51, 51, 51, 0, 52, 52, 52, 0, 52, 52, 52, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 56, 56, 56, 0, 56, 56, 56, 21, 51, 51, 51, 210, 51, 51, 51, 255, 51, 51, 51, 215, 47, 47, 47, 24, 47, 47, 47, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 52, 52, 52, 0, 52, 52, 52, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 204, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 52, 52, 52, 191, 52, 52, 52, 0, 52, 52, 52, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 204, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 52, 52, 52, 191, 52, 52, 52, 0, 52, 52, 52, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 56, 56, 56, 0, 56, 56, 56, 21, 51, 51, 51, 210, 51, 51, 51, 255, 51, 51, 51, 215, 51, 51, 51, 25, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 52, 52, 52, 0, 52, 52, 52, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 56, 56, 56, 0, 56, 56, 56, 0, 56, 56, 56, 21, 51, 51, 51, 210, 51, 51, 51, 255, 51, 51, 51, 215, 51, 51, 51, 25, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 52, 52, 52, 0, 52, 52, 52, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 56, 56, 56, 0, 56, 56, 56, 0, 56, 56, 56, 0, 49, 49, 49, 22, 51, 51, 51, 211, 51, 51, 51, 255, 51, 51, 51, 211, 51, 51, 51, 12, 54, 54, 54, 0, 54, 54, 54, 0, 52, 52, 52, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 56, 56, 56, 0, 56, 56, 56, 0, 49, 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 22, 51, 51, 51, 211, 51, 51, 51, 251, 54, 54, 54, 31, 54, 54, 54, 0, 54, 54, 54, 0, 54, 54, 54, 0, 47, 47, 47, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 53, 53, 53, 0, 53, 53, 53, 0, 49, 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 0, 51, 51, 51, 12, 54, 54, 54, 31, 54, 54, 54, 0, 54, 54, 54, 0, 54, 54, 54, 0, 47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 242, 51, 51, 51, 255, 53, 53, 53, 28, 53, 53, 53, 0, 53, 53, 53, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 49, 49, 49, 0, 54, 54, 54, 0, 54, 54, 54, 0, 54, 54, 54, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 29, 51, 51, 51, 255, 51, 51, 51, 240, 51, 51, 51, 175, 51, 51, 51, 255, 51, 51, 51, 182, 53, 53, 53, 28, 53, 53, 53, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 47, 47, 47, 0, 47, 47, 47, 29, 51, 51, 51, 183, 51, 51, 51, 255, 50, 50, 50, 169, 48, 48, 48, 39, 51, 51, 51, 238, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 236, 53, 53, 53, 28, 48, 48, 48, 0, 47, 47, 47, 29, 51, 51, 51, 170, 51, 51, 51, 241, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 241, 50, 50, 50, 169, 53, 53, 53, 28, 53, 53, 53, 0 ), 58 | "format": "RGBA8", 59 | "height": 20, 60 | "mipmaps": false, 61 | "width": 20 62 | } 63 | 64 | [sub_resource type="ImageTexture" id=8] 65 | image = SubResource( 7 ) 66 | size = Vector2( 20, 20 ) 67 | 68 | [sub_resource type="Image" id=9] 69 | data = { 70 | "data": PoolByteArray( 47, 47, 47, 0, 47, 47, 47, 29, 51, 51, 51, 172, 51, 51, 51, 242, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 242, 51, 51, 51, 175, 48, 48, 48, 39, 48, 48, 48, 0, 47, 47, 47, 29, 51, 51, 51, 237, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 238, 47, 47, 47, 29, 51, 51, 51, 172, 51, 51, 51, 255, 51, 51, 51, 180, 49, 49, 49, 27, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 53, 53, 53, 28, 51, 51, 51, 182, 51, 51, 51, 255, 51, 51, 51, 170, 51, 51, 51, 242, 51, 51, 51, 255, 53, 53, 53, 28, 49, 49, 49, 0, 49, 49, 49, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 53, 53, 53, 0, 53, 53, 53, 0, 53, 53, 53, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 53, 53, 53, 0, 53, 53, 53, 0, 47, 47, 47, 29, 51, 51, 51, 255, 51, 51, 51, 241, 51, 51, 51, 255, 51, 51, 51, 255, 53, 53, 53, 0, 53, 53, 53, 0, 49, 49, 49, 0, 49, 49, 49, 0, 48, 48, 48, 0, 48, 48, 48, 0, 53, 53, 53, 0, 53, 53, 53, 33, 53, 53, 53, 12, 49, 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 0, 53, 53, 53, 0, 53, 53, 53, 0, 47, 47, 47, 0, 47, 47, 47, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 53, 53, 53, 0, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 34, 51, 51, 51, 252, 51, 51, 51, 211, 49, 49, 49, 22, 49, 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 0, 47, 47, 47, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 12, 51, 51, 51, 211, 51, 51, 51, 255, 51, 51, 51, 211, 49, 49, 49, 22, 49, 49, 49, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 56, 56, 56, 0, 56, 56, 56, 0, 56, 56, 56, 21, 51, 51, 51, 210, 51, 51, 51, 255, 51, 51, 51, 215, 51, 51, 51, 25, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 56, 56, 56, 0, 56, 56, 56, 21, 51, 51, 51, 210, 51, 51, 51, 255, 51, 51, 51, 215, 51, 51, 51, 25, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 193, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 203, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 193, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 203, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 56, 56, 56, 21, 51, 51, 51, 210, 51, 51, 51, 255, 51, 51, 51, 215, 47, 47, 47, 24, 47, 47, 47, 0, 47, 47, 47, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 56, 56, 56, 0, 56, 56, 56, 21, 51, 51, 51, 210, 51, 51, 51, 255, 51, 51, 51, 215, 47, 47, 47, 24, 47, 47, 47, 0, 47, 47, 47, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 52, 52, 52, 0, 52, 52, 52, 0, 51, 51, 51, 12, 51, 51, 51, 211, 51, 51, 51, 255, 51, 51, 51, 211, 49, 49, 49, 22, 47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 51, 51, 51, 0, 53, 53, 53, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 43, 51, 51, 51, 254, 51, 51, 51, 211, 49, 49, 49, 22, 49, 49, 49, 0, 49, 49, 49, 0, 47, 47, 47, 0, 47, 47, 47, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 0, 53, 53, 53, 0, 53, 53, 53, 0, 53, 53, 53, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 50, 50, 50, 42, 51, 51, 51, 12, 49, 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 0, 47, 47, 47, 0, 47, 47, 47, 0, 51, 51, 51, 0, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 242, 51, 51, 51, 255, 53, 53, 53, 28, 53, 53, 53, 0, 53, 53, 53, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 0, 49, 49, 49, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 29, 51, 51, 51, 255, 51, 51, 51, 240, 51, 51, 51, 175, 51, 51, 51, 255, 51, 51, 51, 182, 53, 53, 53, 28, 53, 53, 53, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 47, 47, 47, 0, 47, 47, 47, 29, 51, 51, 51, 183, 51, 51, 51, 255, 50, 50, 50, 169, 48, 48, 48, 39, 51, 51, 51, 238, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 236, 53, 53, 53, 28, 48, 48, 48, 0, 47, 47, 47, 29, 51, 51, 51, 170, 51, 51, 51, 241, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 241, 50, 50, 50, 169, 53, 53, 53, 28, 53, 53, 53, 0 ), 71 | "format": "RGBA8", 72 | "height": 20, 73 | "mipmaps": false, 74 | "width": 20 75 | } 76 | 77 | [sub_resource type="ImageTexture" id=10] 78 | image = SubResource( 9 ) 79 | size = Vector2( 20, 20 ) 80 | 81 | [sub_resource type="Image" id=11] 82 | data = { 83 | "data": PoolByteArray( 47, 0, 0, 0, 47, 0, 0, 29, 51, 0, 0, 172, 51, 0, 0, 242, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 242, 51, 0, 0, 175, 48, 0, 0, 39, 48, 0, 0, 0, 47, 0, 0, 29, 51, 0, 0, 237, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 238, 47, 0, 0, 29, 51, 0, 0, 172, 51, 0, 0, 255, 51, 0, 0, 180, 49, 0, 0, 27, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 53, 0, 0, 28, 51, 0, 0, 182, 51, 0, 0, 255, 51, 0, 0, 170, 51, 0, 0, 242, 51, 0, 0, 255, 53, 0, 0, 28, 49, 0, 0, 0, 49, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 53, 0, 0, 0, 53, 0, 0, 0, 47, 0, 0, 29, 51, 0, 0, 255, 51, 0, 0, 241, 51, 0, 0, 255, 51, 0, 0, 255, 53, 0, 0, 0, 53, 0, 0, 0, 53, 0, 0, 0, 53, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 0, 51, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 47, 0, 0, 0, 47, 0, 0, 0, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 0, 51, 0, 0, 0, 53, 0, 0, 0, 53, 0, 0, 23, 51, 0, 0, 122, 51, 0, 0, 20, 51, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 21, 51, 0, 0, 122, 49, 0, 0, 22, 49, 0, 0, 0, 49, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 122, 51, 0, 0, 255, 51, 0, 0, 211, 49, 0, 0, 22, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 22, 51, 0, 0, 211, 51, 0, 0, 255, 50, 0, 0, 119, 50, 0, 0, 0, 50, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 0, 51, 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 21, 51, 0, 0, 211, 51, 0, 0, 255, 51, 0, 0, 211, 49, 0, 0, 22, 49, 0, 0, 22, 51, 0, 0, 211, 51, 0, 0, 255, 51, 0, 0, 211, 56, 0, 0, 21, 56, 0, 0, 0, 56, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 0, 51, 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 0, 49, 0, 0, 22, 51, 0, 0, 211, 51, 0, 0, 255, 51, 0, 0, 211, 51, 0, 0, 211, 51, 0, 0, 255, 51, 0, 0, 211, 49, 0, 0, 22, 56, 0, 0, 0, 56, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 0, 51, 0, 0, 0, 56, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 56, 0, 0, 21, 51, 0, 0, 210, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 215, 47, 0, 0, 24, 49, 0, 0, 0, 49, 0, 0, 0, 56, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 0, 51, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 21, 51, 0, 0, 210, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 215, 51, 0, 0, 25, 51, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 0, 51, 0, 0, 0, 56, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 22, 51, 0, 0, 211, 51, 0, 0, 255, 51, 0, 0, 211, 51, 0, 0, 211, 51, 0, 0, 255, 51, 0, 0, 211, 49, 0, 0, 22, 49, 0, 0, 0, 56, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 0, 51, 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 21, 51, 0, 0, 211, 51, 0, 0, 255, 51, 0, 0, 211, 49, 0, 0, 22, 49, 0, 0, 22, 51, 0, 0, 211, 51, 0, 0, 255, 51, 0, 0, 211, 56, 0, 0, 21, 56, 0, 0, 0, 56, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 122, 51, 0, 0, 255, 51, 0, 0, 211, 49, 0, 0, 22, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 22, 51, 0, 0, 211, 51, 0, 0, 255, 51, 0, 0, 122, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 0, 51, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 22, 51, 0, 0, 120, 51, 0, 0, 20, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 51, 0, 0, 20, 51, 0, 0, 122, 51, 0, 0, 25, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 0, 53, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 49, 0, 0, 0, 49, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 47, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 242, 51, 0, 0, 255, 53, 0, 0, 28, 53, 0, 0, 0, 53, 0, 0, 0, 49, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 47, 0, 0, 0, 47, 0, 0, 0, 47, 0, 0, 29, 51, 0, 0, 255, 51, 0, 0, 240, 51, 0, 0, 175, 51, 0, 0, 255, 51, 0, 0, 182, 53, 0, 0, 28, 53, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 47, 0, 0, 0, 47, 0, 0, 29, 51, 0, 0, 183, 51, 0, 0, 255, 50, 0, 0, 169, 48, 0, 0, 39, 51, 0, 0, 238, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 236, 53, 0, 0, 28, 48, 0, 0, 0, 47, 0, 0, 29, 51, 0, 0, 170, 51, 0, 0, 241, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 241, 50, 0, 0, 169, 53, 0, 0, 28, 53, 0, 0, 0 ), 84 | "format": "RGBA8", 85 | "height": 20, 86 | "mipmaps": false, 87 | "width": 20 88 | } 89 | 90 | [sub_resource type="ImageTexture" id=12] 91 | image = SubResource( 11 ) 92 | size = Vector2( 20, 20 ) 93 | 94 | [sub_resource type="Image" id=13] 95 | data = { 96 | "data": PoolByteArray( 51, 51, 51, 0, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 3, 50, 50, 50, 87, 51, 51, 51, 172, 51, 51, 51, 224, 51, 51, 51, 251, 51, 51, 51, 239, 51, 51, 51, 207, 52, 52, 52, 141, 52, 52, 52, 38, 52, 52, 52, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 50, 50, 50, 0, 50, 50, 50, 57, 51, 51, 51, 213, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 253, 51, 51, 51, 153, 51, 51, 51, 10, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 50, 50, 50, 0, 51, 51, 51, 0, 51, 51, 51, 85, 51, 51, 51, 248, 51, 51, 51, 255, 51, 51, 51, 249, 52, 52, 52, 161, 52, 52, 52, 88, 52, 52, 52, 58, 50, 50, 50, 69, 51, 51, 51, 115, 51, 51, 51, 206, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 207, 51, 51, 51, 17, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 50, 50, 50, 0, 50, 50, 50, 57, 51, 51, 51, 248, 51, 51, 51, 255, 51, 51, 51, 200, 53, 53, 53, 33, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 50, 50, 50, 0, 51, 51, 51, 0, 51, 51, 51, 1, 52, 52, 52, 96, 51, 51, 51, 246, 51, 51, 51, 255, 51, 51, 51, 195, 51, 51, 51, 3, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 3, 51, 51, 51, 213, 51, 51, 51, 255, 51, 51, 51, 200, 51, 51, 51, 9, 53, 53, 53, 0, 53, 53, 53, 0, 52, 52, 52, 0, 52, 52, 52, 0, 50, 50, 50, 0, 51, 51, 51, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 68, 51, 51, 51, 251, 51, 51, 51, 255, 51, 51, 51, 108, 51, 51, 51, 0, 51, 51, 51, 0, 50, 50, 50, 0, 50, 50, 50, 87, 51, 51, 51, 255, 51, 51, 51, 248, 53, 53, 53, 33, 53, 53, 53, 0, 53, 53, 53, 0, 53, 53, 53, 0, 53, 53, 53, 0, 52, 52, 52, 0, 50, 50, 50, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 51, 51, 51, 137, 51, 51, 51, 255, 51, 51, 51, 226, 51, 51, 51, 3, 50, 50, 50, 0, 50, 50, 50, 0, 51, 51, 51, 172, 51, 51, 51, 255, 51, 51, 51, 162, 53, 53, 53, 0, 53, 53, 53, 0, 53, 53, 53, 0, 53, 53, 53, 0, 53, 53, 53, 0, 52, 52, 52, 0, 50, 50, 50, 0, 52, 52, 52, 0, 52, 52, 52, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 20, 51, 51, 51, 251, 51, 51, 51, 255, 50, 50, 50, 62, 50, 50, 50, 0, 50, 50, 50, 0, 51, 51, 51, 224, 51, 51, 51, 255, 52, 52, 52, 88, 52, 52, 52, 0, 52, 52, 52, 0, 53, 53, 53, 0, 53, 53, 53, 0, 53, 53, 53, 0, 53, 53, 53, 0, 52, 52, 52, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 198, 51, 51, 51, 255, 50, 50, 50, 114, 50, 50, 50, 0, 50, 50, 50, 0, 51, 51, 51, 249, 51, 51, 51, 255, 49, 49, 49, 59, 49, 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 0, 53, 53, 53, 0, 153, 153, 153, 0, 52, 52, 52, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 167, 51, 51, 51, 255, 52, 52, 52, 136, 52, 52, 52, 0, 52, 52, 52, 0, 51, 51, 51, 240, 51, 51, 51, 255, 52, 52, 52, 68, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 51, 51, 51, 0, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 177, 51, 51, 51, 255, 51, 51, 51, 132, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 207, 51, 51, 51, 255, 51, 51, 51, 115, 51, 51, 51, 0, 51, 51, 51, 0, 52, 52, 52, 0, 52, 52, 52, 0, 51, 51, 51, 0, 51, 51, 51, 0, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 0, 51, 51, 51, 1, 51, 51, 51, 224, 51, 51, 51, 255, 52, 52, 52, 93, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 141, 51, 51, 51, 255, 51, 51, 51, 206, 51, 51, 51, 1, 52, 52, 52, 0, 52, 52, 52, 0, 52, 52, 52, 0, 51, 51, 51, 0, 51, 51, 51, 0, 50, 50, 50, 0, 50, 50, 50, 0, 51, 51, 51, 0, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 62, 51, 51, 51, 255, 51, 51, 51, 253, 54, 54, 54, 31, 54, 54, 54, 0, 54, 54, 54, 0, 48, 48, 48, 39, 51, 51, 51, 253, 51, 51, 51, 255, 52, 52, 52, 96, 52, 52, 52, 0, 52, 52, 52, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 0, 51, 51, 51, 0, 52, 52, 52, 6, 52, 52, 52, 201, 51, 51, 51, 255, 51, 51, 51, 183, 54, 54, 54, 0, 54, 54, 54, 0, 54, 54, 54, 0, 48, 48, 48, 0, 51, 51, 51, 153, 51, 51, 51, 255, 51, 51, 51, 246, 52, 52, 52, 68, 52, 52, 52, 0, 51, 51, 51, 0, 51, 51, 51, 0, 52, 52, 52, 0, 51, 51, 51, 0, 50, 50, 50, 0, 50, 50, 50, 0, 51, 51, 51, 6, 51, 51, 51, 163, 51, 51, 51, 255, 51, 51, 51, 250, 51, 51, 51, 45, 51, 51, 51, 0, 51, 51, 51, 0, 54, 54, 54, 0, 51, 51, 51, 0, 51, 51, 51, 10, 51, 51, 51, 207, 51, 51, 51, 255, 51, 51, 51, 251, 51, 51, 51, 137, 51, 51, 51, 20, 51, 51, 51, 0, 52, 52, 52, 0, 51, 51, 51, 0, 50, 50, 50, 0, 50, 50, 50, 62, 51, 51, 51, 202, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 236, 48, 48, 48, 39, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 17, 51, 51, 51, 195, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 251, 51, 51, 51, 198, 52, 52, 52, 166, 51, 51, 51, 178, 51, 51, 51, 224, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 250, 51, 51, 51, 236, 51, 51, 51, 255, 51, 51, 51, 229, 48, 48, 48, 39, 48, 48, 48, 0, 48, 48, 48, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 3, 51, 51, 51, 108, 51, 51, 51, 226, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 255, 51, 51, 51, 253, 51, 51, 51, 183, 51, 51, 51, 45, 48, 48, 48, 39, 51, 51, 51, 229, 51, 51, 51, 255, 51, 51, 51, 229, 48, 48, 48, 39, 48, 48, 48, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 2, 50, 50, 50, 62, 50, 50, 50, 114, 52, 52, 52, 136, 51, 51, 51, 132, 52, 52, 52, 93, 54, 54, 54, 31, 51, 51, 51, 0, 51, 51, 51, 0, 48, 48, 48, 0, 48, 48, 48, 39, 51, 51, 51, 229, 51, 51, 51, 255, 51, 51, 51, 229, 48, 48, 48, 39, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 0, 52, 52, 52, 0, 51, 51, 51, 0, 52, 52, 52, 0, 54, 54, 54, 0, 54, 54, 54, 0, 51, 51, 51, 0, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 39, 51, 51, 51, 230, 51, 51, 51, 255, 51, 51, 51, 219, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 51, 51, 51, 0, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 0, 52, 52, 52, 0, 51, 51, 51, 0, 52, 52, 52, 0, 54, 54, 54, 0, 54, 54, 54, 0, 54, 54, 54, 0, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 39, 51, 51, 51, 220, 52, 52, 52, 181 ), 97 | "format": "RGBA8", 98 | "height": 20, 99 | "mipmaps": false, 100 | "width": 20 101 | } 102 | 103 | [sub_resource type="ImageTexture" id=14] 104 | image = SubResource( 13 ) 105 | size = Vector2( 20, 20 ) 106 | 107 | [node name="HBoxContainer2" type="HBoxContainer"] 108 | margin_top = 576.0 109 | margin_right = 1024.0 110 | margin_bottom = 600.0 111 | script = ExtResource( 2 ) 112 | 113 | [node name="ButtonFromCSV" type="Control" parent="."] 114 | margin_bottom = 24.0 115 | 116 | [node name="FileDialog" type="FileDialog" parent="ButtonFromCSV"] 117 | margin_right = 520.0 118 | margin_bottom = 326.0 119 | window_title = "Open a File" 120 | mode = 0 121 | access = 2 122 | filters = PoolStringArray( "*.csv" ) 123 | 124 | [node name="csvOptions" type="WindowDialog" parent="ButtonFromCSV"] 125 | margin_left = 222.0 126 | margin_top = -378.0 127 | margin_right = 578.0 128 | margin_bottom = -189.0 129 | rect_min_size = Vector2( 168, 86 ) 130 | window_title = "CSV Options" 131 | 132 | [node name="VBoxContainer" type="VBoxContainer" parent="ButtonFromCSV/csvOptions"] 133 | anchor_right = 1.0 134 | anchor_bottom = 0.704 135 | margin_bottom = 0.0639877 136 | alignment = 1 137 | 138 | [node name="hasHeadings" type="HBoxContainer" parent="ButtonFromCSV/csvOptions/VBoxContainer"] 139 | margin_top = 42.0 140 | margin_right = 356.0 141 | margin_bottom = 66.0 142 | size_flags_horizontal = 5 143 | alignment = 1 144 | 145 | [node name="Label" type="Label" parent="ButtonFromCSV/csvOptions/VBoxContainer/hasHeadings"] 146 | margin_left = 103.0 147 | margin_top = 5.0 148 | margin_right = 225.0 149 | margin_bottom = 19.0 150 | text = "Contains Headings:" 151 | 152 | [node name="CheckBoxHeadings" type="CheckBox" parent="ButtonFromCSV/csvOptions/VBoxContainer/hasHeadings"] 153 | margin_left = 229.0 154 | margin_right = 253.0 155 | margin_bottom = 24.0 156 | 157 | [node name="Delimeter" type="HBoxContainer" parent="ButtonFromCSV/csvOptions/VBoxContainer"] 158 | margin_left = 129.0 159 | margin_top = 70.0 160 | margin_right = 227.0 161 | margin_bottom = 90.0 162 | size_flags_horizontal = 6 163 | size_flags_vertical = 0 164 | alignment = 1 165 | 166 | [node name="LabelDelimiter" type="Label" parent="ButtonFromCSV/csvOptions/VBoxContainer/Delimeter"] 167 | margin_right = 61.0 168 | margin_bottom = 20.0 169 | size_flags_vertical = 1 170 | text = "Delimiter" 171 | valign = 1 172 | 173 | [node name="OptionButton" type="OptionButton" parent="ButtonFromCSV/csvOptions/VBoxContainer/Delimeter"] 174 | margin_left = 65.0 175 | margin_right = 98.0 176 | margin_bottom = 20.0 177 | text = "," 178 | items = [ ",", null, false, 0, null, ";", null, false, 1, null ] 179 | selected = 0 180 | 181 | [node name="VBoxContainer2" type="VBoxContainer" parent="ButtonFromCSV/csvOptions"] 182 | anchor_top = 0.767 183 | anchor_right = 1.0 184 | anchor_bottom = 0.893 185 | margin_left = -1.0 186 | margin_top = 0.0469971 187 | margin_right = 1.0 188 | margin_bottom = 0.0129852 189 | size_flags_vertical = 7 190 | alignment = 1 191 | 192 | [node name="HBoxContainer" type="HBoxContainer" parent="ButtonFromCSV/csvOptions/VBoxContainer2"] 193 | margin_top = 1.0 194 | margin_right = 358.0 195 | margin_bottom = 21.0 196 | rect_pivot_offset = Vector2( 119, -204 ) 197 | alignment = 1 198 | 199 | [node name="ButtonOk" type="Button" parent="ButtonFromCSV/csvOptions/VBoxContainer2/HBoxContainer"] 200 | margin_left = 135.0 201 | margin_right = 165.0 202 | margin_bottom = 20.0 203 | text = "Ok" 204 | 205 | [node name="ButtonCancel" type="Button" parent="ButtonFromCSV/csvOptions/VBoxContainer2/HBoxContainer"] 206 | margin_left = 169.0 207 | margin_right = 223.0 208 | margin_bottom = 20.0 209 | text = "Cancel" 210 | 211 | [node name="SearchDiag" type="Control" parent="."] 212 | margin_left = 4.0 213 | margin_right = 4.0 214 | margin_bottom = 24.0 215 | 216 | [node name="WindowDialog" type="WindowDialog" parent="SearchDiag"] 217 | margin_top = -110.0 218 | margin_right = 236.0 219 | margin_bottom = 40.0 220 | window_title = "Search" 221 | resizable = true 222 | 223 | [node name="MarginContainer" type="MarginContainer" parent="SearchDiag/WindowDialog"] 224 | anchor_right = 1.0 225 | anchor_bottom = 1.0 226 | margin_left = 5.0 227 | margin_right = -5.0 228 | 229 | [node name="v" type="VBoxContainer" parent="SearchDiag/WindowDialog/MarginContainer"] 230 | margin_right = 226.0 231 | margin_bottom = 150.0 232 | alignment = 1 233 | 234 | [node name="h" type="HBoxContainer" parent="SearchDiag/WindowDialog/MarginContainer/v"] 235 | margin_top = 54.0 236 | margin_right = 226.0 237 | margin_bottom = 78.0 238 | alignment = 1 239 | 240 | [node name="Label" type="Label" parent="SearchDiag/WindowDialog/MarginContainer/v/h"] 241 | margin_top = 5.0 242 | margin_right = 46.0 243 | margin_bottom = 19.0 244 | text = "Search:" 245 | 246 | [node name="LineEdit" type="LineEdit" parent="SearchDiag/WindowDialog/MarginContainer/v/h"] 247 | margin_left = 50.0 248 | margin_right = 186.0 249 | margin_bottom = 24.0 250 | size_flags_horizontal = 3 251 | 252 | [node name="ButtonFind" type="Button" parent="SearchDiag/WindowDialog/MarginContainer/v/h"] 253 | margin_left = 190.0 254 | margin_right = 226.0 255 | margin_bottom = 24.0 256 | text = "find" 257 | 258 | [node name="Label" type="Label" parent="SearchDiag/WindowDialog/MarginContainer/v"] 259 | modulate = Color( 1, 1, 1, 0.6 ) 260 | margin_top = 82.0 261 | margin_right = 226.0 262 | margin_bottom = 96.0 263 | align = 1 264 | valign = 1 265 | 266 | [node name="ButtonFile" type="MenuButton" parent="."] 267 | margin_left = 8.0 268 | margin_right = 64.0 269 | margin_bottom = 24.0 270 | text = "Import" 271 | items = [ "csv", null, 0, false, false, 0, 0, null, "", false, "dict", null, 0, false, false, 1, 0, null, "", false, "tres", null, 0, false, false, 2, 0, null, "", false ] 272 | script = ExtResource( 1 ) 273 | 274 | [node name="ButtonSave" type="Button" parent="."] 275 | margin_left = 68.0 276 | margin_right = 109.0 277 | margin_bottom = 24.0 278 | text = "Save" 279 | flat = true 280 | 281 | [node name="ButtonUndo" type="Button" parent="."] 282 | margin_left = 113.0 283 | margin_right = 159.0 284 | margin_bottom = 24.0 285 | text = "Undo" 286 | flat = true 287 | 288 | [node name="MenuButtonCol" type="MenuButton" parent="."] 289 | visible = false 290 | margin_left = 115.0 291 | margin_right = 175.0 292 | margin_bottom = 24.0 293 | text = "column" 294 | items = [ "insert column", null, 0, false, false, 0, 0, null, "", false, "delete column", null, 0, false, false, 1, 0, null, "", false, "move right", null, 0, false, false, 2, 0, null, "", false, "move left", null, 0, false, false, 3, 0, null, "", false ] 295 | script = ExtResource( 3 ) 296 | 297 | [node name="MenuButtonRow" type="MenuButton" parent="."] 298 | visible = false 299 | margin_left = 179.0 300 | margin_right = 214.0 301 | margin_bottom = 24.0 302 | text = "row" 303 | items = [ "insert row", null, 0, false, false, 0, 0, null, "", false, "delete row", null, 0, false, false, 1, 0, null, "", false ] 304 | script = ExtResource( 4 ) 305 | 306 | [node name="h" type="HBoxContainer" parent="."] 307 | margin_left = 163.0 308 | margin_right = 272.0 309 | margin_bottom = 24.0 310 | 311 | [node name="Label" type="Label" parent="h"] 312 | margin_top = 5.0 313 | margin_right = 37.0 314 | margin_bottom = 19.0 315 | text = "Rows:" 316 | 317 | [node name="ButtonAddRowAbove" type="TextureButton" parent="h"] 318 | margin_left = 41.0 319 | margin_right = 61.0 320 | margin_bottom = 24.0 321 | hint_tooltip = "Insert row above" 322 | texture_normal = ExtResource( 7 ) 323 | texture_disabled = SubResource( 2 ) 324 | script = ExtResource( 8 ) 325 | 326 | [node name="ButtonAddRowBelow" type="TextureButton" parent="h"] 327 | margin_left = 65.0 328 | margin_right = 85.0 329 | margin_bottom = 24.0 330 | hint_tooltip = "Insert row below" 331 | texture_normal = ExtResource( 11 ) 332 | texture_disabled = SubResource( 4 ) 333 | script = ExtResource( 8 ) 334 | 335 | [node name="TextureButtonDeleCurRow" type="TextureButton" parent="h"] 336 | margin_left = 89.0 337 | margin_right = 109.0 338 | margin_bottom = 24.0 339 | hint_tooltip = "Delete current row" 340 | texture_normal = ExtResource( 6 ) 341 | texture_disabled = SubResource( 6 ) 342 | script = ExtResource( 8 ) 343 | tint = Color( 1, 0, 0, 1 ) 344 | 345 | [node name="Button" type="Button" parent="."] 346 | visible = false 347 | margin_left = 214.0 348 | margin_right = 280.0 349 | margin_bottom = 24.0 350 | text = "serialize" 351 | flat = true 352 | 353 | [node name="ButtonLoad" type="Button" parent="."] 354 | visible = false 355 | margin_left = 214.0 356 | margin_right = 253.0 357 | margin_bottom = 24.0 358 | text = "load" 359 | 360 | [node name="h2" type="HBoxContainer" parent="."] 361 | margin_left = 276.0 362 | margin_right = 408.0 363 | margin_bottom = 24.0 364 | 365 | [node name="Label" type="Label" parent="h2"] 366 | margin_top = 5.0 367 | margin_right = 60.0 368 | margin_bottom = 19.0 369 | text = "Columns:" 370 | 371 | [node name="TextureButton" type="TextureButton" parent="h2"] 372 | margin_left = 64.0 373 | margin_right = 84.0 374 | margin_bottom = 24.0 375 | texture_normal = ExtResource( 9 ) 376 | texture_disabled = SubResource( 8 ) 377 | script = ExtResource( 8 ) 378 | 379 | [node name="TextureButton2" type="TextureButton" parent="h2"] 380 | margin_left = 88.0 381 | margin_right = 108.0 382 | margin_bottom = 24.0 383 | texture_normal = ExtResource( 5 ) 384 | texture_disabled = SubResource( 10 ) 385 | script = ExtResource( 8 ) 386 | 387 | [node name="TextureButtonColClose" type="TextureButton" parent="h2"] 388 | margin_left = 112.0 389 | margin_right = 132.0 390 | margin_bottom = 24.0 391 | texture_normal = ExtResource( 6 ) 392 | texture_disabled = SubResource( 12 ) 393 | script = ExtResource( 8 ) 394 | tint = Color( 1, 0, 0, 1 ) 395 | 396 | [node name="MoveMenu" type="MenuButton" parent="."] 397 | margin_left = 412.0 398 | margin_right = 459.0 399 | margin_bottom = 24.0 400 | text = "Move" 401 | items = [ "Column move left", null, 0, false, false, 0, 0, null, "", false, "Column move right", null, 0, false, false, 1, 0, null, "", false ] 402 | script = ExtResource( 12 ) 403 | 404 | [node name="ButtonSearch" type="TextureButton" parent="."] 405 | margin_left = 463.0 406 | margin_right = 483.0 407 | margin_bottom = 24.0 408 | texture_normal = ExtResource( 10 ) 409 | texture_disabled = SubResource( 14 ) 410 | script = ExtResource( 8 ) 411 | 412 | [connection signal="file_selected" from="ButtonFromCSV/FileDialog" to="." method="_on_FileDialog_file_selected"] 413 | [connection signal="pressed" from="ButtonFromCSV/csvOptions/VBoxContainer2/HBoxContainer/ButtonOk" to="." method="_on_ButtonOk_pressed"] 414 | [connection signal="pressed" from="ButtonFromCSV/csvOptions/VBoxContainer2/HBoxContainer/ButtonCancel" to="." method="_on_ButtonCancel_pressed"] 415 | [connection signal="pressed" from="SearchDiag/WindowDialog/MarginContainer/v/h/ButtonFind" to="." method="_on_ButtonFind_pressed"] 416 | [connection signal="pressed" from="ButtonSave" to="." method="_on_ButtonSave_pressed"] 417 | [connection signal="pressed" from="ButtonUndo" to="." method="_on_ButtonUndo_pressed"] 418 | [connection signal="pressed" from="h/ButtonAddRowAbove" to="." method="_on_ButtonAddRowAbove_pressed"] 419 | [connection signal="pressed" from="h/ButtonAddRowBelow" to="." method="_on_ButtonAddRowBelow_pressed"] 420 | [connection signal="pressed" from="h/TextureButtonDeleCurRow" to="." method="_on_TextureButtonDeleCurRow_pressed"] 421 | [connection signal="pressed" from="Button" to="." method="_on_Button_pressed"] 422 | [connection signal="pressed" from="ButtonLoad" to="." method="_on_ButtonLoad_pressed"] 423 | [connection signal="pressed" from="h2/TextureButton" to="." method="_on_TextureButton_pressed"] 424 | [connection signal="pressed" from="h2/TextureButton2" to="." method="_on_TextureButton2_pressed"] 425 | [connection signal="pressed" from="h2/TextureButtonColClose" to="." method="_on_TextureButtonColClose_pressed"] 426 | [connection signal="pressed" from="ButtonSearch" to="." method="_on_ButtonSearch_pressed"] 427 | --------------------------------------------------------------------------------