Skip to content

Commit

Permalink
Select stroke when at least one point is in selection rectangle
Browse files Browse the repository at this point in the history
  • Loading branch information
mbrlabs committed Jul 21, 2021
1 parent 7e4b6a1 commit 7344dd6
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 6 deletions.
1 change: 1 addition & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Switched to GLES3 backend
- Removed unimplemented color-preset ui-elements from colorpickers
- Introduced a minimum window size so it can't be resized to 0 anymore
- The selection tool now selects any brush stroke when at least one stroke point is inside the selection rectangle

## [0.2.0] - 2021-06-03

Expand Down
4 changes: 4 additions & 0 deletions lorien/BrushStroke/BrushStroke.gd
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ var color: Color setget set_color, get_color
var size: int
var points: Array # Array<Vector2>
var pressures: Array # Array<float>
var top_left_pos: Vector2
var bottom_right_pos: Vector2

# ------------------------------------------------------------------------------------------------
func _ready():
Expand Down Expand Up @@ -117,6 +119,8 @@ func refresh() -> void:
bottom_right.y = max(bottom_right.y, point.y)

_line2d.width_curve.bake()
top_left_pos = top_left
bottom_right_pos = bottom_right
_visibility_notifier.rect = Utils.calculate_rect(top_left, bottom_right)

# TODO: calculate bounding box for the visibility notifier and move the correct position
Expand Down
4 changes: 4 additions & 0 deletions lorien/InfiniteCanvas/InfiniteCanvas.gd
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ func get_camera() -> Camera2D:
func get_strokes_in_camera_frustrum() -> Array:
return get_tree().get_nodes_in_group(BrushStroke.GROUP_ONSCREEN)

# -------------------------------------------------------------------------------------------------
func get_all_strokes() -> Array:
return _current_project.strokes

# -------------------------------------------------------------------------------------------------
func enable() -> void:
Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
Expand Down
28 changes: 22 additions & 6 deletions lorien/InfiniteCanvas/Tools/SelectionTool.gd
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ var _multi_selecting: bool
var _mouse_moved_during_pressed := false
var _stroke_positions_before_move := {} # BrushStroke -> Vector2

var _bounding_box_cache = {} # BrushStroke -> Rect2

# ------------------------------------------------------------------------------------------------
func _ready():
_selection_rectangle = get_node(selection_rectangle_path)
Expand All @@ -37,9 +39,11 @@ func _input(event: InputEvent) -> void:
if event.shift:
_state = State.SELECTING
_multi_selecting = true
_build_bounding_boxes()
elif get_selected_strokes().size() == 0:
_state = State.SELECTING
_multi_selecting = false
_build_bounding_boxes()
else:
_state = State.MOVING
_mouse_moved_during_pressed = false
Expand Down Expand Up @@ -92,17 +96,29 @@ func _input(event: InputEvent) -> void:

# ------------------------------------------------------------------------------------------------
func compute_selection(start_pos: Vector2, end_pos: Vector2) -> void:
var rect : Rect2 = Utils.calculate_rect(start_pos, end_pos)
var selection_rect : Rect2 = Utils.calculate_rect(start_pos, end_pos)
for stroke in _canvas.get_strokes_in_camera_frustrum():
# Strokes are selected when the first and last points are in the rect
var first_point: Vector2 = _get_absolute_stroke_point_pos(stroke.points[0], stroke)
var last_point: Vector2 = _get_absolute_stroke_point_pos(stroke.points.back(), stroke)
var is_inside_selection_rect := rect.has_point(first_point) && rect.has_point(last_point)
var bounding_box: Rect2 = _bounding_box_cache[stroke]
var is_inside_selection_rect := false
if selection_rect.intersects(bounding_box):
for point in stroke.points:
if selection_rect.has_point(_calc_abs_stroke_point(point, stroke)):
is_inside_selection_rect = true
break
_set_stroke_selected(stroke, is_inside_selection_rect)
_canvas.info.selected_lines = get_selected_strokes().size()

# ------------------------------------------------------------------------------------------------
func _get_absolute_stroke_point_pos(p: Vector2, stroke: BrushStroke) -> Vector2:
func _build_bounding_boxes() -> void:
_bounding_box_cache.clear()
for stroke in _canvas.get_all_strokes():
var top_left := _calc_abs_stroke_point(stroke.top_left_pos, stroke)
var bottom_right := _calc_abs_stroke_point(stroke.bottom_right_pos, stroke)
var bounding_box := Utils.calculate_rect(top_left, bottom_right)
_bounding_box_cache[stroke] = bounding_box

# ------------------------------------------------------------------------------------------------
func _calc_abs_stroke_point(p: Vector2, stroke: BrushStroke) -> Vector2:
return (p + stroke.position - _canvas.get_camera_offset()) / _canvas.get_camera_zoom()

# ------------------------------------------------------------------------------------------------
Expand Down

0 comments on commit 7344dd6

Please sign in to comment.