mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-01-19 01:29:49 +00:00
[EXPERIMENTAL] Re-making the timeline
Trying to merge layers into the timeline, and eventually add more features like "share layer with all frames", among others. THIS IS NOT FINISHED, IT WILL *NOT* WORK PROPERLY. Once it is finished, this branch will be merged onto master. So far only add layer and add frame work, and even they may have some issues. Undoing also does not work properly yet. The UI is also not finished, as it currently has problems with the scroll containers.
This commit is contained in:
parent
7c408731b8
commit
953d002d91
|
@ -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,17 @@ 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 )
|
||||
|
||||
[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 +100,218 @@ 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="FrameLayerButtonContainer" type="HBoxContainer" parent="AnimationContainer/TimelineContainer"]
|
||||
margin_right = 543.0
|
||||
margin_bottom = 36.0
|
||||
|
||||
[node name="LayerButtons" type="HBoxContainer" parent="AnimationContainer/TimelineContainer/FrameLayerButtonContainer"]
|
||||
margin_right = 326.0
|
||||
margin_bottom = 36.0
|
||||
|
||||
[node name="AddLayer" type="TextureButton" parent="AnimationContainer/TimelineContainer/FrameLayerButtonContainer/LayerButtons" groups=[
|
||||
"UIButtons",
|
||||
]]
|
||||
margin_right = 32.0
|
||||
margin_bottom = 36.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/FrameLayerButtonContainer/LayerButtons" groups=[
|
||||
"UIButtons",
|
||||
]]
|
||||
margin_left = 36.0
|
||||
margin_right = 68.0
|
||||
margin_bottom = 36.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/FrameLayerButtonContainer/LayerButtons" groups=[
|
||||
"UIButtons",
|
||||
]]
|
||||
margin_left = 72.0
|
||||
margin_right = 104.0
|
||||
margin_bottom = 36.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/FrameLayerButtonContainer/LayerButtons" groups=[
|
||||
"UIButtons",
|
||||
]]
|
||||
margin_left = 108.0
|
||||
margin_right = 140.0
|
||||
margin_bottom = 36.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/FrameLayerButtonContainer/LayerButtons" groups=[
|
||||
"UIButtons",
|
||||
]]
|
||||
margin_left = 144.0
|
||||
margin_right = 176.0
|
||||
margin_bottom = 36.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/FrameLayerButtonContainer/LayerButtons" groups=[
|
||||
"UIButtons",
|
||||
]]
|
||||
margin_left = 180.0
|
||||
margin_right = 212.0
|
||||
margin_bottom = 36.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="TagsAndFrameIDs" type="VBoxContainer" parent="AnimationContainer/TimelineContainer/FrameLayerButtonContainer/LayerButtons"]
|
||||
margin_left = 216.0
|
||||
margin_right = 326.0
|
||||
margin_bottom = 36.0
|
||||
|
||||
[node name="AnimationTags" type="VBoxContainer" parent="AnimationContainer/TimelineContainer/FrameLayerButtonContainer/LayerButtons/TagsAndFrameIDs"]
|
||||
editor/display_folded = true
|
||||
margin_right = 110.0
|
||||
margin_bottom = 36.0
|
||||
size_flags_vertical = 0
|
||||
|
||||
[node name="Line2D" type="Line2D" parent="AnimationContainer/TimelineContainer/FrameLayerButtonContainer/LayerButtons/TagsAndFrameIDs/AnimationTags"]
|
||||
points = PoolVector2Array( 0, 32, 0, 0, 110, 0, 110, 32 )
|
||||
width = 1.0
|
||||
|
||||
[node name="Label" type="Label" parent="AnimationContainer/TimelineContainer/FrameLayerButtonContainer/LayerButtons/TagsAndFrameIDs/AnimationTags"]
|
||||
margin_right = 110.0
|
||||
margin_bottom = 32.0
|
||||
rect_min_size = Vector2( 110, 32 )
|
||||
size_flags_vertical = 1
|
||||
text = "Animation Tags"
|
||||
align = 1
|
||||
valign = 1
|
||||
|
||||
[node name="FramesContainer" type="HBoxContainer" parent="AnimationContainer/TimelineContainer/FrameLayerButtonContainer/LayerButtons/TagsAndFrameIDs/AnimationTags"]
|
||||
margin_top = 36.0
|
||||
margin_right = 110.0
|
||||
margin_bottom = 36.0
|
||||
|
||||
[node name="OpacityContainer" type="HBoxContainer" parent="AnimationContainer/TimelineContainer"]
|
||||
margin_top = 40.0
|
||||
margin_right = 543.0
|
||||
margin_bottom = 64.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="FrameIDs" type="HBoxContainer" parent="AnimationContainer/TimelineContainer/OpacityContainer"]
|
||||
margin_left = 245.0
|
||||
margin_right = 281.0
|
||||
margin_bottom = 24.0
|
||||
|
||||
[node name="Label" type="Label" parent="AnimationContainer/TimelineContainer/OpacityContainer/FrameIDs"]
|
||||
margin_top = 5.0
|
||||
margin_right = 36.0
|
||||
margin_bottom = 19.0
|
||||
rect_min_size = Vector2( 36, 0 )
|
||||
text = "1"
|
||||
align = 1
|
||||
|
||||
[node name="TimelineScroll" type="ScrollContainer" parent="AnimationContainer/TimelineContainer"]
|
||||
margin_top = 68.0
|
||||
margin_right = 543.0
|
||||
margin_bottom = 160.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="LayersAndFrames" type="GridContainer" parent="AnimationContainer/TimelineContainer/TimelineScroll"]
|
||||
margin_right = 212.0
|
||||
margin_bottom = 36.0
|
||||
custom_constants/vseparation = 4
|
||||
custom_constants/hseparation = 4
|
||||
columns = 2
|
||||
|
||||
[node name="LayerContainer" parent="AnimationContainer/TimelineContainer/TimelineScroll/LayersAndFrames" instance=ExtResource( 18 )]
|
||||
margin_right = 212.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
|
||||
editor/display_folded = true
|
||||
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 +322,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 +335,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 +349,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 +365,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 +379,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 +392,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 +420,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 +473,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/FrameLayerButtonContainer/LayerButtons/AddLayer" to="." method="add_layer" binds= [ true ]]
|
||||
[connection signal="pressed" from="AnimationContainer/TimelineContainer/FrameLayerButtonContainer/LayerButtons/RemoveLayer" to="." method="_on_RemoveLayer_pressed"]
|
||||
[connection signal="pressed" from="AnimationContainer/TimelineContainer/FrameLayerButtonContainer/LayerButtons/MoveUpLayer" to="." method="change_layer_order" binds= [ 1 ]]
|
||||
[connection signal="pressed" from="AnimationContainer/TimelineContainer/FrameLayerButtonContainer/LayerButtons/MovwDownLayer" to="." method="change_layer_order" binds= [ -1 ]]
|
||||
[connection signal="pressed" from="AnimationContainer/TimelineContainer/FrameLayerButtonContainer/LayerButtons/CloneLayer" to="." method="add_layer" binds= [ false ]]
|
||||
[connection signal="pressed" from="AnimationContainer/TimelineContainer/FrameLayerButtonContainer/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 +493,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"]
|
||||
|
|
|
@ -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
|
||||
|
@ -17,7 +14,7 @@ toggle_mode = true
|
|||
button_mask = 7
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[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 +25,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"]
|
||||
|
|
18
Prefabs/FrameContainer.tscn
Normal file
18
Prefabs/FrameContainer.tscn
Normal file
|
@ -0,0 +1,18 @@
|
|||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://Prefabs/FrameButton.tscn" type="PackedScene" id=1]
|
||||
|
||||
[node name="FrameContainer" type="VBoxContainer"]
|
||||
margin_right = 32.0
|
||||
margin_bottom = 50.0
|
||||
|
||||
[node name="FrameID" type="Label" parent="."]
|
||||
margin_right = 36.0
|
||||
margin_bottom = 17.0
|
||||
rect_min_size = Vector2( 0, 17 )
|
||||
text = "0"
|
||||
align = 1
|
||||
|
||||
[node name="FrameButton" parent="." instance=ExtResource( 1 )]
|
||||
margin_top = 21.0
|
||||
margin_bottom = 57.0
|
|
@ -5,22 +5,30 @@
|
|||
[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 )
|
||||
toggle_mode = true
|
||||
script = ExtResource( 1 )
|
||||
__meta__ = {
|
||||
"_edit_horizontal_guides_": [ ]
|
||||
}
|
||||
|
||||
[node name="VisibilityButton" type="TextureButton" parent="." groups=[
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="."]
|
||||
anchor_top = 0.5
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 0.5
|
||||
margin_top = -16.0
|
||||
margin_bottom = 16.0
|
||||
mouse_default_cursor_shape = 2
|
||||
alignment = 1
|
||||
|
||||
[node name="VisibilityButton" type="TextureButton" parent="HBoxContainer" groups=[
|
||||
"UIButtons",
|
||||
]]
|
||||
margin_left = 6.0
|
||||
margin_top = 5.0
|
||||
margin_right = 38.0
|
||||
margin_bottom = 37.0
|
||||
margin_left = 65.0
|
||||
margin_right = 97.0
|
||||
margin_bottom = 32.0
|
||||
hint_tooltip = "LAYERVISIBILITY_HT"
|
||||
mouse_default_cursor_shape = 2
|
||||
size_flags_horizontal = 0
|
||||
|
@ -28,29 +36,10 @@ 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"]
|
||||
margin_left = 36.0
|
||||
margin_left = 101.0
|
||||
margin_top = 9.0
|
||||
margin_right = 82.0
|
||||
margin_right = 147.0
|
||||
margin_bottom = 23.0
|
||||
text = "Layer 0"
|
||||
align = 1
|
||||
|
@ -68,5 +57,5 @@ 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="pressed" from="HBoxContainer/VisibilityButton" to="." method="_on_VisibilityButton_pressed"]
|
||||
[connection signal="text_changed" from="HBoxContainer/LineEdit" to="." method="_on_LineEdit_text_changed"]
|
||||
|
|
|
@ -23,10 +23,10 @@ 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 i in range(Global.layers.size()):
|
||||
for child in Global.layers[i][1].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)
|
||||
|
@ -39,18 +39,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"
|
||||
|
@ -101,13 +98,13 @@ func _on_AnimationTimer_timeout() -> void:
|
|||
Global.current_frame += 1
|
||||
else:
|
||||
match animation_loop:
|
||||
0: #No loop
|
||||
0: # No loop
|
||||
Global.play_forward.pressed = false
|
||||
Global.play_backwards.pressed = false
|
||||
Global.animation_timer.stop()
|
||||
1: #Cycle loop
|
||||
1: # Cycle loop
|
||||
Global.current_frame = 0
|
||||
2: #Ping pong loop
|
||||
2: # Ping pong loop
|
||||
animation_forward = false
|
||||
_on_AnimationTimer_timeout()
|
||||
|
||||
|
@ -116,13 +113,13 @@ func _on_AnimationTimer_timeout() -> void:
|
|||
Global.current_frame -= 1
|
||||
else:
|
||||
match animation_loop:
|
||||
0: #No loop
|
||||
0: # No loop
|
||||
Global.play_backwards.pressed = false
|
||||
Global.play_forward.pressed = false
|
||||
Global.animation_timer.stop()
|
||||
1: #Cycle loop
|
||||
1: # Cycle loop
|
||||
Global.current_frame = Global.canvases.size() - 1
|
||||
2: #Ping pong loop
|
||||
2: # Ping pong loop
|
||||
animation_forward = true
|
||||
_on_AnimationTimer_timeout()
|
||||
|
||||
|
@ -142,3 +139,104 @@ 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 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.current_layer][0])
|
||||
layer_name = Global.canvas.layers[Global.current_layer][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.layers.duplicate()
|
||||
|
||||
# Store [layer name, frame container]
|
||||
new_layers.append([layer_name, HBoxContainer.new()])
|
||||
|
||||
Global.undos += 1
|
||||
Global.undo_redo.create_action("Add Layer")
|
||||
Global.undo_redo.add_do_property(Global, "current_layer", Global.current_layer + 1)
|
||||
Global.undo_redo.add_do_property(Global, "layers", new_layers)
|
||||
|
||||
for c in Global.canvases:
|
||||
var new_canvas_layers : Array = c.layers.duplicate()
|
||||
# Store [Image, ImageTexture, Visibity boolean, Opacity]
|
||||
new_canvas_layers.append([new_layer, new_layer_tex, true, 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_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.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_MergeDownLayer_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_OpacitySlider_value_changed(value) -> void:
|
||||
Global.canvas.layers[Global.current_layer][3] = value / 100
|
||||
Global.layer_opacity_slider.value = value
|
||||
Global.layer_opacity_spinbox.value = value
|
||||
Global.canvas.update()
|
||||
|
|
|
@ -7,8 +7,6 @@ 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 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,40 +29,38 @@ var pen_pressure := 1.0 # For tablet pressure sensitivity
|
|||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
# 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"):
|
||||
size.x = Global.config_cache.get_value("preferences", "default_width")
|
||||
if Global.config_cache.has_section_key("preferences", "default_height"):
|
||||
size.y = Global.config_cache.get_value("preferences", "default_height")
|
||||
if Global.config_cache.has_section_key("preferences", "default_fill_color"):
|
||||
fill_color = Global.config_cache.get_value("preferences", "default_fill_color")
|
||||
Global.is_default_image = !Global.is_default_image
|
||||
var fill_layers := layers.empty()
|
||||
for i in range(Global.layers.size()):
|
||||
print(i)
|
||||
if fill_layers:
|
||||
# The sprite itself
|
||||
var sprite := Image.new()
|
||||
if Global.is_default_image:
|
||||
if Global.config_cache.has_section_key("preferences", "default_width"):
|
||||
size.x = Global.config_cache.get_value("preferences", "default_width")
|
||||
if Global.config_cache.has_section_key("preferences", "default_height"):
|
||||
size.y = Global.config_cache.get_value("preferences", "default_height")
|
||||
if Global.config_cache.has_section_key("preferences", "default_fill_color"):
|
||||
fill_color = Global.config_cache.get_value("preferences", "default_fill_color")
|
||||
Global.is_default_image = !Global.is_default_image
|
||||
|
||||
sprite.create(size.x, size.y, false, Image.FORMAT_RGBA8)
|
||||
sprite.fill(fill_color)
|
||||
sprite.lock()
|
||||
sprite.create(size.x, size.y, false, Image.FORMAT_RGBA8)
|
||||
sprite.fill(fill_color)
|
||||
sprite.lock()
|
||||
|
||||
var tex := ImageTexture.new()
|
||||
tex.create_from_image(sprite, 0)
|
||||
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])
|
||||
# Store [Image, ImageTexture, Layer Name, Opacity]
|
||||
layers.append([sprite, tex, 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
|
||||
var frame_button = load("res://Prefabs/FrameButton.tscn").instance()
|
||||
frame_button.frame = frame
|
||||
frame_button.layer = i
|
||||
frame_button.pressed = true
|
||||
#frame_button.get_node("FrameID").text = str(frame + 1)
|
||||
#frame_button.get_node("FrameID").add_color_override("font_color", Color("#3c5d75"))
|
||||
Global.layers[i][2].add_child(frame_button)
|
||||
|
||||
# Only handle camera zoom settings & offset on the first frame
|
||||
if Global.canvases[0] == self:
|
||||
|
@ -79,8 +75,8 @@ func _ready() -> void:
|
|||
|
||||
func _draw() -> void:
|
||||
draw_texture_rect(Global.transparent_background, Rect2(location, size), true) #Draw transparent background
|
||||
#Onion Skinning
|
||||
#Past
|
||||
# Onion Skinning
|
||||
# Past
|
||||
if Global.onion_skinning_past_rate > 0:
|
||||
var color : Color
|
||||
if Global.onion_skinning_blue_red:
|
||||
|
@ -89,11 +85,11 @@ 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:
|
||||
for layer in Global.canvases[Global.current_frame - i].layers:
|
||||
color.a = 0.6/i
|
||||
draw_texture(texture[1], location, color)
|
||||
draw_texture(layer[1], location, color)
|
||||
|
||||
#Future
|
||||
# Future
|
||||
if Global.onion_skinning_future_rate > 0:
|
||||
var color : Color
|
||||
if Global.onion_skinning_blue_red:
|
||||
|
@ -102,44 +98,44 @@ 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:
|
||||
for layer in Global.canvases[Global.current_frame + i].layers:
|
||||
color.a = 0.6/i
|
||||
draw_texture(texture[1], location, color)
|
||||
draw_texture(layer[1], location, color)
|
||||
|
||||
#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)
|
||||
# Draw current frame layers
|
||||
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)
|
||||
# Idea taken from flurick (on GitHub)
|
||||
if Global.draw_grid:
|
||||
for x in range(0, size.x, Global.grid_width):
|
||||
draw_line(Vector2(x, location.y), Vector2(x, size.y), Global.grid_color, true)
|
||||
for y in range(0, size.y, Global.grid_height):
|
||||
draw_line(Vector2(location.x, y), Vector2(size.x, y), Global.grid_color, true)
|
||||
|
||||
#Draw rectangle to indicate the pixel currently being hovered on
|
||||
# Draw rectangle to indicate the pixel currently being hovered on
|
||||
var mouse_pos := current_pixel
|
||||
if point_in_rectangle(mouse_pos, location, location + size):
|
||||
mouse_pos = mouse_pos.floor()
|
||||
if Global.left_square_indicator_visible && Global.can_draw:
|
||||
if Global.current_left_brush_type == Global.Brush_Types.PIXEL || Global.current_left_tool == "LightenDarken":
|
||||
if Global.current_left_brush_type == Global.BRUSH_TYPES.PIXEL || Global.current_left_tool == "LightenDarken":
|
||||
if Global.current_left_tool == "Pencil" || Global.current_left_tool == "Eraser" || Global.current_left_tool == "LightenDarken":
|
||||
var start_pos_x = mouse_pos.x - (Global.left_brush_size >> 1)
|
||||
var start_pos_y = mouse_pos.y - (Global.left_brush_size >> 1)
|
||||
draw_rect(Rect2(start_pos_x, start_pos_y, Global.left_brush_size, Global.left_brush_size), Color.blue, false)
|
||||
elif Global.current_left_brush_type == Global.Brush_Types.CIRCLE || Global.current_left_brush_type == Global.Brush_Types.FILLED_CIRCLE:
|
||||
elif Global.current_left_brush_type == Global.BRUSH_TYPES.CIRCLE || Global.current_left_brush_type == Global.BRUSH_TYPES.FILLED_CIRCLE:
|
||||
if Global.current_left_tool == "Pencil" || Global.current_left_tool == "Eraser":
|
||||
draw_set_transform(mouse_pos, rotation, scale)
|
||||
for rect in Global.left_circle_points:
|
||||
|
@ -152,12 +148,12 @@ func _draw() -> void:
|
|||
draw_texture(Global.custom_left_brush_texture, dst)
|
||||
|
||||
if Global.right_square_indicator_visible && Global.can_draw:
|
||||
if Global.current_right_brush_type == Global.Brush_Types.PIXEL || Global.current_right_tool == "LightenDarken":
|
||||
if Global.current_right_brush_type == Global.BRUSH_TYPES.PIXEL || Global.current_right_tool == "LightenDarken":
|
||||
if Global.current_right_tool == "Pencil" || Global.current_right_tool == "Eraser" || Global.current_right_tool == "LightenDarken":
|
||||
var start_pos_x = mouse_pos.x - (Global.right_brush_size >> 1)
|
||||
var start_pos_y = mouse_pos.y - (Global.right_brush_size >> 1)
|
||||
draw_rect(Rect2(start_pos_x, start_pos_y, Global.right_brush_size, Global.right_brush_size), Color.red, false)
|
||||
elif Global.current_right_brush_type == Global.Brush_Types.CIRCLE || Global.current_right_brush_type == Global.Brush_Types.FILLED_CIRCLE:
|
||||
elif Global.current_right_brush_type == Global.BRUSH_TYPES.CIRCLE || Global.current_right_brush_type == Global.BRUSH_TYPES.FILLED_CIRCLE:
|
||||
if Global.current_right_tool == "Pencil" || Global.current_right_tool == "Eraser":
|
||||
draw_set_transform(mouse_pos, rotation, scale)
|
||||
for rect in Global.right_circle_points:
|
||||
|
@ -204,6 +200,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()
|
||||
|
@ -292,9 +289,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 +306,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 +360,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 +419,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, (Input.is_action_just_released("left_mouse") || Input.is_action_just_released("right_mouse")))
|
||||
|
||||
func camera_zoom() -> void:
|
||||
# Set camera zoom based on the sprite size
|
||||
|
@ -454,7 +451,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
|
||||
|
@ -496,27 +493,29 @@ func handle_redo(action : String) -> void:
|
|||
|
||||
func update_texture(layer_index : int, update_frame_tex := true) -> 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 layer_container := get_layer_container(layer_index)
|
||||
# if layer_container:
|
||||
# layer_container.get_child(1).get_child(0).texture = layers[layer_index][1]
|
||||
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]
|
||||
# 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
|
||||
|
||||
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)
|
||||
# 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():
|
||||
|
@ -525,7 +524,8 @@ func get_layer_container(layer_index : int) -> LayerContainer:
|
|||
return null
|
||||
|
||||
func generate_layer_panels() -> void:
|
||||
for child in Global.vbox_layer_container.get_children():
|
||||
return
|
||||
for child in Global.layers_container.get_children():
|
||||
if child is LayerContainer:
|
||||
child.queue_free()
|
||||
|
||||
|
@ -539,32 +539,31 @@ func generate_layer_panels() -> void:
|
|||
|
||||
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
|
||||
# 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)
|
||||
layer_container.get_child(0).get_child(1).text = layers[i][2]
|
||||
layer_container.get_child(0).get_child(2).text = layers[i][2]
|
||||
Global.layer_and_frame_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 +634,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 = layers[Global.current_layer][0].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 +654,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)
|
||||
layers[Global.current_layer][0].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 = layers[Global.current_layer][0].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,10 +671,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)
|
||||
layers[Global.current_layer][0].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)
|
||||
|
||||
if vertical_mirror:
|
||||
current_pixel_color = layers[Global.current_layer][0].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[Global.current_layer][0].set_pixel(cur_pos_x, mirror_y, _c)
|
||||
sprite_changed_this_frame = true
|
||||
|
||||
if horizontal_mirror && vertical_mirror:
|
||||
current_pixel_color = layers[Global.current_layer][0].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
|
||||
|
@ -685,34 +698,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(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)
|
||||
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(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)
|
||||
elif brush_type == Global.BRUSH_TYPES.CIRCLE || 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 +755,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 +770,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 +789,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 +803,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 +813,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 +832,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
|
||||
|
||||
|
|
|
@ -254,8 +254,8 @@ func change_theme(ID : int) -> void:
|
|||
var disabled_file_name = button.texture_disabled.resource_path.get_file()
|
||||
button.texture_disabled = load("res://Assets/Graphics/%s Themes/%s/%s" % [Global.theme_type, button_category, disabled_file_name])
|
||||
|
||||
# Make sure the frame text gets updated
|
||||
Global.current_frame = Global.current_frame
|
||||
# Make sure the frame text gets updated
|
||||
Global.current_frame = Global.current_frame
|
||||
|
||||
func _on_GridWidthValue_value_changed(value : float) -> void:
|
||||
Global.grid_width = value
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
extends Button
|
||||
|
||||
var frame := 0
|
||||
var layer := 0
|
||||
|
||||
onready var popup_menu := $PopupMenu
|
||||
|
||||
func _on_FrameButton_pressed() -> void:
|
||||
if Input.is_action_just_released("left_mouse"):
|
||||
Global.current_frame = frame
|
||||
Global.current_layer = layer
|
||||
print(str(frame), str(layer))
|
||||
elif Input.is_action_just_released("right_mouse"):
|
||||
if Global.canvases.size() == 1:
|
||||
popup_menu.set_item_disabled(0, true)
|
||||
|
@ -30,7 +33,7 @@ func _on_PopupMenu_id_pressed(ID : int) -> void:
|
|||
0: #Remove Frame
|
||||
remove_frame()
|
||||
|
||||
1: #Clone Layer
|
||||
1: # Clone Layer
|
||||
var canvas : Canvas = Global.canvases[frame]
|
||||
var new_canvas : Canvas = load("res://Prefabs/Canvas.tscn").instance()
|
||||
new_canvas.size = Global.canvas.size
|
||||
|
@ -58,7 +61,7 @@ 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():
|
||||
for child in Global.frame_containers.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)
|
||||
|
|
|
@ -13,7 +13,9 @@ var undos := 0 # The number of times we added undo properties
|
|||
var saved := true # Checks if the user has saved
|
||||
|
||||
# Canvas related stuff
|
||||
var layers := []
|
||||
var current_frame := 0 setget frame_changed
|
||||
var current_layer := 0
|
||||
# warning-ignore:unused_class_variable
|
||||
var can_draw := false
|
||||
# warning-ignore:unused_class_variable
|
||||
|
@ -223,14 +225,14 @@ 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 layer_and_frame_container : GridContainer
|
||||
|
||||
var vbox_layer_container : VBoxContainer
|
||||
var remove_layer_button : BaseButton
|
||||
var move_up_layer_button : BaseButton
|
||||
var move_down_layer_button : BaseButton
|
||||
|
@ -340,24 +342,23 @@ func _ready() -> void:
|
|||
|
||||
animation_timeline = find_node_by_name(root, "AnimationTimeline")
|
||||
|
||||
layer_and_frame_container = find_node_by_name(animation_timeline, "LayersAndFrames")
|
||||
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 +371,10 @@ func _ready() -> void:
|
|||
|
||||
error_dialog = find_node_by_name(root, "ErrorDialog")
|
||||
|
||||
# Store [layer name, frame container]
|
||||
layers.append([tr("Layer") + " 0", HBoxContainer.new()])
|
||||
layer_and_frame_container.add_child(layers[0][1])
|
||||
|
||||
# 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:
|
||||
|
@ -412,7 +417,7 @@ func undo(_canvases : Array, layer_index : int = -1) -> void:
|
|||
|
||||
if action_name == "Add Frame":
|
||||
canvas_parent.remove_child(_canvases[0])
|
||||
frame_container.remove_child(_canvases[0].frame_button)
|
||||
layer_and_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 +426,10 @@ 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)
|
||||
layer_and_frame_container.add_child(_canvases[0].frame_button)
|
||||
layer_and_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)
|
||||
layer_and_frame_container.move_child(_canvases[0].frame_button, _canvases[0].frame)
|
||||
canvas_parent.move_child(_canvases[0], _canvases[0].frame)
|
||||
|
||||
canvas.update()
|
||||
|
@ -448,26 +453,49 @@ 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 Layer":
|
||||
var layer_container = load("res://Prefabs/LayerContainer.tscn").instance()
|
||||
_canvases[0].layers[current_layer][2] = tr("Layer") + " %s" % current_layer
|
||||
layer_container.i = current_layer
|
||||
layer_container.get_child(0).get_child(1).text = _canvases[0].layers[current_layer][2]
|
||||
layer_container.get_child(0).get_child(2).text = _canvases[0].layers[current_layer][2]
|
||||
layer_and_frame_container.add_child(layer_container)
|
||||
layer_and_frame_container.move_child(layer_container, 0)
|
||||
|
||||
layer_and_frame_container.add_child(layers[current_layer][1])
|
||||
layer_and_frame_container.move_child(layers[current_layer][1], 1)
|
||||
for i in range(canvases.size()):
|
||||
var frame_button = load("res://Prefabs/FrameButton.tscn").instance()
|
||||
frame_button.frame = i
|
||||
frame_button.layer = current_layer
|
||||
frame_button.pressed = true
|
||||
|
||||
layers[current_layer][1].add_child(frame_button)
|
||||
|
||||
|
||||
# if action_name == "Change Layer Order":
|
||||
# var current_layer_index : int = _canvases[0].current_layer_index
|
||||
# _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)
|
||||
var label := Label.new()
|
||||
label.rect_min_size.x = 36
|
||||
label.align = Label.ALIGN_CENTER
|
||||
label.text = str(canvases.size() + 1)
|
||||
frame_ids.add_child(label)
|
||||
if !layer_and_frame_container.is_a_parent_of(_canvases[0].frame_button):
|
||||
layer_and_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)
|
||||
layer_and_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)
|
||||
layer_and_frame_container.move_child(_canvases[0].frame_button, _canvases[0].frame)
|
||||
canvas_parent.move_child(_canvases[0], _canvases[0].frame)
|
||||
|
||||
canvas.update()
|
||||
|
@ -491,18 +519,17 @@ func frame_changed(value : int) -> void:
|
|||
c.line_2d.set_point_position(1, c.line_2d.points[0])
|
||||
canvas = canvases[current_frame]
|
||||
canvas.visible = true
|
||||
canvas.generate_layer_panels()
|
||||
#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)
|
||||
c.frame_button.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"))
|
||||
|
||||
canvas.frame_button.pressed = true
|
||||
#canvas.frame_button.get_node("FrameID").add_color_override("font_color", Color("#3c5d75"))
|
||||
|
||||
func create_brush_button(brush_img : Image, brush_type := Brush_Types.CUSTOM, hint_tooltip := "") -> void:
|
||||
var brush_container
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
class_name LayerContainer
|
||||
extends Button
|
||||
|
||||
var i
|
||||
var i := 0
|
||||
# warning-ignore:unused_class_variable
|
||||
var currently_selected := false
|
||||
|
||||
onready var visibility_button := $VisibilityButton
|
||||
onready var visibility_button := $HBoxContainer/VisibilityButton
|
||||
onready var label := $HBoxContainer/Label
|
||||
onready var line_edit := $HBoxContainer/LineEdit
|
||||
|
||||
func _ready() -> void:
|
||||
changed_selection()
|
||||
#changed_selection()
|
||||
if Global.canvas.layers[i][3]:
|
||||
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)
|
||||
|
@ -27,8 +27,8 @@ func _input(event : InputEvent) -> void:
|
|||
func _on_LayerContainer_pressed() -> void:
|
||||
var initially_pressed := pressed
|
||||
var label_initially_visible : bool = label.visible
|
||||
Global.canvas.current_layer_index = i
|
||||
changed_selection()
|
||||
# Global.canvas.current_layer_index = i
|
||||
# changed_selection()
|
||||
if !initially_pressed:
|
||||
if label_initially_visible:
|
||||
label.visible = false
|
||||
|
@ -44,14 +44,15 @@ func changed_selection() -> void:
|
|||
var parent := get_parent()
|
||||
for child in parent.get_children():
|
||||
if child is Button:
|
||||
#print(child.name)
|
||||
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
|
||||
Global.layer_opacity_slider.value = Global.canvas.layers[child.i][3] * 100
|
||||
Global.layer_opacity_spinbox.value = Global.canvas.layers[child.i][3] * 100
|
||||
|
||||
if Global.canvas.current_layer_index < Global.canvas.layers.size() - 1:
|
||||
Global.move_up_layer_button.disabled = false
|
||||
|
@ -86,5 +87,5 @@ func _on_VisibilityButton_pressed() -> void:
|
|||
Global.canvas.update()
|
||||
|
||||
func _on_LineEdit_text_changed(new_text : String) -> void:
|
||||
Global.canvas.layers[i][2] = new_text
|
||||
Global.layers[i][0] = new_text
|
||||
label.text = new_text
|
||||
|
|
|
@ -406,9 +406,10 @@ func _on_OpenSprite_file_selected(path : String) -> void:
|
|||
Global.canvas = canvas
|
||||
var width := file.get_16()
|
||||
var height := file.get_16()
|
||||
print(width, height)
|
||||
|
||||
var layer_line := file.get_line()
|
||||
while layer_line == "-": #Load layers
|
||||
while layer_line == "-": # Load layers
|
||||
var buffer := file.get_buffer(width * height * 4)
|
||||
var layer_name := file.get_line()
|
||||
var layer_transparency := 1.0
|
||||
|
@ -507,7 +508,7 @@ func _on_SaveSprite_file_selected(path : String) -> void:
|
|||
file.store_float(layer[4]) # Layer transparency
|
||||
file.store_line("END_LAYERS")
|
||||
|
||||
for child in canvas.get_children(): #Store guides
|
||||
for child in canvas.get_children(): # Store guides
|
||||
if child is Guide:
|
||||
file.store_line("|")
|
||||
file.store_8(child.type)
|
||||
|
@ -554,7 +555,7 @@ 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():
|
||||
for child in Global.frame_containers.get_children():
|
||||
child.queue_free()
|
||||
for child in Global.canvas_parent.get_children():
|
||||
if child is Canvas:
|
||||
|
@ -687,86 +688,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
|
||||
|
|
Loading…
Reference in a new issue