mirror of
https://github.com/tonytins/CozyPixelStudio.git
synced 2025-05-05 16:24:49 -04:00
Rename SelectionRectangle to SelectionShape, make it have non-rectangular shape and multiple SelectionShapes can exist
- Create multiple selection rectangles - Merge them together if they intersect - Move the selections (without contents as of right now) - Gizmos are being drawn but they are not functional yet Code is very ugly.
This commit is contained in:
parent
2a086e3ea0
commit
f3fb98e068
10 changed files with 230 additions and 74 deletions
|
@ -84,6 +84,16 @@ _global_script_classes=[ {
|
||||||
"language": "GDScript",
|
"language": "GDScript",
|
||||||
"path": "res://src/Classes/Project.gd"
|
"path": "res://src/Classes/Project.gd"
|
||||||
}, {
|
}, {
|
||||||
|
"base": "Reference",
|
||||||
|
"class": "Selection",
|
||||||
|
"language": "GDScript",
|
||||||
|
"path": "res://src/Classes/Selection.gd"
|
||||||
|
}, {
|
||||||
|
"base": "Polygon2D",
|
||||||
|
"class": "SelectionShape",
|
||||||
|
"language": "GDScript",
|
||||||
|
"path": "res://src/Tools/SelectionShape.gd"
|
||||||
|
}, {
|
||||||
"base": "Guide",
|
"base": "Guide",
|
||||||
"class": "SymmetryGuide",
|
"class": "SymmetryGuide",
|
||||||
"language": "GDScript",
|
"language": "GDScript",
|
||||||
|
@ -105,6 +115,8 @@ _global_script_class_icons={
|
||||||
"PaletteColor": "",
|
"PaletteColor": "",
|
||||||
"Patterns": "",
|
"Patterns": "",
|
||||||
"Project": "",
|
"Project": "",
|
||||||
|
"Selection": "",
|
||||||
|
"SelectionShape": "",
|
||||||
"SymmetryGuide": ""
|
"SymmetryGuide": ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,6 @@ var small_preview_viewport : ViewportContainer
|
||||||
var camera : Camera2D
|
var camera : Camera2D
|
||||||
var camera2 : Camera2D
|
var camera2 : Camera2D
|
||||||
var camera_preview : Camera2D
|
var camera_preview : Camera2D
|
||||||
var selection_rectangle : Polygon2D
|
|
||||||
var horizontal_ruler : BaseButton
|
var horizontal_ruler : BaseButton
|
||||||
var vertical_ruler : BaseButton
|
var vertical_ruler : BaseButton
|
||||||
var transparent_checker : ColorRect
|
var transparent_checker : ColorRect
|
||||||
|
@ -215,7 +214,6 @@ func _ready() -> void:
|
||||||
camera = find_node_by_name(main_viewport, "Camera2D")
|
camera = find_node_by_name(main_viewport, "Camera2D")
|
||||||
camera2 = find_node_by_name(root, "Camera2D2")
|
camera2 = find_node_by_name(root, "Camera2D2")
|
||||||
camera_preview = find_node_by_name(root, "CameraPreview")
|
camera_preview = find_node_by_name(root, "CameraPreview")
|
||||||
selection_rectangle = find_node_by_name(root, "SelectionRectangle")
|
|
||||||
horizontal_ruler = find_node_by_name(root, "HorizontalRuler")
|
horizontal_ruler = find_node_by_name(root, "HorizontalRuler")
|
||||||
vertical_ruler = find_node_by_name(root, "VerticalRuler")
|
vertical_ruler = find_node_by_name(root, "VerticalRuler")
|
||||||
transparent_checker = find_node_by_name(root, "TransparentChecker")
|
transparent_checker = find_node_by_name(root, "TransparentChecker")
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
class_name Project extends Reference
|
class_name Project extends Reference
|
||||||
# A class for project properties.
|
# A class for project properties.
|
||||||
|
|
||||||
|
|
||||||
var name := "" setget name_changed
|
var name := "" setget name_changed
|
||||||
var size : Vector2 setget size_changed
|
var size : Vector2 setget size_changed
|
||||||
var undo_redo : UndoRedo
|
var undo_redo : UndoRedo
|
||||||
|
@ -24,7 +23,7 @@ var x_symmetry_axis : SymmetryGuide
|
||||||
var y_symmetry_axis : SymmetryGuide
|
var y_symmetry_axis : SymmetryGuide
|
||||||
|
|
||||||
var selected_pixels := []
|
var selected_pixels := []
|
||||||
var selected_rect := Rect2(0, 0, 0, 0) setget _set_selected_rect
|
var selections := [] setget _set_selections # Array of SelectionShape(s)
|
||||||
|
|
||||||
# For every camera (currently there are 3)
|
# For every camera (currently there are 3)
|
||||||
var cameras_zoom := [Vector2(0.15, 0.15), Vector2(0.15, 0.15), Vector2(0.15, 0.15)] # Array of Vector2
|
var cameras_zoom := [Vector2(0.15, 0.15), Vector2(0.15, 0.15), Vector2(0.15, 0.15)] # Array of Vector2
|
||||||
|
@ -85,9 +84,9 @@ func clear_selection() -> void:
|
||||||
selected_pixels.clear()
|
selected_pixels.clear()
|
||||||
|
|
||||||
|
|
||||||
func _set_selected_rect(value : Rect2) -> void:
|
func _set_selections(value : Array) -> void:
|
||||||
selected_rect = value
|
selections = value
|
||||||
Global.selection_rectangle.set_rect(value)
|
# Global.selection_rectangl.set_rect(value)
|
||||||
|
|
||||||
|
|
||||||
func change_project() -> void:
|
func change_project() -> void:
|
||||||
|
@ -147,7 +146,7 @@ func change_project() -> void:
|
||||||
self.animation_tags = animation_tags
|
self.animation_tags = animation_tags
|
||||||
|
|
||||||
# Change the selection rectangle
|
# Change the selection rectangle
|
||||||
Global.selection_rectangle.set_rect(selected_rect)
|
# Global.selection_rectangl.set_rect(selected_rect)
|
||||||
|
|
||||||
# Change the guides
|
# Change the guides
|
||||||
for guide in Global.canvas.get_children():
|
for guide in Global.canvas.get_children():
|
||||||
|
@ -364,7 +363,7 @@ func name_changed(value : String) -> void:
|
||||||
func size_changed(value : Vector2) -> void:
|
func size_changed(value : Vector2) -> void:
|
||||||
size = value
|
size = value
|
||||||
update_tile_mode_rects()
|
update_tile_mode_rects()
|
||||||
Global.selection_rectangle.set_rect(Global.selection_rectangle.get_rect())
|
# Global.selection_rectangl.set_rect(Global.selection_rectangl.get_rect())
|
||||||
|
|
||||||
|
|
||||||
func frames_changed(value : Array) -> void:
|
func frames_changed(value : Array) -> void:
|
||||||
|
@ -583,3 +582,16 @@ func update_tile_mode_rects() -> void:
|
||||||
|
|
||||||
func is_empty() -> bool:
|
func is_empty() -> bool:
|
||||||
return frames.size() == 1 and layers.size() == 1 and frames[0].cels[0].image.is_invisible() and animation_tags.size() == 0
|
return frames.size() == 1 and layers.size() == 1 and frames[0].cels[0].image.is_invisible() and animation_tags.size() == 0
|
||||||
|
|
||||||
|
|
||||||
|
func get_selection_image() -> Image:
|
||||||
|
var image := Image.new()
|
||||||
|
var cel_image : Image = frames[current_frame].cels[current_layer].image
|
||||||
|
image.copy_from(cel_image)
|
||||||
|
image.lock()
|
||||||
|
image.fill(Color(0, 0, 0, 0))
|
||||||
|
for pixel in selected_pixels:
|
||||||
|
var color : Color = cel_image.get_pixelv(pixel)
|
||||||
|
image.set_pixelv(pixel, color)
|
||||||
|
image.unlock()
|
||||||
|
return image
|
||||||
|
|
11
src/Classes/Selection.gd
Normal file
11
src/Classes/Selection.gd
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
class_name Selection extends Reference
|
||||||
|
|
||||||
|
|
||||||
|
var selected_area := [] # Selected pixels for each selection
|
||||||
|
var borders : PoolVector2Array
|
||||||
|
var node : SelectionShape
|
||||||
|
|
||||||
|
|
||||||
|
func _init(_node : SelectionShape) -> void:
|
||||||
|
node = _node
|
||||||
|
Global.canvas.add_child(node)
|
|
@ -9,12 +9,16 @@ 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:
|
||||||
Global.selection_rectangle.move_start(true)
|
pass
|
||||||
|
# Global.selection_rectangl.move_start(true)
|
||||||
|
|
||||||
|
|
||||||
func draw_move(position : Vector2) -> void:
|
func draw_move(position : Vector2) -> void:
|
||||||
if Global.current_project.selected_pixels:
|
if Global.current_project.selected_pixels:
|
||||||
Global.selection_rectangle.move_rect(position - offset)
|
for selection in Global.current_project.selections:
|
||||||
|
selection.move_polygon(position - offset)
|
||||||
|
offset = position
|
||||||
|
# Global.selection_rectangl.move_rect(position - offset)
|
||||||
else:
|
else:
|
||||||
Global.canvas.move_preview_location = position - starting_pos
|
Global.canvas.move_preview_location = position - starting_pos
|
||||||
offset = position
|
offset = position
|
||||||
|
@ -37,7 +41,8 @@ func draw_end(position : Vector2) -> void:
|
||||||
|
|
||||||
# print(pixels[3])
|
# print(pixels[3])
|
||||||
if project.selected_pixels:
|
if project.selected_pixels:
|
||||||
Global.selection_rectangle.move_end()
|
for selection in Global.current_project.selections:
|
||||||
|
selection.select_rect()
|
||||||
else:
|
else:
|
||||||
Global.canvas.move_preview_location = Vector2.ZERO
|
Global.canvas.move_preview_location = Vector2.ZERO
|
||||||
var image_copy := Image.new()
|
var image_copy := Image.new()
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
extends BaseTool
|
extends BaseTool
|
||||||
|
|
||||||
|
|
||||||
|
var current_selection_id := -1
|
||||||
|
var start_position := Vector2.INF
|
||||||
var _start := Rect2(0, 0, 0, 0)
|
var _start := Rect2(0, 0, 0, 0)
|
||||||
var _offset := Vector2.ZERO
|
var _offset := Vector2.ZERO
|
||||||
var _drag := false
|
var _drag := false
|
||||||
|
@ -8,49 +10,85 @@ var _move := false
|
||||||
|
|
||||||
|
|
||||||
func draw_start(position : Vector2) -> void:
|
func draw_start(position : Vector2) -> void:
|
||||||
if Global.selection_rectangle.has_point(position):
|
var i := 0
|
||||||
|
for selection in Global.current_project.selections:
|
||||||
|
if selection.has_point(position):
|
||||||
|
current_selection_id = i
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
if current_selection_id == -1:
|
||||||
|
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)
|
||||||
|
_start = Rect2(position, Vector2.ZERO)
|
||||||
|
selection_shape.set_rect(_start)
|
||||||
|
else:
|
||||||
|
var selection : SelectionShape = Global.current_project.selections[current_selection_id]
|
||||||
_move = true
|
_move = true
|
||||||
_offset = position
|
_offset = position
|
||||||
Global.selection_rectangle.move_start(Tools.shift)
|
start_position = position
|
||||||
_set_cursor_text(Global.selection_rectangle.get_rect())
|
_set_cursor_text(selection.get_rect())
|
||||||
else:
|
# if Global.selection_rectangle.has_point(position):
|
||||||
_drag = true
|
# _move = true
|
||||||
_start = Rect2(position, Vector2.ZERO)
|
# _offset = position
|
||||||
Global.selection_rectangle.set_rect(_start)
|
# Global.selection_rectangle.move_start(Tools.shift)
|
||||||
|
# _set_cursor_text(Global.selection_rectangle.get_rect())
|
||||||
|
# else:
|
||||||
|
# _drag = true
|
||||||
|
# _start = Rect2(position, Vector2.ZERO)
|
||||||
|
# Global.selection_rectangle.set_rect(_start)
|
||||||
|
|
||||||
|
|
||||||
func draw_move(position : Vector2) -> void:
|
func draw_move(position : Vector2) -> void:
|
||||||
|
var selection : SelectionShape = Global.current_project.selections[current_selection_id]
|
||||||
|
|
||||||
if _move:
|
if _move:
|
||||||
Global.selection_rectangle.move_rect(position - _offset)
|
for _selection in Global.current_project.selections:
|
||||||
|
_selection.move_polygon(position - _offset)
|
||||||
_offset = position
|
_offset = position
|
||||||
_set_cursor_text(Global.selection_rectangle.get_rect())
|
_set_cursor_text(selection.get_rect())
|
||||||
else:
|
else:
|
||||||
var rect := _start.expand(position).abs()
|
var rect := _start.expand(position).abs()
|
||||||
rect = rect.grow_individual(0, 0, 1, 1)
|
rect = rect.grow_individual(0, 0, 1, 1)
|
||||||
Global.selection_rectangle.set_rect(rect)
|
selection.set_rect(rect)
|
||||||
_set_cursor_text(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:
|
func draw_end(position : Vector2) -> void:
|
||||||
if _move:
|
if _move:
|
||||||
Global.selection_rectangle.move_end()
|
for _selection in Global.current_project.selections:
|
||||||
|
_selection.move_polygon_end(position, start_position)
|
||||||
else:
|
else:
|
||||||
Global.selection_rectangle.select_rect()
|
var selection : SelectionShape = Global.current_project.selections[current_selection_id]
|
||||||
_drag = false
|
selection.select_rect()
|
||||||
|
# _drag = false
|
||||||
_move = false
|
_move = false
|
||||||
cursor_text = ""
|
cursor_text = ""
|
||||||
|
start_position = Vector2.INF
|
||||||
|
current_selection_id = -1
|
||||||
|
|
||||||
|
|
||||||
func cursor_move(position : Vector2) -> void:
|
func cursor_move(_position : Vector2) -> void:
|
||||||
if _drag:
|
pass
|
||||||
_cursor = Vector2.INF
|
# if _drag:
|
||||||
elif Global.selection_rectangle.has_point(position):
|
# _cursor = Vector2.INF
|
||||||
_cursor = Vector2.INF
|
# elif Global.selection_rectangle.has_point(position):
|
||||||
Global.main_viewport.mouse_default_cursor_shape = Input.CURSOR_MOVE
|
# _cursor = Vector2.INF
|
||||||
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
# Global.main_viewport.mouse_default_cursor_shape = Input.CURSOR_MOVE
|
||||||
else:
|
# Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
||||||
_cursor = position
|
# else:
|
||||||
Global.main_viewport.mouse_default_cursor_shape = Input.CURSOR_CROSS
|
# _cursor = position
|
||||||
|
# Global.main_viewport.mouse_default_cursor_shape = Input.CURSOR_CROSS
|
||||||
|
|
||||||
|
|
||||||
func _set_cursor_text(rect : Rect2) -> void:
|
func _set_cursor_text(rect : Rect2) -> void:
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
extends Polygon2D
|
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 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)
|
||||||
var _move_image := Image.new()
|
var _move_image := Image.new()
|
||||||
|
@ -53,6 +55,20 @@ func _draw() -> void:
|
||||||
var end := Vector2(end_x, end_y)
|
var end := Vector2(end_x, end_y)
|
||||||
draw_dashed_line(start, end, Color.white, Color.black, 1.0, 1.0, false)
|
draw_dashed_line(start, end, Color.white, Color.black, 1.0, 1.0, false)
|
||||||
|
|
||||||
|
if !local_selected_pixels:
|
||||||
|
return
|
||||||
|
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:
|
if _move_pixel:
|
||||||
draw_texture(_move_texture, _clipped_rect.position, Color(1, 1, 1, 0.5))
|
draw_texture(_move_texture, _clipped_rect.position, Color(1, 1, 1, 0.5))
|
||||||
|
|
||||||
|
@ -114,8 +130,22 @@ func draw_dashed_line(from : Vector2, to : Vector2, color : Color, color2 : Colo
|
||||||
draw_line(segment_start, to, color, width, antialiased)
|
draw_line(segment_start, to, color, width, antialiased)
|
||||||
|
|
||||||
|
|
||||||
|
func _local_selected_pixels_changed(value : Array) -> void:
|
||||||
|
for pixel in local_selected_pixels:
|
||||||
|
if pixel in Global.current_project.selected_pixels:
|
||||||
|
Global.current_project.selected_pixels.erase(pixel)
|
||||||
|
|
||||||
|
local_selected_pixels = value
|
||||||
|
|
||||||
|
for pixel in local_selected_pixels:
|
||||||
|
if pixel in Global.current_project.selected_pixels:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
Global.current_project.selected_pixels.append(pixel)
|
||||||
|
|
||||||
|
|
||||||
func has_point(position : Vector2) -> bool:
|
func has_point(position : Vector2) -> bool:
|
||||||
return _selected_rect.has_point(position)
|
return Geometry.is_point_in_polygon(position, polygon)
|
||||||
|
|
||||||
|
|
||||||
func get_rect() -> Rect2:
|
func get_rect() -> Rect2:
|
||||||
|
@ -128,32 +158,69 @@ func set_rect(rect : Rect2) -> void:
|
||||||
polygon[1] = Vector2(rect.end.x, rect.position.y)
|
polygon[1] = Vector2(rect.end.x, rect.position.y)
|
||||||
polygon[2] = rect.end
|
polygon[2] = rect.end
|
||||||
polygon[3] = Vector2(rect.position.x, rect.end.y)
|
polygon[3] = Vector2(rect.position.x, rect.end.y)
|
||||||
visible = not rect.has_no_area()
|
# visible = not rect.has_no_area()
|
||||||
|
|
||||||
var project : Project = Global.current_project
|
|
||||||
if rect.has_no_area():
|
|
||||||
project.selected_pixels = []
|
|
||||||
else:
|
|
||||||
project.clear_selection()
|
|
||||||
for x in range(rect.position.x, rect.end.x):
|
|
||||||
for y in range(rect.position.y, rect.end.y):
|
|
||||||
if x < 0 or x >= project.size.x:
|
|
||||||
continue
|
|
||||||
if y < 0 or y >= project.size.y:
|
|
||||||
continue
|
|
||||||
project.selected_pixels.append(Vector2(x, y))
|
|
||||||
|
|
||||||
|
|
||||||
func move_rect(move : Vector2) -> void:
|
func move_polygon(move : Vector2) -> void:
|
||||||
_selected_rect.position += move
|
_selected_rect.position += move
|
||||||
_clipped_rect.position += move
|
_clipped_rect.position += move
|
||||||
set_rect(_selected_rect)
|
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() -> void:
|
func select_rect() -> void:
|
||||||
var undo_data = _get_undo_data(false)
|
var project : Project = Global.current_project
|
||||||
Global.current_project.selected_rect = _selected_rect
|
self.local_selected_pixels = []
|
||||||
commit_undo("Rectangle Select", undo_data)
|
var selected_pixels_copy = local_selected_pixels.duplicate()
|
||||||
|
for x in range(_selected_rect.position.x, _selected_rect.end.x):
|
||||||
|
for y in range(_selected_rect.position.y, _selected_rect.end.y):
|
||||||
|
var pos := Vector2(x, y)
|
||||||
|
# if polygon.size() > 4: # if it's not a rectangle
|
||||||
|
# if !Geometry.is_point_in_polygon(pos, polygon):
|
||||||
|
# continue
|
||||||
|
if x < 0 or x >= project.size.x:
|
||||||
|
continue
|
||||||
|
if y < 0 or y >= project.size.y:
|
||||||
|
continue
|
||||||
|
selected_pixels_copy.append(pos)
|
||||||
|
|
||||||
|
self.local_selected_pixels = selected_pixels_copy
|
||||||
|
if local_selected_pixels.size() == 0:
|
||||||
|
queue_free()
|
||||||
|
return
|
||||||
|
merge_multiple_selections()
|
||||||
|
# var undo_data = _get_undo_data(false)
|
||||||
|
# Global.current_project.selected_rect = _selected_rect
|
||||||
|
# commit_undo("Rectangle Select", undo_data)
|
||||||
|
|
||||||
|
|
||||||
|
func merge_multiple_selections() -> void:
|
||||||
|
if Global.current_project.selections.size() < 2:
|
||||||
|
return
|
||||||
|
for selection in Global.current_project.selections:
|
||||||
|
if selection == self:
|
||||||
|
continue
|
||||||
|
var arr = Geometry.merge_polygons_2d(polygon, selection.polygon)
|
||||||
|
# print(arr)
|
||||||
|
if arr.size() == 1: # if the selections intersect
|
||||||
|
set_polygon(arr[0])
|
||||||
|
_selected_rect = _selected_rect.merge(selection._selected_rect)
|
||||||
|
var selected_pixels_copy = local_selected_pixels.duplicate()
|
||||||
|
for pixel in selection.local_selected_pixels:
|
||||||
|
selected_pixels_copy.append(pixel)
|
||||||
|
selection.clear_selection_on_tree_exit = false
|
||||||
|
selection.queue_free()
|
||||||
|
self.local_selected_pixels = selected_pixels_copy
|
||||||
|
|
||||||
|
|
||||||
func move_start(move_pixel : bool) -> void:
|
func move_start(move_pixel : bool) -> void:
|
||||||
|
@ -283,3 +350,9 @@ func _get_undo_data(undo_image : bool) -> Dictionary:
|
||||||
data["image_data"] = image.data
|
data["image_data"] = image.data
|
||||||
image.lock()
|
image.lock()
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
func _on_SelectionShape_tree_exiting() -> void:
|
||||||
|
Global.current_project.selections.erase(self)
|
||||||
|
if clear_selection_on_tree_exit:
|
||||||
|
self.local_selected_pixels = []
|
12
src/Tools/SelectionShape.tscn
Normal file
12
src/Tools/SelectionShape.tscn
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[gd_scene load_steps=2 format=2]
|
||||||
|
|
||||||
|
[ext_resource path="res://src/Tools/SelectionShape.gd" type="Script" id=1]
|
||||||
|
|
||||||
|
[node name="SelectionShape" type="Polygon2D"]
|
||||||
|
z_index = 1
|
||||||
|
color = Color( 1, 1, 1, 0 )
|
||||||
|
invert_enable = true
|
||||||
|
invert_border = 0.5
|
||||||
|
polygon = PoolVector2Array( 0, 0, 0, 0, 0, 0, 0, 0 )
|
||||||
|
script = ExtResource( 1 )
|
||||||
|
[connection signal="tree_exiting" from="." to="." method="_on_SelectionShape_tree_exiting"]
|
|
@ -257,16 +257,21 @@ func edit_menu_id_pressed(id : int) -> void:
|
||||||
Global.current_project.undo_redo.redo()
|
Global.current_project.undo_redo.redo()
|
||||||
Global.control.redone = false
|
Global.control.redone = false
|
||||||
EditMenuId.COPY:
|
EditMenuId.COPY:
|
||||||
Global.selection_rectangle.copy()
|
pass
|
||||||
|
# Global.selection_rectangl.copy()
|
||||||
EditMenuId.CUT:
|
EditMenuId.CUT:
|
||||||
Global.selection_rectangle.cut()
|
pass
|
||||||
|
# Global.selection_rectangl.cut()
|
||||||
EditMenuId.PASTE:
|
EditMenuId.PASTE:
|
||||||
Global.selection_rectangle.paste()
|
pass
|
||||||
|
# Global.selection_rectangl.paste()
|
||||||
EditMenuId.DELETE:
|
EditMenuId.DELETE:
|
||||||
Global.selection_rectangle.delete()
|
pass
|
||||||
|
# Global.selection_rectangl.delete()
|
||||||
EditMenuId.CLEAR_SELECTION:
|
EditMenuId.CLEAR_SELECTION:
|
||||||
Global.selection_rectangle.set_rect(Rect2(0, 0, 0, 0))
|
pass
|
||||||
Global.selection_rectangle.select_rect()
|
# Global.selection_rectangl.set_rect(Rect2(0, 0, 0, 0))
|
||||||
|
# Global.selection_rectangl.select_rect()
|
||||||
EditMenuId.PREFERENCES:
|
EditMenuId.PREFERENCES:
|
||||||
Global.preferences_dialog.popup_centered(Vector2(400, 280))
|
Global.preferences_dialog.popup_centered(Vector2(400, 280))
|
||||||
Global.dialog_open(true)
|
Global.dialog_open(true)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
[gd_scene load_steps=28 format=2]
|
[gd_scene load_steps=27 format=2]
|
||||||
|
|
||||||
[ext_resource path="res://src/UI/ToolButtons.gd" type="Script" id=1]
|
[ext_resource path="res://src/UI/ToolButtons.gd" type="Script" id=1]
|
||||||
[ext_resource path="res://src/UI/Canvas/CanvasPreview.tscn" type="PackedScene" id=2]
|
[ext_resource path="res://src/UI/Canvas/CanvasPreview.tscn" type="PackedScene" id=2]
|
||||||
|
@ -7,7 +7,6 @@
|
||||||
[ext_resource path="res://src/UI/TransparentChecker.tscn" type="PackedScene" id=5]
|
[ext_resource path="res://src/UI/TransparentChecker.tscn" type="PackedScene" id=5]
|
||||||
[ext_resource path="res://src/UI/Canvas/Rulers/HorizontalRuler.gd" type="Script" id=6]
|
[ext_resource path="res://src/UI/Canvas/Rulers/HorizontalRuler.gd" type="Script" id=6]
|
||||||
[ext_resource path="res://src/UI/Canvas/CameraMovement.gd" type="Script" id=7]
|
[ext_resource path="res://src/UI/Canvas/CameraMovement.gd" type="Script" id=7]
|
||||||
[ext_resource path="res://src/SelectionRectangle.gd" type="Script" id=8]
|
|
||||||
[ext_resource path="res://src/Shaders/TransparentChecker.shader" type="Shader" id=9]
|
[ext_resource path="res://src/Shaders/TransparentChecker.shader" type="Shader" id=9]
|
||||||
[ext_resource path="res://assets/graphics/dark_themes/tools/bucket.png" type="Texture" id=10]
|
[ext_resource path="res://assets/graphics/dark_themes/tools/bucket.png" type="Texture" id=10]
|
||||||
[ext_resource path="res://assets/graphics/dark_themes/tools/colorpicker.png" type="Texture" id=11]
|
[ext_resource path="res://assets/graphics/dark_themes/tools/colorpicker.png" type="Texture" id=11]
|
||||||
|
@ -348,15 +347,6 @@ current = true
|
||||||
zoom = Vector2( 0.15, 0.15 )
|
zoom = Vector2( 0.15, 0.15 )
|
||||||
script = ExtResource( 7 )
|
script = ExtResource( 7 )
|
||||||
|
|
||||||
[node name="SelectionRectangle" type="Polygon2D" parent="CanvasAndTimeline/ViewportAndRulers/HSplitContainer/ViewportandVerticalRuler/ViewportContainer/Viewport"]
|
|
||||||
visible = false
|
|
||||||
z_index = 1
|
|
||||||
color = Color( 1, 1, 1, 0 )
|
|
||||||
invert_enable = true
|
|
||||||
invert_border = 0.5
|
|
||||||
polygon = PoolVector2Array( 0, 0, 0, 0, 0, 0, 0, 0 )
|
|
||||||
script = ExtResource( 8 )
|
|
||||||
|
|
||||||
[node name="ViewportContainer2" type="ViewportContainer" parent="CanvasAndTimeline/ViewportAndRulers/HSplitContainer"]
|
[node name="ViewportContainer2" type="ViewportContainer" parent="CanvasAndTimeline/ViewportAndRulers/HSplitContainer"]
|
||||||
margin_left = 902.0
|
margin_left = 902.0
|
||||||
margin_right = 902.0
|
margin_right = 902.0
|
||||||
|
|
Loading…
Add table
Reference in a new issue