From d17a151f8d595ee38f1253dab7f2cf476e9fb715 Mon Sep 17 00:00:00 2001 From: Emmanouil Papadeas Date: Thu, 7 Mar 2024 01:06:46 +0200 Subject: [PATCH] Delete and change properties of multiple cels at once --- src/UI/Timeline/CelButton.gd | 45 ++++++++++++++++++++-------- src/UI/Timeline/CelProperties.gd | 34 ++++++++++++++++----- src/UI/Timeline/CelProperties.tscn | 22 ++++++++++++-- src/UI/Timeline/FrameProperties.gd | 4 +-- src/UI/Timeline/FrameProperties.tscn | 24 +++++---------- 5 files changed, 87 insertions(+), 42 deletions(-) diff --git a/src/UI/Timeline/CelButton.gd b/src/UI/Timeline/CelButton.gd index fe0cd1e84..07cafe1e4 100644 --- a/src/UI/Timeline/CelButton.gd +++ b/src/UI/Timeline/CelButton.gd @@ -119,7 +119,7 @@ func _on_CelButton_pressed() -> void: func _on_PopupMenu_id_pressed(id: int) -> void: match id: MenuOptions.PROPERTIES: - properties.cel = cel + properties.cel_indices = _get_cel_indices() properties.popup_centered() MenuOptions.DELETE: _delete_cel_content() @@ -128,7 +128,7 @@ func _on_PopupMenu_id_pressed(id: int) -> void: var project := Global.current_project if id == MenuOptions.UNLINK: project.undo_redo.create_action("Unlink Cel") - var selected_cels := project.selected_cels.duplicate() + var selected_cels := _get_cel_indices(true) if not selected_cels.has([frame, layer]): selected_cels.append([frame, layer]) # Include this cel with the selected ones for cel_index in selected_cels: @@ -206,20 +206,29 @@ func _on_PopupMenu_id_pressed(id: int) -> void: func _delete_cel_content() -> void: + var indices := _get_cel_indices() var project := Global.current_project - var empty_content = cel.create_empty_content() - var old_content = cel.get_content() project.undos += 1 project.undo_redo.create_action("Draw") - if cel.link_set == null: - project.undo_redo.add_do_method(cel.set_content.bind(empty_content)) - project.undo_redo.add_undo_method(cel.set_content.bind(old_content)) - else: - for linked_cel in cel.link_set["cels"]: - project.undo_redo.add_do_method(linked_cel.set_content.bind(empty_content)) - project.undo_redo.add_undo_method(linked_cel.set_content.bind(old_content)) - project.undo_redo.add_do_method(Global.undo_or_redo.bind(false, frame, layer, project)) - project.undo_redo.add_undo_method(Global.undo_or_redo.bind(true, frame, layer, project)) + for cel_index in indices: + var frame_index: int = cel_index[0] + var layer_index: int = cel_index[1] + var selected_cel := project.frames[frame_index].cels[layer_index] + var empty_content = selected_cel.create_empty_content() + var old_content = selected_cel.get_content() + if selected_cel.link_set == null: + project.undo_redo.add_do_method(selected_cel.set_content.bind(empty_content)) + project.undo_redo.add_undo_method(selected_cel.set_content.bind(old_content)) + else: + for linked_cel in selected_cel.link_set["cels"]: + project.undo_redo.add_do_method(linked_cel.set_content.bind(empty_content)) + project.undo_redo.add_undo_method(linked_cel.set_content.bind(old_content)) + project.undo_redo.add_do_method( + Global.undo_or_redo.bind(false, frame_index, layer_index, project) + ) + project.undo_redo.add_undo_method( + Global.undo_or_redo.bind(true, frame_index, layer_index, project) + ) project.undo_redo.commit_action() @@ -317,3 +326,13 @@ func _get_region_rect(x_begin: float, x_end: float) -> Rect2: rect.position.x += rect.size.x * x_begin rect.size.x *= x_end - x_begin return rect + + +func _get_cel_indices(add_current_cel := false) -> Array: + var indices := Global.current_project.selected_cels.duplicate() + if not [frame, layer] in indices: + if add_current_cel: + indices.append([frame, layer]) + else: + indices = [[frame, layer]] + return indices diff --git a/src/UI/Timeline/CelProperties.gd b/src/UI/Timeline/CelProperties.gd index 6d09c7f58..b3fbe5236 100644 --- a/src/UI/Timeline/CelProperties.gd +++ b/src/UI/Timeline/CelProperties.gd @@ -1,31 +1,49 @@ extends AcceptDialog -var cel: BaseCel +var cel_indices: Array +@onready var frame_num := $GridContainer/FrameNum as Label +@onready var layer_num := $GridContainer/LayerNum as Label @onready var opacity_slider := $GridContainer/OpacitySlider as ValueSlider @onready var z_index_slider := $GridContainer/ZIndexSlider as ValueSlider func _on_visibility_changed() -> void: + if cel_indices.size() == 0: + return Global.dialog_open(visible) + var first_cel := Global.current_project.frames[cel_indices[0][0]].cels[cel_indices[0][1]] if visible: - opacity_slider.value = cel.opacity * 100.0 - z_index_slider.value = cel.z_index + if cel_indices.size() == 1: + var layer := Global.current_project.layers[cel_indices[0][1]] + frame_num.text = str(cel_indices[0][0] + 1) + layer_num.text = layer.name + else: + var first_layer := Global.current_project.layers[cel_indices[0][1]] + var last_layer := Global.current_project.layers[cel_indices[-1][1]] + frame_num.text = "[%s...%s]" % [cel_indices[0][0] + 1, cel_indices[-1][0] + 1] + layer_num.text = "[%s...%s]" % [first_layer.name, last_layer.name] + opacity_slider.value = first_cel.opacity * 100.0 + z_index_slider.value = first_cel.z_index else: - cel = null + cel_indices = [] func _on_opacity_slider_value_changed(value: float) -> void: - if not is_instance_valid(cel): + if cel_indices.size() == 0: return - cel.opacity = value / 100.0 + for cel_index in cel_indices: + var cel := Global.current_project.frames[cel_index[0]].cels[cel_index[1]] + cel.opacity = value / 100.0 Global.canvas.queue_redraw() func _on_z_index_slider_value_changed(value: float) -> void: - if not is_instance_valid(cel): + if cel_indices.size() == 0: return - cel.z_index = value + for cel_index in cel_indices: + var cel := Global.current_project.frames[cel_index[0]].cels[cel_index[1]] + cel.z_index = value Global.current_project.order_layers() Global.canvas.update_all_layers = true Global.canvas.queue_redraw() diff --git a/src/UI/Timeline/CelProperties.tscn b/src/UI/Timeline/CelProperties.tscn index 083b80a71..2ed73ab78 100644 --- a/src/UI/Timeline/CelProperties.tscn +++ b/src/UI/Timeline/CelProperties.tscn @@ -5,7 +5,7 @@ [node name="CelProperties" type="AcceptDialog"] title = "Cel properties" -size = Vector2i(300, 111) +size = Vector2i(300, 161) exclusive = false popup_window = true script = ExtResource("1_lyy7i") @@ -14,9 +14,27 @@ script = ExtResource("1_lyy7i") offset_left = 8.0 offset_top = 8.0 offset_right = 292.0 -offset_bottom = 66.0 +offset_bottom = 112.0 columns = 2 +[node name="Frame" type="Label" parent="GridContainer"] +layout_mode = 2 +text = "Frame" + +[node name="FrameNum" type="Label" parent="GridContainer"] +layout_mode = 2 +text = "1" +horizontal_alignment = 1 + +[node name="Layer" type="Label" parent="GridContainer"] +layout_mode = 2 +text = "Layer" + +[node name="LayerNum" type="Label" parent="GridContainer"] +layout_mode = 2 +text = "1" +horizontal_alignment = 1 + [node name="OpacityLabel" type="Label" parent="GridContainer"] layout_mode = 2 size_flags_horizontal = 3 diff --git a/src/UI/Timeline/FrameProperties.gd b/src/UI/Timeline/FrameProperties.gd index a91967685..b28428bb3 100644 --- a/src/UI/Timeline/FrameProperties.gd +++ b/src/UI/Timeline/FrameProperties.gd @@ -1,8 +1,8 @@ extends ConfirmationDialog var frame_indices := [] -@onready var frame_num = $VBoxContainer/GridContainer/FrameNum -@onready var frame_dur = $VBoxContainer/GridContainer/FrameTime +@onready var frame_num = $GridContainer/FrameNum +@onready var frame_dur = $GridContainer/FrameTime func _on_FrameProperties_about_to_show() -> void: diff --git a/src/UI/Timeline/FrameProperties.tscn b/src/UI/Timeline/FrameProperties.tscn index 413efe690..7b70d8ecf 100644 --- a/src/UI/Timeline/FrameProperties.tscn +++ b/src/UI/Timeline/FrameProperties.tscn @@ -4,41 +4,31 @@ [node name="FrameProperties" type="ConfirmationDialog"] title = "Frame properties" -size = Vector2i(224, 156) +size = Vector2i(224, 115) exclusive = false popup_window = true script = ExtResource("1") -[node name="VBoxContainer" type="VBoxContainer" parent="."] +[node name="GridContainer" type="GridContainer" parent="."] offset_left = 8.0 offset_top = 8.0 offset_right = 216.0 -offset_bottom = 107.0 - -[node name="Label" type="Label" parent="VBoxContainer"] -layout_mode = 2 -text = "Frame properties" - -[node name="HSeparator" type="HSeparator" parent="VBoxContainer"] -layout_mode = 2 - -[node name="GridContainer" type="GridContainer" parent="VBoxContainer"] -layout_mode = 2 +offset_bottom = 66.0 columns = 2 -[node name="Frame" type="Label" parent="VBoxContainer/GridContainer"] +[node name="Frame" type="Label" parent="GridContainer"] layout_mode = 2 text = "Frame" -[node name="FrameNum" type="Label" parent="VBoxContainer/GridContainer"] +[node name="FrameNum" type="Label" parent="GridContainer"] layout_mode = 2 text = "1" -[node name="FrameDuration" type="Label" parent="VBoxContainer/GridContainer"] +[node name="FrameDuration" type="Label" parent="GridContainer"] layout_mode = 2 text = "Frame duration" -[node name="FrameTime" type="SpinBox" parent="VBoxContainer/GridContainer"] +[node name="FrameTime" type="SpinBox" parent="GridContainer"] layout_mode = 2 size_flags_horizontal = 3 mouse_default_cursor_shape = 2