Files
Cuteminded--jellyframe/tests/test_pointer_input.gd
T
Lizzy 364eaca48f Add playback overlay and timeline seeking
This change replaces the old playback button strip with a transparent overlay attached to the movie screen. It adds a seekable timeline, duration reporting, and proper seek routing for resumed/transcoded streams while preserving paused state and overlay behavior across settings and recenter actions.

Pointer and scroll handling were also hardened to improve controller input stability, including hover tracking, exit handling, aim smoothing, and synthetic wheel release events. Regression tests and testing notes were extended to cover overlay toggling, timeline formatting, seek flows, recenter behavior, and pointer/scroll edge cases.
2026-08-16 18:06:11 +02:00

81 lines
2.9 KiB
GDScript

extends SceneTree
class FeedbackProbe extends MenuFeedback:
var clicks := 0
func _play() -> void:
clicks += 1
var activations := 0
var failures := 0
var pointer := PointerInput.new()
var point := Vector2(110, 70)
func _initialize() -> void:
call_deferred("run_checks")
func run_checks() -> void:
var feedback := FeedbackProbe.new()
root.add_child(feedback)
var viewport := SubViewport.new()
viewport.size = Vector2i(500, 300)
root.add_child(viewport)
pointer.viewport = viewport
var button := Widgets.button("Open library", func(): activations += 1, viewport)
button.position = Vector2(40, 40)
button.size = Vector2(180, 60)
await process_frame
check(button.action_mode == BaseButton.ACTION_MODE_BUTTON_PRESS, "Buttons respond to the initial press")
check(feedback.player.stream.get_length() > 0, "Click sound contains audio samples")
sample(0.0)
check(pointer.hovering, "The viewport receives pointer entry")
sample(0.65)
check(activations == 1, "Initial trigger press activates immediately")
for value in [0.58, 0.62, 0.35, 0.59]: sample(value)
check(activations == 1, "Trigger jitter cannot cause repeated activation")
point = Vector2(250, 70)
sample(0.1)
check(activations == 1, "Moving off the button during release does not lose or repeat the click")
point = Vector2(110, 70)
sample(0.7, false)
sample(0.8)
check(activations == 1, "Holding a trigger while entering the panel does not click")
sample(0.0)
sample(0.7)
pointer.cancel()
sample(0.8)
check(activations == 2 and not pointer.mouse_down, "Hiding the menu cancels mouse capture without reactivating on return")
sample(0.0)
sample(0.7)
pointer.cancel()
var other := PointerInput.new()
other.viewport = viewport
other.sample_trigger(0.7)
other.aim(point, true)
other.sample_trigger(0.0)
other.aim(point, true)
check(activations == 4, "Controller handoff releases the previous pointer before the new click")
other.cancel()
button.disabled = true
sample(0.0)
sample(0.7)
check(activations == 4 and feedback.clicks == 4, "Disabled buttons do not activate or play click feedback")
pointer.cancel()
check(not pointer.hovering, "Cancellation clears viewport hover")
var aim := PointerAim.new()
aim.update(Vector2(100, 70), 0.016, false)
check(aim.update(Vector2(120, 70), 0.016, true) == Vector2(100, 70), "Trigger squeeze preserves the displayed target for small aim movement")
check(aim.update(Vector2(500, 70), 0.016, true) == Vector2(500, 70), "Large intentional aim changes do not select the old target")
aim.reset()
check(aim.update(Vector2(20, 40), 0.016, false) == Vector2(20, 40), "Switching panels resets aim smoothing")
print("VR pointer and click feedback checks: %s" % ("PASS" if failures == 0 else "FAIL"))
quit(1 if failures else 0)
func sample(value: float, inside: bool = true) -> void:
pointer.sample_trigger(value)
pointer.aim(point, inside)
func check(condition: bool, message: String) -> void:
if condition: return
failures += 1
push_error(message)