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

Basic UI for animation frame tags

You can add tags by right clicking on a cel and selecting "Add Frame Tag". No tag modifying and deletion is implemented yet.

I'm using a different ScrollContainer for the tags, which gets updated everytime the main timeline ScrollContainer gets updated. I hide its sliders from its theme, wish there was a more straightforward way.
This commit is contained in:
OverloadedOrama 2020-04-02 03:29:14 +03:00
parent 25f74a136d
commit 53338e4310
9 changed files with 241 additions and 60 deletions

View file

@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Added ### Added
- Cels are now in the timeline. Each cel refers to a specific layer AND a frame. Frames are a collection of cels for every layer. - Cels are now in the timeline. Each cel refers to a specific layer AND a frame. Frames are a collection of cels for every layer.
- Cel linking is now possible. This way, layers can be "shared" in multiple frames. - Cel linking is now possible. This way, layers can be "shared" in multiple frames.
- You can now group multiple frames with tags.
- Pattern filling is now possible. If the user chooses a brush that is not the pixel or a circle brush and uses the bucket tool, the brush image is used as a pattern that fills the area. - Pattern filling is now possible. If the user chooses a brush that is not the pixel or a circle brush and uses the bucket tool, the brush image is used as a pattern that fills the area.
- Importing .pngs as palettes is now possible - thanks to Martin Novák (novhack)! - Importing .pngs as palettes is now possible - thanks to Martin Novák (novhack)!
- A confirmation message now appears when the user quits Pixelorama, if there are unsaved changes - thanks to Schweini07! - A confirmation message now appears when the user quits Pixelorama, if there are unsaved changes - thanks to Schweini07!
@ -27,7 +28,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Layer visibility is taken into account when exporting the drawing as a .png file. This means that invisible layers will not be included in the final .png file. - Layer visibility is taken into account when exporting the drawing as a .png file. This means that invisible layers will not be included in the final .png file.
- Visual change, added border outlines to all window dialogs. - Visual change, added border outlines to all window dialogs.
- Animation now loops by default. - Animation now loops by default.
- Onion skinning settings have been moved to a popup window, and 2 new buttons were added. One that enables it, and one that opens the settings window. - Onion skinning settings have been moved to a popup window, and 2 new buttons were added. One that toggles onion skinning, and one that opens the settings window.
- The splash screen is no longer purple, it now gets affected by the chosen theme. - The splash screen is no longer purple, it now gets affected by the chosen theme.
### Fixed ### Fixed

24
Prefabs/AnimationTag.tscn Normal file
View file

@ -0,0 +1,24 @@
[gd_scene format=2]
[node name="AnimationTag" type="VBoxContainer"]
margin_right = 39.0
margin_bottom = 32.0
rect_min_size = Vector2( 39, 32 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Line2D" type="Line2D" parent="."]
points = PoolVector2Array( 0, 32, 0, 0, 39, 0, 39, 32 )
width = 1.0
texture_mode = 1313163520
[node name="Label" type="Label" parent="."]
margin_left = 7.0
margin_right = 32.0
margin_bottom = 32.0
size_flags_horizontal = 4
size_flags_vertical = 3
text = "Idle"
align = 1
valign = 1

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=52 format=2] [gd_scene load_steps=58 format=2]
[ext_resource path="res://Scripts/AnimationTimeline.gd" type="Script" id=1] [ext_resource path="res://Scripts/AnimationTimeline.gd" type="Script" id=1]
[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.png" type="Texture" id=2]
@ -84,6 +84,27 @@ scancode = 16777230
[sub_resource type="ShortCut" id=12] [sub_resource type="ShortCut" id=12]
shortcut = SubResource( 11 ) shortcut = SubResource( 11 )
[sub_resource type="StyleBoxEmpty" id=13]
[sub_resource type="StyleBoxEmpty" id=14]
[sub_resource type="StyleBoxEmpty" id=15]
[sub_resource type="StyleBoxEmpty" id=16]
[sub_resource type="StyleBoxEmpty" id=17]
[sub_resource type="Theme" id=18]
HScrollBar/icons/decrement = null
HScrollBar/icons/decrement_highlight = null
HScrollBar/icons/increment = null
HScrollBar/icons/increment_highlight = null
HScrollBar/styles/grabber = SubResource( 13 )
HScrollBar/styles/grabber_highlight = SubResource( 14 )
HScrollBar/styles/grabber_pressed = SubResource( 15 )
HScrollBar/styles/scroll = SubResource( 16 )
HScrollBar/styles/scroll_focus = SubResource( 17 )
[node name="AnimationTimeline" type="Panel"] [node name="AnimationTimeline" type="Panel"]
margin_top = 438.0 margin_top = 438.0
margin_right = 704.0 margin_right = 704.0
@ -210,26 +231,6 @@ size_flags_horizontal = 3
[node name="SpacerControl" type="Control" parent="AnimationContainer/TimelineContainer"] [node name="SpacerControl" type="Control" parent="AnimationContainer/TimelineContainer"]
margin_right = 604.0 margin_right = 604.0
[node name="AnimationTags" type="VBoxContainer" parent="AnimationContainer/TimelineContainer"]
visible = false
margin_right = 471.0
margin_bottom = 32.0
[node name="Line2D" type="Line2D" parent="AnimationContainer/TimelineContainer/AnimationTags"]
points = PoolVector2Array( 0, 32, 0, 0, 110, 0, 110, 32 )
width = 1.0
texture_mode = 1313163520
[node name="Label" type="Label" parent="AnimationContainer/TimelineContainer/AnimationTags"]
margin_right = 110.0
margin_bottom = 32.0
rect_min_size = Vector2( 110, 32 )
size_flags_horizontal = 0
size_flags_vertical = 0
text = "Animation Tags"
align = 1
valign = 1
[node name="AnimationButtons" type="HBoxContainer" parent="AnimationContainer/TimelineContainer"] [node name="AnimationButtons" type="HBoxContainer" parent="AnimationContainer/TimelineContainer"]
margin_top = 4.0 margin_top = 4.0
margin_right = 604.0 margin_right = 604.0
@ -238,15 +239,16 @@ rect_min_size = Vector2( 0, 24 )
[node name="CurrentFrame" type="Label" parent="AnimationContainer/TimelineContainer/AnimationButtons"] [node name="CurrentFrame" type="Label" parent="AnimationContainer/TimelineContainer/AnimationButtons"]
margin_top = 5.0 margin_top = 5.0
margin_right = 117.0 margin_right = 150.0
margin_bottom = 19.0 margin_bottom = 19.0
rect_min_size = Vector2( 150, 0 )
text = "Current frame: 1/1" text = "Current frame: 1/1"
[node name="AddFrame" type="TextureButton" parent="AnimationContainer/TimelineContainer/AnimationButtons" groups=[ [node name="AddFrame" type="TextureButton" parent="AnimationContainer/TimelineContainer/AnimationButtons" groups=[
"UIButtons", "UIButtons",
]] ]]
margin_left = 121.0 margin_left = 154.0
margin_right = 141.0 margin_right = 174.0
margin_bottom = 20.0 margin_bottom = 20.0
hint_tooltip = "Add a new frame" hint_tooltip = "Add a new frame"
mouse_default_cursor_shape = 2 mouse_default_cursor_shape = 2
@ -256,8 +258,8 @@ texture_normal = ExtResource( 19 )
texture_hover = ExtResource( 20 ) texture_hover = ExtResource( 20 )
[node name="PlaybackButtons" type="HBoxContainer" parent="AnimationContainer/TimelineContainer/AnimationButtons"] [node name="PlaybackButtons" type="HBoxContainer" parent="AnimationContainer/TimelineContainer/AnimationButtons"]
margin_left = 234.0 margin_left = 251.0
margin_right = 374.0 margin_right = 391.0
margin_bottom = 24.0 margin_bottom = 24.0
size_flags_horizontal = 6 size_flags_horizontal = 6
@ -398,55 +400,72 @@ margin_top = 32.0
margin_right = 604.0 margin_right = 604.0
margin_bottom = 36.0 margin_bottom = 36.0
[node name="OpacityContainer" type="HBoxContainer" parent="AnimationContainer/TimelineContainer"] [node name="OpacityAndTagContainer" type="HBoxContainer" parent="AnimationContainer/TimelineContainer"]
margin_top = 40.0 margin_top = 40.0
margin_right = 604.0 margin_right = 604.0
margin_bottom = 64.0 margin_bottom = 72.0
custom_constants/separation = 2 custom_constants/separation = 2
[node name="OpacityLabel" type="Label" parent="AnimationContainer/TimelineContainer/OpacityContainer"] [node name="OpacityContainer" type="HBoxContainer" parent="AnimationContainer/TimelineContainer/OpacityAndTagContainer"]
margin_right = 214.0
margin_bottom = 32.0
rect_min_size = Vector2( 214, 0 )
[node name="OpacityLabel" type="Label" parent="AnimationContainer/TimelineContainer/OpacityAndTagContainer/OpacityContainer"]
margin_right = 53.0 margin_right = 53.0
margin_bottom = 24.0 margin_bottom = 32.0
size_flags_horizontal = 0 size_flags_horizontal = 0
size_flags_vertical = 1 size_flags_vertical = 1
text = "Opacity:" text = "Opacity:"
valign = 1 valign = 1
[node name="OpacitySlider" type="HSlider" parent="AnimationContainer/TimelineContainer/OpacityContainer"] [node name="OpacitySlider" type="HSlider" parent="AnimationContainer/TimelineContainer/OpacityAndTagContainer/OpacityContainer"]
margin_left = 55.0 margin_left = 57.0
margin_right = 167.0 margin_right = 136.0
margin_bottom = 24.0 margin_bottom = 32.0
rect_min_size = Vector2( 112, 0 )
mouse_default_cursor_shape = 2 mouse_default_cursor_shape = 2
size_flags_horizontal = 3
size_flags_vertical = 1 size_flags_vertical = 1
value = 100.0 value = 100.0
ticks_on_borders = true ticks_on_borders = true
[node name="OpacitySpinBox" type="SpinBox" parent="AnimationContainer/TimelineContainer/OpacityContainer"] [node name="OpacitySpinBox" type="SpinBox" parent="AnimationContainer/TimelineContainer/OpacityAndTagContainer/OpacityContainer"]
margin_left = 169.0 margin_left = 140.0
margin_right = 243.0 margin_top = 4.0
margin_bottom = 24.0 margin_right = 214.0
margin_bottom = 28.0
mouse_default_cursor_shape = 2 mouse_default_cursor_shape = 2
size_flags_vertical = 4 size_flags_vertical = 4
value = 100.0 value = 100.0
align = 1 align = 1
[node name="TagScroll" type="ScrollContainer" parent="AnimationContainer/TimelineContainer/OpacityAndTagContainer"]
margin_left = 216.0
margin_right = 604.0
margin_bottom = 32.0
rect_min_size = Vector2( 0, 32 )
size_flags_horizontal = 3
theme = SubResource( 18 )
scroll_vertical_enabled = false
[node name="TagContainer" type="Control" parent="AnimationContainer/TimelineContainer/OpacityAndTagContainer/TagScroll"]
[node name="TimelineScroll" type="ScrollContainer" parent="AnimationContainer/TimelineContainer"] [node name="TimelineScroll" type="ScrollContainer" parent="AnimationContainer/TimelineContainer"]
margin_top = 68.0 margin_top = 76.0
margin_right = 604.0 margin_right = 604.0
margin_bottom = 200.0 margin_bottom = 200.0
size_flags_vertical = 3 size_flags_vertical = 3
[node name="LayersAndFrames" type="HBoxContainer" parent="AnimationContainer/TimelineContainer/TimelineScroll"] [node name="LayersAndFrames" type="HBoxContainer" parent="AnimationContainer/TimelineContainer/TimelineScroll"]
margin_right = 252.0 margin_right = 252.0
margin_bottom = 132.0 margin_bottom = 124.0
size_flags_vertical = 3 size_flags_vertical = 3
[node name="VBoxContainer" type="VBoxContainer" parent="AnimationContainer/TimelineContainer/TimelineScroll/LayersAndFrames"] [node name="LayerVBoxCont" type="VBoxContainer" parent="AnimationContainer/TimelineContainer/TimelineScroll/LayersAndFrames"]
margin_right = 212.0 margin_right = 212.0
margin_bottom = 132.0 margin_bottom = 124.0
[node name="LayerLabel" type="Label" parent="AnimationContainer/TimelineContainer/TimelineScroll/LayersAndFrames/VBoxContainer"] [node name="LayerLabel" type="Label" parent="AnimationContainer/TimelineContainer/TimelineScroll/LayersAndFrames/LayerVBoxCont"]
margin_right = 212.0 margin_right = 212.0
margin_bottom = 16.0 margin_bottom = 16.0
rect_min_size = Vector2( 0, 16 ) rect_min_size = Vector2( 0, 16 )
@ -454,31 +473,31 @@ text = "Layers"
align = 1 align = 1
valign = 1 valign = 1
[node name="LayersContainer" type="VBoxContainer" parent="AnimationContainer/TimelineContainer/TimelineScroll/LayersAndFrames/VBoxContainer"] [node name="LayersContainer" type="VBoxContainer" parent="AnimationContainer/TimelineContainer/TimelineScroll/LayersAndFrames/LayerVBoxCont"]
margin_top = 20.0 margin_top = 20.0
margin_right = 212.0 margin_right = 212.0
margin_bottom = 56.0 margin_bottom = 56.0
[node name="LayerContainer" parent="AnimationContainer/TimelineContainer/TimelineScroll/LayersAndFrames/VBoxContainer/LayersContainer" instance=ExtResource( 18 )] [node name="LayerContainer" parent="AnimationContainer/TimelineContainer/TimelineScroll/LayersAndFrames/LayerVBoxCont/LayersContainer" instance=ExtResource( 18 )]
margin_right = 212.0 margin_right = 212.0
[node name="VBoxContainer2" type="VBoxContainer" parent="AnimationContainer/TimelineContainer/TimelineScroll/LayersAndFrames"] [node name="FrameButtonsAndIds" type="VBoxContainer" parent="AnimationContainer/TimelineContainer/TimelineScroll/LayersAndFrames"]
margin_left = 216.0 margin_left = 216.0
margin_right = 252.0 margin_right = 252.0
margin_bottom = 132.0 margin_bottom = 124.0
[node name="FrameIDs" type="HBoxContainer" parent="AnimationContainer/TimelineContainer/TimelineScroll/LayersAndFrames/VBoxContainer2"] [node name="FrameIDs" type="HBoxContainer" parent="AnimationContainer/TimelineContainer/TimelineScroll/LayersAndFrames/FrameButtonsAndIds"]
margin_right = 36.0 margin_right = 36.0
margin_bottom = 14.0 margin_bottom = 14.0
[node name="Label" type="Label" parent="AnimationContainer/TimelineContainer/TimelineScroll/LayersAndFrames/VBoxContainer2/FrameIDs"] [node name="Label" type="Label" parent="AnimationContainer/TimelineContainer/TimelineScroll/LayersAndFrames/FrameButtonsAndIds/FrameIDs"]
margin_right = 36.0 margin_right = 36.0
margin_bottom = 14.0 margin_bottom = 14.0
rect_min_size = Vector2( 36, 0 ) rect_min_size = Vector2( 36, 0 )
text = "1" text = "1"
align = 1 align = 1
[node name="FramesContainer" type="VBoxContainer" parent="AnimationContainer/TimelineContainer/TimelineScroll/LayersAndFrames/VBoxContainer2"] [node name="FramesContainer" type="VBoxContainer" parent="AnimationContainer/TimelineContainer/TimelineScroll/LayersAndFrames/FrameButtonsAndIds"]
margin_top = 18.0 margin_top = 18.0
margin_right = 36.0 margin_right = 36.0
margin_bottom = 18.0 margin_bottom = 18.0
@ -544,6 +563,78 @@ margin_right = 132.0
margin_bottom = 116.0 margin_bottom = 116.0
mouse_default_cursor_shape = 2 mouse_default_cursor_shape = 2
text = "Blue-Red Mode" text = "Blue-Red Mode"
[node name="TagDialog" type="ConfirmationDialog" parent="."]
margin_right = 83.0
margin_bottom = 58.0
window_title = "Frame Tag Properties"
resizable = true
__meta__ = {
"_edit_use_anchors_": false
}
[node name="GridContainer" type="GridContainer" parent="TagDialog"]
margin_left = 8.0
margin_top = 8.0
margin_right = 192.0
margin_bottom = 124.0
custom_constants/vseparation = 8
custom_constants/hseparation = 8
columns = 2
__meta__ = {
"_edit_use_anchors_": false
}
[node name="NameLabel" type="Label" parent="TagDialog/GridContainer"]
margin_top = 5.0
margin_right = 42.0
margin_bottom = 19.0
text = "Name:"
[node name="NameLineEdit" type="LineEdit" parent="TagDialog/GridContainer"]
margin_left = 50.0
margin_right = 124.0
margin_bottom = 24.0
[node name="ColorLabel" type="Label" parent="TagDialog/GridContainer"]
margin_top = 35.0
margin_right = 42.0
margin_bottom = 49.0
text = "Color:"
[node name="ColorPickerButton" type="ColorPickerButton" parent="TagDialog/GridContainer"]
margin_left = 50.0
margin_top = 32.0
margin_right = 124.0
margin_bottom = 52.0
[node name="FromLabel" type="Label" parent="TagDialog/GridContainer"]
margin_top = 65.0
margin_right = 42.0
margin_bottom = 79.0
text = "From:"
[node name="FromSpinBox" type="SpinBox" parent="TagDialog/GridContainer"]
margin_left = 50.0
margin_top = 60.0
margin_right = 124.0
margin_bottom = 84.0
min_value = 1.0
value = 1.0
[node name="ToLabel" type="Label" parent="TagDialog/GridContainer"]
margin_top = 97.0
margin_right = 42.0
margin_bottom = 111.0
text = "To:"
[node name="ToSpinBox" type="SpinBox" parent="TagDialog/GridContainer"]
margin_left = 50.0
margin_top = 92.0
margin_right = 124.0
margin_bottom = 116.0
min_value = 1.0
value = 1.0
[connection signal="pressed" from="AnimationContainer/ForLayerButtons/LayerButtons/AddLayer" to="." method="add_layer" binds= [ true ]] [connection signal="pressed" from="AnimationContainer/ForLayerButtons/LayerButtons/AddLayer" to="." method="add_layer" binds= [ true ]]
[connection signal="pressed" from="AnimationContainer/ForLayerButtons/LayerButtons/RemoveLayer" to="." method="_on_RemoveLayer_pressed"] [connection signal="pressed" from="AnimationContainer/ForLayerButtons/LayerButtons/RemoveLayer" to="." method="_on_RemoveLayer_pressed"]
[connection signal="pressed" from="AnimationContainer/ForLayerButtons/LayerButtons/MoveUpLayer" to="." method="change_layer_order" binds= [ 1 ]] [connection signal="pressed" from="AnimationContainer/ForLayerButtons/LayerButtons/MoveUpLayer" to="." method="change_layer_order" binds= [ 1 ]]
@ -561,9 +652,12 @@ text = "Blue-Red Mode"
[connection signal="pressed" from="AnimationContainer/TimelineContainer/AnimationButtons/LoopButtons/OnionSkinning" to="." method="_on_OnionSkinning_pressed"] [connection signal="pressed" from="AnimationContainer/TimelineContainer/AnimationButtons/LoopButtons/OnionSkinning" to="." method="_on_OnionSkinning_pressed"]
[connection signal="pressed" from="AnimationContainer/TimelineContainer/AnimationButtons/LoopButtons/LoopAnim" to="." method="_on_LoopAnim_pressed"] [connection signal="pressed" from="AnimationContainer/TimelineContainer/AnimationButtons/LoopButtons/LoopAnim" to="." method="_on_LoopAnim_pressed"]
[connection signal="value_changed" from="AnimationContainer/TimelineContainer/AnimationButtons/LoopButtons/FPSValue" to="." method="_on_FPSValue_value_changed"] [connection signal="value_changed" from="AnimationContainer/TimelineContainer/AnimationButtons/LoopButtons/FPSValue" to="." method="_on_FPSValue_value_changed"]
[connection signal="value_changed" from="AnimationContainer/TimelineContainer/OpacityContainer/OpacitySlider" to="." method="_on_OpacitySlider_value_changed"] [connection signal="value_changed" from="AnimationContainer/TimelineContainer/OpacityAndTagContainer/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="value_changed" from="AnimationContainer/TimelineContainer/OpacityAndTagContainer/OpacityContainer/OpacitySpinBox" to="." method="_on_OpacitySlider_value_changed"]
[connection signal="timeout" from="AnimationTimer" to="." method="_on_AnimationTimer_timeout"] [connection signal="timeout" from="AnimationTimer" to="." method="_on_AnimationTimer_timeout"]
[connection signal="popup_hide" from="OnionSkinningSettings" to="." method="_on_OnionSkinningSettings_popup_hide"]
[connection signal="value_changed" from="OnionSkinningSettings/OnionSkinningButtons/PastOnionSkinning" to="." method="_on_PastOnionSkinning_value_changed"] [connection signal="value_changed" from="OnionSkinningSettings/OnionSkinningButtons/PastOnionSkinning" to="." method="_on_PastOnionSkinning_value_changed"]
[connection signal="value_changed" from="OnionSkinningSettings/OnionSkinningButtons/FutureOnionSkinning" to="." method="_on_FutureOnionSkinning_value_changed"] [connection signal="value_changed" from="OnionSkinningSettings/OnionSkinningButtons/FutureOnionSkinning" to="." method="_on_FutureOnionSkinning_value_changed"]
[connection signal="toggled" from="OnionSkinningSettings/OnionSkinningButtons/BlueRedMode" to="." method="_on_BlueRedMode_toggled"] [connection signal="toggled" from="OnionSkinningSettings/OnionSkinningButtons/BlueRedMode" to="." method="_on_BlueRedMode_toggled"]
[connection signal="confirmed" from="TagDialog" to="." method="_on_TagDialog_confirmed"]
[connection signal="popup_hide" from="TagDialog" to="." method="_on_TagDialog_popup_hide"]

View file

@ -9,7 +9,6 @@
[ext_resource path="res://Assets/Fonts/Roboto-Small.tres" type="DynamicFont" id=7] [ext_resource path="res://Assets/Fonts/Roboto-Small.tres" type="DynamicFont" id=7]
[node name="SplashDialog" type="WindowDialog"] [node name="SplashDialog" type="WindowDialog"]
visible = true
margin_right = 600.0 margin_right = 600.0
margin_bottom = 400.0 margin_bottom = 400.0
rect_min_size = Vector2( 600, 560 ) rect_min_size = Vector2( 600, 560 )
@ -137,7 +136,7 @@ margin_bottom = 260.0
rect_min_size = Vector2( 0, 260 ) rect_min_size = Vector2( 0, 260 )
[node name="Label" type="Label" parent="Contents/PatronsArtNews/ChangelogContainer/ChangelogScroll"] [node name="Label" type="Label" parent="Contents/PatronsArtNews/ChangelogContainer/ChangelogScroll"]
margin_right = 130.0 margin_right = 142.0
margin_bottom = 2921.0 margin_bottom = 2921.0
size_flags_horizontal = 3 size_flags_horizontal = 3
size_flags_vertical = 3 size_flags_vertical = 3

View file

@ -35,7 +35,7 @@ __meta__ = {
margin_right = 20.0 margin_right = 20.0
margin_bottom = 20.0 margin_bottom = 20.0
mouse_default_cursor_shape = 2 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, "Unlink Cel", null, 0, false, true, 4, 0, null, "", false ] 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, "Add Frame Tag", null, 0, false, false, 4, 0, null, "", false, "Unlink Cel", null, 0, false, true, 5, 0, null, "", false ]
[node name="LinkedIndicator" type="Polygon2D" parent="."] [node name="LinkedIndicator" type="Polygon2D" parent="."]
visible = false visible = false

View file

@ -4,6 +4,18 @@ var fps := 6.0
var animation_loop := 1 # 0 is no loop, 1 is cycle loop, 2 is ping-pong loop var animation_loop := 1 # 0 is no loop, 1 is cycle loop, 2 is ping-pong loop
var animation_forward := true var animation_forward := true
onready var timeline_scroll : ScrollContainer = $AnimationContainer/TimelineContainer/TimelineScroll
onready var tag_scroll_container : ScrollContainer = $AnimationContainer/TimelineContainer/OpacityAndTagContainer/TagScroll
func _ready() -> void:
timeline_scroll.get_h_scrollbar().connect("value_changed", self, "_h_scroll_changed")
func _h_scroll_changed(value : float) -> void:
# Let the main timeline ScrollContainer affect the tag ScrollContainer too
tag_scroll_container.get_child(0).rect_min_size.x = timeline_scroll.get_child(0).rect_size.x - 212
tag_scroll_container.scroll_horizontal = value
func add_frame() -> void: func add_frame() -> void:
var new_canvas : Canvas = load("res://Prefabs/Canvas.tscn").instance() var new_canvas : Canvas = load("res://Prefabs/Canvas.tscn").instance()
@ -291,3 +303,19 @@ func _on_OpacitySlider_value_changed(value) -> void:
Global.layer_opacity_spinbox.value = value Global.layer_opacity_spinbox.value = value
Global.canvas.update() Global.canvas.update()
func _on_TagDialog_confirmed() -> void:
var tag_name : String = Global.tag_dialog.get_node("GridContainer/NameLineEdit").text
var tag_color : Color = Global.tag_dialog.get_node("GridContainer/ColorPickerButton").color
var tag_from : int = Global.tag_dialog.get_node("GridContainer/FromSpinBox").value
var tag_to : int = Global.tag_dialog.get_node("GridContainer/ToSpinBox").value
Global.animation_tags.append([tag_name, tag_color, tag_from, tag_to])
Global.animation_tags = Global.animation_tags # To execute animation_tags_changed()
func _on_OnionSkinningSettings_popup_hide() -> void:
Global.can_draw = true
func _on_TagDialog_popup_hide() -> void:
Global.can_draw = true

View file

@ -9,10 +9,10 @@ func _ready() -> void:
hint_tooltip = "Frame: %s, Layer: %s" % [frame, layer] hint_tooltip = "Frame: %s, Layer: %s" % [frame, layer]
if Global.canvases[frame] in Global.layers[layer][5]: if Global.canvases[frame] in Global.layers[layer][5]:
get_node("LinkedIndicator").visible = true get_node("LinkedIndicator").visible = true
popup_menu.set_item_disabled(4, false) # Unlink cel popup_menu.set_item_disabled(5, false) # Unlink cel
else: else:
get_node("LinkedIndicator").visible = false get_node("LinkedIndicator").visible = false
popup_menu.set_item_disabled(4, true) # Unlink cel popup_menu.set_item_disabled(5, true) # Unlink cel
func _on_FrameButton_pressed() -> void: func _on_FrameButton_pressed() -> void:
if Input.is_action_just_released("left_mouse"): if Input.is_action_just_released("left_mouse"):
@ -87,7 +87,11 @@ func _on_PopupMenu_id_pressed(ID : int) -> void:
change_frame_order(-1) change_frame_order(-1)
3: # Move Right 3: # Move Right
change_frame_order(1) change_frame_order(1)
4: # Unlink Cel 4: # Add Frame Tag
Global.tag_dialog.popup_centered()
Global.tag_dialog.get_node("GridContainer/FromSpinBox").value = frame + 1
Global.tag_dialog.get_node("GridContainer/ToSpinBox").value = frame + 1
5: # Unlink Cel
var cel_index : int = Global.layers[layer][5].find(Global.canvases[frame]) var cel_index : int = Global.layers[layer][5].find(Global.canvases[frame])
Global.layers[layer][5].remove(cel_index) Global.layers[layer][5].remove(cel_index)
_ready() _ready()

View file

@ -33,6 +33,7 @@ var transparent_background : ImageTexture
# warning-ignore:unused_class_variable # warning-ignore:unused_class_variable
var selected_pixels := [] var selected_pixels := []
var image_clipboard : Image var image_clipboard : Image
var animation_tags := [] setget animation_tags_changed # [Name, Color, From, To]
# warning-ignore:unused_class_variable # warning-ignore:unused_class_variable
var theme_type := "Dark" var theme_type := "Dark"
@ -232,6 +233,8 @@ var play_backwards : BaseButton
var timeline_seconds : Control var timeline_seconds : Control
var layers_container : VBoxContainer var layers_container : VBoxContainer
var frames_container : VBoxContainer var frames_container : VBoxContainer
var tag_container : Control
var tag_dialog : ConfirmationDialog
var remove_layer_button : BaseButton var remove_layer_button : BaseButton
var move_up_layer_button : BaseButton var move_up_layer_button : BaseButton
@ -346,6 +349,8 @@ func _ready() -> void:
loop_animation_button = find_node_by_name(animation_timeline, "LoopAnim") loop_animation_button = find_node_by_name(animation_timeline, "LoopAnim")
play_forward = find_node_by_name(animation_timeline, "PlayForward") play_forward = find_node_by_name(animation_timeline, "PlayForward")
play_backwards = find_node_by_name(animation_timeline, "PlayBackwards") play_backwards = find_node_by_name(animation_timeline, "PlayBackwards")
tag_container = find_node_by_name(animation_timeline, "TagContainer")
tag_dialog = find_node_by_name(animation_timeline, "TagDialog")
remove_layer_button = find_node_by_name(animation_timeline, "RemoveLayer") remove_layer_button = find_node_by_name(animation_timeline, "RemoveLayer")
move_up_layer_button = find_node_by_name(animation_timeline, "MoveUpLayer") move_up_layer_button = find_node_by_name(animation_timeline, "MoveUpLayer")
@ -370,6 +375,7 @@ func _ready() -> void:
# will new frames be linked boolean (4), Array of linked frames (5)] # will new frames be linked boolean (4), Array of linked frames (5)]
layers.append([tr("Layer") + " 0", true, false, HBoxContainer.new(), false, []]) layers.append([tr("Layer") + " 0", true, false, HBoxContainer.new(), false, []])
# Thanks to https://godotengine.org/qa/17524/how-to-find-an-instanced-scene-by-its-name # 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: func find_node_by_name(root, node_name) -> Node:
if root.get_name() == node_name: if root.get_name() == node_name:
@ -609,6 +615,25 @@ func layer_changed(value : int) -> void:
yield(get_tree().create_timer(0.01), "timeout") yield(get_tree().create_timer(0.01), "timeout")
self.current_frame = current_frame # Call frame_changed to update UI self.current_frame = current_frame # Call frame_changed to update UI
func animation_tags_changed(value : Array) -> void:
animation_tags = value
var tag : Container = load("res://Prefabs/AnimationTag.tscn").instance()
tag_container.add_child(tag)
var tag_position := tag_container.get_child_count() - 1
tag_container.move_child(tag, tag_position)
tag.get_node("Label").text = animation_tags[tag_position][0]
tag.get_node("Label").modulate = animation_tags[tag_position][1]
tag.get_node("Line2D").default_color = animation_tags[tag_position][1]
tag.rect_position.x = (animation_tags[tag_position][2] - 1) * 39 + animation_tags[tag_position][2]
var size : int = animation_tags[tag_position][3] - animation_tags[tag_position][2]
tag.rect_min_size.x = (size + 1) * 39
tag.get_node("Line2D").points[2] = Vector2(tag.rect_min_size.x, 0)
tag.get_node("Line2D").points[3] = Vector2(tag.rect_min_size.x, 32)
func create_brush_button(brush_img : Image, brush_type := Brush_Types.CUSTOM, hint_tooltip := "") -> void: func create_brush_button(brush_img : Image, brush_type := Brush_Types.CUSTOM, hint_tooltip := "") -> void:
var brush_container var brush_container
var brush_button = load("res://Prefabs/BrushButton.tscn").instance() var brush_button = load("res://Prefabs/BrushButton.tscn").instance()

View file

@ -630,6 +630,12 @@ msgstr ""
msgid "Move Right" msgid "Move Right"
msgstr "" msgstr ""
msgid "Add Frame Tag"
msgstr ""
msgid "Unlink Cel"
msgstr ""
msgid "Layer" msgid "Layer"
msgstr "" msgstr ""