diff --git a/src/Tools/RectSelect.gd b/src/Tools/RectSelect.gd index 18c5bbda9..8531a5d3e 100644 --- a/src/Tools/RectSelect.gd +++ b/src/Tools/RectSelect.gd @@ -2,12 +2,30 @@ extends BaseTool var _rect := Rect2(0, 0, 0, 0) -var _start := Rect2(0, 0, 0, 0) +var _start_pos := Vector2.ZERO var _offset := Vector2.ZERO var _move := false + +var _add := false # Shift + Mouse Click +var _subtract := false # Ctrl + Mouse Click +var _square := false # Mouse Click + Shift +var _expand_from_center := false # Mouse Click + Ctrl + var undo_data : Dictionary +func _input(event : InputEvent) -> void: + if !_move and !_rect.has_no_area(): + if event.is_action_pressed("shift"): + _square = true + elif event.is_action_released("shift"): + _square = false + if event.is_action_pressed("ctrl"): + _expand_from_center = true + elif event.is_action_released("ctrl"): + _expand_from_center = false + + func draw_start(position : Vector2) -> void: Global.canvas.selection.move_content_confirm() undo_data = Global.canvas.selection._get_undo_data(false) @@ -25,7 +43,9 @@ func draw_start(position : Vector2) -> void: Global.canvas.selection.move_borders_start() else: - _start = Rect2(position, Vector2.ZERO) + _start_pos = position + _add = Tools.shift + _subtract = Tools.control func draw_move(position : Vector2) -> void: @@ -34,8 +54,7 @@ func draw_move(position : Vector2) -> void: _offset = position _set_cursor_text(Global.canvas.selection.big_bounding_rectangle) else: - _rect = _start.expand(position).abs() - _rect = _rect.grow_individual(0, 0, 1, 1) + _rect = _get_result_rect(_start_pos, position) _set_cursor_text(_rect) Global.canvas.selection.drawn_rect = _rect Global.canvas.selection.update() @@ -45,12 +64,12 @@ func draw_end(_position : Vector2) -> void: if _move: Global.canvas.selection.move_borders_end() else: - if !Tools.shift and !Tools.control: + if !_add and !_subtract: Global.canvas.selection.clear_selection() if _rect.size == Vector2.ZERO and Global.current_project.has_selection: Global.canvas.selection.commit_undo("Rectangle Select", undo_data) if _rect.size != Vector2.ZERO: - Global.canvas.selection.select_rect(_rect, !Tools.control) + Global.canvas.selection.select_rect(_rect, !_subtract) Global.canvas.selection.commit_undo("Rectangle Select", undo_data) _move = false @@ -58,6 +77,39 @@ func draw_end(_position : Vector2) -> void: _rect = Rect2(0, 0, 0, 0) Global.canvas.selection.drawn_rect = _rect Global.canvas.selection.update() + _square = false + _expand_from_center = false + + +# Given an origin point and destination point, returns a rect representing where the shape will be drawn and what it's size +func _get_result_rect(origin: Vector2, dest: Vector2) -> Rect2: + var rect := Rect2(Vector2.ZERO, Vector2.ZERO) + + # Center the rect on the mouse + if _expand_from_center: + var new_size := (dest - origin).floor() + # Make rect 1:1 while centering it on the mouse + if _square: + var _square_size := max(abs(new_size.x), abs(new_size.y)) + new_size = Vector2(_square_size, _square_size) + + origin -= new_size + dest = origin + 2 * new_size + + # Make rect 1:1 while not trying to center it + if _square: + var square_size := min(abs(origin.x - dest.x), abs(origin.y - dest.y)) + rect.position.x = origin.x if origin.x < dest.x else origin.x - square_size + rect.position.y = origin.y if origin.y < dest.y else origin.y - square_size + rect.size = Vector2(square_size, square_size) + # Get the rect without any modifications + else: + rect.position = Vector2(min(origin.x, dest.x), min(origin.y, dest.y)) + rect.size = (origin - dest).abs() + + rect.size += Vector2.ONE + + return rect func _set_cursor_text(rect : Rect2) -> void: