73 lines
2.1 KiB
GDScript3
73 lines
2.1 KiB
GDScript3
|
|
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()
|