Skip to content

Commit 0c152fd

Browse files
fix(gamepad-tester): replace dropdowns with buttons (#311)
1 parent 907f45f commit 0c152fd

File tree

3 files changed

+89
-33
lines changed

3 files changed

+89
-33
lines changed

_sass/styles.scss

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,3 +164,22 @@ table tr:nth-child(2n) {
164164
.list-group {
165165
--bs-list-group-bg: var(--navbar-col);
166166
}
167+
168+
/* gamepad selector cards */
169+
.gamepad-selector-card {
170+
transition: all 0.2s ease-in-out;
171+
user-select: none;
172+
}
173+
174+
.gamepad-selector-card:hover {
175+
transform: translateY(-2px);
176+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
177+
}
178+
179+
.gamepad-selector-card.border-primary {
180+
box-shadow: 0 0 10px rgba(13, 110, 253, 0.3);
181+
}
182+
183+
.gamepad-selector-card.border-primary:hover {
184+
box-shadow: 0 4px 12px rgba(13, 110, 253, 0.5);
185+
}

assets/js/gamepad-tester.js

Lines changed: 68 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,15 @@ document.addEventListener('DOMContentLoaded', function() {
2020
// Setup gamepad event listeners
2121
window.addEventListener("gamepadconnected", function(e) {
2222
gamepads[e.gamepad.index] = e.gamepad;
23-
updateGamepadSelector();
23+
24+
// Always activate the newly connected gamepad
25+
activeGamepadIndex = e.gamepad.index;
26+
27+
updateGamepadSelector(); // This will highlight the active card
2428
updateStatus(`Gamepad ${e.gamepad.id} connected`);
2529

26-
// If this is the first gamepad, activate it
27-
if (activeGamepadIndex === null) {
28-
activeGamepadIndex = e.gamepad.index;
29-
gamepadSelector.value = activeGamepadIndex;
30+
// Start the loop if it's not already running
31+
if (!animationFrameId) {
3032
startGamepadLoop();
3133
}
3234
});
@@ -45,18 +47,21 @@ document.addEventListener('DOMContentLoaded', function() {
4547
const remainingIndices = Object.keys(gamepads);
4648
if (remainingIndices.length > 0) {
4749
activeGamepadIndex = Number.parseInt(remainingIndices[0]);
48-
gamepadSelector.value = activeGamepadIndex;
4950
} else {
5051
stopGamepadLoop();
5152
}
5253
}
5354
});
5455

55-
// Event listener for gamepad selector change
56-
gamepadSelector.addEventListener('change', function() {
57-
activeGamepadIndex = Number.parseInt(this.value);
58-
initGamepadButtons();
59-
initGamepadAxes();
56+
// Event delegation for gamepad selector cards
57+
gamepadSelector.addEventListener('click', function(e) {
58+
const card = e.target.closest('.gamepad-selector-card');
59+
if (card) {
60+
activeGamepadIndex = Number.parseInt(card.dataset.index);
61+
updateGamepadSelector(); // Re-render to update active state
62+
initGamepadButtons();
63+
initGamepadAxes();
64+
}
6065
});
6166

6267
// Event listeners for vibration controls
@@ -76,7 +81,7 @@ document.addEventListener('DOMContentLoaded', function() {
7681
document.getElementById('strong-value').textContent = this.value;
7782
});
7883

79-
// Update gamepad selector dropdown
84+
// Update gamepad selector buttons
8085
function updateGamepadSelector() {
8186
gamepadSelector.innerHTML = '';
8287

@@ -87,20 +92,56 @@ document.addEventListener('DOMContentLoaded', function() {
8792
gamepadInfoSection.style.display = 'flex';
8893

8994
gamepadIndices.forEach(index => {
90-
const option = document.createElement('option');
91-
option.value = index;
92-
option.textContent = `${gamepads[index].id} (Index: ${index})`;
93-
gamepadSelector.appendChild(option);
95+
const card = document.createElement('div');
96+
card.className = 'card gamepad-selector-card';
97+
card.dataset.index = index;
98+
card.style.cursor = 'pointer';
99+
card.style.minWidth = '200px';
100+
card.style.maxWidth = '300px';
101+
card.style.borderWidth = '2px'; // Always use 2px border
102+
103+
const isActive = activeGamepadIndex !== null && Number.parseInt(index) === activeGamepadIndex;
104+
105+
// Mark active gamepad card
106+
if (isActive) {
107+
card.classList.add('border-primary');
108+
card.style.backgroundColor = 'rgba(13, 110, 253, 0.15)';
109+
} else {
110+
card.classList.add('border-secondary');
111+
card.style.backgroundColor = 'rgba(255, 255, 255, 0.05)';
112+
}
113+
114+
const cardBody = document.createElement('div');
115+
cardBody.className = 'card-body p-2';
116+
117+
const gamepadInfo = gamepads[index];
118+
const typeInfo = gamepadHelper.getGamepadInfo(gamepadInfo.id);
119+
120+
cardBody.innerHTML = `
121+
<div class="d-flex align-items-center">
122+
<div class="me-2">
123+
<i class="fas fa-gamepad fa-2x ${isActive ? 'text-primary' : 'text-light'}"></i>
124+
</div>
125+
<div class="flex-grow-1">
126+
<div class="fw-bold small text-truncate text-white">${typeInfo.name}</div>
127+
<div class="text-light opacity-75" style="font-size: 0.75rem;">Index: ${index}</div>
128+
<div class="text-light opacity-75" style="font-size: 0.7rem;">${gamepadInfo.buttons.length} buttons, ${gamepadInfo.axes.length} axes</div>
129+
</div>
130+
<div class="ms-2" style="min-width: 50px; text-align: right;">
131+
${isActive ? '<span class="badge bg-primary">Active</span>' : ''}
132+
</div>
133+
</div>
134+
`;
135+
136+
card.appendChild(cardBody);
137+
gamepadSelector.appendChild(card);
94138
});
95139

96-
// Select the active gamepad
140+
// Initialize buttons and axes for the selected gamepad
97141
if (activeGamepadIndex !== null) {
98-
gamepadSelector.value = activeGamepadIndex;
142+
initGamepadButtons();
143+
initGamepadAxes();
99144
}
100-
101-
// Initialize buttons and axes for the selected gamepad
102-
initGamepadButtons();
103-
initGamepadAxes();
104145
} else {
105146
gamepadSelectorContainer.style.display = 'none';
106147
gamepadInfoSection.style.display = 'none';
@@ -481,18 +522,17 @@ document.addEventListener('DOMContentLoaded', function() {
481522

482523
// Initial check for already connected gamepads
483524
const initialGamepads = navigator.getGamepads();
484-
for (let i = 0; i < initialGamepads.length; i++) {
485-
if (initialGamepads[i]) {
486-
gamepads[initialGamepads[i].index] = initialGamepads[i];
525+
for (const element of initialGamepads) {
526+
if (element) {
527+
gamepads[element.index] = element;
487528
}
488529
}
489530

490-
updateGamepadSelector();
491-
492-
// If we have gamepads already, start the loop
531+
// If we have gamepads already, activate the first one
493532
if (Object.keys(gamepads).length > 0) {
494533
activeGamepadIndex = Number.parseInt(Object.keys(gamepads)[0]);
495534
updateStatus(`Gamepad ${gamepads[activeGamepadIndex].id} connected`);
535+
updateGamepadSelector(); // Update after setting activeGamepadIndex
496536
startGamepadLoop();
497537
}
498538
});

gamepad-tester.html

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,8 @@ <h2 class="fw-bolder mb-1">Gamepad Tester</h2>
2626
</div>
2727

2828
<div class="row mb-2" id="gamepad-selector-container" style="display: none;">
29-
<div class="col-md-6 mx-auto">
30-
<div class="input-group">
31-
<label for="gamepad-selector" class="input-group-text">Gamepad:</label>
32-
<select class="form-select" id="gamepad-selector"></select>
33-
</div>
29+
<div class="col-12">
30+
<div class="d-flex flex-wrap gap-2 justify-content-center" id="gamepad-selector"></div>
3431
</div>
3532
</div>
3633

0 commit comments

Comments
 (0)