extends Draggable class_name StickyNote var sticky_id var parent_id var sibling: StickyNote var shift_tween: Tween var modulate_tween: Tween var attached_to: Node = null: set(new_attatchement): attached_to = new_attatchement # cannot be explicitly typed, as this can be both handled by picker and physics-board var current_handle: Node var position_locked: bool = false signal transform_tween_finished @onready var background_sprite: AnimatedSprite2D = %BackgroundSprite @export var text: String = "" : set (value): if is_node_ready(): _on_text_updated.call_deferred() text = value var content: Node2D var label: Label @export var picked_random: bool = false @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 mouse_offset: 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 = "sticky_note", card_id: StringName = "-1") -> void: name = sticky_name text = sticky_name parent_id = StringName(card_id.rsplit(".", false, 1)[0]) sticky_id = card_id func _ready() -> void: label = $Content/Label background_sprite = $Content/BackgroundSprite content = $Content _on_text_updated.call_deferred() 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 _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") and "handle_hover" in current_handle: current_handle.handle_hover(self) func _on_mouse_exited(): highlighted = false # Let parent card re-check hover state if this sticky is attached to it if is_sticky_note_attached() and "check_hover" in attached_to: attached_to.check_hover() func _on_area_enter(area: Area2D): # Handle sticky note panel gap creation if area is StickyNote and is_sticky_note_in_panel() and not is_dragged: attached_to.create_gap() func _on_area_exit(area: Area2D): # Handle sticky note panel gap collapse if area is StickyNote and is_sticky_note_in_panel(): attached_to.collapse_gap() func _on_input_event(_viewport, event, _shape_idx): if event is InputEventMouseButton and "handle_mouse_button" in current_handle: if (event.button_index == MOUSE_BUTTON_LEFT and event.pressed) or event.button_index == MOUSE_BUTTON_RIGHT: mouse_offset = get_viewport().get_mouse_position() - global_position current_handle.handle_mouse_button(event, self) func _move_sticky_note(): if is_dragged: global_position = get_viewport().get_mouse_position() - mouse_offset confine_to_screen() func is_sticky_note_attached() -> bool: # FIXME: this breaks if attatched to is previousely freed because GODOT IS FUCKING STUPID return attached_to is Card func is_sticky_note_in_panel() -> bool: ## fixme ~> see above return attached_to is StickyNotePanel var transform_tween: Tween func tween_transform_to(target: Transform2D): if transform_tween and transform_tween.is_running(): transform_tween.stop() transform_tween = create_tween() transform_tween.tween_property(self, "transform", target, 0.25) await transform_tween.finished transform_tween_finished.emit()