diff --git a/.gitignore b/.gitignore index 245ddbb1d..d69a443a3 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -Scripts/Old/ \ No newline at end of file +Scripts/Old/ +Assets/Graphics/Tools/ \ No newline at end of file diff --git a/.import/.png-05675a12d3f10112da9382ffea612140.md5 b/.import/.png-05675a12d3f10112da9382ffea612140.md5 deleted file mode 100644 index 7f0c11ab1..000000000 --- a/.import/.png-05675a12d3f10112da9382ffea612140.md5 +++ /dev/null @@ -1,3 +0,0 @@ -source_md5="b8469a8d2b9b7f33cde9c50c882514d3" -dest_md5="611bf34048e600d74fb53c849097c026" - diff --git a/.import/Sprite Editor.png-13de7b2e25322c0fe05acb73bde7971f.md5 b/.import/Sprite Editor.png-13de7b2e25322c0fe05acb73bde7971f.md5 deleted file mode 100644 index 91a5f1f3b..000000000 --- a/.import/Sprite Editor.png-13de7b2e25322c0fe05acb73bde7971f.md5 +++ /dev/null @@ -1,3 +0,0 @@ -source_md5="3f3e12abce4c2177df141c708b02c3cc" -dest_md5="5bb71e82d18a6514c7bec6e2f2996585" - diff --git a/.import/Sprite Editor.png-13de7b2e25322c0fe05acb73bde7971f.stex b/.import/Sprite Editor.png-13de7b2e25322c0fe05acb73bde7971f.stex deleted file mode 100644 index 325997866..000000000 Binary files a/.import/Sprite Editor.png-13de7b2e25322c0fe05acb73bde7971f.stex and /dev/null differ diff --git a/.import/Transparency500.png-01fadc6686974ab1f9d994c50d1e42a1.md5 b/.import/Transparency500.png-01fadc6686974ab1f9d994c50d1e42a1.md5 deleted file mode 100644 index 2d466955e..000000000 --- a/.import/Transparency500.png-01fadc6686974ab1f9d994c50d1e42a1.md5 +++ /dev/null @@ -1,3 +0,0 @@ -source_md5="90f1e764a9d0303186411784568ef237" -dest_md5="b40997122ed6d10d1612023e114c7315" - diff --git a/.import/Transparency500.png-a6b83c75a67b83f874e6120982b6723d.md5 b/.import/Transparency500.png-a6b83c75a67b83f874e6120982b6723d.md5 deleted file mode 100644 index 2c9cc5680..000000000 --- a/.import/Transparency500.png-a6b83c75a67b83f874e6120982b6723d.md5 +++ /dev/null @@ -1,3 +0,0 @@ -source_md5="90f1e764a9d0303186411784568ef237" -dest_md5="5d2507d2ac9dd6d7f8b781cd64e5e4b6" - diff --git a/.import/Transparency500.png-a6b83c75a67b83f874e6120982b6723d.stex b/.import/Transparency500.png-a6b83c75a67b83f874e6120982b6723d.stex deleted file mode 100644 index eb3a71865..000000000 Binary files a/.import/Transparency500.png-a6b83c75a67b83f874e6120982b6723d.stex and /dev/null differ diff --git a/.import/Transparent Background.png-b5955c8e7e6eaecd8f24a1732239745d.stex b/.import/Transparent Background.png-b5955c8e7e6eaecd8f24a1732239745d.stex deleted file mode 100644 index 04fd7d9dd..000000000 Binary files a/.import/Transparent Background.png-b5955c8e7e6eaecd8f24a1732239745d.stex and /dev/null differ diff --git a/.import/eraser-outline.png-cba7a0d7dc311bf5109856c071223323.md5 b/.import/eraser-outline.png-cba7a0d7dc311bf5109856c071223323.md5 deleted file mode 100644 index 8efb6706b..000000000 --- a/.import/eraser-outline.png-cba7a0d7dc311bf5109856c071223323.md5 +++ /dev/null @@ -1,3 +0,0 @@ -source_md5="6861c2574df688e89c30a4d2c3ff0512" -dest_md5="5eaa4f1834b413cd6fba1a5e73afdea5" - diff --git a/.import/grid.png-643b5c8878aaf0c84a360796789dae22.stex b/.import/grid.png-643b5c8878aaf0c84a360796789dae22.stex deleted file mode 100644 index b3492bd54..000000000 Binary files a/.import/grid.png-643b5c8878aaf0c84a360796789dae22.stex and /dev/null differ diff --git a/.import/hello.png-e103c16b45db77894c95005feb7fad3f.md5 b/.import/hello.png-e103c16b45db77894c95005feb7fad3f.md5 deleted file mode 100644 index 436041223..000000000 --- a/.import/hello.png-e103c16b45db77894c95005feb7fad3f.md5 +++ /dev/null @@ -1,3 +0,0 @@ -source_md5="327bd47a99785cc67d3b563e11e15386" -dest_md5="f762a141beffeb685bedf56872c571fc" - diff --git a/.import/o.png-32d3b5843c98359b9557fafcc551e353.md5 b/.import/o.png-32d3b5843c98359b9557fafcc551e353.md5 deleted file mode 100644 index 2bd01ac08..000000000 --- a/.import/o.png-32d3b5843c98359b9557fafcc551e353.md5 +++ /dev/null @@ -1,3 +0,0 @@ -source_md5="3b9968d48bb94408d74340e812e4a715" -dest_md5="2d008139a38b2c0df1d773b0eb202d2f" - diff --git a/.import/ok.png-436d9a0bf8e96a20d85e9c9482696318.md5 b/.import/ok.png-436d9a0bf8e96a20d85e9c9482696318.md5 deleted file mode 100644 index 644dd459c..000000000 --- a/.import/ok.png-436d9a0bf8e96a20d85e9c9482696318.md5 +++ /dev/null @@ -1,3 +0,0 @@ -source_md5="d0ec0d56b87c9a8c60688d6af9d226a0" -dest_md5="605f5c73c93dc2a072713c6f3fcd0563" - diff --git a/.import/ooo.png-987fe23e74877197b78dca2a42501332.md5 b/.import/ooo.png-987fe23e74877197b78dca2a42501332.md5 deleted file mode 100644 index 0c29490e8..000000000 --- a/.import/ooo.png-987fe23e74877197b78dca2a42501332.md5 +++ /dev/null @@ -1,3 +0,0 @@ -source_md5="1afa25ff3984b4aa5d235e151ea745f2" -dest_md5="3331184ae61337c572353772eeedb37b" - diff --git a/.import/pencil-striped-outlined-tool-in-diagonal-position.png-0306dc70550a8aeeafa7b550dccd1b4a.md5 b/.import/pencil-striped-outlined-tool-in-diagonal-position.png-0306dc70550a8aeeafa7b550dccd1b4a.md5 deleted file mode 100644 index e4a59f740..000000000 --- a/.import/pencil-striped-outlined-tool-in-diagonal-position.png-0306dc70550a8aeeafa7b550dccd1b4a.md5 +++ /dev/null @@ -1,3 +0,0 @@ -source_md5="8cc6a8f03f20c923403c7d96eb234a23" -dest_md5="b99e77f302c757ba661cafd4fec3bab0" - diff --git a/.import/strelitzia baby.png-3d5a982cb56eb81a92736b42a51d4a5b.md5 b/.import/strelitzia baby.png-3d5a982cb56eb81a92736b42a51d4a5b.md5 deleted file mode 100644 index 3847bcd04..000000000 --- a/.import/strelitzia baby.png-3d5a982cb56eb81a92736b42a51d4a5b.md5 +++ /dev/null @@ -1,3 +0,0 @@ -source_md5="16bf0d760b5c4ff30efd2a7ddb10c5a7" -dest_md5="c9a9e4d828f496f7c9371c42dd41c332" - diff --git a/.import/yy.png-6cdc85baf6ec3016cd63aa20e3a024a2.md5 b/.import/yy.png-6cdc85baf6ec3016cd63aa20e3a024a2.md5 deleted file mode 100644 index 1b0bac548..000000000 --- a/.import/yy.png-6cdc85baf6ec3016cd63aa20e3a024a2.md5 +++ /dev/null @@ -1,3 +0,0 @@ -source_md5="702bfdd94a8185490af255dd080e549d" -dest_md5="0944e37fba7b57fbcd1c1b699eddb31f" - diff --git a/FrameButton.tscn b/FrameButton.tscn new file mode 100644 index 000000000..21047560b --- /dev/null +++ b/FrameButton.tscn @@ -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"] diff --git a/Main.tscn b/Main.tscn index 3b29a904b..2b9718524 100644 --- a/Main.tscn +++ b/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"] diff --git a/Scripts/CameraMovement.gd b/Scripts/CameraMovement.gd index 99b1fb3d1..749be2788 100644 --- a/Scripts/CameraMovement.gd +++ b/Scripts/CameraMovement.gd @@ -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: - zoom += zoom_margin \ No newline at end of file + #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)] \ No newline at end of file diff --git a/Scripts/Canvas.gd b/Scripts/Canvas.gd index 617f76f41..26256bdc8 100644 --- a/Scripts/Canvas.gd +++ b/Scripts/Canvas.gd @@ -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) - - #Store [Image, ImageTexture, Layer Name, Visibity boolean] - layers.append([current_sprite, tex, "Layer 0", true]) + sprite.lock() + var tex := ImageTexture.new() + tex.create_from_image(sprite, 0) + + #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,9 +102,18 @@ 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(): @@ -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): diff --git a/Scripts/FrameButton.gd b/Scripts/FrameButton.gd new file mode 100644 index 000000000..3802568a1 --- /dev/null +++ b/Scripts/FrameButton.gd @@ -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() \ No newline at end of file diff --git a/Scripts/Global.gd b/Scripts/Global.gd index 7a068a146..e1223af8e 100644 --- a/Scripts/Global.gd +++ b/Scripts/Global.gd @@ -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: @@ -48,4 +80,27 @@ func find_node_by_name(root, node_name) -> Node: var found = find_node_by_name(child, node_name) if found: return found - return null \ No newline at end of file + 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 \ No newline at end of file diff --git a/Scripts/Main.gd b/Scripts/Main.gd index ab2f0cf3b..c49392e25 100644 --- a/Scripts/Main.gd +++ b/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 _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_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 \ No newline at end of file diff --git a/export_presets.cfg b/export_presets.cfg index 2cd5d2174..355a00f7a 100644 --- a/export_presets.cfg +++ b/export_presets.cfg @@ -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=""