Skip to content

[FEATURE] Centralized Base Button SFX Hook #763

Description

@ikostan

Sub-Issue 4: Centralized Base Button SFX Hook


Description

Implement a centralized runtime hook to automatically attach selection feedback audio to all standard flat buttons across the entire user interface. Instead of manually wiring local button signals or dealing with split mouse/keyboard input event logic, this system intercepts UI element instantiation globally. It guarantees that any native base button fires the confirmation chime when activated via mouse click, keyboard (Enter/Space), or controller submission, while strictly shielding specialized toggle components from double-triggering or incorrect audio mapping.

Note: Automated GUT unit testing for this specific hook is tracked as an integrated testing requirement under its own dedicated task specifications.

Audio Mappings

  • Button Pressed: Activating a qualifying base button triggers AudioManager.play_sfx("ui_accept").

Technical Architectural Requirements

1. Scene Tree Instantiation Monitoring (res://scripts/core/globals.gd)

  • Inside the _ready() function of the Globals autoload singleton, establish a listener tracking the global scene graph by connecting to the tree monitor signal: get_tree().node_added.connect(_on_node_added).

2. Strict Class Filtering & Exclusion Gate

  • Implement the callback func _on_node_added(node: Node) -> void to dynamically evaluate UI elements as they enter active memory.
  • Strict Type Matching: Explicitly filter elements using string comparison against the native base class: if node.get_class() == "Button":.
  • Subclass Protection: This exact check prevents the audio connection from spreading to more specialized structural inheritance nodes which manage their own distinct interaction profiles, cleanly isolating the sound away from:
    • CheckButton
    • CheckBox
    • OptionButton (dropdown handles)

3. Thread-Safe Deferred Signal Connection

  • Connect the filtered button's native pressed signal to an anonymous lambda invocation or a private helper executing AudioManager.play_sfx("ui_accept").
  • Deferred Connection Guard: Always pass the CONNECT_DEFERRED flag as the final argument to the connection function:
    node.pressed.connect(func(): AudioManager.play_sfx("ui_accept"), CONNECT_DEFERRED)

Metadata

Metadata

Labels

Projects

Status
Done

Relationships

None yet

Development

No branches or pull requests

Issue actions