class_name StickyNotePanel extends Panel var minimum_size:Vector2 = Vector2(400, 100): set(size): minimum_size = size custom_minimum_size = size var attached_sticky_note: StickyNote 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) func _ready(): custom_minimum_size = Vector2(custom_minimum_size.x, 0) var is_attatching: bool = false func attatch_sticky_note(attatchment: StickyNote, custom_owner: Node, tween:bool = true, re_parent:bool = true): is_attatching = true attatchment.on_board = false attached_sticky_note = attatchment attatchment.attached_to = null if tween: await get_tree().process_frame var height_tween: Tween = create_tween() height_tween.tween_property(self, "custom_minimum_size", minimum_size, 0.1) 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)) await attatchment.transform_tween_finished await get_tree().process_frame attatchment.reparent(self) attatchment.position = ancor_position else: custom_minimum_size = minimum_size if re_parent: attatchment.reparent(self) else: add_child(attatchment) attatchment.position = ancor_position is_attatching = false attatchment.owner = custom_owner attatchment.attached_to = self attatchment.current_handle = custom_owner var is_gapped: bool = false func create_gap(): var self_id = get_parent().get_children().find(self) var next_id = min(self_id + 1, get_parent().get_child_count() - 1) var previous_id = max(self_id - 1, 0) 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: if is_empty() and attached_sticky_note.attached_to != Card: is_attatching = true attached_sticky_note.on_board = false attached_sticky_note.tween_transform_to(Transform2D(0, get_screen_position() + ancor_position)) await attached_sticky_note.transform_tween_finished await get_tree().process_frame attached_sticky_note.reparent(self) attached_sticky_note.attached_to = self attached_sticky_note.owner = self.owner is_attatching = false return true return false var invalid: bool = false func clear_if_empty(): if !is_empty(): return invalid = true 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() func replace_sticky_note_with(new_sticky_note: StickyNote): if is_empty(): attached_sticky_note = new_sticky_note func is_empty() -> bool: return get_child_count() == 0 and not is_attatching # === 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