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()