From 650c8b7f4e5cb6865152a1b75706b31252d1e6e7 Mon Sep 17 00:00:00 2001 From: Emmanouil Papadeas <35376950+OverloadedOrama@users.noreply.github.com> Date: Fri, 5 Apr 2024 18:14:28 +0300 Subject: [PATCH] Store image data in undo/redo of the move tool This fixes an issue where, if the user moves pixels outside the canvas and then undos, those cut pixels will not be restored. --- src/Autoload/Global.gd | 10 ---------- src/Tools/Move.gd | 41 +++++++++++++++++++++++++++++++++++------ 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/Autoload/Global.gd b/src/Autoload/Global.gd index 49dda0f43..9c9fb0061 100644 --- a/src/Autoload/Global.gd +++ b/src/Autoload/Global.gd @@ -651,13 +651,3 @@ func undo_redo_draw_op( var decompressed := compressed_image_data.decompress(buffer_size) image.crop(new_size.x, new_size.y) image.data["data"] = decompressed - - -## Used by the Move tool for undo/redo, moves all of the Images in the images array -## by diff pixels. -func undo_redo_move(diff: Vector2, images: Array) -> void: - for image in images: - var image_copy := Image.new() - image_copy.copy_from(image) - image.fill(Color(0, 0, 0, 0)) - image.blit_rect(image_copy, Rect2(Vector2.ZERO, image.get_size()), diff) diff --git a/src/Tools/Move.gd b/src/Tools/Move.gd index 1e8e80ab8..e64a993ef 100644 --- a/src/Tools/Move.gd +++ b/src/Tools/Move.gd @@ -2,11 +2,11 @@ extends BaseTool var _start_pos: Vector2 var _offset: Vector2 - # Used to check if the state of content transformation has been changed # while draw_move() is being called. For example, pressing Enter while still moving content var _content_transformation_check := false var _snap_to_grid := false # Mouse Click + Ctrl +var _undo_data := {} onready var selection_node: Node2D = Global.canvas.selection @@ -41,6 +41,7 @@ func draw_start(position: Vector2) -> void: return _start_pos = position _offset = position + _undo_data = _get_undo_data() if Global.current_project.has_selection: selection_node.transform_content_start() _content_transformation_check = selection_node.is_moving_content @@ -81,7 +82,14 @@ func draw_end(position: Vector2) -> void: else: var pixel_diff: Vector2 = position - _start_pos Global.canvas.move_preview_location = Vector2.ZERO - commit_undo("Draw", pixel_diff) + var images := _get_selected_draw_images() + for image in images: + var image_copy := Image.new() + image_copy.copy_from(image) + image.fill(Color(0, 0, 0, 0)) + image.blit_rect(image_copy, Rect2(Vector2.ZERO, project.size), pixel_diff) + + commit_undo("Draw") _start_pos = Vector2.INF _snap_to_grid = false @@ -114,18 +122,39 @@ func _snap_position(position: Vector2) -> Vector2: return position -func commit_undo(action: String, diff: Vector2) -> void: +func commit_undo(action: String) -> void: + var redo_data := _get_undo_data() var project: Project = Global.current_project var frame := -1 var layer := -1 if Global.animation_timer.is_stopped() and project.selected_cels.size() == 1: frame = project.current_frame layer = project.current_layer - var images := _get_selected_draw_images() + project.undos += 1 project.undo_redo.create_action(action) - project.undo_redo.add_do_method(Global, "undo_redo_move", diff, images) + Global.undo_redo_compress_images(redo_data, _undo_data, project) project.undo_redo.add_do_method(Global, "undo_or_redo", false, frame, layer) - project.undo_redo.add_undo_method(Global, "undo_redo_move", -diff, images) project.undo_redo.add_undo_method(Global, "undo_or_redo", true, frame, layer) project.undo_redo.commit_action() + + +func _get_undo_data() -> Dictionary: + var data := {} + var project: Project = Global.current_project + var cels := [] # Array of Cels + if Global.animation_timer.is_stopped(): + for cel_index in project.selected_cels: + cels.append(project.frames[cel_index[0]].cels[cel_index[1]]) + else: + for frame in project.frames: + var cel: BaseCel = frame.cels[project.current_layer] + cels.append(cel) + for cel in cels: + if not cel is PixelCel: + continue + var image: Image = cel.image + image.unlock() + data[image] = image.data + image.lock() + return data