input_prompt_manager.gd 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. # Copyright (C) 2022-2023 John Pennycook
  2. # SPDX-License-Identifier: MIT
  3. @tool
  4. class_name InputPromptManager
  5. extends Node
  6. ## Singleton class for managing [InputPrompt]s.
  7. ##
  8. ## Singleton class for managing [InputPrompt]s.
  9. ## [br][br]
  10. ## [b]Note[/b]: An instance of [InputPromptManager] is autoloaded under the name
  11. ## PromptManager.
  12. ## Emitted when the preferred icons change. If the preferred icons are set to
  13. ## "Automatic", emitted whenever the input device changes.
  14. signal icons_changed
  15. ## The icons currently used by [ActionPrompt] nodes.
  16. var icons := InputPrompt.Icons.XBOX:
  17. get:
  18. # In the Editor, InputMap reflects Editor settings
  19. # Pick a default so there's something to render
  20. if Engine.is_editor_hint():
  21. return InputPrompt.Icons.XBOX
  22. return icons
  23. ## The icons currently used by [JoypadButtonPrompt] and [JoypadMotionPrompt] nodes.
  24. var joy_icons = InputPrompt.Icons.XBOX:
  25. get:
  26. # In the Editor, InputMap reflects Editor settings
  27. # Pick a default so there's something to render
  28. if Engine.is_editor_hint():
  29. return InputPrompt.Icons.XBOX
  30. return joy_icons
  31. ## The preferred icons to be used by [ActionPrompt], [JoypadButtonPrompt] and [JoypadMotionPrompt]
  32. ## nodes. When set to a specific value, all nodes with "Automatic" icons will be overridden to use
  33. ## the specified value.
  34. var preferred_icons := InputPrompt.Icons.AUTOMATIC:
  35. set(value):
  36. preferred_icons = value
  37. if preferred_icons == null or preferred_icons == InputPrompt.Icons.AUTOMATIC:
  38. icons = InputPrompt.Icons.XBOX
  39. else:
  40. icons = value
  41. emit_signal("icons_changed")
  42. ## The deadzone value used to detect joypad activity. The default value is determined by the
  43. ## "addons/input_prompts/joypad_detection_deadzone" setting in [ProjectSettings].
  44. var joypad_detection_deadzone := ProjectSettings.get_setting(
  45. "addons/input_prompts/joypad_detection_deadzone", 0.5
  46. )
  47. var _keyboard_textures: KeyboardTextures = load(
  48. ProjectSettings.get_setting(
  49. "addons/input_prompts/icons/keyboard", "res://addons/input_prompts/key_prompt/keys.tres"
  50. )
  51. )
  52. var _mouse_button_textures: MouseButtonTextures = load(
  53. ProjectSettings.get_setting(
  54. "addons/input_prompts/icons/mouse_buttons",
  55. "res://addons/input_prompts/mouse_button_prompt/buttons.tres"
  56. )
  57. )
  58. var _nintendo_button_textures: JoypadButtonTextures = load(
  59. ProjectSettings.get_setting(
  60. "addons/input_prompts/icons/joypad_buttons/nintendo",
  61. "res://addons/input_prompts/joypad_button_prompt/nintendo.tres"
  62. )
  63. )
  64. var _sony_button_textures: JoypadButtonTextures = load(
  65. ProjectSettings.get_setting(
  66. "addons/input_prompts/icons/joypad_buttons/sony",
  67. "res://addons/input_prompts/joypad_button_prompt/sony.tres"
  68. )
  69. )
  70. var _xbox_button_textures: JoypadButtonTextures = load(
  71. ProjectSettings.get_setting(
  72. "addons/input_prompts/icons/joypad_buttons/xbox",
  73. "res://addons/input_prompts/joypad_button_prompt/xbox.tres"
  74. )
  75. )
  76. var _nintendo_motion_textures: JoypadMotionTextures = load(
  77. ProjectSettings.get_setting(
  78. "addons/input_prompts/icons/joypad_motion/nintendo",
  79. "res://addons/input_prompts/joypad_motion_prompt/nintendo.tres"
  80. )
  81. )
  82. var _sony_motion_textures: JoypadMotionTextures = load(
  83. ProjectSettings.get_setting(
  84. "addons/input_prompts/icons/joypad_motion/sony",
  85. "res://addons/input_prompts/joypad_motion_prompt/sony.tres"
  86. )
  87. )
  88. var _xbox_motion_textures: JoypadMotionTextures = load(
  89. ProjectSettings.get_setting(
  90. "addons/input_prompts/icons/joypad_motion/xbox",
  91. "res://addons/input_prompts/joypad_motion_prompt/xbox.tres"
  92. )
  93. )
  94. ## Force all [InputPrompt] nodes to refresh their icons and events.
  95. ## Must be called if the [InputMap] is changed.
  96. func refresh() -> void:
  97. var prompts := get_tree().get_nodes_in_group("_input_prompts")
  98. for prompt in prompts:
  99. prompt.call_deferred("refresh")
  100. ## Return the [KeyboardTextures] used by [KeyPrompt] nodes.
  101. func get_keyboard_textures() -> KeyboardTextures:
  102. return _keyboard_textures
  103. ## Return the [MouseButtonTextures] used by [MouseButtonPrompt] nodes.
  104. func get_mouse_textures() -> MouseButtonTextures:
  105. return _mouse_button_textures
  106. ## Return the [JoypadButtonTextures] used by [JoypadButtonPrompt] nodes.
  107. func get_joypad_button_textures(icons: int) -> JoypadButtonTextures:
  108. match icons:
  109. InputPrompt.Icons.AUTOMATIC:
  110. return get_joypad_button_textures(joy_icons)
  111. InputPrompt.Icons.XBOX:
  112. return _xbox_button_textures
  113. InputPrompt.Icons.SONY:
  114. return _sony_button_textures
  115. InputPrompt.Icons.NINTENDO:
  116. return _nintendo_button_textures
  117. InputPrompt.Icons.KEYBOARD:
  118. push_error("No JoypadButtonTextures for InputPrompt.Icons.KEYBOARD.")
  119. return null
  120. ## Return the [JoypadMotionTextures] used by [JoypadMotionPrompt] nodes.
  121. func get_joypad_motion_textures(icons: int) -> JoypadMotionTextures:
  122. match icons:
  123. InputPrompt.Icons.AUTOMATIC:
  124. return get_joypad_motion_textures(joy_icons)
  125. InputPrompt.Icons.XBOX:
  126. return _xbox_motion_textures
  127. InputPrompt.Icons.SONY:
  128. return _sony_motion_textures
  129. InputPrompt.Icons.NINTENDO:
  130. return _nintendo_motion_textures
  131. InputPrompt.Icons.KEYBOARD:
  132. push_error("No JoypadMotionTextures for InputPrompt.Icons.KEYBOARD.")
  133. return null
  134. # Monitor InputEvents and emit icons_changed if:
  135. # 1) The user has not expressed an icon preference
  136. # 2) The type of InputEvent is different to last time
  137. func _input(event: InputEvent):
  138. if not (preferred_icons == null or preferred_icons == InputPrompt.Icons.AUTOMATIC):
  139. return
  140. if event is InputEventKey or event is InputEventMouse:
  141. if icons != InputPrompt.Icons.KEYBOARD:
  142. icons = InputPrompt.Icons.KEYBOARD
  143. emit_signal("icons_changed")
  144. if event is InputEventJoypadButton or event is InputEventJoypadMotion:
  145. # Do not detect Joypad unless value exceeds deadzone
  146. if event is InputEventJoypadMotion and absf(event.axis_value) < joypad_detection_deadzone:
  147. return
  148. var device = event.device
  149. var joy_name = Input.get_joy_name(device)
  150. if joy_name.find("Xbox") != -1:
  151. joy_icons = InputPrompt.Icons.XBOX
  152. elif joy_name.find("DualShock") != -1 or joy_name.find("PS") != -1:
  153. joy_icons = InputPrompt.Icons.SONY
  154. elif joy_name.find("Nintendo") != -1:
  155. joy_icons = InputPrompt.Icons.NINTENDO
  156. else:
  157. joy_icons = InputPrompt.Icons.XBOX
  158. if icons != joy_icons:
  159. icons = joy_icons
  160. emit_signal("icons_changed")