feat: complete controller-first menu navigation
This commit is contained in:
parent
26c9308fcf
commit
4ac7d5edb8
35 changed files with 2013 additions and 85 deletions
|
|
@ -56,6 +56,8 @@ var _base_position: Vector2 = Vector2.ZERO
|
|||
var _presented_size: Vector2 = Vector2.ZERO
|
||||
var _compact: bool = false
|
||||
var _presentation_initialized: bool = false
|
||||
var _controller_preview_active: bool = false
|
||||
var _controller_preview_texture: Texture2D
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
|
|
@ -146,6 +148,15 @@ func set_drag_enabled(enabled: bool) -> void:
|
|||
_hovered = false
|
||||
|
||||
|
||||
func set_controller_placement_preview(
|
||||
active: bool,
|
||||
texture: Texture2D,
|
||||
) -> void:
|
||||
_controller_preview_active = active
|
||||
_controller_preview_texture = texture
|
||||
refresh()
|
||||
|
||||
|
||||
func refresh() -> void:
|
||||
if _hotbar == null:
|
||||
return
|
||||
|
|
@ -161,11 +172,16 @@ func refresh() -> void:
|
|||
if _fish_inventory != null and not catch_id.is_empty()
|
||||
else null
|
||||
)
|
||||
_item_icon.texture = (
|
||||
var assigned_texture: Texture2D = (
|
||||
fish_catch.fish.display_texture
|
||||
if fish_catch != null
|
||||
else item.icon if item != null else null
|
||||
)
|
||||
_item_icon.texture = (
|
||||
_controller_preview_texture
|
||||
if _controller_preview_active
|
||||
else assigned_texture
|
||||
)
|
||||
var quantity: int = (
|
||||
_bag.get_quantity(item_id)
|
||||
if _bag != null and not item_id.is_empty()
|
||||
|
|
@ -177,7 +193,9 @@ func refresh() -> void:
|
|||
else ""
|
||||
)
|
||||
_quantity_label.text = quantity_text
|
||||
_quantity_label.visible = not quantity_text.is_empty()
|
||||
_quantity_label.visible = (
|
||||
not _controller_preview_active and not quantity_text.is_empty()
|
||||
)
|
||||
tooltip_text = (
|
||||
"%s · %.1f lb" % [
|
||||
FishQualityType.qualified_name(
|
||||
|
|
@ -192,7 +210,11 @@ func refresh() -> void:
|
|||
var was_selected: bool = _selected
|
||||
var was_empty: bool = _empty
|
||||
_selected = slot_index == _hotbar.get_selected_slot()
|
||||
_empty = item == null and fish_catch == null
|
||||
_empty = (
|
||||
not _controller_preview_active
|
||||
and item == null
|
||||
and fish_catch == null
|
||||
)
|
||||
if was_selected != _selected or was_empty != _empty:
|
||||
_apply_style()
|
||||
|
||||
|
|
@ -220,7 +242,9 @@ func _apply_style() -> void:
|
|||
var normal_fill: Color = profile.normal_fill
|
||||
normal_fill.a = 1.0
|
||||
var selected_fill: Color = normal_fill
|
||||
if _selected:
|
||||
if _controller_preview_active:
|
||||
selected_fill = normal_fill.lightened(0.22)
|
||||
elif _selected:
|
||||
selected_fill = normal_fill.lightened(0.12)
|
||||
add_theme_stylebox_override(
|
||||
"normal",
|
||||
|
|
|
|||
|
|
@ -42,6 +42,53 @@ func _ready() -> void:
|
|||
_apply_icon_presentation(neutral_size)
|
||||
|
||||
|
||||
func _gui_input(event: InputEvent) -> void:
|
||||
if _adjustment_direction(self) == 0:
|
||||
return
|
||||
var direction: int = 0
|
||||
if event.is_action_pressed(&"ui_left"):
|
||||
direction = -1
|
||||
elif event.is_action_pressed(&"ui_right"):
|
||||
direction = 1
|
||||
if direction == 0:
|
||||
return
|
||||
var adjustment_button: BaseButton = _find_adjustment_button(direction)
|
||||
if adjustment_button == null:
|
||||
return
|
||||
adjustment_button.pressed.emit()
|
||||
accept_event()
|
||||
|
||||
|
||||
func _find_adjustment_button(direction: int) -> BaseButton:
|
||||
var parent_node: Node = get_parent()
|
||||
if parent_node == null:
|
||||
return null
|
||||
for child: Node in parent_node.get_children():
|
||||
var button := child as BaseButton
|
||||
if (
|
||||
button != null
|
||||
and button.visible
|
||||
and not button.disabled
|
||||
and _adjustment_direction(button) == direction
|
||||
):
|
||||
return button
|
||||
return null
|
||||
|
||||
|
||||
func _adjustment_direction(button: BaseButton) -> int:
|
||||
var descriptions: Array[String] = [
|
||||
button.text.strip_edges().to_lower(),
|
||||
button.tooltip_text.strip_edges().to_lower(),
|
||||
button.accessibility_name.strip_edges().to_lower(),
|
||||
]
|
||||
for description: String in descriptions:
|
||||
if description in ["-", "−", "minus", "decrease"]:
|
||||
return -1
|
||||
if description in ["+", "plus", "increase"]:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
func apply_layout(
|
||||
center: Vector2,
|
||||
bubble_size: Vector2,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
class_name BubbleCluster
|
||||
extends Control
|
||||
|
||||
const ControllerFocusNavigationType = preload(
|
||||
"res://ui/controller_focus_navigation.gd"
|
||||
)
|
||||
|
||||
@export var profile: BubbleMenuProfile
|
||||
@export var desktop_reference_size: Vector2 = Vector2(396.0, 318.0)
|
||||
@export var compact_reference_size: Vector2 = Vector2(294.0, 200.0)
|
||||
|
|
@ -18,14 +22,6 @@ func configure(bubbles: Array[BubbleButton]) -> void:
|
|||
if bubble.profile == null:
|
||||
bubble.profile = profile
|
||||
bubble.apply_profile()
|
||||
if index > 0:
|
||||
bubble.focus_neighbor_top = bubble.get_path_to(
|
||||
_bubbles[index - 1]
|
||||
)
|
||||
if index + 1 < _bubbles.size():
|
||||
bubble.focus_neighbor_bottom = bubble.get_path_to(
|
||||
_bubbles[index + 1]
|
||||
)
|
||||
|
||||
|
||||
func apply_layout(field_size: Vector2, compact: bool) -> void:
|
||||
|
|
@ -52,6 +48,7 @@ func apply_layout(field_size: Vector2, compact: bool) -> void:
|
|||
bubble_size,
|
||||
profile.font_size_ratio
|
||||
)
|
||||
ControllerFocusNavigationType.configure_spatial_neighbors(_bubbles)
|
||||
|
||||
|
||||
func advance_motion(delta: float) -> void:
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ var _quality_color := Color.WHITE
|
|||
|
||||
|
||||
func _ready() -> void:
|
||||
set_meta(&"controller_focus_inversion_disabled", true)
|
||||
resized.connect(_update_visual_pivot)
|
||||
focus_entered.connect(_refresh_style)
|
||||
focus_exited.connect(_refresh_style)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue