mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-01-18 17:19:50 +00:00
v0.2 - Animation Timeline & UI changes!
v0.2 of Pixelorama is out! - Added animation timeline. You can add. remove. clone and change order of your frames! - You can now import multiple images as frames. - Ability to save individual frames, all frames as multiple files, or all frames as a single file in the form of a horizontal or vertical spritesheet! - Different frames can have a unique amount of layers and they can be of different sizes. - Image scaling is now functional. - Added hints for UI elements. - A lot of UI changes.
This commit is contained in:
parent
1f80291a4b
commit
5781c42821
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
Scripts/Old/
|
||||
Assets/Graphics/Tools/
|
|
@ -1,3 +0,0 @@
|
|||
source_md5="b8469a8d2b9b7f33cde9c50c882514d3"
|
||||
dest_md5="611bf34048e600d74fb53c849097c026"
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
source_md5="3f3e12abce4c2177df141c708b02c3cc"
|
||||
dest_md5="5bb71e82d18a6514c7bec6e2f2996585"
|
||||
|
Binary file not shown.
|
@ -1,3 +0,0 @@
|
|||
source_md5="90f1e764a9d0303186411784568ef237"
|
||||
dest_md5="b40997122ed6d10d1612023e114c7315"
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
source_md5="90f1e764a9d0303186411784568ef237"
|
||||
dest_md5="5d2507d2ac9dd6d7f8b781cd64e5e4b6"
|
||||
|
Binary file not shown.
Binary file not shown.
|
@ -1,3 +0,0 @@
|
|||
source_md5="6861c2574df688e89c30a4d2c3ff0512"
|
||||
dest_md5="5eaa4f1834b413cd6fba1a5e73afdea5"
|
||||
|
Binary file not shown.
|
@ -1,3 +0,0 @@
|
|||
source_md5="327bd47a99785cc67d3b563e11e15386"
|
||||
dest_md5="f762a141beffeb685bedf56872c571fc"
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
source_md5="3b9968d48bb94408d74340e812e4a715"
|
||||
dest_md5="2d008139a38b2c0df1d773b0eb202d2f"
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
source_md5="d0ec0d56b87c9a8c60688d6af9d226a0"
|
||||
dest_md5="605f5c73c93dc2a072713c6f3fcd0563"
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
source_md5="1afa25ff3984b4aa5d235e151ea745f2"
|
||||
dest_md5="3331184ae61337c572353772eeedb37b"
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
source_md5="8cc6a8f03f20c923403c7d96eb234a23"
|
||||
dest_md5="b99e77f302c757ba661cafd4fec3bab0"
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
source_md5="16bf0d760b5c4ff30efd2a7ddb10c5a7"
|
||||
dest_md5="c9a9e4d828f496f7c9371c42dd41c332"
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
source_md5="702bfdd94a8185490af255dd080e549d"
|
||||
dest_md5="0944e37fba7b57fbcd1c1b699eddb31f"
|
||||
|
34
FrameButton.tscn
Normal file
34
FrameButton.tscn
Normal file
|
@ -0,0 +1,34 @@
|
|||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://Scripts/FrameButton.gd" type="Script" id=1]
|
||||
|
||||
[node name="Frame" type="VBoxContainer"]
|
||||
margin_right = 32.0
|
||||
margin_bottom = 50.0
|
||||
|
||||
[node name="FrameButton" type="Button" parent="."]
|
||||
margin_right = 36.0
|
||||
margin_bottom = 36.0
|
||||
rect_min_size = Vector2( 36, 36 )
|
||||
mouse_default_cursor_shape = 2
|
||||
size_flags_horizontal = 0
|
||||
size_flags_vertical = 0
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="FrameTexture" type="TextureRect" parent="FrameButton"]
|
||||
margin_left = 2.0
|
||||
margin_top = 2.0
|
||||
margin_right = 34.0
|
||||
margin_bottom = 34.0
|
||||
rect_min_size = Vector2( 32, 32 )
|
||||
size_flags_horizontal = 0
|
||||
size_flags_vertical = 0
|
||||
expand = true
|
||||
|
||||
[node name="FrameID" type="Label" parent="."]
|
||||
margin_top = 40.0
|
||||
margin_right = 36.0
|
||||
margin_bottom = 54.0
|
||||
text = "0"
|
||||
align = 1
|
||||
[connection signal="pressed" from="FrameButton" to="FrameButton" method="_on_FrameButton_pressed"]
|
308
Main.tscn
308
Main.tscn
|
@ -211,27 +211,163 @@ min_value = 1.0
|
|||
value = 1.0
|
||||
suffix = "px"
|
||||
|
||||
[node name="ViewportContainer" type="ViewportContainer" parent="UI"]
|
||||
editor/display_folded = true
|
||||
[node name="CanvasAndTimeline" type="VBoxContainer" parent="UI"]
|
||||
margin_left = 324.0
|
||||
margin_right = 860.0
|
||||
margin_bottom = 600.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="ViewportContainer" type="ViewportContainer" parent="UI/CanvasAndTimeline"]
|
||||
margin_right = 536.0
|
||||
margin_bottom = 448.0
|
||||
mouse_default_cursor_shape = 3
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
stretch = true
|
||||
|
||||
[node name="Viewport" type="Viewport" parent="UI/ViewportContainer"]
|
||||
size = Vector2( 536, 600 )
|
||||
[node name="Viewport" type="Viewport" parent="UI/CanvasAndTimeline/ViewportContainer"]
|
||||
size = Vector2( 536, 448 )
|
||||
handle_input_locally = false
|
||||
render_target_update_mode = 3
|
||||
|
||||
[node name="Canvas" parent="UI/ViewportContainer/Viewport" instance=ExtResource( 5 )]
|
||||
[node name="Canvas" parent="UI/CanvasAndTimeline/ViewportContainer/Viewport" instance=ExtResource( 5 )]
|
||||
|
||||
[node name="Camera2D" type="Camera2D" parent="UI/ViewportContainer/Viewport"]
|
||||
[node name="Camera2D" type="Camera2D" parent="UI/CanvasAndTimeline/ViewportContainer/Viewport"]
|
||||
current = true
|
||||
zoom = Vector2( 0.15, 0.15 )
|
||||
script = ExtResource( 6 )
|
||||
|
||||
[node name="AnimationTimeline" type="Panel" parent="UI/CanvasAndTimeline"]
|
||||
margin_top = 452.0
|
||||
margin_right = 536.0
|
||||
margin_bottom = 600.0
|
||||
rect_min_size = Vector2( 0, 148 )
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="TimelineContainer" type="VBoxContainer" parent="UI/CanvasAndTimeline/AnimationTimeline"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="ButtonContainer" type="CenterContainer" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer"]
|
||||
margin_right = 536.0
|
||||
margin_bottom = 40.0
|
||||
|
||||
[node name="AnimationButtons" type="HBoxContainer" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/ButtonContainer"]
|
||||
margin_left = 69.0
|
||||
margin_right = 467.0
|
||||
margin_bottom = 40.0
|
||||
|
||||
[node name="LoopAnim" type="CheckButton" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/ButtonContainer/AnimationButtons"]
|
||||
margin_right = 111.0
|
||||
margin_bottom = 40.0
|
||||
hint_tooltip = "Should the animation loop (play again after it reached the end)?"
|
||||
mouse_default_cursor_shape = 2
|
||||
text = "Loop"
|
||||
|
||||
[node name="PlayBackwards" type="Button" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/ButtonContainer/AnimationButtons"]
|
||||
margin_left = 115.0
|
||||
margin_right = 224.0
|
||||
margin_bottom = 40.0
|
||||
hint_tooltip = "Play the animation backwards (from end to beggining)"
|
||||
mouse_default_cursor_shape = 2
|
||||
toggle_mode = true
|
||||
text = "Play Backwards"
|
||||
|
||||
[node name="PlayForward" type="Button" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/ButtonContainer/AnimationButtons"]
|
||||
margin_left = 228.0
|
||||
margin_right = 320.0
|
||||
margin_bottom = 40.0
|
||||
hint_tooltip = "Play the animation forward (from beggining to end)"
|
||||
mouse_default_cursor_shape = 2
|
||||
size_flags_horizontal = 0
|
||||
toggle_mode = true
|
||||
text = "Play Forward"
|
||||
|
||||
[node name="FPSValue" type="SpinBox" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/ButtonContainer/AnimationButtons"]
|
||||
margin_left = 324.0
|
||||
margin_right = 398.0
|
||||
margin_bottom = 40.0
|
||||
hint_tooltip = "How many frames per second should the animation preview be? The more FPS, the faster the animation plays."
|
||||
mouse_default_cursor_shape = 2
|
||||
min_value = 1.0
|
||||
value = 1.0
|
||||
suffix = "FPS"
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer"]
|
||||
margin_top = 44.0
|
||||
margin_right = 536.0
|
||||
margin_bottom = 48.0
|
||||
|
||||
[node name="CenterContainer" type="CenterContainer" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer"]
|
||||
margin_top = 52.0
|
||||
margin_right = 536.0
|
||||
margin_bottom = 72.0
|
||||
|
||||
[node name="FrameButtons" type="HBoxContainer" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/CenterContainer"]
|
||||
margin_left = 209.0
|
||||
margin_right = 326.0
|
||||
margin_bottom = 20.0
|
||||
|
||||
[node name="AddFrame" type="Button" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/CenterContainer/FrameButtons"]
|
||||
margin_right = 20.0
|
||||
margin_bottom = 20.0
|
||||
hint_tooltip = "Add a new frame"
|
||||
mouse_default_cursor_shape = 2
|
||||
size_flags_horizontal = 0
|
||||
text = "+"
|
||||
|
||||
[node name="RemoveFrame" type="Button" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/CenterContainer/FrameButtons"]
|
||||
margin_left = 24.0
|
||||
margin_right = 41.0
|
||||
margin_bottom = 20.0
|
||||
hint_tooltip = "Remove selected frame"
|
||||
mouse_default_cursor_shape = 8
|
||||
disabled = true
|
||||
text = "-"
|
||||
|
||||
[node name="MoveFrameLeft" type="Button" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/CenterContainer/FrameButtons"]
|
||||
margin_left = 45.0
|
||||
margin_right = 65.0
|
||||
margin_bottom = 20.0
|
||||
hint_tooltip = "Move selected frame to the left"
|
||||
mouse_default_cursor_shape = 8
|
||||
disabled = true
|
||||
text = "<"
|
||||
|
||||
[node name="MoveFrameRight" type="Button" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/CenterContainer/FrameButtons"]
|
||||
margin_left = 69.0
|
||||
margin_right = 89.0
|
||||
margin_bottom = 20.0
|
||||
hint_tooltip = "Move selected frame to the right"
|
||||
mouse_default_cursor_shape = 8
|
||||
disabled = true
|
||||
text = ">"
|
||||
|
||||
[node name="CloneFrame" type="Button" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/CenterContainer/FrameButtons"]
|
||||
margin_left = 93.0
|
||||
margin_right = 117.0
|
||||
margin_bottom = 20.0
|
||||
hint_tooltip = "Clone current frame"
|
||||
mouse_default_cursor_shape = 2
|
||||
size_flags_horizontal = 0
|
||||
text = "Cl"
|
||||
|
||||
[node name="HSeparator2" type="HSeparator" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer"]
|
||||
margin_top = 76.0
|
||||
margin_right = 536.0
|
||||
margin_bottom = 80.0
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer"]
|
||||
margin_top = 84.0
|
||||
margin_right = 536.0
|
||||
margin_bottom = 148.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
scroll_vertical_enabled = false
|
||||
|
||||
[node name="FrameContainer" type="HBoxContainer" parent="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/ScrollContainer"]
|
||||
|
||||
[node name="LayerPanel" type="Panel" parent="UI"]
|
||||
editor/display_folded = true
|
||||
margin_left = 864.0
|
||||
|
@ -239,19 +375,22 @@ margin_right = 1024.0
|
|||
margin_bottom = 600.0
|
||||
rect_min_size = Vector2( 160, 0 )
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="UI/LayerPanel"]
|
||||
editor/display_folded = true
|
||||
[node name="LayersAndMisc" type="VBoxContainer" parent="UI/LayerPanel"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="UI/LayerPanel/LayersAndMisc"]
|
||||
margin_right = 160.0
|
||||
margin_bottom = 600.0
|
||||
margin_bottom = 538.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="VBoxLayerContainer" type="VBoxContainer" parent="UI/LayerPanel/ScrollContainer"]
|
||||
[node name="VBoxLayerContainer" type="VBoxContainer" parent="UI/LayerPanel/LayersAndMisc/ScrollContainer"]
|
||||
margin_right = 160.0
|
||||
margin_bottom = 38.0
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="LayerLabel" type="Label" parent="UI/LayerPanel/ScrollContainer/VBoxLayerContainer"]
|
||||
[node name="LayerLabel" type="Label" parent="UI/LayerPanel/LayersAndMisc/ScrollContainer/VBoxLayerContainer"]
|
||||
margin_right = 160.0
|
||||
margin_bottom = 14.0
|
||||
size_flags_horizontal = 3
|
||||
|
@ -259,19 +398,25 @@ size_flags_vertical = 0
|
|||
text = "Layers"
|
||||
align = 1
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="UI/LayerPanel/ScrollContainer/VBoxLayerContainer"]
|
||||
[node name="CenterContainer" type="CenterContainer" parent="UI/LayerPanel/LayersAndMisc/ScrollContainer/VBoxLayerContainer"]
|
||||
editor/display_folded = true
|
||||
margin_top = 18.0
|
||||
margin_right = 160.0
|
||||
margin_bottom = 38.0
|
||||
|
||||
[node name="AddLayerButton" type="Button" parent="UI/LayerPanel/ScrollContainer/VBoxLayerContainer/HBoxContainer"]
|
||||
[node name="LayerButtons" type="HBoxContainer" parent="UI/LayerPanel/LayersAndMisc/ScrollContainer/VBoxLayerContainer/CenterContainer"]
|
||||
margin_left = 7.0
|
||||
margin_right = 153.0
|
||||
margin_bottom = 20.0
|
||||
|
||||
[node name="AddLayerButton" type="Button" parent="UI/LayerPanel/LayersAndMisc/ScrollContainer/VBoxLayerContainer/CenterContainer/LayerButtons"]
|
||||
margin_right = 20.0
|
||||
margin_bottom = 20.0
|
||||
hint_tooltip = "Create a new layer"
|
||||
mouse_default_cursor_shape = 2
|
||||
text = "+"
|
||||
|
||||
[node name="RemoveLayerButton" type="Button" parent="UI/LayerPanel/ScrollContainer/VBoxLayerContainer/HBoxContainer"]
|
||||
[node name="RemoveLayerButton" type="Button" parent="UI/LayerPanel/LayersAndMisc/ScrollContainer/VBoxLayerContainer/CenterContainer/LayerButtons"]
|
||||
margin_left = 24.0
|
||||
margin_right = 44.0
|
||||
margin_bottom = 20.0
|
||||
|
@ -280,7 +425,7 @@ mouse_default_cursor_shape = 8
|
|||
disabled = true
|
||||
text = "X"
|
||||
|
||||
[node name="MoveUpLayer" type="Button" parent="UI/LayerPanel/ScrollContainer/VBoxLayerContainer/HBoxContainer"]
|
||||
[node name="MoveUpLayer" type="Button" parent="UI/LayerPanel/LayersAndMisc/ScrollContainer/VBoxLayerContainer/CenterContainer/LayerButtons"]
|
||||
margin_left = 48.0
|
||||
margin_right = 67.0
|
||||
margin_bottom = 20.0
|
||||
|
@ -289,7 +434,7 @@ mouse_default_cursor_shape = 8
|
|||
disabled = true
|
||||
text = "^"
|
||||
|
||||
[node name="MoveDownLayer" type="Button" parent="UI/LayerPanel/ScrollContainer/VBoxLayerContainer/HBoxContainer"]
|
||||
[node name="MoveDownLayer" type="Button" parent="UI/LayerPanel/LayersAndMisc/ScrollContainer/VBoxLayerContainer/CenterContainer/LayerButtons"]
|
||||
margin_left = 71.0
|
||||
margin_right = 90.0
|
||||
margin_bottom = 20.0
|
||||
|
@ -298,7 +443,7 @@ mouse_default_cursor_shape = 8
|
|||
disabled = true
|
||||
text = "v"
|
||||
|
||||
[node name="CloneLayer" type="Button" parent="UI/LayerPanel/ScrollContainer/VBoxLayerContainer/HBoxContainer"]
|
||||
[node name="CloneLayer" type="Button" parent="UI/LayerPanel/LayersAndMisc/ScrollContainer/VBoxLayerContainer/CenterContainer/LayerButtons"]
|
||||
margin_left = 94.0
|
||||
margin_right = 118.0
|
||||
margin_bottom = 20.0
|
||||
|
@ -306,7 +451,7 @@ hint_tooltip = "Clone current layer"
|
|||
mouse_default_cursor_shape = 2
|
||||
text = "Cl"
|
||||
|
||||
[node name="MergeDownLayer" type="Button" parent="UI/LayerPanel/ScrollContainer/VBoxLayerContainer/HBoxContainer"]
|
||||
[node name="MergeDownLayer" type="Button" parent="UI/LayerPanel/LayersAndMisc/ScrollContainer/VBoxLayerContainer/CenterContainer/LayerButtons"]
|
||||
margin_left = 122.0
|
||||
margin_right = 146.0
|
||||
margin_bottom = 20.0
|
||||
|
@ -315,6 +460,28 @@ mouse_default_cursor_shape = 8
|
|||
disabled = true
|
||||
text = "M"
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="UI/LayerPanel/LayersAndMisc"]
|
||||
margin_top = 542.0
|
||||
margin_right = 160.0
|
||||
margin_bottom = 546.0
|
||||
|
||||
[node name="CursorPosition" type="Label" parent="UI/LayerPanel/LayersAndMisc"]
|
||||
margin_top = 550.0
|
||||
margin_right = 160.0
|
||||
margin_bottom = 564.0
|
||||
text = "[64x64]"
|
||||
|
||||
[node name="ZoomLevel" type="Label" parent="UI/LayerPanel/LayersAndMisc"]
|
||||
margin_top = 568.0
|
||||
margin_right = 160.0
|
||||
margin_bottom = 582.0
|
||||
text = "Zoom: x7.81"
|
||||
|
||||
[node name="EmptyLabel" type="Label" parent="UI/LayerPanel/LayersAndMisc"]
|
||||
margin_top = 586.0
|
||||
margin_right = 160.0
|
||||
margin_bottom = 600.0
|
||||
|
||||
[node name="CreateNewImage" type="ConfirmationDialog" parent="."]
|
||||
editor/display_folded = true
|
||||
margin_right = 200.0
|
||||
|
@ -342,11 +509,14 @@ margin_right = 46.0
|
|||
margin_bottom = 19.0
|
||||
text = "Width: "
|
||||
|
||||
[node name="LineEdit" type="LineEdit" parent="CreateNewImage/VBoxContainer/WidthCont"]
|
||||
[node name="WidthValue" type="SpinBox" parent="CreateNewImage/VBoxContainer/WidthCont"]
|
||||
margin_left = 50.0
|
||||
margin_right = 108.0
|
||||
margin_right = 124.0
|
||||
margin_bottom = 24.0
|
||||
text = "64"
|
||||
min_value = 1.0
|
||||
max_value = 16384.0
|
||||
value = 64.0
|
||||
suffix = "px"
|
||||
|
||||
[node name="HeightCont" type="HBoxContainer" parent="CreateNewImage/VBoxContainer"]
|
||||
margin_top = 46.0
|
||||
|
@ -359,18 +529,21 @@ margin_right = 46.0
|
|||
margin_bottom = 19.0
|
||||
text = "Height:"
|
||||
|
||||
[node name="LineEdit" type="LineEdit" parent="CreateNewImage/VBoxContainer/HeightCont"]
|
||||
[node name="HeightValue" type="SpinBox" parent="CreateNewImage/VBoxContainer/HeightCont"]
|
||||
margin_left = 50.0
|
||||
margin_right = 108.0
|
||||
margin_right = 124.0
|
||||
margin_bottom = 24.0
|
||||
text = "64"
|
||||
min_value = 1.0
|
||||
max_value = 16384.0
|
||||
value = 64.0
|
||||
suffix = "px"
|
||||
|
||||
[node name="OpenSprite" type="FileDialog" parent="."]
|
||||
margin_right = 515.0
|
||||
margin_bottom = 348.0
|
||||
window_title = "Open a File"
|
||||
window_title = "Open File(s)"
|
||||
resizable = true
|
||||
mode = 0
|
||||
mode = 1
|
||||
access = 2
|
||||
filters = PoolStringArray( "*jpg, *.png ; JPG, PNG Images" )
|
||||
current_dir = "C:/Users/Overloaded/Dropbox/Orama Founding Members/εταιρικα αρχεια/Godot Projects/Pixelorama"
|
||||
|
@ -385,7 +558,7 @@ margin_left = -512.0
|
|||
margin_top = -300.0
|
||||
margin_right = 3.0
|
||||
margin_bottom = 48.0
|
||||
window_title = "Create a new image"
|
||||
window_title = "Export sprite"
|
||||
resizable = true
|
||||
access = 2
|
||||
filters = PoolStringArray( "*.png ; PNG Image" )
|
||||
|
@ -393,24 +566,25 @@ current_dir = "C:/Users/Overloaded/Dropbox/Orama Founding Members/εταιρικ
|
|||
current_path = "C:/Users/Overloaded/Dropbox/Orama Founding Members/εταιρικα αρχεια/Godot Projects/Pixelorama/"
|
||||
|
||||
[node name="ScaleImage" type="ConfirmationDialog" parent="."]
|
||||
editor/display_folded = true
|
||||
visible = true
|
||||
margin_right = 200.0
|
||||
margin_bottom = 114.0
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="ScaleImage"]
|
||||
margin_left = 8.0
|
||||
margin_top = 8.0
|
||||
margin_right = 192.0
|
||||
margin_bottom = 78.0
|
||||
margin_right = 257.0
|
||||
margin_bottom = 102.0
|
||||
|
||||
[node name="ImageSize" type="Label" parent="ScaleImage/VBoxContainer"]
|
||||
margin_right = 184.0
|
||||
margin_right = 249.0
|
||||
margin_bottom = 14.0
|
||||
text = "Image Size"
|
||||
|
||||
[node name="WidthCont" type="HBoxContainer" parent="ScaleImage/VBoxContainer"]
|
||||
editor/display_folded = true
|
||||
margin_top = 18.0
|
||||
margin_right = 184.0
|
||||
margin_right = 249.0
|
||||
margin_bottom = 42.0
|
||||
|
||||
[node name="WidthLabel" type="Label" parent="ScaleImage/VBoxContainer/WidthCont"]
|
||||
|
@ -419,15 +593,19 @@ margin_right = 46.0
|
|||
margin_bottom = 19.0
|
||||
text = "Width: "
|
||||
|
||||
[node name="LineEdit" type="LineEdit" parent="ScaleImage/VBoxContainer/WidthCont"]
|
||||
[node name="WidthValue" type="SpinBox" parent="ScaleImage/VBoxContainer/WidthCont"]
|
||||
margin_left = 50.0
|
||||
margin_right = 108.0
|
||||
margin_right = 124.0
|
||||
margin_bottom = 24.0
|
||||
text = "64"
|
||||
min_value = 1.0
|
||||
max_value = 16384.0
|
||||
value = 64.0
|
||||
suffix = "px"
|
||||
|
||||
[node name="HeightCont" type="HBoxContainer" parent="ScaleImage/VBoxContainer"]
|
||||
editor/display_folded = true
|
||||
margin_top = 46.0
|
||||
margin_right = 184.0
|
||||
margin_right = 249.0
|
||||
margin_bottom = 70.0
|
||||
|
||||
[node name="Height" type="Label" parent="ScaleImage/VBoxContainer/HeightCont"]
|
||||
|
@ -436,11 +614,35 @@ margin_right = 46.0
|
|||
margin_bottom = 19.0
|
||||
text = "Height:"
|
||||
|
||||
[node name="LineEdit" type="LineEdit" parent="ScaleImage/VBoxContainer/HeightCont"]
|
||||
[node name="HeightValue" type="SpinBox" parent="ScaleImage/VBoxContainer/HeightCont"]
|
||||
margin_left = 50.0
|
||||
margin_right = 108.0
|
||||
margin_right = 124.0
|
||||
margin_bottom = 24.0
|
||||
text = "64"
|
||||
min_value = 1.0
|
||||
max_value = 16384.0
|
||||
value = 64.0
|
||||
suffix = "px"
|
||||
|
||||
[node name="InterpolationContainer" type="HBoxContainer" parent="ScaleImage/VBoxContainer"]
|
||||
margin_top = 74.0
|
||||
margin_right = 249.0
|
||||
margin_bottom = 94.0
|
||||
|
||||
[node name="InterpolationLabel" type="Label" parent="ScaleImage/VBoxContainer/InterpolationContainer"]
|
||||
margin_top = 3.0
|
||||
margin_right = 87.0
|
||||
margin_bottom = 17.0
|
||||
text = "Interpolation:"
|
||||
|
||||
[node name="InterpolationType" type="OptionButton" parent="ScaleImage/VBoxContainer/InterpolationContainer"]
|
||||
margin_left = 91.0
|
||||
margin_right = 249.0
|
||||
margin_bottom = 20.0
|
||||
text = "Interpolation Type"
|
||||
items = [ "Nearest", null, false, 0, null, "Bilinear", null, false, 1, null, "Cubic", null, false, 2, null, "Trilinear", null, false, 3, null ]
|
||||
selected = 0
|
||||
|
||||
[node name="AnimationTimer" type="Timer" parent="."]
|
||||
[connection signal="toggled" from="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/LeftIndicatorCheckbox" to="." method="_on_LeftIndicatorCheckbox_toggled"]
|
||||
[connection signal="popup_closed" from="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/LeftColorPickerButton" to="." method="_can_draw_true"]
|
||||
[connection signal="pressed" from="UI/ToolPanel/Tools/ToolOptions/LeftToolOptions/LeftColorPickerButton" to="." method="_can_draw_false"]
|
||||
|
@ -449,19 +651,29 @@ text = "64"
|
|||
[connection signal="popup_closed" from="UI/ToolPanel/Tools/ToolOptions/RightToolOptions/RightColorPickerButton" to="." method="_can_draw_true"]
|
||||
[connection signal="pressed" from="UI/ToolPanel/Tools/ToolOptions/RightToolOptions/RightColorPickerButton" to="." method="_can_draw_false"]
|
||||
[connection signal="value_changed" from="UI/ToolPanel/Tools/ToolOptions/RightToolOptions/BrushSize/RightBrushSizeEdit" to="." method="_on_RightBrushSizeEdit_value_changed"]
|
||||
[connection signal="mouse_entered" from="UI/ViewportContainer" to="." method="_on_ViewportContainer_mouse_entered"]
|
||||
[connection signal="mouse_exited" from="UI/ViewportContainer" to="." method="_on_ViewportContainer_mouse_exited"]
|
||||
[connection signal="pressed" from="UI/LayerPanel/ScrollContainer/VBoxLayerContainer/HBoxContainer/AddLayerButton" to="." method="_on_AddLayerButton_pressed"]
|
||||
[connection signal="pressed" from="UI/LayerPanel/ScrollContainer/VBoxLayerContainer/HBoxContainer/RemoveLayerButton" to="." method="_on_RemoveLayerButton_pressed"]
|
||||
[connection signal="pressed" from="UI/LayerPanel/ScrollContainer/VBoxLayerContainer/HBoxContainer/MoveUpLayer" to="." method="_on_MoveUpLayer_pressed"]
|
||||
[connection signal="pressed" from="UI/LayerPanel/ScrollContainer/VBoxLayerContainer/HBoxContainer/MoveDownLayer" to="." method="_on_MoveDownLayer_pressed"]
|
||||
[connection signal="pressed" from="UI/LayerPanel/ScrollContainer/VBoxLayerContainer/HBoxContainer/CloneLayer" to="." method="_on_CloneLayer_pressed"]
|
||||
[connection signal="pressed" from="UI/LayerPanel/ScrollContainer/VBoxLayerContainer/HBoxContainer/MergeDownLayer" to="." method="_on_MergeLayer_pressed"]
|
||||
[connection signal="mouse_entered" from="UI/CanvasAndTimeline/ViewportContainer" to="." method="_on_ViewportContainer_mouse_entered"]
|
||||
[connection signal="mouse_exited" from="UI/CanvasAndTimeline/ViewportContainer" to="." method="_on_ViewportContainer_mouse_exited"]
|
||||
[connection signal="toggled" from="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/ButtonContainer/AnimationButtons/LoopAnim" to="." method="_on_LoopAnim_toggled"]
|
||||
[connection signal="toggled" from="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/ButtonContainer/AnimationButtons/PlayBackwards" to="." method="_on_PlayBackwards_toggled"]
|
||||
[connection signal="toggled" from="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/ButtonContainer/AnimationButtons/PlayForward" to="." method="_on_PlayForward_toggled"]
|
||||
[connection signal="value_changed" from="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/ButtonContainer/AnimationButtons/FPSValue" to="." method="_on_FPSValue_value_changed"]
|
||||
[connection signal="pressed" from="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/CenterContainer/FrameButtons/AddFrame" to="." method="_on_AddFrame_pressed"]
|
||||
[connection signal="pressed" from="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/CenterContainer/FrameButtons/RemoveFrame" to="." method="_on_RemoveFrame_pressed"]
|
||||
[connection signal="pressed" from="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/CenterContainer/FrameButtons/MoveFrameLeft" to="." method="_on_MoveFrameLeft_pressed"]
|
||||
[connection signal="pressed" from="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/CenterContainer/FrameButtons/MoveFrameRight" to="." method="_on_MoveFrameRight_pressed"]
|
||||
[connection signal="pressed" from="UI/CanvasAndTimeline/AnimationTimeline/TimelineContainer/CenterContainer/FrameButtons/CloneFrame" to="." method="_on_CloneFrame_pressed"]
|
||||
[connection signal="pressed" from="UI/LayerPanel/LayersAndMisc/ScrollContainer/VBoxLayerContainer/CenterContainer/LayerButtons/AddLayerButton" to="." method="_on_AddLayerButton_pressed"]
|
||||
[connection signal="pressed" from="UI/LayerPanel/LayersAndMisc/ScrollContainer/VBoxLayerContainer/CenterContainer/LayerButtons/RemoveLayerButton" to="." method="_on_RemoveLayerButton_pressed"]
|
||||
[connection signal="pressed" from="UI/LayerPanel/LayersAndMisc/ScrollContainer/VBoxLayerContainer/CenterContainer/LayerButtons/MoveUpLayer" to="." method="_on_MoveUpLayer_pressed"]
|
||||
[connection signal="pressed" from="UI/LayerPanel/LayersAndMisc/ScrollContainer/VBoxLayerContainer/CenterContainer/LayerButtons/MoveDownLayer" to="." method="_on_MoveDownLayer_pressed"]
|
||||
[connection signal="pressed" from="UI/LayerPanel/LayersAndMisc/ScrollContainer/VBoxLayerContainer/CenterContainer/LayerButtons/CloneLayer" to="." method="_on_CloneLayer_pressed"]
|
||||
[connection signal="pressed" from="UI/LayerPanel/LayersAndMisc/ScrollContainer/VBoxLayerContainer/CenterContainer/LayerButtons/MergeDownLayer" to="." method="_on_MergeLayer_pressed"]
|
||||
[connection signal="confirmed" from="CreateNewImage" to="." method="_on_CreateNewImage_confirmed"]
|
||||
[connection signal="popup_hide" from="CreateNewImage" to="." method="_can_draw_true"]
|
||||
[connection signal="file_selected" from="OpenSprite" to="." method="_on_OpenSprite_file_selected"]
|
||||
[connection signal="files_selected" from="OpenSprite" to="." method="_on_OpenSprite_files_selected"]
|
||||
[connection signal="popup_hide" from="OpenSprite" to="." method="_on_OpenSprite_popup_hide"]
|
||||
[connection signal="file_selected" from="SaveSprite" to="." method="_on_SaveSprite_file_selected"]
|
||||
[connection signal="popup_hide" from="SaveSprite" to="." method="_can_draw_true"]
|
||||
[connection signal="confirmed" from="ScaleImage" to="." method="_on_ScaleImage_confirmed"]
|
||||
[connection signal="popup_hide" from="ScaleImage" to="." method="_can_draw_true"]
|
||||
[connection signal="timeout" from="AnimationTimer" to="." method="_on_AnimationTimer_timeout"]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
extends Camera2D
|
||||
|
||||
var zoom_min := Vector2(0.005, 0.005)
|
||||
var zoom_max := Vector2(0.8, 0.8)
|
||||
var zoom_max := Vector2.ONE
|
||||
|
||||
var drag := false
|
||||
|
||||
|
@ -21,5 +21,11 @@ func _input(event) -> void:
|
|||
# Zoom Camera
|
||||
func zoom_camera(dir : int) -> void:
|
||||
var zoom_margin = zoom * dir / 10
|
||||
if zoom + zoom_margin > zoom_min && zoom + zoom_margin < zoom_max:
|
||||
#if zoom + zoom_margin > zoom_min && zoom + zoom_margin < zoom_max:
|
||||
if zoom + zoom_margin > zoom_min:
|
||||
zoom += zoom_margin
|
||||
|
||||
if zoom > zoom_max:
|
||||
zoom = zoom_max
|
||||
|
||||
Global.zoom_level_label.text = "Zoom: x%s" % [stepify(1 / zoom.x, 0.01)]
|
|
@ -4,20 +4,18 @@ class_name Canvas
|
|||
var layers := []
|
||||
var current_layer_index := 0
|
||||
var trans_background : ImageTexture
|
||||
var current_sprite : Image
|
||||
var location := Vector2.ZERO
|
||||
var size := Vector2(64, 64)
|
||||
var frame := 0
|
||||
var frame_button : VBoxContainer
|
||||
var frame_texture_rect : TextureRect
|
||||
|
||||
var previous_mouse_pos := Vector2.ZERO
|
||||
var mouse_inside_canvas := false #used for undo
|
||||
var sprite_changed_this_frame := false #for optimization purposes
|
||||
var left_square_indicator_visible := true
|
||||
var right_square_indicator_visible := false
|
||||
var left_brush_size := 1
|
||||
var right_brush_size := 1
|
||||
|
||||
var is_making_line := false
|
||||
var line_2d : Line2D
|
||||
var draw_grid := false
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
|
@ -27,24 +25,29 @@ func _ready() -> void:
|
|||
trans_background.create_from_image(load("res://Transparent Background.png"), 0)
|
||||
|
||||
#The sprite itself
|
||||
if !current_sprite:
|
||||
current_sprite = Image.new()
|
||||
current_sprite.create(size.x, size.y, false, Image.FORMAT_RGBA8)
|
||||
if layers.empty():
|
||||
var sprite := Image.new()
|
||||
sprite.create(size.x, size.y, false, Image.FORMAT_RGBA8)
|
||||
|
||||
current_sprite.lock()
|
||||
var tex := ImageTexture.new()
|
||||
tex.create_from_image(current_sprite, 0)
|
||||
sprite.lock()
|
||||
var tex := ImageTexture.new()
|
||||
tex.create_from_image(sprite, 0)
|
||||
|
||||
#Store [Image, ImageTexture, Layer Name, Visibity boolean]
|
||||
layers.append([current_sprite, tex, "Layer 0", true])
|
||||
#Store [Image, ImageTexture, Layer Name, Visibity boolean]
|
||||
layers.append([sprite, tex, "Layer 0", true])
|
||||
|
||||
generate_layer_panels()
|
||||
#Set camera offset to the center of canvas
|
||||
$"../Camera2D".offset = size / 2
|
||||
#Set camera zoom based on the sprite size
|
||||
var bigger = max(size.x, size.y)
|
||||
$"../Camera2D".zoom_max = Vector2(bigger, bigger) * 0.01
|
||||
$"../Camera2D".zoom = Vector2(bigger, bigger) * 0.002
|
||||
|
||||
frame_button = load("res://FrameButton.tscn").instance()
|
||||
frame_button.name = "Frame_%s" % frame
|
||||
frame_button.get_node("FrameButton").frame = frame
|
||||
frame_button.get_node("FrameID").text = str(frame)
|
||||
Global.frame_container.add_child(frame_button)
|
||||
|
||||
frame_texture_rect = Global.find_node_by_name(frame_button, "FrameTexture")
|
||||
frame_texture_rect.texture = layers[0][1] #ImageTexture current_layer_index
|
||||
|
||||
camera_zoom()
|
||||
|
||||
# warning-ignore:unused_argument
|
||||
func _process(delta) -> void:
|
||||
|
@ -60,11 +63,16 @@ func _process(delta) -> void:
|
|||
current_mouse_button = "R"
|
||||
current_action = Global.current_right_tool
|
||||
|
||||
if visible:
|
||||
if !point_in_rectangle(mouse_pos, location, location + size):
|
||||
if !Input.is_mouse_button_pressed(BUTTON_LEFT) && !Input.is_mouse_button_pressed(BUTTON_RIGHT):
|
||||
if mouse_inside_canvas:
|
||||
mouse_inside_canvas = false
|
||||
Global.cursor_position_label.text = "[%sx%s]" % [size.x, size.y]
|
||||
else:
|
||||
var mouse_pos_floored := mouse_pos.floor()
|
||||
Global.cursor_position_label.text = "[%sx%s] %s, %s" % [size.x, size.y, mouse_pos_floored.x, mouse_pos_floored.y]
|
||||
|
||||
if !point_in_rectangle(mouse_pos, location, location + size):
|
||||
if !Input.is_mouse_button_pressed(BUTTON_LEFT) && !Input.is_mouse_button_pressed(BUTTON_RIGHT):
|
||||
if mouse_inside_canvas:
|
||||
mouse_inside_canvas = false
|
||||
match current_action:
|
||||
"Pencil":
|
||||
var current_color : Color
|
||||
|
@ -76,7 +84,7 @@ func _process(delta) -> void:
|
|||
"Eraser":
|
||||
pencil_and_eraser(mouse_pos, Color(0, 0, 0, 0), current_mouse_button)
|
||||
"Fill":
|
||||
if point_in_rectangle(mouse_pos, location, location + size) && Global.can_draw && Global.has_focus:
|
||||
if point_in_rectangle(mouse_pos, location, location + size) && Global.can_draw && Global.has_focus && Global.current_frame == frame:
|
||||
var current_color : Color
|
||||
if current_mouse_button == "L":
|
||||
current_color = Global.left_color_picker.color
|
||||
|
@ -94,10 +102,19 @@ func _process(delta) -> void:
|
|||
if sprite_changed_this_frame:
|
||||
update_texture(current_layer_index)
|
||||
|
||||
func update_texture(layer_index : int):
|
||||
func update_texture(layer_index : int) -> void:
|
||||
layers[layer_index][1].create_from_image(layers[layer_index][0], 0)
|
||||
get_layer_container(layer_index).get_child(0).get_child(1).texture = layers[layer_index][1]
|
||||
|
||||
var whole_image := Image.new()
|
||||
whole_image.create(size.x, size.y, false, Image.FORMAT_RGBA8)
|
||||
for layer in layers:
|
||||
whole_image.blend_rect(layer[0], Rect2(position, size), Vector2.ZERO)
|
||||
layer[0].lock()
|
||||
var whole_image_texture := ImageTexture.new()
|
||||
whole_image_texture.create_from_image(whole_image, 0)
|
||||
frame_texture_rect.texture = whole_image_texture
|
||||
|
||||
func get_layer_container(layer_index : int) -> PanelContainer:
|
||||
for container in Global.vbox_layer_container.get_children():
|
||||
if container is PanelContainer && container.i == layer_index:
|
||||
|
@ -112,7 +129,7 @@ func _draw() -> void:
|
|||
draw_texture(texture[1], location)
|
||||
|
||||
#Idea taken from flurick (on GitHub)
|
||||
if draw_grid:
|
||||
if Global.draw_grid:
|
||||
for x in size.x:
|
||||
draw_line(Vector2(x, location.y), Vector2(x, size.y), Color.black, true)
|
||||
for y in size.y:
|
||||
|
@ -122,14 +139,14 @@ func _draw() -> void:
|
|||
var mouse_pos := get_local_mouse_position() - location
|
||||
if point_in_rectangle(mouse_pos, location, location + size):
|
||||
mouse_pos = mouse_pos.floor()
|
||||
if left_square_indicator_visible:
|
||||
var start_pos_x = mouse_pos.x - (left_brush_size >> 1)
|
||||
var start_pos_y = mouse_pos.y - (left_brush_size >> 1)
|
||||
draw_rect(Rect2(start_pos_x, start_pos_y, left_brush_size, left_brush_size), Color.blue, false)
|
||||
if right_square_indicator_visible:
|
||||
var start_pos_x = mouse_pos.x - (right_brush_size >> 1)
|
||||
var start_pos_y = mouse_pos.y - (right_brush_size >> 1)
|
||||
draw_rect(Rect2(start_pos_x, start_pos_y, right_brush_size, right_brush_size), Color.red, false)
|
||||
if Global.left_square_indicator_visible:
|
||||
var start_pos_x = mouse_pos.x - (Global.left_brush_size >> 1)
|
||||
var start_pos_y = mouse_pos.y - (Global.left_brush_size >> 1)
|
||||
draw_rect(Rect2(start_pos_x, start_pos_y, Global.left_brush_size, Global.left_brush_size), Color.blue, false)
|
||||
if Global.right_square_indicator_visible:
|
||||
var start_pos_x = mouse_pos.x - (Global.right_brush_size >> 1)
|
||||
var start_pos_y = mouse_pos.y - (Global.right_brush_size >> 1)
|
||||
draw_rect(Rect2(start_pos_x, start_pos_y, Global.right_brush_size, Global.right_brush_size), Color.red, false)
|
||||
|
||||
func generate_layer_panels() -> void:
|
||||
for child in Global.vbox_layer_container.get_children():
|
||||
|
@ -155,6 +172,19 @@ func generate_layer_panels() -> void:
|
|||
layer_container.get_child(0).get_child(1).texture = layers[i][1]
|
||||
Global.vbox_layer_container.add_child(layer_container)
|
||||
|
||||
func camera_zoom() -> void:
|
||||
#Set camera offset to the center of canvas
|
||||
Global.camera.offset = size / 2
|
||||
#Set camera zoom based on the sprite size
|
||||
var bigger = max(size.x, size.y)
|
||||
var zoom_max := Vector2(bigger, bigger) * 0.01
|
||||
if zoom_max > Vector2.ONE:
|
||||
Global.camera.zoom_max = zoom_max
|
||||
else:
|
||||
Global.camera.zoom_max = Vector2.ONE
|
||||
Global.camera.zoom = Vector2(bigger, bigger) * 0.002
|
||||
Global.zoom_level_label.text = "Zoom: x%s" % [stepify(1 / $"../Camera2D".zoom.x, 0.01)]
|
||||
|
||||
func pencil_and_eraser(mouse_pos : Vector2, color : Color, current_mouse_button : String) -> void:
|
||||
if Input.is_key_pressed(KEY_SHIFT):
|
||||
if !is_making_line:
|
||||
|
@ -168,9 +198,9 @@ func pencil_and_eraser(mouse_pos : Vector2, color : Color, current_mouse_button
|
|||
else:
|
||||
var brush_size := 1
|
||||
if current_mouse_button == "L":
|
||||
brush_size = left_brush_size
|
||||
brush_size = Global.left_brush_size
|
||||
elif current_mouse_button == "R":
|
||||
brush_size = right_brush_size
|
||||
brush_size = Global.right_brush_size
|
||||
|
||||
if is_making_line:
|
||||
fill_gaps(mouse_pos, color, brush_size)
|
||||
|
@ -187,7 +217,7 @@ func pencil_and_eraser(mouse_pos : Vector2, color : Color, current_mouse_button
|
|||
fill_gaps(mouse_pos, color, brush_size)
|
||||
|
||||
func draw_pixel(pos : Vector2, color : Color, brush_size : int) -> void:
|
||||
if Global.can_draw && Global.has_focus:
|
||||
if Global.can_draw && Global.has_focus && Global.current_frame == frame:
|
||||
var start_pos_x = pos.x - (brush_size >> 1)
|
||||
var start_pos_y = pos.y - (brush_size >> 1)
|
||||
for cur_pos_x in range(start_pos_x, start_pos_x + brush_size):
|
||||
|
|
8
Scripts/FrameButton.gd
Normal file
8
Scripts/FrameButton.gd
Normal file
|
@ -0,0 +1,8 @@
|
|||
extends Button
|
||||
|
||||
var frame := 0
|
||||
|
||||
func _on_FrameButton_pressed() -> void:
|
||||
Global.current_frame = frame
|
||||
#print(len(Global.canvases))
|
||||
Global.change_frame()
|
|
@ -1,22 +1,44 @@
|
|||
extends Node
|
||||
|
||||
# warning-ignore:unused_class_variable
|
||||
var current_frame := 0
|
||||
# warning-ignore:unused_class_variable
|
||||
var can_draw := false
|
||||
# warning-ignore:unused_class_variable
|
||||
var has_focus := true
|
||||
# warning-ignore:unused_class_variable
|
||||
var draw_grid := false
|
||||
var canvases := []
|
||||
var canvas : Canvas
|
||||
var canvas_parent
|
||||
var canvas_parent : Node
|
||||
# warning-ignore:unused_class_variable
|
||||
var left_square_indicator_visible := true
|
||||
# warning-ignore:unused_class_variable
|
||||
var right_square_indicator_visible := false
|
||||
# warning-ignore:unused_class_variable
|
||||
var left_brush_size := 1
|
||||
# warning-ignore:unused_class_variable
|
||||
var right_brush_size := 1
|
||||
var camera : Camera2D
|
||||
var left_color_picker : ColorPickerButton
|
||||
var right_color_picker : ColorPickerButton
|
||||
var file_menu : MenuButton
|
||||
var edit_menu : MenuButton
|
||||
var left_indicator : Sprite
|
||||
var right_indicator : Sprite
|
||||
var play_forward : Button
|
||||
var play_backwards : Button
|
||||
var frame_container : HBoxContainer
|
||||
var remove_frame_button : Button
|
||||
var move_left_frame_button : Button
|
||||
var move_right_frame_button : Button
|
||||
var vbox_layer_container : VBoxContainer
|
||||
var remove_layer_button : Button
|
||||
var move_up_layer_button : Button
|
||||
var move_down_layer_button : Button
|
||||
var merge_down_layer_button : Button
|
||||
var cursor_position_label : Label
|
||||
var zoom_level_label : Label
|
||||
# warning-ignore:unused_class_variable
|
||||
var current_left_tool := "Pencil"
|
||||
# warning-ignore:unused_class_variable
|
||||
|
@ -25,18 +47,28 @@ var current_right_tool := "Eraser"
|
|||
func _ready() -> void:
|
||||
var root = get_tree().get_root()
|
||||
canvas = find_node_by_name(root, "Canvas")
|
||||
canvases.append(canvas)
|
||||
canvas_parent = canvas.get_parent()
|
||||
camera = find_node_by_name(canvas_parent, "Camera2D")
|
||||
left_color_picker = find_node_by_name(root, "LeftColorPickerButton")
|
||||
right_color_picker = find_node_by_name(root, "RightColorPickerButton")
|
||||
file_menu = find_node_by_name(root, "FileMenu")
|
||||
edit_menu = find_node_by_name(root, "EditMenu")
|
||||
left_indicator = find_node_by_name(root, "LeftIndicator")
|
||||
right_indicator = find_node_by_name(root, "RightIndicator")
|
||||
play_forward = find_node_by_name(root, "PlayForward")
|
||||
play_backwards = find_node_by_name(root, "PlayBackwards")
|
||||
frame_container = find_node_by_name(root, "FrameContainer")
|
||||
remove_frame_button = find_node_by_name(root, "RemoveFrame")
|
||||
move_left_frame_button = find_node_by_name(root, "MoveFrameLeft")
|
||||
move_right_frame_button = find_node_by_name(root, "MoveFrameRight")
|
||||
vbox_layer_container = find_node_by_name(root, "VBoxLayerContainer")
|
||||
remove_layer_button = find_node_by_name(root, "RemoveLayerButton")
|
||||
move_up_layer_button = find_node_by_name(root, "MoveUpLayer")
|
||||
move_down_layer_button = find_node_by_name(root, "MoveDownLayer")
|
||||
merge_down_layer_button = find_node_by_name(root, "MergeDownLayer")
|
||||
cursor_position_label = find_node_by_name(root, "CursorPosition")
|
||||
zoom_level_label = find_node_by_name(root, "ZoomLevel")
|
||||
|
||||
#Thanks to https://godotengine.org/qa/17524/how-to-find-an-instanced-scene-by-its-name
|
||||
func find_node_by_name(root, node_name) -> Node:
|
||||
|
@ -49,3 +81,26 @@ func find_node_by_name(root, node_name) -> Node:
|
|||
if found:
|
||||
return found
|
||||
return null
|
||||
|
||||
func change_frame() -> void:
|
||||
for c in canvases:
|
||||
c.visible = false
|
||||
canvas = canvases[current_frame]
|
||||
canvas.visible = true
|
||||
canvas.generate_layer_panels()
|
||||
handle_layer_order_buttons()
|
||||
|
||||
func handle_layer_order_buttons() -> void:
|
||||
if current_frame == 0:
|
||||
move_left_frame_button.disabled = true
|
||||
move_left_frame_button.mouse_default_cursor_shape = Control.CURSOR_FORBIDDEN
|
||||
else:
|
||||
move_left_frame_button.disabled = false
|
||||
move_left_frame_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
|
||||
|
||||
if current_frame == canvases.size() - 1:
|
||||
move_right_frame_button.disabled = true
|
||||
move_right_frame_button.mouse_default_cursor_shape = Control.CURSOR_FORBIDDEN
|
||||
else:
|
||||
move_right_frame_button.disabled = false
|
||||
move_right_frame_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
|
374
Scripts/Main.gd
374
Scripts/Main.gd
|
@ -5,21 +5,30 @@ var opensprite_file_selected := false
|
|||
var pencil_tool
|
||||
var eraser_tool
|
||||
var fill_tool
|
||||
var export_all_frames : CheckButton
|
||||
var export_as_single_file : CheckButton
|
||||
var export_vertical_spritesheet : CheckButton
|
||||
var fps := 1.0
|
||||
var animation_loop := false
|
||||
var animation_forward := true
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
var file_menu_items := {
|
||||
"New..." : KEY_MASK_CTRL + KEY_N,
|
||||
#The import and export key shortcuts will change,
|
||||
#and they will be bound to Open and Save/Save as once I
|
||||
#make a custom file for Pixelorama projects
|
||||
"Import..." : KEY_MASK_CTRL + KEY_O,
|
||||
"Export..." : KEY_MASK_CTRL + KEY_S,
|
||||
"Export as..." : KEY_MASK_SHIFT + KEY_MASK_CTRL + KEY_S,
|
||||
"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,
|
||||
#"Scale Image" : 0
|
||||
}
|
||||
var file_menu : PopupMenu = Global.file_menu.get_popup()
|
||||
var edit_menu : PopupMenu = Global.edit_menu.get_popup()
|
||||
|
@ -42,6 +51,16 @@ func _ready() -> void:
|
|||
eraser_tool.connect("pressed", self, "_on_Tool_pressed", [eraser_tool])
|
||||
fill_tool.connect("pressed", self, "_on_Tool_pressed", [fill_tool])
|
||||
|
||||
export_all_frames = CheckButton.new()
|
||||
export_all_frames.text = "Export all frames?"
|
||||
export_as_single_file = CheckButton.new()
|
||||
export_as_single_file.text = "Export frames as a single file?"
|
||||
export_vertical_spritesheet = CheckButton.new()
|
||||
export_vertical_spritesheet.text = "Vertical spritesheet?"
|
||||
$SaveSprite.get_vbox().add_child(export_all_frames)
|
||||
$SaveSprite.get_vbox().add_child(export_as_single_file)
|
||||
$SaveSprite.get_vbox().add_child(export_vertical_spritesheet)
|
||||
|
||||
func _input(event):
|
||||
#Handle tool shortcuts
|
||||
if event.is_action_pressed("right_pencil_tool"):
|
||||
|
@ -57,6 +76,7 @@ func _input(event):
|
|||
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
|
||||
|
@ -71,7 +91,7 @@ func file_menu_id_pressed(id : int) -> void:
|
|||
$SaveSprite.popup_centered()
|
||||
Global.can_draw = false
|
||||
else:
|
||||
save_sprite()
|
||||
export_project()
|
||||
3: #Export as
|
||||
$SaveSprite.popup_centered()
|
||||
Global.can_draw = false
|
||||
|
@ -80,58 +100,165 @@ func file_menu_id_pressed(id : int) -> void:
|
|||
|
||||
func edit_menu_id_pressed(id : int) -> void:
|
||||
match id:
|
||||
0: #Show grid
|
||||
Global.canvas.draw_grid = !Global.canvas.draw_grid
|
||||
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/LineEdit.text)
|
||||
var height = float($CreateNewImage/VBoxContainer/HeightCont/LineEdit.text)
|
||||
width = clamp(width, 1, 16384)
|
||||
height = clamp(height, 1, 16384)
|
||||
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 : String) -> void:
|
||||
var image = Image.new()
|
||||
var err = image.load(path)
|
||||
if err == OK:
|
||||
opensprite_file_selected = true
|
||||
new_canvas(image.get_size(), image)
|
||||
else:
|
||||
OS.alert("Can't load file")
|
||||
|
||||
func new_canvas(size : Vector2, sprite : Image = null) -> void:
|
||||
var left_indicator_visible = Global.canvas.left_square_indicator_visible
|
||||
var right_indicator_visible = Global.canvas.right_square_indicator_visible
|
||||
var left_brush_size = Global.canvas.left_brush_size
|
||||
var right_brush_size = Global.canvas.right_brush_size
|
||||
#func _on_OpenSprite_file_selected(path : String) -> void:
|
||||
# var image = Image.new()
|
||||
# var err = image.load(path)
|
||||
# if err == OK:
|
||||
# opensprite_file_selected = true
|
||||
# new_canvas(image.get_size(), image)
|
||||
# else:
|
||||
# OS.alert("Can't load file")
|
||||
|
||||
func _on_OpenSprite_files_selected(paths) -> void:
|
||||
for child in Global.vbox_layer_container.get_children():
|
||||
if child is PanelContainer:
|
||||
child.queue_free()
|
||||
Global.canvas.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()
|
||||
|
||||
#Find the biggest image and let it handle the camera zoom options
|
||||
var max_size : Vector2
|
||||
var biggest_canvas : Canvas
|
||||
var i := 0
|
||||
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 i == 0:
|
||||
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 new_canvas(size : Vector2, sprite : Image = null) -> 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()
|
||||
Global.canvas = load("res://Canvas.tscn").instance()
|
||||
Global.canvas.size = size
|
||||
Global.canvas.left_square_indicator_visible = left_indicator_visible
|
||||
Global.canvas.right_square_indicator_visible = right_indicator_visible
|
||||
Global.canvas.left_brush_size = left_brush_size
|
||||
Global.canvas.right_brush_size = right_brush_size
|
||||
|
||||
if sprite:
|
||||
Global.canvas.current_sprite = sprite
|
||||
Global.canvas.current_sprite.convert(Image.FORMAT_RGBA8)
|
||||
# if sprite:
|
||||
# var layer0 := sprite
|
||||
# layer0.convert(Image.FORMAT_RGBA8)
|
||||
# var tex := ImageTexture.new()
|
||||
# tex.create_from_image(layer0, 0)
|
||||
# #Store [Image, ImageTexture, Layer Name, Visibity boolean]
|
||||
# Global.canvas.layers.append([layer0, tex, "Layer 0", true])
|
||||
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_SaveSprite_file_selected(path : String) -> void:
|
||||
current_path = path
|
||||
save_sprite()
|
||||
export_project()
|
||||
|
||||
func save_sprite() -> void:
|
||||
func export_project() -> void:
|
||||
if export_all_frames.pressed:
|
||||
if !export_as_single_file.pressed:
|
||||
var i := 0
|
||||
for canvas in Global.canvases:
|
||||
var path := "%s_%s" % [current_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_path)
|
||||
|
||||
func save_sprite(canvas : Canvas, path : String) -> void:
|
||||
var whole_image := Image.new()
|
||||
whole_image.create(Global.canvas.size.x, Global.canvas.size.y, false, Image.FORMAT_RGBA8)
|
||||
for layer in Global.canvas.layers:
|
||||
whole_image.blend_rect(layer[0], Rect2(Global.canvas.position, Global.canvas.size), Vector2.ZERO)
|
||||
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 = Global.canvas.current_sprite.save_png(current_path)
|
||||
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:
|
||||
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:
|
||||
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_path)
|
||||
if err != OK:
|
||||
OS.alert("Can't save file")
|
||||
|
@ -163,22 +290,19 @@ func _on_Tool_pressed(tool_pressed : BaseButton, mouse_press := true, key_for_le
|
|||
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/LineEdit.text)
|
||||
var height = float($ScaleImage/VBoxContainer/HeightCont/LineEdit.text)
|
||||
width = clamp(width, 1, 16384)
|
||||
height = clamp(height, 1, 16384)
|
||||
#var sprites := []
|
||||
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)
|
||||
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()
|
||||
|
@ -226,16 +350,164 @@ func _on_MergeLayer_pressed() -> void:
|
|||
Global.canvas.update_texture(Global.canvas.current_layer_index - 1)
|
||||
_on_RemoveLayerButton_pressed()
|
||||
|
||||
func _on_LeftIndicatorCheckbox_toggled(button_pressed):
|
||||
Global.canvas.left_square_indicator_visible = button_pressed
|
||||
func _on_LeftIndicatorCheckbox_toggled(button_pressed) -> void:
|
||||
Global.left_square_indicator_visible = button_pressed
|
||||
|
||||
func _on_RightIndicatorCheckbox_toggled(button_pressed):
|
||||
Global.canvas.right_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):
|
||||
func _on_LeftBrushSizeEdit_value_changed(value) -> void:
|
||||
var new_size = int(value)
|
||||
Global.canvas.left_brush_size = new_size
|
||||
Global.left_brush_size = new_size
|
||||
|
||||
func _on_RightBrushSizeEdit_value_changed(value):
|
||||
func _on_RightBrushSizeEdit_value_changed(value) -> void:
|
||||
var new_size = int(value)
|
||||
Global.canvas.right_brush_size = new_size
|
||||
Global.right_brush_size = new_size
|
||||
|
||||
func _on_AddFrame_pressed() -> void:
|
||||
var canvas = load("res://Canvas.tscn").instance()
|
||||
canvas.size = Global.canvas.size
|
||||
Global.current_frame = Global.canvases.size()
|
||||
canvas.frame = Global.current_frame
|
||||
for canvas in Global.canvases:
|
||||
canvas.visible = false
|
||||
Global.canvases.append(canvas)
|
||||
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)
|
||||
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]])
|
||||
Global.current_frame = Global.canvases.size()
|
||||
canvas.frame = Global.current_frame
|
||||
for canvas in Global.canvases:
|
||||
canvas.visible = false
|
||||
Global.canvases.append(canvas)
|
||||
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)
|
||||
|
||||
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_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:
|
||||
if animation_loop:
|
||||
Global.current_frame = 0
|
||||
else:
|
||||
Global.play_forward.pressed = false
|
||||
Global.play_forward.text = "Play Forward"
|
||||
$AnimationTimer.stop()
|
||||
else:
|
||||
if Global.current_frame > 0:
|
||||
Global.current_frame -= 1
|
||||
else:
|
||||
if animation_loop:
|
||||
Global.current_frame = Global.canvases.size() - 1
|
||||
else:
|
||||
Global.play_backwards.pressed = false
|
||||
Global.play_backwards.text = "Play Backwards"
|
||||
$AnimationTimer.stop()
|
||||
|
||||
Global.change_frame()
|
||||
|
||||
func _on_FPSValue_value_changed(value) -> void:
|
||||
fps = float(value)
|
||||
$AnimationTimer.wait_time = 1 / fps
|
||||
|
||||
func _on_LoopAnim_toggled(button_pressed) -> void:
|
||||
animation_loop = button_pressed
|
|
@ -23,8 +23,8 @@ binary_format/64_bits=true
|
|||
custom_template/release=""
|
||||
custom_template/debug=""
|
||||
application/icon=""
|
||||
application/file_version="0.1"
|
||||
application/product_version="0.1"
|
||||
application/file_version="0.2"
|
||||
application/product_version="0.2"
|
||||
application/company_name="Orama Interactive"
|
||||
application/product_name="Pixelorama"
|
||||
application/file_description=""
|
||||
|
|
Loading…
Reference in a new issue