mirror of
https://github.com/thegatesbrowser/thegates.git
synced 2025-08-23 17:17:31 -04:00
carousel scroll
This commit is contained in:
parent
ad3fddb4eb
commit
572bf851fa
2 changed files with 86 additions and 2 deletions
|
@ -3,12 +3,23 @@ extends Control
|
|||
@export var ui_events: UiEvents
|
||||
@export var line: Control
|
||||
@export var close: Button
|
||||
@export var tween_duration: float
|
||||
|
||||
@export var tween_duration: float = 0.3
|
||||
@export var drag_deadzone: float = 20.0
|
||||
@export var page_switch_threshold: float = 75.0
|
||||
@export var overscroll_softness: float = 30.0
|
||||
@export var overscroll_limit: float = 200.0
|
||||
|
||||
var boards: Array[OnboardingBoard] = []
|
||||
var focused_page: int
|
||||
var tween: Tween
|
||||
|
||||
var dragging: bool
|
||||
var drag_started: bool
|
||||
var drag_start_position: Vector2
|
||||
var drag_start_line_x: float
|
||||
var last_mouse_position: Vector2
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
setup_boards()
|
||||
|
@ -59,3 +70,77 @@ func refresh_mouse_position() -> void:
|
|||
var event = InputEventMouseMotion.new()
|
||||
event.position = get_viewport().get_mouse_position()
|
||||
Input.parse_input_event(event)
|
||||
|
||||
|
||||
func set_focus_buttons_disabled(disabled: bool) -> void:
|
||||
close.disabled = disabled
|
||||
for board in boards:
|
||||
board.focus_button.disabled = disabled
|
||||
|
||||
|
||||
func _gui_input(event: InputEvent) -> void:
|
||||
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
|
||||
if event.pressed:
|
||||
# Start dragging
|
||||
dragging = true
|
||||
drag_started = false
|
||||
drag_start_position = event.position
|
||||
last_mouse_position = event.position
|
||||
drag_start_line_x = line.position.x
|
||||
else:
|
||||
# End dragging
|
||||
if dragging:
|
||||
dragging = false
|
||||
if not drag_started:
|
||||
# Treat as click: if no tween is playing, keep current focused page
|
||||
if not (is_instance_valid(tween) and tween.is_running()):
|
||||
move_line(focused_page)
|
||||
return
|
||||
|
||||
# Drag was active: consume release and re-enable focus buttons
|
||||
set_focus_buttons_disabled(false)
|
||||
accept_event()
|
||||
|
||||
# Decide target page based on drag distance/direction
|
||||
var total_drag_x: float = event.position.x - drag_start_position.x
|
||||
var last_index: int = boards.size() - 1
|
||||
var target_index: int = focused_page
|
||||
|
||||
if abs(total_drag_x) >= page_switch_threshold:
|
||||
if total_drag_x < 0.0:
|
||||
target_index = min(focused_page + 1, last_index)
|
||||
else:
|
||||
target_index = max(focused_page - 1, 0)
|
||||
|
||||
move_line(target_index)
|
||||
|
||||
elif event is InputEventMouseMotion:
|
||||
if dragging:
|
||||
var delta_x: float = event.position.x - last_mouse_position.x
|
||||
if not drag_started:
|
||||
var moved_enough: bool = abs(event.position.x - drag_start_position.x) >= drag_deadzone
|
||||
if moved_enough:
|
||||
drag_started = true
|
||||
# Now that drag truly started, stop any ongoing tween
|
||||
if is_instance_valid(tween): tween.stop()
|
||||
set_focus_buttons_disabled(true)
|
||||
accept_event()
|
||||
|
||||
if drag_started:
|
||||
var displacement: float = abs(line.position.x - drag_start_line_x)
|
||||
var resistance: float = 1.0 / (1.0 + displacement / overscroll_softness)
|
||||
var applied_dx: float = delta_x * resistance
|
||||
var new_x: float = line.position.x + applied_dx
|
||||
var delta_from_start: float = new_x - drag_start_line_x
|
||||
|
||||
if delta_from_start > overscroll_limit:
|
||||
new_x = drag_start_line_x + overscroll_limit
|
||||
elif delta_from_start < -overscroll_limit:
|
||||
new_x = drag_start_line_x - overscroll_limit
|
||||
|
||||
line.position.x = new_x
|
||||
|
||||
last_mouse_position = event.position
|
||||
|
||||
if drag_started:
|
||||
accept_event()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue