1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-01-31 07:29:49 +00:00

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.
This commit is contained in:
Emmanouil Papadeas 2024-04-05 18:14:28 +03:00
parent 0c6566de76
commit 650c8b7f4e
2 changed files with 35 additions and 16 deletions

View file

@ -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)

View file

@ -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