Skip to content

Commit

Permalink
Added color picker tool, activated pressing Ctrl
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniele Tolomelli committed Nov 28, 2024
1 parent 5cbb73d commit d87b93d
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class_name ColorPickerCursor
extends BaseCursor

# -------------------------------------------------------------------------------------------------
func _on_zoom_changed(zoom_value: float) -> void:
scale = Vector2.ONE / zoom_value
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[gd_scene load_steps=5 format=3 uid="uid://dmybbclki2clv"]

[ext_resource type="Shader" path="res://InfiniteCanvas/Cursor/cursor.gdshader" id="1_q5575"]
[ext_resource type="Script" path="res://InfiniteCanvas/Cursor/ColorPickerCursor/ColorPickerCursor.gd" id="2_labi7"]
[ext_resource type="Texture2D" uid="uid://tcovt1vw06tr" path="res://Assets/Icons/color_picker.png" id="3_rydea"]

[sub_resource type="ShaderMaterial" id="1"]
shader = ExtResource("1_q5575")

[node name="ColorPickerCursor" type="Sprite2D"]
material = SubResource("1")
script = ExtResource("2_labi7")

[node name="Sprite2D" type="Sprite2D" parent="."]
position = Vector2(7, -7)
texture = ExtResource("3_rydea")
15 changes: 15 additions & 0 deletions lorien/InfiniteCanvas/InfiniteCanvas.gd
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const PLAYER = preload("res://Misc/Player/Player.tscn")
@onready var _circle_tool: CircleTool = $CircleTool
@onready var _eraser_tool: EraserTool = $EraserTool
@onready var _selection_tool: SelectionTool = $SelectionTool
@onready var _color_picker_tool: ColorPickerTool = $ColorPickerTool
@onready var _active_tool: CanvasTool = _brush_tool
@onready var _active_tool_type: int = Types.Tool.BRUSH
@onready var _strokes_parent: Node2D = $SubViewport/Strokes
Expand Down Expand Up @@ -88,6 +89,16 @@ func _process_event(event: InputEvent) -> void:
else:
# restore tool from type
use_tool(_active_tool_type)

if event is InputEventKey:
var keyEvent: InputEventKey = event as InputEventKey
if keyEvent.keycode == KEY_CTRL:
if keyEvent.pressed:
var tool_type := _active_tool_type
use_tool(Types.Tool.COLOR_PICKER)
_active_tool_type = tool_type
else:
use_tool(_active_tool_type)

if event.is_action("deselect_all_strokes"):
if _active_tool == _selection_tool:
Expand Down Expand Up @@ -133,6 +144,10 @@ func use_tool(tool_type: int) -> void:
Types.Tool.SELECT:
_active_tool = _selection_tool
_use_optimizer = false
Types.Tool.COLOR_PICKER:
_active_tool = _color_picker_tool
_use_optimizer = false


if prev_tool != _active_tool:
prev_tool.enabled = false
Expand Down
8 changes: 8 additions & 0 deletions lorien/InfiniteCanvas/InfiniteCanvas.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@
[ext_resource type="Script" path="res://InfiniteCanvas/Tools/SelectionTool.gd" id="7"]
[ext_resource type="PackedScene" path="res://InfiniteCanvas/Cursor/SelectionCursor/SelectionCursor.tscn" id="8"]
[ext_resource type="Script" path="res://InfiniteCanvas/Tools/SelectionRectangle.gd" id="9"]
[ext_resource type="Script" path="res://InfiniteCanvas/Tools/ColorPickerTool.gd" id="9_xqyd5"]
[ext_resource type="Shader" path="res://InfiniteCanvas/Tools/selection_rectangle.gdshader" id="10"]
[ext_resource type="Script" path="res://InfiniteCanvas/Tools/RectangleTool.gd" id="11"]
[ext_resource type="Script" path="res://InfiniteCanvas/InfiniteCanvasGrid.gd" id="12"]
[ext_resource type="Script" path="res://InfiniteCanvas/Tools/CircleTool.gd" id="13"]
[ext_resource type="Script" path="res://InfiniteCanvas/Tools/EraserTool.gd" id="14"]
[ext_resource type="Script" path="res://InfiniteCanvas/DebugDraw.gd" id="15"]
[ext_resource type="PackedScene" uid="uid://dmybbclki2clv" path="res://InfiniteCanvas/Cursor/ColorPickerCursor/ColorPickerCursor.tscn" id="16_mifpa"]

[sub_resource type="ShaderMaterial" id="1"]
shader = ExtResource("10")
Expand Down Expand Up @@ -55,6 +57,10 @@ script = ExtResource("7")
selection_rectangle_path = NodePath("../SubViewport/SelectionRectangle")
cursor_path = NodePath("../SubViewport/SelectionCursor")

[node name="ColorPickerTool" type="Node" parent="."]
script = ExtResource("9_xqyd5")
cursor_path = NodePath("../SubViewport/ColorPickerCursor")

[node name="SubViewport" type="SubViewport" parent="."]
handle_input_locally = false
size = Vector2i(1920, 1080)
Expand All @@ -80,3 +86,5 @@ script = ExtResource("9")
[node name="BrushCursor" parent="SubViewport" instance=ExtResource("4")]

[node name="SelectionCursor" parent="SubViewport" instance=ExtResource("8")]

[node name="ColorPickerCursor" parent="SubViewport" instance=ExtResource("16_mifpa")]
63 changes: 63 additions & 0 deletions lorien/InfiniteCanvas/Tools/ColorPickerTool.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
class_name ColorPickerTool extends CanvasTool

# -------------------------------------------------------------------------------------------------
func tool_event(event: InputEvent) -> void:
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.is_pressed():
var picked_color = _pick_color(_cursor.global_position)
if picked_color != Color.TRANSPARENT:
GlobalSignals.color_changed.emit(picked_color)


# -------------------------------------------------------------------------------------------------
func _pick_color(pos: Vector2) -> Color:
var strokes = _canvas.get_all_strokes()
# search the strokes in reverse order to prioritize latest strokes
# since these are drawn on top and then are prioritized
for i in range(strokes.size() - 1, -1, -1):
var stroke = strokes[i]
if stroke.points.is_empty():
continue

# bounding box check
var bbox = Rect2(stroke.top_left_pos, stroke.bottom_right_pos - stroke.top_left_pos)
# grow the bounding box to enclose not only the stroke points but also its size
bbox.grow(stroke.size)
if not bbox.has_point(pos):
continue

# if the stroke has only 1 point, check the distance to this single point
if stroke.points.size() == 1:
if pos.distance_to(pos) < 0.5 * stroke.size:
return stroke.color
else:
continue

# if the stroke has more points, check if the distance between the cursor the and line
# between two points is less than the stroke size
# is used the formula to compute the distance between a point and a line
for p in range(stroke.points.size() - 1):
# the picker must be between the line points
# so the dot product between the direction from the picker to the points must be large
var p1: Vector2 = stroke.points[p]
var p2: Vector2 = stroke.points[p + 1]
# check first distance the distance between the first point
if p1.distance_squared_to(pos) < (stroke.size * stroke.size):
return stroke.color
var dir1 = pos.direction_to(p1)
var dir2 = pos.direction_to(p2)
if dir1.dot(dir2) > 0.5:
continue

# formula to check the distance from the point to the line
var a = p2.y - p1.y
var b = p2.x - p1.x
var c = p2.x * p1.y - p2.y * p1.x
var denom = sqrt(a * a + b * b)
if denom == 0.0:
continue
var dist = abs(a * pos.x - b * pos.y + c) / denom
if dist < 0.5 * stroke.size:
return stroke.color

# if the pos is too far away from any stroke, return a transparent color instead
return Color.TRANSPARENT
1 change: 1 addition & 0 deletions lorien/Main.gd
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ func _ready() -> void:

_brush_color_picker.closed.connect(_on_BrushColorPicker_closed)
_brush_color_picker.color_changed.connect(_on_BrushColorPicker_color_changed)
GlobalSignals.connect("color_changed", self._on_BrushColorPicker_color_changed)

_new_palette_dialog.new_palette_created.connect(_on_NewPaletteDialog_new_palette_created)
_delete_palette_dialog.palette_deleted.connect(_on_DeletePaletteDialog_palette_deleted)
Expand Down
1 change: 1 addition & 0 deletions lorien/Misc/GlobalSignals.gd
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ extends Node
# -------------------------------------------------------------------------------------------------
signal language_changed
signal keybinding_changed(action: KeybindingsManager.Action)
signal color_changed(color: Color)
1 change: 1 addition & 0 deletions lorien/Misc/Types.gd
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ enum Tool {
LINE,
ERASER,
SELECT,
COLOR_PICKER
}

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

0 comments on commit d87b93d

Please sign in to comment.