mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-01-18 17:19:50 +00:00
For the move tool, only store the difference vector in undo/redo
Instead of storing copies of entire images. This is a bit slower on the CPU side, mostly on larger canvases, but it is a massive RAM optimization. Perhaps it could be move optimal to use a shader here.
This commit is contained in:
parent
e62548517f
commit
4f5f37a522
|
@ -856,7 +856,10 @@ func path_join_array(basepaths: PackedStringArray, subpath: String) -> PackedStr
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
func undo_redo_compress_images(redo_data: Dictionary, undo_data: Dictionary, project := current_project) -> void:
|
## Used by undo/redo operations to store compressed images in memory.
|
||||||
|
func undo_redo_compress_images(
|
||||||
|
redo_data: Dictionary, undo_data: Dictionary, project := current_project
|
||||||
|
) -> void:
|
||||||
for image in redo_data:
|
for image in redo_data:
|
||||||
if not image is Image:
|
if not image is Image:
|
||||||
continue
|
continue
|
||||||
|
@ -873,8 +876,8 @@ func undo_redo_compress_images(redo_data: Dictionary, undo_data: Dictionary, pro
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
## Decompresses the [param compressed_image_data] with [params buffer_size] to the [param image]
|
## Decompresses the [param compressed_image_data] with [param buffer_size] to the [param image]
|
||||||
## This is an opmization method used by [param Draw.gd] while performing undo/redo.
|
## This is an optimization method used while performing undo/redo drawing operations.
|
||||||
func undo_redo_draw_op(
|
func undo_redo_draw_op(
|
||||||
image: Image, compressed_image_data: PackedByteArray, buffer_size: int
|
image: Image, compressed_image_data: PackedByteArray, buffer_size: int
|
||||||
) -> void:
|
) -> void:
|
||||||
|
@ -885,3 +888,13 @@ func undo_redo_draw_op(
|
||||||
image.get_format(),
|
image.get_format(),
|
||||||
compressed_image_data.decompress(buffer_size)
|
compressed_image_data.decompress(buffer_size)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
## 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)
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
extends BaseTool
|
extends BaseTool
|
||||||
|
|
||||||
var _undo_data := {}
|
|
||||||
var _start_pos: Vector2i
|
var _start_pos: Vector2i
|
||||||
var _offset: Vector2i
|
var _offset: Vector2i
|
||||||
|
|
||||||
|
@ -41,7 +40,6 @@ 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,14 +80,8 @@ 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()
|
|
||||||
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")
|
_commit_undo("Draw", pixel_diff)
|
||||||
|
|
||||||
_start_pos = Vector2.INF
|
_start_pos = Vector2.INF
|
||||||
_snap_to_grid = false
|
_snap_to_grid = false
|
||||||
|
@ -120,8 +112,7 @@ func _snap_position(pos: Vector2) -> Vector2:
|
||||||
return pos
|
return pos
|
||||||
|
|
||||||
|
|
||||||
func commit_undo(action: String) -> void:
|
func _commit_undo(action: String, diff: Vector2i) -> 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
|
||||||
|
@ -129,33 +120,11 @@ func commit_undo(action: String) -> 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)
|
||||||
for image in redo_data:
|
project.undo_redo.add_do_method(Global.undo_redo_move.bind(diff, images))
|
||||||
project.undo_redo.add_do_property(image, "data", redo_data[image])
|
|
||||||
for image in _undo_data:
|
|
||||||
project.undo_redo.add_undo_property(image, "data", _undo_data[image])
|
|
||||||
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: PixelCel = 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
|
|
||||||
|
|
Loading…
Reference in a new issue