This repository has been archived on 2024-08-28. You can view files and clone it, but cannot push or open issues or pull requests.
gmtk-2024/addons/AsepriteWizard/interface/docks/wizard/as_wizard_window.gd
2024-08-17 15:22:33 +01:00

274 lines
8.8 KiB
GDScript

@tool
extends PanelContainer
signal close_requested
signal import_success(file_settings)
const result_code = preload("../../../config/result_codes.gd")
var _config = preload("../../../config/config.gd").new()
var _import_helper = preload("./wizard_import_helper.gd").new()
var _file_system: EditorFileSystem = EditorInterface.get_resource_filesystem()
var _file_dialog_aseprite: EditorFileDialog
var _output_folder_dialog: EditorFileDialog
var _warning_dialog: AcceptDialog
@onready var _layer_section_btn: Button = $container/options/layer_section/header/section_header
@onready var _layer_section_content: MarginContainer = $container/options/layer_section/section_content
@onready var _output_section_btn: Button = $container/options/output_section/header/section_header
@onready var _output_section_content: MarginContainer = $container/options/output_section/section_content
@onready var _file_location_field: LineEdit = $container/options/file_location/HBoxContainer/file_location_path
@onready var _output_folder_field: LineEdit = $container/options/output_section/section_content/items/output_folder/HBoxContainer/file_location_path
@onready var _exception_pattern_field: LineEdit = $container/options/layer_section/section_content/items/exclude_pattern/pattern
@onready var _split_mode_field: CheckBox = $container/options/layer_section/section_content/items/split_layers/field
@onready var _only_visible_layers_field: CheckBox = $container/options/layer_section/section_content/items/visible_layers/field
@onready var _custom_name_field: LineEdit = $container/options/output_section/section_content/items/custom_filename/pattern
@onready var _do_not_create_res_field: CheckBox = $container/options/output_section/section_content/items/disable_resource_creation/field
const INTERFACE_SECTION_KEY_LAYER = "layer_section"
const INTERFACE_SECTION_KEY_OUTPUT = "output_section"
@onready var _expandable_sections = {
INTERFACE_SECTION_KEY_LAYER: { "header": _layer_section_btn, "content": _layer_section_content},
INTERFACE_SECTION_KEY_OUTPUT: { "header": _output_section_btn, "content": _output_section_content},
}
var _interface_section_state = {}
func _ready():
_configure_sections()
_load_persisted_config()
func _exit_tree():
if is_instance_valid(_file_dialog_aseprite):
_file_dialog_aseprite.queue_free()
if is_instance_valid(_output_folder_dialog):
_output_folder_dialog.queue_free()
if is_instance_valid(_warning_dialog):
_warning_dialog.queue_free()
func _init_aseprite_file_selection_dialog():
_file_dialog_aseprite = _create_aseprite_file_selection()
get_parent().get_parent().add_child(_file_dialog_aseprite)
func _init_output_folder_selection_dialog():
_output_folder_dialog = _create_outuput_folder_selection()
get_parent().get_parent().add_child(_output_folder_dialog)
func _init_warning_dialog():
_warning_dialog = AcceptDialog.new()
_warning_dialog.exclusive = false
get_parent().get_parent().add_child(_warning_dialog)
func _load_persisted_config() -> void:
var cfg = _load_last_import_cfg()
_load_config(cfg)
func _load_config(cfg: Dictionary) -> void:
_split_mode_field.button_pressed = cfg.split_layers
_only_visible_layers_field.button_pressed = cfg.only_visible_layers
_exception_pattern_field.text = cfg.layer_exclusion_pattern
_custom_name_field.text = cfg.output_name
_file_location_field.text = cfg.source_file
_do_not_create_res_field.button_pressed = cfg.do_not_create_resource
_output_folder_field.text = cfg.output_location if cfg.output_location != "" else "res://"
func _save_config() -> void:
_config.set_standalone_spriteframes_last_import_config(_get_field_values())
func _get_field_values() -> Dictionary:
return {
"split_layers": _split_mode_field.button_pressed,
"only_visible_layers": _only_visible_layers_field.button_pressed,
"layer_exclusion_pattern": _exception_pattern_field.text,
"output_name": _custom_name_field.text,
"source_file": _file_location_field.text,
"do_not_create_resource": _do_not_create_res_field.button_pressed,
"output_location": _output_folder_field.text if _output_folder_field.text != "" else "res://",
}
func _clear_config() -> void:
_config.clear_standalone_spriteframes_last_import_config()
var default = _get_default_config()
_load_config(default)
## This is used by the other tabs to set the form fields
func load_import_config(field_values: Dictionary):
_split_mode_field.button_pressed = field_values.split_layers
_only_visible_layers_field.button_pressed = field_values.only_visible_layers
_exception_pattern_field.text = field_values.layer_exclusion_pattern
_custom_name_field.text = field_values.output_name
_file_location_field.text = field_values.source_file
_do_not_create_res_field.button_pressed = field_values.do_not_create_resource
_output_folder_field.text = field_values.output_location
func _open_aseprite_file_selection_dialog():
if not is_instance_valid(_file_dialog_aseprite):
_init_aseprite_file_selection_dialog()
var current_selection = _file_location_field.text
if current_selection != "":
_file_dialog_aseprite.current_dir = current_selection.get_base_dir()
_file_dialog_aseprite.popup_centered_ratio()
func _open_output_folder_selection_dialog():
if not is_instance_valid(_output_folder_dialog):
_init_output_folder_selection_dialog()
var current_selection = _output_folder_field.text
if current_selection != "":
_output_folder_dialog.current_dir = current_selection
_output_folder_dialog.popup_centered_ratio()
func _create_aseprite_file_selection():
var file_dialog = EditorFileDialog.new()
file_dialog.file_mode = EditorFileDialog.FILE_MODE_OPEN_FILE
file_dialog.access = EditorFileDialog.ACCESS_FILESYSTEM
file_dialog.connect("file_selected", _on_aseprite_file_selected)
file_dialog.set_filters(PackedStringArray(["*.ase","*.aseprite"]))
return file_dialog
func _create_outuput_folder_selection():
var file_dialog = EditorFileDialog.new()
file_dialog.file_mode = EditorFileDialog.FILE_MODE_OPEN_DIR
file_dialog.access = EditorFileDialog.ACCESS_RESOURCES
file_dialog.connect("dir_selected", _on_output_folder_selected)
return file_dialog
func _on_aseprite_file_selected(path):
var localized_path = ProjectSettings.localize_path(path)
_file_location_field.text = localized_path
func _on_output_folder_selected(path):
_output_folder_field.text = path
func _on_next_btn_up():
var aseprite_file = _file_location_field.text
var fields = _get_field_values()
var exit_code = await _import_helper.import_and_create_resources(aseprite_file, _get_field_values())
if exit_code != OK:
_show_error(exit_code)
return
emit_signal("import_success", fields)
if _config.should_remove_source_files():
_file_system.call_deferred("scan")
_show_import_success_message()
func trigger_import():
_on_next_btn_up()
func _on_close_btn_up():
_close_window()
func _close_window():
_save_config()
self.emit_signal("close_requested")
func _on_clear_button_up():
_clear_config()
func _show_error(code: int):
_show_error_message(result_code.get_error_message(code))
func _show_error_message(message: String):
if not is_instance_valid(_warning_dialog):
_init_warning_dialog()
_warning_dialog.dialog_text = "Error: %s" % message
_warning_dialog.popup_centered()
func _show_import_success_message():
if not is_instance_valid(_warning_dialog):
_init_warning_dialog()
_warning_dialog.dialog_text = "Aseprite import succeeded"
_warning_dialog.popup_centered()
_save_config()
func _configure_sections():
for key in _expandable_sections:
_adjust_section_visibility(key)
func _adjust_section_visibility(key: String) -> void:
var section = _expandable_sections[key]
var is_visible = _interface_section_state.get(key, true)
_adjust_icon(section.header, is_visible)
section.content.visible = is_visible
func _adjust_icon(section: Button, is_visible: bool = true) -> void:
var icon_name = "GuiTreeArrowDown" if is_visible else "GuiTreeArrowRight"
section.icon = get_theme_icon(icon_name, "EditorIcons")
func _toggle_section_visibility(key: String) -> void:
_interface_section_state[key] = not _interface_section_state.get(key, true)
_adjust_section_visibility(key)
func _on_layer_section_header_button_down():
_toggle_section_visibility(INTERFACE_SECTION_KEY_LAYER)
func _on_output_section_header_button_down():
_toggle_section_visibility(INTERFACE_SECTION_KEY_OUTPUT)
func _load_last_import_cfg() -> Dictionary:
var cfg = _config.get_standalone_spriteframes_last_import_config()
if cfg.is_empty():
return _get_default_config()
return cfg
func _get_default_config() -> Dictionary:
return {
"split_layers": false,
"only_visible_layers": _config.should_include_only_visible_layers_by_default(),
"layer_exclusion_pattern": _config.get_default_exclusion_pattern(),
"output_name": "",
"source_file": "",
"do_not_create_resource": false,
"output_location": "res://",
}