tool extends Control var selected_item = null var selected_id = null var selected_class = null onready var item_tree = get_node("VBox/Body/ItemTree") onready var id_label = get_node("VBox/Body/Content/VBox/Container/ItemIdLabel") onready var instance_details = get_node("VBox/Body/Content/VBox/InstanceDetails/") onready var class_properties = get_node("VBox/Body/Content/VBox/InstanceDetails/HBox/ClassProperties") onready var custom_properties = get_node("VBox/Body/Content/VBox/InstanceDetails/HBox/CustomProperties") onready var class_overview = get_node("VBox/Body/Content/VBox/ClassOverview") onready var no_classes = get_node("VBox/Body/Content/VBox/NoClasses") #onready var last_modified_date = get_node("VBox/Body/Content/VBox/Container/GridContainer/LastModifiedDate") #onready var created_date = get_node("VBox/Body/Content/VBox/Container/GridContainer/CreatedDate") onready var new_custom_property_dialog = get_node("NewCustomPropertyDialog") onready var new_custom_property_name = get_node("NewCustomPropertyDialog/LineEdit") onready var new_custom_property_type_options = get_node("NewCustomPropertyDialog/TypeOptions") onready var add_button = get_node("VBox/Head/Add") onready var delete_button = get_node("VBox/Head/Delete") onready var duplicate_button = get_node("VBox/Head/Duplicate") onready var change_display_name_button = get_node("VBox/Body/Content/VBox/Container/HBox/DisplayName") onready var rename_button = get_node("VBox/Head/Rename") onready var save_button = get_node("VBox/Head/Save") onready var save_all_button = get_node("VBox/Head/SaveAll") onready var copy_id_button = get_node("VBox/Body/Content/VBox/Container/HBox/CopyId") onready var edit_class_button = get_node("VBox/Body/Content/VBox/Container/HBox/EditClass") # Dialogs onready var input_dialog = get_node("InputDialog") onready var new_item_class_dialog = get_node("NewClassDialog") onready var new_item_class_name = get_node("NewClassDialog/ClassName") onready var new_item_class_icon = get_node("NewClassDialog/ClassIconPath") onready var new_item_class_icon_dialog = get_node("NewClassDialog/ClassIconFileDialog") onready var warn_dialog = get_node("WarnDialog") onready var options_screen = get_node("OptionsDialog") var item_tree_class = preload("item_tree.tscn") #var active_element = null var item_manager = null signal class_edit_requested(script) signal input_dialog_confirmed(text1, text2) # First initialize the item manager which is used for loading, saving and configs func _init(): item_manager = preload("item_manager.gd").new() # This item_manager will add itself to the globals func _ready(): Globals.set("debug_is_editor", false) # Tree signals item_tree.connect("on_new_item_pressed", self, "handle_actions", ["add"]) item_tree.connect("on_rename_pressed", self, "handle_actions", ["rename"]) item_tree.connect("on_delete_pressed", self, "handle_actions", ["delete"]) item_tree.connect("on_duplicate_pressed", self, "handle_actions", ["duplicate"]) item_tree.connect("on_item_selected", self, "change_item_context", []) item_tree.connect("on_open", self, "open_item", []) custom_properties.connect("custom_property_add_requested", self, "handle_actions", ["add_custom_property"]) custom_properties.connect("new_custom_property_created", self, "handle_actions", ["add_custom_property"]) custom_properties.connect("custom_property_delete_requested", self, "delete_custom_property", []) class_properties.connect("on_item_changed", self, "toggle_item_dirty_state", []) options_screen.connect("extension_changed", item_manager, "rename_extension_of_all_items", []) options_screen.connect("encryption_changed", item_manager, "delete_and_resave", []) item_manager.connect("class_insertion_failed", self, "show_warning", []) item_manager.connect("item_insertion_failed", self, "show_warning", []) item_manager.connect("custom_property_insertion_failed", self, "show_warning", []) item_manager.connect("item_duplication_failed", self, "show_warning", []) # item_manager.connect("class_is_invalid", self, "show_warning", []) # Add types to the custom property type dropdown var type_names = item_manager.type_names.keys() type_names.sort() new_custom_property_type_options.clear() var index = 0 for type in type_names: new_custom_property_type_options.add_item(type) new_custom_property_type_options.set_item_metadata(index, item_manager.type_names[type]) index += 1 # No classes available var has_no_classes = item_manager.classes.size() == 0 if has_no_classes: change_display_name_button.set_disabled(has_no_classes) duplicate_button.set_disabled(true) save_button.set_disabled(true) save_all_button.set_disabled(true) save_all_button.set_disabled(true) rename_button.set_disabled(true) add_button.set_disabled(true) delete_button.set_disabled(true) copy_id_button.set_disabled(true) edit_class_button.set_disabled(true) no_classes.show() id_label.set_text("No Classes") instance_details.hide() class_overview.hide() else: # Select the first item in the tree when loading the GUI var all_classes = item_manager.classes.keys() all_classes.sort() selected_class = all_classes[0] change_item_context(selected_item, selected_class) # TODO: Implement func open_item(): var item_path = item_manager.get_full_path(selected_item) var program = "" var os_name = OS.get_name() if os_name == "Windows": program = "explorer" item_path = item_path.replace("/", "\\") # ~_~... # TODO: Not sure if these work... Probably add the possibility to add a custom editor elif os_name == "OSX": program = "open" else: program = "nautilus" OS.execute(program, [item_path], false) func change_item_context(selected_item, selected_class): if selected_class: self.selected_class = selected_class # TODO: Move to method, clean up var has_no_classes = item_manager.classes.size() == 0 if has_no_classes: change_display_name_button.set_disabled(has_no_classes) duplicate_button.set_disabled(true) save_button.set_disabled(true) save_all_button.set_disabled(true) save_all_button.set_disabled(true) rename_button.set_disabled(true) add_button.set_disabled(true) delete_button.set_disabled(true) copy_id_button.set_disabled(true) edit_class_button.set_disabled(true) no_classes.show() instance_details.hide() class_overview.hide() id_label.set_text("No Classes") # An item was selected if selected_item: # Context was lost, e.g. because of changes to the classes. Reload. if selected_item and not selected_item.get("_id"): self.item_manager.load_manager() self.item_tree.load_tree(true) selected_item = item_tree.select_first_element() change_display_name_button.set_disabled(false) duplicate_button.set_disabled(false) save_button.set_disabled(false) save_all_button.set_disabled(false) rename_button.set_disabled(false) add_button.set_disabled(false) delete_button.set_disabled(false) copy_id_button.set_disabled(false) edit_class_button.set_disabled(false) self.selected_item = selected_item self.selected_id = selected_item._id class_overview.hide() no_classes.hide() instance_details.show() if selected_item._display_name == selected_id: id_label.set_text(selected_id) else: id_label.set_text(selected_item._display_name + " (" + selected_id + ")") class_properties.build_properties(selected_item) custom_properties.build_properties(selected_item) # A class was selected elif selected_class: change_display_name_button.set_disabled(true) duplicate_button.set_disabled(true) save_button.set_disabled(true) save_all_button.set_disabled(false) rename_button.set_disabled(false) add_button.set_disabled(false) delete_button.set_disabled(false) copy_id_button.set_disabled(false) edit_class_button.set_disabled(false) self.selected_item = null self.selected_id = null id_label.set_text(selected_class.capitalize()) if item_manager.invalid_classes.has(selected_class): class_overview.set_label("There is a problem with this class, please check if there are any issues. Press 'Reload' once you are ready.") else: class_overview.set_label("") class_overview.show() instance_details.hide() no_classes.hide() func _on_ItemTree_on_new_item_created(new_item): selected_item = new_item func create_shortcut(keys): var short_cut = ShortCut.new() var input_event = InputEvent() input_event.type = InputEvent.KEY input_event.ID = keys short_cut.set_shortcut(input_event) # TODO: Implement func warn_about_reload(): if item_manager.has_unsaved_items(): input_dialog.popup(self, "reload_confirmed", tr("Confirm reload"), tr("Some changes have not been saved. \nThey will be discarded if you proceed. Are you sure you want to perform this action?")) func reload(): item_manager.load_manager() item_tree.load_tree(true) if item_manager.get_item(selected_class, selected_id): item_tree.select_item(item_manager.get_item(selected_class, selected_id)) func toggle_item_dirty_state(item): item._dirty = true item_tree.set_tree_item_label_text(item) # Validation takes place in the item manager func _on_NewCustomPropertyDialog_confirmed(): var custom_property_id = new_custom_property_name.get_text().strip_edges() var custom_property_type = new_custom_property_type_options.get_selected_metadata() var success = item_manager.add_custom_property(selected_item, custom_property_id, custom_property_type) if success: item_tree.set_tree_item_label_text(selected_item) toggle_item_dirty_state(selected_item) custom_properties.build_properties(selected_item) # TODO: Show confirmation dialog func delete_custom_property(property_name): item_manager.delete_custom_property(selected_item, property_name) toggle_item_dirty_state(selected_item) custom_properties.build_properties(selected_item) # TODO: New Class Dialog is still a mess func _on_AddClassButton_button_down(): new_item_class_name.set_text("") new_item_class_icon.set_text("") new_item_class_icon_dialog.set_current_path("") new_item_class_dialog.popup_centered() new_item_class_name.grab_focus() func _on_NewClassDialog_confirmed(): var name = new_item_class_name.get_text().to_lower() var icon_path = new_item_class_icon.get_text() item_manager.create_class(name, icon_path) item_tree.load_tree() item_tree.select_class(name) reload() edit_class() # New Class Dialog func _on_NewClassIconSearchButton_button_down(): new_item_class_icon_dialog.popup_centered() # Icon for new class was selected func _on_NewClassIconFileDialog_file_selected(path): new_item_class_icon.set_text(path) # General handler for a lot of actions to centralize the GUI logic a bit func handle_actions(action, argument = ""): if action == "add": input_dialog.popup(self, "_on_add_item_confirmed", tr("New Item"), tr("Please enter an ID for and optionally a display name the new item"), tr("ID"), "", tr("Display Name (optional)"), "") elif action == "rename": if selected_item: input_dialog.popup(self, "_on_rename_item_confirmed", tr("Rename Item"), tr("Please enter a new ID for this item."), "ID", selected_id) else: input_dialog.popup(self, "_on_rename_class_confirmed", tr("Rename Class"), tr("Please enter a new name for this class. All pending changes will be discarded!"), "ID", selected_class) elif action == "duplicate": var new_display_name = "" if selected_item._dirty: input_dialog.popup(self, "item_duplication_failed", tr("Item duplication failed"), tr("Before duplicating this item, please first save it.")) return selected_item._display_name = "" input_dialog.popup(self, "_on_duplicate_confirmed", tr("Duplicate Item"), tr("Please enter a new ID for this item"), "ID", selected_id, tr("Display Name (optional)"), new_display_name) elif action == "save": item_manager.save_item(selected_item) item_tree.load_tree() #reload() elif action == "save_all": item_manager.save_all_items() item_tree.load_tree() #reload() elif action == "reload": item_manager.load_manager() reload() elif action == "new_class": _on_AddClassButton_button_down() # TODO: Incorporate into dialog handling elif action == "delete": if selected_item: input_dialog.popup(self, "_on_delete_item_confirmed", tr("Delete Item"), tr("Are you sure you want to delete this item?")) else: input_dialog.popup(self, "_on_delete_class_confirmed", tr("Delete Class"), tr("Are you sure you want to delete class along with all items?")) elif action == "options": options_screen.popup_centered() elif action == "edit_class": edit_class() elif action == "copy_id": copy_id() elif action == "change_display_name": input_dialog.popup(self, "change_display_name", tr("Change Display Name"), tr("Please enter a display name for this item."), "Display Name", selected_item._display_name) elif action == "add_custom_property": new_custom_property_name.set_text("") new_custom_property_dialog.popup_centered() new_custom_property_name.grab_focus() ######################################################################### # Handlers # ######################################################################### func _on_add_item_confirmed(id, display_name): var new_item = item_manager.create_and_add_new_item(selected_class, id, display_name) if new_item: item_tree.add_leaf(new_item, true) func _on_rename_item_confirmed(id): item_manager.rename_item(selected_item, id) reload() func _on_rename_class_confirmed(name): item_manager.rename_class(selected_class, name) reload() func _on_duplicate_confirmed(id, display_name): var duplicated_item = item_manager.duplicate_item(selected_item, id, display_name, false) item_tree.add_leaf(duplicated_item, true) reload() func _on_delete_item_confirmed(): item_manager.delete_item(selected_item) reload() func _on_delete_class_confirmed(): item_manager.delete_class(selected_class) if item_manager.classes.size() > 0: item_tree.select_class(item_manager.class_names[0]) else: change_item_context(null, null) reload() ######################################################################### # Buttons on the right # ######################################################################### func change_display_name(new_name): selected_item._display_name = new_name toggle_item_dirty_state(selected_item) change_item_context(selected_item, selected_class) func copy_id(): if selected_item: OS.set_clipboard(selected_id) else: OS.set_clipboard(selected_class) func edit_class(): var script = item_manager.classes[selected_class] emit_signal("class_edit_requested", script) ##################################################### # OTHERS ##################################################### func show_warning(title, text): warn_dialog.set_title(title) warn_dialog.set_text(text) warn_dialog.popup_centered() func log_text(text): var file = File.new() file.open("res://test.log", File.READ_WRITE) var old_text = file.get_as_text() var date = str(OS.get_datetime()["hour"]) + ":" + str(OS.get_datetime()["minute"]) + ":" + str(OS.get_datetime()["second"]) + "\t" file.store_line(old_text + date + text)