fix: stabilize controller menu navigation
This commit is contained in:
parent
5df8b2e7cc
commit
a8be597d27
32 changed files with 910 additions and 2376 deletions
|
|
@ -236,13 +236,15 @@ func _input(event: InputEvent) -> void:
|
|||
close_shop()
|
||||
return
|
||||
if uses_accept:
|
||||
if _controller_zone != ControllerZone.TABS:
|
||||
# Content buttons use Godot's native ui_accept activation. Keeping a
|
||||
# second manual pressed.emit() path here allowed one controller press
|
||||
# to be interpreted by two different owners.
|
||||
return
|
||||
get_viewport().set_input_as_handled()
|
||||
if not button_event.pressed or _transaction_in_progress:
|
||||
return
|
||||
if _controller_zone == ControllerZone.TABS:
|
||||
_enter_shop_content_zone()
|
||||
else:
|
||||
_activate_focused_shop_control()
|
||||
_enter_shop_content_zone()
|
||||
return
|
||||
var uses_left_bumper: bool = (
|
||||
_controller_mapping_manager.event_uses_role(
|
||||
|
|
@ -295,19 +297,6 @@ func _enter_shop_content_zone() -> void:
|
|||
_select_shop_section(section_index, true)
|
||||
|
||||
|
||||
func _activate_focused_shop_control() -> bool:
|
||||
var focused := get_viewport().gui_get_focus_owner() as BaseButton
|
||||
if (
|
||||
focused == null
|
||||
or focused.disabled
|
||||
or _is_shop_tab(focused)
|
||||
or not focused.is_visible_in_tree()
|
||||
):
|
||||
return false
|
||||
focused.pressed.emit()
|
||||
return true
|
||||
|
||||
|
||||
func _focused_shop_tab_index() -> int:
|
||||
var focused: Control = get_viewport().gui_get_focus_owner()
|
||||
for tab_index: int in _shop_tabs.size():
|
||||
|
|
@ -430,11 +419,34 @@ func _configure_controller_focus() -> void:
|
|||
if not visible or _cooler_page_active:
|
||||
return
|
||||
_apply_shop_controller_zone_focus_modes()
|
||||
var candidates: Array[Control] = []
|
||||
_collect_controller_focusables(self, candidates)
|
||||
var candidates: Array[Control] = _active_shop_controller_controls()
|
||||
ControllerFocusNavigationType.configure_spatial_neighbors(candidates)
|
||||
|
||||
|
||||
func _active_shop_controller_controls() -> Array[Control]:
|
||||
var controls: Array[Control] = []
|
||||
if _controller_zone == ControllerZone.TABS:
|
||||
for tab: OrganizerTab in _shop_tabs:
|
||||
if ControllerFocusNavigationType.is_focusable(tab):
|
||||
controls.append(tab)
|
||||
return controls
|
||||
var active_root: Control = (
|
||||
_upgrades_content
|
||||
if _shop_section == ShopSection.UPGRADES
|
||||
else _supplies_content
|
||||
)
|
||||
for node: Node in active_root.find_children(
|
||||
"*", "BaseButton", true, false
|
||||
):
|
||||
var button := node as BaseButton
|
||||
if ControllerFocusNavigationType.is_focusable(button):
|
||||
controls.append(button)
|
||||
var close_button := %CloseButton as Button
|
||||
if ControllerFocusNavigationType.is_focusable(close_button):
|
||||
controls.append(close_button)
|
||||
return controls
|
||||
|
||||
|
||||
func _apply_shop_controller_zone_focus_modes() -> void:
|
||||
var tabs_active: bool = _controller_zone == ControllerZone.TABS
|
||||
for tab: OrganizerTab in _shop_tabs:
|
||||
|
|
@ -459,22 +471,6 @@ func _set_descendant_button_focus_mode(
|
|||
button.focus_mode = focus_mode
|
||||
|
||||
|
||||
func _collect_controller_focusables(
|
||||
root: Node,
|
||||
output: Array[Control],
|
||||
) -> void:
|
||||
for child: Node in root.get_children():
|
||||
var control := child as Control
|
||||
if control != null and not control.is_visible_in_tree():
|
||||
continue
|
||||
if (
|
||||
ControllerFocusNavigationType.is_focusable(control)
|
||||
and not control is ScrollBar
|
||||
):
|
||||
output.append(control)
|
||||
_collect_controller_focusables(child, output)
|
||||
|
||||
|
||||
func _update_shop_tab_selection() -> void:
|
||||
for tab_index: int in range(_shop_tabs.size()):
|
||||
_shop_tabs[tab_index].set_selected(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue