forked from ShadowBlip/OpenGamepadUI-plugin-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplugin.gd
168 lines (132 loc) · 5.82 KB
/
plugin.gd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
extends Plugin
var library_manager := load("res://core/global/library_manager.tres") as LibraryManager
var settings_manager := load("res://core/global/settings_manager.tres") as SettingsManager
var menu_state_machine := load("res://assets/state/state_machines/menu_state_machine.tres") as StateMachine
var launcher_state := load("res://assets/state/states/game_launcher.tres") as State
var card_scene := load("res://core/ui/components/card.tscn") as PackedScene
# Dictionary to track library items in the custom tab
var _library := {}
var _current_selection := {}
var _refresh_requested := false
var _refresh_in_progress := false
func _ready() -> void:
logger = Log.get_logger("TemplatePlugin", Log.LEVEL.DEBUG)
logger.info("Template plugin loaded")
# Load the Library implementation
var library: Library = load(plugin_base + "/core/library.tscn").instantiate()
add_child(library)
# Duplicate the AllGamesTab and rename it
var source_node = $"/root/CardUI/MenuContent/FullscreenMenus/LibraryMenu/TabContainer/AllGamesTab"
var copied_node = source_node.duplicate()
copied_node.name = "MyCategoryTab"
var tab_container = $"/root/CardUI/MenuContent/FullscreenMenus/LibraryMenu/TabContainer"
tab_container.add_child(copied_node)
# Rename AllGamesGrid to MyCategoryGrid
var grid_node = copied_node.get_node("MarginContainer/AllGamesGrid")
if grid_node:
grid_node.name = "MyCategoryGrid"
else:
logger.error("Failed to find MarginContainer/AllGamesGrid in copied node")
# Add the tab to tabs_state
var my_category_tab_node := ScrollContainer.new()
my_category_tab_node.name = "MyCategory"
var tabs_state := load("res://core/ui/card_ui/library/library_tabs_state.tres") as TabContainerState
tabs_state.add_tab("MyCategory", my_category_tab_node)
# Connect library change signals
var on_library_changed := func(item: LibraryItem):
logger.debug("Library changed for item: " + item.name + ", queuing refresh")
queue_refresh()
library_manager.library_item_added.connect(on_library_changed, CONNECT_DEFERRED)
library_manager.library_item_removed.connect(on_library_changed, CONNECT_DEFERRED)
library_manager.library_item_unhidden.connect(on_library_changed, CONNECT_DEFERRED)
# Initial population
queue_refresh()
## Queues a refresh of the MyCategoryGrid
func queue_refresh() -> void:
_refresh_requested = true
_refresh()
## Handles the actual refresh logic
func _refresh() -> void:
if not _refresh_requested or _refresh_in_progress:
return
_refresh_requested = false
_refresh_in_progress = true
await _populate_my_category_grid()
_refresh_in_progress = false
_refresh.call_deferred()
# Populates the MyCategoryGrid with library items
func _populate_my_category_grid() -> void:
var grid_node = $"/root/CardUI/MenuContent/FullscreenMenus/LibraryMenu/TabContainer/MyCategoryTab/MarginContainer/MyCategoryGrid"
if not grid_node or not grid_node is HFlowContainer:
logger.error("MyCategoryGrid not found or not an HFlowContainer")
return
# Clear existing children
for child in grid_node.get_children():
child.queue_free()
# Define the tab index for MyCategory (arbitrary, unique for tracking)
var tab_num := 100
# Get library items (modify this to filter for your category if needed)
var modifiers: Array[Callable] = [library_manager.sort_by_name]
var library_items := library_manager.get_library_items(modifiers)
# Clear the library dictionary for this tab
_library[tab_num] = {}
# Populate the grid
for i in range(library_items.size()):
var item: LibraryItem = library_items[i]
# Check if the item should be hidden
var is_hidden := settings_manager.get_library_value(item, "hidden", false) as bool
if is_hidden:
continue
# Build a card for the library item
var card := await _build_card(item)
# Listen for focus changes to track selection
card.focus_entered.connect(_on_focus_updated.bind(card, tab_num))
# Listen for library item removed events
var on_removed := func():
if tab_num in _library and item.name in _library[tab_num]:
var tracked_card = _library[tab_num][item.name]
_library[tab_num].erase(item.name)
if tab_num in _current_selection and _current_selection[tab_num] == tracked_card:
_current_selection.erase(tab_num)
if is_instance_valid(tracked_card):
tracked_card.queue_free()
else:
logger.warn("Attempted to free an invalid card for item: " + item.name)
item.removed_from_library.connect(on_removed)
item.hidden.connect(on_removed)
# Add the card to the grid
grid_node.add_child(card)
# Track the card in the library dictionary
_library[tab_num][item.name] = card
# Focus the first card if available
if grid_node.get_child_count() > 0:
var first_card: Control = grid_node.get_child(0)
if first_card.visible:
first_card.grab_focus.call_deferred()
# Builds a card from a library item
func _build_card(item: LibraryItem) -> GameCard:
var card := card_scene.instantiate() as GameCard
await card.set_library_item(item)
# Connect button press to launch the game
var on_button_up := func():
launcher_state.data = {"item": item}
menu_state_machine.push_state(launcher_state)
card.button_up.connect(on_button_up)
return card
# Handles focus updates for cards
func _on_focus_updated(card: Control, tab: int) -> void:
_current_selection[tab] = card
# Skip scrolling if mouse or touch is used
var input_manager := get_tree().get_first_node_in_group("InputManager")
if input_manager:
if (input_manager as InputManager).current_touches > 0:
return
if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
return
# Get the scroll container
var scroll_container := $"/root/CardUI/MenuContent/FullscreenMenus/LibraryMenu/TabContainer/MyCategoryTab" as ScrollContainer
if not scroll_container:
return
# Smoothly scroll to the card
var tween := get_tree().create_tween()
tween.tween_property(scroll_container, "scroll_vertical", card.position.y - card.size.y / 3, 0.25)