UndoRedo for border moving

Nothing else in the selections system works properly in UndoRedo right now. Needs:

- UR support for creating selections
- UR support for modifying selections (merging and cutting selections together)
- UR support for removing selection
- UR support for moving content

& for all the rest of the remaining features
This commit is contained in:
Manolis Papadeas 2021-02-25 01:38:00 +02:00
parent 4574c9b60d
commit 76575a1c80
4 changed files with 110 additions and 77 deletions

View file

@ -10,7 +10,6 @@ func draw_start(position : Vector2) -> void:
offset = position
if Global.current_project.selected_pixels:
Global.canvas.selection.move_content_start()
# Global.selection_rectangl.move_start(true)
func draw_move(position : Vector2) -> void:

View file

@ -33,6 +33,7 @@ func draw_start(position : Vector2) -> void:
_move = true
_offset = position
start_position = position
Global.canvas.selection.move_borders_start()
_set_cursor_text(selection.get_rect())
# if Global.selection_rectangle.has_point(position):
# _move = true

View file

@ -7,8 +7,8 @@ var local_selected_pixels := [] setget _local_selected_pixels_changed # Array of
var local_image := Image.new()
var local_image_texture := ImageTexture.new()
var clear_selection_on_tree_exit := true
var temp_polygon : PoolVector2Array setget _temp_polygon_changed
var _selected_rect := Rect2(0, 0, 0, 0)
var _clipped_rect := Rect2(0, 0, 0, 0)
var _move_image := Image.new()
var _move_texture := ImageTexture.new()
var _clear_image := Image.new()
@ -152,6 +152,11 @@ func _local_selected_pixels_changed(value : Array) -> void:
# Global.canvas.get_node("Selection").generate_polygons()
func _temp_polygon_changed(value : PoolVector2Array) -> void:
temp_polygon = value
polygon = temp_polygon
func has_point(position : Vector2) -> bool:
return Geometry.is_point_in_polygon(position, polygon)
@ -311,80 +316,51 @@ func copy() -> void:
project.brushes.append(brush)
Brushes.add_project_brush(brush)
func cut() -> void: # This is basically the same as copy + delete
if _selected_rect.has_no_area():
return
var undo_data = _get_undo_data(true)
var project := Global.current_project
var image : Image = project.frames[project.current_frame].cels[project.current_layer].image
var size := _selected_rect.size
var rect = Rect2(Vector2.ZERO, size)
_clipboard = image.get_rect(_selected_rect)
if _clipboard.is_invisible():
return
_clear_image.resize(size.x, size.y, Image.INTERPOLATE_NEAREST)
var brush = _clipboard.get_rect(_clipboard.get_used_rect())
project.brushes.append(brush)
Brushes.add_project_brush(brush)
# move_end() # The selection_rectangle can be used while is moving, this prevents malfunctioning
image.blit_rect(_clear_image, rect, _selected_rect.position)
commit_undo("Draw", undo_data)
func paste() -> void:
if _clipboard.get_size() <= Vector2.ZERO:
return
var undo_data = _get_undo_data(true)
var project := Global.current_project
var image : Image = project.frames[project.current_frame].cels[project.current_layer].image
var size := _selected_rect.size
var rect = Rect2(Vector2.ZERO, size)
image.blend_rect(_clipboard, rect, _selected_rect.position)
# move_end() # The selection_rectangle can be used while is moving, this prevents malfunctioning
commit_undo("Draw", undo_data)
func delete() -> void:
var undo_data = _get_undo_data(true)
var project := Global.current_project
var image : Image = project.frames[project.current_frame].cels[project.current_layer].image
var size := _selected_rect.size
var rect = Rect2(Vector2.ZERO, size)
_clear_image.resize(size.x, size.y, Image.INTERPOLATE_NEAREST)
image.blit_rect(_clear_image, rect, _selected_rect.position)
# move_end() # The selection_rectangle can be used while is moving, this prevents malfunctioning
commit_undo("Draw", undo_data)
func commit_undo(action : String, undo_data : Dictionary) -> void:
var redo_data = _get_undo_data("image_data" in undo_data)
var project := Global.current_project
project.undos += 1
project.undo_redo.create_action(action)
project.undo_redo.add_do_property(project, "selected_rect", redo_data["selected_rect"])
project.undo_redo.add_undo_property(project, "selected_rect", undo_data["selected_rect"])
if "image_data" in undo_data:
var image : Image = project.frames[project.current_frame].cels[project.current_layer].image
project.undo_redo.add_do_property(image, "data", redo_data["image_data"])
project.undo_redo.add_undo_property(image, "data", undo_data["image_data"])
project.undo_redo.add_do_method(Global, "redo", project.current_frame, project.current_layer)
project.undo_redo.add_undo_method(Global, "undo", project.current_frame, project.current_layer)
project.undo_redo.commit_action()
func _get_undo_data(undo_image : bool) -> Dictionary:
var data = {}
var project := Global.current_project
data["selected_rect"] = Global.current_project.selected_rect
if undo_image:
var image : Image = project.frames[project.current_frame].cels[project.current_layer].image
image.unlock()
data["image_data"] = image.data
image.lock()
return data
#func cut() -> void: # This is basically the same as copy + delete
# if _selected_rect.has_no_area():
# return
#
# var undo_data = _get_undo_data(true)
# var project := Global.current_project
# var image : Image = project.frames[project.current_frame].cels[project.current_layer].image
# var size := _selected_rect.size
# var rect = Rect2(Vector2.ZERO, size)
# _clipboard = image.get_rect(_selected_rect)
# if _clipboard.is_invisible():
# return
#
# _clear_image.resize(size.x, size.y, Image.INTERPOLATE_NEAREST)
# var brush = _clipboard.get_rect(_clipboard.get_used_rect())
# project.brushes.append(brush)
# Brushes.add_project_brush(brush)
## move_end() # The selection_rectangle can be used while is moving, this prevents malfunctioning
# image.blit_rect(_clear_image, rect, _selected_rect.position)
# commit_undo("Draw", undo_data)
#
#func paste() -> void:
# if _clipboard.get_size() <= Vector2.ZERO:
# return
#
# var undo_data = _get_undo_data(true)
# var project := Global.current_project
# var image : Image = project.frames[project.current_frame].cels[project.current_layer].image
# var size := _selected_rect.size
# var rect = Rect2(Vector2.ZERO, size)
# image.blend_rect(_clipboard, rect, _selected_rect.position)
## move_end() # The selection_rectangle can be used while is moving, this prevents malfunctioning
# commit_undo("Draw", undo_data)
#
#
#func delete() -> void:
# var undo_data = _get_undo_data(true)
# var project := Global.current_project
# var image : Image = project.frames[project.current_frame].cels[project.current_layer].image
# var size := _selected_rect.size
# var rect = Rect2(Vector2.ZERO, size)
# _clear_image.resize(size.x, size.y, Image.INTERPOLATE_NEAREST)
# image.blit_rect(_clear_image, rect, _selected_rect.position)
## move_end() # The selection_rectangle can be used while is moving, this prevents malfunctioning
# commit_undo("Draw", undo_data)
func _on_SelectionShape_tree_exiting() -> void:

View file

@ -9,25 +9,37 @@ extends Node2D
# var selected_pixels := [] # Array of Vector2s - the selected pixels
func move_borders_start() -> void:
for shape in get_children():
shape.temp_polygon = shape.polygon
func move_borders(move : Vector2) -> void:
for shape in get_children():
shape._selected_rect.position += move
shape._clipped_rect.position += move
for i in shape.polygon.size():
shape.polygon[i] += move
func move_borders_end(new_pos : Vector2, old_pos : Vector2) -> void:
# for shape in get_children():
# var diff := new_pos - old_pos
# for i in shape.polygon.size():
# shape.polygon[i] -= diff # Temporarily set the polygon back to be used for undoredo
var undo_data = _get_undo_data(false)
for shape in get_children():
shape.temp_polygon = shape.polygon
var diff := new_pos - old_pos
var selected_pixels_copy = shape.local_selected_pixels.duplicate()
for i in selected_pixels_copy.size():
selected_pixels_copy[i] += diff
shape.local_selected_pixels = selected_pixels_copy
commit_undo("Rectangle Select", undo_data)
func move_content_start() -> void:
move_borders_start()
for shape in get_children():
if !shape.local_image.is_empty():
return
@ -52,6 +64,51 @@ func move_content_end() -> void:
shape.local_image_texture = ImageTexture.new()
func commit_undo(action : String, undo_data : Dictionary) -> void:
var redo_data = _get_undo_data("image_data" in undo_data)
var project := Global.current_project
project.undos += 1
project.undo_redo.create_action(action)
var i := 0
for shape in get_children():
project.undo_redo.add_do_property(shape, "temp_polygon", redo_data["temp_polygon_%s" % i])
project.undo_redo.add_do_property(shape, "_selected_rect", redo_data["_selected_rect_%s" % i])
project.undo_redo.add_do_property(shape, "local_selected_pixels", redo_data["local_selected_pixels_%s" % i])
project.undo_redo.add_undo_property(shape, "temp_polygon", undo_data["temp_polygon_%s" % i])
project.undo_redo.add_undo_property(shape, "_selected_rect", undo_data["_selected_rect_%s" % i])
project.undo_redo.add_undo_property(shape, "local_selected_pixels", undo_data["local_selected_pixels_%s" % i])
i += 1
if "image_data" in undo_data:
var image : Image = project.frames[project.current_frame].cels[project.current_layer].image
project.undo_redo.add_do_property(image, "data", redo_data["image_data"])
project.undo_redo.add_undo_property(image, "data", undo_data["image_data"])
project.undo_redo.add_do_method(Global, "redo", project.current_frame, project.current_layer)
project.undo_redo.add_undo_method(Global, "undo", project.current_frame, project.current_layer)
project.undo_redo.commit_action()
func _get_undo_data(undo_image : bool) -> Dictionary:
var data = {}
var project := Global.current_project
var i := 0
for shape in get_children():
data["temp_polygon_%s" % i] = shape.temp_polygon
data["_selected_rect_%s" % i] = shape._selected_rect
data["local_selected_pixels_%s" % i] = shape.local_selected_pixels
i += 1
# data["selected_rect"] = Global.current_project.selected_rect
if undo_image:
var image : Image = project.frames[project.current_frame].cels[project.current_layer].image
image.unlock()
data["image_data"] = image.data
image.lock()
for d in data.keys():
print(d, data[d])
return data
func generate_rect(pixels : Array) -> Rect2:
if !pixels:
return Rect2()