This commit is contained in:
Eric Vande Voort
2025-01-07 16:10:03 -06:00
commit 7eb0dea424
147 changed files with 9096 additions and 0 deletions

View File

@@ -0,0 +1,39 @@
@tool
extends TabContainer
signal close_requested
const WizardWindow = preload("./as_wizard_window.tscn")
func _ready():
$Import.close_requested.connect(emit_signal.bind("close_requested"))
$Import.import_success.connect(_on_import_success)
$History.request_edit.connect(_on_edit_request)
$History.request_import.connect(_on_import_request)
$ImportedSpriteFrames.import_success.connect($History.add_entry)
self.set_tab_title(1, "Imported Resources")
func _on_AsWizardDockContainer_tab_changed(tab: int):
match tab:
1:
$ImportedSpriteFrames.init_resources()
2:
$History.reload()
func _on_edit_request(import_cfg: Dictionary):
$Import.load_import_config(import_cfg)
self.current_tab = 0
func _on_import_request(import_cfg: Dictionary):
$Import.load_import_config(import_cfg)
$Import.trigger_import()
func _on_import_success(settings: Dictionary):
$ImportedSpriteFrames.init_resources()
$ImportedSpriteFrames.reload_tree()
$History.add_entry(settings)

View File

@@ -0,0 +1,28 @@
[gd_scene load_steps=5 format=3 uid="uid://b844j1tk3vxer"]
[ext_resource type="PackedScene" uid="uid://c5dwobjd34w3p" path="res://addons/AsepriteWizard/interface/docks/wizard/as_wizard_window.tscn" id="1"]
[ext_resource type="Script" path="res://addons/AsepriteWizard/interface/docks/wizard/as_wizard_dock_container.gd" id="2"]
[ext_resource type="PackedScene" uid="uid://cyoin5ncul0fm" path="res://addons/AsepriteWizard/interface/docks/wizard/sprite_frames_import_history.tscn" id="3"]
[ext_resource type="PackedScene" uid="uid://bfhsdslj8kt7b" path="res://addons/AsepriteWizard/interface/docks/wizard/imported_sprite_frames.tscn" id="3_25qb4"]
[node name="AsWizardDockContainer" type="TabContainer"]
offset_right = 281.0
offset_bottom = 36.0
tab_alignment = 2
use_hidden_tabs_for_min_size = true
script = ExtResource("2")
[node name="Import" parent="." instance=ExtResource("1")]
layout_mode = 2
tooltip_text = "SpriteFrames Importer"
[node name="ImportedSpriteFrames" parent="." instance=ExtResource("3_25qb4")]
visible = false
layout_mode = 2
metadata/_tab_name = "Imported Resources"
[node name="History" parent="." instance=ExtResource("3")]
visible = false
layout_mode = 2
[connection signal="tab_changed" from="." to="." method="_on_AsWizardDockContainer_tab_changed"]

View File

@@ -0,0 +1,274 @@
@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://",
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,304 @@
@tool
extends PanelContainer
signal import_success(fields)
const result_code = preload("../../../config/result_codes.gd")
const wizard_config = preload("../../../config/wizard_config.gd")
var _import_helper = preload("./wizard_import_helper.gd").new()
@onready var _tree_container = $MarginContainer/HSplitContainer/tree
@onready var _resource_tree = _tree_container.get_resource_tree()
@onready var _nothing_container = $MarginContainer/HSplitContainer/MarginContainer/VBoxContainer/nothing
@onready var _single_item_container = $MarginContainer/HSplitContainer/MarginContainer/VBoxContainer/single_item
@onready var _multiple_items_container = $MarginContainer/HSplitContainer/MarginContainer/VBoxContainer/multiple_items
@onready var _confirmation_warning_container = $MarginContainer/HSplitContainer/MarginContainer/VBoxContainer/confirmation_warning
var _selection_count = 0
var _current_container = null
var _resources_to_process = null
var _is_loaded = false
var _groups = {}
func init_resources():
if _is_loaded:
return
_is_loaded = true
var file_tree = _get_file_tree("res://")
_setup_tree(file_tree)
func _get_file_tree(base_path: String, dir_name: String = "") -> Dictionary:
var dir_path = base_path.path_join(dir_name)
var dir = DirAccess.open(dir_path)
var dir_data = { "path": dir_path, "name": dir_name, "children": [], "type": "dir", }
if not dir:
return dir_data
dir.list_dir_begin()
var file_name = dir.get_next()
while file_name != "":
if dir.current_is_dir() and _is_importable_folder(dir_path, file_name):
var child_data = _get_file_tree(dir_path, file_name)
if not child_data.children.is_empty():
dir_data.children.push_back(child_data)
elif file_name.ends_with(".res"):
var resource_path = dir_path.path_join(file_name)
var resource = ResourceLoader.load(resource_path)
if resource is SpriteFrames:
if resource.has_meta(wizard_config.WIZARD_CONFIG_META_NAME):
var meta = resource.get_meta(wizard_config.WIZARD_CONFIG_META_NAME)
var parent_node = dir_data
if meta.group != "":
var group
if _groups.has(meta.group):
group = _groups[meta.group]
else:
group = { "folders": {} }
_groups[meta.group] = group
if not group.folders.has(dir_path):
group.folders[dir_path] = {
"node": {
"type": "group",
"name": "Split: %s" % meta.fields.source_file.get_file(),
"has_moved": meta.fields.output_location != dir_path,
"path": meta.fields.source_file,
"folder": dir_path,
"has_changes": _has_source_changes(resource, meta),
"children": [],
}
}
parent_node.children.push_back(group.folders[dir_path].node)
parent_node = group.folders[dir_path].node
parent_node.children.push_back({
"type": "resource",
"resource_type": "SpriteFrames",
"name": resource.resource_path.get_file(),
"path": resource.resource_path,
"meta": meta,
"has_changes": _has_source_changes(resource, meta),
"has_moved": meta.fields.output_location != dir_path,
})
file_name = dir.get_next()
return dir_data
func _is_importable_folder(dir_path: String, dir_name: String) -> bool:
return dir_path != "res://" or dir_name != "addons"
func _setup_tree(resource_tree: Dictionary) -> void:
var root = _resource_tree.create_item()
_add_items_to_tree(root, resource_tree.children)
func _add_items_to_tree(root: TreeItem, children: Array):
for node in children:
var item: TreeItem = _resource_tree.create_item(root)
item.set_text(0, node.name)
item.set_meta("node", node)
match node.type:
"dir":
item.set_icon(0, get_theme_icon("Folder", "EditorIcons"))
_add_items_to_tree(item, node.children)
#
"group":
item.set_icon(0, get_theme_icon("CompressedTexture2D", "EditorIcons"))
_add_items_to_tree(item, node.children)
if node.has_changes:
item.set_text(0, "%s (*)" % node.name)
if node.has_moved:
item.set_suffix(0, "(moved)")
"resource":
item.set_icon(0, get_theme_icon(node.resource_type, "EditorIcons"))
if node.has_changes:
item.set_text(0, "%s (*)" % node.name)
if node.meta.group != "":
item.set_custom_color(0, item.get_icon_modulate(0).darkened(0.5))
item.set_selectable(0, false)
elif node.has_moved:
item.set_suffix(0, "(moved)")
func _has_source_changes(resource: Object, meta: Dictionary) -> bool:
var current_hash = FileAccess.get_md5(meta.fields.source_file)
var saved_hash = wizard_config.get_source_hash(resource)
return saved_hash != current_hash
func _is_supported_type(resource_type: String) -> bool:
return resource_type == "SpriteFrames"
func reload_tree():
_confirmation_warning_container.hide()
_resources_to_process = null
if _current_container != null:
_current_container.show_buttons()
_current_container = null
_groups = {}
_selection_count = 0
_resource_tree.clear()
var file_tree = _get_file_tree("res://")
_setup_tree(file_tree)
func _set_empty_details_state():
_nothing_container.show()
_single_item_container.hide()
_multiple_items_container.hide()
func _on_tree_multi_selected(item: TreeItem, column: int, selected: bool):
_confirmation_warning_container.hide()
_resources_to_process = null
if _current_container != null:
_current_container.show_buttons()
#
if selected:
_selection_count += 1
else:
_selection_count -= 1
#
_nothing_container.hide()
_single_item_container.hide()
_multiple_items_container.hide()
#
match _selection_count:
0:
_nothing_container.show()
1:
_single_item_container.show()
_set_item_details(_resource_tree.get_selected())
_current_container = _single_item_container
_:
_multiple_items_container.show()
_multiple_items_container.set_selected_count(_selection_count)
_current_container = _multiple_items_container
func _set_item_details(item: TreeItem) -> void:
if not item.has_meta("node"):
return
var data = item.get_meta("node")
_single_item_container.set_resource_details(data)
func _on_single_item_import_triggered():
var selected = _resource_tree.get_selected()
var meta = selected.get_meta("node")
match meta.type:
"dir":
var selected_item = _resource_tree.get_selected()
var all_resources = []
var scenes_to_open = _set_all_resources(selected_item.get_meta("node"), all_resources)
_resources_to_process = all_resources
_show_confirmation_message(all_resources.size())
"resource":
var code = await _do_import(meta.path, meta.meta)
_set_tree_item_as_saved(_resource_tree.get_selected())
_single_item_container.hide_source_change_warning()
if code == OK:
EditorInterface.get_resource_filesystem().scan()
"group":
var first_item = meta.children[0]
var code = await _do_import(first_item.path, first_item.meta)
_set_tree_item_as_saved(selected)
_single_item_container.hide_source_change_warning()
if code == OK:
EditorInterface.get_resource_filesystem().scan()
_on_tree_refresh_triggered()
func _on_confirmation_warning_warning_confirmed():
_confirmation_warning_container.hide()
_current_container.show_buttons()
for resource in _resources_to_process:
await _do_import(resource.path, resource.meta)
_resources_to_process = null
EditorInterface.get_resource_filesystem().scan()
_on_tree_refresh_triggered()
func _on_confirmation_warning_warning_declined():
_confirmation_warning_container.hide()
_current_container.show_buttons()
_resources_to_process = null
func _on_tree_refresh_triggered():
_set_empty_details_state()
reload_tree()
func _set_tree_item_as_saved(item: TreeItem) -> void:
var meta = item.get_meta("node")
meta.has_changes = false
meta.has_moved = false
item.set_meta("node", meta)
item.set_text(0, meta.name)
item.set_suffix(0, "")
func _do_import(resource_path: String, metadata: Dictionary) -> int:
var resource_base_dir = resource_path.get_base_dir()
if resource_base_dir != metadata.fields.output_location:
print("Resource has moved. Changing output folder from %s to %s" % [resource_base_dir, metadata.fields.output_location])
metadata.fields.output_location = resource_base_dir
var exit_code := await _import_helper.import_and_create_resources(metadata.fields.source_file, metadata.fields)
if exit_code == OK:
print("Import complete: %s" % resource_path)
import_success.emit(metadata.fields)
else:
printerr("Failed to import %s. Error: %s" % [resource_path, result_code.get_error_message(exit_code)])
return exit_code
func _set_all_resources(meta: Dictionary, resources: Array):
match meta.type:
"dir":
for c in meta.children:
_set_all_resources(c, resources)
"resource":
if not resources.has(meta):
resources.push_back(meta)
"group":
var first_item = meta.children[0]
resources.push_back(first_item)
func _show_confirmation_message(resources: int):
_current_container.hide_buttons()
_confirmation_warning_container.set_message("You are about to re-import %s resources. Do you wish to continue?" % resources)
_confirmation_warning_container.show()
func _on_multiple_items_import_triggered():
var selected_item = _resource_tree.get_next_selected(null)
var all_resources = []
while selected_item != null:
_set_all_resources(selected_item.get_meta("node"), all_resources)
selected_item = _resource_tree.get_next_selected(selected_item)
_resources_to_process = all_resources
_show_confirmation_message(all_resources.size())

View File

@@ -0,0 +1,67 @@
[gd_scene load_steps=6 format=3 uid="uid://bfhsdslj8kt7b"]
[ext_resource type="Script" path="res://addons/AsepriteWizard/interface/docks/wizard/imported_sprite_frames.gd" id="1_dk2ra"]
[ext_resource type="PackedScene" uid="uid://cisgsfvp4nf1g" path="res://addons/AsepriteWizard/interface/shared/tree/resource_tree.tscn" id="2_svrqo"]
[ext_resource type="PackedScene" uid="uid://q7eyyg2kvvv2" path="res://addons/AsepriteWizard/interface/docks/wizard/resource_tree_single_item.tscn" id="3_pe1cg"]
[ext_resource type="PackedScene" uid="uid://fscemkx5w1dw" path="res://addons/AsepriteWizard/interface/docks/wizard/resource_tree_multiple_items.tscn" id="4_vteew"]
[ext_resource type="PackedScene" uid="uid://qgmln507kjnm" path="res://addons/AsepriteWizard/interface/shared/tree/tree_selection_confirmation_warning.tscn" id="5_jigim"]
[node name="ImportedSpriteFrames" type="PanelContainer"]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_dk2ra")
[node name="MarginContainer" type="MarginContainer" parent="."]
layout_mode = 2
[node name="HSplitContainer" type="HSplitContainer" parent="MarginContainer"]
layout_mode = 2
[node name="tree" parent="MarginContainer/HSplitContainer" instance=ExtResource("2_svrqo")]
layout_mode = 2
[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/HSplitContainer"]
custom_minimum_size = Vector2(200, 0)
layout_mode = 2
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/HSplitContainer/MarginContainer"]
layout_mode = 2
[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/HSplitContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
[node name="Label" type="Label" parent="MarginContainer/HSplitContainer/MarginContainer/VBoxContainer/MarginContainer"]
layout_mode = 2
text = "Details"
horizontal_alignment = 1
[node name="HSeparator" type="HSeparator" parent="MarginContainer/HSplitContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
[node name="nothing" type="Label" parent="MarginContainer/HSplitContainer/MarginContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 6
text = "Nothing selected"
horizontal_alignment = 1
[node name="single_item" parent="MarginContainer/HSplitContainer/MarginContainer/VBoxContainer" instance=ExtResource("3_pe1cg")]
visible = false
layout_mode = 2
[node name="multiple_items" parent="MarginContainer/HSplitContainer/MarginContainer/VBoxContainer" instance=ExtResource("4_vteew")]
visible = false
layout_mode = 2
[node name="confirmation_warning" parent="MarginContainer/HSplitContainer/MarginContainer/VBoxContainer" instance=ExtResource("5_jigim")]
visible = false
layout_mode = 2
[connection signal="multi_selected" from="MarginContainer/HSplitContainer/tree" to="." method="_on_tree_multi_selected"]
[connection signal="refresh_triggered" from="MarginContainer/HSplitContainer/tree" to="." method="_on_tree_refresh_triggered"]
[connection signal="import_triggered" from="MarginContainer/HSplitContainer/MarginContainer/VBoxContainer/single_item" to="." method="_on_single_item_import_triggered"]
[connection signal="import_triggered" from="MarginContainer/HSplitContainer/MarginContainer/VBoxContainer/multiple_items" to="." method="_on_multiple_items_import_triggered"]
[connection signal="warning_confirmed" from="MarginContainer/HSplitContainer/MarginContainer/VBoxContainer/confirmation_warning" to="." method="_on_confirmation_warning_warning_confirmed"]
[connection signal="warning_declined" from="MarginContainer/HSplitContainer/MarginContainer/VBoxContainer/confirmation_warning" to="." method="_on_confirmation_warning_warning_declined"]

View File

@@ -0,0 +1,22 @@
@tool
extends VBoxContainer
signal import_triggered
@onready var _import_message = $message
@onready var _import_button = $buttons
func set_selected_count(number_of_items: int) -> void:
_import_message.text = "%2d items selected" % number_of_items
func show_buttons():
_import_button.show()
func hide_buttons():
_import_button.hide()
func _on_import_selected_button_up():
import_triggered.emit()

View File

@@ -0,0 +1,24 @@
[gd_scene load_steps=2 format=3 uid="uid://fscemkx5w1dw"]
[ext_resource type="Script" path="res://addons/AsepriteWizard/interface/docks/wizard/resource_tree_multiple_items.gd" id="1_lg81l"]
[node name="multiple_items" type="VBoxContainer"]
size_flags_vertical = 3
script = ExtResource("1_lg81l")
[node name="message" type="Label" parent="."]
layout_mode = 2
size_flags_vertical = 6
text = "Multiple items selected
"
horizontal_alignment = 1
[node name="buttons" type="HFlowContainer" parent="."]
layout_mode = 2
[node name="import_selected" type="Button" parent="buttons"]
layout_mode = 2
size_flags_horizontal = 3
text = "Re-Import all"
[connection signal="button_up" from="buttons/import_selected" to="." method="_on_import_selected_button_up"]

View File

@@ -0,0 +1,171 @@
@tool
extends VBoxContainer
signal import_triggered
@onready var _file_name = $GridContainer/file_name_value
@onready var _type = $GridContainer/type_value
@onready var _path = $GridContainer/path_value
@onready var _source_label = $GridContainer/source_file_label
@onready var _source = $GridContainer/source_file_value
@onready var _only_visible_layers_label = $GridContainer/only_visible_layers_label
@onready var _only_visible_layers = $GridContainer/only_visible_layers_value
@onready var _layer_ex_pattern_label = $GridContainer/layer_ex_patt_label
@onready var _layer_ex_pattern = $GridContainer/layer_ex_patt_value
@onready var _o_name_label = $GridContainer/o_name_label
@onready var _o_name = $GridContainer/o_name_value
@onready var _o_folder_label = $GridContainer/o_folder_label
@onready var _o_folder_value = $GridContainer/o_folder_value
@onready var _resource_list_label = $GridContainer/resource_list_label
@onready var _resource_list = $GridContainer/resource_list
@onready var _resource_list_separator_1 = $GridContainer/HSeparator3
@onready var _resource_list_separator_2 = $GridContainer/HSeparator4
@onready var _resource_buttons = $resource_buttons
@onready var _dir_buttons = $dir_buttons
@onready var _group_buttons = $group_buttons
@onready var _source_change_warning = $source_changed_warning
@onready var _resource_only_fields = [
_source_label,
_source,
_only_visible_layers_label,
_only_visible_layers,
_layer_ex_pattern_label,
_layer_ex_pattern,
_o_name_label,
_o_name,
_o_folder_label,
_o_folder_value,
_source_change_warning,
]
var _current_resource_type = "resource"
var _resource_config: Dictionary = {}
func _ready():
_source_change_warning.set_text("Source file changed since last import")
_source_change_warning.hide()
func set_resource_details(resource_details: Dictionary) -> void:
_resource_config = resource_details
_resource_buttons.hide()
_dir_buttons.hide()
_group_buttons.hide()
_hide_resource_list()
_source_change_warning.hide()
_file_name.text = resource_details.name
_path.text = resource_details.path
_current_resource_type = resource_details.type
match resource_details.type:
"resource":
_type.text = resource_details.resource_type
_show_resource_fields()
_resource_buttons.show()
var fields = resource_details.meta.fields
_load_fields(fields)
_resource_buttons.show()
_source_change_warning.visible = resource_details.has_changes
"group":
_type.text = "Split Group"
_show_resource_fields()
_load_fields(resource_details.children[0].meta.fields)
_source_change_warning.visible = resource_details.children[0].has_changes
_group_buttons.show()
_show_resource_list()
for c in _resource_list.get_children():
c.queue_free()
for child_resource in resource_details.children:
var label = Label.new()
label.text = child_resource.name
_resource_list.add_child(label)
_:
_type.text = "Folder"
_hide_resource_fields()
_dir_buttons.show()
return
func _load_fields(fields: Dictionary):
_only_visible_layers.text = "Yes" if fields.only_visible_layers else "No"
_layer_ex_pattern.text = fields.layer_exclusion_pattern
_o_name.text = fields.output_name
_o_folder_value.text = fields.output_location
_source.text = fields.source_file
func _hide_resource_fields():
for f in _resource_only_fields:
f.hide()
func _show_resource_fields():
for f in _resource_only_fields:
f.show()
func show_buttons():
match _current_resource_type:
"resource":
_resource_buttons.show()
_:
_dir_buttons.show()
func hide_buttons():
_resource_buttons.hide()
_dir_buttons.hide()
func hide_source_change_warning():
_source_change_warning.hide()
func _on_show_in_fs_button_up():
EditorInterface.get_file_system_dock().navigate_to_path(_path.text)
func _on_show_dir_in_fs_button_up():
EditorInterface.get_file_system_dock().navigate_to_path(_path.text)
func _on_import_all_button_up():
import_triggered.emit()
func _on_import_button_up():
import_triggered.emit()
func _hide_resource_list():
_resource_list_separator_1.hide()
_resource_list_separator_2.hide()
_resource_list_label.hide()
_resource_list.hide()
func _show_resource_list():
_resource_list_separator_1.show()
_resource_list_separator_2.show()
_resource_list_label.show()
_resource_list.show()
func _on_import_all_pressed():
import_triggered.emit()
func _on_show_in_fs_pressed():
EditorInterface.get_file_system_dock().navigate_to_path(_resource_config.children[0].path)

View File

@@ -0,0 +1,172 @@
[gd_scene load_steps=3 format=3 uid="uid://q7eyyg2kvvv2"]
[ext_resource type="Script" path="res://addons/AsepriteWizard/interface/docks/wizard/resource_tree_single_item.gd" id="1_h1q4t"]
[ext_resource type="PackedScene" uid="uid://c1l0bk12iwln3" path="res://addons/AsepriteWizard/interface/shared/tree/inline_warning_panel.tscn" id="2_hmv61"]
[node name="single_item" type="VBoxContainer"]
script = ExtResource("1_h1q4t")
[node name="GridContainer" type="GridContainer" parent="."]
layout_mode = 2
size_flags_vertical = 3
theme_override_constants/h_separation = 10
columns = 2
[node name="type_label" type="Label" parent="GridContainer"]
layout_mode = 2
size_flags_vertical = 0
text = "Type"
[node name="type_value" type="Label" parent="GridContainer"]
layout_mode = 2
text = "-"
[node name="file_name_label" type="Label" parent="GridContainer"]
layout_mode = 2
size_flags_vertical = 0
text = "File"
[node name="file_name_value" type="Label" parent="GridContainer"]
custom_minimum_size = Vector2(50, 0)
layout_mode = 2
text = "-"
autowrap_mode = 1
[node name="path_label" type="Label" parent="GridContainer"]
layout_mode = 2
size_flags_vertical = 0
text = "Path"
[node name="path_value" type="Label" parent="GridContainer"]
custom_minimum_size = Vector2(50, 0)
layout_mode = 2
size_flags_horizontal = 3
text = "-"
autowrap_mode = 1
[node name="HSeparator" type="HSeparator" parent="GridContainer"]
layout_mode = 2
[node name="HSeparator2" type="HSeparator" parent="GridContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="source_file_label" type="Label" parent="GridContainer"]
layout_mode = 2
size_flags_vertical = 0
text = "Aseprite File"
[node name="source_file_value" type="Label" parent="GridContainer"]
custom_minimum_size = Vector2(50, 0)
layout_mode = 2
size_flags_horizontal = 3
text = "-"
autowrap_mode = 1
[node name="only_visible_layers_label" type="Label" parent="GridContainer"]
layout_mode = 2
size_flags_vertical = 0
text = "Only Visible Layers"
[node name="only_visible_layers_value" type="Label" parent="GridContainer"]
layout_mode = 2
text = "-"
[node name="layer_ex_patt_label" type="Label" parent="GridContainer"]
layout_mode = 2
size_flags_vertical = 0
text = "Slice"
[node name="layer_ex_patt_value" type="Label" parent="GridContainer"]
layout_mode = 2
text = "-"
[node name="o_folder_label" type="Label" parent="GridContainer"]
visible = false
layout_mode = 2
size_flags_vertical = 0
text = "Output Folder"
[node name="o_folder_value" type="Label" parent="GridContainer"]
visible = false
custom_minimum_size = Vector2(50, 0)
layout_mode = 2
size_flags_horizontal = 3
text = "-"
autowrap_mode = 2
[node name="o_name_label" type="Label" parent="GridContainer"]
layout_mode = 2
size_flags_vertical = 0
text = "Output Name"
[node name="o_name_value" type="Label" parent="GridContainer"]
layout_mode = 2
text = "-"
[node name="HSeparator3" type="HSeparator" parent="GridContainer"]
layout_mode = 2
[node name="HSeparator4" type="HSeparator" parent="GridContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="resource_list_label" type="Label" parent="GridContainer"]
layout_mode = 2
size_flags_vertical = 0
text = "Resources"
[node name="resource_list" type="VBoxContainer" parent="GridContainer"]
layout_mode = 2
[node name="source_changed_warning" parent="." instance=ExtResource("2_hmv61")]
layout_mode = 2
[node name="resource_buttons" type="HFlowContainer" parent="."]
visible = false
layout_mode = 2
[node name="import" type="Button" parent="resource_buttons"]
layout_mode = 2
size_flags_horizontal = 3
text = "Re-Import"
[node name="show_in_fs" type="Button" parent="resource_buttons"]
layout_mode = 2
size_flags_horizontal = 3
text = "Show In FileSystem"
[node name="group_buttons" type="HFlowContainer" parent="."]
visible = false
layout_mode = 2
[node name="import_all" type="Button" parent="group_buttons"]
layout_mode = 2
size_flags_horizontal = 3
text = "Re-Import all"
[node name="show_in_fs" type="Button" parent="group_buttons"]
layout_mode = 2
size_flags_horizontal = 3
text = "Show In FileSystem"
[node name="dir_buttons" type="HFlowContainer" parent="."]
visible = false
layout_mode = 2
[node name="import_all" type="Button" parent="dir_buttons"]
layout_mode = 2
size_flags_horizontal = 3
text = "Re-Import all"
[node name="show_dir_in_fs" type="Button" parent="dir_buttons"]
layout_mode = 2
size_flags_horizontal = 3
text = "Show In FileSystem"
[connection signal="button_up" from="resource_buttons/import" to="." method="_on_import_button_up"]
[connection signal="button_up" from="resource_buttons/show_in_fs" to="." method="_on_show_in_fs_button_up"]
[connection signal="pressed" from="group_buttons/import_all" to="." method="_on_import_all_pressed"]
[connection signal="pressed" from="group_buttons/show_in_fs" to="." method="_on_show_in_fs_pressed"]
[connection signal="button_up" from="dir_buttons/import_all" to="." method="_on_import_all_button_up"]
[connection signal="button_up" from="dir_buttons/show_dir_in_fs" to="." method="_on_show_dir_in_fs_button_up"]

View File

@@ -0,0 +1,260 @@
@tool
extends PanelContainer
signal request_edit(import_cfg)
signal request_import(import_cfg)
const SourcePathField = preload("./wizard_nodes/source_path.tscn")
const OutputPathField = preload("./wizard_nodes/output_path.tscn")
const ImportDateField = preload("./wizard_nodes/import_date.tscn")
const ItemActions = preload("./wizard_nodes/list_actions.tscn")
const DetailsField = preload("./wizard_nodes/details.tscn")
const SORT_BY_DATE := 0
const SORT_BY_PATH := 1
const INITIAL_GRID_INDEX := 4
var _config = preload("../../../config/config.gd").new()
var _history: Array
var _history_nodes := {}
var _history_nodes_list := []
var _is_busy := false
var _import_requested_for := -1
var _sort_by = SORT_BY_DATE
@onready var grid = $MarginContainer/VBoxContainer/ScrollContainer/GridContainer
@onready var loading_warning = $MarginContainer/VBoxContainer/loading_warning
@onready var no_history_warning = $MarginContainer/VBoxContainer/no_history_warning
func reload():
if _history:
return
if _config.has_old_history():
_migrate_history()
_history = _config.get_import_history()
for index in range(_history.size()):
var entry = _history[index]
_create_node_list_entry(entry, index)
loading_warning.hide()
if _history.is_empty():
no_history_warning.show()
else:
grid.get_parent().show()
func _create_node_list_entry(entry: Dictionary, index: int):
_add_to_node_list(entry, _create_nodes(entry, index))
func _create_nodes(entry: Dictionary, index: int) -> Dictionary:
var import_date = ImportDateField.instantiate()
import_date.set_date(entry.import_date)
var source_path = SourcePathField.instantiate()
source_path.set_entry(entry)
var output_path = OutputPathField.instantiate()
output_path.text = entry.output_location
output_path.tooltip_text = entry.output_location
var details = DetailsField.instantiate()
details.set_details(entry)
var actions = ItemActions.instantiate()
actions.history_index = index
actions.connect("import_clicked",Callable(self,"_on_entry_reimport_clicked"))
actions.connect("edit_clicked",Callable(self,"_on_entry_edit_clicked"))
actions.connect("removed_clicked",Callable(self,"_on_entry_remove_clicked"))
grid.get_child(INITIAL_GRID_INDEX).add_sibling(import_date)
import_date.add_sibling(source_path)
source_path.add_sibling(output_path)
output_path.add_sibling(details)
details.add_sibling(actions)
return {
"history_index": index,
"timestamp": entry.import_date,
"source_file": entry.source_file,
"source_path_node": source_path,
"output_path_node": output_path,
"import_date_node": import_date,
"actions_node": actions,
"details_node": details,
}
func _add_to_node_list(entry: Dictionary, node: Dictionary):
if not _history_nodes.has(entry.source_file):
_history_nodes[entry.source_file] = []
_history_nodes[entry.source_file].push_front(node)
_history_nodes_list.push_front(node)
func add_entry(file_settings: Dictionary):
if _history == null:
reload()
#
var dt = Time.get_datetime_dict_from_system()
file_settings["import_date"] = "%04d-%02d-%02d %02d:%02d:%02d" % [dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second]
#
if _import_requested_for != -1:
_remove_item(_import_requested_for)
_import_requested_for = -1
elif _history.size() > _config.get_history_max_entries():
_remove_entries(_history[0].source_file, 0)
#
_history.push_back(file_settings)
_config.save_import_history(_history)
_create_node_list_entry(file_settings, _history.size() - 1)
if _sort_by == SORT_BY_PATH:
_trigger_sort()
no_history_warning.hide()
loading_warning.hide()
grid.get_parent().show()
_is_busy = false
func _on_entry_reimport_clicked(entry_index: int):
if _is_busy:
return
_is_busy = true
_import_requested_for = entry_index
emit_signal("request_import", _history[entry_index])
func _on_entry_edit_clicked(entry_index: int):
if _is_busy:
return
emit_signal("request_edit", _history[entry_index])
func _on_entry_remove_clicked(entry_index: int):
if _is_busy:
return
_is_busy = true
_remove_item(entry_index)
_config.save_import_history(_history)
if (_history.is_empty()):
grid.get_parent().hide()
no_history_warning.show()
_is_busy = false
func _remove_item(entry_index: int):
var entry = _history[entry_index]
_remove_entries(entry.source_file, entry_index)
# removes nodes and entry from history. If entry_index is not provided, all
# entries for path are removed.
func _remove_entries(source_file_path: String, entry_index: int = -1):
var files_entries = _history_nodes[source_file_path]
var indexes_to_remove = []
for f in files_entries:
if entry_index == -1 or f.history_index == entry_index:
_free_entry_nodes(f)
_history_nodes_list.erase(f)
if entry_index != -1:
files_entries.erase(f)
_remove_from_history(f.history_index)
return
indexes_to_remove.push_back(f.history_index)
for i in indexes_to_remove:
_remove_from_history(i)
_history_nodes[source_file_path] = []
func _remove_from_history(entry_index: int):
var _already_adjusted = []
# to avoid re-creating the whole nodes list, I just decrement
# the index from items newer than the excluded one
for index in range(entry_index + 1, _history.size()):
if _already_adjusted.has(_history[index].source_file):
continue
_already_adjusted.push_back(_history[index].source_file)
var nodes = _history_nodes[_history[index].source_file]
for f in nodes:
if f.history_index > entry_index:
f.history_index -= 1
f.actions_node.history_index = f.history_index
_history.remove_at(entry_index)
func _free_entry_nodes(entry_history_node: Dictionary):
entry_history_node.source_path_node.queue_free()
entry_history_node.output_path_node.queue_free()
entry_history_node.import_date_node.queue_free()
entry_history_node.actions_node.queue_free()
entry_history_node.details_node.queue_free()
func _on_SortOptions_item_selected(index):
if index == _sort_by:
return
_trigger_sort(index)
func _trigger_sort(sort_type: int = _sort_by):
if sort_type == SORT_BY_DATE:
_history_nodes_list.sort_custom(Callable(self,"_sort_by_date"))
else:
_history_nodes_list.sort_custom(Callable(self,"_sort_by_path"))
_reorganise_nodes()
_sort_by = sort_type
func _sort_by_date(a, b):
return a.timestamp < b.timestamp
func _sort_by_path(a, b):
return a.source_file > b.source_file
func _reorganise_nodes():
for entry in _history_nodes_list:
grid.move_child(entry.import_date_node, INITIAL_GRID_INDEX + 1)
grid.move_child(entry.source_path_node, INITIAL_GRID_INDEX + 2)
grid.move_child(entry.output_path_node, INITIAL_GRID_INDEX + 3)
grid.move_child(entry.details_node, INITIAL_GRID_INDEX + 4)
grid.move_child(entry.actions_node, INITIAL_GRID_INDEX + 5)
func _migrate_history():
var history = _config.get_old_import_history()
var new_history = []
for index in range(history.size()):
var entry = history[index]
new_history.push_back({
"split_layers": true if entry.options.export_mode else false,
"only_visible_layers": entry.options.only_visible_layers,
"layer_exclusion_pattern": entry.options.exception_pattern,
"output_name": entry.options.output_filename,
"source_file": entry.source_file,
"do_not_create_resource": entry.options.do_not_create_resource,
"output_location": entry.output_location,
"import_date": entry.import_date,
})
_config.save_import_history(new_history)
_config.remove_old_history_setting()

View File

@@ -0,0 +1,85 @@
[gd_scene load_steps=2 format=3 uid="uid://cyoin5ncul0fm"]
[ext_resource type="Script" path="res://addons/AsepriteWizard/interface/docks/wizard/sprite_frames_import_history.gd" id="1"]
[node name="SpriteFramesImportHistory" type="PanelContainer"]
anchors_preset = 10
anchor_right = 1.0
grow_horizontal = 2
size_flags_horizontal = 3
size_flags_vertical = 3
script = ExtResource("1")
[node name="MarginContainer" type="MarginContainer" parent="."]
layout_mode = 2
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"]
layout_mode = 2
[node name="list actions" type="HBoxContainer" parent="MarginContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 0
alignment = 2
[node name="divider" type="Label" parent="MarginContainer/VBoxContainer/list actions"]
layout_mode = 2
[node name="sort_label" type="Label" parent="MarginContainer/VBoxContainer/list actions"]
layout_mode = 2
text = "Sort by:"
[node name="SortOptions" type="OptionButton" parent="MarginContainer/VBoxContainer/list actions"]
layout_mode = 2
item_count = 2
selected = 0
popup/item_0/text = "Date"
popup/item_0/id = 0
popup/item_1/text = "Source File"
popup/item_1/id = 1
[node name="loading_warning" type="Label" parent="MarginContainer/VBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 6
text = "Loading..."
[node name="no_history_warning" type="Label" parent="MarginContainer/VBoxContainer"]
visible = false
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 6
text = "No import history"
[node name="ScrollContainer" type="ScrollContainer" parent="MarginContainer/VBoxContainer"]
visible = false
layout_mode = 2
size_flags_vertical = 3
[node name="GridContainer" type="GridContainer" parent="MarginContainer/VBoxContainer/ScrollContainer"]
layout_mode = 2
size_flags_horizontal = 3
columns = 5
[node name="date_label" type="Label" parent="MarginContainer/VBoxContainer/ScrollContainer/GridContainer"]
layout_mode = 2
text = "Date"
[node name="source_label" type="Label" parent="MarginContainer/VBoxContainer/ScrollContainer/GridContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_stretch_ratio = 2.0
text = "Source File"
[node name="output_label" type="Label" parent="MarginContainer/VBoxContainer/ScrollContainer/GridContainer"]
layout_mode = 2
text = "Output Folder"
[node name="details_label" type="Label" parent="MarginContainer/VBoxContainer/ScrollContainer/GridContainer"]
layout_mode = 2
text = "Details"
[node name="actions_label" type="Label" parent="MarginContainer/VBoxContainer/ScrollContainer/GridContainer"]
layout_mode = 2
text = "Actions"
[connection signal="item_selected" from="MarginContainer/VBoxContainer/list actions/SortOptions" to="." method="_on_SortOptions_item_selected"]

View File

@@ -0,0 +1,69 @@
@tool
extends Node
const wizard_meta = preload("../../../config/wizard_config.gd")
const result_code = preload("../../../config/result_codes.gd")
var _aseprite_file_exporter = preload("../../../aseprite/file_exporter.gd").new()
var _sf_creator = preload("../../../creators/sprite_frames/sprite_frames_creator.gd").new()
var _config = preload("../../../config/config.gd").new()
var _file_system: EditorFileSystem = EditorInterface.get_resource_filesystem()
# fields
# "split_layers"
# "only_visible_layers"
# "layer_exclusion_pattern"
# "output_name"
# "source_file"
# "do_not_create_resource"
# "output_location"
func import_and_create_resources(aseprite_file: String, fields: Dictionary) -> int:
var export_mode = _aseprite_file_exporter.LAYERS_EXPORT_MODE if fields.split_layers else _aseprite_file_exporter.FILE_EXPORT_MODE
var options = {
"export_mode": export_mode,
"exception_pattern": fields.layer_exclusion_pattern,
"only_visible_layers": fields.only_visible_layers,
"output_filename": fields.output_name,
"do_not_create_resource": fields.do_not_create_resource,
"output_folder": fields.output_location,
}
var aseprite_output = _aseprite_file_exporter.generate_aseprite_files(
ProjectSettings.globalize_path(aseprite_file),
options
)
if not aseprite_output.is_ok:
return aseprite_output.code
_file_system.scan()
await _file_system.filesystem_changed
var exit_code = OK
if !options.get("do_not_create_resource", false):
var resources = _sf_creator.create_resources(aseprite_output.content)
if resources.is_ok:
_add_metadata(resources.content, aseprite_file, fields, options)
exit_code = _sf_creator.save_resources(resources.content)
if _config.should_remove_source_files():
_remove_source_files(aseprite_output.content)
return exit_code
func _add_metadata(resources: Array, aseprite_file: String, fields: Dictionary, options: Dictionary) -> void:
var source_hash = FileAccess.get_md5(aseprite_file)
var group = str(ResourceUID.create_id()) if options.export_mode == _aseprite_file_exporter.LAYERS_EXPORT_MODE else ""
for r in resources:
wizard_meta.set_source_hash(r.resource, source_hash)
wizard_meta.save_config(r.resource, { "fields": fields, "group": group })
func _remove_source_files(source_files: Array):
for s in source_files:
DirAccess.remove_absolute(s.data_file)

View File

@@ -0,0 +1,42 @@
@tool
extends VBoxContainer
@onready var _details_btn = $label
@onready var _details_container = $MarginContainer/GridContainer
@onready var _split_layers_field = $MarginContainer/GridContainer/split_layers
@onready var _only_visible_layers = $MarginContainer/GridContainer/only_visible_layers
@onready var _layer_exclusion_pattern = $MarginContainer/GridContainer/layer_exclusion_pattern
@onready var _output_name = $MarginContainer/GridContainer/output_name
@onready var _do_not_create_resource = $MarginContainer/GridContainer/do_not_create_resource
var _entry
func _ready():
_adjust_icon(false)
_details_container.hide()
_load_fields()
func set_details(entry: Dictionary):
_entry = entry
func _load_fields():
_split_layers_field.text = "Yes" if _entry.split_layers else "No"
_only_visible_layers.text = "Yes" if _entry.only_visible_layers else "No"
_layer_exclusion_pattern.text = _entry.layer_exclusion_pattern
_output_name.text = _entry.output_name
_output_name.text = _entry.output_name
_do_not_create_resource.text = "Yes" if _entry.do_not_create_resource else "No"
func _adjust_icon(is_visible: bool) -> void:
var icon_name = "GuiTreeArrowDown" if is_visible else "GuiTreeArrowRight"
_details_btn.icon = get_theme_icon(icon_name, "EditorIcons")
func _on_label_pressed():
_details_container.visible = not _details_container.visible
_adjust_icon(_details_container.visible)

View File

@@ -0,0 +1,60 @@
[gd_scene load_steps=2 format=3 uid="uid://b1jb5yierm2bq"]
[ext_resource type="Script" path="res://addons/AsepriteWizard/interface/docks/wizard/wizard_nodes/details.gd" id="1_1v4dc"]
[node name="Details" type="VBoxContainer"]
offset_right = 40.0
offset_bottom = 40.0
script = ExtResource("1_1v4dc")
[node name="label" type="Button" parent="."]
layout_mode = 2
text = "Details"
flat = true
alignment = 0
[node name="MarginContainer" type="MarginContainer" parent="."]
layout_mode = 2
theme_override_constants/margin_left = 10
[node name="GridContainer" type="GridContainer" parent="MarginContainer"]
layout_mode = 2
theme_override_constants/h_separation = 5
columns = 2
[node name="split_layers_label" type="Label" parent="MarginContainer/GridContainer"]
layout_mode = 2
text = "Split layers:"
[node name="split_layers" type="Label" parent="MarginContainer/GridContainer"]
layout_mode = 2
[node name="only_visible_layers_label" type="Label" parent="MarginContainer/GridContainer"]
layout_mode = 2
text = "Only visible layers:"
[node name="only_visible_layers" type="Label" parent="MarginContainer/GridContainer"]
layout_mode = 2
[node name="layer_exclusion_pattern_label" type="Label" parent="MarginContainer/GridContainer"]
layout_mode = 2
text = "Layer Ex Pattern:"
[node name="layer_exclusion_pattern" type="Label" parent="MarginContainer/GridContainer"]
layout_mode = 2
[node name="output_name_label" type="Label" parent="MarginContainer/GridContainer"]
layout_mode = 2
text = "Output name:"
[node name="output_name" type="Label" parent="MarginContainer/GridContainer"]
layout_mode = 2
[node name="do_not_create_resource_label" type="Label" parent="MarginContainer/GridContainer"]
layout_mode = 2
text = "Do not create resource:"
[node name="do_not_create_resource" type="Label" parent="MarginContainer/GridContainer"]
layout_mode = 2
[connection signal="pressed" from="label" to="." method="_on_label_pressed"]

View File

@@ -0,0 +1,6 @@
@tool
extends Label
func set_date(timestamp: String):
self.text = timestamp

View File

@@ -0,0 +1,12 @@
[gd_scene load_steps=2 format=3 uid="uid://bs0i357m5d7ho"]
[ext_resource type="Script" path="res://addons/AsepriteWizard/interface/docks/wizard/wizard_nodes/import_date.gd" id="1"]
[node name="import_date" type="Label"]
offset_left = 660.0
offset_top = 39.0
offset_right = 774.0
offset_bottom = 53.0
size_flags_vertical = 0
text = "2022-07-18 18:01"
script = ExtResource("1")

View File

@@ -0,0 +1,20 @@
@tool
extends HBoxContainer
signal import_clicked(index)
signal edit_clicked(index)
signal removed_clicked(index)
var history_index = -1
func _on_edit_pressed():
emit_signal("edit_clicked", history_index)
func _on_reimport_pressed():
emit_signal("import_clicked", history_index)
func _on_remove_pressed():
emit_signal("removed_clicked", history_index)

View File

@@ -0,0 +1,35 @@
[gd_scene load_steps=2 format=3]
[ext_resource type="Script" path="res://addons/AsepriteWizard/interface/docks/wizard/wizard_nodes/list_actions.gd" id="1"]
[node name="actions" type="HBoxContainer"]
offset_left = 784.0
offset_top = 34.0
offset_right = 950.0
offset_bottom = 58.0
custom_constants/separation = 5
script = ExtResource( 1 )
[node name="edit" type="Button" parent="."]
offset_right = 36.0
offset_bottom = 20.0
size_flags_vertical = 0
text = "Edit"
[node name="reimport" type="Button" parent="."]
offset_left = 41.0
offset_right = 97.0
offset_bottom = 20.0
size_flags_vertical = 0
text = "Import"
[node name="remove_at" type="Button" parent="."]
offset_left = 102.0
offset_right = 166.0
offset_bottom = 20.0
size_flags_vertical = 0
text = "Remove"
[connection signal="pressed" from="edit" to="." method="_on_edit_pressed"]
[connection signal="pressed" from="reimport" to="." method="_on_reimport_pressed"]
[connection signal="pressed" from="remove_at" to="." method="_on_remove_pressed"]

View File

@@ -0,0 +1,12 @@
[gd_scene format=2]
[node name="output_path" type="LineEdit"]
offset_left = 450.0
offset_top = 34.0
offset_right = 650.0
offset_bottom = 58.0
minimum_size = Vector2( 200, 0 )
size_flags_vertical = 0
text = "/some/output"
align = 3
editable = false

View File

@@ -0,0 +1,6 @@
@tool
extends LineEdit
func set_entry(entry: Dictionary):
self.text = entry.source_file
self.tooltip_text = entry.source_file

View File

@@ -0,0 +1,18 @@
[gd_scene load_steps=2 format=3]
[ext_resource type="Script" path="res://addons/AsepriteWizard/interface/docks/wizard/wizard_nodes/source_path.gd" id="1"]
[node name="source_path" type="LineEdit"]
offset_top = 34.0
offset_right = 440.0
offset_bottom = 58.0
minimum_size = Vector2( 200, 0 )
tooltip_text = "Output name / prefix: some_name
Ex. Pattern: $_
Split: Yes
Only Visible: No
No Resource: No"
size_flags_vertical = 0
text = "/some/very/long/source/path/to/test/field"
editable = false
script = ExtResource( 1 )