From 4412671a0885a017f837afc90d38263601b496d9 Mon Sep 17 00:00:00 2001 From: Manolis Papadeas <35376950+OverloadedOrama@users.noreply.github.com> Date: Thu, 22 Apr 2021 18:12:45 +0300 Subject: [PATCH] Add selection intersection with Ctrl + Shift + Mouse click --- src/Tools/ColorSelect.gd | 18 +++++++++++++++--- src/Tools/MagicWand.gd | 18 +++++++++++++++--- src/Tools/RectSelect.gd | 15 +++++++++++---- src/UI/Canvas/Selection.gd | 17 +++++++++++++++-- 4 files changed, 56 insertions(+), 12 deletions(-) diff --git a/src/Tools/ColorSelect.gd b/src/Tools/ColorSelect.gd index 8fccdb70e..e82a9943f 100644 --- a/src/Tools/ColorSelect.gd +++ b/src/Tools/ColorSelect.gd @@ -1,12 +1,18 @@ extends BaseTool +var _add := false # Shift + Mouse Click +var _subtract := false # Ctrl + Mouse Click +var _intersect := false # Shift + Ctrl + Mouse Click var undo_data : Dictionary func draw_start(_position : Vector2) -> void: Global.canvas.selection.move_content_confirm() undo_data = Global.canvas.selection._get_undo_data(false) + _intersect = Tools.shift && Tools.control + _add = Tools.shift && !_intersect + _subtract = Tools.control && !_intersect func draw_move(_position : Vector2) -> void: @@ -20,11 +26,14 @@ func draw_end(position : Vector2) -> void: if position.x > project.size.x - 1 or position.y > project.size.y - 1: return - var subtract_from_selection : bool = Tools.control - if !Tools.shift and !subtract_from_selection: + if !_add and !_subtract and !_intersect: Global.canvas.selection.clear_selection() var selection_bitmap_copy : BitMap = project.selection_bitmap.duplicate() + if _intersect: + var full_rect = Rect2(Vector2.ZERO, selection_bitmap_copy.get_size()) + selection_bitmap_copy.set_bit_rect(full_rect, false) + var cel_image := Image.new() cel_image.copy_from(project.frames[project.current_frame].cels[project.current_layer].image) cel_image.lock() @@ -33,7 +42,10 @@ func draw_end(position : Vector2) -> void: for y in cel_image.get_width(): var pos := Vector2(x, y) if color.is_equal_approx(cel_image.get_pixelv(pos)): - selection_bitmap_copy.set_bit(pos, !subtract_from_selection) + if _intersect: + selection_bitmap_copy.set_bit(pos, project.selection_bitmap.get_bit(pos)) + else: + selection_bitmap_copy.set_bit(pos, !_subtract) cel_image.unlock() project.selection_bitmap = selection_bitmap_copy diff --git a/src/Tools/MagicWand.gd b/src/Tools/MagicWand.gd index a0a6e9bcb..20bea1851 100644 --- a/src/Tools/MagicWand.gd +++ b/src/Tools/MagicWand.gd @@ -1,12 +1,18 @@ extends BaseTool +var _add := false # Shift + Mouse Click +var _subtract := false # Ctrl + Mouse Click +var _intersect := false # Shift + Ctrl + Mouse Click var undo_data : Dictionary func draw_start(_position : Vector2) -> void: Global.canvas.selection.move_content_confirm() undo_data = Global.canvas.selection._get_undo_data(false) + _intersect = Tools.shift && Tools.control + _add = Tools.shift && !_intersect + _subtract = Tools.control && !_intersect func draw_move(_position : Vector2) -> void: @@ -20,11 +26,14 @@ func draw_end(position : Vector2) -> void: if position.x > project.size.x - 1 or position.y > project.size.y - 1: return - var subtract_from_selection : bool = Tools.control - if !Tools.shift and !subtract_from_selection: + if !_add and !_subtract and !_intersect: Global.canvas.selection.clear_selection() var selection_bitmap_copy : BitMap = project.selection_bitmap.duplicate() + if _intersect: + var full_rect = Rect2(Vector2.ZERO, selection_bitmap_copy.get_size()) + selection_bitmap_copy.set_bit_rect(full_rect, false) + var cel_image := Image.new() cel_image.copy_from(project.frames[project.current_frame].cels[project.current_layer].image) cel_image.lock() @@ -45,7 +54,10 @@ func draw_end(position : Vector2) -> void: east += Vector2.RIGHT for px in range(west.x + 1, east.x): var p := Vector2(px, n.y) - selection_bitmap_copy.set_bit(p, !subtract_from_selection) + if _intersect: + selection_bitmap_copy.set_bit(p, project.selection_bitmap.get_bit(p)) + else: + selection_bitmap_copy.set_bit(p, !_subtract) processed.set_bit(p, true) var north := p + Vector2.UP var south := p + Vector2.DOWN diff --git a/src/Tools/RectSelect.gd b/src/Tools/RectSelect.gd index 8531a5d3e..210feb657 100644 --- a/src/Tools/RectSelect.gd +++ b/src/Tools/RectSelect.gd @@ -8,6 +8,7 @@ var _move := false var _add := false # Shift + Mouse Click var _subtract := false # Ctrl + Mouse Click +var _intersect := false # Shift + Ctrl + Mouse Click var _square := false # Mouse Click + Shift var _expand_from_center := false # Mouse Click + Ctrl @@ -44,8 +45,9 @@ func draw_start(position : Vector2) -> void: else: _start_pos = position - _add = Tools.shift - _subtract = Tools.control + _intersect = Tools.shift && Tools.control + _add = Tools.shift && !_intersect + _subtract = Tools.control && !_intersect func draw_move(position : Vector2) -> void: @@ -64,12 +66,17 @@ func draw_end(_position : Vector2) -> void: if _move: Global.canvas.selection.move_borders_end() else: - if !_add and !_subtract: + if !_add and !_subtract and !_intersect: 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, !_subtract) + var operation := 0 + if _subtract: + operation = 1 + elif _intersect: + operation = 2 + Global.canvas.selection.select_rect(_rect, operation) Global.canvas.selection.commit_undo("Rectangle Select", undo_data) _move = false diff --git a/src/UI/Canvas/Selection.gd b/src/UI/Canvas/Selection.gd index a8761e71a..68a514978 100644 --- a/src/UI/Canvas/Selection.gd +++ b/src/UI/Canvas/Selection.gd @@ -35,6 +35,9 @@ class Gizmo: return cursor +enum SelectionOperation {ADD, SUBTRACT, INTERSECT} + + var clipboard := Clipboard.new() var is_moving_content := false var is_pasting := false @@ -244,7 +247,7 @@ func gizmo_rotate() -> void: # Does not work properly yet update() -func select_rect(rect : Rect2, select := true) -> void: +func select_rect(rect : Rect2, operation : int = SelectionOperation.ADD) -> void: var project : Project = Global.current_project var selection_bitmap_copy : BitMap = project.selection_bitmap.duplicate() var offset_position := Vector2.ZERO # Used only if the selection is outside of the canvas boundaries, on the left and/or above (negative coords) @@ -259,7 +262,17 @@ func select_rect(rect : Rect2, select := true) -> void: big_bounding_rectangle.position -= offset_position project.move_bitmap_values(selection_bitmap_copy) - selection_bitmap_copy.set_bit_rect(rect, select) + if operation == SelectionOperation.ADD: + selection_bitmap_copy.set_bit_rect(rect, true) + elif operation == SelectionOperation.SUBTRACT: + selection_bitmap_copy.set_bit_rect(rect, false) + elif operation == SelectionOperation.INTERSECT: + var full_rect = Rect2(Vector2.ZERO, selection_bitmap_copy.get_size()) + selection_bitmap_copy.set_bit_rect(full_rect, false) + for x in range(rect.position.x, rect.end.x): + for y in range(rect.position.y, rect.end.y): + var pos := Vector2(x, y) + selection_bitmap_copy.set_bit(pos, project.selection_bitmap.get_bit(pos)) big_bounding_rectangle = project.get_selection_rectangle(selection_bitmap_copy) if offset_position != Vector2.ZERO: