From 2164c2e1fc9672c2c281b448144ce3dd8f809e60 Mon Sep 17 00:00:00 2001 From: Tiger Jove Date: Sun, 18 Jan 2026 17:32:31 +0100 Subject: [PATCH] fix: can now attach notes --- src/logic-scenes/board/card-board.gd | 64 ++++++++++++++++----------- src/logic-scenes/board/card.gd | 34 +++----------- src/logic-scenes/board/draggable.gd | 33 ++++++++++++++ src/logic-scenes/board/sticky-note.gd | 9 ++-- src/logic-scenes/playable.gd | 1 + 5 files changed, 85 insertions(+), 56 deletions(-) diff --git a/src/logic-scenes/board/card-board.gd b/src/logic-scenes/board/card-board.gd index 8a31d09..52fb0be 100644 --- a/src/logic-scenes/board/card-board.gd +++ b/src/logic-scenes/board/card-board.gd @@ -204,14 +204,13 @@ func is_in_dropzone(to_check: Draggable) -> bool: # Called by notes when a mouse event needs handling func handle_mouse_button(input: InputEventMouseButton, target: Draggable) -> void: - # === DRAG START === if input.button_index == MOUSE_BUTTON_LEFT and input.is_pressed(): _start_drag(target) return # === DRAG END === - if input.button_index == MOUSE_BUTTON_LEFT and not input.is_released(): + if input.button_index == MOUSE_BUTTON_LEFT and input.is_released(): _end_drag(target) return @@ -220,7 +219,6 @@ func handle_mouse_button(input: InputEventMouseButton, target: Draggable) -> voi func _start_drag(draggable: Draggable) -> void: selection = draggable current_context = DRAG - var mouse_offset := get_viewport().get_mouse_position() - draggable.global_position draggable.start_drag(mouse_offset) @@ -234,28 +232,44 @@ func _end_drag(draggable: Draggable) -> void: var destination := draggable.end_drag() - if not destination and draggable is StickyNote: - # reclaim if necessary - pass - - if destination and destination is Card: - # attach / unattach - pass - - if destination and destination is StickyNote: - # unattach and attach to parent - pass - - # Let draggable find its own drop target - #var drop_target := draggable.find_drop_target() - - # Execute the drop - #if drop_target and Draggable.is_drop_target(drop_target): - # var result = drop_target.handle_drop(draggable) - # pass - - # Check win condition if sticky was attached to card - if draggable is StickyNote and draggable.is_attached: + # Handle sticky note drops + if draggable is StickyNote: + var sticky := draggable as StickyNote + + # If dropped on a card, attach it + if destination and destination is Card: + var target_card := destination as Card + + # If sticky was previously attached to a different card, detach it first + if sticky.is_attached and sticky.attached_to != target_card: + sticky.attached_to.remove_sticky_note() + + # If target card already has a sticky, exchange them + if target_card.has_sticky_note_attached(): + var exchanged_sticky := target_card.exchange_sticky_note_with(sticky) + # Reclaim the exchanged sticky to the board + if exchanged_sticky: + reclaim_sticky(exchanged_sticky) + else: + # Simple attach + sticky.reparent(target_card) + target_card.attach_sticky_note(sticky) + + # If dropped on board (no destination), ensure it's a child of the board + elif not destination: + # If it was attached to a card, detach it first + if sticky.is_attached: + sticky.attached_to.remove_sticky_note() + + # Make sure sticky is parented to board + if sticky.get_parent() != self: + sticky.reparent(self) + + # Ensure it's in the notes array + if not sticky in notes: + notes.append(sticky) + + # Check win condition after any sticky movement check_board_completion() diff --git a/src/logic-scenes/board/card.gd b/src/logic-scenes/board/card.gd index c216db2..70812f3 100644 --- a/src/logic-scenes/board/card.gd +++ b/src/logic-scenes/board/card.gd @@ -145,8 +145,6 @@ func init(card_name: String = "card", own_id:StringName = "-1") -> void: func _ready(): super._ready() - input_event.connect(_on_input_event) - _handle_wiggle(0) _on_text_updated.call_deferred() @@ -192,11 +190,6 @@ func _handle_wiggle(delta): rotation = noise.get_noise_1d(wiggle_pos)*wiggle_strength -func _input(event: InputEvent) -> void: - if event is InputEventMouseButton: - if event.button_index == MOUSE_BUTTON_LEFT and not event.pressed: - is_dragged = false - func _on_mouse_entered() -> void: super._on_mouse_entered() @@ -205,12 +198,6 @@ func _on_mouse_exited(): if burn_state == burned.SINGED: burn_state = burned.NOT -func _on_input_event(_viewport, event, _shape_idx): - if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed: - if highlighted: - mouse_offset = get_viewport().get_mouse_position() - position - if _get_board(): _get_board().handle_mouse_button(event, self) - func _move_card(): if is_dragged: update_drag_position(get_viewport().get_mouse_position()) @@ -258,9 +245,12 @@ func remove_sticky_note() -> StickyNote: return former_child func exchange_sticky_note_with(new_note: StickyNote) -> StickyNote: - var tmp := remove_sticky_note() + if new_note == get_attached_sticky_note(): + return null + + var old_note := remove_sticky_note() attach_sticky_note(new_note) - return tmp + return old_note # === DROP TARGET PATTERN IMPLEMENTATION === @@ -297,7 +287,7 @@ func handle_drop(draggable: StickyNote) -> int: ## Retrieves the sticky that was exchanged during last drop ## Clears the reference after retrieval func get_last_exchanged_sticky() -> StickyNote: - var result = _last_exchanged_sticky + var result := _last_exchanged_sticky _last_exchanged_sticky = null return result @@ -307,15 +297,3 @@ func get_last_exchanged_sticky() -> StickyNote: ## Cards always drop back to board dropzone func find_drop_target() -> Node: return _get_board() - - -# === HELPER FUNCTIONS === - -## Walks up the scene tree to find the CardBoard -func _get_board() -> CardBoard: - var node := get_parent() - while node: - if node is CardBoard: - return node - node = node.get_parent() - return null diff --git a/src/logic-scenes/board/draggable.gd b/src/logic-scenes/board/draggable.gd index fe93df8..fb22df1 100644 --- a/src/logic-scenes/board/draggable.gd +++ b/src/logic-scenes/board/draggable.gd @@ -43,6 +43,7 @@ var _drag_source: Node = null # Where the drag started from func _ready() -> void: mouse_entered.connect(_on_mouse_entered) mouse_exited.connect(_on_mouse_exited) + input_event.connect(_on_input_event) func _get_hover_handler() -> Node: @@ -51,6 +52,16 @@ func _get_hover_handler() -> Node: parent = parent.get_parent() return parent + +## Walks up the scene tree to find the CardBoard +func _get_board() -> Node: + var node := get_parent() + while node: + if node.has_method("handle_mouse_button"): + return node + node = node.get_parent() + return null + ## === DRAG LIFECYCLE METHODS === ## Override these in Card and StickyNote for specific behavior @@ -68,6 +79,28 @@ func _on_mouse_exited() -> void: if handler: handler.handle_hover(self) +## Handles global input events (used to catch mouse release during drag) +func _input(event: InputEvent) -> void: + if event is InputEventMouseButton: + if event.button_index == MOUSE_BUTTON_LEFT and not event.pressed: + if is_dragged: + is_dragged = false + # Trigger the drop logic + var board := _get_board() + if board and board.has_method("_end_drag"): + board._end_drag(self) + + +## Handles input events on this Area2D (used to start drag) +func _on_input_event(_viewport, event, _shape_idx): + if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed: + if highlighted: + var mouse_offset := get_viewport().get_mouse_position() - position + var board := _get_board() + if board and board.has_method("handle_mouse_button"): + board.handle_mouse_button(event, self) + + ## Starts a drag operation func start_drag(mouse_offset: Vector2) -> void: _drag_start_position = global_position diff --git a/src/logic-scenes/board/sticky-note.gd b/src/logic-scenes/board/sticky-note.gd index 5946ac8..52ff4e2 100644 --- a/src/logic-scenes/board/sticky-note.gd +++ b/src/logic-scenes/board/sticky-note.gd @@ -150,11 +150,14 @@ func _find_drop_target() -> Node: if area is StickyNote and not area.is_attached: continue # Can only drop on attached stickies if area is Card: - if (not closest) or ((closest.position-position).length() < (area.position - position).length()): + if (not closest) or ((area.position - position).length() < (closest.position - position).length()): closest = area - return area - # Priority 3: Default to board (stay loose in dropzone) + # Return the closest card if found + if closest: + return closest + + # Priority 2: Default to board (stay loose in dropzone) return null ## Find the nearest panel that can accept this sticky diff --git a/src/logic-scenes/playable.gd b/src/logic-scenes/playable.gd index 77ea4c9..4c05b56 100644 --- a/src/logic-scenes/playable.gd +++ b/src/logic-scenes/playable.gd @@ -7,3 +7,4 @@ func play() -> void: func handle_hover(area: Draggable): prints("Playable[base].handle_hover", area, area.name) + pass