From 6ab9bcb96e108c417bf30cf5d635f6ed974fbd7f Mon Sep 17 00:00:00 2001 From: don-tnowe <67479453+don-tnowe@users.noreply.github.com> Date: Sat, 22 Oct 2022 19:23:50 +0300 Subject: [PATCH] Delegate storage of import data to separate class --- .../import_export/import_export_dialog.gd | 220 +++++------------- .../import_export/import_export_dialog.tscn | 19 +- .../import_export/spreadsheet_import.gd | 120 ++++++++++ project.godot | 9 + 4 files changed, 205 insertions(+), 163 deletions(-) create mode 100644 addons/resources_speadsheet_view/import_export/spreadsheet_import.gd diff --git a/addons/resources_speadsheet_view/import_export/import_export_dialog.gd b/addons/resources_speadsheet_view/import_export/import_export_dialog.gd index 9844419..95d1a31 100644 --- a/addons/resources_speadsheet_view/import_export/import_export_dialog.gd +++ b/addons/resources_speadsheet_view/import_export/import_export_dialog.gd @@ -1,21 +1,6 @@ tool extends WindowDialog -enum PropType { - BOOL, - INT, - REAL, - STRING, - VECTOR2, - RECT2, - VECTOR3, - COLOR, - ARRAY, - OBJECT, - ENUM, - MAX, -} - export var prop_list_item_scene : PackedScene onready var editor_view := $"../.." @@ -24,30 +9,24 @@ onready var node_classname_field := $"TabContainer/Import/MarginContainer/Scroll onready var node_filename_props := $"TabContainer/Import/MarginContainer/ScrollContainer/VBoxContainer/GridContainer/OptionButton" onready var prop_list := $"TabContainer/Import/MarginContainer/ScrollContainer/VBoxContainer" -var prop_types := [] -var prop_names := [] - var entries := [] var uniques := {} -var delimeter := "" -var path := "res://" var property_used_as_filename := 0 -var script_classname := "" -var remove_first_row := true - -var new_script : GDScript +var import_data : SpreadsheetImport +var delimeter := "," func _on_FileDialogText_file_selected(path : String): - self.path = path + import_data = SpreadsheetImport.new() + import_data.path = path _open_dialog() popup_centered() func _open_dialog(): node_classname_field.text = TextEditingUtils\ - .string_snake_to_naming_case(path.get_file().get_basename())\ + .string_snake_to_naming_case(import_data.path.get_file().get_basename())\ .replace(" ", "") _load_entries() @@ -57,7 +36,7 @@ func _open_dialog(): func _load_entries(): var file = File.new() - file.open(path, File.READ) + file.open(import_data.path, File.READ) delimeter = ";" var text_lines := [file.get_line().split(delimeter)] @@ -79,170 +58,86 @@ func _load_entries(): func _load_property_names(): - prop_names = Array(entries[0]) - prop_types.resize(prop_names.size()) - prop_types.fill(4) - for i in prop_names.size(): - prop_names[i] = entries[0][i].replace(" ", "_").to_lower() + import_data.prop_names = Array(entries[0]) + import_data.prop_types.resize(import_data.prop_names.size()) + import_data.prop_types.fill(4) + for i in import_data.prop_names.size(): + import_data.prop_names[i] = entries[0][i].replace(" ", "_").to_lower() if entries[1][i].is_valid_integer(): - prop_types[i] = PropType.INT + import_data.prop_types[i] = SpreadsheetImport.PropType.INT elif entries[1][i].is_valid_float(): - prop_types[i] = PropType.REAL + import_data.prop_types[i] = SpreadsheetImport.PropType.REAL elif entries[1][i].begins_with("res://"): - prop_types[i] = PropType.OBJECT + import_data.prop_types[i] = SpreadsheetImport.PropType.OBJECT - else: prop_types[i] = PropType.STRING + else: import_data.prop_types[i] = SpreadsheetImport.PropType.STRING node_filename_options.clear() - for i in prop_names.size(): - node_filename_options.add_item(prop_names[i], i) + for i in import_data.prop_names.size(): + node_filename_options.add_item(import_data.prop_names[i], i) func _create_prop_editors(): for x in prop_list.get_children(): if !x is GridContainer: x.free() - for i in prop_names.size(): + for i in import_data.prop_names.size(): var new_node = prop_list_item_scene.instance() prop_list.add_child(new_node) - new_node.display(prop_names[i], prop_types[i]) + new_node.display(import_data.prop_names[i], import_data.prop_types[i]) new_node.connect_all_signals(self, i) func _generate_class(): - new_script = GDScript.new() - if script_classname != "": - new_script.source_code = "class_name " + script_classname + " \nextends Resource\n\n" + var new_script = GDScript.new() + if import_data.script_classname != "": + new_script.source_code = "class_name " + import_data.script_classname + " \nextends Resource\n\n" else: new_script.source_code = "extends Resource\n\n" # Enums uniques = {} - for i in prop_types.size(): - if prop_types[i] == PropType.ENUM: - new_script.source_code += _create_enum_for_prop(i) + for i in import_data.prop_types.size(): + if import_data.prop_types[i] == SpreadsheetImport.PropType.ENUM: + var cur_value := "" + uniques[i] = {} + for j in entries.size(): + if j == 0 && import_data.remove_first_row: continue + + cur_value = entries[j][i].replace(" ", "_").to_upper() + if cur_value == "": + cur_value = "N_A" + + if !uniques[i].has(cur_value): + uniques[i][cur_value] = uniques[i].size() + + new_script.source_code += import_data.create_enum_for_prop(i, uniques) # Properties - for i in prop_names.size(): - new_script.source_code += _create_property_line_for_prop(i) + for i in import_data.prop_names.size(): + new_script.source_code += import_data.create_property_line_for_prop(i) - ResourceSaver.save(path.get_basename() + ".gd", new_script) + ResourceSaver.save(import_data.path.get_basename() + ".gd", new_script) new_script.reload() - new_script = load(path.get_basename() + ".gd") # Because when instanced, objects have a copy of the script + new_script = load(import_data.path.get_basename() + ".gd") # Because when instanced, objects have a copy of the script + import_data.new_script = new_script func _export_tres_folder(): var dir = Directory.new() - dir.make_dir_recursive(path.get_basename()) + dir.make_dir_recursive(import_data.path.get_basename()) - var prop_used_as_filename_str : String = prop_names[property_used_as_filename] + import_data.prop_used_as_filename = import_data.prop_names[property_used_as_filename] var new_res : Resource for i in entries.size(): - if remove_first_row && i == 0: + if import_data.remove_first_row && i == 0: continue - - new_res = new_script.new() - for j in prop_names.size(): - new_res.set(prop_names[j], _string_to_property(entries[i][j], j)) - - new_res.resource_path = path.get_basename() + "/" + new_res.get(prop_used_as_filename_str) + ".tres" - ResourceSaver.save(new_res.resource_path, new_res) - - -func _create_property_line_for_prop(col_index : int): - var result = "export var " + prop_names[col_index] + " :" - match prop_types[col_index]: - PropType.STRING: - return result + "= \"\"\n" - - PropType.BOOL: - return result + "= false\n" - - PropType.REAL: - return result + "= 0.0\n" - - PropType.INT: - return result + "= 0\n" - - PropType.COLOR: - return result + "= Color.white\n" - - PropType.OBJECT: - return result + " Resource\n" - - PropType.ENUM: - return result.replace( - "export var", - "export(" - + TextEditingUtils.string_snake_to_naming_case( - prop_names[col_index] - ).replace(" ", "") - + ") var" - ) + "= 0\n" - - -func _create_enum_for_prop(col_index): - # Find all uniques - var cur_value := "" - uniques[col_index] = {} - for i in entries.size(): - if i == 0 && remove_first_row: continue - - cur_value = entries[i][col_index].replace(" ", "_").to_upper() - if cur_value == "": - cur_value = "N_A" - - if !uniques[col_index].has(cur_value): - uniques[col_index][cur_value] = uniques[col_index].size() - # Write to script - var result := ( - "enum " - + TextEditingUtils.string_snake_to_naming_case(prop_names[col_index]).replace(" ", "") - + " {\n" - ) - for k in uniques[col_index]: - result += ( - "\t" - + k # Enum Entry - + " = " - + str(uniques[col_index][k]) # Value - + ",\n" - ) - result += "\tMAX,\n}\n\n" - return result - - -func _string_to_property(string : String, col_index : int): - match prop_types[col_index]: - PropType.STRING: - return string - - PropType.BOOL: - string = string.to_lower() - return !string in ["no", "disabled", "-", "false", "absent", "wrong", ""] - - PropType.REAL: - return string.to_float() - - PropType.INT: - return string.to_int() - - PropType.COLOR: - return Color(string) - - PropType.OBJECT: - return load(string) - - PropType.ENUM: - if string == "": - return int(uniques[col_index]["N_A"]) - - else: - return int(uniques[col_index][string.to_upper().replace(" ", "_")]) + new_res = import_data.strings_to_resource(entries[i], uniques) + ResourceSaver.save(new_res.resource_path, new_res) func _on_Ok_pressed(): @@ -250,17 +145,28 @@ func _on_Ok_pressed(): _generate_class() _export_tres_folder() yield(get_tree(), "idle_frame") - editor_view.display_folder(path.get_basename()) + editor_view.display_folder(import_data.path.get_basename()) yield(get_tree(), "idle_frame") editor_view.refresh() + +func _on_OkSafe_pressed(): + hide() + _generate_class() + import_data.save() + yield(get_tree(), "idle_frame") + editor_view.display_folder(import_data.path.get_basename()) + yield(get_tree(), "idle_frame") + editor_view.refresh() + + # Input controls func _on_classname_field_text_changed(new_text : String): - script_classname = new_text.replace(" ", "") + import_data.script_classname = new_text.replace(" ", "") func _on_remove_first_row_toggled(button_pressed : bool): - remove_first_row = button_pressed + import_data.remove_first_row = button_pressed func _on_filename_options_item_selected(index): @@ -268,8 +174,8 @@ func _on_filename_options_item_selected(index): func _on_list_item_type_selected(type : int, index : int): - prop_types[index] = type + import_data.prop_types[index] = type func _on_list_item_name_changed(name : String, index : int): - prop_names[index] = name.replace(" ", "") + import_data.prop_names[index] = name.replace(" ", "") diff --git a/addons/resources_speadsheet_view/import_export/import_export_dialog.tscn b/addons/resources_speadsheet_view/import_export/import_export_dialog.tscn index bec9d18..a60b6b3 100644 --- a/addons/resources_speadsheet_view/import_export/import_export_dialog.tscn +++ b/addons/resources_speadsheet_view/import_export/import_export_dialog.tscn @@ -94,20 +94,27 @@ margin_right = 485.0 margin_bottom = 258.0 alignment = 1 -[node name="Ok" type="Button" parent="TabContainer/Import/HBoxContainer"] -margin_left = 182.0 -margin_right = 244.0 +[node name="Ok2" type="Button" parent="TabContainer/Import/HBoxContainer"] +margin_left = 50.0 +margin_right = 168.0 margin_bottom = 20.0 -text = "Confirm" +text = "Confirm and edit" + +[node name="Ok" type="Button" parent="TabContainer/Import/HBoxContainer"] +margin_left = 172.0 +margin_right = 376.0 +margin_bottom = 20.0 +text = "Convert to Resources and edit" [node name="Cancel" type="Button" parent="TabContainer/Import/HBoxContainer"] -margin_left = 248.0 -margin_right = 302.0 +margin_left = 380.0 +margin_right = 434.0 margin_bottom = 20.0 text = "Cancel" [connection signal="item_selected" from="TabContainer/Import/MarginContainer/ScrollContainer/VBoxContainer/GridContainer/OptionButton" to="." method="_on_filename_options_item_selected"] [connection signal="text_changed" from="TabContainer/Import/MarginContainer/ScrollContainer/VBoxContainer/GridContainer/LineEdit" to="." method="_on_classname_field_text_changed"] [connection signal="toggled" from="TabContainer/Import/MarginContainer/ScrollContainer/VBoxContainer/GridContainer/CheckBox" to="." method="_on_remove_first_row_toggled"] +[connection signal="pressed" from="TabContainer/Import/HBoxContainer/Ok2" to="." method="_on_OkSafe_pressed"] [connection signal="pressed" from="TabContainer/Import/HBoxContainer/Ok" to="." method="_on_Ok_pressed"] [connection signal="pressed" from="TabContainer/Import/HBoxContainer/Cancel" to="." method="hide"] diff --git a/addons/resources_speadsheet_view/import_export/spreadsheet_import.gd b/addons/resources_speadsheet_view/import_export/spreadsheet_import.gd new file mode 100644 index 0000000..57f01f3 --- /dev/null +++ b/addons/resources_speadsheet_view/import_export/spreadsheet_import.gd @@ -0,0 +1,120 @@ +class_name SpreadsheetImport +extends Resource + +enum PropType { + BOOL, + INT, + REAL, + STRING, + VECTOR2, + RECT2, + VECTOR3, + COLOR, + ARRAY, + OBJECT, + ENUM, + MAX, +} + +var prop_types := [] +var prop_names := [] + +var path := "res://" +var prop_used_as_filename := "name" +var script_classname := "" +var remove_first_row := true + +var new_script : GDScript + + +func save(): + resource_path = path.get_basename() + "_spreadsheet_import.tres" + ResourceSaver.save(resource_path, self) + + +func string_to_property(string : String, col_index : int, uniques : Dictionary): + match prop_types[col_index]: + PropType.STRING: + return string + + PropType.BOOL: + string = string.to_lower() + return !string in ["no", "disabled", "-", "false", "absent", "wrong", ""] + + PropType.REAL: + return string.to_float() + + PropType.INT: + return string.to_int() + + PropType.COLOR: + return Color(string) + + PropType.OBJECT: + return load(string) + + PropType.ENUM: + if string == "": + return int(uniques[col_index]["N_A"]) + + else: + return int(uniques[col_index][string.to_upper().replace(" ", "_")]) + + +func create_property_line_for_prop(col_index : int): + var result = "export var " + prop_names[col_index] + " :" + match prop_types[col_index]: + PropType.STRING: + return result + "= \"\"\n" + + PropType.BOOL: + return result + "= false\n" + + PropType.REAL: + return result + "= 0.0\n" + + PropType.INT: + return result + "= 0\n" + + PropType.COLOR: + return result + "= Color.white\n" + + PropType.OBJECT: + return result + " Resource\n" + + PropType.ENUM: + return result.replace( + "export var", + "export(" + + TextEditingUtils.string_snake_to_naming_case( + prop_names[col_index] + ).replace(" ", "") + + ") var" + ) + "= 0\n" + + +func create_enum_for_prop(col_index, uniques): + var result := ( + "enum " + + TextEditingUtils.string_snake_to_naming_case(prop_names[col_index]).replace(" ", "") + + " {\n" + ) + for k in uniques[col_index]: + result += ( + "\t" + + k # Enum Entry + + " = " + + str(uniques[col_index][k]) # Value + + ",\n" + ) + result += "\tMAX,\n}\n\n" + return result + + +func strings_to_resource(strings : Array, uniques : Dictionary): + var new_res = new_script.new() + for j in prop_names.size(): + new_res.set(prop_names[j], string_to_property(strings[j], j, uniques)) + + new_res.resource_path = path.get_basename() + "/" + new_res.get(prop_used_as_filename) + ".tres" + return new_res diff --git a/project.godot b/project.godot index 42b34c7..18efc8a 100644 --- a/project.godot +++ b/project.godot @@ -39,6 +39,12 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://addons/resources_speadsheet_view/import_export/formats_edit/edit_tres.gd" }, { +"base": "Resource", +"class": "SpreadsheetImport", +"language": "GDScript", +"path": "res://addons/resources_speadsheet_view/import_export/spreadsheet_import.gd" +}, { +"base": "Reference", "class": "TextEditingUtils", "language": "GDScript", "path": "res://addons/resources_speadsheet_view/text_editing_utils.gd" @@ -58,6 +64,9 @@ _global_script_class_icons={ "CellEditorArray": "", "SettingsGrid": "", "SheetsDockEditor": "", +"SpreadsheetEditFormat": "", +"SpreadsheetEditFormatTres": "", +"SpreadsheetImport": "", "TextEditingUtils": "", "ThemeIconButton": "", "ThemeStylebox": ""