Skip to content

Commit

Permalink
fix(Cards): better touch support
Browse files Browse the repository at this point in the history
  • Loading branch information
ShadowApex committed Dec 22, 2024
1 parent e3a0b9a commit f0ce244
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 16 deletions.
44 changes: 34 additions & 10 deletions core/systems/input/input_manager.gd
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ var popup_state := preload("res://assets/state/states/popup.tres") as State
## Map of pressed actions to prevent double inputs
var actions_pressed := {}

## Number of currently pressed touches
var current_touches := 0

## Will show logger events with the prefix InputManager
var logger := Log.get_logger("InputManager", Log.LEVEL.INFO)

Expand All @@ -53,6 +56,11 @@ func _init_inputplumber() -> void:
_watch_dbus_device(device)


## Returns true if the given event is an InputPlumber event
static func is_inputplumber_event(event: InputEvent) -> bool:
return event.has_meta("dbus_path")


## Queue a release event for the given action
func action_release(dbus_path: String, action: String, strength: float = 1.0) -> void:
Input.action_release(action)
Expand All @@ -76,10 +84,26 @@ func _send_input(dbus_path: String, action: String, pressed: bool, strength: flo
Input.parse_input_event(input_action)


## Process all unhandled input, possibly preventing the input from propagating further.
## https://docs.godotengine.org/en/latest/tutorials/inputs/inputevent.html#how-does-it-work
## Process all window input. Window input is processed before all _input and
## _gui_input node methods.
## @tutorial https://docs.godotengine.org/en/latest/tutorials/inputs/inputevent.html#how-does-it-work
func _input(event: InputEvent) -> void:
logger.debug("Got input event to handle: " + str(event))

# Keep track of the current number of touch inputs
if event is InputEventScreenTouch:
if event.is_pressed():
self.current_touches += 1
else:
self.current_touches -= 1

# Don't process Godot events if InputPlumber is running
if input_plumber.is_running() and not is_inputplumber_event(event):
if event is InputEventJoypadButton or event is InputEventJoypadMotion:
logger.debug("Skipping Godot event while InputPlumber is running:", event)
get_viewport().set_input_as_handled()
return

var dbus_path := event.get_meta("dbus_path", "") as String

# Consume double inputs for controllers with DPads that have TRIGGER_HAPPY events
Expand Down Expand Up @@ -275,18 +299,18 @@ func _audio_input(event: InputEvent) -> void:


func _watch_dbus_device(device: CompositeDevice) -> void:
for target in device.dbus_devices:
if target.input_event.is_connected(_on_dbus_input_event.bind(device.dbus_path)):
continue
logger.debug("Adding watch for " + device.name + " " + target.dbus_path)
logger.debug(str(target.get_instance_id()))
logger.debug(str(target.get_rid()))
target.input_event.connect(_on_dbus_input_event.bind(device.dbus_path))
for target in device.dbus_devices:
if target.input_event.is_connected(_on_dbus_input_event.bind(device.dbus_path)):
continue
logger.debug("Adding watch for " + device.name + " " + target.dbus_path)
logger.debug(str(target.get_instance_id()))
logger.debug(str(target.get_rid()))
target.input_event.connect(_on_dbus_input_event.bind(device.dbus_path))


func _on_dbus_input_event(event: String, value: float, dbus_path: String) -> void:
var pressed := value == 1.0
logger.debug("Handling dbus input event from" + dbus_path + ": " + event + " pressed: " + str(pressed))
logger.debug("Handling dbus input event from '" + dbus_path + "': " + event + " pressed: " + str(pressed))

var action := event
match event:
Expand Down
12 changes: 12 additions & 0 deletions core/systems/input/overlay_mode_input_manager.gd
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,19 @@ func _send_input(dbus_path: String, action: String, pressed: bool, strength: flo
## https://docs.godotengine.org/en/latest/tutorials/inputs/inputevent.html#how-does-it-work
func _input(event: InputEvent) -> void:
logger.debug("Got input event to handle: " + str(event))
# Don't process Godot events if InputPlumber is running
if input_plumber.is_running() and not InputManager.is_inputplumber_event(event):
if event is InputEventJoypadButton or event is InputEventJoypadMotion:
logger.debug("Skipping Godot event while InputPlumber is running:", event)
get_viewport().set_input_as_handled()
return

var dbus_path := event.get_meta("dbus_path", "") as String

# Don't process Godot events if InputPlumber is running
if input_plumber.is_running() and not InputManager.is_inputplumber_event(event):
logger.trace("Skipping Godot event while InputPlumber is running:", event)
return

# Consume double inputs for controllers with DPads that have TRIGGER_HAPPY events
const possible_doubles := ["ui_left", "ui_right", "ui_up", "ui_down"]
Expand Down
1 change: 1 addition & 0 deletions core/systems/launcher/interactive_process.gd
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
@icon("res://assets/editor-icons/devicon-plain--bash.svg")
extends Resource
class_name InteractiveProcess

Expand Down
5 changes: 2 additions & 3 deletions core/ui/card_ui/card_ui.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,6 @@ grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_f8851")

[node name="InputManager" parent="." instance=ExtResource("1_34t85")]

[node name="InputIconProcessor" type="Node" parent="."]
script = ExtResource("3_y116l")

Expand Down Expand Up @@ -231,7 +229,6 @@ size_flags_vertical = 8
layout_mode = 2

[node name="ContextBar" parent="MenuContent/BottomMargin/VBoxContainer" instance=ExtResource("12_bstc8")]
visible = false
layout_mode = 2

[node name="MenuContainer" type="MarginContainer" parent="MenuContent"]
Expand Down Expand Up @@ -363,4 +360,6 @@ grow_vertical = 2
stream = ExtResource("21_s3peg")
autoplay = true

[node name="InputManager" parent="." instance=ExtResource("1_34t85")]

[editable path="AlwaysVisibleContent/OnScreenKeyboard"]
9 changes: 9 additions & 0 deletions core/ui/card_ui/home/cardui_home.gd
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,15 @@ func _on_card_focused(item: LibraryItem, card: Control) -> void:
player.play("fade_in")
banner.texture = await BoxArtManager.get_boxart_or_placeholder(item, BoxArtProvider.LAYOUT.BANNER)
library_banner.visible = false

# Don't scroll to the card if mouse or touch is being used
var input_manager := get_tree().get_first_node_in_group("InputManager")
if input_manager:
if (input_manager as InputManager).current_touches > 0:
return
if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
return

_scroll_to(card)


Expand Down
9 changes: 9 additions & 0 deletions core/ui/card_ui/library/library_menu.gd
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,17 @@ func _on_uninstalled(req: InstallManager.Request) -> void:

# Called when a library card is focused
func _on_focus_updated(card: Control, tab: int) -> void:
# Update the currently selected card
_current_selection[tab] = card

# Don't scroll to the card if mouse or touch is being used
var input_manager := get_tree().get_first_node_in_group("InputManager")
if input_manager:
if (input_manager as InputManager).current_touches > 0:
return
if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
return

# Get the scroll container for this card
var scroll_container := tab_container.get_child(tab) as ScrollContainer
if not scroll_container:
Expand Down
4 changes: 2 additions & 2 deletions core/ui/card_ui_overlay_mode/card_ui_overlay_mode.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ grow_vertical = 2
theme = ExtResource("1_0qmlq")
script = ExtResource("2_3ptao")

[node name="InputManager" parent="." instance=ExtResource("3_klhmb")]

[node name="InputIconProcessor" type="Node" parent="."]
script = ExtResource("4_6rltg")

Expand Down Expand Up @@ -92,3 +90,5 @@ anchor_right = 0.5
anchor_bottom = 0.5
grow_horizontal = 2
grow_vertical = 2

[node name="InputManager" parent="." instance=ExtResource("3_klhmb")]
17 changes: 16 additions & 1 deletion core/ui/components/card.gd
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@ signal unhighlighted
progress.value = v

var library_item: LibraryItem
var tapped_count := 0
var logger := Log.get_logger("GameCard")

@onready var texture := $%TextureRect
@onready var name_container := $%NameMargin
@onready var name_label := $%NameLabel
@onready var progress := $%ProgressBar as ProgressBar
@onready var tap_timer := $%TapTimer as Timer


# Called when the node enters the scene tree for the first time.
Expand All @@ -53,7 +55,12 @@ func _ready() -> void:
focus_exited.connect(_on_unfocus)
texture.mouse_entered.connect(_on_focus)
texture.mouse_exited.connect(_on_unfocus)


# Setup a timer callback to clear number of taps on the card
var on_timeout := func():
tapped_count = 0
tap_timer.timeout.connect(on_timeout)

var parent := get_parent()
if parent and parent is Container:
parent.queue_sort()
Expand Down Expand Up @@ -101,6 +108,14 @@ func _gui_input(event: InputEvent) -> void:
if event is InputEventMouseButton:
if event.is_pressed() and event.double_click:
button_up.emit()
if event is InputEventScreenTouch:
if event.is_pressed():
tapped_count += 1
if tapped_count > 1:
tapped_count = 0
button_up.emit()
else:
tap_timer.start()
if event.is_action("ui_accept"):
if event.is_pressed():
button_down.emit()
Expand Down
6 changes: 6 additions & 0 deletions core/ui/components/card.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ clip_children = 1
layout_mode = 0
offset_right = 40.0
offset_bottom = 40.0
mouse_filter = 1
theme_override_styles/panel = SubResource("StyleBoxFlat_ygsnb")

[node name="TextureRect" type="TextureRect" parent="PanelContainer"]
Expand Down Expand Up @@ -136,3 +137,8 @@ show_behind_parent = true
layout_mode = 2
mouse_filter = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_st1t5")

[node name="TapTimer" type="Timer" parent="."]
unique_name_in_owner = true
wait_time = 0.5
one_shot = true

0 comments on commit f0ce244

Please sign in to comment.