diff --git a/src/Tools/Move.gd b/src/Tools/Move.gd index 1ac8c1d..b1ba169 100644 --- a/src/Tools/Move.gd +++ b/src/Tools/Move.gd @@ -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() diff --git a/src/Tools/RectSelect.gd b/src/Tools/RectSelect.gd index 15ffe43..20112c2 100644 --- a/src/Tools/RectSelect.gd +++ b/src/Tools/RectSelect.gd @@ -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) diff --git a/src/Tools/SelectionShape.gd b/src/Tools/SelectionShape.gd index 578c0da..5a2daee 100644 --- a/src/Tools/SelectionShape.gd +++ b/src/Tools/SelectionShape.gd @@ -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 = [] diff --git a/src/UI/Canvas/Canvas.gd b/src/UI/Canvas/Canvas.gd index 643a5af..6307669 100644 --- a/src/UI/Canvas/Canvas.gd +++ b/src/UI/Canvas/Canvas.gd @@ -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 diff --git a/src/UI/Canvas/Canvas.tscn b/src/UI/Canvas/Canvas.tscn index bdbb9c9..fef04cc 100644 --- a/src/UI/Canvas/Canvas.tscn +++ b/src/UI/Canvas/Canvas.tscn @@ -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 ) diff --git a/src/UI/Canvas/Selection.gd b/src/UI/Canvas/Selection.gd index 05d5235..5344e9e 100644 --- a/src/UI/Canvas/Selection.gd +++ b/src/UI/Canvas/Selection.gd @@ -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