diff --git a/src/logic-scenes/board/card collider.gd b/src/logic-scenes/board/card collider.gd index fc8c7cb..b95c476 100644 --- a/src/logic-scenes/board/card collider.gd +++ b/src/logic-scenes/board/card collider.gd @@ -1,9 +1,4 @@ class_name CardCollider -extends Area2D +extends Draggable @export var direction: Vector2 = Vector2.ZERO - -var is_dragged: bool = false: - set(dragged): - is_dragged = dragged - z_index = int(dragged) diff --git a/src/logic-scenes/board/card.gd b/src/logic-scenes/board/card.gd index b56494b..57f94f6 100644 --- a/src/logic-scenes/board/card.gd +++ b/src/logic-scenes/board/card.gd @@ -228,6 +228,7 @@ func _on_input_event(_viewport, event, _shape_idx): func _move_card(): if is_dragged: position += (get_viewport().get_mouse_position() - position) - mouse_offset + confine_to_screen() func has_sticky_note_attached() -> bool: return get_attached_sticky_note() != null diff --git a/src/logic-scenes/board/draggable.gd b/src/logic-scenes/board/draggable.gd new file mode 100644 index 0000000..2136905 --- /dev/null +++ b/src/logic-scenes/board/draggable.gd @@ -0,0 +1,72 @@ +class_name Draggable +extends Area2D + +## Base class for draggable UI elements (Cards and StickyNotes) +## Provides common dragging behavior and boundary protection + +var is_dragged: bool = false: + set(dragged): + is_dragged = dragged + z_index = int(dragged) + +## Margin from screen edges when confining to screen bounds +@export var screen_margin: float = 50.0 + +## Confines this draggable element to stay within screen or container bounds +## Skip this check if a sticky note is attached to a card +func confine_to_screen() -> void: + # Skip if this is a sticky note attached to a card + if self is StickyNote: + var sticky := self as StickyNote + if sticky.attached_to is Card: + return + + # Try to get bounds from parent container + var bounds := _get_container_bounds() + + # If no container bounds, use viewport/screen bounds + if bounds == Rect2(): + bounds = _get_viewport_bounds() + + # If we have valid bounds, clamp position + if bounds != Rect2(): + position.x = clampf(position.x, bounds.position.x, bounds.position.x + bounds.size.x) + position.y = clampf(position.y, bounds.position.y, bounds.position.y + bounds.size.y) + +## Gets the bounds of the parent container if it exists and is a Control node +func _get_container_bounds() -> Rect2: + var parent := get_parent() + + # Check if parent is a Control node with a defined rect + if parent is Control: + var control := parent as Control + # Return the usable area with margins + return Rect2( + screen_margin, + screen_margin, + control.size.x - screen_margin * 2, + control.size.y - screen_margin * 2 + ) + + # Check if parent is a Node2D with defined boundaries + # (for future support of non-Control containers) + if parent is Node2D: + # For now, return empty rect - could be extended in the future + # to check for custom boundary properties + pass + + return Rect2() + +## Gets the viewport bounds as fallback +func _get_viewport_bounds() -> Rect2: + var viewport := get_viewport() + if viewport: + var viewport_size := viewport.get_visible_rect().size + return Rect2( + screen_margin, + screen_margin, + viewport_size.x - screen_margin * 2, + viewport_size.y - screen_margin * 2 + ) + + return Rect2() diff --git a/src/logic-scenes/board/draggable.gd.uid b/src/logic-scenes/board/draggable.gd.uid new file mode 100644 index 0000000..1709597 --- /dev/null +++ b/src/logic-scenes/board/draggable.gd.uid @@ -0,0 +1 @@ +uid://v03l76xq8tcp diff --git a/src/logic-scenes/board/sticky-note.gd b/src/logic-scenes/board/sticky-note.gd index 529da0d..f0c6f25 100644 --- a/src/logic-scenes/board/sticky-note.gd +++ b/src/logic-scenes/board/sticky-note.gd @@ -1,4 +1,4 @@ -extends Area2D +extends Draggable class_name StickyNote var sticky_id @@ -62,11 +62,6 @@ var label: Label @export var is_dragable: bool = false @onready var base_rotation := rotation @onready var base_scale := scale -var is_dragged: bool = false: - set(dragged): - is_dragged = dragged - z_index = int(dragged) - if not is_dragged: highlighted = false var initial_drag_position: Vector2 var mouse_diff: Vector2 @@ -171,6 +166,7 @@ func _move_sticky_note(): if is_dragged: #var old_position = position position = initial_drag_position + get_viewport().get_mouse_position() - mouse_diff + confine_to_screen() if hovering_cards != []: var closest: Card = hovering_cards[0]