├── .gitignore ├── addons └── easy_sheet_manager │ ├── plugin.cfg │ ├── scripts │ ├── SpriteData.gd │ ├── ImprovedList.gd │ ├── SpriteBox.gd │ ├── SpriteSheet2D.gd │ ├── SpriteSheet3D.gd │ ├── DynamicButton.gd │ ├── ESM_Parser.gd │ └── Manager.gd │ ├── main.gd │ ├── spr_box.tscn │ └── Manager.tscn ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Godot-specific ignores 3 | .import/ 4 | export.cfg 5 | export_presets.cfg 6 | 7 | # Mono-specific ignores 8 | .mono/ 9 | data_*/ 10 | -------------------------------------------------------------------------------- /addons/easy_sheet_manager/plugin.cfg: -------------------------------------------------------------------------------- 1 | [plugin] 2 | 3 | name="EasySheetManager" 4 | description="This plugins facilitates the sprite sheet management" 5 | author="nonunknown" 6 | version="1.0" 7 | script="main.gd" 8 | -------------------------------------------------------------------------------- /addons/easy_sheet_manager/scripts/SpriteData.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends Resource 3 | class_name SpriteData 4 | 5 | 6 | export var data:Array 7 | 8 | func get_size() -> int: return data.size()-1 9 | 10 | func insert_data(value:Rect2): 11 | data.append(value) 12 | pass 13 | 14 | func reset(): 15 | data = [] 16 | -------------------------------------------------------------------------------- /addons/easy_sheet_manager/scripts/ImprovedList.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends ItemList 3 | class_name ImprovedList 4 | 5 | func get_item_by_name(name:String) -> int: 6 | var idx:int = -1 7 | 8 | for i in range(get_item_count()-1): 9 | var current_name = get_item_text(i) 10 | if name == current_name: 11 | return i 12 | 13 | return idx; 14 | 15 | func select_item_by_name(name:String) -> void: 16 | select(get_item_by_name(name),false) 17 | -------------------------------------------------------------------------------- /addons/easy_sheet_manager/main.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends EditorPlugin 3 | 4 | var ps_manager = preload("res://addons/easy_sheet_manager/Manager.tscn") 5 | var manager:WindowDialog 6 | var opened:bool = false 7 | func _enter_tree(): 8 | manager = ps_manager.instance() 9 | manager.editor_interface = get_editor_interface() 10 | get_editor_interface().get_base_control().add_child(manager) 11 | 12 | pass 13 | 14 | 15 | func _exit_tree(): 16 | get_editor_interface().get_base_control().call_deferred("remove_child",manager) 17 | manager = null 18 | pass 19 | 20 | func _input(event): 21 | if event is InputEventKey: 22 | if event.is_pressed() and event.scancode == KEY_F9: 23 | manager.emit_signal("about_to_show") 24 | 25 | -------------------------------------------------------------------------------- /addons/easy_sheet_manager/scripts/SpriteBox.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends Control 3 | class_name SpriteBox 4 | 5 | signal box_pressed 6 | var data:Dictionary = {} 7 | 8 | func get_button() -> DynamicButton: return get_child(0) as DynamicButton 9 | func get_data() -> Dictionary: return data 10 | func get_sprite_id() -> int: return data.id 11 | 12 | func insert_data(data:Dictionary): 13 | self.data = data 14 | #{region,id} 15 | get_button().rect_position = data.region.position 16 | get_button().rect_size = data.region.size 17 | $DynamicButton/label.text = data.name 18 | pass 19 | 20 | func unselect(): 21 | $DynamicButton.set_state($DynamicButton.STATE.NORMAL) 22 | 23 | func select(): 24 | $DynamicButton.set_state($DynamicButton.STATE.CLICKED) 25 | 26 | 27 | func _on_DynamicButton_pressed(): 28 | print(str(get_sprite_id())) 29 | # var manager:Manager = get_parent().get_parent().get_parent() 30 | emit_signal("box_pressed",data) 31 | pass # Replace with function body. 32 | -------------------------------------------------------------------------------- /addons/easy_sheet_manager/scripts/SpriteSheet2D.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends Sprite 3 | class_name SpriteSheet2D 4 | 5 | export var sprite_id:int = 0 setget set_sprite 6 | var _sprite_data:SpriteData 7 | 8 | func _enter_tree(): 9 | if _sprite_data == null: 10 | var dir = texture.resource_path 11 | var ext = dir.get_extension() 12 | dir = dir.replace(ext,"tres") 13 | var test = ResourceLoader.load(dir) as SpriteData 14 | _sprite_data = SpriteData.new() 15 | _sprite_data.data = test.data 16 | 17 | func _init(): 18 | self._enter_tree() 19 | 20 | func set_sprite(value:int): 21 | if value < 0 or value >= _sprite_data.data.size(): 22 | return 23 | sprite_id = value 24 | print(_sprite_data.data[value]) 25 | region_rect = _sprite_data.data[value] 26 | 27 | func add_data(x,y,width,height,_name) -> Dictionary: 28 | var rect:Rect2 29 | rect.size = Vector2(width,height) 30 | rect.position = Vector2(x,y) 31 | _sprite_data.insert_data(rect) 32 | return {region=rect,id=_sprite_data.get_size(),name=_name} 33 | -------------------------------------------------------------------------------- /addons/easy_sheet_manager/scripts/SpriteSheet3D.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends Sprite3D 3 | class_name SpriteSheet3D 4 | 5 | export var sprite_id:int = 0 setget set_sprite 6 | var _sprite_data:SpriteData 7 | 8 | func _enter_tree(): 9 | if _sprite_data == null: 10 | var dir = texture.resource_path 11 | var ext = dir.get_extension() 12 | dir = dir.replace(ext,"tres") 13 | var test = ResourceLoader.load(dir) as SpriteData 14 | _sprite_data = SpriteData.new() 15 | _sprite_data.data = test.data 16 | 17 | func _init(): 18 | self._enter_tree() 19 | 20 | func set_sprite(value:int): 21 | if value < 0 or value >= _sprite_data.data.size(): 22 | return 23 | sprite_id = value 24 | print(_sprite_data.data[value]) 25 | region_rect = _sprite_data.data[value] 26 | 27 | func add_data(x,y,width,height,_name) -> Dictionary: 28 | var rect:Rect2 29 | rect.size = Vector2(width,height) 30 | rect.position = Vector2(x,y) 31 | _sprite_data.insert_data(rect) 32 | return {region=rect,id=_sprite_data.get_size(),name=_name} 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 nonunknown 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /addons/easy_sheet_manager/scripts/DynamicButton.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends Panel 3 | class_name DynamicButton 4 | 5 | signal on_pressed 6 | 7 | enum STATE {NORMAL,HOVER,CLICKED} 8 | export(STATE) var state setget set_state 9 | 10 | export var toggle:bool = true 11 | 12 | export var theme_normal:StyleBox 13 | export var theme_hover:StyleBox 14 | export var theme_clicked:StyleBox 15 | 16 | var _pressed:bool = false 17 | 18 | func _enter_tree(): 19 | set_state(STATE.NORMAL) 20 | 21 | func set_state(value:int): 22 | state = value 23 | match value: 24 | STATE.NORMAL: 25 | _pressed = false 26 | set("custom_styles/panel",theme_normal) 27 | STATE.HOVER: 28 | set("custom_styles/panel",theme_hover) 29 | pass 30 | STATE.CLICKED: 31 | set("custom_styles/panel",theme_clicked) 32 | if toggle: 33 | _pressed = !_pressed 34 | if _pressed: 35 | emit_signal("on_pressed") 36 | else: 37 | _pressed = true 38 | emit_signal("on_pressed") 39 | yield(get_tree().create_timer(0.1,false),"timeout") 40 | _pressed = false 41 | set_state(STATE.HOVER) 42 | pass 43 | 44 | func _on_gui_input(event): 45 | if event is InputEventMouseButton: 46 | if event.pressed and event.button_index == BUTTON_LEFT: 47 | set_state(STATE.CLICKED) 48 | 49 | 50 | func _on_mouse_entered(): 51 | if ( toggle and !_pressed ) or (!toggle): 52 | set_state(STATE.HOVER) 53 | 54 | 55 | func _on_mouse_exited(): 56 | if ( toggle and !_pressed ) or ( !toggle ): 57 | set_state(STATE.NORMAL) 58 | 59 | 60 | func _on_DynamicButton_on_pressed(): 61 | print("test") 62 | pass # Replace with function body. 63 | -------------------------------------------------------------------------------- /addons/easy_sheet_manager/scripts/ESM_Parser.gd: -------------------------------------------------------------------------------- 1 | class_name ESM_Parser 2 | 3 | var box = preload("res://addons/easy_sheet_manager/spr_box.tscn") 4 | var thread:Thread = Thread.new() 5 | var file = File.new() 6 | var manager 7 | func read(_manager): 8 | manager = _manager 9 | # print(manager.texture_json) 10 | var err = file.open(manager.texture_json,File.READ) 11 | if err != OK: 12 | printerr("ESM: Plz Make sure ->\n* JSON file is in the same dir as texture.\n* File name is the same as the texture") 13 | file.close() 14 | return 15 | manager.container.texture = manager.texture 16 | 17 | generate_box() 18 | 19 | func generate_box(): 20 | var text = file.get_as_text() 21 | file.close() 22 | var json = parse_json(text) 23 | 24 | var spr = manager.sprite 25 | spr._sprite_data = SpriteData.new() 26 | 27 | for value in json: 28 | #height,name,width,x,y 29 | var dict:Dictionary = value 30 | var height = dict["height"] 31 | var name = dict["name"] 32 | var width = dict["width"] 33 | var x = dict["x"] 34 | var y = dict["y"] 35 | 36 | var spr_box = box.instance() 37 | spr_box.connect("box_pressed",manager,"_on_box_pressed") 38 | manager.container.add_child(spr_box) 39 | var data:Dictionary = spr.add_data(x,y,width,height,name) 40 | spr_box.insert_data(data) 41 | manager.item_list.add_item(name) 42 | 43 | 44 | manager.item_list.sort_items_by_text() 45 | print(manager.texture_json) 46 | var dir = manager.texture_json 47 | var ext = dir.get_extension() 48 | dir = dir.replace(ext,"tres") 49 | var error = ResourceSaver.save(dir,spr._sprite_data) 50 | print(str(error)) 51 | print("BoxCount: "+str(manager.container.get_child_count())) 52 | # print(str(spr._sprite_data)) 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Godot Easy Sheet Manager 2 | 3 | This plugin lets the user deal with irregular spritesheets, and automatically generates animations from selected ones. 4 | 5 | ![alt text](https://i.imgur.com/F6gqVGB.gif) 6 | 7 | ## ChangeLog 8 | 9 | ## v1.5 10 | * Added Support for 2D Sprites 11 | * Removed a bug where you cant play animations, when the engine is reopened/reloaded 12 | 13 | ### Working Version 14 | 3.2+ 15 | 3.2.2 beta 1 16 | 17 | ## Installation 18 | * Place inside your project folder 19 | * Enable Plugin 20 | 21 | ## How to use 22 | * Create your spritesheet here: https://www.leshylabs.com/apps/sstool/ 23 | * Set the FileName type to json 24 | * JSON and PNG file must be the same name, and located in the same folder 25 | * Go to your Scene which contains: 26 | - AnimationPlayer 27 | - Sprite 28 | * **IMPORTANT: Attach SpriteSheet2D or SpriteSheet3D to your Sprite Node** 29 | * Select Both 30 | * Press **F9 Shortcut key** 31 | * Window should appear 32 | * Select Sprites in sequence you want 33 | - If you select wrong, just right-click and clear selection 34 | * click the button: Create Animation 35 | * Configure as you like 36 | - If you want to know what the checkboxes does just leave the mouse above to show HINT 37 | * **Reselect the AnimationPlayer node to see changes** 38 | 39 | ## Known Bugs 40 | * None 41 | 42 | # Important 43 | if you want to improve this plugin you're very welcome. 44 | Here are some things that could make this plugin better: 45 | * Multi-threading 46 | * Hide already-in-use sprites 47 | * Hide sprite-boxes (buttons) off the screen to improve performance 48 | * Colorize with different colors the in-use sprites 49 | * Modify existing animations created with this plugin 50 | - Like changing the frame distance (step) 51 | * Reorganize the texture of the spritesheet acording to names 52 | * Show/Hide sprite names 53 | * Zoom in/out spritesheet 54 | * Middle Mouse button move the sheet 55 | * better organized sprite names 56 | 57 | -------------------------------------------------------------------------------- /addons/easy_sheet_manager/spr_box.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=2] 2 | 3 | [ext_resource path="res://addons/easy_sheet_manager/scripts/SpriteBox.gd" type="Script" id=1] 4 | [ext_resource path="res://addons/easy_sheet_manager/scripts/DynamicButton.gd" type="Script" id=2] 5 | 6 | [sub_resource type="StyleBoxFlat" id=1] 7 | bg_color = Color( 0.6, 0.6, 0.6, 0.0352941 ) 8 | 9 | [sub_resource type="StyleBoxFlat" id=2] 10 | bg_color = Color( 0.6, 0.6, 0.6, 0.180392 ) 11 | border_width_left = 2 12 | border_width_top = 2 13 | border_width_right = 2 14 | border_width_bottom = 2 15 | border_color = Color( 0.235294, 0.258824, 0.498039, 1 ) 16 | 17 | [sub_resource type="StyleBoxFlat" id=3] 18 | bg_color = Color( 0.0509804, 0.254902, 0.337255, 0.45098 ) 19 | border_width_left = 2 20 | border_width_top = 2 21 | border_width_right = 2 22 | border_width_bottom = 2 23 | border_color = Color( 0.8, 0.454902, 0.454902, 1 ) 24 | 25 | [node name="spr_box" type="Control"] 26 | anchor_right = 0.104941 27 | anchor_bottom = 0.0824008 28 | script = ExtResource( 1 ) 29 | __meta__ = { 30 | "_edit_use_anchors_": true 31 | } 32 | 33 | [node name="DynamicButton" type="Panel" parent="."] 34 | margin_right = 78.0 35 | margin_bottom = 39.0 36 | focus_mode = 1 37 | custom_styles/panel = SubResource( 1 ) 38 | script = ExtResource( 2 ) 39 | __meta__ = { 40 | "_edit_use_anchors_": false 41 | } 42 | theme_normal = SubResource( 1 ) 43 | theme_hover = SubResource( 2 ) 44 | theme_clicked = SubResource( 3 ) 45 | 46 | [node name="label" type="Label" parent="DynamicButton"] 47 | anchor_right = 1.0 48 | anchor_bottom = 1.0 49 | custom_colors/font_color = Color( 1, 1, 1, 1 ) 50 | custom_colors/font_color_shadow = Color( 0, 0, 0, 1 ) 51 | custom_constants/shadow_as_outline = 10 52 | text = "ID" 53 | align = 1 54 | valign = 2 55 | uppercase = true 56 | __meta__ = { 57 | "_edit_use_anchors_": false 58 | } 59 | [connection signal="gui_input" from="DynamicButton" to="DynamicButton" method="_on_gui_input"] 60 | [connection signal="mouse_entered" from="DynamicButton" to="DynamicButton" method="_on_mouse_entered"] 61 | [connection signal="mouse_exited" from="DynamicButton" to="DynamicButton" method="_on_mouse_exited"] 62 | [connection signal="on_pressed" from="DynamicButton" to="." method="_on_DynamicButton_pressed"] 63 | -------------------------------------------------------------------------------- /addons/easy_sheet_manager/scripts/Manager.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends WindowDialog 3 | class_name Manager 4 | 5 | var parser 6 | 7 | var item_list:ItemList 8 | var editor_interface 9 | var texture:Texture 10 | var texture_json:String 11 | var sprite = null 12 | var animation:AnimationPlayer = null 13 | var anim_arr:Array = [] 14 | 15 | onready var anim_name_dialog:PopupDialog = $AnimNameDialog 16 | onready var lb_sequence:Label = $AnimPanel/lb_sequence 17 | onready var action_list:ItemList = $ActionList 18 | onready var container = $ScrollContainer/TextureRect 19 | 20 | func _enter_tree(): 21 | self.connect("about_to_show",self,"_on_show") 22 | parser = ESM_Parser.new() 23 | item_list = $ItemList 24 | 25 | print("test") 26 | 27 | func _on_show(): 28 | create() 29 | 30 | func create(data=null): 31 | var selected_nodes = editor_interface.get_selection().get_selected_nodes() 32 | 33 | if selected_nodes.size() > 2 or selected_nodes.size() == 0: 34 | printerr("ESM: "+"there is no node select, or more than two") 35 | return false 36 | sprite = null 37 | animation = null 38 | for node in selected_nodes: 39 | if node is Sprite or node is Sprite3D: 40 | push_warning("Make sure your sprite contains has one of the following scripts attached :\n*SpriteSheet2D\n* SpriteSheet3D") 41 | sprite = node 42 | elif node is AnimationPlayer: 43 | animation = node 44 | if sprite == null or animation == null: 45 | printerr("ESM: You need to select a Sprite and AnimationPlayer") 46 | return false 47 | var new_texture = texture 48 | texture = sprite.texture 49 | if texture == null: 50 | printerr("ESM: Sprite does not contain texture") 51 | return false 52 | sprite.region_enabled = true 53 | 54 | var ext = sprite.texture.resource_path.get_extension() 55 | texture_json = sprite.texture.resource_path.replace(ext,"json") 56 | 57 | if new_texture != texture: 58 | clear() 59 | parser.read(self) 60 | show() 61 | print("opening") 62 | 63 | return true 64 | 65 | func clear(): 66 | print("clearing") 67 | for child in $ScrollContainer/TextureRect.get_children(): 68 | child.call_deferred("free") 69 | item_list.clear() 70 | 71 | func clear_selection(): 72 | add_anim(0,true) # clear anim array 73 | item_list.unselect_all() 74 | for box in $ScrollContainer/TextureRect.get_children(): 75 | box.unselect() 76 | 77 | 78 | func create_animation(name:String,loop:bool,inverse:bool,first:bool,space:float): 79 | # print("creating animation") 80 | var anim = Animation.new() 81 | var idx = anim.add_track(Animation.TYPE_VALUE) 82 | anim.value_track_set_update_mode(idx,Animation.UPDATE_DISCRETE) 83 | anim.track_set_path(idx,sprite.name +":sprite_id") 84 | anim.loop = loop 85 | # print("space: "+str(space)) 86 | var length = 0#float(anim_arr.size()-1) /10.0 87 | for i in range(anim_arr.size()): 88 | # var value:float = float(i) / 10.0 89 | # print("value: "+str(value)+" i: "+str(i)) 90 | anim.track_insert_key(idx,length,anim_arr[i]) 91 | if i < anim_arr.size()-1: 92 | length += space 93 | print(str(length)) 94 | if inverse: 95 | print("inverse") 96 | for i in range(anim_arr.size()-2,0,-1): 97 | length += space 98 | anim.track_insert_key(idx,length,anim_arr[i]) 99 | pass 100 | 101 | if first: 102 | length += space 103 | anim.track_insert_key(idx,length,anim_arr[0]) 104 | anim.length = length 105 | animation.add_animation(name,anim) 106 | print("animationCreated") 107 | 108 | func get_selected_sprites() -> Array: 109 | var arr = [] 110 | for box in container.get_children(): 111 | var b:SpriteBox = box 112 | if b.get_button()._pressed: 113 | arr.append(b.get_data()) 114 | return arr 115 | 116 | func _input(event): 117 | if event is InputEventMouseButton: 118 | if event.pressed and event.button_index == BUTTON_RIGHT: 119 | action_list.rect_position = get_local_mouse_position() 120 | action_list.visible = true 121 | return 122 | 123 | 124 | func _on_ActionList_item_selected(index): 125 | if index == 0: #Clear selection 126 | clear_selection() 127 | 128 | action_list.visible = false 129 | pass # Replace with function body. 130 | 131 | 132 | func _on_ActionList_mouse_exited(): 133 | action_list.visible = false 134 | pass # Replace with function body. 135 | 136 | 137 | 138 | func _on_box_pressed(data): 139 | # print(str(data)) 140 | item_list.select_item_by_name(data.name) 141 | add_anim(data.id) 142 | pass 143 | 144 | func add_anim(idx:int,clear:bool=false): 145 | if !clear: 146 | anim_arr.append(idx) 147 | else: 148 | anim_arr = [] 149 | lb_sequence.text = str(anim_arr) 150 | 151 | 152 | func _on_ItemList_multi_selected(index, selected): 153 | # var name = item_list.get_item_by_name(item_list.get_item_text(index)) 154 | var name = item_list.get_item_text(index) 155 | print("selected: " +name) 156 | for box in $ScrollContainer/TextureRect.get_children(): 157 | if box.data.name == name: 158 | box.select() 159 | 160 | 161 | func _on_bt_add_anim_pressed(): 162 | if anim_arr.size() <= 0: 163 | printerr("ESM: Select some sprites first") 164 | return 165 | anim_name_dialog.popup_centered() 166 | pass # Replace with function body. 167 | 168 | 169 | func _on_AnimNameDialog_confirmed(): 170 | var anim_name = "CustomAnimation" 171 | var name:String = $AnimNameDialog/VBoxContainer/Name.text 172 | if name.length() <= 0: 173 | printerr("Invalid name") 174 | return 175 | anim_name = name 176 | var loop = $AnimNameDialog/VBoxContainer/cb_loop.pressed 177 | var inverse = $AnimNameDialog/VBoxContainer/cb_inverse.pressed 178 | var first = $AnimNameDialog/VBoxContainer/cb_first.pressed 179 | var space = float($AnimNameDialog/VBoxContainer/SpinBox.value) 180 | create_animation(anim_name,loop,inverse,first,space) 181 | anim_name_dialog.visible = false 182 | pass # Replace with function body. 183 | 184 | 185 | func _on_Manager_popup_hide(): 186 | clear() 187 | pass # Replace with function body. 188 | -------------------------------------------------------------------------------- /addons/easy_sheet_manager/Manager.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://addons/easy_sheet_manager/scripts/ImprovedList.gd" type="Script" id=1] 4 | [ext_resource path="res://addons/easy_sheet_manager/scripts/Manager.gd" type="Script" id=2] 5 | 6 | [sub_resource type="GDScript" id=1] 7 | script/source = "extends ItemList 8 | 9 | 10 | var initial_pos 11 | func _enter_tree(): 12 | initial_pos = rect_position 13 | 14 | 15 | 16 | func _on_ActionList_visibility_changed(): 17 | if !visible: rect_position = initial_pos 18 | print(\"changed\") 19 | pass # Replace with function body. 20 | " 21 | 22 | [node name="Manager" type="WindowDialog"] 23 | anchor_left = 0.0742188 24 | anchor_top = 0.113333 25 | anchor_right = 0.921875 26 | anchor_bottom = 0.895 27 | window_title = "Easy Sheet Manager" 28 | resizable = true 29 | script = ExtResource( 2 ) 30 | __meta__ = { 31 | "_edit_use_anchors_": true 32 | } 33 | 34 | [node name="ScrollContainer" type="ScrollContainer" parent="."] 35 | anchor_right = 0.859 36 | anchor_bottom = 0.936 37 | margin_right = 0.388 38 | margin_bottom = 0.0158081 39 | follow_focus = true 40 | __meta__ = { 41 | "_edit_use_anchors_": false 42 | } 43 | 44 | [node name="TextureRect" type="TextureRect" parent="ScrollContainer"] 45 | __meta__ = { 46 | "_edit_use_anchors_": false 47 | } 48 | 49 | [node name="ItemList" type="ItemList" parent="."] 50 | anchor_left = 0.864055 51 | anchor_right = 1.0 52 | anchor_bottom = 1.0 53 | margin_right = -6.10352e-05 54 | select_mode = 1 55 | script = ExtResource( 1 ) 56 | __meta__ = { 57 | "_edit_use_anchors_": true 58 | } 59 | 60 | [node name="ActionList" type="ItemList" parent="."] 61 | visible = false 62 | anchor_left = 1.019 63 | anchor_top = -0.085 64 | anchor_right = 1.019 65 | anchor_bottom = -0.085 66 | margin_left = -71.492 67 | margin_top = 121.865 68 | margin_right = 50.508 69 | margin_bottom = 150.865 70 | items = [ "Clear Selection", null, false ] 71 | allow_reselect = true 72 | script = SubResource( 1 ) 73 | __meta__ = { 74 | "_edit_use_anchors_": false 75 | } 76 | 77 | [node name="AnimPanel" type="Panel" parent="."] 78 | anchor_top = 0.946695 79 | anchor_right = 0.862903 80 | anchor_bottom = 1.0 81 | __meta__ = { 82 | "_edit_use_anchors_": true 83 | } 84 | 85 | [node name="Label" type="Label" parent="AnimPanel"] 86 | anchor_left = 0.00370348 87 | anchor_top = 0.0887622 88 | anchor_right = 0.190619 89 | anchor_bottom = 1.00876 90 | text = "Animation Sequence: " 91 | valign = 1 92 | __meta__ = { 93 | "_edit_use_anchors_": true 94 | } 95 | 96 | [node name="lb_sequence" type="Label" parent="AnimPanel"] 97 | anchor_left = 0.188251 98 | anchor_top = 0.08 99 | anchor_right = 0.81976 100 | anchor_bottom = 1.0 101 | text = "[]" 102 | valign = 1 103 | __meta__ = { 104 | "_edit_use_anchors_": true 105 | } 106 | 107 | [node name="bt_add_anim" type="Button" parent="AnimPanel"] 108 | anchor_left = 0.832993 109 | anchor_top = 0.117173 110 | anchor_right = 0.997212 111 | anchor_bottom = 0.917173 112 | text = "Create Animation" 113 | __meta__ = { 114 | "_edit_use_anchors_": true 115 | } 116 | 117 | [node name="AnimNameDialog" type="AcceptDialog" parent="."] 118 | visible = true 119 | anchor_left = 0.0495392 120 | anchor_top = 0.147121 121 | anchor_right = 0.412442 122 | anchor_bottom = 0.607676 123 | popup_exclusive = true 124 | window_title = "Settings" 125 | dialog_hide_on_ok = false 126 | __meta__ = { 127 | "_edit_use_anchors_": true 128 | } 129 | 130 | [node name="VBoxContainer" type="VBoxContainer" parent="AnimNameDialog"] 131 | anchor_right = 1.0 132 | anchor_bottom = 1.0 133 | margin_left = 8.0 134 | margin_top = 8.0 135 | margin_right = -8.0 136 | margin_bottom = -36.0 137 | __meta__ = { 138 | "_edit_use_anchors_": false 139 | } 140 | 141 | [node name="cb_loop" type="CheckBox" parent="AnimNameDialog/VBoxContainer"] 142 | margin_right = 299.0 143 | margin_bottom = 24.0 144 | pressed = true 145 | text = "Loop" 146 | __meta__ = { 147 | "_edit_use_anchors_": true 148 | } 149 | 150 | [node name="cb_inverse" type="CheckBox" parent="AnimNameDialog/VBoxContainer"] 151 | margin_top = 28.0 152 | margin_right = 299.0 153 | margin_bottom = 52.0 154 | hint_tooltip = "For example if your animation is [1,2,3,4], by enabling this option it will result in: [1,2,3,4,3,2]" 155 | text = "Add Reverse at End" 156 | __meta__ = { 157 | "_edit_use_anchors_": true 158 | } 159 | 160 | [node name="cb_first" type="CheckBox" parent="AnimNameDialog/VBoxContainer"] 161 | margin_top = 56.0 162 | margin_right = 299.0 163 | margin_bottom = 80.0 164 | hint_tooltip = "This option will add the first frame at the end of the animation, example: [1,2,3] will result in: [1,2,3,1]" 165 | text = "Add First Frame at End" 166 | __meta__ = { 167 | "_edit_use_anchors_": true 168 | } 169 | 170 | [node name="Label" type="Label" parent="AnimNameDialog/VBoxContainer"] 171 | margin_top = 84.0 172 | margin_right = 299.0 173 | margin_bottom = 98.0 174 | text = "Space between frames:" 175 | 176 | [node name="SpinBox" type="SpinBox" parent="AnimNameDialog/VBoxContainer"] 177 | margin_top = 102.0 178 | margin_right = 299.0 179 | margin_bottom = 126.0 180 | min_value = 0.001 181 | step = 0.01 182 | value = 0.1 183 | allow_greater = true 184 | 185 | [node name="Label2" type="Label" parent="AnimNameDialog/VBoxContainer"] 186 | margin_top = 130.0 187 | margin_right = 299.0 188 | margin_bottom = 144.0 189 | text = "Animation name:" 190 | 191 | [node name="Name" type="LineEdit" parent="AnimNameDialog/VBoxContainer"] 192 | margin_top = 148.0 193 | margin_right = 299.0 194 | margin_bottom = 172.0 195 | max_length = 25 196 | placeholder_text = "MyCustomAnimation" 197 | placeholder_alpha = 0.288 198 | __meta__ = { 199 | "_edit_use_anchors_": true 200 | } 201 | [connection signal="popup_hide" from="." to="." method="_on_Manager_popup_hide"] 202 | [connection signal="multi_selected" from="ItemList" to="." method="_on_ItemList_multi_selected"] 203 | [connection signal="item_selected" from="ActionList" to="." method="_on_ActionList_item_selected"] 204 | [connection signal="mouse_exited" from="ActionList" to="." method="_on_ActionList_mouse_exited"] 205 | [connection signal="visibility_changed" from="ActionList" to="ActionList" method="_on_ActionList_visibility_changed"] 206 | [connection signal="pressed" from="AnimPanel/bt_add_anim" to="." method="_on_bt_add_anim_pressed"] 207 | [connection signal="confirmed" from="AnimNameDialog" to="." method="_on_AnimNameDialog_confirmed"] 208 | --------------------------------------------------------------------------------