From 02f85ade061613162cfd590de7da8f548a5511dc Mon Sep 17 00:00:00 2001 From: Emmanouil Papadeas <35376950+OverloadedOrama@users.noreply.github.com> Date: Mon, 6 May 2024 20:13:09 +0300 Subject: [PATCH] Make TagOptions its own scene --- src/UI/Timeline/FrameTagDialog.gd | 115 +++------------------------- src/UI/Timeline/FrameTagDialog.tscn | 78 +------------------ src/UI/Timeline/TagOptions.gd | 103 +++++++++++++++++++++++++ src/UI/Timeline/TagOptions.tscn | 78 +++++++++++++++++++ 4 files changed, 194 insertions(+), 180 deletions(-) create mode 100644 src/UI/Timeline/TagOptions.gd create mode 100644 src/UI/Timeline/TagOptions.tscn diff --git a/src/UI/Timeline/FrameTagDialog.gd b/src/UI/Timeline/FrameTagDialog.gd index 97900654a..49371a1df 100644 --- a/src/UI/Timeline/FrameTagDialog.gd +++ b/src/UI/Timeline/FrameTagDialog.gd @@ -1,21 +1,10 @@ extends AcceptDialog -var current_tag_id := 0 var tag_vboxes := [] -var delete_tag_button: Button @onready var main_vbox_cont: VBoxContainer = $VBoxContainer/ScrollContainer/VBoxTagContainer @onready var add_tag_button: Button = $VBoxContainer/ScrollContainer/VBoxTagContainer/AddTag -@onready var options_dialog := $TagOptions -@onready var name_line_edit := $TagOptions/GridContainer/NameLineEdit as LineEdit -@onready var color_picker_button := $TagOptions/GridContainer/ColorPickerButton as ColorPickerButton -@onready var from_spinbox := $TagOptions/GridContainer/FromSpinBox as SpinBox -@onready var to_spinbox := $TagOptions/GridContainer/ToSpinBox as SpinBox -@onready var user_data_text_edit := $TagOptions/GridContainer/UserDataTextEdit as TextEdit - - -func _ready() -> void: - $"TagOptions/GridContainer/ColorPickerButton".get_picker().presets_visible = false +@onready var options_dialog := $TagOptions as ConfirmationDialog func _on_FrameTagDialog_about_to_show() -> void: @@ -68,111 +57,25 @@ func _on_FrameTagDialog_visibility_changed() -> void: func _on_AddTag_pressed() -> void: var x_pos := add_tag_button.global_position.x var y_pos := add_tag_button.global_position.y + 2 * add_tag_button.size.y - options_dialog.popup(Rect2i(position + Vector2i(x_pos, y_pos), options_dialog.size)) - current_tag_id = Global.current_project.animation_tags.size() + var dialog_position := Rect2i(position + Vector2i(x_pos, y_pos), options_dialog.size) + var current_tag_id := Global.current_project.animation_tags.size() # Determine tag values (array sort method) - var frames := [] + var frames := PackedInt32Array([]) for cel in Global.current_project.selected_cels: frames.append(cel[0]) frames.sort() - - from_spinbox.value = (frames[0] + 1) - to_spinbox.value = (frames[-1] + 1) - color_picker_button.color = Color(randf(), randf(), randf()) - user_data_text_edit.text = "" + options_dialog.show_dialog(dialog_position, current_tag_id, false, frames) func _on_EditButton_pressed(_tag_id: int, edit_button: Button) -> void: var x_pos := edit_button.global_position.x var y_pos := edit_button.global_position.y + 2 * edit_button.size.y - options_dialog.popup(Rect2i(position + Vector2i(x_pos, y_pos), options_dialog.size)) - current_tag_id = _tag_id - var animation_tag := Global.current_project.animation_tags[_tag_id] - name_line_edit.text = animation_tag.name - color_picker_button.color = animation_tag.color - from_spinbox.value = animation_tag.from - to_spinbox.value = animation_tag.to - user_data_text_edit.text = animation_tag.user_data - if !delete_tag_button: - delete_tag_button = options_dialog.add_button("Delete", true, "delete_tag") - else: - delete_tag_button.visible = true + var dialog_position := Rect2i(position + Vector2i(x_pos, y_pos), options_dialog.size) + options_dialog.show_dialog(dialog_position, _tag_id, true) -func _on_TagOptions_confirmed() -> void: - var tag_name := name_line_edit.text - var tag_color := color_picker_button.color - var tag_from := from_spinbox.value - var tag_to := to_spinbox.value - var user_data := user_data_text_edit.text - - if tag_to > Global.current_project.frames.size(): - tag_to = Global.current_project.frames.size() - - if tag_from > tag_to: - tag_from = tag_to - - var new_animation_tags := Global.current_project.animation_tags.duplicate() - # Loop through the tags to create new classes for them, so that they won't be the same - # as Global.current_project.animation_tags's classes. Needed for undo/redo to work properly. - for i in new_animation_tags.size(): - var prev_tag: AnimationTag = new_animation_tags[i] - new_animation_tags[i] = AnimationTag.new( - prev_tag.name, prev_tag.color, prev_tag.from, prev_tag.to - ) - new_animation_tags[i].user_data = prev_tag.user_data - - if current_tag_id == Global.current_project.animation_tags.size(): - var new_tag := AnimationTag.new(tag_name, tag_color, tag_from, tag_to) - new_tag.user_data = user_data - new_animation_tags.append(new_tag) - else: - new_animation_tags[current_tag_id].name = tag_name - new_animation_tags[current_tag_id].color = tag_color - new_animation_tags[current_tag_id].from = tag_from - new_animation_tags[current_tag_id].to = tag_to - new_animation_tags[current_tag_id].user_data = user_data - - # Handle Undo/Redo - Global.current_project.undos += 1 - Global.current_project.undo_redo.create_action("Modify Frame Tag") - Global.current_project.undo_redo.add_do_method(Global.general_redo) - Global.current_project.undo_redo.add_undo_method(Global.general_undo) - Global.current_project.undo_redo.add_do_property( - Global.current_project, "animation_tags", new_animation_tags - ) - Global.current_project.undo_redo.add_undo_property( - Global.current_project, "animation_tags", Global.current_project.animation_tags - ) - Global.current_project.undo_redo.commit_action() - _on_FrameTagDialog_about_to_show() - - -func _on_TagOptions_custom_action(action: String) -> void: - if action != "delete_tag": - return - var new_animation_tags := Global.current_project.animation_tags.duplicate() - new_animation_tags.remove_at(current_tag_id) - # Handle Undo/Redo - Global.current_project.undos += 1 - Global.current_project.undo_redo.create_action("Delete Frame Tag") - Global.current_project.undo_redo.add_do_method(Global.general_redo) - Global.current_project.undo_redo.add_undo_method(Global.general_undo) - Global.current_project.undo_redo.add_do_property( - Global.current_project, "animation_tags", new_animation_tags - ) - Global.current_project.undo_redo.add_undo_property( - Global.current_project, "animation_tags", Global.current_project.animation_tags - ) - Global.current_project.undo_redo.commit_action() - - options_dialog.hide() - _on_FrameTagDialog_about_to_show() - - -func _on_TagOptions_visibility_changed() -> void: - if delete_tag_button: - delete_tag_button.visible = false +func _on_tag_options_visibility_changed() -> void: + _on_FrameTagDialog_about_to_show.call_deferred() func _on_PlayOnlyTags_toggled(button_pressed: bool) -> void: diff --git a/src/UI/Timeline/FrameTagDialog.tscn b/src/UI/Timeline/FrameTagDialog.tscn index cb4811da9..0207c51d7 100644 --- a/src/UI/Timeline/FrameTagDialog.tscn +++ b/src/UI/Timeline/FrameTagDialog.tscn @@ -1,7 +1,8 @@ -[gd_scene load_steps=3 format=3 uid="uid://c6je8lgr850wf"] +[gd_scene load_steps=4 format=3 uid="uid://c6je8lgr850wf"] [ext_resource type="Script" path="res://src/UI/Timeline/FrameTagDialog.gd" id="1"] [ext_resource type="Texture2D" uid="uid://d1urikaf1lxwl" path="res://assets/graphics/timeline/new_frame.png" id="2"] +[ext_resource type="PackedScene" uid="uid://c6fyrnyt3663o" path="res://src/UI/Timeline/TagOptions.tscn" id="3_hw52m"] [node name="FrameTagDialog" type="AcceptDialog"] title = "Frame Tag Properties" @@ -62,81 +63,10 @@ mouse_default_cursor_shape = 2 button_pressed = true text = "Animation plays only on frames of the same tag" -[node name="TagOptions" type="ConfirmationDialog" parent="."] -size = Vector2i(303, 240) -exclusive = false -popup_window = true - -[node name="GridContainer" type="GridContainer" parent="TagOptions"] -offset_left = 8.0 -offset_top = 8.0 -offset_right = 295.0 -offset_bottom = 191.0 -theme_override_constants/h_separation = 8 -theme_override_constants/v_separation = 8 -columns = 2 - -[node name="NameLabel" type="Label" parent="TagOptions/GridContainer"] -layout_mode = 2 -size_flags_horizontal = 3 -text = "Name:" - -[node name="NameLineEdit" type="LineEdit" parent="TagOptions/GridContainer"] -layout_mode = 2 -size_flags_horizontal = 3 -caret_blink = true -caret_blink_interval = 0.5 - -[node name="ColorLabel" type="Label" parent="TagOptions/GridContainer"] -layout_mode = 2 -size_flags_horizontal = 3 -text = "Color:" - -[node name="ColorPickerButton" type="ColorPickerButton" parent="TagOptions/GridContainer"] -layout_mode = 2 -size_flags_horizontal = 3 -mouse_default_cursor_shape = 2 -color = Color(1, 0, 0, 1) - -[node name="FromLabel" type="Label" parent="TagOptions/GridContainer"] -layout_mode = 2 -size_flags_horizontal = 3 -text = "From:" - -[node name="FromSpinBox" type="SpinBox" parent="TagOptions/GridContainer"] -layout_mode = 2 -size_flags_horizontal = 3 -mouse_default_cursor_shape = 2 -min_value = 1.0 -value = 1.0 -allow_greater = true - -[node name="ToLabel" type="Label" parent="TagOptions/GridContainer"] -layout_mode = 2 -size_flags_horizontal = 3 -text = "To:" - -[node name="ToSpinBox" type="SpinBox" parent="TagOptions/GridContainer"] -layout_mode = 2 -size_flags_horizontal = 3 -mouse_default_cursor_shape = 2 -min_value = 1.0 -value = 1.0 -allow_greater = true - -[node name="UserDataLabel" type="Label" parent="TagOptions/GridContainer"] -layout_mode = 2 -size_flags_vertical = 0 -text = "User data:" - -[node name="UserDataTextEdit" type="TextEdit" parent="TagOptions/GridContainer"] -layout_mode = 2 -scroll_fit_content_height = true +[node name="TagOptions" parent="." instance=ExtResource("3_hw52m")] [connection signal="about_to_popup" from="." to="." method="_on_FrameTagDialog_about_to_show"] [connection signal="visibility_changed" from="." to="." method="_on_FrameTagDialog_visibility_changed"] [connection signal="pressed" from="VBoxContainer/ScrollContainer/VBoxTagContainer/AddTag" to="." method="_on_AddTag_pressed"] [connection signal="toggled" from="VBoxContainer/PlayOnlyTags" to="." method="_on_PlayOnlyTags_toggled"] -[connection signal="confirmed" from="TagOptions" to="." method="_on_TagOptions_confirmed"] -[connection signal="custom_action" from="TagOptions" to="." method="_on_TagOptions_custom_action"] -[connection signal="visibility_changed" from="TagOptions" to="." method="_on_TagOptions_visibility_changed"] +[connection signal="visibility_changed" from="TagOptions" to="." method="_on_tag_options_visibility_changed"] diff --git a/src/UI/Timeline/TagOptions.gd b/src/UI/Timeline/TagOptions.gd new file mode 100644 index 000000000..21aa3b923 --- /dev/null +++ b/src/UI/Timeline/TagOptions.gd @@ -0,0 +1,103 @@ +extends ConfirmationDialog + +var current_tag_id := 0 +@onready var delete_tag_button := add_button("Delete", true, "delete_tag") +@onready var name_line_edit := $GridContainer/NameLineEdit as LineEdit +@onready var color_picker_button := $GridContainer/ColorPickerButton as ColorPickerButton +@onready var from_spinbox := $GridContainer/FromSpinBox as SpinBox +@onready var to_spinbox := $GridContainer/ToSpinBox as SpinBox +@onready var user_data_text_edit := $GridContainer/UserDataTextEdit as TextEdit + + +func _ready() -> void: + color_picker_button.get_picker().presets_visible = false + + +func show_dialog( + popup_rect: Rect2i, tag_id: int, is_editing: bool, selected_frames := PackedInt32Array() +) -> void: + current_tag_id = tag_id + if is_editing: + var animation_tag := Global.current_project.animation_tags[tag_id] + name_line_edit.text = animation_tag.name + color_picker_button.color = animation_tag.color + from_spinbox.value = animation_tag.from + to_spinbox.value = animation_tag.to + user_data_text_edit.text = animation_tag.user_data + delete_tag_button.visible = true + else: + from_spinbox.value = (selected_frames[0] + 1) + to_spinbox.value = (selected_frames[-1] + 1) + color_picker_button.color = Color(randf(), randf(), randf()) + user_data_text_edit.text = "" + delete_tag_button.visible = false + popup(popup_rect) + + +func _on_confirmed() -> void: + var tag_name := name_line_edit.text + var tag_color := color_picker_button.color + var tag_from := from_spinbox.value + var tag_to := to_spinbox.value + var user_data := user_data_text_edit.text + + if tag_to > Global.current_project.frames.size(): + tag_to = Global.current_project.frames.size() + + if tag_from > tag_to: + tag_from = tag_to + + var new_animation_tags := Global.current_project.animation_tags.duplicate() + # Loop through the tags to create new classes for them, so that they won't be the same + # as Global.current_project.animation_tags's classes. Needed for undo/redo to work properly. + for i in new_animation_tags.size(): + var prev_tag: AnimationTag = new_animation_tags[i] + new_animation_tags[i] = AnimationTag.new( + prev_tag.name, prev_tag.color, prev_tag.from, prev_tag.to + ) + new_animation_tags[i].user_data = prev_tag.user_data + + if current_tag_id == Global.current_project.animation_tags.size(): + var new_tag := AnimationTag.new(tag_name, tag_color, tag_from, tag_to) + new_tag.user_data = user_data + new_animation_tags.append(new_tag) + else: + new_animation_tags[current_tag_id].name = tag_name + new_animation_tags[current_tag_id].color = tag_color + new_animation_tags[current_tag_id].from = tag_from + new_animation_tags[current_tag_id].to = tag_to + new_animation_tags[current_tag_id].user_data = user_data + + # Handle Undo/Redo + Global.current_project.undos += 1 + Global.current_project.undo_redo.create_action("Modify Frame Tag") + Global.current_project.undo_redo.add_do_method(Global.general_redo) + Global.current_project.undo_redo.add_undo_method(Global.general_undo) + Global.current_project.undo_redo.add_do_property( + Global.current_project, "animation_tags", new_animation_tags + ) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "animation_tags", Global.current_project.animation_tags + ) + Global.current_project.undo_redo.commit_action() + + +func _on_custom_action(action: String) -> void: + if action != "delete_tag": + return + var new_animation_tags := Global.current_project.animation_tags.duplicate() + new_animation_tags.remove_at(current_tag_id) + # Handle Undo/Redo + Global.current_project.undos += 1 + Global.current_project.undo_redo.create_action("Delete Frame Tag") + Global.current_project.undo_redo.add_do_method(Global.general_redo) + Global.current_project.undo_redo.add_undo_method(Global.general_undo) + Global.current_project.undo_redo.add_do_property( + Global.current_project, "animation_tags", new_animation_tags + ) + Global.current_project.undo_redo.add_undo_property( + Global.current_project, "animation_tags", Global.current_project.animation_tags + ) + Global.current_project.undo_redo.commit_action() + + hide() diff --git a/src/UI/Timeline/TagOptions.tscn b/src/UI/Timeline/TagOptions.tscn new file mode 100644 index 000000000..afb6b4162 --- /dev/null +++ b/src/UI/Timeline/TagOptions.tscn @@ -0,0 +1,78 @@ +[gd_scene load_steps=2 format=3 uid="uid://c6fyrnyt3663o"] + +[ext_resource type="Script" path="res://src/UI/Timeline/TagOptions.gd" id="1_wbmaq"] + +[node name="TagOptions" type="ConfirmationDialog"] +size = Vector2i(303, 240) +exclusive = false +popup_window = true +script = ExtResource("1_wbmaq") + +[node name="GridContainer" type="GridContainer" parent="."] +offset_left = 8.0 +offset_top = 8.0 +offset_right = 295.0 +offset_bottom = 191.0 +theme_override_constants/h_separation = 8 +theme_override_constants/v_separation = 8 +columns = 2 + +[node name="NameLabel" type="Label" parent="GridContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Name:" + +[node name="NameLineEdit" type="LineEdit" parent="GridContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +caret_blink = true +caret_blink_interval = 0.5 + +[node name="ColorLabel" type="Label" parent="GridContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Color:" + +[node name="ColorPickerButton" type="ColorPickerButton" parent="GridContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +mouse_default_cursor_shape = 2 +color = Color(1, 0, 0, 1) + +[node name="FromLabel" type="Label" parent="GridContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "From:" + +[node name="FromSpinBox" type="SpinBox" parent="GridContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +mouse_default_cursor_shape = 2 +min_value = 1.0 +value = 1.0 +allow_greater = true + +[node name="ToLabel" type="Label" parent="GridContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "To:" + +[node name="ToSpinBox" type="SpinBox" parent="GridContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +mouse_default_cursor_shape = 2 +min_value = 1.0 +value = 1.0 +allow_greater = true + +[node name="UserDataLabel" type="Label" parent="GridContainer"] +layout_mode = 2 +size_flags_vertical = 0 +text = "User data:" + +[node name="UserDataTextEdit" type="TextEdit" parent="GridContainer"] +layout_mode = 2 +scroll_fit_content_height = true + +[connection signal="confirmed" from="." to="." method="_on_confirmed"] +[connection signal="custom_action" from="." to="." method="_on_custom_action"]