Move selection with contents with the move tool

Code is still a mess, don't bother looking.
This commit is contained in:
Manolis Papadeas 2021-02-22 18:43:39 +02:00
parent a4641a0eb2
commit ac5d492298
3 changed files with 131 additions and 82 deletions

View file

@ -640,14 +640,14 @@ static func sort_by_angle(a, b) -> bool:
return false return false
func get_selection_image() -> Image: #func get_selection_image() -> Image:
var image := Image.new() # var image := Image.new()
var cel_image : Image = frames[current_frame].cels[current_layer].image # var cel_image : Image = frames[current_frame].cels[current_layer].image
image.copy_from(cel_image) # image.copy_from(cel_image)
image.lock() # image.lock()
image.fill(Color(0, 0, 0, 0)) # image.fill(Color(0, 0, 0, 0))
for pixel in selected_pixels: # for pixel in selected_pixels:
var color : Color = cel_image.get_pixelv(pixel) # var color : Color = cel_image.get_pixelv(pixel)
image.set_pixelv(pixel, color) # image.set_pixelv(pixel, color)
image.unlock() # image.unlock()
return image # return image

View file

@ -9,7 +9,8 @@ func draw_start(position : Vector2) -> void:
starting_pos = position starting_pos = position
offset = position offset = position
if Global.current_project.selected_pixels: if Global.current_project.selected_pixels:
pass for selection in Global.current_project.selections:
selection.move_content_start()
# Global.selection_rectangl.move_start(true) # Global.selection_rectangl.move_start(true)
@ -27,34 +28,27 @@ func draw_move(position : Vector2) -> void:
func draw_end(position : Vector2) -> void: func draw_end(position : Vector2) -> void:
if starting_pos != Vector2.INF: if starting_pos != Vector2.INF:
var pixel_diff : Vector2 = position - starting_pos var pixel_diff : Vector2 = position - starting_pos
if pixel_diff != Vector2.ZERO: # if pixel_diff != Vector2.ZERO:
var project : Project = Global.current_project var project : Project = Global.current_project
var image : Image = _get_draw_image() var image : Image = _get_draw_image()
# var pixels := []
# if project.selected_pixels:
# pixels = project.selected_pixels.duplicate()
# else:
# for x in Global.current_project.size.x:
# for y in Global.current_project.size.y:
# var pos := Vector2(x, y)
# pixels.append([pos, image.get_pixelv(pos)])
# print(pixels[3]) if project.selected_pixels:
if project.selected_pixels: pass
for selection in Global.current_project.selections: # for selection in Global.current_project.selections:
selection.select_rect() # selection.move_content_end()
else: # selection.move_polygon_end(position, starting_pos)
Global.canvas.move_preview_location = Vector2.ZERO else:
var image_copy := Image.new() Global.canvas.move_preview_location = Vector2.ZERO
image_copy.copy_from(image) var image_copy := Image.new()
Global.canvas.handle_undo("Draw") image_copy.copy_from(image)
image.fill(Color(0, 0, 0, 0)) Global.canvas.handle_undo("Draw")
# image.blit_rect(image_copy, Rect2(Vector2.ZERO, project.size), pixel_diff) image.fill(Color(0, 0, 0, 0))
image.blit_rect(image_copy, Rect2(Vector2.ZERO, project.size), pixel_diff) # image.blit_rect(image_copy, Rect2(Vector2.ZERO, project.size), pixel_diff)
# for pixel in pixels: image.blit_rect(image_copy, Rect2(Vector2.ZERO, project.size), pixel_diff)
## image.set_pixelv(pixel[0] + pixel_diff, Color.red) # for pixel in pixels:
# image.set_pixelv(pixel[0] + pixel_diff, pixel[1]) ## image.set_pixelv(pixel[0] + pixel_diff, Color.red)
Global.canvas.handle_redo("Draw") # image.set_pixelv(pixel[0] + pixel_diff, pixel[1])
Global.canvas.handle_redo("Draw")
print(pixel_diff) print(pixel_diff)
starting_pos = Vector2.INF starting_pos = Vector2.INF

View file

@ -4,6 +4,8 @@ class_name SelectionShape extends Polygon2D
var line_offset := Vector2.ZERO setget _offset_changed var line_offset := Vector2.ZERO setget _offset_changed
var tween : Tween var tween : Tween
var local_selected_pixels := [] setget _local_selected_pixels_changed # Array of Vector2s var local_selected_pixels := [] setget _local_selected_pixels_changed # Array of Vector2s
var local_image := Image.new()
var local_image_texture := ImageTexture.new()
var clear_selection_on_tree_exit := true var clear_selection_on_tree_exit := true
var _selected_rect := Rect2(0, 0, 0, 0) var _selected_rect := Rect2(0, 0, 0, 0)
var _clipped_rect := Rect2(0, 0, 0, 0) var _clipped_rect := Rect2(0, 0, 0, 0)
@ -69,8 +71,11 @@ func _draw() -> void:
# draw_circle(Vector2(rect_pos.x, rect_end.y), 1, Color.gray) # draw_circle(Vector2(rect_pos.x, rect_end.y), 1, Color.gray)
# draw_circle(Vector2(rect_pos.x, (rect_end.y + rect_pos.y) / 2), 1, Color.gray) # draw_circle(Vector2(rect_pos.x, (rect_end.y + rect_pos.y) / 2), 1, Color.gray)
if _move_pixel: if !local_image.is_empty():
draw_texture(_move_texture, _clipped_rect.position, Color(1, 1, 1, 0.5)) draw_texture(local_image_texture, _selected_rect.position, Color(1, 1, 1, 0.5))
# if _move_pixel:
# draw_texture(_move_texture, _clipped_rect.position, Color(1, 1, 1, 0.5))
# Taken and modified from https://github.com/juddrgledhill/godot-dashed-line # Taken and modified from https://github.com/juddrgledhill/godot-dashed-line
@ -191,10 +196,10 @@ func select_rect(merge := true) -> void:
# if polygon.size() > 4: # if it's not a rectangle # if polygon.size() > 4: # if it's not a rectangle
# if !Geometry.is_point_in_polygon(pos, polygon): # if !Geometry.is_point_in_polygon(pos, polygon):
# continue # continue
if x < 0 or x >= project.size.x: # if x < 0 or x >= project.size.x:
continue # continue
if y < 0 or y >= project.size.y: # if y < 0 or y >= project.size.y:
continue # continue
selected_pixels_copy.append(pos) selected_pixels_copy.append(pos)
self.local_selected_pixels = selected_pixels_copy self.local_selected_pixels = selected_pixels_copy
@ -217,6 +222,7 @@ func merge_multiple_selections(merge := true) -> void:
continue continue
if merge: if merge:
var arr = Geometry.merge_polygons_2d(polygon, selection.polygon) var arr = Geometry.merge_polygons_2d(polygon, selection.polygon)
# print(arr.size())
if arr.size() == 1: # if the selections intersect if arr.size() == 1: # if the selections intersect
set_polygon(arr[0]) set_polygon(arr[0])
_selected_rect = _selected_rect.merge(selection._selected_rect) _selected_rect = _selected_rect.merge(selection._selected_rect)
@ -228,7 +234,6 @@ func merge_multiple_selections(merge := true) -> void:
self.local_selected_pixels = selected_pixels_copy self.local_selected_pixels = selected_pixels_copy
else: else:
var arr = Geometry.clip_polygons_2d(selection.polygon, polygon) var arr = Geometry.clip_polygons_2d(selection.polygon, polygon)
# print(arr.size())
if arr.size() == 0: # if the new selection completely overlaps the current if arr.size() == 0: # if the new selection completely overlaps the current
selection.queue_free() selection.queue_free()
else: # if the selections intersect else: # if the selections intersect
@ -244,44 +249,93 @@ func merge_multiple_selections(merge := true) -> void:
selection_shape.set_polygon(arr[i]) selection_shape.set_polygon(arr[i])
func move_start(move_pixel : bool) -> void: func get_image() -> Image:
if not move_pixel: var project : Project = Global.current_project
var cel_image : Image = project.frames[project.current_frame].cels[project.current_layer].image
var image := Image.new()
image = cel_image.get_rect(_selected_rect)
# print(polygon.size())
if polygon.size() > 4:
image.lock()
var image_pixel := Vector2.ZERO
for x in range(_selected_rect.position.x, _selected_rect.end.x):
image_pixel.y = 0
for y in range(_selected_rect.position.y, _selected_rect.end.y):
var pos := Vector2(x, y)
# if not Geometry.is_point_in_polygon(pos, polygon):
if not pos in local_selected_pixels:
# print(pixel)
image.set_pixelv(image_pixel, Color(0, 0, 0, 0))
image_pixel.y += 1
image_pixel.x += 1
image.unlock()
# image.create(_selected_rect.size.x, _selected_rect.size.y, false, Image.FORMAT_RGBA8)
return image
func move_content_start() -> void:
if !local_image.is_empty():
return return
local_image = get_image()
_undo_data = _get_undo_data(true) local_image_texture.create_from_image(local_image, 0)
var project := Global.current_project var project : Project = Global.current_project
var image : Image = project.frames[project.current_frame].cels[project.current_layer].image var cel_image : Image = project.frames[project.current_frame].cels[project.current_layer].image
_clear_image.resize(_selected_rect.size.x, _selected_rect.size.y, Image.INTERPOLATE_NEAREST)
var rect = Rect2(Vector2.ZERO, project.size) cel_image.blit_rect_mask(_clear_image, local_image, Rect2(Vector2.ZERO, _selected_rect.size), _selected_rect.position)
_clipped_rect = rect.clip(_selected_rect)
_move_image = image.get_rect(_clipped_rect)
_move_texture.create_from_image(_move_image, 0)
var size := _clipped_rect.size
rect = Rect2(Vector2.ZERO, size)
_clear_image.resize(size.x, size.y, Image.INTERPOLATE_NEAREST)
image.blit_rect(_clear_image, rect, _clipped_rect.position)
Global.canvas.update_texture(project.current_layer) Global.canvas.update_texture(project.current_layer)
_move_pixel = true
update() func move_content_end() -> void:
if local_image.is_empty():
return
var project : Project = Global.current_project
var cel_image : Image = project.frames[project.current_frame].cels[project.current_layer].image
cel_image.blit_rect_mask(local_image, local_image, Rect2(Vector2.ZERO, _selected_rect.size), _selected_rect.position)
Global.canvas.update_texture(project.current_layer)
local_image = Image.new()
local_image_texture = ImageTexture.new()
func move_end() -> void: #func move_start(move_pixel : bool) -> void:
var undo_data = _undo_data if _move_pixel else _get_undo_data(false) # if not move_pixel:
# return
if _move_pixel: #
var project := Global.current_project # _undo_data = _get_undo_data(true)
var image : Image = project.frames[project.current_frame].cels[project.current_layer].image # var project := Global.current_project
var size := _clipped_rect.size # var image : Image = project.frames[project.current_frame].cels[project.current_layer].image
var rect = Rect2(Vector2.ZERO, size) #
image.blit_rect_mask(_move_image, _move_image, rect, _clipped_rect.position) # var rect = Rect2(Vector2.ZERO, project.size)
_move_pixel = false # _clipped_rect = rect.clip(_selected_rect)
update() # _move_image = image.get_rect(_clipped_rect)
# _move_texture.create_from_image(_move_image, 0)
Global.current_project.selected_rect = _selected_rect #
commit_undo("Rectangle Select", undo_data) # var size := _clipped_rect.size
_undo_data.clear() # rect = Rect2(Vector2.ZERO, size)
# _clear_image.resize(size.x, size.y, Image.INTERPOLATE_NEAREST)
# image.blit_rect(_clear_image, rect, _clipped_rect.position)
# Global.canvas.update_texture(project.current_layer)
#
# _move_pixel = true
# update()
#
#
#func move_end() -> void:
# var undo_data = _undo_data if _move_pixel else _get_undo_data(false)
#
# if _move_pixel:
# var project := Global.current_project
# var image : Image = project.frames[project.current_frame].cels[project.current_layer].image
# var size := _clipped_rect.size
# var rect = Rect2(Vector2.ZERO, size)
# image.blit_rect_mask(_move_image, _move_image, rect, _clipped_rect.position)
# _move_pixel = false
# update()
#
# Global.current_project.selected_rect = _selected_rect
# commit_undo("Rectangle Select", undo_data)
# _undo_data.clear()
func copy() -> void: func copy() -> void:
@ -314,7 +368,7 @@ func cut() -> void: # This is basically the same as copy + delete
var brush = _clipboard.get_rect(_clipboard.get_used_rect()) var brush = _clipboard.get_rect(_clipboard.get_used_rect())
project.brushes.append(brush) project.brushes.append(brush)
Brushes.add_project_brush(brush) Brushes.add_project_brush(brush)
move_end() # The selection_rectangle can be used while is moving, this prevents malfunctioning # move_end() # The selection_rectangle can be used while is moving, this prevents malfunctioning
image.blit_rect(_clear_image, rect, _selected_rect.position) image.blit_rect(_clear_image, rect, _selected_rect.position)
commit_undo("Draw", undo_data) commit_undo("Draw", undo_data)
@ -328,7 +382,7 @@ func paste() -> void:
var size := _selected_rect.size var size := _selected_rect.size
var rect = Rect2(Vector2.ZERO, size) var rect = Rect2(Vector2.ZERO, size)
image.blend_rect(_clipboard, rect, _selected_rect.position) image.blend_rect(_clipboard, rect, _selected_rect.position)
move_end() # The selection_rectangle can be used while is moving, this prevents malfunctioning # move_end() # The selection_rectangle can be used while is moving, this prevents malfunctioning
commit_undo("Draw", undo_data) commit_undo("Draw", undo_data)
@ -340,7 +394,7 @@ func delete() -> void:
var rect = Rect2(Vector2.ZERO, size) var rect = Rect2(Vector2.ZERO, size)
_clear_image.resize(size.x, size.y, Image.INTERPOLATE_NEAREST) _clear_image.resize(size.x, size.y, Image.INTERPOLATE_NEAREST)
image.blit_rect(_clear_image, rect, _selected_rect.position) image.blit_rect(_clear_image, rect, _selected_rect.position)
move_end() # The selection_rectangle can be used while is moving, this prevents malfunctioning # move_end() # The selection_rectangle can be used while is moving, this prevents malfunctioning
commit_undo("Draw", undo_data) commit_undo("Draw", undo_data)
@ -374,6 +428,7 @@ func _get_undo_data(undo_image : bool) -> Dictionary:
func _on_SelectionShape_tree_exiting() -> void: func _on_SelectionShape_tree_exiting() -> void:
move_content_end()
Global.current_project.selections.erase(self) Global.current_project.selections.erase(self)
if clear_selection_on_tree_exit: if clear_selection_on_tree_exit:
self.local_selected_pixels = [] self.local_selected_pixels = []