1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-02-07 10:59:49 +00:00

Store image data in undo/redo of the move tool, reverts 4f5f37a522

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:02:46 +03:00
parent 596c174c92
commit 0ac7789bf9
2 changed files with 35 additions and 18 deletions

View file

@ -1012,6 +1012,8 @@ func set_locale(locale: String) -> void:
## Used by undo/redo operations to store compressed images in memory. ## Used by undo/redo operations to store compressed images in memory.
## [param redo_data] and [param undo_data] are Dictionaries,
## with keys of type [Image] and [Dictionary] values, coming from [member Image.data].
func undo_redo_compress_images( func undo_redo_compress_images(
redo_data: Dictionary, undo_data: Dictionary, project := current_project redo_data: Dictionary, undo_data: Dictionary, project := current_project
) -> void: ) -> void:
@ -1038,7 +1040,7 @@ func undo_redo_compress_images(
## Decompresses the [param compressed_image_data] with [param buffer_size] to the [param image] ## Decompresses the [param compressed_image_data] with [param buffer_size] to the [param image]
## This is an optimization method used while performing undo/redo drawing operations. ## This is a memory optimization method used while performing undo/redo drawing operations.
func undo_redo_draw_op( func undo_redo_draw_op(
image: Image, new_size: Vector2i, compressed_image_data: PackedByteArray, buffer_size: int image: Image, new_size: Vector2i, compressed_image_data: PackedByteArray, buffer_size: int
) -> void: ) -> void:
@ -1046,16 +1048,6 @@ func undo_redo_draw_op(
image.set_data(new_size.x, new_size.y, image.has_mipmaps(), image.get_format(), decompressed) image.set_data(new_size.x, new_size.y, image.has_mipmaps(), image.get_format(), decompressed)
## Used by the Move tool for undo/redo, moves all of the [Image]s in [param images]
## by [param diff] pixels.
func undo_redo_move(diff: Vector2i, images: Array[Image]) -> 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, Rect2i(Vector2i.ZERO, image.get_size()), diff)
func create_ui_for_shader_uniforms( func create_ui_for_shader_uniforms(
shader: Shader, shader: Shader,
params: Dictionary, params: Dictionary,

View file

@ -2,11 +2,11 @@ extends BaseTool
var _start_pos: Vector2i var _start_pos: Vector2i
var _offset: Vector2i var _offset: Vector2i
## Used to check if the state of content transformation has been changed ## 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 ## while draw_move() is being called. For example, pressing Enter while still moving content
var _content_transformation_check := false var _content_transformation_check := false
var _snap_to_grid := false ## Mouse Click + Ctrl var _snap_to_grid := false ## Mouse Click + Ctrl
var _undo_data := {}
@onready var selection_node: Node2D = Global.canvas.selection @onready var selection_node: Node2D = Global.canvas.selection
@ -40,6 +40,7 @@ func draw_start(pos: Vector2i) -> void:
return return
_start_pos = pos _start_pos = pos
_offset = pos _offset = pos
_undo_data = _get_undo_data()
if Global.current_project.has_selection: if Global.current_project.has_selection:
selection_node.transform_content_start() selection_node.transform_content_start()
_content_transformation_check = selection_node.is_moving_content _content_transformation_check = selection_node.is_moving_content
@ -82,8 +83,13 @@ func draw_end(pos: Vector2i) -> void:
else: else:
var pixel_diff := pos - _start_pos var pixel_diff := pos - _start_pos
Global.canvas.move_preview_location = Vector2i.ZERO Global.canvas.move_preview_location = Vector2i.ZERO
var images := _get_selected_draw_images()
_commit_undo("Draw", pixel_diff) 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, Rect2i(Vector2i.ZERO, project.size), pixel_diff)
_commit_undo("Draw")
_start_pos = Vector2.INF _start_pos = Vector2.INF
_snap_to_grid = false _snap_to_grid = false
@ -115,7 +121,8 @@ func _snap_position(pos: Vector2) -> Vector2:
return pos return pos
func _commit_undo(action: String, diff: Vector2i) -> void: func _commit_undo(action: String) -> void:
var redo_data := _get_undo_data()
var project := Global.current_project var project := Global.current_project
var frame := -1 var frame := -1
var layer := -1 var layer := -1
@ -123,11 +130,29 @@ func _commit_undo(action: String, diff: Vector2i) -> void:
frame = project.current_frame frame = project.current_frame
layer = project.current_layer layer = project.current_layer
var images := _get_selected_draw_images()
project.undos += 1 project.undos += 1
project.undo_redo.create_action(action) project.undo_redo.create_action(action)
project.undo_redo.add_do_method(Global.undo_redo_move.bind(diff, images)) Global.undo_redo_compress_images(redo_data, _undo_data, project)
project.undo_redo.add_do_method(Global.undo_or_redo.bind(false, frame, layer)) project.undo_redo.add_do_method(Global.undo_or_redo.bind(false, frame, layer))
project.undo_redo.add_undo_method(Global.undo_redo_move.bind(-diff, images))
project.undo_redo.add_undo_method(Global.undo_or_redo.bind(true, frame, layer)) project.undo_redo.add_undo_method(Global.undo_or_redo.bind(true, frame, layer))
project.undo_redo.commit_action() project.undo_redo.commit_action()
_undo_data.clear()
func _get_undo_data() -> Dictionary:
var data := {}
var project := Global.current_project
var cels: Array[BaseCel] = []
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 := frame.cels[project.current_layer]
cels.append(cel)
for cel in cels:
if not cel is PixelCel:
continue
var image: Image = cel.image
data[image] = image.data
return data