Make bubble menu feedback immediate

This commit is contained in:
Alexander Sellite 2026-08-22 22:56:44 -04:00
parent 8f8398cbcd
commit 3dbfd74b6c
6 changed files with 214 additions and 238 deletions

View file

@ -1,6 +1,8 @@
class_name TitleConfirmationBubblePage
extends Control
const QUICK_ENTER_SCALE: float = 0.97
signal confirmed
signal cancelled
@ -17,8 +19,6 @@ signal cancelled
Vector2(90.0, 90.0)
)
@export var compact_height_threshold: float = 250.0
@export_range(0.0, 128.0, 1.0) var transition_safe_margin: float = 24.0
var _cluster: BubbleCluster
var _prompt: BubbleButton
var _prompt_label: Label
@ -47,6 +47,7 @@ func _ready() -> void:
)
_bubbles = [_prompt, _confirm_button, _cancel_button]
_cluster.configure(_bubbles)
_cluster.motion_scale = 0.0
_prompt.focus_mode = Control.FOCUS_NONE
_prompt.mouse_filter = Control.MOUSE_FILTER_IGNORE
_confirm_button.pressed.connect(confirmed.emit)
@ -97,12 +98,13 @@ func set_stage_rect(stage_rect: Rect2) -> void:
field_size,
false
)
_cluster.pivot_offset = _cluster.size * 0.5
if not _is_transitioning:
_cluster.position = _resting_cluster_position
func transition_in(
_duration: float,
duration: float,
completed: Callable,
) -> void:
_transition_generation += 1
@ -111,21 +113,19 @@ func transition_in(
_is_transitioning = true
_set_interactive(false)
set_process(true)
_cluster.position = Vector2(
_resting_cluster_position.x,
size.y + transition_safe_margin
)
var duration := UIMotion.bubble_duration(
_cluster.position.y - _resting_cluster_position.y
)
_cluster.position = _resting_cluster_position
_cluster.pivot_offset = _cluster.size * 0.5
_cluster.scale = Vector2.ONE * QUICK_ENTER_SCALE
_cluster.modulate.a = 0.0
var generation: int = _transition_generation
_transition = create_tween()
_transition = create_tween().set_parallel(true)
_transition.tween_property(
_cluster,
"position",
_resting_cluster_position,
"scale",
Vector2.ONE,
duration
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_OUT)
_transition.tween_property(_cluster, "modulate:a", 1.0, duration)
_transition.finished.connect(
_finish_transition_in.bind(generation, completed),
CONNECT_ONE_SHOT
@ -133,7 +133,7 @@ func transition_in(
func transition_out(
_duration: float,
duration: float,
completed: Callable,
) -> void:
if not visible or _is_transitioning:
@ -142,18 +142,17 @@ func transition_out(
_cancel_transition()
_is_transitioning = true
_set_interactive(false)
var target_y: float = -_cluster.size.y - transition_safe_margin
var duration := UIMotion.bubble_duration(
target_y - _cluster.position.y
)
_cluster.position = _resting_cluster_position
_cluster.pivot_offset = _cluster.size * 0.5
var generation: int = _transition_generation
_transition = create_tween()
_transition = create_tween().set_parallel(true)
_transition.tween_property(
_cluster,
"position:y",
target_y,
"scale",
Vector2.ONE * QUICK_ENTER_SCALE,
duration
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_IN)
_transition.tween_property(_cluster, "modulate:a", 0.0, duration)
_transition.finished.connect(
_finish_transition_out.bind(generation, completed),
CONNECT_ONE_SHOT
@ -169,6 +168,7 @@ func hide_page() -> void:
hide()
if _cluster != null:
_cluster.position = _resting_cluster_position
_reset_cluster_presentation()
func lock_interaction() -> void:
@ -240,6 +240,8 @@ func _finish_transition_in(
return
_transition = null
_is_transitioning = false
_cluster.position = _resting_cluster_position
_reset_cluster_presentation()
_set_interactive(true)
focus_confirm()
completed.call()
@ -255,6 +257,7 @@ func _finish_transition_out(
_is_transitioning = false
hide()
_cluster.position = _resting_cluster_position
_reset_cluster_presentation()
set_process(false)
completed.call()
@ -263,3 +266,10 @@ func _cancel_transition() -> void:
if _transition != null:
_transition.kill()
_transition = null
func _reset_cluster_presentation() -> void:
if _cluster == null:
return
_cluster.scale = Vector2.ONE
_cluster.modulate.a = 1.0