Browse Source

Add sources

levelz
Alice Gaudon 1 year ago
commit
1c4873e103
  1. 15
      .gitignore
  2. 21
      addons/aseprite_importer/LICENSE
  3. 174
      addons/aseprite_importer/classes/AsepriteImportData.gd
  4. 153
      addons/aseprite_importer/classes/AsepriteImporter.gd
  5. 26
      addons/aseprite_importer/classes/EditorTheme.gd
  6. 156
      addons/aseprite_importer/interface/Main.gd
  7. 100
      addons/aseprite_importer/interface/Main.tscn
  8. BIN
      addons/aseprite_importer/interface/icons/dark_icon.png
  9. 34
      addons/aseprite_importer/interface/icons/dark_icon.png.import
  10. BIN
      addons/aseprite_importer/interface/icons/light_icon.png
  11. 34
      addons/aseprite_importer/interface/icons/light_icon.png.import
  12. 75
      addons/aseprite_importer/interface/import_menu/JSONImportMenu.gd
  13. 78
      addons/aseprite_importer/interface/import_menu/JSONImportMenu.tscn
  14. 64
      addons/aseprite_importer/interface/import_menu/SelectAnimationPlayerMenu.gd
  15. 53
      addons/aseprite_importer/interface/import_menu/SelectAnimationPlayerMenu.tscn
  16. 144
      addons/aseprite_importer/interface/import_menu/SelectNodeDialog.gd
  17. 98
      addons/aseprite_importer/interface/import_menu/SelectNodeDialog.tscn
  18. 81
      addons/aseprite_importer/interface/import_menu/SelectSpriteMenu.gd
  19. 43
      addons/aseprite_importer/interface/import_menu/SelectSpriteMenu.tscn
  20. 202
      addons/aseprite_importer/interface/import_menu/TagsMenu.gd
  21. 41
      addons/aseprite_importer/interface/import_menu/TagsMenu.tscn
  22. 95
      addons/aseprite_importer/interface/spritesheet_inspector/ColorMenuItem.gd
  23. 37
      addons/aseprite_importer/interface/spritesheet_inspector/ColorMenuItem.tscn
  24. 74
      addons/aseprite_importer/interface/spritesheet_inspector/SettingsMenu.gd
  25. 246
      addons/aseprite_importer/interface/spritesheet_inspector/SpritesheetInspector.gd
  26. 255
      addons/aseprite_importer/interface/spritesheet_inspector/SpritesheetInspector.tscn
  27. 315
      addons/aseprite_importer/interface/spritesheet_inspector/SpritesheetView.gd
  28. 48
      addons/aseprite_importer/interface/spritesheet_inspector/SpritesheetView.tscn
  29. BIN
      addons/aseprite_importer/interface/spritesheet_inspector/godot_button/godot_hover.png
  30. 34
      addons/aseprite_importer/interface/spritesheet_inspector/godot_button/godot_hover.png.import
  31. BIN
      addons/aseprite_importer/interface/spritesheet_inspector/godot_button/godot_normal.png
  32. 34
      addons/aseprite_importer/interface/spritesheet_inspector/godot_button/godot_normal.png.import
  33. BIN
      addons/aseprite_importer/interface/spritesheet_inspector/godot_button/godot_pressed.png
  34. 34
      addons/aseprite_importer/interface/spritesheet_inspector/godot_button/godot_pressed.png.import
  35. 7
      addons/aseprite_importer/plugin.cfg
  36. 101
      addons/aseprite_importer/plugin.gd
  37. 7
      default_env.tres
  38. 8
      dialogues/intro_1.json
  39. BIN
      fonts/EnterCommand-Bold.ttf
  40. BIN
      fonts/EnterCommand-Italic.ttf
  41. BIN
      fonts/EnterCommand.ttf
  42. 7
      fonts/dialog_default_font.tres
  43. BIN
      icon.png
  44. 34
      icon.png.import
  45. BIN
      images/Ely_Sitting.png
  46. 34
      images/Ely_Sitting.png.import
  47. BIN
      images/campfire.png
  48. 34
      images/campfire.png.import
  49. 107
      images/campfire.tres
  50. 555
      images/ely.tres
  51. BIN
      images/herbert_Eyes.png
  52. 34
      images/herbert_Eyes.png.import
  53. BIN
      images/herbert_FirstStep.png
  54. 34
      images/herbert_FirstStep.png.import
  55. BIN
      images/herbert_SecondStep.png
  56. 34
      images/herbert_SecondStep.png.import
  57. BIN
      images/menu.png
  58. 34
      images/menu.png.import
  59. BIN
      images/titleCampfire_loop.png
  60. 34
      images/titleCampfire_loop.png.import
  61. BIN
      images/titleCampfire_start.png
  62. 34
      images/titleCampfire_start.png.import
  63. BIN
      images/titleCrab.png
  64. 34
      images/titleCrab.png.import
  65. BIN
      images/titleEly_idle.png
  66. 34
      images/titleEly_idle.png.import
  67. BIN
      images/titleEly_start.png
  68. 34
      images/titleEly_start.png.import
  69. 401
      images/title_background.tres
  70. 497
      images/title_background_campfire.tres
  71. BIN
      images/ui/brassy_frame.png
  72. 34
      images/ui/brassy_frame.png.import
  73. BIN
      images/ui/dialogue_bg.png
  74. 34
      images/ui/dialogue_bg.png.import
  75. 87
      project.godot
  76. 35
      scenes/campfire.tscn
  77. 196
      scenes/dialogue.tscn
  78. 90
      scenes/main_menu.tscn
  79. 6
      scenes/startup.tscn
  80. 22
      scripts/DialogueAction.gd
  81. 45
      scripts/DialogueBox.gd
  82. 26
      scripts/DialogueDatabase.gd
  83. 12
      scripts/menu/MainMenu.gd
  84. 3
      scripts/menu/MenuButton.gd
  85. 10
      scripts/menu/title_background.gd
  86. 6
      scripts/pause_menu.gd
  87. 15
      scripts/scenes/IntroScript.gd
  88. 4
      scripts/scenes/startup.gd

15
.gitignore

@ -0,0 +1,15 @@
.idea/
### Godot ###
# Godot-specific ignores
.import/
export.cfg
export_presets.cfg
# Imported translations (automatically generated from CSV files)
*.translation
# Mono-specific ignores
.mono/
data_*/

21
addons/aseprite_importer/LICENSE

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Hector Margittay
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

174
addons/aseprite_importer/classes/AsepriteImportData.gd

@ -0,0 +1,174 @@
tool
extends Node
class_name AsepriteImportData
enum Error{
OK,
ERR_JSON_PARSE_ERROR,
ERR_INVALID_JSON_DATA,
}
const FRAME_TEMPLATE = {
frame = {
x = TYPE_INT,
y = TYPE_INT,
w = TYPE_INT,
h = TYPE_INT,
},
spriteSourceSize = {
x = TYPE_INT,
y = TYPE_INT,
w = TYPE_INT,
h = TYPE_INT,
},
sourceSize = {
w = TYPE_INT,
h = TYPE_INT,
},
duration = TYPE_INT,
}
const META_TEMPLATE = {
frameTags = [
{
name = TYPE_STRING,
from = TYPE_INT,
to = TYPE_INT,
direction = TYPE_STRING
},
],
size = {
w = TYPE_INT,
h = TYPE_INT,
},
}
var json_filepath : String
var json_data : Dictionary
func load(filepath : String) -> int:
var file := File.new()
var error := file.open(filepath, File.READ)
if error != OK:
return error
var file_text = file.get_as_text()
file.close()
var json := JSON.parse(file_text)
if json.error != OK:
return Error.ERR_JSON_PARSE_ERROR
if not _validate_json(json):
return Error.ERR_INVALID_JSON_DATA
json_filepath = filepath
json_data = json.result
return OK
func get_frame_array() -> Array:
if not json_data:
return []
var frame_data = json_data.frames
if frame_data is Dictionary:
return frame_data.values()
return frame_data
func get_image_filename() -> String:
if not (json_data and json_data.meta.has("image")):
return ""
return json_data.meta.image
func get_image_size() -> Vector2:
if not json_data:
return Vector2.ZERO
var image_size : Dictionary = json_data.meta.size
return Vector2(
image_size.w,
image_size.h
)
func get_tag(tag_idx : int) -> Dictionary:
var tags := get_tags()
if tag_idx >= 0 and tag_idx < tags.size():
return tags[tag_idx]
return {}
func get_tags() -> Array:
if not json_data:
return []
return json_data.meta.frameTags
static func _validate_json(json : JSONParseResult) -> bool:
var data : Dictionary = json.result
if not (data is Dictionary and data.has_all(["frames", "meta"])):
return false
# "frames" validation
var frames = data.frames
var is_hash := frames is Dictionary
for frame in frames:
if is_hash:
frame = frames[frame]
if not _match_template(frame, FRAME_TEMPLATE):
return false
# "meta" validation
return _match_template(data.meta, META_TEMPLATE)
"""
This helper function recursively walks an Array or a Dictionary checking if each
children's type matches the template
"""
static func _match_template(data, template) -> bool:
match typeof(template):
TYPE_INT:
# When parsed, the JSON interprets integer values as floats
if template == TYPE_INT and typeof(data) == TYPE_REAL:
return true
return typeof(data) == template
TYPE_DICTIONARY:
if typeof(data) != TYPE_DICTIONARY:
return false
if not data.has_all(template.keys()):
return false
for key in template:
if not _match_template(data[key], template[key]):
return false
TYPE_ARRAY:
if typeof(data) != TYPE_ARRAY:
return false
if data.empty():
return false
for element in data:
if not _match_template(element, template[0]):
return false
return true

153
addons/aseprite_importer/classes/AsepriteImporter.gd

@ -0,0 +1,153 @@
tool
extends Node
class_name AsepriteImporter
enum Error{
OK,
INVALID_JSON_DATA,
MISSING_JSON_DATA,
MISSING_ANIMATION_PLAYER,
MISSING_SPRITE,
NO_TAGS_SELECTED,
DUPLICATE_TAG_NAME,
MISSING_TEXTURE,
}
static func generate_animations(import_data : AsepriteImportData, selected_tags : Array,
animation_player : AnimationPlayer, sprite : Node, texture : Texture) -> int:
if not(import_data and import_data.json_data):
return Error.MISSING_JSON_DATA
var frame_tags : Array = import_data.get_tags()
if not selected_tags:
return Error.NO_TAGS_SELECTED
else:
var tag_names := []
for tag_idx in selected_tags:
var tag_name : String = frame_tags[tag_idx].name
if tag_names.has(tag_name):
return Error.DUPLICATE_TAG_NAME
else:
tag_names.append(tag_name)
if not animation_player:
return Error.MISSING_ANIMATION_PLAYER
if not(sprite is Sprite or sprite is Sprite3D):
return Error.MISSING_SPRITE
if texture == null:
return Error.MISSING_TEXTURE
var animation_root_path := animation_player.root_node
var animation_root_node := animation_player.get_node(animation_root_path)
var sprite_relative_path := str(animation_root_node.get_path_to(sprite))
# These are tracks that will be used
var tracks := {
"region" : {
path = (sprite_relative_path + ":region_rect"),
},
"offset" : {
path = (sprite_relative_path + ":offset")
}
}
var frames := import_data.get_frame_array()
var is_sprite3d := sprite is Sprite3D
# Iterate over each tag (animation)
for tag_idx in selected_tags:
var tag : Dictionary = frame_tags[tag_idx]
var animation : Animation
# Check if the animation already exists
if animation_player.has_animation(tag.name):
animation = animation_player.get_animation(tag.name)
else:
# If it doesn't, adds a new one
animation = Animation.new()
# warning-ignore:return_value_discarded
animation_player.add_animation(tag.name, animation)
# Setup the animation tracks
for track_name in tracks:
var track : Dictionary = tracks[track_name]
track.idx = animation.find_track(track.path)
# Checks if the track doesn't exist
if track.idx == -1:
# Create a new_track
track.idx = animation.add_track(Animation.TYPE_VALUE)
animation.track_set_path(track.idx, track.path)
else:
# Remove all existing keys from the track
for key_idx in range(animation.track_get_key_count(track.idx)):
animation.track_remove_key(track.idx, 0)
# Set the track Interpolation Mode to Nearest
animation.track_set_interpolation_type(track.idx, Animation.INTERPOLATION_NEAREST)
#Enable the track
animation.track_set_enabled(track.idx, true)
var time := 0.0
var frame_idxs := range(tag.from, tag.to + 1)
# Modify the frame order based on the tag's direction
match tag.direction:
"reverse":
frame_idxs.invert()
"pingpong":
var pong_frame_idxs := range(tag.from + 1, tag.to)
pong_frame_idxs.invert()
frame_idxs += pong_frame_idxs
# Insert the new keys
for i in frame_idxs:
var frame : Dictionary = frames[i]
# Get the region of the spritesheet that has the frame
var rect = frame.frame
var region = Rect2(rect.x, rect.y, rect.w, rect.h)
# Insert the new key for the region track
animation.track_insert_key(tracks.region.idx, time, region)
# Get the center of the frame in the original size
var source_size : Dictionary = frame.sourceSize
var source_center_x : float = source_size.w / 2
var source_center_y : float = source_size.h / 2
# Get the center of the trimmed frame in the spritesheet
var trim_rect : Dictionary = frame.spriteSourceSize
var trim_rect_center_x : float = trim_rect.x + (trim_rect.w / 2)
var trim_rect_center_y : float = trim_rect.y + (trim_rect.h / 2)
# Calculate the offset between the trimmed frame center and original frame center
var offset_x := trim_rect_center_x - source_center_x
var offset_y := trim_rect_center_y - source_center_y
# Invert the vertical offset when the selected sprite is a Sprite3D
if is_sprite3d:
offset_y *= -1
# Insert the new key for the offset track
animation.track_insert_key(tracks.offset.idx, time, Vector2(offset_x, offset_y))
# Add up the current frame's duration for the next key position
time += frame.duration / 1000
# Set the animation length equal to the sum of all frame's durations
animation.length = time
sprite.texture = texture
sprite.region_enabled = true
sprite.centered = true
return OK

26
addons/aseprite_importer/classes/EditorTheme.gd

@ -0,0 +1,26 @@
tool
extends Node
class_name EditorTheme
var _theme : Theme
func _init(theme : Theme) -> void:
_theme = theme
func get_color(color_name : String, color_list := "Editor") -> Color:
return _theme.get_color(color_name, color_list)
func get_font(font_name : String, font_list := "EditorFonts") -> Font:
return _theme.get_font(font_name, font_list)
func get_icon(icon_name : String, icon_list := "EditorIcons") -> Texture:
return _theme.get_icon(icon_name, icon_list)
func get_stylebox(stylebox_name : String, stylebox_list := "EditorStyles") -> StyleBox:
return _theme.get_stylebox(stylebox_name, stylebox_list)

156
addons/aseprite_importer/interface/Main.gd

@ -0,0 +1,156 @@
tool
extends PanelContainer
onready var import_menu : Container = $Body/ImportMenu
onready var steps : Container = import_menu.get_node("Steps")
onready var json_import_menu : Container = steps.get_node("JSONImportMenu")
onready var tags_menu : Container = steps.get_node("TagsMenu")
onready var select_animation_player_menu = steps.get_node("SelectAnimationPlayerMenu")
onready var select_sprite_menu = steps.get_node("SelectSpriteMenu")
onready var generate_button : Button = steps.get_node("GenerateButton")
onready var spritesheet_inspector : Container = $Body/SpritesheetInspector
onready var alert_dialog : AcceptDialog = $AlertDialog
const ERROR_MSG := {
AsepriteImporter.Error.MISSING_JSON_DATA : "Missing JSON Data!",
AsepriteImporter.Error.MISSING_ANIMATION_PLAYER : "Select an AnimationPlayer node!",
AsepriteImporter.Error.MISSING_SPRITE : "Select a Sprite node!",
AsepriteImporter.Error.NO_TAGS_SELECTED : "No tags selected to import!",
AsepriteImporter.Error.DUPLICATE_TAG_NAME : "Two or more of the selected tags share the same name\nSelect only tags with distinct names",
AsepriteImporter.Error.MISSING_TEXTURE: "No texture selected!",
}
const IMPORT_MENU_INITIAL_WIDTH := 300
var import_data : AsepriteImportData
var _is_ready := false
signal animations_generated(animation_player)
func _ready() -> void:
import_menu.rect_size.x = IMPORT_MENU_INITIAL_WIDTH
alert_dialog.set_as_toplevel(true)
json_import_menu.connect("data_imported", self, "_on_JSONImportMenu_data_imported")
json_import_menu.connect("data_cleared", self, "_on_JSONImportMenu_data_cleared")
tags_menu.connect("frame_selected", self, "_on_TagSelectMenu_frame_selected")
tags_menu.connect("tag_selected", self, "_on_TagSelectMenu_tag_selected")
generate_button.connect("pressed", self, "_on_GenerateButton_pressed")
func get_state() -> Dictionary:
var state := {
"import_data" : import_data,
"tags_menu" : tags_menu.get_state(),
"select_sprite_menu" : select_sprite_menu.get_state(),
"select_animation_player_menu" : select_animation_player_menu.get_state(),
"spritesheet_inspector" : spritesheet_inspector.get_state(),
}
return state
func set_state(new_state : Dictionary) -> void:
var json_filepath := ""
var tags := []
var selected_tags := []
if new_state.get("import_data", false):
import_data = new_state.import_data
json_filepath = import_data.json_filepath
tags = import_data.get_tags()
spritesheet_inspector.frames = import_data.get_frame_array()
# var selected_tag := import_data.get_tag(tag_name)
# if selected_tag:
# spritesheet_inspector.select_frames(range(selected_tag.from, selected_tag.to + 1))
else:
import_data = null
new_state.erase("tags_menu")
# new_state.erase("spritesheet_inspector")
json_import_menu.set_json_filepath(json_filepath)
select_sprite_menu.set_state(new_state.get("select_sprite_menu", {}))
select_animation_player_menu.set_state(new_state.get("select_animation_player_menu", {}))
spritesheet_inspector.set_state(new_state.get("spritesheet_inspector", {}))
tags_menu.load_tags(tags)
tags_menu.set_state(new_state.get("tags_menu", {}))
func _show_alert(message : String) -> void:
alert_dialog.dialog_text = message
alert_dialog.popup_centered()
func _update_theme(editor_theme : EditorTheme) -> void:
generate_button.icon = editor_theme.get_icon("ImportCheck")
# Signal Callbacks
func _on_GenerateButton_pressed() -> void:
var selected_tags : Array = tags_menu.get_selected_tags()
var animation_player : AnimationPlayer = select_animation_player_menu.animation_player
var sprite : Node = select_sprite_menu.sprite
var texture : Texture = spritesheet_inspector.get_texture()
var error := AsepriteImporter.generate_animations(import_data, selected_tags, animation_player, sprite, texture)
if error != OK:
var error_msg : String
if ERROR_MSG.has(error):
error_msg = ERROR_MSG[error]
else:
error_msg = "An error ocurred!"
_show_alert(error_msg)
else:
emit_signal("animations_generated", animation_player)
func _on_JSONImportMenu_data_imported(new_import_data : AsepriteImportData) -> void:
import_data = new_import_data
var tags : Array = import_data.get_tags()
tags_menu.load_tags(tags)
var json_filepath := import_data.json_filepath
var json_dir_path := json_filepath.rsplit("/", true, 1)[0]
var image_filepath := ""
var image_filename := import_data.get_image_filename()
image_filepath = str(json_dir_path, "/", image_filename)
spritesheet_inspector.texture_size = import_data.get_image_size()
spritesheet_inspector.frames = import_data.get_frame_array()
spritesheet_inspector.load_texture(image_filepath)
func _on_JSONImportMenu_data_cleared() -> void:
import_data = null
spritesheet_inspector.clear_texture()
tags_menu.clear_options()
func _on_TagSelectMenu_frame_selected(idx : int) -> void:
spritesheet_inspector.select_frames([idx])
func _on_TagSelectMenu_tag_selected(tag_idx : int) -> void:
var selected_tag := import_data.get_tag(tag_idx)
spritesheet_inspector.select_frames(range(selected_tag.from, selected_tag.to + 1))

100
addons/aseprite_importer/interface/Main.tscn

@ -0,0 +1,100 @@
[gd_scene load_steps=9 format=2]
[ext_resource path="res://addons/aseprite_importer/interface/Main.gd" type="Script" id=1]
[ext_resource path="res://addons/aseprite_importer/interface/import_menu/SelectAnimationPlayerMenu.tscn" type="PackedScene" id=2]
[ext_resource path="res://addons/aseprite_importer/interface/import_menu/JSONImportMenu.tscn" type="PackedScene" id=3]
[ext_resource path="res://addons/aseprite_importer/interface/import_menu/TagsMenu.tscn" type="PackedScene" id=4]
[ext_resource path="res://addons/aseprite_importer/interface/import_menu/SelectSpriteMenu.tscn" type="PackedScene" id=5]
[ext_resource path="res://addons/aseprite_importer/interface/spritesheet_inspector/SpritesheetInspector.tscn" type="PackedScene" id=6]
[sub_resource type="Image" id=3]
data = {
"data": PoolByteArray( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114, 229, 127, 0, 113, 241, 127, 0, 113, 240, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114, 229, 127, 0, 114, 229, 127, 20, 113, 241, 127, 184, 113, 240, 127, 144, 113, 240, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114, 229, 127, 0, 114, 229, 127, 20, 114, 241, 127, 210, 115, 242, 128, 255, 114, 241, 127, 170, 114, 241, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114, 229, 127, 0, 114, 229, 127, 20, 114, 241, 126, 209, 115, 242, 128, 255, 114, 241, 127, 210, 109, 230, 121, 21, 109, 230, 121, 0, 0, 0, 0, 0, 113, 240, 127, 0, 113, 241, 127, 0, 114, 229, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 235, 123, 0, 114, 229, 127, 20, 114, 241, 127, 208, 115, 242, 128, 255, 114, 241, 127, 210, 104, 231, 127, 22, 106, 230, 124, 0, 0, 0, 0, 0, 113, 240, 127, 0, 113, 240, 127, 144, 113, 241, 127, 184, 114, 229, 127, 20, 114, 229, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 240, 123, 0, 107, 241, 120, 19, 114, 241, 126, 207, 115, 242, 128, 255, 114, 241, 126, 211, 104, 231, 127, 22, 104, 231, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114, 241, 127, 0, 114, 241, 127, 170, 115, 242, 128, 255, 114, 241, 127, 210, 114, 229, 127, 20, 114, 229, 127, 0, 113, 240, 127, 0, 113, 240, 127, 18, 114, 241, 126, 207, 115, 242, 128, 255, 114, 241, 127, 212, 104, 231, 127, 22, 104, 231, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 230, 121, 0, 109, 230, 121, 21, 114, 241, 127, 210, 115, 242, 128, 255, 114, 241, 126, 209, 114, 229, 127, 20, 113, 240, 127, 18, 114, 241, 126, 207, 115, 242, 128, 255, 114, 241, 126, 213, 104, 231, 127, 22, 104, 231, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 230, 124, 0, 104, 231, 127, 22, 114, 241, 127, 210, 115, 242, 128, 255, 114, 241, 126, 207, 113, 241, 127, 206, 115, 242, 128, 255, 114, 241, 126, 213, 110, 232, 121, 23, 107, 231, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104, 231, 127, 0, 104, 231, 127, 22, 114, 241, 127, 212, 115, 242, 128, 255, 115, 242, 128, 255, 114, 241, 126, 213, 106, 233, 127, 24, 108, 232, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104, 231, 127, 0, 104, 231, 127, 22, 113, 241, 127, 186, 114, 241, 126, 187, 106, 233, 127, 24, 106, 233, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104, 231, 127, 0, 113, 241, 127, 0, 114, 241, 126, 0, 106, 233, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ),
"format": "RGBA8",
"height": 16,
"mipmaps": false,
"width": 16
}
[sub_resource type="ImageTexture" id=2]
flags = 0
flags = 0
image = SubResource( 3 )
size = Vector2( 16, 16 )
[node name="Main" type="PanelContainer"]
anchor_right = 1.0
anchor_bottom = 1.0
size_flags_horizontal = 3
size_flags_vertical = 3
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Body" type="HSplitContainer" parent="."]
margin_left = 7.0
margin_top = 7.0
margin_right = 1017.0
margin_bottom = 593.0
size_flags_vertical = 3
[node name="ImportMenu" type="ScrollContainer" parent="Body"]
margin_right = 300.0
margin_bottom = 586.0
rect_min_size = Vector2( 300, 0 )
size_flags_vertical = 3
follow_focus = true
scroll_horizontal_enabled = false
scroll_horizontal = 100
[node name="Steps" type="VBoxContainer" parent="Body/ImportMenu"]
margin_right = 300.0
margin_bottom = 586.0
size_flags_horizontal = 3
size_flags_vertical = 3
custom_constants/separation = 12
[node name="JSONImportMenu" parent="Body/ImportMenu/Steps" instance=ExtResource( 3 )]
margin_right = 300.0
[node name="TagsMenu" parent="Body/ImportMenu/Steps" instance=ExtResource( 4 )]
margin_top = 50.0
margin_right = 300.0
margin_bottom = 432.0
[node name="SelectAnimationPlayerMenu" parent="Body/ImportMenu/Steps" instance=ExtResource( 2 )]
margin_top = 444.0
margin_right = 300.0
margin_bottom = 484.0
[node name="SelectSpriteMenu" parent="Body/ImportMenu/Steps" instance=ExtResource( 5 )]
margin_top = 496.0
margin_right = 300.0
margin_bottom = 536.0
[node name="HSeparator" type="HSeparator" parent="Body/ImportMenu/Steps"]
margin_top = 548.0
margin_right = 300.0
margin_bottom = 552.0
[node name="GenerateButton" type="Button" parent="Body/ImportMenu/Steps"]
margin_top = 564.0
margin_right = 300.0
margin_bottom = 586.0
hint_tooltip = "Generate the animations in the selected AnimationPlayer node"
size_flags_horizontal = 3
text = "Generate Animations"
icon = SubResource( 2 )
[node name="SpritesheetInspector" parent="Body" instance=ExtResource( 6 )]
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 312.0
margin_right = 1010.0
margin_bottom = 586.0
[node name="AlertDialog" type="AcceptDialog" parent="."]
margin_right = 83.0
margin_bottom = 58.0
popup_exclusive = true

BIN
addons/aseprite_importer/interface/icons/dark_icon.png

After

Width: 16  |  Height: 16  |  Size: 226 B

34
addons/aseprite_importer/interface/icons/dark_icon.png.import

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/dark_icon.png-bd7f807ed17ce703bf3818e1cafe2892.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/aseprite_importer/interface/icons/dark_icon.png"
dest_files=[ "res://.import/dark_icon.png-bd7f807ed17ce703bf3818e1cafe2892.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

BIN
addons/aseprite_importer/interface/icons/light_icon.png

After

Width: 16  |  Height: 16  |  Size: 225 B

34
addons/aseprite_importer/interface/icons/light_icon.png.import

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/light_icon.png-7736224c34e6f06ad3ecf9b37cd89cab.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/aseprite_importer/interface/icons/light_icon.png"
dest_files=[ "res://.import/light_icon.png-7736224c34e6f06ad3ecf9b37cd89cab.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

75
addons/aseprite_importer/interface/import_menu/JSONImportMenu.gd

@ -0,0 +1,75 @@
tool
extends Container
onready var import_button : Button = $InputContainer/ImportButton
onready var clear_button : Button = $InputContainer/ClearButton
onready var file_dialog : FileDialog = $FileDialog
onready var alert_dialog : AcceptDialog = $AlertDialog
const IMPORT_BUTTON_DEFAULT_TEXT = "Import JSON"
signal data_imported(import_data)
signal data_cleared
func _ready():
clear_button.hide()
alert_dialog.set_as_toplevel(true)
import_button.connect("pressed", self, "_on_ImportButton_pressed")
clear_button.connect("pressed", self, "_on_ClearButton_pressed")
file_dialog.connect("file_selected", self, "_on_FileDialog_file_selected")
func set_json_filepath(new_filepath : String) -> void:
if new_filepath:
import_button.text = new_filepath
clear_button.show()
else:
import_button.text = IMPORT_BUTTON_DEFAULT_TEXT
clear_button.hide()
func _update_theme(editor_theme : EditorTheme) -> void:
import_button.icon = editor_theme.get_icon("Load")
clear_button.icon = editor_theme.get_icon("Clear")
#Signal Callbacks
func _on_ImportButton_pressed() -> void:
file_dialog.popup_centered_ratio(0.5)
func _on_ClearButton_pressed() -> void:
set_json_filepath("")
emit_signal("data_cleared")
func _on_FileDialog_file_selected(path : String) -> void:
var import_data := AsepriteImportData.new()
var error := import_data.load(path)
if error != OK:
var error_msg : String
match error:
AsepriteImportData.Error.JSON_PARSE_ERROR:
error_msg = "Error parsing the file"
AsepriteImportData.Error.INVALID_JSON_DATA:
error_msg = "Invalid Aseprite JSON file"
var code:
error_msg = "An error occurred!\nerror code: %d" % code
set_json_filepath("")
yield(get_tree(), "idle_frame")
alert_dialog.dialog_text = error_msg
alert_dialog.popup_centered()
else:
set_json_filepath(path)
emit_signal("data_imported", import_data)

78
addons/aseprite_importer/interface/import_menu/JSONImportMenu.tscn

@ -0,0 +1,78 @@
[gd_scene load_steps=4 format=2]
[ext_resource path="res://addons/aseprite_importer/interface/import_menu/JSONImportMenu.gd" type="Script" id=1]
[sub_resource type="Image" id=3]
data = {
"data": PoolByteArray( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 223, 223, 223, 0, 223, 223, 223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 223, 223, 223, 0, 223, 223, 223, 179, 223, 223, 223, 179, 223, 223, 223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 223, 223, 223, 0, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 223, 223, 223, 0, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 223, 223, 223, 0, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 223, 223, 223, 0, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 0, 223, 223, 223, 0, 223, 223, 223, 0, 223, 223, 223, 0, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 0, 223, 223, 223, 0, 223, 223, 223, 0, 220, 220, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 0, 220, 220, 220, 59, 223, 223, 223, 201, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 200, 220, 220, 220, 59, 220, 220, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 222, 222, 222, 0, 222, 222, 222, 199, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 222, 222, 222, 198, 222, 222, 222, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 223, 223, 223, 0, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 223, 223, 223, 0, 223, 223, 223, 0, 223, 223, 223, 0, 223, 223, 223, 0, 223, 223, 223, 0, 223, 223, 223, 0, 223, 223, 223, 0, 223, 223, 223, 0, 223, 223, 223, 0, 223, 223, 223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 223, 223, 223, 0, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 223, 223, 223, 0, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 223, 223, 223, 0, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 254, 223, 223, 223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 223, 223, 223, 0, 223, 223, 223, 254, 223, 223, 223, 203, 223, 223, 223, 203, 223, 223, 223, 152, 223, 223, 223, 152, 222, 222, 222, 101, 222, 222, 222, 101, 219, 219, 219, 50, 219, 219, 219, 50, 221, 221, 221, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 223, 223, 223, 0, 223, 223, 223, 0, 223, 223, 223, 0, 223, 223, 223, 0, 223, 223, 223, 0, 222, 222, 222, 0, 222, 222, 222, 0, 219, 219, 219, 0, 219, 219, 219, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ),
"format": "RGBA8",
"height": 16,
"mipmaps": false,
"width": 16
}
[sub_resource type="ImageTexture" id=2]
flags = 0
flags = 0
image = SubResource( 3 )
size = Vector2( 16, 16 )
[node name="JSONImport" type="VBoxContainer"]
margin_right = 91.0
margin_bottom = 38.0
size_flags_horizontal = 3
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Label" type="Label" parent="."]
margin_right = 91.0
margin_bottom = 14.0
text = "JSON Data"
valign = 1
[node name="InputContainer" type="HBoxContainer" parent="."]
margin_top = 18.0
margin_right = 91.0
margin_bottom = 38.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="ImportButton" type="Button" parent="InputContainer"]
margin_right = 91.0
margin_bottom = 20.0
hint_tooltip = "Import a Aseprite JSON file"
size_flags_horizontal = 3
text = "Import JSON"
[node name="ClearButton" type="Button" parent="InputContainer"]
visible = false
margin_left = 143.0
margin_top = -18.0
margin_right = 187.0
margin_bottom = 2.0
text = "Clear"
icon = SubResource( 2 )
[node name="FileDialog" type="FileDialog" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
margin_bottom = 110.0
window_title = "Select the JSON file"
resizable = true
mode_overrides_title = false
mode = 0
filters = PoolStringArray( "*.json ; JSON Files" )
show_hidden_files = true
[node name="AlertDialog" type="AcceptDialog" parent="."]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_top = 42.0
margin_right = 400.0
margin_bottom = 100.0
popup_exclusive = true

64
addons/aseprite_importer/interface/import_menu/SelectAnimationPlayerMenu.gd

@ -0,0 +1,64 @@
tool
extends Container
onready var select_button : Button = $Button
onready var select_node_dialog : WindowDialog = $SelectNodeDialog
const SELECT_BUTTON_DEFAULT_TEXT := "Select a Node"
var animation_player : AnimationPlayer setget set_animation_player
signal node_selected(animation_player)
func _ready():
select_node_dialog.class_filters = ["AnimationPlayer"]
select_button.connect("pressed", self, "_on_SelectButton_pressed")
select_node_dialog.connect("node_selected", self, "_on_SelectNodeDialog_node_selected")
func get_state() -> Dictionary:
var state := {}
if animation_player:
state.animation_player = animation_player
return state
func set_state(new_state : Dictionary) -> void:
var new_animation_player : Node = new_state.get("animation_player")
if new_animation_player != null :
self.animation_player = new_animation_player
else:
animation_player = null
select_button.text = SELECT_BUTTON_DEFAULT_TEXT
func _update_theme(editor_theme : EditorTheme) -> void:
select_button.icon = editor_theme.get_icon("AnimationPlayer")
# Setters and Getters
func set_animation_player(node : AnimationPlayer) -> void:
animation_player = node
var node_path := node.owner.get_parent().get_path_to(node)
select_button.text = node_path
# Signal Callbacks
func _on_SelectButton_pressed() -> void:
if select_node_dialog.initialize():
select_node_dialog.popup_centered_ratio(.5)
func _on_SelectNodeDialog_node_selected(selected_node : Node) -> void:
self.animation_player = selected_node
emit_signal("node_selected", selected_node)

53
addons/aseprite_importer/interface/import_menu/SelectAnimationPlayerMenu.tscn

@ -0,0 +1,53 @@
[gd_scene load_steps=5 format=2]
[ext_resource path="res://addons/aseprite_importer/interface/import_menu/SelectNodeDialog.tscn" type="PackedScene" id=1]
[ext_resource path="res://addons/aseprite_importer/interface/import_menu/SelectAnimationPlayerMenu.gd" type="Script" id=2]
[sub_resource type="Image" id=1]
data = {
"data": PoolByteArray( 0, 0, 0, 0, 206, 164, 241, 0, 204, 159, 235, 0, 0, 0, 0, 0, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 164, 241, 0, 0, 0, 0, 0, 206, 164, 241, 0, 206, 164, 241, 255, 204, 159, 235, 40, 205, 161, 238, 0, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 255, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 255, 204, 159, 235, 40, 205, 162, 239, 0, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 255, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 255, 204, 159, 235, 40, 205, 162, 239, 0, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 255, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 255, 204, 159, 235, 40, 205, 162, 239, 0, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 255, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 255, 204, 159, 235, 40, 205, 162, 239, 0, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 255, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 255, 204, 159, 235, 40, 205, 162, 239, 0, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 255, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 255, 204, 159, 235, 40, 205, 162, 239, 0, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 255, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 255, 204, 159, 235, 40, 205, 161, 238, 0, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 255, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 255, 206, 164, 241, 0, 0, 0, 0, 0, 206, 164, 241, 0, 204, 159, 235, 0, 0, 0, 0, 0, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 0, 206, 164, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 164, 241, 0, 0, 0, 0, 0 ),
"format": "RGBA8",
"height": 16,
"mipmaps": false,
"width": 16
}
[sub_resource type="ImageTexture" id=2]
flags = 0
flags = 0
image = SubResource( 1 )
size = Vector2( 16, 16 )
[node name="SelectAnimationPlayer" type="VBoxContainer"]
margin_right = 148.0
margin_bottom = 38.0
script = ExtResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Label" type="Label" parent="."]
margin_right = 148.0
margin_bottom = 14.0
text = "Select AnimationPlayer"
[node name="Button" type="Button" parent="."]
margin_top = 18.0
margin_right = 148.0
margin_bottom = 40.0
hint_tooltip = "Select a AnimationPlayer node from the current scene"
text = "Select Node"
icon = SubResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="SelectNodeDialog" parent="." instance=ExtResource( 1 )]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 42.0
margin_right = 245.0
margin_bottom = 43.0
window_title = "Select the AnimationPlayer Node"

144
addons/aseprite_importer/interface/import_menu/SelectNodeDialog.gd

@ -0,0 +1,144 @@
tool
extends WindowDialog
onready var body : VBoxContainer = $MarginContainer/Body
onready var edited_scene_view : Container = body.get_node('EditedSceneView')
onready var scene_tree : Tree = edited_scene_view.get_node('SceneTree')
onready var footer : HBoxContainer = body.get_node('Footer')
onready var confirm_button : Button = footer.get_node('ConfirmButton')
onready var cancel_button : Button = footer.get_node('CancelButton')
onready var alert_dialog : AcceptDialog = $AlertDialog
enum Columns {
NAME,
PATH,
}
const MSG_EMPTY_SCENE = 'The current scene is empty!'
const MSG_UNSAVED_SCENE = 'The current scene is still not saved!'
const MSG_NO_FILTERED_NODES_IN_SCENE = "There aren't any %s nodes in the current scene"
const WINDOW_TITLE_DEFAULT = 'Select a Node'
const WINDOW_TITLE_WITH_FILTER = "Select the %s Node"
const DISABLED_ICON_MODULATE := Color(1, 1, 1, .5)
var class_filters : Array setget set_class_filters
var edited_scene_root : Node
var _editor_theme : EditorTheme
signal node_selected(selected_node)
func _ready():
self.class_filters = class_filters
scene_tree.columns = Columns.size()
scene_tree.set_column_expand(Columns.PATH, false)
alert_dialog.set_as_toplevel(true)
scene_tree.connect('item_activated', self, '_on_node_selected')
confirm_button.connect('pressed', self, '_on_node_selected')
cancel_button.connect('pressed', self, 'hide')
func initialize() -> bool:
edited_scene_root = get_tree().get_edited_scene_root()
if edited_scene_root == null:
_show_alert(MSG_EMPTY_SCENE)
return false
var scene_filename := edited_scene_root.filename
if not scene_filename:
_show_alert(MSG_UNSAVED_SCENE)
return false
scene_tree.clear()
var filtered_node_count := _add_node_to_scene_tree(edited_scene_root)
if class_filters and filtered_node_count == 0:
var filters_str := PoolStringArray(class_filters).join(" / ")
_show_alert(MSG_NO_FILTERED_NODES_IN_SCENE % filters_str)
return false
return true
func _add_node_to_scene_tree(node : Node, parent : TreeItem = null) -> int:
var tree_item := scene_tree.create_item(parent)
var node_class := node.get_class()
tree_item.set_icon(Columns.NAME, _editor_theme.get_icon(node_class))
tree_item.set_text(Columns.NAME, node.name)
tree_item.set_text(Columns.PATH, edited_scene_root.get_path_to(node))
var disabled_font_color := _editor_theme.get_color("disabled_font_color")
var filtered_node_count := 0
if class_filters:
var is_valid := false
for filter in class_filters:
if node.is_class(filter):
is_valid = true
filtered_node_count += 1
break
if not is_valid:
tree_item.set_selectable(Columns.NAME, false)
tree_item.set_icon_modulate(Columns.NAME, DISABLED_ICON_MODULATE)
tree_item.set_custom_color(Columns.NAME, disabled_font_color)
for child in node.get_children():
if child.owner == edited_scene_root:
filtered_node_count += _add_node_to_scene_tree(child, tree_item)
return filtered_node_count
func _show_alert(message : String) -> void:
alert_dialog.dialog_text = message
alert_dialog.popup_centered()
func _update_theme(editor_theme : EditorTheme) -> void:
_editor_theme = editor_theme
# Setters and Getters
func set_class_filters(filters : Array) -> void:
class_filters = filters
if class_filters != []:
var filters_str := PoolStringArray(class_filters).join(" / ")
window_title = WINDOW_TITLE_WITH_FILTER % filters_str
else:
window_title = WINDOW_TITLE_DEFAULT
# Signal Callbacks
func _on_node_selected() -> void:
var selected_item := scene_tree.get_selected()
if selected_item:
var node_path := selected_item.get_text(Columns.PATH)
var selected_node := edited_scene_root.get_node(node_path)
emit_signal('node_selected', selected_node)
hide()

98
addons/aseprite_importer/interface/import_menu/SelectNodeDialog.tscn

@ -0,0 +1,98 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://addons/aseprite_importer/interface/import_menu/SelectNodeDialog.gd" type="Script" id=1]
[node name="SelectNodeDialog" type="WindowDialog"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -150.0
margin_top = -100.0
margin_right = 150.0
margin_bottom = 100.0
rect_min_size = Vector2( 300, 200 )
size_flags_horizontal = 3
size_flags_vertical = 3
window_title = "Select a Node"
resizable = true
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="MarginContainer" type="MarginContainer" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
custom_constants/margin_right = 8
custom_constants/margin_top = 8
custom_constants/margin_left = 8
custom_constants/margin_bottom = 8
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Body" type="VBoxContainer" parent="MarginContainer"]
margin_left = 8.0
margin_top = 8.0
margin_right = 292.0
margin_bottom = 192.0
size_flags_horizontal = 3
size_flags_vertical = 3
__meta__ = {
"_edit_use_anchors_": false
}
[node name="EditedSceneView" type="VBoxContainer" parent="MarginContainer/Body"]
margin_right = 284.0
margin_bottom = 160.0
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="Label" type="Label" parent="MarginContainer/Body/EditedSceneView"]
margin_right = 284.0
margin_bottom = 14.0
size_flags_horizontal = 3
text = "Current Edited Scene:"
[node name="SceneTree" type="Tree" parent="MarginContainer/Body/EditedSceneView"]
margin_top = 18.0
margin_right = 284.0
margin_bottom = 160.0
size_flags_horizontal = 3
size_flags_vertical = 3
columns = 2
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Footer" type="HBoxContainer" parent="MarginContainer/Body"]
margin_top = 164.0
margin_right = 284.0
margin_bottom = 184.0
size_flags_horizontal = 3
[node name="ConfirmButton" type="Button" parent="MarginContainer/Body/Footer"]
margin_left = 25.0
margin_right = 114.0
margin_bottom = 20.0
size_flags_horizontal = 6
text = "Select Node"
[node name="CancelButton" type="Button" parent="MarginContainer/Body/Footer"]
margin_left = 187.0
margin_right = 241.0
margin_bottom = 20.0
size_flags_horizontal = 6
text = "Cancel"
[node name="AlertDialog" type="AcceptDialog" parent="."]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -41.5
margin_top = -29.0
margin_right = 41.5
margin_bottom = 29.0
popup_exclusive = true

81
addons/aseprite_importer/interface/import_menu/SelectSpriteMenu.gd

@ -0,0 +1,81 @@
tool
extends Container
onready var select_button : Button = $Button
onready var select_node_dialog : WindowDialog = $SelectNodeDialog
const SELECT_BUTTON_DEFAULT_TEXT := "Select a Node"
var sprite : Node setget set_sprite
var _sprite_icon : Texture
var _sprite3d_icon : Texture
signal node_selected(sprite)
func _ready():
select_node_dialog.class_filters = ["Sprite", "Sprite3D"]
select_button.connect("pressed", self, "_on_SelectButton_pressed")
select_node_dialog.connect("node_selected", self, "_on_SelectNodeDialog_node_selected")
func get_state() -> Dictionary:
var state := {}
if sprite:
state.sprite = sprite
return state
func set_state(new_state : Dictionary) -> void:
var new_sprite : Node = new_state.get("sprite")
if new_sprite != null:
self.sprite = new_sprite
else:
sprite = null
select_button.text = SELECT_BUTTON_DEFAULT_TEXT
select_button.icon = _sprite_icon
func _update_theme(editor_theme : EditorTheme) -> void:
var is_sprite3d := select_button.icon == _sprite3d_icon
_sprite_icon = editor_theme.get_icon("Sprite")
_sprite3d_icon = editor_theme.get_icon("Sprite3D")
if is_sprite3d:
select_button.icon = _sprite3d_icon
else:
select_button.icon = _sprite_icon
# Setters and Getters
func set_sprite(node : Node) -> void:
sprite = node
var node_path := node.owner.get_parent().get_path_to(node)
select_button.text = node_path
if node.is_class("Sprite"):
select_button.icon = _sprite_icon
elif node.is_class("Sprite3D"):
select_button.icon = _sprite3d_icon
# Signal Callbacks
func _on_SelectButton_pressed() -> void:
if select_node_dialog.initialize():
select_node_dialog.popup_centered_ratio(.5)
func _on_SelectNodeDialog_node_selected(selected_node : Node) -> void:
self.sprite = selected_node
emit_signal("node_selected", selected_node)

43
addons/aseprite_importer/interface/import_menu/SelectSpriteMenu.tscn

@ -0,0 +1,43 @@
[gd_scene load_steps=5 format=2]
[ext_resource path="res://addons/aseprite_importer/interface/import_menu/SelectNodeDialog.tscn" type="PackedScene" id=1]
[ext_resource path="res://addons/aseprite_importer/interface/import_menu/SelectSpriteMenu.gd" type="Script" id=2]
[sub_resource type="Image" id=3]
data = {
"data": PoolByteArray( 0, 0, 0, 0, 0, 0, 0, 0, 163, 182, 236, 0, 164, 182, 242, 0, 164, 182, 242, 0, 165, 183, 243, 0, 165, 183, 243, 0, 165, 183, 243, 0, 165, 183, 243, 0, 165, 183, 243, 0, 165, 183, 243, 0, 164, 182, 242, 0, 164, 182, 242, 0, 160, 179, 236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 161, 180, 236, 0, 163, 182, 236, 28, 164, 182, 242, 169, 164, 182, 242, 229, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 164, 182, 242, 229, 164, 182, 242, 169, 160, 179, 236, 27, 160, 179, 236, 0, 0, 0, 0, 0, 160, 179, 236, 0, 160, 179, 236, 27, 164, 182, 242, 236, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 164, 182, 242, 236, 160, 179, 236, 27, 160, 179, 236, 0, 164, 181, 242, 0, 164, 181, 242, 164, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 164, 181, 242, 163, 164, 181, 242, 0, 164, 182, 242, 0, 164, 182, 242, 225, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 164, 182, 242, 225, 164, 182, 242, 0, 165, 183, 243, 0, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 0, 165, 183, 243, 0, 165, 183, 243, 255, 165, 183, 243, 255, 163, 182, 240, 70, 163, 182, 240, 70, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 163, 182, 240, 70, 163, 182, 240, 70, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 0, 165, 183, 243, 0, 165, 183, 243, 255, 165, 183, 243, 255, 164, 182, 241, 0, 164, 182, 241, 0, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 164, 182, 241, 0, 164, 182, 241, 0, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 0, 165, 183, 243, 0, 165, 183, 243, 255, 165, 183, 243, 255, 164, 182, 241, 0, 164, 182, 241, 0, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 164, 182, 241, 0, 164, 182, 241, 0, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 0, 165, 183, 243, 0, 165, 183, 243, 255, 165, 183, 243, 255, 163, 182, 240, 70, 163, 182, 240, 70, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 163, 182, 240, 70, 163, 182, 240, 70, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 0, 165, 183, 243, 0, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 0, 164, 182, 242, 0, 164, 182, 242, 226, 165, 183, 243, 255, 165, 183, 243, 255, 164, 182, 242, 252, 163, 182, 241, 95, 163, 182, 241, 95, 164, 182, 242, 201, 164, 182, 242, 201, 163, 182, 241, 95, 163, 182, 241, 95, 164, 182, 242, 251, 165, 183, 243, 255, 165, 183, 243, 255, 164, 182, 242, 225, 164, 182, 242, 0, 164, 181, 242, 0, 164, 181, 242, 164, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 163, 182, 236, 28, 163, 182, 239, 0, 163, 177, 238, 0, 163, 177, 238, 0, 163, 181, 240, 0, 161, 178, 238, 30, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 164, 181, 242, 164, 164, 181, 242, 0, 160, 179, 236, 0, 160, 179, 236, 27, 164, 182, 242, 237, 165, 183, 243, 255, 165, 183, 243, 255, 164, 182, 242, 226, 163, 182, 242, 84, 163, 173, 234, 25, 163, 173, 234, 25, 165, 183, 243, 85, 164, 182, 242, 226, 165, 183, 243, 255, 165, 183, 243, 255, 164, 182, 242, 237, 160, 179, 236, 27, 160, 179, 236, 0, 0, 0, 0, 0, 161, 180, 236, 0, 163, 182, 236, 28, 164, 182, 242, 169, 164, 182, 242, 229, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 165, 183, 243, 255, 164, 182, 242, 229, 164, 182, 242, 169, 160, 179, 236, 27, 160, 179, 236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 182, 236, 0, 164, 182, 242, 0, 164, 182, 242, 0, 165, 183, 243, 0, 165, 183, 243, 0, 165, 183, 243, 0, 165, 183, 243, 0, 165, 183, 243, 0, 165, 183, 243, 0, 164, 182, 242, 0, 164, 182, 242, 0, 160, 179, 236, 0, 0, 0, 0, 0, 0, 0, 0, 0 ),
"format": "RGBA8",
"height": 16,
"mipmaps": false,
"width": 16
}
[sub_resource type="ImageTexture" id=2]
flags = 0
flags = 0
image = SubResource( 3 )
size = Vector2( 16, 16 )
[node name="SelectSprite" type="VBoxContainer"]
margin_right = 89.0
margin_bottom = 38.0
size_flags_horizontal = 3
script = ExtResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Label" type="Label" parent="."]
margin_right = 107.0
margin_bottom = 14.0
text = "Select Sprite"
[node name="Button" type="Button" parent="."]
margin_top = 18.0
margin_right = 107.0
margin_bottom = 40.0
hint_tooltip = "Select a Sprite node from the current scene"
text = "Select Node"
icon = SubResource( 2 )
[node name="SelectNodeDialog" parent="." instance=ExtResource( 1 )]

202
addons/aseprite_importer/interface/import_menu/TagsMenu.gd

@ -0,0 +1,202 @@
tool
extends Container
onready var select_all_button : CheckBox = find_node("SelectAllButton")
onready var options_list : VBoxContainer = find_node("OptionsList")
onready var tree : Tree = $Tree
enum Columns {
SELECTED,
NAME,
START,
END,
DIRECTION,
}
var _tree_root : TreeItem
var _options := []
var _toggling_option := false
signal frame_selected(idx)
signal selected_tags_changed(selected_tags)
signal tag_selected(tag_name)
func _ready():
clear_options()
tree.columns = Columns.size()
tree.set_column_expand(Columns.SELECTED, false)
tree.set_column_min_width(Columns.SELECTED, 32)
tree.set_column_title(Columns.NAME, "Name")
tree.set_column_expand(Columns.NAME, true)
tree.set_column_min_width(Columns.START, 48)
tree.set_column_title(Columns.START, "Start")
tree.set_column_expand(Columns.START, false)
tree.set_column_min_width(Columns.START, 48)
tree.set_column_title(Columns.END, "End")
tree.set_column_expand(Columns.END, false)
tree.set_column_min_width(Columns.END, 48)
tree.set_column_title(Columns.DIRECTION, "Direction")
tree.set_column_expand(Columns.DIRECTION, false)
tree.set_column_min_width(Columns.DIRECTION, 84)
tree.set_column_titles_visible(true)
select_all_button.connect("toggled", self, "_on_SelectAllButton_toggled")
tree.connect("cell_selected", self, "_on_Tree_cell_selected")
tree.connect("item_edited", self, "_on_Tree_item_edited")
func clear_options() -> void:
select_all_button.hide()
for option in _options:
option.free()
_options.clear()
tree.clear()
_tree_root = tree.create_item()
func load_tags(tags : Array) -> void:
clear_options()
if tags == []:
return
for tag in tags:
var new_tree_item := tree.create_item(_tree_root)
new_tree_item.set_cell_mode(Columns.SELECTED, TreeItem.CELL_MODE_CHECK)
new_tree_item.set_editable(Columns.SELECTED, true)
new_tree_item.set_checked(Columns.SELECTED, true)
new_tree_item.set_selectable(Columns.SELECTED, false)
new_tree_item.set_text(Columns.NAME, tag.name)
new_tree_item.set_text(Columns.START, str(floor(tag.from)))
new_tree_item.set_text_align(Columns.START, TreeItem.ALIGN_CENTER)
new_tree_item.set_text(Columns.END, str(floor(tag.to)))
new_tree_item.set_text_align(Columns.END, TreeItem.ALIGN_CENTER)
new_tree_item.set_text(Columns.DIRECTION, " %s" % tag.direction)
new_tree_item.set_selectable(Columns.DIRECTION, false)
_options.append(new_tree_item)
select_all_button.pressed = true
select_all_button.show()
func get_selected_tags() -> Array:
var selected_tags := []
for i in range(_options.size()):
var item : TreeItem = _options[i]
if item.is_checked(Columns.SELECTED):
selected_tags.append(i)
return selected_tags
func get_state() -> Dictionary:
var state := {
selected_tags = get_selected_tags()
}
var selected_item := tree.get_selected()
if selected_item != null:
var selected_column := tree.get_selected_column()
var item_idx := _options.find(selected_item)
state.selected_cell = Vector2(selected_column, item_idx)
return state
func set_state(new_state : Dictionary) -> void:
if new_state.has("selected_tags") and _options != []:
select_all_button.pressed = false
for tag in new_state.selected_tags:
_options[tag].set_checked(Columns.SELECTED, true)
if new_state.has("selected_cell"):
var selected_cell : Vector2 = new_state.selected_cell
var tree_item : TreeItem = _options[selected_cell.y]
var column : int = selected_cell.x
tree_item.select(column)
match column:
Columns.NAME:
emit_signal("tag_selected", selected_cell.y)
Columns.START, Columns.END:
emit_signal("frame_selected", int(tree_item.get_text(column)))
for option in _options:
if not option.is_checked(Columns.SELECTED):
return
_toggling_option = true
select_all_button.pressed = true
_toggling_option = false
# Signal Callbacks
func _on_SelectAllButton_toggled(button_pressed : bool) -> void:
if _toggling_option:
return
for option in _options:
option.set_checked(Columns.SELECTED, button_pressed)
emit_signal("selected_tags_changed", get_selected_tags())
func _on_Tree_cell_selected() -> void:
var selected_column := tree.get_selected_column()
var selected_item := tree.get_selected()
match selected_column:
Columns.NAME:
emit_signal("tag_selected", _options.find(selected_item))
Columns.START, Columns.END:
emit_signal("frame_selected", int(selected_item.get_text(selected_column)))
func _on_Tree_item_edited() -> void:
_toggling_option = true
if select_all_button.pressed:
for option in _options:
if option.is_checked(Columns.SELECTED):
select_all_button.pressed = false
break
else:
var is_all_selected := true
for option in _options:
if not option.is_checked(Columns.SELECTED):
is_all_selected = false
break
if is_all_selected:
select_all_button.pressed = true
_toggling_option = false
emit_signal("selected_tags_changed", get_selected_tags())

41
addons/aseprite_importer/interface/import_menu/TagsMenu.tscn

@ -0,0 +1,41 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://addons/aseprite_importer/interface/import_menu/TagsMenu.gd" type="Script" id=1]
[node name="TagSelectMenu" type="VBoxContainer"]
rect_min_size = Vector2( 0, 120 )
size_flags_vertical = 3
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Header" type="HBoxContainer" parent="."]
margin_right = 28.0
margin_bottom = 14.0
[node name="Label" type="Label" parent="Header"]
margin_right = 28.0
margin_bottom = 14.0
size_flags_horizontal = 3
text = "Tags"
valign = 1
[node name="SelectAllButton" type="CheckBox" parent="Header"]
visible = false
margin_left = 32.0
margin_right = 120.0
margin_bottom = 24.0
size_flags_horizontal = 8
text = "Select All"
[node name="Tree" type="Tree" parent="."]
margin_top = 18.0
margin_right = 28.0
margin_bottom = 120.0
size_flags_vertical = 3
columns = 5
hide_folding = true
hide_root = true

95
addons/aseprite_importer/interface/spritesheet_inspector/ColorMenuItem.gd

@ -0,0 +1,95 @@
tool
extends Container
onready var label : Label = $Head