@tool extends Area2D class_name StickyNote var sticky_id var parent_id var sibling: StickyNote var shift_tween: Tween var modulate_tween: Tween var card_stick_tween: Tween var hovering_cards: Array[Card] var hover_pos_shift: float var attached_to: Node = null: set(new_attatchement): attached_to = new_attatchement # cannot be explicitly typed, as this can be bnoth handled by picker and physics-board var current_handle: Node var position_locked: bool = false signal transform_tween_finished @export var text: String = "" : set (value): if is_node_ready(): _on_text_updated() text = value var content: Node2D var label: Label var background_sprite: AnimatedSprite2D @export var shift_by: Vector2 = Vector2(-32, 0) @export_color_no_alpha var highlight_color: Color = Color(1.5, 1.5, 1.5) @export var highlighted: bool = false: set(highlight): if highlight != highlighted: highlighted = highlight if is_inside_tree() and is_node_ready(): if modulate_tween: modulate_tween.kill() if shift_tween: shift_tween.kill() if highlighted: modulate_tween = get_tree().create_tween() modulate_tween.tween_property(self, "modulate", highlight_color, 0.1) shift_tween = get_tree().create_tween() shift_tween.tween_property(content, "position", shift_by, 0.2) else: modulate_tween = get_tree().create_tween() modulate_tween.tween_property(self, "modulate", Color(1, 1, 1), 0.3) shift_tween = get_tree().create_tween() shift_tween.tween_property(content, "position", Vector2.ZERO, 0.5) else: if highlighted: modulate = Color(1, 1, 1) else: modulate = Color(1, 1, 1) @export var voice_line: AudioStream = null @export var is_dragable: bool = false @onready var base_rotation = rotation @onready var base_scale = scale var is_dragged: bool = false: set(dragged): is_dragged = dragged z_index = int(dragged) if not is_dragged: highlighted = false var initial_drag_position: Vector2 var mouse_diff: Vector2 @onready var diameter = 312.0 @export_range(1.0, 10.0) var bounce_speed: float = 8 var on_board: bool = false func _init(sticky_name: String = "card", card_id: StringName = "-1", own_id:StringName = "-1") -> void: text = sticky_name parent_id = card_id sticky_id = own_id func _ready() -> void: if get_child_count() == 0: content = Node2D.new() add_child(content, false, Node.INTERNAL_MODE_BACK) label = Label.new() label.autowrap_mode = TextServer.AUTOWRAP_WORD label.size = Vector2( 295.0, 97.0 ) label.position = Vector2( -52.0, -50.0 ) label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER #FIXME eventually replace with better theme handling label.theme = State.current_main_theme State.theme_changed.connect(func change_theme(new_theme): label.theme = new_theme) content.add_child(label, false, Node.INTERNAL_MODE_BACK) background_sprite = AnimatedSprite2D.new() background_sprite.sprite_frames = preload("res://logic-scenes/board/card-textures/sticky-note_sprites.tres") background_sprite.scale = Vector2(0.65, 0.65) background_sprite.position = Vector2(99.5, 0) content.add_child(background_sprite, false, Node.INTERNAL_MODE_FRONT) var collision_shape := CollisionShape2D.new() var capsule := CapsuleShape2D.new() capsule.radius = 48.0 capsule.height = diameter collision_shape.shape = capsule add_child(collision_shape, false, Node.INTERNAL_MODE_FRONT) collision_shape.position.x = 99.5 collision_shape.rotation = PI/2 label.theme_type_variation = "card_text" else: label = $Content/Label background_sprite = $Content/BackgroundSprite content = $Content _on_text_updated() input_event.connect(_on_input_event) mouse_entered.connect(_on_mouse_entered) mouse_exited.connect(_on_mouse_exited) area_entered.connect(_on_area_enter) area_exited.connect(_on_area_exit) func _on_text_updated(): label.text = text background_sprite.frame = text.hash() % background_sprite.sprite_frames.get_frame_count(background_sprite.animation) func replace_with(sticky_note: StickyNote): self.text = sticky_note.text self.voice_line = sticky_note.voice_line self.sibling = sticky_note.sibling self.name = sticky_note.name for group in self.get_groups(): self.remove_from_group(group) for group in sticky_note.get_groups(): self.add_to_group(group) func _process(delta: float) -> void: if get_overlapping_areas().size() > 0 and is_dragable and on_board: for area in get_overlapping_areas(): if area is Card or area is CardCollider: if area is CardCollider: position += area.direction * delta elif not area.highlighted or self.highlighted: var diff:Vector2 = position - area.position position -= diff.normalized() * ((diff.length()-diameter)/diameter) * bounce_speed * (delta/(1.0/60)) _move_sticky_note() func _on_mouse_entered(): if not Input.is_action_pressed("mouse_left"): highlighted = true if current_handle != null: if "handle_hover" in current_handle: current_handle.handle_hover(self) func _on_mouse_exited(): if not is_dragged: highlighted = false if is_sticky_note_attached() and "check_hover" in attached_to: attached_to.check_hover() func _on_area_enter(card: Area2D): if card is Card: if hovering_cards == []: hovering_cards = [card] card_stick_tween = get_tree().create_tween() card_stick_tween.set_ease(Tween.EASE_IN_OUT) card_stick_tween.tween_property(self, "hover_pos_shift", 0.3, 0.1) else: hovering_cards.append(card) elif card is StickyNote and is_sticky_note_in_panel() and not is_dragged: attached_to.create_gap() func _on_area_exit(card: Area2D): if hovering_cards != [] and card is Card: if card in hovering_cards: hovering_cards.erase(card) card.highlighted = false if hovering_cards == []: hover_pos_shift = 0 content.position = Vector2.ZERO elif card is StickyNote and is_sticky_note_in_panel(): attached_to.collapse_gap() func _on_input_event(_viewport, event, _shape_idx): if event is InputEventMouseButton: if (event.button_index == MOUSE_BUTTON_LEFT and event.pressed) or event.button_index == MOUSE_BUTTON_RIGHT: if "handle_hover" in current_handle: mouse_diff = get_viewport().get_mouse_position() initial_drag_position = global_position current_handle.handle_mouse_button(event, self) func _move_sticky_note(): if is_dragged: var old_position = position position = initial_drag_position + get_viewport().get_mouse_position() - mouse_diff if hovering_cards != []: var closest: Card = hovering_cards[0] for card in hovering_cards: card.highlighted = false if (closest.position - position).length() > (closest.position - position).length(): card = closest closest.highlighted = true content.position = (closest.sticky_note_anchor.global_position - global_position) * hover_pos_shift func is_sticky_note_attached() -> bool: return attached_to is Card func is_sticky_note_in_panel() -> bool: return attached_to is StickyNotePanel func tween_transform_to(target: Transform2D): var transform_tween: Tween = create_tween() transform_tween.tween_property(self, "transform", target, 0.25) await transform_tween.finished transform_tween_finished.emit() func reset_drag(): if attached_to != null: attached_to.reclaim_sticky_note() func free() -> void: assert(false)