diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cfacd9e5..157a91059 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ Laurenz Reinthaler (Schweini07), kleonc, Variable-ind ### Added - A new pan tool, used to move around the canvas. ([#399](https://github.com/Orama-Interactive/Pixelorama/pull/399)) +- Dragging and dropping individual cels in the timeline to change their position is now possible. - Added a new "Performance" tab in the Preferences that exposes options related to the application's FPS to the user. - Added a new pixel grid, which is a grid of size 1px and it appears after a certain zoom level. ([#427](https://github.com/Orama-Interactive/Pixelorama/pull/427)) - Added offset options to the grid. ([#434](https://github.com/Orama-Interactive/Pixelorama/pull/434)) diff --git a/src/Autoload/Global.gd b/src/Autoload/Global.gd index bc5a2e045..506c89e2e 100644 --- a/src/Autoload/Global.gd +++ b/src/Autoload/Global.gd @@ -358,6 +358,9 @@ func undo(_frame_index := -1, _layer_index := -1, project : Project = current_pr play_backwards.pressed = false animation_timer.stop() + elif "Move Cels" == action_name: + project.frames = project.frames # to call frames_changed + canvas.update() if !project.has_changed: project.has_changed = true @@ -388,6 +391,9 @@ func redo(_frame_index := -1, _layer_index := -1, project : Project = current_pr play_backwards.pressed = false animation_timer.stop() + elif "Move Cels" == action_name: + project.frames = project.frames # to call frames_changed + canvas.update() if !project.has_changed: project.has_changed = true diff --git a/src/UI/Timeline/AnimationTimeline.gd b/src/UI/Timeline/AnimationTimeline.gd index a712372d0..468f996bc 100644 --- a/src/UI/Timeline/AnimationTimeline.gd +++ b/src/UI/Timeline/AnimationTimeline.gd @@ -168,18 +168,21 @@ func _on_CopyFrame_pressed(frame := -1) -> void: func _on_FrameTagButton_pressed() -> void: Global.tag_dialog.popup_centered() + func _on_MoveLeft_pressed() -> void: var frame : int = Global.current_project.current_frame if frame == 0: return Global.current_project.layers[Global.current_project.current_layer].frame_container.get_child(frame).change_frame_order(-1) + func _on_MoveRight_pressed() -> void: var frame : int = Global.current_project.current_frame if frame == last_frame: return Global.current_project.layers[Global.current_project.current_layer].frame_container.get_child(frame).change_frame_order(1) + func _on_OnionSkinning_pressed() -> void: Global.onion_skinning = !Global.onion_skinning Global.canvas.update() @@ -189,6 +192,7 @@ func _on_OnionSkinning_pressed() -> void: else: Global.change_button_texturerect(texture_button, "onion_skinning_off.png") + func _on_OnionSkinningSettings_pressed() -> void: $OnionSkinningSettings.popup(Rect2(Global.onion_skinning_button.rect_global_position.x - $OnionSkinningSettings.rect_size.x - 16, Global.onion_skinning_button.rect_global_position.y - 106, 136, 126)) diff --git a/src/UI/Timeline/CelButton.gd b/src/UI/Timeline/CelButton.gd index 0510e9a31..a8373642f 100644 --- a/src/UI/Timeline/CelButton.gd +++ b/src/UI/Timeline/CelButton.gd @@ -107,6 +107,7 @@ func _on_PopupMenu_id_pressed(ID : int) -> void: Global.frame_properties.set_frame_label(frame) Global.frame_properties.set_frame_dur(Global.current_project.frames[frame].duration) + func change_frame_order(rate : int) -> void: var change = frame + rate var new_frames : Array = Global.current_project.frames.duplicate() @@ -126,3 +127,63 @@ func change_frame_order(rate : int) -> void: Global.current_project.undo_redo.add_undo_method(Global, "undo") Global.current_project.undo_redo.add_do_method(Global, "redo") Global.current_project.undo_redo.commit_action() + + +func get_drag_data(_position) -> Array: + var button := Button.new() + button.rect_size = rect_size + button.theme = Global.control.theme + var texture_rect := TextureRect.new() + texture_rect.rect_size = $CelTexture.rect_size + texture_rect.rect_position = $CelTexture.rect_position + texture_rect.expand = true + texture_rect.texture = $CelTexture.texture + button.add_child(texture_rect) + set_drag_preview(button) + + return [frame, layer] + + +func can_drop_data(_pos, data) -> bool: + if typeof(data) == TYPE_ARRAY: + var new_frame = data[0] + var new_layer = data[1] + if Global.current_project.frames[frame] in Global.current_project.layers[layer].linked_cels or Global.current_project.frames[new_frame] in Global.current_project.layers[new_layer].linked_cels: + # If the cel we're dragging or the cel we are targeting are linked, don't allow dragging + return false + else: + return true + else: + return false + + +func drop_data(_pos, data) -> void: + var new_frame = data[0] + var new_layer = data[1] + + var this_frame_new_cels = Global.current_project.frames[frame].cels.duplicate() + var new_frame_new_cels + var temp = this_frame_new_cels[layer] + this_frame_new_cels[layer] = Global.current_project.frames[new_frame].cels[new_layer] + if frame == new_frame: + this_frame_new_cels[new_layer] = temp + else: + new_frame_new_cels = Global.current_project.frames[new_frame].cels.duplicate() + new_frame_new_cels[new_layer] = temp + + Global.current_project.undo_redo.create_action("Move Cels") + Global.current_project.undo_redo.add_do_property(Global.current_project.frames[frame], "cels", this_frame_new_cels) + + if frame != new_frame: # If the cel moved to a different frame + Global.current_project.undo_redo.add_do_property(Global.current_project.frames[new_frame], "cels", new_frame_new_cels) + + Global.current_project.undo_redo.add_do_property(Global.current_project, "current_frame", frame) + Global.current_project.undo_redo.add_undo_property(Global.current_project, "current_frame", Global.current_project.current_frame) + + Global.current_project.undo_redo.add_undo_property(Global.current_project.frames[new_frame], "cels", Global.current_project.frames[new_frame].cels) + + Global.current_project.undo_redo.add_undo_property(Global.current_project.frames[frame], "cels", Global.current_project.frames[frame].cels) + + Global.current_project.undo_redo.add_undo_method(Global, "undo") + Global.current_project.undo_redo.add_do_method(Global, "redo") + Global.current_project.undo_redo.commit_action()