mirror of
https://github.com/tonytins/CozyPixelStudio.git
synced 2025-06-25 06:54:43 -04: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:
parent
25f74a136d
commit
53338e4310
9 changed files with 241 additions and 60 deletions
|
@ -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_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:
|
||||
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.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
|
||||
|
|
|
@ -9,10 +9,10 @@ func _ready() -> void:
|
|||
hint_tooltip = "Frame: %s, Layer: %s" % [frame, layer]
|
||||
if Global.canvases[frame] in Global.layers[layer][5]:
|
||||
get_node("LinkedIndicator").visible = true
|
||||
popup_menu.set_item_disabled(4, false) # Unlink cel
|
||||
popup_menu.set_item_disabled(5, false) # Unlink cel
|
||||
else:
|
||||
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:
|
||||
if Input.is_action_just_released("left_mouse"):
|
||||
|
@ -87,7 +87,11 @@ func _on_PopupMenu_id_pressed(ID : int) -> void:
|
|||
change_frame_order(-1)
|
||||
3: # Move Right
|
||||
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])
|
||||
Global.layers[layer][5].remove(cel_index)
|
||||
_ready()
|
||||
|
|
|
@ -33,6 +33,7 @@ var transparent_background : ImageTexture
|
|||
# warning-ignore:unused_class_variable
|
||||
var selected_pixels := []
|
||||
var image_clipboard : Image
|
||||
var animation_tags := [] setget animation_tags_changed # [Name, Color, From, To]
|
||||
|
||||
# warning-ignore:unused_class_variable
|
||||
var theme_type := "Dark"
|
||||
|
@ -232,6 +233,8 @@ var play_backwards : BaseButton
|
|||
var timeline_seconds : Control
|
||||
var layers_container : VBoxContainer
|
||||
var frames_container : VBoxContainer
|
||||
var tag_container : Control
|
||||
var tag_dialog : ConfirmationDialog
|
||||
|
||||
var remove_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")
|
||||
play_forward = find_node_by_name(animation_timeline, "PlayForward")
|
||||
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")
|
||||
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)]
|
||||
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
|
||||
func find_node_by_name(root, node_name) -> Node:
|
||||
if root.get_name() == node_name:
|
||||
|
@ -609,6 +615,25 @@ func layer_changed(value : int) -> void:
|
|||
yield(get_tree().create_timer(0.01), "timeout")
|
||||
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:
|
||||
var brush_container
|
||||
var brush_button = load("res://Prefabs/BrushButton.tscn").instance()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue