From 74560701df63d309fa00614e839fc209bc286144 Mon Sep 17 00:00:00 2001 From: "Sven | @greenpixels_" Date: Sat, 22 Feb 2025 21:18:02 +0100 Subject: [PATCH 1/8] feat: add force_device variable to always use a specified device --- .../objects/ControllerIconTexture.gd | 49 +++++++++++-------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/addons/controller_icons/objects/ControllerIconTexture.gd b/addons/controller_icons/objects/ControllerIconTexture.gd index 1af92ea..780d9dd 100644 --- a/addons/controller_icons/objects/ControllerIconTexture.gd +++ b/addons/controller_icons/objects/ControllerIconTexture.gd @@ -50,7 +50,7 @@ class_name ControllerIconTexture ## # res://addons/controller_icons/assets/steam/gyro.png ## path = "steam/gyro" ## [/codeblock] -@export var path : String = "": +@export var path: String = "": set(_path): path = _path _load_texture_path() @@ -63,7 +63,7 @@ enum ShowMode { ## Show the icon only if a specific input method is being used. When hidden, ## the icon will not occupy have any space (no width and height). -@export var show_mode : ShowMode = ShowMode.ANY: +@export var show_mode: ShowMode = ShowMode.ANY: set(_show_mode): show_mode = _show_mode _load_texture_path() @@ -71,7 +71,7 @@ enum ShowMode { enum ForceType { NONE, ## Icon will swap according to the used input method. KEYBOARD_MOUSE, ## Icon will always show the keyboard/mouse action. - CONTROLLER, ## Icon will always show the controller action. + CONTROLLER, ## Icon will always show the controller action. } ## Forces the icon to show either the keyboard/mouse or controller icon, @@ -79,14 +79,22 @@ enum ForceType { ##[br][br] ## This is only relevant for paths using input actions, and has no effect on ## other scenarios. -@export var force_type : ForceType = ForceType.NONE: +@export var force_type: ForceType = ForceType.NONE: set(_force_type): force_type = _force_type _load_texture_path() +## Forces the icon to use the textures for the device connected at the specified index. +## For example, if a PlayStation 5 controller is connected at device_index 0, +## the icon will always show PlayStation 5 textures. +@export var force_device: int = -1: + set(_force_device): + force_device = _force_device + _load_texture_path() + @export_subgroup("Text Rendering") ## Custom LabelSettings. If set, overrides the addon's global label settings. -@export var custom_label_settings : LabelSettings: +@export var custom_label_settings: LabelSettings: set(_custom_label_settings): custom_label_settings = _custom_label_settings _load_texture_path() @@ -117,7 +125,7 @@ func _can_be_shown(): 0, _: return true -var _textures : Array[Texture2D]: +var _textures: Array[Texture2D]: set(__textures): # UPGRADE: In Godot 4.2, for-loop variables can be # statically typed: @@ -147,9 +155,9 @@ var _textures : Array[Texture2D]: if tex: tex.connect("changed", _reload_resource) -var _font : Font -var _label_settings : LabelSettings -var _text_size : Vector2 +var _font: Font +var _label_settings: LabelSettings +var _text_size: Vector2 func _on_label_settings_changed(): _font = ThemeDB.fallback_font if not _label_settings.font else _label_settings.font @@ -161,13 +169,14 @@ func _reload_resource(): emit_changed() func _load_texture_path_impl(): - var textures : Array[Texture2D] = [] + var textures: Array[Texture2D] = [] if ControllerIcons.is_node_ready() and _can_be_shown(): var input_type = ControllerIcons._last_input_type if force_type == ForceType.NONE else force_type - 1 if ControllerIcons.get_path_type(path) == ControllerIcons.PathType.INPUT_ACTION: var event := ControllerIcons.get_matching_event(path, input_type) textures.append_array(ControllerIcons.parse_event_modifiers(event)) - var tex := ControllerIcons.parse_path(path, input_type) + var target_device = force_device if force_device >= 0 else ControllerIcons._last_controller + var tex := ControllerIcons.parse_path(path, input_type, target_device) if tex: textures.append(tex) _textures = textures @@ -200,7 +209,7 @@ func _get_width() -> int: return accum , 0) if _label_settings: - ret += max(0, _textures.size()-1) * _text_size.x + ret += max(0, _textures.size() - 1) * _text_size.x # If ret is 0, return a size of 2 to prevent triggering engine checks # for null sizes. The correct size will be set at a later frame. return ret if ret > 0 else _NULL_SIZE @@ -235,7 +244,7 @@ func _draw(to_canvas_item: RID, pos: Vector2, modulate: Color, transpose: bool): var position := pos for i in range(_textures.size()): - var tex:Texture2D = _textures[i] + var tex: Texture2D = _textures[i] if !tex: continue if i != 0: @@ -256,7 +265,7 @@ func _draw_rect(to_canvas_item: RID, rect: Rect2, tile: bool, modulate: Color, t var height_ratio := rect.size.y / _get_height() for i in range(_textures.size()): - var tex:Texture2D = _textures[i] + var tex: Texture2D = _textures[i] if !tex: continue if i != 0: @@ -278,7 +287,7 @@ func _draw_rect_region(to_canvas_item: RID, rect: Rect2, src_rect: Rect2, modula var height_ratio := rect.size.y / _get_height() for i in range(_textures.size()): - var tex:Texture2D = _textures[i] + var tex: Texture2D = _textures[i] if !tex: continue if i != 0: @@ -314,15 +323,15 @@ func _draw_text(to_canvas_item: RID, font_position: Vector2, text: String): _font.draw_string_outline(to_canvas_item, font_position, text, HORIZONTAL_ALIGNMENT_LEFT, -1, _label_settings.font_size, _label_settings.outline_size, _label_settings.outline_color) _font.draw_string(to_canvas_item, font_position, text, HORIZONTAL_ALIGNMENT_CENTER, -1, _label_settings.font_size, _label_settings.font_color) -var _helper_viewport : Viewport -var _is_stitching_texture : bool = false +var _helper_viewport: Viewport +var _is_stitching_texture: bool = false func _stitch_texture(): if _textures.is_empty(): return _is_stitching_texture = true - var font_image : Image + var font_image: Image if _textures.size() > 1: # Generate a viewport to draw the text _helper_viewport = SubViewport.new() @@ -345,7 +354,7 @@ func _stitch_texture(): _helper_viewport.free() var position := Vector2i(0, 0) - var img : Image + var img: Image for i in range(_textures.size()): if !_textures[i]: continue @@ -375,7 +384,7 @@ func _stitch_texture(): # This is necessary for 3D sprites, as the texture is assigned to a material, and not drawn directly. # For multi prompts, we need to generate a texture var _dirty := true -var _texture_3d : Texture +var _texture_3d: Texture func _get_rid(): if _dirty: if not _is_stitching_texture: From 36dd46b4c1bff545ee42bfd360d6b25dcc8f306e Mon Sep 17 00:00:00 2001 From: "Sven | @greenpixels_" Date: Sun, 23 Feb 2025 00:52:43 +0100 Subject: [PATCH 2/8] change: extend fallback logic to include all possible devices in an action --- addons/controller_icons/ControllerIcons.gd | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/addons/controller_icons/ControllerIcons.gd b/addons/controller_icons/ControllerIcons.gd index aac44a5..92f22fd 100644 --- a/addons/controller_icons/ControllerIcons.gd +++ b/addons/controller_icons/ControllerIcons.gd @@ -270,7 +270,7 @@ func get_matching_event(path: String, input_type: InputType = _last_input_type, else: events = InputMap.action_get_events(path) - var fallback = null + var fallbacks = [] for event in events: if not is_instance_valid(event): continue @@ -283,11 +283,13 @@ func get_matching_event(path: String, input_type: InputType = _last_input_type, # Use the first device specific mapping if there is one. if event.device == controller: return event - # Otherwise use the first "all devices" mapping. - elif fallback == null and event.device < 0: - fallback = event + # Otherwise, we create a fallback prioritizing events with 'ALL_DEVICE' + if event.device < 0: # All-device event + fallbacks.push_front(event) + else: + fallbacks.push_back(event) - return fallback + return fallbacks[0] if not fallbacks.is_empty() else null func _expand_path(path: String, input_type: int, controller: int) -> Array: var paths := [] From 23aecdaa2aaaec2c5d422a6810751ba11ec93336 Mon Sep 17 00:00:00 2001 From: "Sven | @greenpixels_" Date: Sun, 23 Feb 2025 01:22:11 +0100 Subject: [PATCH 3/8] change: use the given controller when resolving the joypad icon path instead of using the event.device --- addons/controller_icons/ControllerIcons.gd | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/controller_icons/ControllerIcons.gd b/addons/controller_icons/ControllerIcons.gd index 92f22fd..39f9f71 100644 --- a/addons/controller_icons/ControllerIcons.gd +++ b/addons/controller_icons/ControllerIcons.gd @@ -310,7 +310,7 @@ func _convert_path_to_asset_file(path: String, input_type: int, controller: int) PathType.INPUT_ACTION: var event := get_matching_event(path, input_type, controller) if event: - return _convert_event_to_path(event) + return _convert_event_to_path(event, controller) return path PathType.JOYPAD_PATH: return Mapper._convert_joypad_path(path, controller, _settings.joypad_fallback) @@ -374,7 +374,7 @@ func _convert_asset_file_to_tts(path: String) -> String: _: return path -func _convert_event_to_path(event: InputEvent): +func _convert_event_to_path(event: InputEvent, controller: int = _last_controller): if event is InputEventKey: # If this is a physical key, convert to localized scancode if event.keycode == 0: @@ -383,9 +383,9 @@ func _convert_event_to_path(event: InputEvent): elif event is InputEventMouseButton: return _convert_mouse_button_to_path(event.button_index) elif event is InputEventJoypadButton: - return _convert_joypad_button_to_path(event.button_index, event.device) + return _convert_joypad_button_to_path(event.button_index, controller) elif event is InputEventJoypadMotion: - return _convert_joypad_motion_to_path(event.axis, event.device) + return _convert_joypad_motion_to_path(event.axis, controller) func _convert_key_to_path(scancode: int): match scancode: From 3a919681ebc0586ecd444f6b1b16fcdb654e1a21 Mon Sep 17 00:00:00 2001 From: "Sven | @greenpixels_" Date: Sun, 2 Mar 2025 15:30:05 +0100 Subject: [PATCH 4/8] change: use enum instead of integer --- .../objects/ControllerIconTexture.gd | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/addons/controller_icons/objects/ControllerIconTexture.gd b/addons/controller_icons/objects/ControllerIconTexture.gd index 780d9dd..028536c 100644 --- a/addons/controller_icons/objects/ControllerIconTexture.gd +++ b/addons/controller_icons/objects/ControllerIconTexture.gd @@ -84,10 +84,30 @@ enum ForceType { force_type = _force_type _load_texture_path() +enum ForceDevice { + DEVICE_0, + DEVICE_1, + DEVICE_2, + DEVICE_3, + DEVICE_4, + DEVICE_5, + DEVICE_6, + DEVICE_7, + DEVICE_8, + DEVICE_9, + DEVICE_10, + DEVICE_11, + DEVICE_12, + DEVICE_13, + DEVICE_14, + DEVICE_15, + ANY # No device will be forced +} + ## Forces the icon to use the textures for the device connected at the specified index. ## For example, if a PlayStation 5 controller is connected at device_index 0, ## the icon will always show PlayStation 5 textures. -@export var force_device: int = -1: +@export var force_device: ForceDevice = ForceDevice.ANY: set(_force_device): force_device = _force_device _load_texture_path() @@ -175,7 +195,7 @@ func _load_texture_path_impl(): if ControllerIcons.get_path_type(path) == ControllerIcons.PathType.INPUT_ACTION: var event := ControllerIcons.get_matching_event(path, input_type) textures.append_array(ControllerIcons.parse_event_modifiers(event)) - var target_device = force_device if force_device >= 0 else ControllerIcons._last_controller + var target_device = force_device if force_device != ForceDevice.ANY else ControllerIcons._last_controller var tex := ControllerIcons.parse_path(path, input_type, target_device) if tex: textures.append(tex) From 2ee77452edee69bf1482767c57e90d6f4e12c1c1 Mon Sep 17 00:00:00 2001 From: "Sven | @greenpixels_" Date: Sun, 2 Mar 2025 17:30:07 +0100 Subject: [PATCH 5/8] feat: add option to force a specific controller icon style --- addons/controller_icons/ControllerIcons.gd | 29 ++++++++++--------- addons/controller_icons/Mapper.gd | 8 +++-- addons/controller_icons/Settings.gd | 3 +- .../objects/ControllerIconTexture.gd | 18 +++++++++++- 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/addons/controller_icons/ControllerIcons.gd b/addons/controller_icons/ControllerIcons.gd index 39f9f71..90dfe56 100644 --- a/addons/controller_icons/ControllerIcons.gd +++ b/addons/controller_icons/ControllerIcons.gd @@ -186,13 +186,14 @@ func refresh(): # All it takes is to signal icons to refresh paths emit_signal("input_type_changed", _last_input_type, _last_controller) +## TODO: Can this be removed? Seems like its unused - greenpixels func get_joypad_type(controller: int = _last_controller) -> ControllerSettings.Devices: return Mapper._get_joypad_type(controller, _settings.joypad_fallback) -func parse_path(path: String, input_type = _last_input_type, last_controller = _last_controller) -> Texture: +func parse_path(path: String, input_type = _last_input_type, last_controller = _last_controller, forced_controller_icon_style = ControllerSettings.Devices.NONE) -> Texture: if typeof(input_type) == TYPE_NIL: return null - var root_paths := _expand_path(path, input_type, last_controller) + var root_paths := _expand_path(path, input_type, last_controller, forced_controller_icon_style) for root_path in root_paths: if _load_icon(root_path): continue @@ -291,7 +292,7 @@ func get_matching_event(path: String, input_type: InputType = _last_input_type, return fallbacks[0] if not fallbacks.is_empty() else null -func _expand_path(path: String, input_type: int, controller: int) -> Array: +func _expand_path(path: String, input_type: int, controller: int, forced_controller_icon_style = ControllerSettings.Devices.NONE) -> Array: var paths := [] var base_paths := [ _settings.custom_asset_dir + "/", @@ -300,20 +301,20 @@ func _expand_path(path: String, input_type: int, controller: int) -> Array: for base_path in base_paths: if base_path.is_empty(): continue - base_path += _convert_path_to_asset_file(path, input_type, controller) + base_path += _convert_path_to_asset_file(path, input_type, controller, forced_controller_icon_style) paths.push_back(base_path + "." + _base_extension) return paths -func _convert_path_to_asset_file(path: String, input_type: int, controller: int) -> String: +func _convert_path_to_asset_file(path: String, input_type: int, controller: int, forced_controller_icon_style = ControllerSettings.Devices.NONE) -> String: match get_path_type(path): PathType.INPUT_ACTION: var event := get_matching_event(path, input_type, controller) if event: - return _convert_event_to_path(event, controller) + return _convert_event_to_path(event, controller, forced_controller_icon_style) return path PathType.JOYPAD_PATH: - return Mapper._convert_joypad_path(path, controller, _settings.joypad_fallback) + return Mapper._convert_joypad_path(path, controller, _settings.joypad_fallback, forced_controller_icon_style) PathType.SPECIFIC_PATH, _: return path @@ -374,7 +375,7 @@ func _convert_asset_file_to_tts(path: String) -> String: _: return path -func _convert_event_to_path(event: InputEvent, controller: int = _last_controller): +func _convert_event_to_path(event: InputEvent, controller: int = _last_controller, forced_controller_icon_style = ControllerSettings.Devices.NONE): if event is InputEventKey: # If this is a physical key, convert to localized scancode if event.keycode == 0: @@ -383,9 +384,9 @@ func _convert_event_to_path(event: InputEvent, controller: int = _last_controlle elif event is InputEventMouseButton: return _convert_mouse_button_to_path(event.button_index) elif event is InputEventJoypadButton: - return _convert_joypad_button_to_path(event.button_index, controller) + return _convert_joypad_button_to_path(event.button_index, controller, forced_controller_icon_style) elif event is InputEventJoypadMotion: - return _convert_joypad_motion_to_path(event.axis, controller) + return _convert_joypad_motion_to_path(event.axis, controller, forced_controller_icon_style) func _convert_key_to_path(scancode: int): match scancode: @@ -617,7 +618,7 @@ func _convert_mouse_button_to_path(button_index: int): _: return "mouse/sample" -func _convert_joypad_button_to_path(button_index: int, controller: int): +func _convert_joypad_button_to_path(button_index: int, controller: int, forced_controller_icon_style = ControllerSettings.Devices.NONE): var path match button_index: JOY_BUTTON_A: @@ -654,9 +655,9 @@ func _convert_joypad_button_to_path(button_index: int, controller: int): path = "joypad/share" _: return "" - return Mapper._convert_joypad_path(path, controller, _settings.joypad_fallback) + return Mapper._convert_joypad_path(path, controller, _settings.joypad_fallback, forced_controller_icon_style) -func _convert_joypad_motion_to_path(axis: int, controller: int): +func _convert_joypad_motion_to_path(axis: int, controller: int, forced_controller_icon_style = ControllerSettings.Devices.NONE): var path : String match axis: JOY_AXIS_LEFT_X, JOY_AXIS_LEFT_Y: @@ -669,7 +670,7 @@ func _convert_joypad_motion_to_path(axis: int, controller: int): path = "joypad/rt" _: return "" - return Mapper._convert_joypad_path(path, controller, _settings.joypad_fallback) + return Mapper._convert_joypad_path(path, controller, _settings.joypad_fallback, forced_controller_icon_style) func _load_icon(path: String) -> int: if _cached_icons.has(path): return OK diff --git a/addons/controller_icons/Mapper.gd b/addons/controller_icons/Mapper.gd index 25d597a..56a608b 100644 --- a/addons/controller_icons/Mapper.gd +++ b/addons/controller_icons/Mapper.gd @@ -1,8 +1,8 @@ extends Node class_name ControllerMapper -func _convert_joypad_path(path: String, device: int, fallback: ControllerSettings.Devices) -> String: - match _get_joypad_type(device, fallback): +func _convert_joypad_path(path: String, device: int, fallback: ControllerSettings.Devices, force_controller_icon_style = ControllerSettings.Devices.NONE) -> String: + match _get_joypad_type(device, fallback, force_controller_icon_style): ControllerSettings.Devices.LUNA: return _convert_joypad_to_luna(path) ControllerSettings.Devices.PS3: @@ -32,7 +32,9 @@ func _convert_joypad_path(path: String, device: int, fallback: ControllerSetting _: return "" -func _get_joypad_type(device, fallback): +func _get_joypad_type(device, fallback, force_controller_icon_style): + if force_controller_icon_style != ControllerSettings.Devices.NONE: + return force_controller_icon_style var available = Input.get_connected_joypads() if available.is_empty(): return fallback diff --git a/addons/controller_icons/Settings.gd b/addons/controller_icons/Settings.gd index 7400e77..cc4bf12 100644 --- a/addons/controller_icons/Settings.gd +++ b/addons/controller_icons/Settings.gd @@ -15,7 +15,8 @@ enum Devices { XBOX360, XBOXONE, XBOXSERIES, - STEAM_DECK + STEAM_DECK, + NONE } ## General addon settings diff --git a/addons/controller_icons/objects/ControllerIconTexture.gd b/addons/controller_icons/objects/ControllerIconTexture.gd index 028536c..e4274fb 100644 --- a/addons/controller_icons/objects/ControllerIconTexture.gd +++ b/addons/controller_icons/objects/ControllerIconTexture.gd @@ -68,6 +68,22 @@ enum ShowMode { show_mode = _show_mode _load_texture_path() + +## Forces the icon to show a specific controller style, regardless of the +## currently used controller type. +##[br][br] +## This will override force_device if set to a value other than NONE. +##[br][br] +## This is only relevant for paths using input actions, and has no effect on +## other scenarios. + + + +@export var force_controller_icon_style: ControllerSettings.Devices = ControllerSettings.Devices.NONE: + set(_force_controller_icon_style): + force_controller_icon_style = _force_controller_icon_style + _load_texture_path() + enum ForceType { NONE, ## Icon will swap according to the used input method. KEYBOARD_MOUSE, ## Icon will always show the keyboard/mouse action. @@ -196,7 +212,7 @@ func _load_texture_path_impl(): var event := ControllerIcons.get_matching_event(path, input_type) textures.append_array(ControllerIcons.parse_event_modifiers(event)) var target_device = force_device if force_device != ForceDevice.ANY else ControllerIcons._last_controller - var tex := ControllerIcons.parse_path(path, input_type, target_device) + var tex := ControllerIcons.parse_path(path, input_type, target_device, force_controller_icon_style) if tex: textures.append(tex) _textures = textures From 20582c337efe1082ec24fa57bde3685d6effcf76 Mon Sep 17 00:00:00 2001 From: "Sven | @greenpixels_" Date: Mon, 3 Mar 2025 15:29:13 +0100 Subject: [PATCH 6/8] change: put NONE enum entry at the beginning --- addons/controller_icons/Settings.gd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/controller_icons/Settings.gd b/addons/controller_icons/Settings.gd index cc4bf12..7c50dcf 100644 --- a/addons/controller_icons/Settings.gd +++ b/addons/controller_icons/Settings.gd @@ -3,6 +3,7 @@ extends Resource class_name ControllerSettings enum Devices { + NONE = -1, LUNA, OUYA, PS3, @@ -15,8 +16,7 @@ enum Devices { XBOX360, XBOXONE, XBOXSERIES, - STEAM_DECK, - NONE + STEAM_DECK } ## General addon settings From 3e8172abfca41a4e8e126dfc262c4fed24ffeded Mon Sep 17 00:00:00 2001 From: "Sven | @greenpixels_" Date: Mon, 3 Mar 2025 15:29:33 +0100 Subject: [PATCH 7/8] style: remove comment and empty lines --- addons/controller_icons/ControllerIcons.gd | 1 - addons/controller_icons/objects/ControllerIconTexture.gd | 2 -- 2 files changed, 3 deletions(-) diff --git a/addons/controller_icons/ControllerIcons.gd b/addons/controller_icons/ControllerIcons.gd index 90dfe56..0bcc975 100644 --- a/addons/controller_icons/ControllerIcons.gd +++ b/addons/controller_icons/ControllerIcons.gd @@ -186,7 +186,6 @@ func refresh(): # All it takes is to signal icons to refresh paths emit_signal("input_type_changed", _last_input_type, _last_controller) -## TODO: Can this be removed? Seems like its unused - greenpixels func get_joypad_type(controller: int = _last_controller) -> ControllerSettings.Devices: return Mapper._get_joypad_type(controller, _settings.joypad_fallback) diff --git a/addons/controller_icons/objects/ControllerIconTexture.gd b/addons/controller_icons/objects/ControllerIconTexture.gd index e4274fb..94369be 100644 --- a/addons/controller_icons/objects/ControllerIconTexture.gd +++ b/addons/controller_icons/objects/ControllerIconTexture.gd @@ -77,8 +77,6 @@ enum ShowMode { ## This is only relevant for paths using input actions, and has no effect on ## other scenarios. - - @export var force_controller_icon_style: ControllerSettings.Devices = ControllerSettings.Devices.NONE: set(_force_controller_icon_style): force_controller_icon_style = _force_controller_icon_style From e7186eff3b49dc589317a20cd26d5196707a9d6a Mon Sep 17 00:00:00 2001 From: greenpixels Date: Sun, 8 Jun 2025 13:43:57 +0200 Subject: [PATCH 8/8] only load textures once per frame --- addons/controller_icons/ControllerIcons.gd | 11 ++++++++-- .../objects/ControllerIconTexture.gd | 21 ++++++++++++------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/addons/controller_icons/ControllerIcons.gd b/addons/controller_icons/ControllerIcons.gd index 0bcc975..be0046d 100644 --- a/addons/controller_icons/ControllerIcons.gd +++ b/addons/controller_icons/ControllerIcons.gd @@ -14,11 +14,13 @@ enum PathType { SPECIFIC_PATH ## The path is a specific path. } +var _textures_to_update: Array[ControllerIconTexture] = [] + var _cached_icons := {} var _custom_input_actions := {} var _cached_callables_lock := Mutex.new() -var _cached_callables : Array[Callable] = [] +var _cached_callables: Array[Callable] = [] var _last_input_type : InputType var _last_controller : int @@ -170,6 +172,11 @@ func _test_mouse_velocity(relative_vec: Vector2): func _process(delta: float) -> void: _t += delta + for texture in _textures_to_update: + texture._load_texture_path() + texture._should_trigger_texture_load = false + + _textures_to_update = [] if not _cached_callables.is_empty() and _cached_callables_lock.try_lock(): # UPGRADE: In Godot 4.2, for-loop variables can be # statically typed: @@ -657,7 +664,7 @@ func _convert_joypad_button_to_path(button_index: int, controller: int, forced_c return Mapper._convert_joypad_path(path, controller, _settings.joypad_fallback, forced_controller_icon_style) func _convert_joypad_motion_to_path(axis: int, controller: int, forced_controller_icon_style = ControllerSettings.Devices.NONE): - var path : String + var path: String match axis: JOY_AXIS_LEFT_X, JOY_AXIS_LEFT_Y: path = "joypad/l_stick" diff --git a/addons/controller_icons/objects/ControllerIconTexture.gd b/addons/controller_icons/objects/ControllerIconTexture.gd index 94369be..e8df869 100644 --- a/addons/controller_icons/objects/ControllerIconTexture.gd +++ b/addons/controller_icons/objects/ControllerIconTexture.gd @@ -53,7 +53,7 @@ class_name ControllerIconTexture @export var path: String = "": set(_path): path = _path - _load_texture_path() + _should_trigger_texture_load = true enum ShowMode { ANY, ## Icon will be display on any input method. @@ -66,7 +66,7 @@ enum ShowMode { @export var show_mode: ShowMode = ShowMode.ANY: set(_show_mode): show_mode = _show_mode - _load_texture_path() + _should_trigger_texture_load = true ## Forces the icon to show a specific controller style, regardless of the @@ -80,7 +80,7 @@ enum ShowMode { @export var force_controller_icon_style: ControllerSettings.Devices = ControllerSettings.Devices.NONE: set(_force_controller_icon_style): force_controller_icon_style = _force_controller_icon_style - _load_texture_path() + _should_trigger_texture_load = true enum ForceType { NONE, ## Icon will swap according to the used input method. @@ -96,7 +96,7 @@ enum ForceType { @export var force_type: ForceType = ForceType.NONE: set(_force_type): force_type = _force_type - _load_texture_path() + _should_trigger_texture_load = true enum ForceDevice { DEVICE_0, @@ -124,14 +124,14 @@ enum ForceDevice { @export var force_device: ForceDevice = ForceDevice.ANY: set(_force_device): force_device = _force_device - _load_texture_path() + _should_trigger_texture_load = true @export_subgroup("Text Rendering") ## Custom LabelSettings. If set, overrides the addon's global label settings. @export var custom_label_settings: LabelSettings: set(_custom_label_settings): custom_label_settings = _custom_label_settings - _load_texture_path() + _should_trigger_texture_load = true # Call _textures setter, which handles signal connections for label settings _textures = _textures @@ -193,6 +193,13 @@ var _font: Font var _label_settings: LabelSettings var _text_size: Vector2 +var _should_trigger_texture_load = false: + set(value): + if _should_trigger_texture_load == value: return + _should_trigger_texture_load = value + if _should_trigger_texture_load and ControllerIcons != null: + ControllerIcons._textures_to_update.append(self) + func _on_label_settings_changed(): _font = ThemeDB.fallback_font if not _label_settings.font else _label_settings.font _text_size = _font.get_string_size("+", HORIZONTAL_ALIGNMENT_LEFT, -1, _label_settings.font_size) @@ -230,7 +237,7 @@ func _init(): ControllerIcons.input_type_changed.connect(_on_input_type_changed) func _on_input_type_changed(input_type: int, controller: int): - _load_texture_path() + _should_trigger_texture_load = true #region "Draw functions" const _NULL_SIZE := 2