Move some methods from SelectionShape.gd to Selection.gd

The purpose of this is to generalize some selection code, so that it applies to all polygons, the entire selection. More will follow.
This commit is contained in:
Manolis Papadeas 2021-02-23 04:05:56 +02:00
parent ac5d492298
commit 4574c9b60d
6 changed files with 124 additions and 250 deletions

View file

@ -9,15 +9,13 @@ func draw_start(position : Vector2) -> void:
starting_pos = position
offset = position
if Global.current_project.selected_pixels:
for selection in Global.current_project.selections:
selection.move_content_start()
Global.canvas.selection.move_content_start()
# Global.selection_rectangl.move_start(true)
func draw_move(position : Vector2) -> void:
if Global.current_project.selected_pixels:
for selection in Global.current_project.selections:
selection.move_polygon(position - offset)
Global.canvas.selection.move_borders(position - offset)
offset = position
# Global.selection_rectangl.move_rect(position - offset)
else:
@ -34,9 +32,8 @@ func draw_end(position : Vector2) -> void:
if project.selected_pixels:
pass
# for selection in Global.current_project.selections:
# selection.move_content_end()
# selection.move_polygon_end(position, starting_pos)
# Global.canvas.selection.move_content_end()
# Global.canvas.selection.move_borders_end(position, starting_pos)
else:
Global.canvas.move_preview_location = Vector2.ZERO
var image_copy := Image.new()

View file

@ -25,7 +25,7 @@ func draw_start(position : Vector2) -> void:
current_selection_id = Global.current_project.selections.size()
var selection_shape := preload("res://src/Tools/SelectionShape.tscn").instance()
Global.current_project.selections.append(selection_shape)
Global.canvas.add_child(selection_shape)
Global.canvas.selection.add_child(selection_shape)
_start = Rect2(position, Vector2.ZERO)
selection_shape.set_rect(_start)
else:
@ -49,8 +49,7 @@ func draw_move(position : Vector2) -> void:
var selection : SelectionShape = Global.current_project.selections[current_selection_id]
if _move:
for _selection in Global.current_project.selections:
_selection.move_polygon(position - _offset)
Global.canvas.selection.move_borders(position - _offset)
_offset = position
_set_cursor_text(selection.get_rect())
else:
@ -58,21 +57,11 @@ func draw_move(position : Vector2) -> void:
rect = rect.grow_individual(0, 0, 1, 1)
selection.set_rect(rect)
_set_cursor_text(rect)
# if _move:
# Global.selection_rectangle.move_rect(position - _offset)
# _offset = position
# _set_cursor_text(Global.selection_rectangle.get_rect())
# else:
# var rect := _start.expand(position).abs()
# rect = rect.grow_individual(0, 0, 1, 1)
# Global.selection_rectangle.set_rect(rect)
# _set_cursor_text(rect)
func draw_end(position : Vector2) -> void:
if _move:
for _selection in Global.current_project.selections:
_selection.move_polygon_end(position, start_position)
Global.canvas.selection.move_borders_end(position, start_position)
else:
var selection : SelectionShape = Global.current_project.selections[current_selection_id]
selection.select_rect(!Tools.control)

View file

@ -169,23 +169,6 @@ func set_rect(rect : Rect2) -> void:
# visible = not rect.has_no_area()
func move_polygon(move : Vector2) -> void:
_selected_rect.position += move
_clipped_rect.position += move
for i in polygon.size():
polygon[i] += move
# set_rect(_selected_rect)
func move_polygon_end(new_pos : Vector2, old_pos : Vector2) -> void:
var diff := new_pos - old_pos
var selected_pixels_copy = local_selected_pixels.duplicate()
for i in selected_pixels_copy.size():
selected_pixels_copy[i] += diff
self.local_selected_pixels = selected_pixels_copy
func select_rect(merge := true) -> void:
var project : Project = Global.current_project
self.local_selected_pixels = []
@ -245,7 +228,7 @@ func merge_multiple_selections(merge := true) -> void:
for i in range(1, arr.size()):
var selection_shape = load("res://src/Tools/SelectionShape.tscn").instance()
Global.current_project.selections.append(selection_shape)
Global.canvas.add_child(selection_shape)
Global.canvas.selection.add_child(selection_shape)
selection_shape.set_polygon(arr[i])
@ -275,29 +258,6 @@ func get_image() -> Image:
return image
func move_content_start() -> void:
if !local_image.is_empty():
return
local_image = get_image()
local_image_texture.create_from_image(local_image, 0)
var project : Project = Global.current_project
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)
cel_image.blit_rect_mask(_clear_image, local_image, Rect2(Vector2.ZERO, _selected_rect.size), _selected_rect.position)
Global.canvas.update_texture(project.current_layer)
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_start(move_pixel : bool) -> void:
# if not move_pixel:
# return
@ -428,7 +388,7 @@ func _get_undo_data(undo_image : bool) -> Dictionary:
func _on_SelectionShape_tree_exiting() -> void:
move_content_end()
get_parent().move_content_end()
Global.current_project.selections.erase(self)
if clear_selection_on_tree_exit:
self.local_selected_pixels = []

View file

@ -11,9 +11,10 @@ var move_preview_location := Vector2.ZERO
onready var currently_visible_frame : Viewport = $CurrentlyVisibleFrame
onready var current_frame_drawer = $CurrentlyVisibleFrame/CurrentFrameDrawer
onready var tile_mode = $TileMode
onready var pixel_grid = $PixelGrid
onready var grid = $Grid
onready var tile_mode = $TileMode
onready var selection = $Selection
onready var indicators = $Indicators

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=8 format=2]
[gd_scene load_steps=9 format=2]
[ext_resource path="res://src/UI/Canvas/Canvas.gd" type="Script" id=1]
[ext_resource path="res://src/UI/Canvas/Grid.gd" type="Script" id=2]
@ -6,6 +6,7 @@
[ext_resource path="res://src/UI/Canvas/TileMode.gd" type="Script" id=4]
[ext_resource path="res://src/UI/Canvas/CurrentFrameDrawer.gd" type="Script" id=5]
[ext_resource path="res://src/UI/Canvas/PixelGrid.gd" type="Script" id=6]
[ext_resource path="res://src/UI/Canvas/Selection.gd" type="Script" id=7]
[sub_resource type="CanvasItemMaterial" id=1]
blend_mode = 4
@ -35,5 +36,8 @@ script = ExtResource( 6 )
[node name="Grid" type="Node2D" parent="."]
script = ExtResource( 2 )
[node name="Selection" type="Node2D" parent="."]
script = ExtResource( 7 )
[node name="Indicators" type="Node2D" parent="."]
script = ExtResource( 3 )

View file

@ -1,94 +1,55 @@
extends Node2D
class SelectionPolygon:
# var project : Project
var border := PoolVector2Array()
var rect_outline : Rect2
var rects := [] # Array of Rect2s
var selected_pixels := [] # Array of Vector2s - the selected pixels
#class SelectionPolygon:
## var project : Project
# var border := PoolVector2Array()
# var rect_outline : Rect2
# var rects := [] # Array of Rect2s
# var selected_pixels := [] # Array of Vector2s - the selected pixels
var line_offset := Vector2.ZERO setget _offset_changed
var tween : Tween
var selection_polygons := [] # Array of SelectionPolygons
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 _ready() -> void:
tween = Tween.new()
tween.connect("tween_completed", self, "_offset_tween_completed")
add_child(tween)
tween.interpolate_property(self, "line_offset", Vector2.ZERO, Vector2(2, 2), 1)
tween.start()
func move_borders_end(new_pos : Vector2, old_pos : Vector2) -> void:
for shape in get_children():
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
func generate_polygons():
# selection_polygons.clear()
# selection_polygons.append(SelectionPolygon.new())
# for pixel in Global.current_project.selected_pixels:
# var current_polygon : SelectionPolygon = selection_polygons[0]
# var rect = Rect2(pixel, Vector2.ONE)
# var pixel_border = get_rect_border(rect)
# var arr = Geometry.merge_polygons_2d(pixel_border, current_polygon.border)
## print("Arr ", arr)
# if arr.size() == 1: # if the selections intersect
## current_polygon.rects.append(rect)
# current_polygon.rect_outline.merge(rect)
# current_polygon.border = arr[0]
#
#
# return
var selected_pixels_copy := Global.current_project.selected_pixels.duplicate()
var rects := []
while selected_pixels_copy.size() > 0:
var rect : Rect2 = generate_rect(selected_pixels_copy)
print("!!!")
if !rect:
break
for pixel in Global.current_project.selected_pixels:
if rect.has_point(pixel):
# print("POINT")
selected_pixels_copy.erase(pixel)
func move_content_start() -> void:
for shape in get_children():
if !shape.local_image.is_empty():
return
shape.local_image = shape.get_image()
shape.local_image_texture.create_from_image(shape.local_image, 0)
var project : Project = Global.current_project
var cel_image : Image = project.frames[project.current_frame].cels[project.current_layer].image
shape._clear_image.resize(shape._selected_rect.size.x, shape._selected_rect.size.y, Image.INTERPOLATE_NEAREST)
cel_image.blit_rect_mask(shape._clear_image, shape.local_image, Rect2(Vector2.ZERO, shape._selected_rect.size), shape._selected_rect.position)
Global.canvas.update_texture(project.current_layer)
rects.append(rect)
print(rects)
# print("e ", selected_pixels_copy)
if !rects:
return
# var polygons := [SelectionPolygon.new()]
selection_polygons.clear()
var polygons := [SelectionPolygon.new()]
var curr_polyg := 0
if rects.size() == 1:
polygons[0].rects.append(rects[0])
polygons[0].rect_outline = rects[0]
polygons[0].selected_pixels = Global.current_project.selected_pixels.duplicate()
var border : PoolVector2Array = get_rect_border(rects[0])
polygons[0].border = border
selection_polygons = polygons
return
for i in rects.size():
var current_polygon : SelectionPolygon = polygons[curr_polyg]
var rect : Rect2 = rects[i]
var outlines : PoolVector2Array = get_rect_border(rect)
# var rect_prev : Rect2 = rects[i - 1]
# var outlines_prev : PoolVector2Array = get_rect_border(rect_prev)
var arr = Geometry.merge_polygons_2d(outlines, current_polygon.border)
print("Arr ", arr)
if arr.size() == 1: # if the selections intersect
current_polygon.rects.append(rect)
# if not rect_prev in current_polygon.rects:
# current_polygon.rects.append(rect_prev)
current_polygon.rect_outline.merge(rect)
current_polygon.border = arr[0]
selection_polygons = polygons
func move_content_end() -> void:
for shape in get_children():
if shape.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(shape.local_image, shape.local_image, Rect2(Vector2.ZERO, shape._selected_rect.size), shape._selected_rect.position)
Global.canvas.update_texture(project.current_layer)
shape.local_image = Image.new()
shape.local_image_texture = ImageTexture.new()
func generate_rect(pixels : Array) -> Rect2:
@ -125,108 +86,70 @@ func get_rect_border(rect : Rect2) -> PoolVector2Array:
return border
func _offset_tween_completed(_object, _key) -> void:
self.line_offset = Vector2.ZERO
tween.interpolate_property(self, "line_offset", Vector2.ZERO, Vector2(2, 2), 1)
tween.start()
func _offset_changed(value : Vector2) -> void:
line_offset = value
update()
func _draw() -> void:
for polygon in selection_polygons:
var points : PoolVector2Array = polygon.border
# print(points)
for i in range(1, points.size() + 1):
var point0 = points[i - 1]
var point1
if i >= points.size():
point1 = points[0]
else:
point1 = points[i]
var start_x = min(point0.x, point1.x)
var start_y = min(point0.y, point1.y)
var end_x = max(point0.x, point1.x)
var end_y = max(point0.y, point1.y)
var start := Vector2(start_x, start_y)
var end := Vector2(end_x, end_y)
draw_dashed_line(start, end, Color.white, Color.black, 1.0, 1.0, false)
if !polygon.selected_pixels:
return
# draw_polygon(Global.current_project.get_selection_polygon(), [Color(1, 1, 1, 0.5)])
# var rect_pos := _selected_rect.position
# var rect_end := _selected_rect.end
# draw_circle(rect_pos, 1, Color.gray)
# draw_circle(Vector2((rect_end.x + rect_pos.x) / 2, rect_pos.y), 1, Color.gray)
# draw_circle(Vector2(rect_end.x, rect_pos.y), 1, Color.gray)
# draw_circle(Vector2(rect_end.x, (rect_end.y + rect_pos.y) / 2), 1, Color.gray)
# draw_circle(rect_end, 1, Color.gray)
# draw_circle(Vector2(rect_end.x, rect_end.y), 1, Color.gray)
# draw_circle(Vector2((rect_end.x + rect_pos.x) / 2, 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)
# 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
func draw_dashed_line(from : Vector2, to : Vector2, color : Color, color2 : Color, width := 1.0, dash_length := 1.0, cap_end := false, antialiased := false) -> void:
var length = (to - from).length()
var normal = (to - from).normalized()
var dash_step = normal * dash_length
var horizontal : bool = from.y == to.y
var _offset : Vector2
if horizontal:
_offset = Vector2(line_offset.x, 0)
else:
_offset = Vector2(0, line_offset.y)
if length < dash_length: # not long enough to dash
draw_line(from, to, color, width, antialiased)
return
else:
var draw_flag = true
var segment_start = from
var steps = length/dash_length
for _start_length in range(0, steps + 1):
var segment_end = segment_start + dash_step
var start = segment_start + _offset
start.x = min(start.x, to.x)
start.y = min(start.y, to.y)
var end = segment_end + _offset
end.x = min(end.x, to.x)
end.y = min(end.y, to.y)
if draw_flag:
draw_line(start, end, color, width, antialiased)
else:
draw_line(start, end, color2, width, antialiased)
if _offset.length() < 1:
draw_line(from, from + _offset, color2, width, antialiased)
else:
var from_offseted : Vector2 = from + _offset
var halfway_point : Vector2 = from_offseted
if horizontal:
halfway_point += Vector2.LEFT
else:
halfway_point += Vector2.UP
from_offseted.x = min(from_offseted.x, to.x)
from_offseted.y = min(from_offseted.y, to.y)
draw_line(halfway_point, from_offseted, color2, width, antialiased)
draw_line(from, halfway_point, color, width, antialiased)
segment_start = segment_end
draw_flag = !draw_flag
if cap_end:
draw_line(segment_start, to, color, width, antialiased)
#func generate_polygons():
## selection_polygons.clear()
## selection_polygons.append(SelectionPolygon.new())
## for pixel in Global.current_project.selected_pixels:
## var current_polygon : SelectionPolygon = selection_polygons[0]
## var rect = Rect2(pixel, Vector2.ONE)
## var pixel_border = get_rect_border(rect)
## var arr = Geometry.merge_polygons_2d(pixel_border, current_polygon.border)
### print("Arr ", arr)
## if arr.size() == 1: # if the selections intersect
### current_polygon.rects.append(rect)
## current_polygon.rect_outline.merge(rect)
## current_polygon.border = arr[0]
##
##
## return
# var selected_pixels_copy := Global.current_project.selected_pixels.duplicate()
# var rects := []
# while selected_pixels_copy.size() > 0:
# var rect : Rect2 = generate_rect(selected_pixels_copy)
# print("!!!")
# if !rect:
# break
# for pixel in Global.current_project.selected_pixels:
# if rect.has_point(pixel):
## print("POINT")
# selected_pixels_copy.erase(pixel)
#
# rects.append(rect)
#
# print(rects)
## print("e ", selected_pixels_copy)
#
# if !rects:
# return
## var polygons := [SelectionPolygon.new()]
# selection_polygons.clear()
# var polygons := [SelectionPolygon.new()]
# var curr_polyg := 0
#
# if rects.size() == 1:
# polygons[0].rects.append(rects[0])
# polygons[0].rect_outline = rects[0]
# polygons[0].selected_pixels = Global.current_project.selected_pixels.duplicate()
# var border : PoolVector2Array = get_rect_border(rects[0])
# polygons[0].border = border
# selection_polygons = polygons
# return
#
# for i in rects.size():
# var current_polygon : SelectionPolygon = polygons[curr_polyg]
# var rect : Rect2 = rects[i]
# var outlines : PoolVector2Array = get_rect_border(rect)
#
## var rect_prev : Rect2 = rects[i - 1]
## var outlines_prev : PoolVector2Array = get_rect_border(rect_prev)
#
# var arr = Geometry.merge_polygons_2d(outlines, current_polygon.border)
# print("Arr ", arr)
# if arr.size() == 1: # if the selections intersect
# current_polygon.rects.append(rect)
## if not rect_prev in current_polygon.rects:
## current_polygon.rects.append(rect_prev)
# current_polygon.rect_outline.merge(rect)
# current_polygon.border = arr[0]
#
# selection_polygons = polygons