mirror of
https://github.com/tonytins/CozyPixelStudio.git
synced 2025-05-05 16:14:50 -04:00
- Onion skinning for animations. Choose past and future steps and toggle blue-red mode. - Custom .pxo file. If you save your project as a .pxo file, it remembers all of your frames, their layers, brush sizes, brush colors and color palletes! - Ping-pong loop type. When the animation finishes, it plays backwards. - Ability to import new frames in the timeline as additions, without deleting the previous frames.
634 lines
No EOL
21 KiB
GDScript
634 lines
No EOL
21 KiB
GDScript
extends Control
|
|
|
|
var current_save_path := ""
|
|
var current_export_path := ""
|
|
var opensprite_file_selected := false
|
|
var pencil_tool
|
|
var eraser_tool
|
|
var fill_tool
|
|
var import_as_new_frame : CheckBox
|
|
var export_all_frames : CheckBox
|
|
var export_as_single_file : CheckBox
|
|
var export_vertical_spritesheet : CheckBox
|
|
var fps := 1.0
|
|
var animation_loop := 0 #0 is no loop, 1 is cycle loop, 2 is ping-pong loop
|
|
var animation_forward := true
|
|
|
|
# Called when the node enters the scene tree for the first time.
|
|
func _ready() -> void:
|
|
# Set a minimum window size to prevent UI elements from collapsing on each other.
|
|
# This property is only available in 3.2alpha or later, so use `set()` to fail gracefully if it doesn't exist.
|
|
OS.set("min_window_size", Vector2(1024, 600))
|
|
|
|
var file_menu_items := {
|
|
"New..." : KEY_MASK_CTRL + KEY_N,
|
|
"Open..." : KEY_MASK_CTRL + KEY_O,
|
|
"Save..." : KEY_MASK_CTRL + KEY_S,
|
|
"Save as..." : KEY_MASK_SHIFT + KEY_MASK_CTRL + KEY_S,
|
|
"Import..." : KEY_MASK_CTRL + KEY_I,
|
|
"Export..." : KEY_MASK_CTRL + KEY_E,
|
|
"Export as..." : KEY_MASK_SHIFT + KEY_MASK_CTRL + KEY_E,
|
|
"Quit" : KEY_MASK_CTRL + KEY_Q
|
|
}
|
|
var edit_menu_items := {
|
|
"Scale Image" : 0,
|
|
"Show Grid" : KEY_MASK_CTRL + KEY_G
|
|
#"Undo" : KEY_MASK_CTRL + KEY_Z,
|
|
#"Redo" : KEY_MASK_SHIFT + KEY_MASK_CTRL + KEY_Z,
|
|
}
|
|
var file_menu : PopupMenu = Global.file_menu.get_popup()
|
|
var edit_menu : PopupMenu = Global.edit_menu.get_popup()
|
|
var i = 0
|
|
for item in file_menu_items.keys():
|
|
file_menu.add_item(item, i, file_menu_items[item])
|
|
i += 1
|
|
i = 0
|
|
for item in edit_menu_items.keys():
|
|
edit_menu.add_item(item, i, edit_menu_items[item])
|
|
i += 1
|
|
file_menu.connect("id_pressed", self, "file_menu_id_pressed")
|
|
edit_menu.connect("id_pressed", self, "edit_menu_id_pressed")
|
|
|
|
pencil_tool = $UI/ToolPanel/Tools/MenusAndTools/ToolsContainer/Pencil
|
|
eraser_tool = $UI/ToolPanel/Tools/MenusAndTools/ToolsContainer/Eraser
|
|
fill_tool = $UI/ToolPanel/Tools/MenusAndTools/ToolsContainer/Fill
|
|
|
|
pencil_tool.connect("pressed", self, "_on_Tool_pressed", [pencil_tool])
|
|
eraser_tool.connect("pressed", self, "_on_Tool_pressed", [eraser_tool])
|
|
fill_tool.connect("pressed", self, "_on_Tool_pressed", [fill_tool])
|
|
|
|
#Options for Import
|
|
import_as_new_frame = CheckBox.new()
|
|
import_as_new_frame.text = "Import as new frame?"
|
|
$ImportSprites.get_vbox().add_child(import_as_new_frame)
|
|
|
|
#Options for Export
|
|
export_all_frames = CheckBox.new()
|
|
export_all_frames.text = "Export all frames?"
|
|
export_as_single_file = CheckBox.new()
|
|
export_as_single_file.text = "Export frames as a single file?"
|
|
export_vertical_spritesheet = CheckBox.new()
|
|
export_vertical_spritesheet.text = "Vertical spritesheet?"
|
|
$ExportSprites.get_vbox().add_child(export_all_frames)
|
|
$ExportSprites.get_vbox().add_child(export_as_single_file)
|
|
$ExportSprites.get_vbox().add_child(export_vertical_spritesheet)
|
|
|
|
|
|
func _input(event):
|
|
#Handle tool shortcuts
|
|
if event.is_action_pressed("right_pencil_tool"):
|
|
_on_Tool_pressed(pencil_tool, false, false)
|
|
elif event.is_action_pressed("left_pencil_tool"):
|
|
_on_Tool_pressed(pencil_tool, false, true)
|
|
elif event.is_action_pressed("right_eraser_tool"):
|
|
_on_Tool_pressed(eraser_tool, false, false)
|
|
elif event.is_action_pressed("left_eraser_tool"):
|
|
_on_Tool_pressed(eraser_tool, false, true)
|
|
elif event.is_action_pressed("right_fill_tool"):
|
|
_on_Tool_pressed(fill_tool, false, false)
|
|
elif event.is_action_pressed("left_fill_tool"):
|
|
_on_Tool_pressed(fill_tool, false, true)
|
|
|
|
|
|
func file_menu_id_pressed(id : int) -> void:
|
|
match id:
|
|
0: #New
|
|
$CreateNewImage.popup_centered()
|
|
Global.can_draw = false
|
|
1: #Open
|
|
$OpenSprite.popup_centered()
|
|
Global.can_draw = false
|
|
opensprite_file_selected = false
|
|
2: #Save
|
|
if current_save_path == "":
|
|
$SaveSprite.popup_centered()
|
|
Global.can_draw = false
|
|
else:
|
|
_on_SaveSprite_file_selected(current_save_path)
|
|
3: #Save as
|
|
$SaveSprite.popup_centered()
|
|
Global.can_draw = false
|
|
4: #Import
|
|
$ImportSprites.popup_centered()
|
|
Global.can_draw = false
|
|
opensprite_file_selected = false
|
|
5: #Export
|
|
if current_export_path == "":
|
|
$ExportSprites.popup_centered()
|
|
Global.can_draw = false
|
|
else:
|
|
export_project()
|
|
6: #Export as
|
|
$ExportSprites.popup_centered()
|
|
Global.can_draw = false
|
|
7: #Quit
|
|
get_tree().quit()
|
|
|
|
func edit_menu_id_pressed(id : int) -> void:
|
|
match id:
|
|
0: #Scale Image
|
|
$ScaleImage.popup_centered()
|
|
Global.can_draw = false
|
|
1: #Show grid
|
|
Global.draw_grid = !Global.draw_grid
|
|
|
|
func _on_CreateNewImage_confirmed() -> void:
|
|
var width = float($CreateNewImage/VBoxContainer/WidthCont/WidthValue.value)
|
|
var height = float($CreateNewImage/VBoxContainer/HeightCont/HeightValue.value)
|
|
new_canvas(Vector2(width, height).floor())
|
|
|
|
func _on_OpenSprite_file_selected(path) -> void:
|
|
var file := File.new()
|
|
var err := file.open(path, File.READ)
|
|
if err == 0:
|
|
var version := file.get_line()
|
|
var frame := 0
|
|
var frame_line := file.get_line()
|
|
clear_canvases()
|
|
while frame_line == "--":
|
|
var canvas : Canvas = load("res://Canvas.tscn").instance()
|
|
Global.canvas = canvas
|
|
var width := file.get_16()
|
|
var height := file.get_16()
|
|
|
|
var layer := 0
|
|
var layer_line := file.get_line()
|
|
|
|
while layer_line == "-":
|
|
var buffer := file.get_buffer(width * height * 4)
|
|
var image := Image.new()
|
|
image.create_from_data(width, height, false, Image.FORMAT_RGBA8, buffer)
|
|
image.lock()
|
|
var tex := ImageTexture.new()
|
|
tex.create_from_image(image, 0)
|
|
canvas.layers.append([image, tex, "Layer %s" % layer, true])
|
|
layer_line = file.get_line()
|
|
layer += 1
|
|
|
|
canvas.size = Vector2(width, height)
|
|
Global.canvases.append(canvas)
|
|
canvas.frame = frame
|
|
Global.canvas_parent.add_child(canvas)
|
|
frame_line = file.get_line()
|
|
frame += 1
|
|
|
|
Global.current_frame = frame - 1
|
|
#Load tool options
|
|
Global.left_color_picker.color = file.get_var()
|
|
Global.right_color_picker.color = file.get_var()
|
|
Global.left_brush_size = file.get_8()
|
|
Global.left_brush_size_edit.value = Global.left_brush_size
|
|
Global.right_brush_size = file.get_8()
|
|
Global.right_brush_size_edit.value = Global.right_brush_size
|
|
var left_palette = file.get_var()
|
|
var right_palette = file.get_var()
|
|
for color in left_palette:
|
|
Global.left_color_picker.get_picker().add_preset(color)
|
|
for color in right_palette:
|
|
Global.right_color_picker.get_picker().add_preset(color)
|
|
|
|
file.close()
|
|
|
|
func _on_SaveSprite_file_selected(path) -> void:
|
|
current_save_path = path
|
|
var file := File.new()
|
|
var err := file.open(path, File.WRITE)
|
|
if err == 0:
|
|
file.store_line(ProjectSettings.get_setting("application/config/Version"))
|
|
for canvas in Global.canvases:
|
|
file.store_line("--")
|
|
file.store_16(canvas.size.x)
|
|
file.store_16(canvas.size.y)
|
|
for layer in canvas.layers:
|
|
file.store_line("-")
|
|
file.store_buffer(layer[0].get_data())
|
|
file.store_line("END_LAYERS")
|
|
file.store_line("END_FRAMES")
|
|
|
|
#Save tool options
|
|
var left_color := Global.left_color_picker.color
|
|
var right_color := Global.right_color_picker.color
|
|
var left_brush_size := Global.left_brush_size
|
|
var right_brush_size := Global.right_brush_size
|
|
var left_palette := Global.left_color_picker.get_picker().get_presets()
|
|
var right_palette := Global.right_color_picker.get_picker().get_presets()
|
|
file.store_var(left_color)
|
|
file.store_var(right_color)
|
|
file.store_8(left_brush_size)
|
|
file.store_8(right_brush_size)
|
|
file.store_var(left_palette)
|
|
file.store_var(right_palette)
|
|
file.close()
|
|
|
|
func _on_ImportSprites_files_selected(paths) -> void:
|
|
if !import_as_new_frame.pressed: #If we're not adding a new frame, delete the previous
|
|
clear_canvases()
|
|
|
|
#Find the biggest image and let it handle the camera zoom options
|
|
var max_size : Vector2
|
|
var biggest_canvas : Canvas
|
|
var i := Global.canvases.size()
|
|
for path in paths:
|
|
var image = Image.new()
|
|
var err = image.load(path)
|
|
if err == OK:
|
|
opensprite_file_selected = true
|
|
var canvas : Canvas = load("res://Canvas.tscn").instance()
|
|
canvas.size = image.get_size()
|
|
image.convert(Image.FORMAT_RGBA8)
|
|
image.lock()
|
|
var tex := ImageTexture.new()
|
|
tex.create_from_image(image, 0)
|
|
#Store [Image, ImageTexture, Layer Name, Visibity boolean]
|
|
canvas.layers.append([image, tex, "Layer 0", true])
|
|
canvas.frame = i
|
|
Global.canvas_parent.add_child(canvas)
|
|
Global.canvases.append(canvas)
|
|
canvas.visible = false
|
|
if path == paths[0]: #If it's the first file
|
|
max_size = canvas.size
|
|
biggest_canvas = canvas
|
|
else:
|
|
if canvas.size > max_size:
|
|
biggest_canvas = canvas
|
|
|
|
else:
|
|
OS.alert("Can't load file")
|
|
|
|
i += 1
|
|
Global.current_frame = i - 1
|
|
Global.canvas = Global.canvases[Global.canvases.size() - 1]
|
|
Global.canvas.visible = true
|
|
Global.handle_layer_order_buttons()
|
|
biggest_canvas.camera_zoom()
|
|
if i > 1:
|
|
Global.remove_frame_button.disabled = false
|
|
Global.remove_frame_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
|
|
else:
|
|
Global.remove_frame_button.disabled = true
|
|
Global.remove_frame_button.mouse_default_cursor_shape = Control.CURSOR_FORBIDDEN
|
|
|
|
func clear_canvases() -> void:
|
|
for child in Global.vbox_layer_container.get_children():
|
|
if child is PanelContainer:
|
|
child.queue_free()
|
|
for child in Global.frame_container.get_children():
|
|
child.queue_free()
|
|
for child in Global.canvas_parent.get_children():
|
|
if child is Canvas:
|
|
child.queue_free()
|
|
Global.canvases.clear()
|
|
|
|
func new_canvas(size : Vector2) -> void:
|
|
clear_canvases()
|
|
Global.canvas = load("res://Canvas.tscn").instance()
|
|
Global.canvas.size = size
|
|
|
|
Global.canvas_parent.add_child(Global.canvas)
|
|
Global.canvases.append(Global.canvas)
|
|
Global.current_frame = 0
|
|
Global.remove_frame_button.disabled = true
|
|
Global.remove_frame_button.mouse_default_cursor_shape = Control.CURSOR_FORBIDDEN
|
|
|
|
func _on_ExportSprites_file_selected(path : String) -> void:
|
|
current_export_path = path
|
|
export_project()
|
|
|
|
func export_project() -> void:
|
|
if export_all_frames.pressed:
|
|
if !export_as_single_file.pressed:
|
|
var i := 1
|
|
for canvas in Global.canvases:
|
|
var path := "%s_%s" % [current_export_path, str(i)]
|
|
path = path.replace(".png", "")
|
|
path = "%s.png" % path
|
|
save_sprite(canvas, path)
|
|
i += 1
|
|
else:
|
|
save_spritesheet()
|
|
else:
|
|
save_sprite(Global.canvas, current_export_path)
|
|
|
|
func save_sprite(canvas : Canvas, path : String) -> void:
|
|
var whole_image := Image.new()
|
|
whole_image.create(canvas.size.x, canvas.size.y, false, Image.FORMAT_RGBA8)
|
|
for layer in canvas.layers:
|
|
whole_image.blend_rect(layer[0], Rect2(canvas.position, canvas.size), Vector2.ZERO)
|
|
layer[0].lock()
|
|
var err = whole_image.save_png(path)
|
|
if err != OK:
|
|
OS.alert("Can't save file")
|
|
|
|
func save_spritesheet() -> void:
|
|
var width
|
|
var height
|
|
if export_vertical_spritesheet.pressed: #Vertical spritesheet
|
|
width = Global.canvas.size.x
|
|
height = 0
|
|
for canvas in Global.canvases:
|
|
height += canvas.size.y
|
|
if canvas.size.x > width:
|
|
width = canvas.size.x
|
|
else: #Horizontal spritesheet
|
|
width = 0
|
|
height = Global.canvas.size.y
|
|
for canvas in Global.canvases:
|
|
width += canvas.size.x
|
|
if canvas.size.y > height:
|
|
height = canvas.size.y
|
|
var whole_image := Image.new()
|
|
whole_image.create(width, height, false, Image.FORMAT_RGBA8)
|
|
var dst := Vector2.ZERO
|
|
for canvas in Global.canvases:
|
|
for layer in canvas.layers:
|
|
whole_image.blend_rect(layer[0], Rect2(canvas.position, canvas.size), dst)
|
|
layer[0].lock()
|
|
if export_vertical_spritesheet.pressed:
|
|
dst += Vector2(0, canvas.size.y)
|
|
else:
|
|
dst += Vector2(canvas.size.x, 0)
|
|
|
|
var err = whole_image.save_png(current_export_path)
|
|
if err != OK:
|
|
OS.alert("Can't save file")
|
|
|
|
func _on_ImportSprites_popup_hide() -> void:
|
|
if !opensprite_file_selected:
|
|
Global.can_draw = true
|
|
|
|
func _on_ViewportContainer_mouse_entered() -> void:
|
|
Global.has_focus = true
|
|
|
|
func _on_ViewportContainer_mouse_exited() -> void:
|
|
Global.has_focus = false
|
|
|
|
func _can_draw_true() -> void:
|
|
Global.can_draw = true
|
|
func _can_draw_false() -> void:
|
|
Global.can_draw = false
|
|
|
|
func _on_Tool_pressed(tool_pressed : BaseButton, mouse_press := true, key_for_left := true) -> void:
|
|
var current_action := tool_pressed.name
|
|
if (mouse_press && Input.is_action_just_released("left_mouse")) || (!mouse_press && key_for_left):
|
|
Global.current_left_tool = current_action
|
|
Global.left_indicator.get_parent().remove_child(Global.left_indicator)
|
|
tool_pressed.add_child(Global.left_indicator)
|
|
elif (mouse_press && Input.is_action_just_released("right_mouse")) || (!mouse_press && !key_for_left):
|
|
Global.current_right_tool = current_action
|
|
Global.right_indicator.get_parent().remove_child(Global.right_indicator)
|
|
tool_pressed.add_child(Global.right_indicator)
|
|
|
|
func _on_ScaleImage_confirmed() -> void:
|
|
var width = float($ScaleImage/VBoxContainer/WidthCont/WidthValue.value)
|
|
var height = float($ScaleImage/VBoxContainer/HeightCont/HeightValue.value)
|
|
for i in range(Global.canvas.layers.size() - 1, -1, -1):
|
|
var sprite = Image.new()
|
|
sprite = Global.canvas.layers[i][1].get_data()
|
|
sprite.resize(width, height, $ScaleImage/VBoxContainer/InterpolationContainer/InterpolationType.selected)
|
|
Global.canvas.layers[i][0] = sprite
|
|
Global.canvas.layers[i][0].lock()
|
|
Global.canvas.update_texture(i)
|
|
|
|
Global.canvas.size = Vector2(width, height).floor()
|
|
Global.canvas.camera_zoom()
|
|
|
|
func add_layer(is_new := true) -> void:
|
|
var new_layer := Image.new()
|
|
if is_new:
|
|
new_layer.create(Global.canvas.size.x, Global.canvas.size.y, false, Image.FORMAT_RGBA8)
|
|
else: #clone layer
|
|
new_layer.copy_from(Global.canvas.layers[Global.canvas.current_layer_index][0])
|
|
new_layer.lock()
|
|
var new_layer_tex := ImageTexture.new()
|
|
new_layer_tex.create_from_image(new_layer, 0)
|
|
Global.canvas.layers.append([new_layer, new_layer_tex, null, true])
|
|
Global.canvas.generate_layer_panels()
|
|
|
|
func _on_AddLayerButton_pressed() -> void:
|
|
add_layer()
|
|
|
|
func _on_RemoveLayerButton_pressed() -> void:
|
|
Global.canvas.layers.remove(Global.canvas.current_layer_index)
|
|
Global.canvas.generate_layer_panels()
|
|
|
|
func _on_MoveUpLayer_pressed() -> void:
|
|
change_layer_order(1)
|
|
|
|
func _on_MoveDownLayer_pressed() -> void:
|
|
change_layer_order(-1)
|
|
|
|
func change_layer_order(rate : int) -> void:
|
|
var change = Global.canvas.current_layer_index + rate
|
|
|
|
var temp = Global.canvas.layers[Global.canvas.current_layer_index]
|
|
Global.canvas.layers[Global.canvas.current_layer_index] = Global.canvas.layers[change]
|
|
Global.canvas.layers[change] = temp
|
|
|
|
Global.canvas.generate_layer_panels()
|
|
Global.canvas.current_layer_index = change
|
|
Global.canvas.get_layer_container(Global.canvas.current_layer_index).changed_selection()
|
|
|
|
func _on_CloneLayer_pressed() -> void:
|
|
add_layer(false)
|
|
|
|
func _on_MergeLayer_pressed() -> void:
|
|
var selected_layer = Global.canvas.layers[Global.canvas.current_layer_index][0]
|
|
Global.canvas.layers[Global.canvas.current_layer_index - 1][0].blend_rect(selected_layer, Rect2(Global.canvas.position, Global.canvas.size), Vector2.ZERO)
|
|
Global.canvas.layers[Global.canvas.current_layer_index - 1][0].lock()
|
|
Global.canvas.update_texture(Global.canvas.current_layer_index - 1)
|
|
_on_RemoveLayerButton_pressed()
|
|
|
|
func _on_LeftIndicatorCheckbox_toggled(button_pressed) -> void:
|
|
Global.left_square_indicator_visible = button_pressed
|
|
|
|
func _on_RightIndicatorCheckbox_toggled(button_pressed) -> void:
|
|
Global.right_square_indicator_visible = button_pressed
|
|
|
|
func _on_LeftBrushSizeEdit_value_changed(value) -> void:
|
|
var new_size = int(value)
|
|
Global.left_brush_size = new_size
|
|
|
|
func _on_RightBrushSizeEdit_value_changed(value) -> void:
|
|
var new_size = int(value)
|
|
Global.right_brush_size = new_size
|
|
|
|
func _on_AddFrame_pressed() -> void:
|
|
var canvas = load("res://Canvas.tscn").instance()
|
|
canvas.size = Global.canvas.size
|
|
canvas.frame = Global.canvases.size()
|
|
for canvas in Global.canvases:
|
|
canvas.visible = false
|
|
Global.canvases.append(canvas)
|
|
Global.current_frame = Global.canvases.size() - 1
|
|
Global.canvas = canvas
|
|
|
|
Global.canvas_parent.add_child(canvas)
|
|
Global.remove_frame_button.disabled = false
|
|
Global.remove_frame_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
|
|
Global.move_left_frame_button.disabled = false
|
|
Global.move_left_frame_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
|
|
|
|
func _on_RemoveFrame_pressed() -> void:
|
|
Global.canvas.frame_button.queue_free()
|
|
Global.canvas.queue_free()
|
|
Global.canvases.remove(Global.current_frame)
|
|
for canvas in Global.canvases:
|
|
if canvas.frame > Global.current_frame:
|
|
canvas.frame -= 1
|
|
canvas.frame_button.get_node("FrameButton").frame = canvas.frame
|
|
canvas.frame_button.get_node("FrameID").text = str(canvas.frame + 1)
|
|
if Global.current_frame > 0:
|
|
Global.current_frame -= 1
|
|
if len(Global.canvases) == 1:
|
|
Global.remove_frame_button.disabled = true
|
|
Global.remove_frame_button.mouse_default_cursor_shape = Control.CURSOR_FORBIDDEN
|
|
Global.canvas = Global.canvases[Global.current_frame]
|
|
Global.canvas.visible = true
|
|
Global.canvas.generate_layer_panels()
|
|
Global.handle_layer_order_buttons()
|
|
|
|
|
|
func _on_CloneFrame_pressed() -> void:
|
|
var canvas = load("res://Canvas.tscn").instance()
|
|
canvas.size = Global.canvas.size
|
|
#canvas.layers = Global.canvas.layers.duplicate(true)
|
|
for layer in Global.canvas.layers:
|
|
var sprite := Image.new()
|
|
sprite.copy_from(layer[0])
|
|
sprite.lock()
|
|
var tex := ImageTexture.new()
|
|
tex.create_from_image(sprite, 0)
|
|
canvas.layers.append([sprite, tex, layer[2], layer[3]])
|
|
canvas.frame = Global.canvases.size()
|
|
for canvas in Global.canvases:
|
|
canvas.visible = false
|
|
Global.canvases.append(canvas)
|
|
Global.current_frame = Global.canvases.size() - 1
|
|
Global.canvas = canvas
|
|
|
|
Global.canvas_parent.add_child(canvas)
|
|
Global.remove_frame_button.disabled = false
|
|
Global.remove_frame_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
|
|
Global.move_left_frame_button.disabled = false
|
|
Global.move_left_frame_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
|
|
|
|
func _on_MoveFrameLeft_pressed() -> void:
|
|
change_frame_order(-1)
|
|
|
|
func _on_MoveFrameRight_pressed() -> void:
|
|
change_frame_order(1)
|
|
|
|
func change_frame_order(rate : int) -> void:
|
|
var frame_button = Global.frame_container.get_node("Frame_%s" % Global.current_frame)
|
|
var change = Global.current_frame + rate
|
|
|
|
var temp = Global.canvases[Global.current_frame]
|
|
Global.canvases[Global.current_frame] = Global.canvases[change]
|
|
Global.canvases[change] = temp
|
|
|
|
#Clear frame button names first, to avoid duplicates like two Frame_0s
|
|
for canvas in Global.canvases:
|
|
canvas.frame_button.name = "frame"
|
|
|
|
for canvas in Global.canvases:
|
|
canvas.frame = Global.canvases.find(canvas)
|
|
canvas.frame_button.name = "Frame_%s" % canvas.frame
|
|
canvas.frame_button.get_node("FrameButton").frame = canvas.frame
|
|
canvas.frame_button.get_node("FrameID").text = str(canvas.frame + 1)
|
|
|
|
Global.current_frame = change
|
|
Global.frame_container.move_child(frame_button, Global.current_frame)
|
|
Global.canvas_parent.move_child(Global.canvas, Global.current_frame)
|
|
#Global.canvas.generate_layer_panels()
|
|
Global.handle_layer_order_buttons()
|
|
|
|
func _on_LoopAnim_pressed() -> void:
|
|
match Global.loop_animation_button.text:
|
|
"No":
|
|
#Make it loop
|
|
animation_loop = 1
|
|
Global.loop_animation_button.text = "Cycle"
|
|
"Cycle":
|
|
#Make it ping-pong
|
|
animation_loop = 2
|
|
Global.loop_animation_button.text = "Ping-Pong"
|
|
"Ping-Pong":
|
|
#Make it stop
|
|
animation_loop = 0
|
|
Global.loop_animation_button.text = "No"
|
|
|
|
func _on_PlayForward_toggled(button_pressed) -> void:
|
|
Global.play_backwards.pressed = false
|
|
Global.play_backwards.text = "Play Backwards"
|
|
|
|
if button_pressed:
|
|
Global.play_forward.text = "Stop"
|
|
$AnimationTimer.wait_time = 1 / fps
|
|
$AnimationTimer.start()
|
|
animation_forward = true
|
|
else:
|
|
Global.play_forward.text = "Play Forward"
|
|
$AnimationTimer.stop()
|
|
|
|
func _on_PlayBackwards_toggled(button_pressed) -> void:
|
|
Global.play_forward.pressed = false
|
|
Global.play_forward.text = "Play Forward"
|
|
|
|
if button_pressed:
|
|
Global.play_backwards.text = "Stop"
|
|
$AnimationTimer.wait_time = 1 / fps
|
|
$AnimationTimer.start()
|
|
animation_forward = false
|
|
else:
|
|
Global.play_backwards.text = "Play Backwards"
|
|
$AnimationTimer.stop()
|
|
|
|
func _on_AnimationTimer_timeout() -> void:
|
|
if animation_forward:
|
|
if Global.current_frame < Global.canvases.size() - 1:
|
|
Global.current_frame += 1
|
|
else:
|
|
match animation_loop:
|
|
0: #No loop
|
|
Global.play_forward.pressed = false
|
|
Global.play_forward.text = "Play Forward"
|
|
Global.play_backwards.pressed = false
|
|
Global.play_backwards.text = "Play Backwards"
|
|
$AnimationTimer.stop()
|
|
1: #Cycle loop
|
|
Global.current_frame = 0
|
|
2: #Ping pong loop
|
|
animation_forward = false
|
|
_on_AnimationTimer_timeout()
|
|
|
|
else:
|
|
if Global.current_frame > 0:
|
|
Global.current_frame -= 1
|
|
else:
|
|
match animation_loop:
|
|
0: #No loop
|
|
Global.play_backwards.pressed = false
|
|
Global.play_backwards.text = "Play Backwards"
|
|
Global.play_forward.pressed = false
|
|
Global.play_forward.text = "Play Forward"
|
|
$AnimationTimer.stop()
|
|
1: #Cycle loop
|
|
Global.current_frame = Global.canvases.size() - 1
|
|
2: #Ping pong loop
|
|
animation_forward = true
|
|
_on_AnimationTimer_timeout()
|
|
|
|
Global.change_frame()
|
|
|
|
func _on_FPSValue_value_changed(value) -> void:
|
|
fps = float(value)
|
|
$AnimationTimer.wait_time = 1 / fps
|
|
|
|
func _on_PastOnionSkinning_value_changed(value) -> void:
|
|
Global.onion_skinning_past_rate = int(value)
|
|
|
|
func _on_FutureOnionSkinning_value_changed(value) -> void:
|
|
Global.onion_skinning_future_rate = int(value)
|
|
|
|
func _on_BlueRedMode_toggled(button_pressed) -> void:
|
|
Global.onion_skinning_blue_red = button_pressed |