1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-01-18 17:19:50 +00:00

Merge pull request #170 from Orama-Interactive/new-timeline

Merge the new timeline into master
This commit is contained in:
Manolis Papadeas 2020-03-09 01:40:16 +02:00 committed by GitHub
commit 65544dcfc1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 935 additions and 840 deletions

329
Main.tscn
View file

@ -1,4 +1,4 @@
[gd_scene load_steps=65 format=2]
[gd_scene load_steps=49 format=2]
[ext_resource path="res://Themes & Styles/Dark Theme/Dark Theme.tres" type="Theme" id=1]
[ext_resource path="res://Scripts/Main.gd" type="Script" id=2]
@ -25,35 +25,19 @@
[ext_resource path="res://Assets/Graphics/Dark Themes/Palette/Edit_Palette.png" type="Texture" id=23]
[ext_resource path="res://Assets/Graphics/Dark Themes/Palette/Edit_Palette_Hover.png" type="Texture" id=24]
[ext_resource path="res://Scripts/Palette/PaletteContainer.gd" type="Script" id=25]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/New_Layer.png" type="Texture" id=26]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/New_Layer_Hover.png" type="Texture" id=27]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Delete_Layer.png" type="Texture" id=28]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Delete_Layer_Hover.png" type="Texture" id=29]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Delete_Layer_Disabled.png" type="Texture" id=30]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Move_Up.png" type="Texture" id=31]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Move_Up_Hover.png" type="Texture" id=32]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Move_Up_Disabled.png" type="Texture" id=33]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Move_Down.png" type="Texture" id=34]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Move_Down_Hover.png" type="Texture" id=35]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Move_Down_Disabled.png" type="Texture" id=36]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Clone_Layer.png" type="Texture" id=37]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Clone_Layer_Hover.png" type="Texture" id=38]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Merge_Down.png" type="Texture" id=39]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Merge_Down_Hover.png" type="Texture" id=40]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Merge_Down_Disabled.png" type="Texture" id=41]
[ext_resource path="res://Prefabs/BrushButton.tscn" type="PackedScene" id=42]
[ext_resource path="res://Prefabs/Dialogs/SplashDialog.tscn" type="PackedScene" id=43]
[ext_resource path="res://Prefabs/Dialogs/CreateNewImage.tscn" type="PackedScene" id=44]
[ext_resource path="res://Prefabs/Dialogs/ImportSprites.tscn" type="PackedScene" id=45]
[ext_resource path="res://Prefabs/Dialogs/ExportSprites.tscn" type="PackedScene" id=46]
[ext_resource path="res://Prefabs/Dialogs/ScaleImage.tscn" type="PackedScene" id=47]
[ext_resource path="res://Prefabs/Dialogs/PreferencesDialog.tscn" type="PackedScene" id=48]
[ext_resource path="res://Prefabs/Dialogs/OutlineDialog.tscn" type="PackedScene" id=49]
[ext_resource path="res://Prefabs/Dialogs/AboutDialog.tscn" type="PackedScene" id=50]
[ext_resource path="res://Prefabs/EditPalettePopup.tscn" type="PackedScene" id=51]
[ext_resource path="res://Prefabs/NewPaletteDialog.tscn" type="PackedScene" id=52]
[ext_resource path="res://Prefabs/PaletteImportFileDialog.tscn" type="PackedScene" id=53]
[ext_resource path="res://Prefabs/Dialogs/RotateImage.tscn" type="PackedScene" id=54]
[ext_resource path="res://Prefabs/BrushButton.tscn" type="PackedScene" id=26]
[ext_resource path="res://Prefabs/Dialogs/SplashDialog.tscn" type="PackedScene" id=27]
[ext_resource path="res://Prefabs/Dialogs/CreateNewImage.tscn" type="PackedScene" id=28]
[ext_resource path="res://Prefabs/Dialogs/ImportSprites.tscn" type="PackedScene" id=29]
[ext_resource path="res://Prefabs/Dialogs/ExportSprites.tscn" type="PackedScene" id=30]
[ext_resource path="res://Prefabs/Dialogs/ScaleImage.tscn" type="PackedScene" id=31]
[ext_resource path="res://Prefabs/Dialogs/PreferencesDialog.tscn" type="PackedScene" id=32]
[ext_resource path="res://Prefabs/Dialogs/OutlineDialog.tscn" type="PackedScene" id=33]
[ext_resource path="res://Prefabs/Dialogs/AboutDialog.tscn" type="PackedScene" id=34]
[ext_resource path="res://Prefabs/EditPalettePopup.tscn" type="PackedScene" id=35]
[ext_resource path="res://Prefabs/NewPaletteDialog.tscn" type="PackedScene" id=36]
[ext_resource path="res://Prefabs/PaletteImportFileDialog.tscn" type="PackedScene" id=37]
[ext_resource path="res://Prefabs/Dialogs/RotateImage.tscn" type="PackedScene" id=38]
[sub_resource type="InputEventKey" id=1]
scancode = 88
@ -124,7 +108,6 @@ theme = ExtResource( 1 )
script = ExtResource( 2 )
__meta__ = {
"_edit_horizontal_guides_": [ ],
"_edit_use_anchors_": false,
"_edit_vertical_guides_": [ ]
}
@ -190,9 +173,6 @@ anchor_bottom = 1.0
margin_left = -65.5
margin_right = 65.5
custom_constants/separation = 20
__meta__ = {
"_edit_use_anchors_": false
}
[node name="ZoomLevel" type="Label" parent="MenuAndUI/TopMenuContainer/HBoxContainer"]
margin_top = 6.0
@ -469,6 +449,7 @@ text = "Left pixel indicator"
margin_top = 39.0
margin_right = 100.0
margin_bottom = 55.0
mouse_default_cursor_shape = 2
size_flags_horizontal = 0
pressed = true
text = "Show tool icon"
@ -717,6 +698,7 @@ text = "Right pixel indicator"
margin_top = 39.0
margin_right = 100.0
margin_bottom = 55.0
mouse_default_cursor_shape = 2
size_flags_horizontal = 0
pressed = true
text = "Show tool icon"
@ -946,13 +928,13 @@ custom_constants/separation = 0
[node name="HViewportContainer" type="HBoxContainer" parent="MenuAndUI/UI/CanvasAndTimeline"]
margin_right = 704.0
margin_bottom = 478.0
margin_bottom = 420.0
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="ViewportAndRulers" type="VBoxContainer" parent="MenuAndUI/UI/CanvasAndTimeline/HViewportContainer"]
margin_right = 704.0
margin_bottom = 478.0
margin_bottom = 420.0
size_flags_horizontal = 3
size_flags_vertical = 3
custom_constants/separation = 0
@ -973,20 +955,20 @@ script = ExtResource( 14 )
[node name="HSplitContainer" type="HSplitContainer" parent="MenuAndUI/UI/CanvasAndTimeline/HViewportContainer/ViewportAndRulers"]
margin_top = 16.0
margin_right = 704.0
margin_bottom = 478.0
margin_bottom = 420.0
size_flags_vertical = 3
custom_constants/autohide = 0
[node name="ViewportandVerticalRuler" type="HBoxContainer" parent="MenuAndUI/UI/CanvasAndTimeline/HViewportContainer/ViewportAndRulers/HSplitContainer"]
margin_right = 692.0
margin_bottom = 462.0
margin_bottom = 404.0
size_flags_horizontal = 3
size_flags_vertical = 3
custom_constants/separation = 0
[node name="VerticalRuler" type="Button" parent="MenuAndUI/UI/CanvasAndTimeline/HViewportContainer/ViewportAndRulers/HSplitContainer/ViewportandVerticalRuler"]
margin_right = 16.0
margin_bottom = 462.0
margin_bottom = 404.0
rect_min_size = Vector2( 16, 0 )
focus_mode = 0
mouse_default_cursor_shape = 15
@ -1003,13 +985,13 @@ script = ExtResource( 15 )
[node name="ViewportContainer" type="ViewportContainer" parent="MenuAndUI/UI/CanvasAndTimeline/HViewportContainer/ViewportAndRulers/HSplitContainer/ViewportandVerticalRuler"]
margin_left = 16.0
margin_right = 692.0
margin_bottom = 462.0
margin_bottom = 404.0
size_flags_horizontal = 3
size_flags_vertical = 3
stretch = true
[node name="Viewport" type="Viewport" parent="MenuAndUI/UI/CanvasAndTimeline/HViewportContainer/ViewportAndRulers/HSplitContainer/ViewportandVerticalRuler/ViewportContainer"]
size = Vector2( 676, 462 )
size = Vector2( 676, 404 )
handle_input_locally = false
usage = 0
render_target_update_mode = 3
@ -1033,12 +1015,12 @@ script = ExtResource( 18 )
[node name="ViewportContainer2" type="ViewportContainer" parent="MenuAndUI/UI/CanvasAndTimeline/HViewportContainer/ViewportAndRulers/HSplitContainer"]
margin_left = 704.0
margin_right = 704.0
margin_bottom = 462.0
margin_bottom = 404.0
size_flags_vertical = 3
stretch = true
[node name="Viewport" type="Viewport" parent="MenuAndUI/UI/CanvasAndTimeline/HViewportContainer/ViewportAndRulers/HSplitContainer/ViewportContainer2"]
size = Vector2( 0, 462 )
size = Vector2( 0, 404 )
handle_input_locally = false
render_target_update_mode = 3
script = ExtResource( 19 )
@ -1049,42 +1031,43 @@ zoom = Vector2( 0.15, 0.15 )
script = ExtResource( 17 )
[node name="AnimationTimeline" parent="MenuAndUI/UI/CanvasAndTimeline" instance=ExtResource( 20 )]
margin_top = 420.0
[node name="LayerPanel" type="Panel" parent="MenuAndUI/UI"]
[node name="RightPanel" type="Panel" parent="MenuAndUI/UI"]
margin_left = 928.0
margin_right = 1152.0
margin_bottom = 620.0
rect_min_size = Vector2( 224, 0 )
[node name="LayersAndMisc" type="VBoxContainer" parent="MenuAndUI/UI/LayerPanel"]
[node name="PreviewAndPalettes" type="VBoxContainer" parent="MenuAndUI/UI/RightPanel"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_top = 16.0
[node name="CanvasPreview" type="ViewportContainer" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc"]
[node name="CanvasPreview" type="ViewportContainer" parent="MenuAndUI/UI/RightPanel/PreviewAndPalettes"]
margin_right = 224.0
margin_bottom = 164.0
rect_min_size = Vector2( 0, 164 )
[node name="Viewport" type="Viewport" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/CanvasPreview"]
[node name="Viewport" type="Viewport" parent="MenuAndUI/UI/RightPanel/PreviewAndPalettes/CanvasPreview"]
size = Vector2( 224, 164 )
transparent_bg = true
handle_input_locally = false
render_target_update_mode = 3
script = ExtResource( 19 )
[node name="CameraPreview" type="Camera2D" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/CanvasPreview/Viewport"]
[node name="CameraPreview" type="Camera2D" parent="MenuAndUI/UI/RightPanel/PreviewAndPalettes/CanvasPreview/Viewport"]
offset = Vector2( 32, 32 )
current = true
zoom = Vector2( 0.15, 0.15 )
script = ExtResource( 17 )
[node name="HSeparator" type="HSeparator" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc"]
[node name="HSeparator" type="HSeparator" parent="MenuAndUI/UI/RightPanel/PreviewAndPalettes"]
margin_top = 168.0
margin_right = 224.0
margin_bottom = 172.0
[node name="PalettesLabel" type="Label" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc"]
[node name="PalettesLabel" type="Label" parent="MenuAndUI/UI/RightPanel/PreviewAndPalettes"]
margin_top = 176.0
margin_right = 224.0
margin_bottom = 191.0
@ -1093,33 +1076,28 @@ size_flags_vertical = 0
text = "Palettes"
align = 1
[node name="HSeparator2" type="HSeparator" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc"]
[node name="HSeparator2" type="HSeparator" parent="MenuAndUI/UI/RightPanel/PreviewAndPalettes"]
margin_top = 195.0
margin_right = 224.0
margin_bottom = 199.0
[node name="VSplitContainer" type="VSplitContainer" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc"]
[node name="PaletteVBoxContainer" type="VBoxContainer" parent="MenuAndUI/UI/RightPanel/PreviewAndPalettes"]
margin_top = 203.0
margin_right = 224.0
margin_bottom = 604.0
size_flags_vertical = 3
custom_constants/autohide = 0
[node name="PaletteVBoxContainer" type="VBoxContainer" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer"]
margin_right = 224.0
margin_bottom = 136.0
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="CenterContainer" type="CenterContainer" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/PaletteVBoxContainer"]
[node name="CenterContainer" type="CenterContainer" parent="MenuAndUI/UI/RightPanel/PreviewAndPalettes/PaletteVBoxContainer"]
margin_right = 224.0
margin_bottom = 32.0
[node name="PaletteButtons" type="HBoxContainer" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/PaletteVBoxContainer/CenterContainer"]
[node name="PaletteButtons" type="HBoxContainer" parent="MenuAndUI/UI/RightPanel/PreviewAndPalettes/PaletteVBoxContainer/CenterContainer"]
margin_left = 24.0
margin_right = 199.0
margin_bottom = 32.0
[node name="AddPalette" type="TextureButton" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/PaletteVBoxContainer/CenterContainer/PaletteButtons" groups=[
[node name="AddPalette" type="TextureButton" parent="MenuAndUI/UI/RightPanel/PreviewAndPalettes/PaletteVBoxContainer/CenterContainer/PaletteButtons" groups=[
"UIButtons",
]]
margin_right = 32.0
@ -1130,12 +1108,12 @@ mouse_default_cursor_shape = 2
texture_normal = ExtResource( 21 )
texture_hover = ExtResource( 22 )
[node name="PopupMenu" type="PopupMenu" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/PaletteVBoxContainer/CenterContainer/PaletteButtons/AddPalette"]
[node name="PopupMenu" type="PopupMenu" parent="MenuAndUI/UI/RightPanel/PreviewAndPalettes/PaletteVBoxContainer/CenterContainer/PaletteButtons/AddPalette"]
margin_right = 12.0
margin_bottom = 20.0
items = [ "New Empty Palette", null, 0, false, false, 0, 0, null, "", false, "Import Palette", null, 0, false, false, 1, 0, null, "", false ]
[node name="EditPalette" type="TextureButton" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/PaletteVBoxContainer/CenterContainer/PaletteButtons" groups=[
[node name="EditPalette" type="TextureButton" parent="MenuAndUI/UI/RightPanel/PreviewAndPalettes/PaletteVBoxContainer/CenterContainer/PaletteButtons" groups=[
"UIButtons",
]]
margin_left = 36.0
@ -1146,7 +1124,7 @@ mouse_default_cursor_shape = 2
texture_normal = ExtResource( 23 )
texture_hover = ExtResource( 24 )
[node name="PaletteOptionButton" type="OptionButton" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/PaletteVBoxContainer/CenterContainer/PaletteButtons"]
[node name="PaletteOptionButton" type="OptionButton" parent="MenuAndUI/UI/RightPanel/PreviewAndPalettes/PaletteVBoxContainer/CenterContainer/PaletteButtons"]
margin_left = 72.0
margin_right = 175.0
margin_bottom = 32.0
@ -1156,190 +1134,25 @@ hint_tooltip = "CHOOSEPALETTE_HT"
mouse_default_cursor_shape = 2
clip_text = true
[node name="ScrollPalette" type="ScrollContainer" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/PaletteVBoxContainer"]
[node name="ScrollPalette" type="ScrollContainer" parent="MenuAndUI/UI/RightPanel/PreviewAndPalettes/PaletteVBoxContainer"]
margin_top = 36.0
margin_right = 224.0
margin_bottom = 136.0
margin_bottom = 401.0
rect_min_size = Vector2( 0, 100 )
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="CenterPalette" type="CenterContainer" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/PaletteVBoxContainer/ScrollPalette"]
[node name="CenterPalette" type="CenterContainer" parent="MenuAndUI/UI/RightPanel/PreviewAndPalettes/PaletteVBoxContainer/ScrollPalette"]
margin_right = 224.0
size_flags_horizontal = 3
[node name="PaletteContainer" type="GridContainer" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/PaletteVBoxContainer/ScrollPalette/CenterPalette"]
[node name="PaletteContainer" type="GridContainer" parent="MenuAndUI/UI/RightPanel/PreviewAndPalettes/PaletteVBoxContainer/ScrollPalette/CenterPalette"]
margin_left = 112.0
margin_right = 112.0
size_flags_horizontal = 3
columns = 5
script = ExtResource( 25 )
[node name="VBoxLayerWithLabels" type="VBoxContainer" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer"]
margin_top = 148.0
margin_right = 224.0
margin_bottom = 401.0
[node name="HSeparator" type="HSeparator" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels"]
margin_right = 224.0
margin_bottom = 4.0
[node name="LayerLabel" type="Label" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels"]
margin_top = 8.0
margin_right = 224.0
margin_bottom = 23.0
size_flags_horizontal = 3
size_flags_vertical = 0
text = "Layers"
align = 1
[node name="HSeparator2" type="HSeparator" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels"]
margin_top = 27.0
margin_right = 224.0
margin_bottom = 31.0
[node name="LayerVBoxContainer" type="VBoxContainer" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels"]
margin_top = 35.0
margin_right = 224.0
margin_bottom = 253.0
size_flags_vertical = 3
custom_constants/separation = 6
[node name="CenterLayerButtons" type="CenterContainer" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels/LayerVBoxContainer"]
margin_right = 224.0
margin_bottom = 32.0
[node name="LayerButtons" type="HBoxContainer" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels/LayerVBoxContainer/CenterLayerButtons"]
margin_left = 6.0
margin_right = 218.0
margin_bottom = 32.0
[node name="AddLayer" type="TextureButton" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels/LayerVBoxContainer/CenterLayerButtons/LayerButtons" groups=[
"UIButtons",
]]
margin_right = 32.0
margin_bottom = 32.0
hint_tooltip = "LAYERNEW_HT"
mouse_default_cursor_shape = 2
texture_normal = ExtResource( 26 )
texture_hover = ExtResource( 27 )
[node name="RemoveLayer" type="TextureButton" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels/LayerVBoxContainer/CenterLayerButtons/LayerButtons" groups=[
"UIButtons",
]]
margin_left = 36.0
margin_right = 68.0
margin_bottom = 32.0
hint_tooltip = "LAYERREMOVE_HT"
mouse_default_cursor_shape = 8
disabled = true
texture_normal = ExtResource( 28 )
texture_hover = ExtResource( 29 )
texture_disabled = ExtResource( 30 )
[node name="MoveUpLayer" type="TextureButton" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels/LayerVBoxContainer/CenterLayerButtons/LayerButtons" groups=[
"UIButtons",
]]
margin_left = 72.0
margin_right = 104.0
margin_bottom = 32.0
hint_tooltip = "LAYERUP_HT"
mouse_default_cursor_shape = 8
disabled = true
texture_normal = ExtResource( 31 )
texture_hover = ExtResource( 32 )
texture_disabled = ExtResource( 33 )
[node name="MovwDownLayer" type="TextureButton" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels/LayerVBoxContainer/CenterLayerButtons/LayerButtons" groups=[
"UIButtons",
]]
margin_left = 108.0
margin_right = 140.0
margin_bottom = 32.0
hint_tooltip = "LAYERDOWN_HT"
mouse_default_cursor_shape = 8
disabled = true
texture_normal = ExtResource( 34 )
texture_hover = ExtResource( 35 )
texture_disabled = ExtResource( 36 )
[node name="CloneLayer" type="TextureButton" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels/LayerVBoxContainer/CenterLayerButtons/LayerButtons" groups=[
"UIButtons",
]]
margin_left = 144.0
margin_right = 176.0
margin_bottom = 32.0
hint_tooltip = "LAYERCLONE_HT"
mouse_default_cursor_shape = 2
texture_normal = ExtResource( 37 )
texture_hover = ExtResource( 38 )
[node name="MergeDownLayer" type="TextureButton" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels/LayerVBoxContainer/CenterLayerButtons/LayerButtons" groups=[
"UIButtons",
]]
margin_left = 180.0
margin_right = 212.0
margin_bottom = 32.0
hint_tooltip = "LAYERMERGE_HT"
mouse_default_cursor_shape = 8
disabled = true
texture_normal = ExtResource( 39 )
texture_hover = ExtResource( 40 )
texture_disabled = ExtResource( 41 )
[node name="OpacityContainer" type="HBoxContainer" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels/LayerVBoxContainer"]
margin_top = 38.0
margin_right = 224.0
margin_bottom = 55.0
custom_constants/separation = 2
alignment = 1
[node name="SpacerControl" type="Control" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels/LayerVBoxContainer/OpacityContainer"]
margin_right = 3.0
margin_bottom = 17.0
rect_min_size = Vector2( 3, 0 )
[node name="OpacityLabel" type="Label" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels/LayerVBoxContainer/OpacityContainer"]
margin_left = 5.0
margin_right = 49.0
margin_bottom = 17.0
size_flags_vertical = 1
text = "Opacity:"
[node name="OpacitySlider" type="HSlider" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels/LayerVBoxContainer/OpacityContainer"]
margin_left = 51.0
margin_right = 166.0
margin_bottom = 17.0
mouse_default_cursor_shape = 2
size_flags_horizontal = 3
size_flags_vertical = 1
value = 100.0
ticks_on_borders = true
[node name="OpacitySpinBox" type="SpinBox" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels/LayerVBoxContainer/OpacityContainer"]
margin_left = 168.0
margin_right = 222.0
margin_bottom = 17.0
mouse_default_cursor_shape = 2
value = 100.0
align = 1
[node name="SpacerControl2" type="Control" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels/LayerVBoxContainer/OpacityContainer"]
margin_left = 224.0
margin_right = 224.0
margin_bottom = 17.0
[node name="ScrollLayers" type="ScrollContainer" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels/LayerVBoxContainer"]
margin_top = 61.0
margin_right = 224.0
margin_bottom = 218.0
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="VBoxLayerContainer" type="VBoxContainer" parent="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels/LayerVBoxContainer/ScrollLayers"]
margin_right = 224.0
size_flags_horizontal = 3
[node name="BrushesPopup" type="Popup" parent="."]
margin_right = 226.0
margin_bottom = 144.0
@ -1367,10 +1180,10 @@ margin_right = 96.0
margin_bottom = 32.0
columns = 6
[node name="PixelBrushButton" parent="BrushesPopup/TabContainer/File/FileBrushContainer" instance=ExtResource( 42 )]
[node name="PixelBrushButton" parent="BrushesPopup/TabContainer/File/FileBrushContainer" instance=ExtResource( 26 )]
hint_tooltip = "Pixel brush"
[node name="CircleBrushButton" parent="BrushesPopup/TabContainer/File/FileBrushContainer" instance=ExtResource( 42 )]
[node name="CircleBrushButton" parent="BrushesPopup/TabContainer/File/FileBrushContainer" instance=ExtResource( 26 )]
margin_left = 32.0
margin_right = 64.0
hint_tooltip = "Filled circle brush"
@ -1380,7 +1193,7 @@ custom_brush_index = -2
[node name="BrushTexture" parent="BrushesPopup/TabContainer/File/FileBrushContainer/CircleBrushButton" index="0"]
texture = SubResource( 8 )
[node name="FilledCircleBrushButton" parent="BrushesPopup/TabContainer/File/FileBrushContainer" instance=ExtResource( 42 )]
[node name="FilledCircleBrushButton" parent="BrushesPopup/TabContainer/File/FileBrushContainer" instance=ExtResource( 26 )]
margin_left = 64.0
margin_right = 96.0
hint_tooltip = "Circle brush"
@ -1405,9 +1218,9 @@ scroll_horizontal_enabled = false
[node name="ProjectBrushContainer" type="GridContainer" parent="BrushesPopup/TabContainer/Project"]
columns = 5
[node name="SplashDialog" parent="." instance=ExtResource( 43 )]
[node name="SplashDialog" parent="." instance=ExtResource( 27 )]
[node name="CreateNewImage" parent="." instance=ExtResource( 44 )]
[node name="CreateNewImage" parent="." instance=ExtResource( 28 )]
[node name="OpenSprite" type="FileDialog" parent="."]
margin_right = 515.0
@ -1436,22 +1249,20 @@ filters = PoolStringArray( "*.pxo ; Pixelorama Project" )
current_dir = "C:/Users/Overloaded/Dropbox/Orama Founding Members/εταιρικα αρχεια/Godot Projects/Pixelorama"
current_path = "C:/Users/Overloaded/Dropbox/Orama Founding Members/εταιρικα αρχεια/Godot Projects/Pixelorama/"
[node name="ImportSprites" parent="." instance=ExtResource( 45 )]
[node name="ImportSprites" parent="." instance=ExtResource( 29 )]
[node name="ExportSprites" parent="." instance=ExtResource( 46 )]
[node name="ExportSprites" parent="." instance=ExtResource( 30 )]
[node name="ScaleImage" parent="." instance=ExtResource( 47 )]
resizable = true
[node name="ScaleImage" parent="." instance=ExtResource( 31 )]
[node name="PreferencesDialog" parent="." instance=ExtResource( 48 )]
[node name="PreferencesDialog" parent="." instance=ExtResource( 32 )]
[node name="RotateImage" parent="." instance=ExtResource( 54 )]
[node name="RotateImage" parent="." instance=ExtResource( 38 )]
[node name="OutlineDialog" parent="." instance=ExtResource( 49 )]
[node name="OutlineDialog" parent="." instance=ExtResource( 33 )]
visible = false
resizable = true
[node name="AboutDialog" parent="." instance=ExtResource( 50 )]
[node name="AboutDialog" parent="." instance=ExtResource( 34 )]
[node name="QuitDialog" type="ConfirmationDialog" parent="."]
margin_right = 200.0
@ -1472,12 +1283,12 @@ margin_bottom = 60.0
window_title = "Error!"
dialog_text = "This is an error message!"
[node name="EditPalettePopup" parent="." instance=ExtResource( 51 )]
[node name="EditPalettePopup" parent="." instance=ExtResource( 35 )]
visible = false
[node name="NewPaletteDialog" parent="." instance=ExtResource( 52 )]
[node name="NewPaletteDialog" parent="." instance=ExtResource( 36 )]
[node name="PaletteImportFileDialog" parent="." instance=ExtResource( 53 )]
[node name="PaletteImportFileDialog" parent="." instance=ExtResource( 37 )]
filters = PoolStringArray( "*.json ; JavaScript Object Notation", "*.gpl ; Gimp Palette Library", "*.png; Portable Network Graphics" )
current_dir = "C:/Users/Overloaded/Dropbox/Orama Founding Members/εταιρικα αρχεια/Godot Projects/Pixelorama"
current_path = "C:/Users/Overloaded/Dropbox/Orama Founding Members/εταιρικα αρχεια/Godot Projects/Pixelorama/"
@ -1529,17 +1340,9 @@ visible = false
[connection signal="mouse_exited" from="MenuAndUI/UI/CanvasAndTimeline/HViewportContainer/ViewportAndRulers/HSplitContainer/ViewportandVerticalRuler/ViewportContainer" to="." method="_on_ViewportContainer_mouse_exited"]
[connection signal="mouse_entered" from="MenuAndUI/UI/CanvasAndTimeline/HViewportContainer/ViewportAndRulers/HSplitContainer/ViewportContainer2" to="." method="_on_ViewportContainer_mouse_entered"]
[connection signal="mouse_exited" from="MenuAndUI/UI/CanvasAndTimeline/HViewportContainer/ViewportAndRulers/HSplitContainer/ViewportContainer2" to="." method="_on_ViewportContainer_mouse_exited"]
[connection signal="pressed" from="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/PaletteVBoxContainer/CenterContainer/PaletteButtons/AddPalette" to="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/PaletteVBoxContainer/ScrollPalette/CenterPalette/PaletteContainer" method="_on_AddPalette_pressed"]
[connection signal="pressed" from="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/PaletteVBoxContainer/CenterContainer/PaletteButtons/EditPalette" to="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/PaletteVBoxContainer/ScrollPalette/CenterPalette/PaletteContainer" method="on_edit_palette"]
[connection signal="item_selected" from="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/PaletteVBoxContainer/CenterContainer/PaletteButtons/PaletteOptionButton" to="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/PaletteVBoxContainer/ScrollPalette/CenterPalette/PaletteContainer" method="_on_PaletteOptionButton_item_selected"]
[connection signal="pressed" from="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels/LayerVBoxContainer/CenterLayerButtons/LayerButtons/AddLayer" to="." method="add_layer"]
[connection signal="pressed" from="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels/LayerVBoxContainer/CenterLayerButtons/LayerButtons/RemoveLayer" to="." method="_on_RemoveLayerButton_pressed"]
[connection signal="pressed" from="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels/LayerVBoxContainer/CenterLayerButtons/LayerButtons/MoveUpLayer" to="." method="change_layer_order" binds= [ 1 ]]
[connection signal="pressed" from="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels/LayerVBoxContainer/CenterLayerButtons/LayerButtons/MovwDownLayer" to="." method="change_layer_order" binds= [ -1 ]]
[connection signal="pressed" from="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels/LayerVBoxContainer/CenterLayerButtons/LayerButtons/CloneLayer" to="." method="add_layer" binds= [ false ]]
[connection signal="pressed" from="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels/LayerVBoxContainer/CenterLayerButtons/LayerButtons/MergeDownLayer" to="." method="_on_MergeLayer_pressed"]
[connection signal="value_changed" from="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels/LayerVBoxContainer/OpacityContainer/OpacitySlider" to="." method="_on_OpacitySlider_value_changed"]
[connection signal="value_changed" from="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/VBoxLayerWithLabels/LayerVBoxContainer/OpacityContainer/OpacitySpinBox" to="." method="_on_OpacitySlider_value_changed"]
[connection signal="pressed" from="MenuAndUI/UI/RightPanel/PreviewAndPalettes/PaletteVBoxContainer/CenterContainer/PaletteButtons/AddPalette" to="MenuAndUI/UI/RightPanel/PreviewAndPalettes/PaletteVBoxContainer/ScrollPalette/CenterPalette/PaletteContainer" method="_on_AddPalette_pressed"]
[connection signal="pressed" from="MenuAndUI/UI/RightPanel/PreviewAndPalettes/PaletteVBoxContainer/CenterContainer/PaletteButtons/EditPalette" to="MenuAndUI/UI/RightPanel/PreviewAndPalettes/PaletteVBoxContainer/ScrollPalette/CenterPalette/PaletteContainer" method="on_edit_palette"]
[connection signal="item_selected" from="MenuAndUI/UI/RightPanel/PreviewAndPalettes/PaletteVBoxContainer/CenterContainer/PaletteButtons/PaletteOptionButton" to="MenuAndUI/UI/RightPanel/PreviewAndPalettes/PaletteVBoxContainer/ScrollPalette/CenterPalette/PaletteContainer" method="_on_PaletteOptionButton_item_selected"]
[connection signal="popup_hide" from="SplashDialog" to="." method="_can_draw_true"]
[connection signal="popup_hide" from="CreateNewImage" to="." method="_can_draw_true"]
[connection signal="file_selected" from="OpenSprite" to="." method="_on_OpenSprite_file_selected"]
@ -1557,8 +1360,8 @@ visible = false
[connection signal="confirmed" from="QuitAndSaveDialog" to="." method="_on_QuitDialog_confirmed"]
[connection signal="custom_action" from="QuitAndSaveDialog" to="." method="_on_QuitAndSaveDialog_custom_action"]
[connection signal="popup_hide" from="QuitAndSaveDialog" to="." method="_can_draw_true"]
[connection signal="confirmed" from="NewPaletteDialog" to="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/PaletteVBoxContainer/ScrollPalette/CenterPalette/PaletteContainer" method="on_new_palette_confirmed"]
[connection signal="file_selected" from="PaletteImportFileDialog" to="MenuAndUI/UI/LayerPanel/LayersAndMisc/VSplitContainer/PaletteVBoxContainer/ScrollPalette/CenterPalette/PaletteContainer" method="on_palette_import_file_selected"]
[connection signal="confirmed" from="NewPaletteDialog" to="MenuAndUI/UI/RightPanel/PreviewAndPalettes/PaletteVBoxContainer/ScrollPalette/CenterPalette/PaletteContainer" method="on_new_palette_confirmed"]
[connection signal="file_selected" from="PaletteImportFileDialog" to="MenuAndUI/UI/RightPanel/PreviewAndPalettes/PaletteVBoxContainer/ScrollPalette/CenterPalette/PaletteContainer" method="on_palette_import_file_selected"]
[editable path="BrushesPopup/TabContainer/File/FileBrushContainer/CircleBrushButton"]

View file

@ -1,23 +1,39 @@
[gd_scene load_steps=31 format=2]
[gd_scene load_steps=47 format=2]
[ext_resource path="res://Scripts/AnimationTimeline.gd" type="Script" id=1]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Go_To_First_Frame.png" type="Texture" id=2]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Go_To_First_Frame_Hover.png" type="Texture" id=3]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Previous_Frame.png" type="Texture" id=4]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Previous_Frame_Hover.png" type="Texture" id=5]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Play Backwards.png" type="Texture" id=6]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Pause.png" type="Texture" id=7]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Play Backwards_Hover.png" type="Texture" id=8]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Play.png" type="Texture" id=9]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Play_Hover.png" type="Texture" id=10]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Next_Frame.png" type="Texture" id=11]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Next_Frame_Hover.png" type="Texture" id=12]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Go_To_Last_Frame.png" type="Texture" id=13]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Go_To_Last_Frame_Hover.png" type="Texture" id=14]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Loop_None.png" type="Texture" id=15]
[ext_resource path="res://Scripts/Rulers/TimelineSeconds.gd" type="Script" id=16]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/New_Frame.png" type="Texture" id=17]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/New_Frame_Hover.png" type="Texture" id=18]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/New_Layer.png" type="Texture" id=2]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/New_Layer_Hover.png" type="Texture" id=3]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Delete_Layer.png" type="Texture" id=4]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Delete_Layer_Hover.png" type="Texture" id=5]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Delete_Layer_Disabled.png" type="Texture" id=6]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Move_Up.png" type="Texture" id=7]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Move_Up_Hover.png" type="Texture" id=8]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Move_Up_Disabled.png" type="Texture" id=9]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Move_Down.png" type="Texture" id=10]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Move_Down_Hover.png" type="Texture" id=11]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Move_Down_Disabled.png" type="Texture" id=12]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Clone_Layer.png" type="Texture" id=13]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Clone_Layer_Hover.png" type="Texture" id=14]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Merge_Down.png" type="Texture" id=15]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Merge_Down_Hover.png" type="Texture" id=16]
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Merge_Down_Disabled.png" type="Texture" id=17]
[ext_resource path="res://Prefabs/LayerContainer.tscn" type="PackedScene" id=18]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/New_Frame.png" type="Texture" id=19]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/New_Frame_Hover.png" type="Texture" id=20]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Go_To_First_Frame.png" type="Texture" id=21]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Go_To_First_Frame_Hover.png" type="Texture" id=22]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Previous_Frame.png" type="Texture" id=23]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Previous_Frame_Hover.png" type="Texture" id=24]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Play Backwards.png" type="Texture" id=25]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Pause.png" type="Texture" id=26]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Play Backwards_Hover.png" type="Texture" id=27]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Play.png" type="Texture" id=28]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Play_Hover.png" type="Texture" id=29]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Next_Frame.png" type="Texture" id=30]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Next_Frame_Hover.png" type="Texture" id=31]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Go_To_Last_Frame.png" type="Texture" id=32]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Go_To_Last_Frame_Hover.png" type="Texture" id=33]
[ext_resource path="res://Assets/Graphics/Dark Themes/Timeline/Loop_None.png" type="Texture" id=34]
[sub_resource type="InputEventKey" id=1]
control = true
@ -64,19 +80,20 @@ scancode = 16777230
shortcut = SubResource( 11 )
[node name="AnimationTimeline" type="Panel"]
margin_top = 478.0
margin_top = 438.0
margin_right = 704.0
margin_bottom = 620.0
rect_min_size = Vector2( 0, 142 )
rect_min_size = Vector2( 0, 200 )
size_flags_horizontal = 3
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="VSeparator" type="VSeparator" parent="."]
anchor_top = 0.5
anchor_bottom = 0.5
margin_top = -71.0
anchor_bottom = 1.0
margin_right = 4.0
margin_bottom = 71.0
size_flags_vertical = 3
[node name="AnimationContainer" type="HBoxContainer" parent="."]
anchor_right = 1.0
@ -86,26 +103,227 @@ margin_top = 4.0
[node name="TimelineContainer" type="VBoxContainer" parent="AnimationContainer"]
margin_right = 543.0
margin_bottom = 138.0
margin_bottom = 196.0
size_flags_horizontal = 3
[node name="AnimationButtons" type="HBoxContainer" parent="AnimationContainer/TimelineContainer"]
[node name="LayerButtons" type="HBoxContainer" parent="AnimationContainer/TimelineContainer"]
margin_right = 543.0
margin_bottom = 32.0
[node name="AddLayer" type="TextureButton" parent="AnimationContainer/TimelineContainer/LayerButtons" groups=[
"UIButtons",
]]
margin_right = 32.0
margin_bottom = 32.0
hint_tooltip = "LAYERNEW_HT"
mouse_default_cursor_shape = 2
texture_normal = ExtResource( 2 )
texture_hover = ExtResource( 3 )
[node name="RemoveLayer" type="TextureButton" parent="AnimationContainer/TimelineContainer/LayerButtons" groups=[
"UIButtons",
]]
margin_left = 36.0
margin_right = 68.0
margin_bottom = 32.0
hint_tooltip = "LAYERREMOVE_HT"
mouse_default_cursor_shape = 8
disabled = true
texture_normal = ExtResource( 4 )
texture_hover = ExtResource( 5 )
texture_disabled = ExtResource( 6 )
[node name="MoveUpLayer" type="TextureButton" parent="AnimationContainer/TimelineContainer/LayerButtons" groups=[
"UIButtons",
]]
margin_left = 72.0
margin_right = 104.0
margin_bottom = 32.0
hint_tooltip = "LAYERUP_HT"
mouse_default_cursor_shape = 8
disabled = true
texture_normal = ExtResource( 7 )
texture_hover = ExtResource( 8 )
texture_disabled = ExtResource( 9 )
[node name="MovwDownLayer" type="TextureButton" parent="AnimationContainer/TimelineContainer/LayerButtons" groups=[
"UIButtons",
]]
margin_left = 108.0
margin_right = 140.0
margin_bottom = 32.0
hint_tooltip = "LAYERDOWN_HT"
mouse_default_cursor_shape = 8
disabled = true
texture_normal = ExtResource( 10 )
texture_hover = ExtResource( 11 )
texture_disabled = ExtResource( 12 )
[node name="CloneLayer" type="TextureButton" parent="AnimationContainer/TimelineContainer/LayerButtons" groups=[
"UIButtons",
]]
margin_left = 144.0
margin_right = 176.0
margin_bottom = 32.0
hint_tooltip = "LAYERCLONE_HT"
mouse_default_cursor_shape = 2
texture_normal = ExtResource( 13 )
texture_hover = ExtResource( 14 )
[node name="MergeDownLayer" type="TextureButton" parent="AnimationContainer/TimelineContainer/LayerButtons" groups=[
"UIButtons",
]]
margin_left = 180.0
margin_right = 212.0
margin_bottom = 32.0
hint_tooltip = "LAYERMERGE_HT"
mouse_default_cursor_shape = 8
disabled = true
texture_normal = ExtResource( 15 )
texture_hover = ExtResource( 16 )
texture_disabled = ExtResource( 17 )
[node name="AnimationTags" type="VBoxContainer" parent="AnimationContainer/TimelineContainer/LayerButtons"]
visible = false
margin_left = 216.0
margin_right = 326.0
margin_bottom = 32.0
[node name="Line2D" type="Line2D" parent="AnimationContainer/TimelineContainer/LayerButtons/AnimationTags"]
points = PoolVector2Array( 0, 32, 0, 0, 110, 0, 110, 32 )
width = 1.0
texture_mode = 1313163520
[node name="Label" type="Label" parent="AnimationContainer/TimelineContainer/LayerButtons/AnimationTags"]
margin_right = 110.0
margin_bottom = 32.0
rect_min_size = Vector2( 110, 32 )
size_flags_horizontal = 0
size_flags_vertical = 0
text = "Animation Tags"
align = 1
valign = 1
[node name="OpacityContainer" type="HBoxContainer" parent="AnimationContainer/TimelineContainer"]
margin_top = 36.0
margin_right = 543.0
margin_bottom = 60.0
custom_constants/separation = 2
[node name="OpacityLabel" type="Label" parent="AnimationContainer/TimelineContainer/OpacityContainer"]
margin_right = 53.0
margin_bottom = 24.0
size_flags_horizontal = 0
size_flags_vertical = 1
text = "Opacity:"
valign = 1
[node name="OpacitySlider" type="HSlider" parent="AnimationContainer/TimelineContainer/OpacityContainer"]
margin_left = 55.0
margin_right = 167.0
margin_bottom = 24.0
rect_min_size = Vector2( 112, 0 )
mouse_default_cursor_shape = 2
size_flags_vertical = 1
value = 100.0
ticks_on_borders = true
[node name="OpacitySpinBox" type="SpinBox" parent="AnimationContainer/TimelineContainer/OpacityContainer"]
margin_left = 169.0
margin_right = 243.0
margin_bottom = 24.0
mouse_default_cursor_shape = 2
size_flags_vertical = 4
value = 100.0
align = 1
[node name="TimelineScroll" type="ScrollContainer" parent="AnimationContainer/TimelineContainer"]
margin_top = 64.0
margin_right = 543.0
margin_bottom = 160.0
size_flags_vertical = 3
[node name="LayersAndFrames" type="HBoxContainer" parent="AnimationContainer/TimelineContainer/TimelineScroll"]
margin_right = 252.0
margin_bottom = 96.0
size_flags_vertical = 3
[node name="VBoxContainer" type="VBoxContainer" parent="AnimationContainer/TimelineContainer/TimelineScroll/LayersAndFrames"]
margin_right = 212.0
margin_bottom = 96.0
[node name="LayerLabel" type="Label" parent="AnimationContainer/TimelineContainer/TimelineScroll/LayersAndFrames/VBoxContainer"]
margin_right = 212.0
margin_bottom = 16.0
rect_min_size = Vector2( 0, 16 )
text = "Layers"
align = 1
valign = 1
[node name="LayersContainer" type="VBoxContainer" parent="AnimationContainer/TimelineContainer/TimelineScroll/LayersAndFrames/VBoxContainer"]
margin_top = 20.0
margin_right = 212.0
margin_bottom = 56.0
[node name="LayerContainer" parent="AnimationContainer/TimelineContainer/TimelineScroll/LayersAndFrames/VBoxContainer/LayersContainer" instance=ExtResource( 18 )]
margin_right = 212.0
[node name="VBoxContainer2" type="VBoxContainer" parent="AnimationContainer/TimelineContainer/TimelineScroll/LayersAndFrames"]
margin_left = 216.0
margin_right = 252.0
margin_bottom = 96.0
[node name="FrameIDs" type="HBoxContainer" parent="AnimationContainer/TimelineContainer/TimelineScroll/LayersAndFrames/VBoxContainer2"]
margin_right = 36.0
margin_bottom = 14.0
[node name="Label" type="Label" parent="AnimationContainer/TimelineContainer/TimelineScroll/LayersAndFrames/VBoxContainer2/FrameIDs"]
margin_right = 36.0
margin_bottom = 14.0
rect_min_size = Vector2( 36, 0 )
text = "1"
align = 1
[node name="FramesContainer" type="VBoxContainer" parent="AnimationContainer/TimelineContainer/TimelineScroll/LayersAndFrames/VBoxContainer2"]
margin_top = 18.0
margin_right = 36.0
margin_bottom = 18.0
[node name="HSeparator" type="HSeparator" parent="AnimationContainer/TimelineContainer"]
margin_top = 164.0
margin_right = 543.0
margin_bottom = 168.0
[node name="AnimationButtons" type="HBoxContainer" parent="AnimationContainer/TimelineContainer"]
margin_top = 172.0
margin_right = 543.0
margin_bottom = 196.0
rect_min_size = Vector2( 0, 24 )
[node name="CurrentFrame" type="Label" parent="AnimationContainer/TimelineContainer/AnimationButtons"]
margin_top = 5.0
margin_right = 218.0
margin_right = 117.0
margin_bottom = 19.0
size_flags_horizontal = 3
text = "Current frame: 1/1"
[node name="AddFrame" type="TextureButton" parent="AnimationContainer/TimelineContainer/AnimationButtons" groups=[
"UIButtons",
]]
margin_left = 121.0
margin_right = 141.0
margin_bottom = 20.0
hint_tooltip = "Add a new frame"
mouse_default_cursor_shape = 2
size_flags_horizontal = 0
size_flags_vertical = 0
texture_normal = ExtResource( 19 )
texture_hover = ExtResource( 20 )
[node name="PlaybackButtons" type="HBoxContainer" parent="AnimationContainer/TimelineContainer/AnimationButtons"]
margin_left = 222.0
margin_right = 362.0
margin_left = 223.0
margin_right = 363.0
margin_bottom = 24.0
size_flags_horizontal = 2
size_flags_horizontal = 6
[node name="FirstFrame" type="TextureButton" parent="AnimationContainer/TimelineContainer/AnimationButtons/PlaybackButtons" groups=[
"UIButtons",
@ -116,8 +334,8 @@ hint_tooltip = "FIRSTFRAME_HT"
mouse_default_cursor_shape = 2
shortcut_in_tooltip = false
shortcut = SubResource( 2 )
texture_normal = ExtResource( 2 )
texture_hover = ExtResource( 3 )
texture_normal = ExtResource( 21 )
texture_hover = ExtResource( 22 )
[node name="PreviousFrame" type="TextureButton" parent="AnimationContainer/TimelineContainer/AnimationButtons/PlaybackButtons" groups=[
"UIButtons",
@ -129,8 +347,8 @@ hint_tooltip = "PREVIOUSFRAME_HT"
mouse_default_cursor_shape = 2
shortcut_in_tooltip = false
shortcut = SubResource( 4 )
texture_normal = ExtResource( 4 )
texture_hover = ExtResource( 5 )
texture_normal = ExtResource( 23 )
texture_hover = ExtResource( 24 )
[node name="PlayBackwards" type="TextureButton" parent="AnimationContainer/TimelineContainer/AnimationButtons/PlaybackButtons" groups=[
"UIButtons",
@ -143,9 +361,9 @@ mouse_default_cursor_shape = 2
toggle_mode = true
shortcut_in_tooltip = false
shortcut = SubResource( 6 )
texture_normal = ExtResource( 6 )
texture_pressed = ExtResource( 7 )
texture_hover = ExtResource( 8 )
texture_normal = ExtResource( 25 )
texture_pressed = ExtResource( 26 )
texture_hover = ExtResource( 27 )
[node name="PlayForward" type="TextureButton" parent="AnimationContainer/TimelineContainer/AnimationButtons/PlaybackButtons" groups=[
"UIButtons",
@ -159,9 +377,9 @@ size_flags_horizontal = 0
toggle_mode = true
shortcut_in_tooltip = false
shortcut = SubResource( 8 )
texture_normal = ExtResource( 9 )
texture_pressed = ExtResource( 7 )
texture_hover = ExtResource( 10 )
texture_normal = ExtResource( 28 )
texture_pressed = ExtResource( 26 )
texture_hover = ExtResource( 29 )
[node name="NextFrame" type="TextureButton" parent="AnimationContainer/TimelineContainer/AnimationButtons/PlaybackButtons" groups=[
"UIButtons",
@ -173,8 +391,8 @@ hint_tooltip = "NEXTFRAME_HT"
mouse_default_cursor_shape = 2
shortcut_in_tooltip = false
shortcut = SubResource( 10 )
texture_normal = ExtResource( 11 )
texture_hover = ExtResource( 12 )
texture_normal = ExtResource( 30 )
texture_hover = ExtResource( 31 )
[node name="LastFrame" type="TextureButton" parent="AnimationContainer/TimelineContainer/AnimationButtons/PlaybackButtons" groups=[
"UIButtons",
@ -186,12 +404,12 @@ hint_tooltip = "LASTFRAME_HT"
mouse_default_cursor_shape = 2
shortcut_in_tooltip = false
shortcut = SubResource( 12 )
texture_normal = ExtResource( 13 )
texture_hover = ExtResource( 14 )
texture_normal = ExtResource( 32 )
texture_hover = ExtResource( 33 )
[node name="LoopButtons" type="HBoxContainer" parent="AnimationContainer/TimelineContainer/AnimationButtons"]
margin_left = 444.0
margin_right = 542.0
margin_left = 445.0
margin_right = 543.0
margin_bottom = 24.0
size_flags_horizontal = 0
@ -214,60 +432,17 @@ margin_right = 98.0
margin_bottom = 24.0
hint_tooltip = "No loop"
mouse_default_cursor_shape = 2
texture_normal = ExtResource( 15 )
[node name="HSeparator" type="HSeparator" parent="AnimationContainer/TimelineContainer"]
margin_top = 28.0
margin_right = 543.0
margin_bottom = 32.0
[node name="TimelineSeconds" type="Control" parent="AnimationContainer/TimelineContainer"]
margin_top = 36.0
margin_right = 543.0
margin_bottom = 52.0
rect_min_size = Vector2( 0, 16 )
script = ExtResource( 16 )
[node name="HSeparator2" type="HSeparator" parent="AnimationContainer/TimelineContainer"]
margin_top = 56.0
margin_right = 543.0
margin_bottom = 60.0
[node name="FrameAndButtonContainer" type="HBoxContainer" parent="AnimationContainer/TimelineContainer"]
margin_top = 64.0
margin_right = 543.0
margin_bottom = 84.0
[node name="AddFrame" type="TextureButton" parent="AnimationContainer/TimelineContainer/FrameAndButtonContainer" groups=[
"UIButtons",
]]
margin_right = 20.0
margin_bottom = 20.0
hint_tooltip = "Add a new frame"
mouse_default_cursor_shape = 2
size_flags_horizontal = 0
texture_normal = ExtResource( 17 )
texture_hover = ExtResource( 18 )
[node name="ScrollContainer" type="ScrollContainer" parent="AnimationContainer/TimelineContainer/FrameAndButtonContainer"]
margin_left = 24.0
margin_right = 543.0
margin_bottom = 20.0
size_flags_horizontal = 3
size_flags_vertical = 3
scroll_vertical_enabled = false
[node name="FrameContainer" type="HBoxContainer" parent="AnimationContainer/TimelineContainer/FrameAndButtonContainer/ScrollContainer"]
texture_normal = ExtResource( 34 )
[node name="VSeparator" type="VSeparator" parent="AnimationContainer"]
margin_left = 547.0
margin_right = 551.0
margin_bottom = 138.0
margin_bottom = 196.0
[node name="OnionSkinningButtons" type="VBoxContainer" parent="AnimationContainer"]
margin_left = 555.0
margin_right = 681.0
margin_bottom = 138.0
margin_bottom = 196.0
[node name="OnionSkinning" type="Label" parent="AnimationContainer/OnionSkinningButtons"]
margin_right = 126.0
@ -310,9 +485,18 @@ text = "Blue-Red Mode"
[node name="VSeparator2" type="VSeparator" parent="AnimationContainer"]
margin_left = 685.0
margin_right = 689.0
margin_bottom = 138.0
margin_bottom = 196.0
[node name="AnimationTimer" type="Timer" parent="."]
[connection signal="pressed" from="AnimationContainer/TimelineContainer/LayerButtons/AddLayer" to="." method="add_layer" binds= [ true ]]
[connection signal="pressed" from="AnimationContainer/TimelineContainer/LayerButtons/RemoveLayer" to="." method="_on_RemoveLayer_pressed"]
[connection signal="pressed" from="AnimationContainer/TimelineContainer/LayerButtons/MoveUpLayer" to="." method="change_layer_order" binds= [ 1 ]]
[connection signal="pressed" from="AnimationContainer/TimelineContainer/LayerButtons/MovwDownLayer" to="." method="change_layer_order" binds= [ -1 ]]
[connection signal="pressed" from="AnimationContainer/TimelineContainer/LayerButtons/CloneLayer" to="." method="add_layer" binds= [ false ]]
[connection signal="pressed" from="AnimationContainer/TimelineContainer/LayerButtons/MergeDownLayer" to="." method="_on_MergeDownLayer_pressed"]
[connection signal="value_changed" from="AnimationContainer/TimelineContainer/OpacityContainer/OpacitySlider" to="." method="_on_OpacitySlider_value_changed"]
[connection signal="value_changed" from="AnimationContainer/TimelineContainer/OpacityContainer/OpacitySpinBox" to="." method="_on_OpacitySlider_value_changed"]
[connection signal="pressed" from="AnimationContainer/TimelineContainer/AnimationButtons/AddFrame" to="." method="add_frame"]
[connection signal="pressed" from="AnimationContainer/TimelineContainer/AnimationButtons/PlaybackButtons/FirstFrame" to="." method="_on_FirstFrame_pressed"]
[connection signal="pressed" from="AnimationContainer/TimelineContainer/AnimationButtons/PlaybackButtons/PreviousFrame" to="." method="_on_PreviousFrame_pressed"]
[connection signal="toggled" from="AnimationContainer/TimelineContainer/AnimationButtons/PlaybackButtons/PlayBackwards" to="." method="_on_PlayBackwards_toggled"]
@ -321,8 +505,6 @@ margin_bottom = 138.0
[connection signal="pressed" from="AnimationContainer/TimelineContainer/AnimationButtons/PlaybackButtons/LastFrame" to="." method="_on_LastFrame_pressed"]
[connection signal="value_changed" from="AnimationContainer/TimelineContainer/AnimationButtons/LoopButtons/FPSValue" to="." method="_on_FPSValue_value_changed"]
[connection signal="pressed" from="AnimationContainer/TimelineContainer/AnimationButtons/LoopButtons/LoopAnim" to="." method="_on_LoopAnim_pressed"]
[connection signal="pressed" from="AnimationContainer/TimelineContainer/FrameAndButtonContainer/AddFrame" to="." method="add_frame"]
[connection signal="gui_input" from="AnimationContainer/TimelineContainer/FrameAndButtonContainer/ScrollContainer" to="AnimationContainer/TimelineContainer/TimelineSeconds" method="_on_ScrollContainer_gui_input"]
[connection signal="value_changed" from="AnimationContainer/OnionSkinningButtons/PastOnionSkinning" to="." method="_on_PastOnionSkinning_value_changed"]
[connection signal="value_changed" from="AnimationContainer/OnionSkinningButtons/FutureOnionSkinning" to="." method="_on_FutureOnionSkinning_value_changed"]
[connection signal="toggled" from="AnimationContainer/OnionSkinningButtons/BlueRedMode" to="." method="_on_BlueRedMode_toggled"]

View file

@ -2,13 +2,10 @@
[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="."]
[node name="FrameButton" type="Button"]
margin_top = 18.0
margin_right = 36.0
margin_bottom = 36.0
margin_bottom = 54.0
rect_min_size = Vector2( 36, 36 )
mouse_default_cursor_shape = 2
size_flags_horizontal = 0
@ -16,8 +13,11 @@ size_flags_vertical = 0
toggle_mode = true
button_mask = 7
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="FrameTexture" type="TextureRect" parent="FrameButton"]
[node name="FrameTexture" type="TextureRect" parent="."]
margin_left = 2.0
margin_top = 2.0
margin_right = 34.0
@ -28,17 +28,10 @@ size_flags_vertical = 0
expand = true
stretch_mode = 6
[node name="PopupMenu" type="PopupMenu" parent="FrameButton"]
[node name="PopupMenu" type="PopupMenu" parent="."]
margin_right = 20.0
margin_bottom = 20.0
mouse_default_cursor_shape = 2
items = [ "Remove Frame", null, 0, false, true, -1, 0, null, "", false, "Clone Frame", null, 0, false, false, -1, 0, null, "", false, "Move Left", null, 0, false, true, -1, 0, null, "", false, "Move Right", null, 0, false, true, -1, 0, null, "", false ]
[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"]
[connection signal="id_pressed" from="FrameButton/PopupMenu" to="FrameButton" method="_on_PopupMenu_id_pressed"]
[connection signal="pressed" from="." to="." method="_on_FrameButton_pressed"]
[connection signal="id_pressed" from="PopupMenu" to="." method="_on_PopupMenu_id_pressed"]

View file

@ -5,22 +5,35 @@
[ext_resource path="res://Assets/Graphics/Dark Themes/Layers/Layer_Visible_Hover.png" type="Texture" id=3]
[node name="LayerContainer" type="Button"]
margin_right = 160.0
margin_bottom = 42.0
rect_min_size = Vector2( 160, 42 )
margin_right = 210.0
margin_bottom = 36.0
rect_min_size = Vector2( 212, 36 )
size_flags_horizontal = 0
toggle_mode = true
script = ExtResource( 1 )
__meta__ = {
"_edit_horizontal_guides_": [ ]
"_edit_horizontal_guides_": [ ],
"_edit_use_anchors_": false
}
[node name="VisibilityButton" type="TextureButton" parent="." groups=[
[node name="HBoxContainer" type="HBoxContainer" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
size_flags_horizontal = 0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="LayerButtons" type="HBoxContainer" parent="HBoxContainer"]
margin_right = 32.0
margin_bottom = 36.0
[node name="VisibilityButton" type="TextureButton" parent="HBoxContainer/LayerButtons" groups=[
"UIButtons",
]]
margin_left = 6.0
margin_top = 5.0
margin_right = 38.0
margin_bottom = 37.0
margin_top = 2.0
margin_right = 32.0
margin_bottom = 34.0
hint_tooltip = "LAYERVISIBILITY_HT"
mouse_default_cursor_shape = 2
size_flags_horizontal = 0
@ -28,34 +41,28 @@ size_flags_vertical = 4
texture_normal = ExtResource( 2 )
texture_hover = ExtResource( 3 )
[node name="HBoxContainer" type="HBoxContainer" parent="."]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -41.0
margin_top = -16.0
margin_right = 41.0
margin_bottom = 16.0
mouse_default_cursor_shape = 2
[node name="TextureRect" type="TextureRect" parent="HBoxContainer"]
margin_right = 32.0
margin_bottom = 32.0
rect_min_size = Vector2( 32, 32 )
size_flags_vertical = 4
expand = true
stretch_mode = 6
[node name="Label" type="Label" parent="HBoxContainer"]
[node name="LayerName" type="HBoxContainer" parent="HBoxContainer"]
margin_left = 36.0
margin_top = 9.0
margin_right = 82.0
margin_bottom = 23.0
margin_right = 212.0
margin_bottom = 36.0
rect_min_size = Vector2( 176, 0 )
mouse_default_cursor_shape = 2
size_flags_horizontal = 0
alignment = 1
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Label" type="Label" parent="HBoxContainer/LayerName"]
margin_top = 11.0
margin_right = 176.0
margin_bottom = 25.0
size_flags_horizontal = 3
text = "Layer 0"
align = 1
clip_text = true
[node name="LineEdit" type="LineEdit" parent="HBoxContainer"]
[node name="LineEdit" type="LineEdit" parent="HBoxContainer/LayerName"]
visible = false
margin_left = 86.0
margin_top = 5.0
@ -68,5 +75,4 @@ editable = false
caret_blink = true
caret_blink_speed = 0.5
[connection signal="pressed" from="." to="." method="_on_LayerContainer_pressed"]
[connection signal="pressed" from="VisibilityButton" to="." method="_on_VisibilityButton_pressed"]
[connection signal="text_changed" from="HBoxContainer/LineEdit" to="." method="_on_LineEdit_text_changed"]
[connection signal="pressed" from="HBoxContainer/LayerButtons/VisibilityButton" to="." method="_on_VisibilityButton_pressed"]

View file

@ -23,10 +23,7 @@ func add_frame() -> void:
Global.undo_redo.add_do_property(Global, "hidden_canvases", Global.hidden_canvases)
Global.undo_redo.add_do_property(Global, "canvas", new_canvas)
Global.undo_redo.add_do_property(Global, "current_frame", new_canvases.size() - 1)
for child in Global.frame_container.get_children():
var frame_button = child.get_node("FrameButton")
Global.undo_redo.add_do_property(frame_button, "pressed", false)
Global.undo_redo.add_undo_property(frame_button, "pressed", frame_button.pressed)
for c in Global.canvases:
Global.undo_redo.add_do_property(c, "visible", false)
Global.undo_redo.add_undo_property(c, "visible", c.visible)
@ -39,18 +36,15 @@ func add_frame() -> void:
func _on_LoopAnim_pressed() -> void:
match animation_loop:
0:
# Make it loop
0: # Make it loop
animation_loop = 1
Global.loop_animation_button.texture_normal = load("res://Assets/Graphics/%s Themes/Timeline/Loop.png" % Global.theme_type)
Global.loop_animation_button.hint_tooltip = "Cycle loop"
1:
# Make it ping-pong
1: # Make it ping-pong
animation_loop = 2
Global.loop_animation_button.texture_normal = load("res://Assets/Graphics/%s Themes/Timeline/Loop_PingPong.png" % Global.theme_type)
Global.loop_animation_button.hint_tooltip = "Ping-pong loop"
2:
# Make it stop
2: # Make it stop
animation_loop = 0
Global.loop_animation_button.texture_normal = load("res://Assets/Graphics/%s Themes/Timeline/Loop_None.png" % Global.theme_type)
Global.loop_animation_button.hint_tooltip = "No loop"
@ -142,3 +136,134 @@ func _on_FutureOnionSkinning_value_changed(value) -> void:
func _on_BlueRedMode_toggled(button_pressed) -> void:
Global.onion_skinning_blue_red = button_pressed
Global.canvas.update()
# Layer buttons
func add_layer(is_new := true) -> void:
var layer_name = null
if !is_new: # clone layer
layer_name = Global.layers[Global.current_layer][0] + " (" + tr("copy") + ")"
var new_layers : Array = Global.layers.duplicate()
# Store [Layer name, Layer visibility boolean, Frame container]
new_layers.append([layer_name, true, HBoxContainer.new()])
Global.undos += 1
Global.undo_redo.create_action("Add Layer")
for c in Global.canvases:
var new_layer := Image.new()
if is_new:
new_layer.create(c.size.x, c.size.y, false, Image.FORMAT_RGBA8)
else: # clone layer
new_layer.copy_from(c.layers[Global.current_layer][0])
new_layer.lock()
var new_layer_tex := ImageTexture.new()
new_layer_tex.create_from_image(new_layer, 0)
var new_canvas_layers : Array = c.layers.duplicate()
# Store [Image, ImageTexture, Opacity]
new_canvas_layers.append([new_layer, new_layer_tex, 1])
Global.undo_redo.add_do_property(c, "layers", new_canvas_layers)
Global.undo_redo.add_undo_property(c, "layers", c.layers)
Global.undo_redo.add_do_property(Global, "current_layer", Global.current_layer + 1)
Global.undo_redo.add_do_property(Global, "layers", new_layers)
Global.undo_redo.add_undo_property(Global, "current_layer", Global.current_layer)
Global.undo_redo.add_undo_property(Global, "layers", Global.layers)
Global.undo_redo.add_undo_method(Global, "undo", [Global.canvas])
Global.undo_redo.add_do_method(Global, "redo", [Global.canvas])
Global.undo_redo.commit_action()
func _on_RemoveLayer_pressed() -> void:
var new_layers : Array = Global.layers.duplicate()
new_layers.remove(Global.current_layer)
Global.undos += 1
Global.undo_redo.create_action("Remove Layer")
if Global.current_layer > 0:
Global.undo_redo.add_do_property(Global, "current_layer", Global.current_layer - 1)
else:
Global.undo_redo.add_do_property(Global, "current_layer", Global.current_layer)
for c in Global.canvases:
var new_canvas_layers : Array = c.layers.duplicate()
new_canvas_layers.remove(Global.current_layer)
Global.undo_redo.add_do_property(c, "layers", new_canvas_layers)
Global.undo_redo.add_undo_property(c, "layers", c.layers)
Global.undo_redo.add_do_property(Global, "layers", new_layers)
Global.undo_redo.add_undo_property(Global, "current_layer", Global.current_layer)
Global.undo_redo.add_undo_property(Global, "layers", Global.layers)
Global.undo_redo.add_do_method(Global, "redo", [Global.canvas])
Global.undo_redo.add_undo_method(Global, "undo", [Global.canvas])
Global.undo_redo.commit_action()
func change_layer_order(rate : int) -> void:
var change = Global.current_layer + rate
var new_layers : Array = Global.layers.duplicate()
var temp = new_layers[Global.current_layer]
new_layers[Global.current_layer] = new_layers[change]
new_layers[change] = temp
Global.undo_redo.create_action("Change Layer Order")
for c in Global.canvases:
var new_layers_canvas : Array = c.layers.duplicate()
var temp_canvas = new_layers_canvas[Global.current_layer]
new_layers_canvas[Global.current_layer] = new_layers_canvas[change]
new_layers_canvas[change] = temp_canvas
Global.undo_redo.add_do_property(c, "layers", new_layers_canvas)
Global.undo_redo.add_undo_property(c, "layers", c.layers)
Global.undo_redo.add_do_property(Global, "current_layer", change)
Global.undo_redo.add_do_property(Global, "layers", new_layers)
Global.undo_redo.add_undo_property(Global, "layers", Global.layers)
Global.undo_redo.add_undo_property(Global, "current_layer", Global.current_layer)
Global.undo_redo.add_undo_method(Global, "undo", [Global.canvas])
Global.undo_redo.add_do_method(Global, "redo", [Global.canvas])
Global.undo_redo.commit_action()
func _on_MergeDownLayer_pressed() -> void:
var new_layers : Array = Global.layers.duplicate()
new_layers.remove(Global.current_layer)
Global.undos += 1
Global.undo_redo.create_action("Merge Layer")
for c in Global.canvases:
var new_layers_canvas : Array = c.layers.duplicate()
new_layers_canvas.remove(Global.current_layer)
var selected_layer = c.layers[Global.current_layer][0]
if c.layers[Global.current_layer][2] < 1: # If we have layer transparency
for xx in selected_layer.get_size().x:
for yy in selected_layer.get_size().y:
var pixel_color : Color = selected_layer.get_pixel(xx, yy)
var alpha : float = pixel_color.a * c.layers[Global.current_layer][4]
selected_layer.set_pixel(xx, yy, Color(pixel_color.r, pixel_color.g, pixel_color.b, alpha))
var new_layer := Image.new()
new_layer.copy_from(c.layers[Global.current_layer - 1][0])
new_layer.lock()
c.blend_rect(new_layer, selected_layer, Rect2(c.position, c.size), Vector2.ZERO)
Global.undo_redo.add_do_property(c, "layers", new_layers_canvas)
Global.undo_redo.add_do_property(c.layers[Global.current_layer - 1][0], "data", new_layer.data)
Global.undo_redo.add_undo_property(c, "layers", c.layers)
Global.undo_redo.add_undo_property(c.layers[Global.current_layer - 1][0], "data", c.layers[Global.current_layer - 1][0].data)
Global.undo_redo.add_do_property(Global, "current_layer", Global.current_layer - 1)
Global.undo_redo.add_do_property(Global, "layers", new_layers)
Global.undo_redo.add_undo_property(Global, "layers", Global.layers)
Global.undo_redo.add_undo_property(Global, "current_layer", Global.current_layer)
Global.undo_redo.add_undo_method(Global, "undo", [Global.canvas])
Global.undo_redo.add_do_method(Global, "redo", [Global.canvas])
Global.undo_redo.commit_action()
func _on_OpacitySlider_value_changed(value) -> void:
Global.canvas.layers[Global.current_layer][2] = value / 100
Global.layer_opacity_slider.value = value
Global.layer_opacity_spinbox.value = value
Global.canvas.update()

View file

@ -6,9 +6,7 @@ var current_layer_index := 0
var location := Vector2.ZERO
var size := Vector2(64, 64)
var fill_color := Color(0, 0, 0, 0)
var frame := 0 setget frame_changed
var frame_button : VBoxContainer
var frame_texture_rect : TextureRect
var frame := 0
var current_pixel := Vector2.ZERO # pretty much same as mouse_pos, but can be accessed externally
var previous_mouse_pos := Vector2.ZERO
var previous_mouse_pos_for_lines := Vector2.ZERO
@ -31,8 +29,10 @@ var pen_pressure := 1.0 # For tablet pressure sensitivity
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
var fill_layers := layers.empty()
for l in Global.layers:
if fill_layers:
# The sprite itself
if layers.empty():
var sprite := Image.new()
if Global.is_default_image:
if Global.config_cache.has_section_key("preferences", "default_width"):
@ -50,21 +50,8 @@ func _ready() -> void:
var tex := ImageTexture.new()
tex.create_from_image(sprite, 0)
# Store [Image, ImageTexture, Layer Name, Visibity boolean, Opacity]
layers.append([sprite, tex, tr("Layer") + " 0", true, 1])
generate_layer_panels()
frame_button = load("res://Prefabs/FrameButton.tscn").instance()
frame_button.name = "Frame_%s" % frame
frame_button.get_node("FrameButton").frame = frame
frame_button.get_node("FrameButton").pressed = true
frame_button.get_node("FrameID").text = str(frame + 1)
frame_button.get_node("FrameID").add_color_override("font_color", Color("#3c5d75"))
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
# Store [Image, ImageTexture, Opacity]
layers.append([sprite, tex, 1])
# Only handle camera zoom settings & offset on the first frame
if Global.canvases[0] == self:
@ -89,9 +76,12 @@ func _draw() -> void:
color = Color.white
for i in range(1, Global.onion_skinning_past_rate + 1):
if Global.current_frame >= i:
for texture in Global.canvases[Global.current_frame - i].layers:
var layer_i := 0
for layer in Global.canvases[Global.current_frame - i].layers:
if Global.layers[layer_i][1]: # If it's visible
color.a = 0.6 / i
draw_texture(texture[1], location, color)
draw_texture(layer[1], location, color)
layer_i += 1
# Future
if Global.onion_skinning_future_rate > 0:
@ -102,25 +92,28 @@ func _draw() -> void:
color = Color.white
for i in range(1, Global.onion_skinning_future_rate + 1):
if Global.current_frame < Global.canvases.size() - i:
for texture in Global.canvases[Global.current_frame + i].layers:
var layer_i := 0
for layer in Global.canvases[Global.current_frame + i].layers:
if Global.layers[layer_i][1]: # If it's visible
color.a = 0.6 / i
draw_texture(texture[1], location, color)
draw_texture(layer[1], location, color)
layer_i += 1
# Draw current frame layers
for texture in layers:
var modulate_color := Color(1, 1, 1, texture[4])
if texture[3]: #if it's visible
draw_texture(texture[1], location, modulate_color)
for i in range(layers.size()):
var modulate_color := Color(1, 1, 1, layers[i][2])
if Global.layers[i][1]: # if it's visible
draw_texture(layers[i][1], location, modulate_color)
if Global.tile_mode:
draw_texture(texture[1], Vector2(location.x, location.y + size.y), modulate_color) #Down
draw_texture(texture[1], Vector2(location.x - size.x, location.y + size.y), modulate_color) #Down Left
draw_texture(texture[1], Vector2(location.x - size.x, location.y), modulate_color) #Left
draw_texture(texture[1], location - size, modulate_color) #Up left
draw_texture(texture[1], Vector2(location.x, location.y - size.y), modulate_color) #Up
draw_texture(texture[1], Vector2(location.x + size.x, location.y - size.y), modulate_color) #Up right
draw_texture(texture[1], Vector2(location.x + size.x, location.y), modulate_color) #Right
draw_texture(texture[1], location + size, modulate_color) #Down right
draw_texture(layers[i][1], Vector2(location.x, location.y + size.y), modulate_color) #Down
draw_texture(layers[i][1], Vector2(location.x - size.x, location.y + size.y), modulate_color) #Down Left
draw_texture(layers[i][1], Vector2(location.x - size.x, location.y), modulate_color) #Left
draw_texture(layers[i][1], location - size, modulate_color) #Up left
draw_texture(layers[i][1], Vector2(location.x, location.y - size.y), modulate_color) #Up
draw_texture(layers[i][1], Vector2(location.x + size.x, location.y - size.y), modulate_color) #Up right
draw_texture(layers[i][1], Vector2(location.x + size.x, location.y), modulate_color) #Right
draw_texture(layers[i][1], location + size, modulate_color) #Down right
# Idea taken from flurick (on GitHub)
if Global.draw_grid:
@ -204,6 +197,7 @@ func _input(event : InputEvent) -> void:
pen_pressure = 1 # This causes problems with tablets though
sprite_changed_this_frame = false
var sprite : Image = layers[Global.current_layer][0]
var mouse_pos := current_pixel
var mouse_pos_floored := mouse_pos.floor()
var mouse_pos_ceiled := mouse_pos.ceil()
@ -248,6 +242,7 @@ func _input(event : InputEvent) -> void:
Global.cursor_position_label.text = "[%s×%s] %s, %s" % [size.x, size.y, mouse_pos_floored.x, mouse_pos_floored.y]
if !cursor_inside_canvas:
cursor_inside_canvas = true
if Global.cursor_image.get_data().get_size() != Vector2.ZERO:
Input.set_custom_mouse_cursor(Global.cursor_image, 0, Vector2(15, 15))
if Global.show_left_tool_icon:
Global.left_cursor.visible = true
@ -292,9 +287,9 @@ func _input(event : InputEvent) -> void:
match current_action: # Handle current tool
"Pencil":
pencil_and_eraser(mouse_pos, current_color, current_mouse_button, current_action)
pencil_and_eraser(sprite, mouse_pos, current_color, current_mouse_button, current_action)
"Eraser":
pencil_and_eraser(mouse_pos, Color(0, 0, 0, 0), current_mouse_button, current_action)
pencil_and_eraser(sprite, mouse_pos, Color(0, 0, 0, 0), current_mouse_button, current_action)
"Bucket":
if can_handle:
if fill_area == 0: # Paint the specific area of the same color
@ -309,34 +304,34 @@ func _input(event : InputEvent) -> void:
horizontal_mirror = Global.right_horizontal_mirror
vertical_mirror = Global.right_vertical_mirror
flood_fill(mouse_pos, layers[current_layer_index][0].get_pixelv(mouse_pos), current_color)
flood_fill(sprite, mouse_pos, sprite.get_pixelv(mouse_pos), current_color)
if horizontal_mirror:
var pos := Vector2(mirror_x, mouse_pos.y)
flood_fill(pos, layers[current_layer_index][0].get_pixelv(pos), current_color)
flood_fill(sprite, pos, sprite.get_pixelv(pos), current_color)
if vertical_mirror:
var pos := Vector2(mouse_pos.x, mirror_y)
flood_fill(pos, layers[current_layer_index][0].get_pixelv(pos), current_color)
flood_fill(sprite, pos, sprite.get_pixelv(pos), current_color)
if horizontal_mirror && vertical_mirror:
var pos := Vector2(mirror_x, mirror_y)
flood_fill(pos, layers[current_layer_index][0].get_pixelv(pos), current_color)
flood_fill(sprite, pos, sprite.get_pixelv(pos), current_color)
else: # Paint all pixels of the same color
var pixel_color : Color = layers[current_layer_index][0].get_pixelv(mouse_pos)
var pixel_color : Color = sprite.get_pixelv(mouse_pos)
for xx in range(west_limit, east_limit):
for yy in range(north_limit, south_limit):
var c : Color = layers[current_layer_index][0].get_pixel(xx, yy)
var c : Color = sprite.get_pixel(xx, yy)
if c == pixel_color:
layers[current_layer_index][0].set_pixel(xx, yy, current_color)
sprite.set_pixel(xx, yy, current_color)
sprite_changed_this_frame = true
"LightenDarken":
if can_handle:
var pixel_color : Color = layers[current_layer_index][0].get_pixelv(mouse_pos)
var pixel_color : Color = sprite.get_pixelv(mouse_pos)
var color_changed : Color
if ld == 0: # Lighten
color_changed = pixel_color.lightened(ld_amount)
else: # Darken
color_changed = pixel_color.darkened(ld_amount)
pencil_and_eraser(mouse_pos, color_changed, current_mouse_button, current_action)
pencil_and_eraser(sprite, mouse_pos, color_changed, current_mouse_button, current_action)
"RectSelect":
# Check SelectionRectangle.gd for more code on Rectangle Selection
if Global.can_draw && Global.has_focus:
@ -363,7 +358,7 @@ func _input(event : InputEvent) -> void:
Global.selection_rectangle.polygon[3] = Vector2(start_pos.x, end_pos.y)
"ColorPicker":
if can_handle:
var pixel_color : Color = layers[current_layer_index][0].get_pixelv(mouse_pos)
var pixel_color : Color = sprite.get_pixelv(mouse_pos)
if color_picker_for == 0: # Pick for the left color
Global.left_color_picker.color = pixel_color
Global.update_left_custom_brush()
@ -422,7 +417,7 @@ func _input(event : InputEvent) -> void:
previous_mouse_pos.x = clamp(previous_mouse_pos.x, location.x, location.x + size.x)
previous_mouse_pos.y = clamp(previous_mouse_pos.y, location.y, location.y + size.y)
if sprite_changed_this_frame:
update_texture(current_layer_index, (Input.is_action_just_released("left_mouse") || Input.is_action_just_released("right_mouse")))
update_texture(Global.current_layer)
func camera_zoom() -> void:
# Set camera zoom based on the sprite size
@ -454,7 +449,7 @@ func handle_undo(action : String) -> void:
var layer_index := -1
if Global.animation_timer.is_stopped(): # if we're not animating, store only the current canvas
canvases = [self]
layer_index = current_layer_index
layer_index = Global.current_layer
else: # If we're animating, store all canvases
canvases = Global.canvases
Global.undos += 1
@ -462,10 +457,10 @@ func handle_undo(action : String) -> void:
for c in canvases:
# I'm not sure why I have to unlock it, but...
# ...if I don't, it doesn't work properly
c.layers[c.current_layer_index][0].unlock()
var data = c.layers[c.current_layer_index][0].data
c.layers[c.current_layer_index][0].lock()
Global.undo_redo.add_undo_property(c.layers[c.current_layer_index][0], "data", data)
c.layers[Global.current_layer][0].unlock()
var data = c.layers[Global.current_layer][0].data
c.layers[Global.current_layer][0].lock()
Global.undo_redo.add_undo_property(c.layers[Global.current_layer][0], "data", data)
if action == "Rectangle Select":
var selected_pixels = Global.selected_pixels.duplicate()
Global.undo_redo.add_undo_property(Global.selection_rectangle, "polygon", Global.selection_rectangle.polygon)
@ -483,40 +478,24 @@ func handle_redo(action : String) -> void:
var layer_index := -1
if Global.animation_timer.is_stopped():
canvases = [self]
layer_index = current_layer_index
layer_index = Global.current_layer
else:
canvases = Global.canvases
for c in canvases:
Global.undo_redo.add_do_property(c.layers[c.current_layer_index][0], "data", c.layers[c.current_layer_index][0].data)
Global.undo_redo.add_do_property(c.layers[Global.current_layer][0], "data", c.layers[Global.current_layer][0].data)
if action == "Rectangle Select":
Global.undo_redo.add_do_property(Global.selection_rectangle, "polygon", Global.selection_rectangle.polygon)
Global.undo_redo.add_do_property(Global, "selected_pixels", Global.selected_pixels)
Global.undo_redo.add_do_method(Global, "redo", canvases, layer_index)
Global.undo_redo.commit_action()
func update_texture(layer_index : int, update_frame_tex := true) -> void:
func update_texture(layer_index : int) -> void:
layers[layer_index][1].create_from_image(layers[layer_index][0], 0)
var layer_container := get_layer_container(layer_index)
if layer_container:
layer_container.get_child(1).get_child(0).texture = layers[layer_index][1]
if update_frame_tex:
# This code is used to update the texture in the animation timeline frame button
# but blend_rect causes major performance issues on large images
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
var frame_texture_rect : TextureRect
frame_texture_rect = Global.find_node_by_name(Global.layers[layer_index][2].get_child(frame),"FrameTexture")
frame_texture_rect.texture = layers[layer_index][1]
func frame_changed(value : int) -> void:
frame = value
if frame_button:
frame_button.get_node("FrameButton").frame = frame
frame_button.get_node("FrameID").text = str(frame + 1)
func get_layer_container(layer_index : int) -> LayerContainer:
for container in Global.vbox_layer_container.get_children():
@ -524,47 +503,24 @@ func get_layer_container(layer_index : int) -> LayerContainer:
return container
return null
func generate_layer_panels() -> void:
for child in Global.vbox_layer_container.get_children():
if child is LayerContainer:
child.queue_free()
current_layer_index = layers.size() - 1
if layers.size() == 1:
Global.remove_layer_button.disabled = true
Global.remove_layer_button.mouse_default_cursor_shape = Control.CURSOR_FORBIDDEN
else:
Global.remove_layer_button.disabled = false
Global.remove_layer_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
for i in range(layers.size() -1, -1, -1):
var layer_container = load("res://Prefabs/LayerContainer.tscn").instance()
if !layers[i][2]:
layers[i][2] = tr("Layer") + " %s" % i
layer_container.i = i
layer_container.get_child(1).get_child(0).texture = layers[i][1]
layer_container.get_child(1).get_child(1).text = layers[i][2]
layer_container.get_child(1).get_child(2).text = layers[i][2]
Global.vbox_layer_container.add_child(layer_container)
func pencil_and_eraser(mouse_pos : Vector2, color : Color, current_mouse_button : String, current_action := "None") -> void:
func pencil_and_eraser(sprite : Image, mouse_pos : Vector2, color : Color, current_mouse_button : String, current_action := "None") -> void:
if made_line:
return
if is_making_line:
fill_gaps(line_2d.points[1], previous_mouse_pos_for_lines, color, current_mouse_button, current_action)
draw_brush(line_2d.points[1], color, current_mouse_button, current_action)
fill_gaps(sprite, line_2d.points[1], previous_mouse_pos_for_lines, color, current_mouse_button, current_action)
draw_brush(sprite, line_2d.points[1], color, current_mouse_button, current_action)
made_line = true
else:
if point_in_rectangle(mouse_pos, location, location + size):
mouse_inside_canvas = true
# Draw
draw_brush(mouse_pos, color, current_mouse_button, current_action)
fill_gaps(mouse_pos, previous_mouse_pos, color, current_mouse_button, current_action) #Fill the gaps
draw_brush(sprite, mouse_pos, color, current_mouse_button, current_action)
fill_gaps(sprite, mouse_pos, previous_mouse_pos, color, current_mouse_button, current_action) # Fill the gaps
# If mouse is not inside bounds but it used to be, fill the gaps
elif point_in_rectangle(previous_mouse_pos, location, location + size):
fill_gaps(mouse_pos, previous_mouse_pos, color, current_mouse_button, current_action)
fill_gaps(sprite, mouse_pos, previous_mouse_pos, color, current_mouse_button, current_action)
func draw_brush(pos : Vector2, color : Color, current_mouse_button : String, current_action := "None") -> void:
func draw_brush(sprite : Image, pos : Vector2, color : Color, current_mouse_button : String, current_action := "None") -> void:
if Global.can_draw && Global.has_focus:
var brush_size := 1
var brush_type = Global.Brush_Types.PIXEL
@ -635,7 +591,7 @@ func draw_brush(pos : Vector2, color : Color, current_mouse_button : String, cur
if point_in_rectangle(Vector2(cur_pos_x, cur_pos_y), Vector2(west_limit - 1, north_limit - 1), Vector2(east_limit, south_limit)):
var pos_floored := Vector2(cur_pos_x, cur_pos_y).floor()
# Don't draw the same pixel over and over and don't re-lighten/darken it
var current_pixel_color : Color = layers[current_layer_index][0].get_pixel(cur_pos_x, cur_pos_y)
var current_pixel_color : Color = sprite.get_pixel(cur_pos_x, cur_pos_y)
var _c := color
if current_action == "Pencil" && color.a < 1:
_c = blend_colors(color, current_pixel_color)
@ -655,14 +611,14 @@ func draw_brush(pos : Vector2, color : Color, current_mouse_button : String, cur
mouse_press_pressure_values.append(pen_pressure)
else:
mouse_press_pressure_values[saved_pixel_index] = pen_pressure
layers[current_layer_index][0].set_pixel(cur_pos_x, cur_pos_y, _c)
sprite.set_pixel(cur_pos_x, cur_pos_y, _c)
sprite_changed_this_frame = true
# Handle mirroring
var mirror_x := east_limit + west_limit - cur_pos_x - 1
var mirror_y := south_limit + north_limit - cur_pos_y - 1
if horizontal_mirror:
current_pixel_color = layers[current_layer_index][0].get_pixel(mirror_x, cur_pos_y)
current_pixel_color = sprite.get_pixel(mirror_x, cur_pos_y)
if current_pixel_color != _c: # don't draw the same pixel over and over
if current_action == "LightenDarken":
if ld == 0: # Lighten
@ -672,23 +628,24 @@ func draw_brush(pos : Vector2, color : Color, current_mouse_button : String, cur
mouse_press_pixels.append(pos_floored)
mouse_press_pressure_values.append(pen_pressure)
layers[current_layer_index][0].set_pixel(mirror_x, cur_pos_y, _c)
sprite.set_pixel(mirror_x, cur_pos_y, _c)
sprite_changed_this_frame = true
if vertical_mirror:
current_pixel_color = layers[current_layer_index][0].get_pixel(cur_pos_x, mirror_y)
current_pixel_color = sprite.get_pixel(cur_pos_x, mirror_y)
if current_pixel_color != _c: # don't draw the same pixel over and over
if current_action == "LightenDarken":
if ld == 0: # Lighten
_c = current_pixel_color.lightened(ld_amount)
else:
_c = current_pixel_color.darkened(ld_amount)
mouse_press_pixels.append(pos_floored)
mouse_press_pressure_values.append(pen_pressure)
layers[current_layer_index][0].set_pixel(cur_pos_x, mirror_y, _c)
sprite.set_pixel(cur_pos_x, mirror_y, _c)
sprite_changed_this_frame = true
if horizontal_mirror && vertical_mirror:
current_pixel_color = layers[current_layer_index][0].get_pixel(mirror_x, mirror_y)
current_pixel_color = sprite.get_pixel(mirror_x, mirror_y)
if current_pixel_color != _c: # don't draw the same pixel over and over
if current_action == "LightenDarken":
if ld == 0: # Lighten
@ -698,21 +655,21 @@ func draw_brush(pos : Vector2, color : Color, current_mouse_button : String, cur
mouse_press_pixels.append(pos_floored)
mouse_press_pressure_values.append(pen_pressure)
layers[current_layer_index][0].set_pixel(mirror_x, mirror_y, _c)
sprite.set_pixel(mirror_x, mirror_y, _c)
sprite_changed_this_frame = true
elif brush_type == Global.Brush_Types.CIRCLE || brush_type == Global.Brush_Types.FILLED_CIRCLE:
plot_circle(layers[current_layer_index][0], pos.x, pos.y, brush_size, color, brush_type == Global.Brush_Types.FILLED_CIRCLE)
plot_circle(sprite, pos.x, pos.y, brush_size, color, brush_type == Global.Brush_Types.FILLED_CIRCLE)
# Handle mirroring
var mirror_x := east_limit + west_limit - pos.x
var mirror_y := south_limit + north_limit - pos.y
if horizontal_mirror:
plot_circle(layers[current_layer_index][0], mirror_x, pos.y, brush_size, color, brush_type == Global.Brush_Types.FILLED_CIRCLE)
plot_circle(sprite, mirror_x, pos.y, brush_size, color, brush_type == Global.Brush_Types.FILLED_CIRCLE)
if vertical_mirror:
plot_circle(layers[current_layer_index][0], pos.x, mirror_y, brush_size, color, brush_type == Global.Brush_Types.FILLED_CIRCLE)
plot_circle(sprite, pos.x, mirror_y, brush_size, color, brush_type == Global.Brush_Types.FILLED_CIRCLE)
if horizontal_mirror && vertical_mirror:
plot_circle(layers[current_layer_index][0], mirror_x, mirror_y, brush_size, color, brush_type == Global.Brush_Types.FILLED_CIRCLE)
plot_circle(sprite, mirror_x, mirror_y, brush_size, color, brush_type == Global.Brush_Types.FILLED_CIRCLE)
sprite_changed_this_frame = true
@ -755,13 +712,13 @@ func draw_brush(pos : Vector2, color : Color, current_mouse_button : String, cur
mirror_y -= 1
# Use custom blend function cause of godot's issue #31124
if color.a > 0: # If it's the pencil
blend_rect(layers[current_layer_index][0], custom_brush_image, src_rect, dst)
blend_rect(sprite, custom_brush_image, src_rect, dst)
if horizontal_mirror:
blend_rect(layers[current_layer_index][0], custom_brush_image, src_rect, Vector2(mirror_x, dst.y))
blend_rect(sprite, custom_brush_image, src_rect, Vector2(mirror_x, dst.y))
if vertical_mirror:
blend_rect(layers[current_layer_index][0], custom_brush_image, src_rect, Vector2(dst.x, mirror_y))
blend_rect(sprite, custom_brush_image, src_rect, Vector2(dst.x, mirror_y))
if horizontal_mirror && vertical_mirror:
blend_rect(layers[current_layer_index][0], custom_brush_image, src_rect, Vector2(mirror_x, mirror_y))
blend_rect(sprite, custom_brush_image, src_rect, Vector2(mirror_x, mirror_y))
else: # if it's transparent - if it's the eraser
var custom_brush := Image.new()
@ -770,15 +727,15 @@ func draw_brush(pos : Vector2, color : Color, current_mouse_button : String, cur
custom_brush.resize(custom_brush_size.x * brush_size, custom_brush_size.y * brush_size, Image.INTERPOLATE_NEAREST)
var custom_brush_blended = Global.blend_image_with_color(custom_brush, color, 1)
layers[current_layer_index][0].blit_rect_mask(custom_brush_blended, custom_brush, src_rect, dst)
sprite.blit_rect_mask(custom_brush_blended, custom_brush, src_rect, dst)
if horizontal_mirror:
layers[current_layer_index][0].blit_rect_mask(custom_brush_blended, custom_brush, src_rect, Vector2(mirror_x, dst.y))
sprite.blit_rect_mask(custom_brush_blended, custom_brush, src_rect, Vector2(mirror_x, dst.y))
if vertical_mirror:
layers[current_layer_index][0].blit_rect_mask(custom_brush_blended, custom_brush, src_rect, Vector2(dst.x, mirror_y))
sprite.blit_rect_mask(custom_brush_blended, custom_brush, src_rect, Vector2(dst.x, mirror_y))
if horizontal_mirror && vertical_mirror:
layers[current_layer_index][0].blit_rect_mask(custom_brush_blended, custom_brush, src_rect, Vector2(mirror_x, mirror_y))
sprite.blit_rect_mask(custom_brush_blended, custom_brush, src_rect, Vector2(mirror_x, mirror_y))
layers[current_layer_index][0].lock()
sprite.lock()
sprite_changed_this_frame = true
previous_mouse_pos_for_lines = pos.floor() + Vector2(0.5, 0.5)
@ -789,7 +746,7 @@ func draw_brush(pos : Vector2, color : Color, current_mouse_button : String, cur
# Bresenham's Algorithm
# Thanks to https://godotengine.org/qa/35276/tile-based-line-drawing-algorithm-efficiency
func fill_gaps(mouse_pos : Vector2, prev_mouse_pos : Vector2, color : Color, current_mouse_button : String, current_action := "None") -> void:
func fill_gaps(sprite : Image, mouse_pos : Vector2, prev_mouse_pos : Vector2, color : Color, current_mouse_button : String, current_action := "None") -> void:
var previous_mouse_pos_floored = prev_mouse_pos.floor()
var mouse_pos_floored = mouse_pos.floor()
mouse_pos_floored.x = clamp(mouse_pos_floored.x, location.x - 1, location.x + size.x)
@ -803,7 +760,7 @@ func fill_gaps(mouse_pos : Vector2, prev_mouse_pos : Vector2, color : Color, cur
var x = previous_mouse_pos_floored.x
var y = previous_mouse_pos_floored.y
while !(x == mouse_pos_floored.x && y == mouse_pos_floored.y):
draw_brush(Vector2(x, y), color, current_mouse_button, current_action)
draw_brush(sprite, Vector2(x, y), color, current_mouse_button, current_action)
e2 = err << 1
if e2 >= dy:
err += dy
@ -813,9 +770,9 @@ func fill_gaps(mouse_pos : Vector2, prev_mouse_pos : Vector2, color : Color, cur
y += sy
# Thanks to https://en.wikipedia.org/wiki/Flood_fill
func flood_fill(pos : Vector2, target_color : Color, replace_color : Color) -> void:
func flood_fill(sprite : Image, pos : Vector2, target_color : Color, replace_color : Color) -> void:
pos = pos.floor()
var pixel = layers[current_layer_index][0].get_pixelv(pos)
var pixel = sprite.get_pixelv(pos)
if target_color == replace_color:
return
elif pixel != target_color:
@ -832,20 +789,20 @@ func flood_fill(pos : Vector2, target_color : Color, replace_color : Color) -> v
break
var west : Vector2 = n
var east : Vector2 = n
while west.x >= west_limit && layers[current_layer_index][0].get_pixelv(west) == target_color:
while west.x >= west_limit && sprite.get_pixelv(west) == target_color:
west += Vector2.LEFT
while east.x < east_limit && layers[current_layer_index][0].get_pixelv(east) == target_color:
while east.x < east_limit && sprite.get_pixelv(east) == target_color:
east += Vector2.RIGHT
for px in range(west.x + 1, east.x):
var p := Vector2(px, n.y)
# Draw
layers[current_layer_index][0].set_pixelv(p, replace_color)
replace_color = layers[current_layer_index][0].get_pixelv(p)
sprite.set_pixelv(p, replace_color)
replace_color = sprite.get_pixelv(p)
var north := p + Vector2.UP
var south := p + Vector2.DOWN
if north.y >= north_limit && layers[current_layer_index][0].get_pixelv(north) == target_color:
if north.y >= north_limit && sprite.get_pixelv(north) == target_color:
q.append(north)
if south.y < south_limit && layers[current_layer_index][0].get_pixelv(south) == target_color:
if south.y < south_limit && sprite.get_pixelv(south) == target_color:
q.append(south)
sprite_changed_this_frame = true

View file

@ -77,7 +77,7 @@ func save_sprite(canvas : Canvas, path : String) -> void:
for layer in canvas.layers:
var img : Image = layer[0]
img.lock()
if layer[4] < 1: # If we have layer transparency
if layer[2] < 1: # If we have layer transparency
for xx in img.get_size().x:
for yy in img.get_size().y:
var pixel_color := img.get_pixel(xx, yy)
@ -132,7 +132,7 @@ func save_spritesheet() -> void:
for layer in canvas.layers:
var img : Image = layer[0]
img.lock()
if layer[4] < 1: # If we have layer transparency
if layer[2] < 1: # If we have layer transparency
for xx in img.get_size().x:
for yy in img.get_size().y:
var pixel_color := img.get_pixel(xx, yy)

View file

@ -55,8 +55,21 @@ func _on_ImportSprites_files_selected(paths : PoolStringArray) -> void:
image.lock()
var tex := ImageTexture.new()
tex.create_from_image(image, 0)
# Store [Image, ImageTexture, Layer Name, Visibity boolean, Opacity]
canvas.layers.append([image, tex, "Layer 0", true, 1])
# Store [Image, ImageTexture, Opacity]
canvas.layers.append([image, tex, 1])
for _i in range(1, Global.layers.size()):
var empty_sprite := Image.new()
empty_sprite.create(canvas.size.x, canvas.size.y, false, Image.FORMAT_RGBA8)
empty_sprite.fill(Color(0, 0, 0, 0))
empty_sprite.lock()
var empty_tex := ImageTexture.new()
empty_tex.create_from_image(empty_sprite, 0)
# Store [Image, ImageTexture, Opacity]
canvas.layers.append([empty_sprite, empty_tex, 1])
canvas.frame = i
Global.canvases.append(canvas)
Global.canvas_parent.add_child(canvas)
@ -96,8 +109,20 @@ func _on_ImportSprites_files_selected(paths : PoolStringArray) -> void:
cropped_image.lock()
var tex := ImageTexture.new()
tex.create_from_image(cropped_image, 0)
# Store [Image, ImageTexture, Layer Name, Visibity boolean, Opacity]
canvas.layers.append([cropped_image, tex, tr("Layer") + " 0", true, 1])
# Store [Image, ImageTexture, Opacity]
canvas.layers.append([cropped_image, tex, 1])
for _i in range(1, Global.layers.size()):
var empty_sprite := Image.new()
empty_sprite.create(canvas.size.x, canvas.size.y, false, Image.FORMAT_RGBA8)
empty_sprite.fill(Color(0, 0, 0, 0))
empty_sprite.lock()
var empty_tex := ImageTexture.new()
empty_tex.create_from_image(empty_sprite, 0)
# Store [Image, ImageTexture, Opacity]
canvas.layers.append([empty_sprite, empty_tex, 1])
canvas.frame = i
Global.canvases.append(canvas)
Global.canvas_parent.add_child(canvas)
@ -107,6 +132,7 @@ func _on_ImportSprites_files_selected(paths : PoolStringArray) -> void:
Global.canvases[Global.canvases.size() - 1].camera_zoom()
Global.canvases = Global.canvases # Just to call Global.canvases_changed
Global.current_frame = i - 1
Global.canvas = Global.canvases[Global.canvases.size() - 1]
Global.canvas.visible = true

View file

@ -9,7 +9,7 @@ func _on_OutlineDialog_confirmed() -> void:
var diagonal : bool = $OptionsContainer/DiagonalCheckBox.pressed
var inside_image : bool = $OptionsContainer/InsideImageCheckBox.pressed
var image : Image = Global.canvas.layers[Global.canvas.current_layer_index][0]
var image : Image = Global.canvas.layers[Global.current_layer][0]
if image.is_invisible():
return
var new_image := Image.new()

View file

@ -1,12 +1,17 @@
extends Button
var frame := 0
var layer := 0
onready var popup_menu := $PopupMenu
func _ready() -> void:
hint_tooltip = "Frame: %s, Layer: %s" % [frame, layer]
func _on_FrameButton_pressed() -> void:
if Input.is_action_just_released("left_mouse"):
Global.current_frame = frame
Global.current_layer = layer
elif Input.is_action_just_released("right_mouse"):
if Global.canvases.size() == 1:
popup_menu.set_item_disabled(0, true)
@ -30,7 +35,7 @@ func _on_PopupMenu_id_pressed(ID : int) -> void:
0: # Remove Frame
remove_frame()
1: #Clone Layer
1: # Clone Frame
var canvas : Canvas = Global.canvases[frame]
var new_canvas : Canvas = load("res://Prefabs/Canvas.tscn").instance()
new_canvas.size = Global.canvas.size
@ -47,7 +52,7 @@ func _on_PopupMenu_id_pressed(ID : int) -> void:
sprite.lock()
var tex := ImageTexture.new()
tex.create_from_image(sprite, 0)
new_canvas.layers.append([sprite, tex, layer[2], layer[3], layer[4]])
new_canvas.layers.append([sprite, tex, layer[2]])
Global.undos += 1
Global.undo_redo.create_action("Add Frame")
@ -58,10 +63,10 @@ func _on_PopupMenu_id_pressed(ID : int) -> void:
Global.undo_redo.add_do_property(Global, "hidden_canvases", Global.hidden_canvases)
Global.undo_redo.add_do_property(Global, "canvas", new_canvas)
Global.undo_redo.add_do_property(Global, "current_frame", new_canvases.size() - 1)
for child in Global.frame_container.get_children():
var frame_button = child.get_node("FrameButton")
Global.undo_redo.add_do_property(frame_button, "pressed", false)
Global.undo_redo.add_undo_property(frame_button, "pressed", frame_button.pressed)
for i in range(Global.layers.size()):
for child in Global.layers[i][2].get_children():
Global.undo_redo.add_do_property(child, "pressed", false)
Global.undo_redo.add_undo_property(child, "pressed", child.pressed)
for c in Global.canvases:
Global.undo_redo.add_do_property(c, "visible", false)
Global.undo_redo.add_undo_property(c, "visible", c.visible)
@ -121,6 +126,10 @@ func change_frame_order(rate : int) -> void:
Global.undo_redo.add_do_property(Global.canvases[frame], "frame", change)
Global.undo_redo.add_do_property(Global.canvases[change], "frame", frame)
if Global.current_frame == frame:
Global.undo_redo.add_do_property(Global, "current_frame", change)
Global.undo_redo.add_undo_property(Global, "current_frame", Global.current_frame)
Global.undo_redo.add_undo_property(Global, "canvases", Global.canvases)
Global.undo_redo.add_undo_property(Global.canvases[frame], "frame", frame)
Global.undo_redo.add_undo_property(Global.canvases[change], "frame", change)

View file

@ -13,12 +13,14 @@ var undos := 0 # The number of times we added undo properties
var saved := true # Checks if the user has saved
# Canvas related stuff
var canvases := [] setget canvases_changed
var layers := [] setget layers_changed
var current_frame := 0 setget frame_changed
var current_layer := 0 setget layer_changed
# warning-ignore:unused_class_variable
var can_draw := false
# warning-ignore:unused_class_variable
var has_focus := false
var canvases := []
# warning-ignore:unused_class_variable
var hidden_canvases := []
var pressure_sensitivity_mode = Pressure_Sensitivity.NONE
@ -223,14 +225,15 @@ var right_mirror_container : Container
var animation_timeline : Panel
var animation_timer : Timer
var frame_ids : HBoxContainer
var current_frame_label : Label
var loop_animation_button : BaseButton
var play_forward : BaseButton
var play_backwards : BaseButton
var timeline_seconds : Control
var frame_container : HBoxContainer
var layers_container : VBoxContainer
var frames_container : VBoxContainer
var vbox_layer_container : VBoxContainer
var remove_layer_button : BaseButton
var move_up_layer_button : BaseButton
var move_down_layer_button : BaseButton
@ -340,24 +343,24 @@ func _ready() -> void:
animation_timeline = find_node_by_name(root, "AnimationTimeline")
layers_container = find_node_by_name(animation_timeline, "LayersContainer")
frames_container = find_node_by_name(animation_timeline, "FramesContainer")
animation_timer = find_node_by_name(animation_timeline, "AnimationTimer")
frame_ids = find_node_by_name(animation_timeline, "FrameIDs")
current_frame_label = find_node_by_name(animation_timeline, "CurrentFrame")
loop_animation_button = find_node_by_name(animation_timeline, "LoopAnim")
play_forward = find_node_by_name(animation_timeline, "PlayForward")
play_backwards = find_node_by_name(animation_timeline, "PlayBackwards")
timeline_seconds = find_node_by_name(animation_timeline, "TimelineSeconds")
frame_container = find_node_by_name(animation_timeline, "FrameContainer")
var layer_stuff_container = find_node_by_name(root, "LayerVBoxContainer")
var layer_buttons = find_node_by_name(layer_stuff_container, "LayerButtons")
remove_layer_button = find_node_by_name(layer_buttons, "RemoveLayer")
move_up_layer_button = find_node_by_name(layer_buttons, "MoveUpLayer")
move_down_layer_button = find_node_by_name(layer_buttons, "MovwDownLayer")
merge_down_layer_button = find_node_by_name(layer_buttons, "MergeDownLayer")
#var layer_stuff_container = find_node_by_name(animation_timeline, "LayerVBoxContainer")
layer_opacity_slider = find_node_by_name(layer_stuff_container, "OpacitySlider")
layer_opacity_spinbox = find_node_by_name(layer_stuff_container, "OpacitySpinBox")
vbox_layer_container = find_node_by_name(layer_stuff_container, "VBoxLayerContainer")
remove_layer_button = find_node_by_name(animation_timeline, "RemoveLayer")
move_up_layer_button = find_node_by_name(animation_timeline, "MoveUpLayer")
move_down_layer_button = find_node_by_name(animation_timeline, "MovwDownLayer")
merge_down_layer_button = find_node_by_name(animation_timeline, "MergeDownLayer")
layer_opacity_slider = find_node_by_name(animation_timeline, "OpacitySlider")
layer_opacity_spinbox = find_node_by_name(animation_timeline, "OpacitySpinBox")
add_palette_button = find_node_by_name(root, "AddPalette")
edit_palette_button = find_node_by_name(root, "EditPalette")
@ -370,6 +373,9 @@ func _ready() -> void:
error_dialog = find_node_by_name(root, "ErrorDialog")
# Store [Layer name, Layer visibility boolean, Frame container]
layers.append([tr("Layer") + " 0", true, HBoxContainer.new()])
# 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:
if root.get_name() == node_name:
@ -403,16 +409,8 @@ func undo(_canvases : Array, layer_index : int = -1) -> void:
if action_name == "Scale":
c.camera_zoom()
if "Layer" in action_name:
var current_layer_index : int = _canvases[0].current_layer_index
_canvases[0].generate_layer_panels()
if action_name == "Change Layer Order":
_canvases[0].current_layer_index = current_layer_index
_canvases[0].get_layer_container(current_layer_index).changed_selection()
if action_name == "Add Frame":
canvas_parent.remove_child(_canvases[0])
frame_container.remove_child(_canvases[0].frame_button)
# This actually means that canvases.size is one, but it hasn't been updated yet
if canvases.size() == 2: # Stop animating
play_forward.pressed = false
@ -421,10 +419,7 @@ func undo(_canvases : Array, layer_index : int = -1) -> void:
elif action_name == "Remove Frame":
canvas_parent.add_child(_canvases[0])
canvas_parent.move_child(_canvases[0], _canvases[0].frame)
frame_container.add_child(_canvases[0].frame_button)
frame_container.move_child(_canvases[0].frame_button, _canvases[0].frame)
elif action_name == "Change Frame Order":
frame_container.move_child(_canvases[0].frame_button, _canvases[0].frame)
canvas_parent.move_child(_canvases[0], _canvases[0].frame)
canvas.update()
@ -448,26 +443,16 @@ func redo(_canvases : Array, layer_index : int = -1) -> void:
if action_name == "Scale":
c.camera_zoom()
if "Layer" in action_name:
var current_layer_index : int = _canvases[0].current_layer_index
_canvases[0].generate_layer_panels()
if action_name == "Change Layer Order":
_canvases[0].current_layer_index = current_layer_index
_canvases[0].get_layer_container(current_layer_index).changed_selection()
if action_name == "Add Frame":
canvas_parent.add_child(_canvases[0])
if !Global.frame_container.is_a_parent_of(_canvases[0].frame_button):
Global.frame_container.add_child(_canvases[0].frame_button)
elif action_name == "Remove Frame":
canvas_parent.remove_child(_canvases[0])
frame_container.remove_child(_canvases[0].frame_button)
if canvases.size() == 1: # Stop animating
play_forward.pressed = false
play_backwards.pressed = false
animation_timer.stop()
elif action_name == "Change Frame Order":
frame_container.move_child(_canvases[0].frame_button, _canvases[0].frame)
canvas_parent.move_child(_canvases[0], _canvases[0].frame)
canvas.update()
@ -481,28 +466,141 @@ func title_changed(value : String) -> void:
window_title = value
OS.set_window_title(value)
func canvases_changed(value : Array) -> void:
canvases = value
for container in frames_container.get_children():
for button in container.get_children():
container.remove_child(button)
button.queue_free()
frames_container.remove_child(container)
for frame_id in frame_ids.get_children():
frame_ids.remove_child(frame_id)
frame_id.queue_free()
for i in range(layers.size() - 1, -1, -1):
frames_container.add_child(layers[i][2])
for j in range(canvases.size()):
var label := Label.new()
label.rect_min_size.x = 36
label.align = Label.ALIGN_CENTER
label.text = str(j + 1)
frame_ids.add_child(label)
for i in range(layers.size() - 1, -1, -1):
var frame_button = load("res://Prefabs/FrameButton.tscn").instance()
frame_button.frame = j
frame_button.layer = i
frame_button.get_child(0).texture = Global.canvases[j].layers[i][1]
layers[i][2].add_child(frame_button)
func layers_changed(value : Array) -> void:
layers = value
for container in layers_container.get_children():
container.queue_free()
for container in frames_container.get_children():
for button in container.get_children():
container.remove_child(button)
button.queue_free()
frames_container.remove_child(container)
for i in range(layers.size() - 1, -1, -1):
var layer_container = load("res://Prefabs/LayerContainer.tscn").instance()
layer_container.i = i
if !layers[i][0]:
layers[i][0] = tr("Layer") + " %s" % i
layers_container.add_child(layer_container)
layer_container.label.text = layers[i][0]
layer_container.line_edit.text = layers[i][0]
frames_container.add_child(layers[i][2])
for j in range(canvases.size()):
var frame_button = load("res://Prefabs/FrameButton.tscn").instance()
frame_button.frame = j
frame_button.layer = i
frame_button.get_child(0).texture = Global.canvases[j].layers[i][1]
layers[i][2].add_child(frame_button)
var layer_button = layers_container.get_child(layers_container.get_child_count() - 1 - current_layer)
layer_button.pressed = true
self.current_frame = current_frame # Call frame_changed to update UI
if layers.size() == 1:
remove_layer_button.disabled = true
remove_layer_button.mouse_default_cursor_shape = Control.CURSOR_FORBIDDEN
move_up_layer_button.disabled = true
move_up_layer_button.mouse_default_cursor_shape = Control.CURSOR_FORBIDDEN
move_down_layer_button.disabled = true
move_down_layer_button.mouse_default_cursor_shape = Control.CURSOR_FORBIDDEN
merge_down_layer_button.disabled = true
merge_down_layer_button.mouse_default_cursor_shape = Control.CURSOR_FORBIDDEN
else:
remove_layer_button.disabled = false
remove_layer_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
func frame_changed(value : int) -> void:
current_frame = value
current_frame_label.text = tr("Current frame:") + " %s/%s" % [str(current_frame + 1), canvases.size()]
for c in canvases:
var i := 0
for c in canvases: # De-select all the other canvases/frames
c.visible = false
c.is_making_line = false
c.line_2d.set_point_position(1, c.line_2d.points[0])
canvas = canvases[current_frame]
canvas.visible = true
canvas.generate_layer_panels()
# Make all frame buttons unpressed
for c in canvases:
var text_color := Color.white
if theme_type == "Gold" || theme_type == "Light":
text_color = Color.black
c.frame_button.get_node("FrameButton").pressed = false
c.frame_button.get_node("FrameID").add_color_override("font_color", text_color)
# Make only the current frame button pressed
canvas.frame_button.get_node("FrameButton").pressed = true
canvas.frame_button.get_node("FrameID").add_color_override("font_color", Color("#3c5d75"))
frame_ids.get_child(i).add_color_override("font_color", text_color)
for layer in layers:
if i < layer[2].get_child_count():
layer[2].get_child(i).pressed = false
i += 1
# Select the new canvas/frame
canvas = canvases[current_frame]
canvas.visible = true
frame_ids.get_child(current_frame).add_color_override("font_color", Color("#3c5d75"))
if current_frame < layers[current_layer][2].get_child_count():
layers[current_layer][2].get_child(current_frame).pressed = true
func layer_changed(value : int) -> void:
current_layer = value
layer_opacity_slider.value = canvas.layers[current_layer][2] * 100
layer_opacity_spinbox.value = canvas.layers[current_layer][2] * 100
for container in layers_container.get_children():
container.pressed = false
if current_layer < layers_container.get_child_count():
var layer_button = layers_container.get_child(layers_container.get_child_count() - 1 - current_layer)
layer_button.pressed = true
if current_layer < layers.size() - 1:
move_up_layer_button.disabled = false
move_up_layer_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
else:
move_up_layer_button.disabled = true
move_up_layer_button.mouse_default_cursor_shape = Control.CURSOR_FORBIDDEN
if current_layer > 0:
move_down_layer_button.disabled = false
move_down_layer_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
merge_down_layer_button.disabled = false
merge_down_layer_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
else:
move_down_layer_button.disabled = true
move_down_layer_button.mouse_default_cursor_shape = Control.CURSOR_FORBIDDEN
merge_down_layer_button.disabled = true
merge_down_layer_button.mouse_default_cursor_shape = Control.CURSOR_FORBIDDEN
yield(get_tree().create_timer(0.01), "timeout")
self.current_frame = current_frame # Call frame_changed to update UI
func create_brush_button(brush_img : Image, brush_type := Brush_Types.CUSTOM, hint_tooltip := "") -> void:
var brush_container

View file

@ -1,17 +1,17 @@
class_name LayerContainer
extends Button
var i
# warning-ignore:unused_class_variable
var currently_selected := false
onready var visibility_button := $VisibilityButton
onready var label := $HBoxContainer/Label
onready var line_edit := $HBoxContainer/LineEdit
var i := 0
var visibility_button : BaseButton
var label : Label
var line_edit : LineEdit
func _ready() -> void:
changed_selection()
if Global.canvas.layers[i][3]:
visibility_button = Global.find_node_by_name(self, "VisibilityButton")
label = Global.find_node_by_name(self, "Label")
line_edit = Global.find_node_by_name(self, "LineEdit")
if Global.layers[i][1]:
visibility_button.texture_normal = load("res://Assets/Graphics/%s Themes/Layers/Layer_Visible.png" % Global.theme_type)
visibility_button.texture_hover = load("res://Assets/Graphics/%s Themes/Layers/Layer_Visible_Hover.png" % Global.theme_type)
else:
@ -23,13 +23,14 @@ func _input(event : InputEvent) -> void:
label.visible = true
line_edit.visible = false
line_edit.editable = false
var new_text : String = line_edit.text
label.text = new_text
Global.layers[i][0] = new_text
func _on_LayerContainer_pressed() -> void:
var initially_pressed := pressed
pressed = !pressed
var label_initially_visible : bool = label.visible
Global.canvas.current_layer_index = i
changed_selection()
if !initially_pressed:
if label_initially_visible:
label.visible = false
line_edit.visible = true
@ -40,51 +41,13 @@ func _on_LayerContainer_pressed() -> void:
line_edit.visible = false
line_edit.editable = false
func changed_selection() -> void:
var parent := get_parent()
for child in parent.get_children():
if child is Button:
child.label.visible = true
child.line_edit.visible = false
child.line_edit.editable = false
if Global.canvas.current_layer_index == child.i: # The selected layer
child.currently_selected = true
child.pressed = true
Global.layer_opacity_slider.value = Global.canvas.layers[child.i][4] * 100
Global.layer_opacity_spinbox.value = Global.canvas.layers[child.i][4] * 100
if Global.canvas.current_layer_index < Global.canvas.layers.size() - 1:
Global.move_up_layer_button.disabled = false
Global.move_up_layer_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
else:
Global.move_up_layer_button.disabled = true
Global.move_up_layer_button.mouse_default_cursor_shape = Control.CURSOR_FORBIDDEN
if Global.canvas.current_layer_index > 0:
Global.move_down_layer_button.disabled = false
Global.move_down_layer_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
Global.merge_down_layer_button.disabled = false
Global.merge_down_layer_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
else:
Global.move_down_layer_button.disabled = true
Global.move_down_layer_button.mouse_default_cursor_shape = Control.CURSOR_FORBIDDEN
Global.merge_down_layer_button.disabled = true
Global.merge_down_layer_button.mouse_default_cursor_shape = Control.CURSOR_FORBIDDEN
else:
child.currently_selected = false
child.pressed = false
func _on_VisibilityButton_pressed() -> void:
if Global.canvas.layers[i][3]:
Global.canvas.layers[i][3] = false
if Global.layers[i][1]:
Global.layers[i][1] = false
visibility_button.texture_normal = load("res://Assets/Graphics/%s Themes/Layers/Layer_Invisible.png" % Global.theme_type)
visibility_button.texture_hover = load("res://Assets/Graphics/%s Themes/Layers/Layer_Invisible_Hover.png" % Global.theme_type)
else:
Global.canvas.layers[i][3] = true
Global.layers[i][1] = true
visibility_button.texture_normal = load("res://Assets/Graphics/%s Themes/Layers/Layer_Visible.png" % Global.theme_type)
visibility_button.texture_hover = load("res://Assets/Graphics/%s Themes/Layers/Layer_Visible_Hover.png" % Global.theme_type)
Global.canvas.update()
func _on_LineEdit_text_changed(new_text : String) -> void:
Global.canvas.layers[i][2] = new_text
label.text = new_text

View file

@ -163,8 +163,9 @@ func _ready() -> void:
Global.window_title = "(" + tr("untitled") + ") - Pixelorama"
Global.canvas.layers[0][2] = tr("Layer") + " 0"
Global.canvas.generate_layer_panels()
Global.layers[0][0] = tr("Layer") + " 0"
Global.layers_container.get_child(0).label.text = Global.layers[0][0]
Global.layers_container.get_child(0).line_edit.text = Global.layers[0][0]
Import.import_brushes("Brushes")
@ -331,23 +332,23 @@ func image_menu_id_pressed(id : int) -> void:
2: # Flip Horizontal
var canvas : Canvas = Global.canvas
canvas.handle_undo("Draw")
canvas.layers[canvas.current_layer_index][0].unlock()
canvas.layers[canvas.current_layer_index][0].flip_x()
canvas.layers[canvas.current_layer_index][0].lock()
canvas.layers[Global.current_layer][0].unlock()
canvas.layers[Global.current_layer][0].flip_x()
canvas.layers[Global.current_layer][0].lock()
canvas.handle_redo("Draw")
3: # Flip Vertical
var canvas : Canvas = Global.canvas
canvas.handle_undo("Draw")
canvas.layers[canvas.current_layer_index][0].unlock()
canvas.layers[canvas.current_layer_index][0].flip_y()
canvas.layers[canvas.current_layer_index][0].lock()
canvas.layers[Global.current_layer][0].unlock()
canvas.layers[Global.current_layer][0].flip_y()
canvas.layers[Global.current_layer][0].lock()
canvas.handle_redo("Draw")
4: # Rotate
var image : Image = Global.canvas.layers[Global.canvas.current_layer_index][0]
var image : Image = Global.canvas.layers[Global.current_layer][0]
$RotateImage.set_sprite(image)
$RotateImage.popup_centered()
5: # Invert Colors
var image : Image = Global.canvas.layers[Global.canvas.current_layer_index][0]
var image : Image = Global.canvas.layers[Global.current_layer][0]
Global.canvas.handle_undo("Draw")
for xx in image.get_size().x:
for yy in image.get_size().y:
@ -357,7 +358,7 @@ func image_menu_id_pressed(id : int) -> void:
image.set_pixel(xx, yy, px_color)
Global.canvas.handle_redo("Draw")
6: # Desaturation
var image : Image = Global.canvas.layers[Global.canvas.current_layer_index][0]
var image : Image = Global.canvas.layers[Global.current_layer][0]
Global.canvas.handle_undo("Draw")
for xx in image.get_size().x:
for yy in image.get_size().y:
@ -398,7 +399,18 @@ func _on_OpenSprite_file_selected(path : String) -> void:
var version_number = float(version.substr(1, 3)) # Example, "0.6"
if current_version_number < 0.5:
OS.alert("File is from an older version of Pixelorama, as such it might not work properly")
var frame := 0
Global.layers.clear()
if (version_number - 0.01) > 0.6:
var global_layer_line := file.get_line()
while global_layer_line == ".":
var layer_name := file.get_line()
var layer_visibility := file.get_8()
# Store [Layer name, Layer visibility boolean, Frame container]
Global.layers.append([layer_name, layer_visibility, HBoxContainer.new()])
global_layer_line = file.get_line()
var frame_line := file.get_line()
clear_canvases()
while frame_line == "--": # Load frames
@ -410,7 +422,10 @@ func _on_OpenSprite_file_selected(path : String) -> void:
var layer_line := file.get_line()
while layer_line == "-": # Load layers
var buffer := file.get_buffer(width * height * 4)
var layer_name := file.get_line()
if version_number < (0.7 - 0.01):
var layer_name_old_version = file.get_line()
if frame == 0:
Global.layers.append([layer_name_old_version, true, HBoxContainer.new()])
var layer_transparency := 1.0
if version_number > 0.5:
layer_transparency = file.get_float()
@ -419,7 +434,7 @@ func _on_OpenSprite_file_selected(path : String) -> void:
image.lock()
var tex := ImageTexture.new()
tex.create_from_image(image, 0)
canvas.layers.append([image, tex, layer_name, true, layer_transparency])
canvas.layers.append([image, tex, layer_transparency])
layer_line = file.get_line()
var guide_line := file.get_line() # "guideline" no pun intended
@ -444,7 +459,9 @@ func _on_OpenSprite_file_selected(path : String) -> void:
frame_line = file.get_line()
frame += 1
Global.canvases = Global.canvases # Just to call Global.canvases_changed
Global.current_frame = frame - 1
Global.layers = Global.layers # Just to call Global.layers_changed
# Load tool options
Global.left_color_picker.color = file.get_var()
Global.right_color_picker.color = file.get_var()
@ -452,6 +469,7 @@ func _on_OpenSprite_file_selected(path : String) -> void:
Global.left_brush_size_edit.value = Global.left_brush_size
Global.right_brush_size = file.get_8()
Global.right_brush_size_edit.value = Global.right_brush_size
if version_number < (0.7 - 0.01):
var left_palette = file.get_var()
var right_palette = file.get_var()
for color in left_palette:
@ -496,15 +514,21 @@ func _on_SaveSprite_file_selected(path : String) -> void:
var err := file.open(path, File.WRITE)
if err == OK:
file.store_line(ProjectSettings.get_setting("application/config/Version"))
for layer in Global.layers: # Store Global layers
file.store_line(".")
file.store_line(layer[0]) # Layer name
file.store_8(layer[1]) # Layer visibility
file.store_line("END_GLOBAL_LAYERS")
for canvas in Global.canvases: # Store frames
file.store_line("--")
file.store_16(canvas.size.x)
file.store_16(canvas.size.y)
for layer in canvas.layers: # Store layers
for layer in canvas.layers: # Store canvas layers
file.store_line("-")
file.store_buffer(layer[0].get_data())
file.store_line(layer[2]) # Layer name
file.store_float(layer[4]) # Layer transparency
file.store_float(layer[2]) # Layer transparency
file.store_line("END_LAYERS")
for child in canvas.get_children(): # Store guides
@ -525,14 +549,10 @@ func _on_SaveSprite_file_selected(path : String) -> void:
var right_color : Color = Global.right_color_picker.color
var left_brush_size : int = Global.left_brush_size
var right_brush_size : int = Global.right_brush_size
var left_palette: PoolColorArray = Global.left_color_picker.get_picker().get_presets()
var right_palette: PoolColorArray = Global.right_color_picker.get_picker().get_presets()
file.store_var(left_color)
file.store_var(right_color)
file.store_8(left_brush_size)
file.store_8(right_brush_size)
file.store_var(left_palette)
file.store_var(right_palette)
# Save custom brushes
for i in range(Global.brushes_from_files, Global.custom_brushes.size()):
var brush = Global.custom_brushes[i]
@ -551,11 +571,6 @@ func _on_SaveSprite_file_selected(path : String) -> void:
_on_QuitDialog_confirmed()
func clear_canvases() -> void:
for child in Global.vbox_layer_container.get_children():
if child is PanelContainer:
child.queue_free()
for child in Global.frame_container.get_children():
child.queue_free()
for child in Global.canvas_parent.get_children():
if child is Canvas:
child.queue_free()
@ -687,86 +702,6 @@ func _on_RightBrushSizeEdit_value_changed(value) -> void:
Global.right_brush_size = new_size
update_right_custom_brush()
func add_layer(is_new := true) -> void:
var new_layer := Image.new()
var layer_name = null
if is_new:
new_layer.create(Global.canvas.size.x, Global.canvas.size.y, false, Image.FORMAT_RGBA8)
else: # clone layer
new_layer.copy_from(Global.canvas.layers[Global.canvas.current_layer_index][0])
layer_name = Global.canvas.layers[Global.canvas.current_layer_index][2] + " (" + tr("copy") + ")"
new_layer.lock()
var new_layer_tex := ImageTexture.new()
new_layer_tex.create_from_image(new_layer, 0)
var new_layers: Array = Global.canvas.layers.duplicate()
# Store [Image, ImageTexture, Layer Name, Visibity boolean, Opacity]
new_layers.append([new_layer, new_layer_tex, layer_name, true, 1])
Global.undos += 1
Global.undo_redo.create_action("Add Layer")
Global.undo_redo.add_do_property(Global.canvas, "layers", new_layers)
Global.undo_redo.add_undo_property(Global.canvas, "layers", Global.canvas.layers)
Global.undo_redo.add_undo_method(Global, "undo", [Global.canvas])
Global.undo_redo.add_do_method(Global, "redo", [Global.canvas])
Global.undo_redo.commit_action()
func _on_RemoveLayerButton_pressed() -> void:
var new_layers: Array = Global.canvas.layers.duplicate()
new_layers.remove(Global.canvas.current_layer_index)
Global.undos += 1
Global.undo_redo.create_action("Remove Layer")
Global.undo_redo.add_do_property(Global.canvas, "layers", new_layers)
Global.undo_redo.add_undo_property(Global.canvas, "layers", Global.canvas.layers)
Global.undo_redo.add_undo_method(Global, "undo", [Global.canvas])
Global.undo_redo.add_do_method(Global, "redo", [Global.canvas])
Global.undo_redo.commit_action()
func change_layer_order(rate : int) -> void:
var change = Global.canvas.current_layer_index + rate
var new_layers: Array = Global.canvas.layers.duplicate()
var temp = new_layers[Global.canvas.current_layer_index]
new_layers[Global.canvas.current_layer_index] = new_layers[change]
new_layers[change] = temp
Global.undo_redo.create_action("Change Layer Order")
Global.undo_redo.add_do_property(Global.canvas, "layers", new_layers)
Global.undo_redo.add_do_property(Global.canvas, "current_layer_index", change)
Global.undo_redo.add_undo_property(Global.canvas, "layers", Global.canvas.layers)
Global.undo_redo.add_undo_property(Global.canvas, "current_layer_index", Global.canvas.current_layer_index)
Global.undo_redo.add_undo_method(Global, "undo", [Global.canvas])
Global.undo_redo.add_do_method(Global, "redo", [Global.canvas])
Global.undo_redo.commit_action()
func _on_MergeLayer_pressed() -> void:
var new_layers: Array = Global.canvas.layers.duplicate()
new_layers.remove(Global.canvas.current_layer_index)
var selected_layer = Global.canvas.layers[Global.canvas.current_layer_index][0]
if Global.canvas.layers[Global.canvas.current_layer_index][4] < 1: # If we have layer transparency
for xx in selected_layer.get_size().x:
for yy in selected_layer.get_size().y:
var pixel_color : Color = selected_layer.get_pixel(xx, yy)
var alpha : float = pixel_color.a * Global.canvas.layers[Global.canvas.current_layer_index][4]
selected_layer.set_pixel(xx, yy, Color(pixel_color.r, pixel_color.g, pixel_color.b, alpha))
var new_layer := Image.new()
new_layer.copy_from(Global.canvas.layers[Global.canvas.current_layer_index - 1][0])
new_layer.lock()
Global.canvas.blend_rect(new_layer, selected_layer, Rect2(Global.canvas.position, Global.canvas.size), Vector2.ZERO)
Global.undos += 1
Global.undo_redo.create_action("Merge Layer")
Global.undo_redo.add_do_property(Global.canvas, "layers", new_layers)
Global.undo_redo.add_do_property(Global.canvas.layers[Global.canvas.current_layer_index - 1][0], "data", new_layer.data)
Global.undo_redo.add_undo_property(Global.canvas, "layers", Global.canvas.layers)
Global.undo_redo.add_undo_property(Global.canvas.layers[Global.canvas.current_layer_index - 1][0], "data", Global.canvas.layers[Global.canvas.current_layer_index - 1][0].data)
Global.undo_redo.add_undo_method(Global, "undo", [Global.canvas])
Global.undo_redo.add_do_method(Global, "redo", [Global.canvas])
Global.undo_redo.commit_action()
func _on_ColorSwitch_pressed() -> void:
var temp: Color = Global.left_color_picker.color
@ -853,7 +788,7 @@ func _on_RightVerticalMirroring_toggled(button_pressed) -> void:
Global.right_vertical_mirror = button_pressed
func _on_OpacitySlider_value_changed(value) -> void:
Global.canvas.layers[Global.canvas.current_layer_index][4] = value / 100
Global.canvas.layers[Global.current_layer][4] = value / 100
Global.layer_opacity_slider.value = value
Global.layer_opacity_spinbox.value = value
Global.canvas.update()

View file

@ -23,7 +23,7 @@ func _process(delta : float) -> void:
var mouse_pos_floored := mouse_pos.floor()
var start_pos := polygon[0]
var end_pos := polygon[2]
var current_layer_index: int = Global.canvas.current_layer_index
var current_layer_index : int = Global.current_layer
var layer : Image = Global.canvas.layers[current_layer_index][0]
if end_pos == start_pos:
@ -59,7 +59,7 @@ func _process(delta : float) -> void:
layer.set_pixelv(curr_px, Color(0, 0, 0, 0))
else: # If part of selection is outside canvas
orig_colors.append(Color(0, 0, 0, 0))
Global.canvas.update_texture(Global.canvas.current_layer_index)
Global.canvas.update_texture(current_layer_index)
tex.create_from_image(img, 0)
update()
@ -90,7 +90,7 @@ func _process(delta : float) -> void:
var px = polygon[0] + Global.selected_pixels[i] - Global.selected_pixels[0]
if point_in_rectangle(px, Global.canvas.location - Vector2.ONE, Global.canvas.size):
layer.set_pixelv(px, orig_colors[i])
Global.canvas.update_texture(Global.canvas.current_layer_index)
Global.canvas.update_texture(current_layer_index)
img.fill(Color(0, 0, 0, 0))
tex.create_from_image(img, 0)
update()
@ -136,8 +136,6 @@ func _process(delta : float) -> void:
layer.set_pixel(xx, yy, Color(0, 0, 0, 0))
Global.canvas.handle_redo("Draw")
func _draw() -> void:
if img.get_size() == polygon[2] - polygon[0]:
draw_texture(tex, polygon[0], Color(1, 1, 1, 0.5))

View file

@ -53,7 +53,7 @@ boot_splash/bg_color=Color( 0.145098, 0.145098, 0.164706, 1 )
config/icon="res://icon.png"
config/macos_native_icon="res://icon.icns"
config/windows_native_icon="res://icon.ico"
config/Version="v0.6.2"
config/Version="v0.7"
[autoload]