frame-of-mind/src/logic-scenes/board/sticky_note_panel.gd

134 lines
4.8 KiB
GDScript3
Raw Normal View History

2025-02-24 15:14:08 +00:00
class_name StickyNotePanel
2023-09-23 14:19:58 +00:00
extends Panel
2025-02-24 15:14:08 +00:00
var minimum_size:Vector2 = Vector2(400, 100):
set(size):
minimum_size = size
custom_minimum_size = size
2023-11-01 22:19:47 +00:00
var attached_sticky_note: StickyNote
2025-02-24 15:14:08 +00:00
var ancor_position: Vector2
func _init(cstm_minimum_size: Vector2 = minimum_size, note_position: Vector2 = Vector2(105, 57)) -> void:
minimum_size = cstm_minimum_size
ancor_position = note_position
mouse_filter = MOUSE_FILTER_PASS
self_modulate = Color(1, 1, 1, 0)
2023-09-23 14:19:58 +00:00
func _ready():
2024-09-15 09:30:31 +00:00
custom_minimum_size = Vector2(custom_minimum_size.x, 0)
2025-02-24 15:14:08 +00:00
var is_attatching: bool = false
2025-12-13 11:52:25 +00:00
func attatch_sticky_note(attatchment: StickyNote, custom_owner: Node, tween:bool = true, re_parent:bool = true):
2025-02-24 15:14:08 +00:00
is_attatching = true
2024-09-15 09:30:31 +00:00
attatchment.on_board = false
2025-02-24 15:14:08 +00:00
attached_sticky_note = attatchment
attatchment.attached_to = null
2024-09-15 09:30:31 +00:00
if tween:
2025-02-24 15:14:08 +00:00
await get_tree().process_frame
2024-09-15 09:30:31 +00:00
var height_tween: Tween = create_tween()
2025-02-24 15:14:08 +00:00
height_tween.tween_property(self, "custom_minimum_size", minimum_size, 0.1)
2025-12-13 11:52:25 +00:00
var target_post := get_global_transform().origin+ancor_position
for panel: StickyNotePanel in get_parent().get_children():
if panel.attached_sticky_note == attatchment and panel.get_index() < get_index():
target_post = get_global_transform().origin+ancor_position - Vector2(0, minimum_size.y)
attatchment.tween_transform_to(Transform2D(0, target_post))
2024-09-15 09:30:31 +00:00
await attatchment.transform_tween_finished
await get_tree().process_frame
attatchment.reparent(self)
attatchment.position = ancor_position
2024-09-15 09:30:31 +00:00
else:
custom_minimum_size = minimum_size
2025-12-13 11:52:25 +00:00
if re_parent:
attatchment.reparent(self)
else:
add_child(attatchment)
attatchment.position = ancor_position
2025-02-24 15:14:08 +00:00
is_attatching = false
attatchment.owner = custom_owner
attatchment.attached_to = self
attatchment.current_handle = custom_owner
2025-02-24 15:14:08 +00:00
var is_gapped: bool = false
func create_gap():
var self_id := get_parent().get_children().find(self)
2025-02-24 15:14:08 +00:00
var next_id = min(self_id + 1, get_parent().get_child_count() - 1)
var previous_id = max(self_id - 1, 0)
2024-09-15 09:30:31 +00:00
2025-02-24 15:14:08 +00:00
if not (is_gapped or get_parent().get_child(next_id).attached_sticky_note.is_dragged or get_parent().get_child(previous_id).attached_sticky_note.is_dragged) and owner.current_context == CardBoard.DRAG:
is_gapped = true
var height_tween: Tween = create_tween()
height_tween.tween_property(self, "custom_minimum_size", minimum_size*Vector2(1.0, 1.8), 0.1)
get_parent().get_child(next_id).collapse_gap()
if not get_parent().get_children().find(self) == 0: get_parent().get_child(previous_id).collapse_gap()
func collapse_gap():
if is_gapped:
is_gapped = false
var height_tween: Tween = create_tween()
height_tween.tween_property(self, "custom_minimum_size", minimum_size, 0.1)
func reclaim_sticky_note() -> bool:
# Don't reclaim if sticky is already attached to this panel (prevents double reclaim)
if is_empty() and attached_sticky_note.attached_to != self and attached_sticky_note.attached_to is not Card:
is_attatching = true
2024-09-15 09:30:31 +00:00
attached_sticky_note.on_board = false
attached_sticky_note.z_index = 125 # Make sure it's on top of all other stickies'
# Reparent while keeping world position (global transform)
attached_sticky_note.reparent(self, true)
2025-02-24 15:14:08 +00:00
attached_sticky_note.attached_to = self
2024-09-15 09:30:31 +00:00
attached_sticky_note.owner = self.owner
# Tween from current position to target anchor position in panel's coordinate space
var tween := create_tween().set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_BACK)
tween.tween_property(attached_sticky_note, "position", ancor_position, 0.7)
await tween.finished
attached_sticky_note.z_index = 0
is_attatching = false
2025-02-24 15:14:08 +00:00
return true
return false
var invalid: bool = false
2023-10-12 16:25:21 +00:00
func clear_if_empty():
2024-09-15 09:30:31 +00:00
if !is_empty(): return
invalid = true
2024-09-15 09:30:31 +00:00
if attached_sticky_note.attached_to == self: attached_sticky_note.attached_to = null
var height_tween: Tween = create_tween()
height_tween.tween_property(self, "custom_minimum_size", Vector2.ZERO, 0.3)
await height_tween.finished
owner.on_sticky_panel_cleared(get_parent().get_children().find(self))
self.queue_free()
2023-10-12 16:25:21 +00:00
func replace_sticky_note_with(new_sticky_note: StickyNote):
2024-09-15 09:30:31 +00:00
if is_empty():
attached_sticky_note = new_sticky_note
2023-10-12 16:25:21 +00:00
func is_empty() -> bool:
2025-02-24 15:14:08 +00:00
return get_child_count() == 0 and not is_attatching
2026-01-16 19:46:16 +00:00
# === DROP TARGET PATTERN IMPLEMENTATION ===
## Checks if this panel can accept the given draggable
func can_accept_drop(draggable: Draggable) -> bool:
return draggable is StickyNote and is_empty()
## Handles dropping a sticky note onto this panel
func handle_drop(draggable: StickyNote) -> int:
if not can_accept_drop(draggable):
return Draggable.DropResult.REJECTED
# Attach sticky to this panel
attatch_sticky_note(draggable, owner, true, true)
# Clean up other empty panels
for panel in get_parent().get_children():
if panel is StickyNotePanel and panel != self:
panel.clear_if_empty()
return Draggable.DropResult.ACCEPTED