2021-05-01 00:10:23 +00:00
|
|
|
class_name SelectionTool extends BaseTool
|
2021-04-27 23:57:48 +00:00
|
|
|
|
|
|
|
|
2021-05-02 23:00:07 +00:00
|
|
|
var _move := false
|
|
|
|
var _move_content := true
|
2021-05-03 15:33:51 +00:00
|
|
|
var _start_pos := Vector2.ZERO
|
2021-05-02 23:00:07 +00:00
|
|
|
var _offset := Vector2.ZERO
|
2021-05-03 15:33:51 +00:00
|
|
|
|
2021-04-27 23:57:48 +00:00
|
|
|
var _add := false # Shift + Mouse Click
|
|
|
|
var _subtract := false # Ctrl + Mouse Click
|
|
|
|
var _intersect := false # Shift + Ctrl + Mouse Click
|
2021-05-03 23:45:14 +00:00
|
|
|
var _snap_to_grid := false # Mouse Click + Ctrl
|
2021-04-27 23:57:48 +00:00
|
|
|
|
|
|
|
var undo_data : Dictionary
|
|
|
|
|
2021-05-03 18:10:49 +00:00
|
|
|
onready var selection_node : Node2D = Global.canvas.selection
|
2021-05-01 00:10:23 +00:00
|
|
|
onready var xspinbox : SpinBox = find_node("XSpinBox")
|
|
|
|
onready var yspinbox : SpinBox = find_node("YSpinBox")
|
|
|
|
onready var wspinbox : SpinBox = find_node("WSpinBox")
|
|
|
|
onready var hspinbox : SpinBox = find_node("HSpinBox")
|
2021-05-10 21:27:57 +00:00
|
|
|
onready var timer : Timer = $Timer
|
2021-05-01 00:10:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
func _ready() -> void:
|
2021-05-08 21:56:23 +00:00
|
|
|
set_spinbox_values()
|
2021-05-01 00:10:23 +00:00
|
|
|
|
2021-04-27 23:57:48 +00:00
|
|
|
|
2021-05-03 23:45:14 +00:00
|
|
|
func _input(event : InputEvent) -> void:
|
|
|
|
if _move:
|
|
|
|
if event.is_action_pressed("ctrl"):
|
|
|
|
_snap_to_grid = true
|
|
|
|
var grid_size := Vector2(Global.grid_width, Global.grid_height)
|
|
|
|
_offset = _offset.snapped(grid_size)
|
|
|
|
var prev_pos = selection_node.big_bounding_rectangle.position
|
|
|
|
selection_node.big_bounding_rectangle.position = selection_node.big_bounding_rectangle.position.snapped(grid_size)
|
|
|
|
selection_node.marching_ants_outline.offset += selection_node.big_bounding_rectangle.position - prev_pos
|
|
|
|
elif event.is_action_released("ctrl"):
|
|
|
|
_snap_to_grid = false
|
|
|
|
|
|
|
|
|
2021-05-08 21:56:23 +00:00
|
|
|
func set_spinbox_values() -> void:
|
|
|
|
var select_rect : Rect2 = selection_node.big_bounding_rectangle
|
|
|
|
xspinbox.editable = !select_rect.has_no_area()
|
|
|
|
yspinbox.editable = !select_rect.has_no_area()
|
|
|
|
wspinbox.editable = !select_rect.has_no_area()
|
|
|
|
hspinbox.editable = !select_rect.has_no_area()
|
|
|
|
|
|
|
|
xspinbox.value = select_rect.position.x
|
|
|
|
yspinbox.value = select_rect.position.y
|
|
|
|
wspinbox.value = select_rect.size.x
|
|
|
|
hspinbox.value = select_rect.size.y
|
|
|
|
|
|
|
|
|
2021-05-02 23:00:07 +00:00
|
|
|
func draw_start(position : Vector2) -> void:
|
2021-05-07 01:33:28 +00:00
|
|
|
if selection_node.arrow_key_move:
|
|
|
|
return
|
2021-05-03 18:10:49 +00:00
|
|
|
var project : Project = Global.current_project
|
|
|
|
undo_data = selection_node._get_undo_data(false)
|
2021-04-27 23:57:48 +00:00
|
|
|
_intersect = Tools.shift && Tools.control
|
|
|
|
_add = Tools.shift && !_intersect
|
|
|
|
_subtract = Tools.control && !_intersect
|
2021-05-03 15:33:51 +00:00
|
|
|
_start_pos = position
|
2021-05-03 00:11:12 +00:00
|
|
|
_offset = position
|
2021-04-27 23:57:48 +00:00
|
|
|
|
2021-05-03 18:10:49 +00:00
|
|
|
var selection_position : Vector2 = selection_node.big_bounding_rectangle.position
|
2021-05-02 23:00:07 +00:00
|
|
|
var offsetted_pos := position
|
|
|
|
if selection_position.x < 0:
|
|
|
|
offsetted_pos.x -= selection_position.x
|
|
|
|
if selection_position.y < 0:
|
|
|
|
offsetted_pos.y -= selection_position.y
|
2021-05-03 18:10:49 +00:00
|
|
|
if offsetted_pos.x >= 0 and offsetted_pos.y >= 0 and project.selection_bitmap.get_bit(offsetted_pos) and (!Tools.control or Tools.alt) and !Tools.shift:
|
2021-05-02 23:00:07 +00:00
|
|
|
# Move current selection
|
|
|
|
_move = true
|
|
|
|
if Tools.control and Tools.alt: # Move selection without content
|
2021-05-03 18:10:49 +00:00
|
|
|
selection_node.transform_content_confirm()
|
2021-05-02 23:00:07 +00:00
|
|
|
_move_content = false
|
2021-05-03 18:10:49 +00:00
|
|
|
selection_node.move_borders_start()
|
2021-05-02 23:00:07 +00:00
|
|
|
else:
|
|
|
|
_move_content = true
|
2021-05-03 18:10:49 +00:00
|
|
|
if Tools.alt: # Move the selection without cutting it from the original position / makes a quick copy of it
|
|
|
|
selection_node.transform_content_confirm()
|
|
|
|
selection_node.transform_content_start()
|
|
|
|
if Tools.alt: # Continuation of the above
|
|
|
|
var cel_image : Image = project.frames[project.current_frame].cels[project.current_layer].image
|
|
|
|
cel_image.blit_rect_mask(selection_node.preview_image, selection_node.preview_image, Rect2(Vector2.ZERO, project.selection_bitmap.get_size()), selection_node.big_bounding_rectangle.position)
|
|
|
|
|
2021-05-02 23:00:07 +00:00
|
|
|
else:
|
2021-05-03 18:10:49 +00:00
|
|
|
selection_node.transform_content_confirm()
|
2021-05-02 23:00:07 +00:00
|
|
|
|
|
|
|
|
|
|
|
func draw_move(position : Vector2) -> void:
|
2021-05-07 01:33:28 +00:00
|
|
|
if selection_node.arrow_key_move:
|
|
|
|
return
|
2021-05-02 23:00:07 +00:00
|
|
|
if _move:
|
2021-05-03 15:33:51 +00:00
|
|
|
if Tools.shift: # Snap to axis
|
|
|
|
var angle := position.angle_to_point(_start_pos)
|
|
|
|
if abs(angle) <= PI / 4 or abs(angle) >= 3*PI / 4:
|
|
|
|
position.y = _start_pos.y
|
|
|
|
else:
|
|
|
|
position.x = _start_pos.x
|
2021-05-03 23:45:14 +00:00
|
|
|
if _snap_to_grid:
|
|
|
|
position = position.snapped(Vector2(Global.grid_width, Global.grid_height))
|
2021-05-03 15:33:51 +00:00
|
|
|
|
2021-05-02 23:00:07 +00:00
|
|
|
if _move_content:
|
2021-05-03 18:10:49 +00:00
|
|
|
selection_node.move_content(position - _offset)
|
2021-05-02 23:00:07 +00:00
|
|
|
else:
|
2021-05-03 18:10:49 +00:00
|
|
|
selection_node.move_borders(position - _offset)
|
2021-05-03 15:33:51 +00:00
|
|
|
|
2021-05-02 23:00:07 +00:00
|
|
|
_offset = position
|
2021-05-03 18:10:49 +00:00
|
|
|
_set_cursor_text(selection_node.big_bounding_rectangle)
|
2021-05-02 23:00:07 +00:00
|
|
|
|
|
|
|
|
|
|
|
func draw_end(_position : Vector2) -> void:
|
2021-05-07 01:33:28 +00:00
|
|
|
if selection_node.arrow_key_move:
|
|
|
|
return
|
2021-05-02 23:00:07 +00:00
|
|
|
if _move:
|
2021-05-10 15:44:12 +00:00
|
|
|
selection_node.move_borders_end()
|
2021-05-02 23:00:07 +00:00
|
|
|
else:
|
|
|
|
apply_selection(_position)
|
|
|
|
|
|
|
|
_move = false
|
2021-05-03 23:45:14 +00:00
|
|
|
_snap_to_grid = false
|
2021-05-02 23:00:07 +00:00
|
|
|
cursor_text = ""
|
|
|
|
|
|
|
|
|
|
|
|
func apply_selection(_position : Vector2) -> void:
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
func _set_cursor_text(rect : Rect2) -> void:
|
|
|
|
cursor_text = "%s, %s" % [rect.position.x, rect.position.y]
|
|
|
|
cursor_text += " -> %s, %s" % [rect.end.x - 1, rect.end.y - 1]
|
|
|
|
cursor_text += " (%s, %s)" % [rect.size.x, rect.size.y]
|
|
|
|
|
|
|
|
|
2021-05-01 00:10:23 +00:00
|
|
|
func _on_XSpinBox_value_changed(value : float) -> void:
|
|
|
|
var project : Project = Global.current_project
|
2021-05-03 18:10:49 +00:00
|
|
|
if !project.has_selection or selection_node.big_bounding_rectangle.position.x == value:
|
2021-05-01 00:10:23 +00:00
|
|
|
return
|
2021-05-10 21:27:57 +00:00
|
|
|
if timer.is_stopped():
|
|
|
|
undo_data = selection_node._get_undo_data(false)
|
|
|
|
timer.start()
|
2021-05-03 18:10:49 +00:00
|
|
|
selection_node.big_bounding_rectangle.position.x = value
|
2021-05-01 00:10:23 +00:00
|
|
|
|
|
|
|
var selection_bitmap_copy : BitMap = project.selection_bitmap.duplicate()
|
|
|
|
project.move_bitmap_values(selection_bitmap_copy)
|
|
|
|
project.selection_bitmap = selection_bitmap_copy
|
|
|
|
project.selection_bitmap_changed()
|
|
|
|
|
|
|
|
|
|
|
|
func _on_YSpinBox_value_changed(value : float) -> void:
|
|
|
|
var project : Project = Global.current_project
|
2021-05-03 18:10:49 +00:00
|
|
|
if !project.has_selection or selection_node.big_bounding_rectangle.position.y == value:
|
2021-05-01 00:10:23 +00:00
|
|
|
return
|
2021-05-10 21:27:57 +00:00
|
|
|
if timer.is_stopped():
|
|
|
|
undo_data = selection_node._get_undo_data(false)
|
|
|
|
timer.start()
|
2021-05-03 18:10:49 +00:00
|
|
|
selection_node.big_bounding_rectangle.position.y = value
|
2021-05-01 00:10:23 +00:00
|
|
|
|
|
|
|
var selection_bitmap_copy : BitMap = project.selection_bitmap.duplicate()
|
|
|
|
project.move_bitmap_values(selection_bitmap_copy)
|
|
|
|
project.selection_bitmap = selection_bitmap_copy
|
|
|
|
project.selection_bitmap_changed()
|
|
|
|
|
|
|
|
|
|
|
|
func _on_WSpinBox_value_changed(value : float) -> void:
|
|
|
|
var project : Project = Global.current_project
|
2021-05-03 18:10:49 +00:00
|
|
|
if !project.has_selection or selection_node.big_bounding_rectangle.size.x == value or selection_node.big_bounding_rectangle.size.x <= 0:
|
2021-05-01 00:10:23 +00:00
|
|
|
return
|
2021-05-10 21:27:57 +00:00
|
|
|
if timer.is_stopped():
|
|
|
|
undo_data = selection_node._get_undo_data(false)
|
|
|
|
timer.start()
|
2021-05-03 18:10:49 +00:00
|
|
|
selection_node.big_bounding_rectangle.size.x = value
|
2021-05-01 00:10:23 +00:00
|
|
|
resize_selection()
|
|
|
|
|
|
|
|
|
|
|
|
func _on_HSpinBox_value_changed(value : float) -> void:
|
|
|
|
var project : Project = Global.current_project
|
2021-05-03 18:10:49 +00:00
|
|
|
if !project.has_selection or selection_node.big_bounding_rectangle.size.y == value or selection_node.big_bounding_rectangle.size.y <= 0:
|
2021-05-01 00:10:23 +00:00
|
|
|
return
|
2021-05-10 21:27:57 +00:00
|
|
|
if timer.is_stopped():
|
|
|
|
undo_data = selection_node._get_undo_data(false)
|
|
|
|
timer.start()
|
2021-05-03 18:10:49 +00:00
|
|
|
selection_node.big_bounding_rectangle.size.y = value
|
2021-05-01 00:10:23 +00:00
|
|
|
resize_selection()
|
2021-04-27 23:57:48 +00:00
|
|
|
|
|
|
|
|
2021-05-01 00:10:23 +00:00
|
|
|
func resize_selection() -> void:
|
|
|
|
var project : Project = Global.current_project
|
2021-05-10 21:27:57 +00:00
|
|
|
var bitmap : BitMap = project.selection_bitmap
|
2021-05-03 18:10:49 +00:00
|
|
|
if selection_node.is_moving_content:
|
2021-05-10 21:27:57 +00:00
|
|
|
bitmap = selection_node.original_bitmap
|
2021-05-03 18:10:49 +00:00
|
|
|
var preview_image : Image = selection_node.preview_image
|
|
|
|
preview_image.copy_from(selection_node.original_preview_image)
|
|
|
|
preview_image.resize(selection_node.big_bounding_rectangle.size.x, selection_node.big_bounding_rectangle.size.y, Image.INTERPOLATE_NEAREST)
|
|
|
|
selection_node.preview_image_texture.create_from_image(preview_image, 0)
|
2021-05-10 21:27:57 +00:00
|
|
|
|
|
|
|
var selection_bitmap_copy : BitMap = project.selection_bitmap.duplicate()
|
|
|
|
selection_bitmap_copy = project.resize_bitmap_values(bitmap, selection_node.big_bounding_rectangle.size, false, false)
|
|
|
|
project.selection_bitmap = selection_bitmap_copy
|
|
|
|
project.selection_bitmap_changed()
|
|
|
|
|
|
|
|
|
|
|
|
func _on_Timer_timeout() -> void:
|
|
|
|
if !selection_node.is_moving_content:
|
|
|
|
selection_node.commit_undo("Move Selection", undo_data)
|