Skip to main content

GamepadWidget Class

A debug widget to visualize the state of a specific gamepad. More...

Declaration

class helios::ext::imgui::widgets::GamepadWidget { ... }

Base class

classImGuiWidget

Abstract base class for ImGui widgets rendered in debug overlays. More...

Public Constructors Index

GamepadWidget (helios::input::InputManager *inputManager)

Constructs the GamepadWidget. More...

Public Member Functions Index

voiddraw () override

Renders the gamepad debug interface using ImGui. More...

Private Member Functions Index

helios::input::types::GamepadindexToId (int index) noexcept

Helper to map an integer index (0-3) to a Gamepad enum ID. More...

voiddrawStickVisualizer (const char *label, const helios::math::vec2f &value, float radius)

Helper method to draw a visual representation of an analog stick. More...

voiddrawSettingsPanel (helios::input::types::Gamepad gamepadId)

Draws the settings panel for the currently selected gamepad. More...

Private Member Attributes Index

helios::input::InputManager *inputManager_ = nullptr

Pointer to the InputManager used to query gamepad states and access settings. Non-owning pointer; must be valid for the lifetime of this widget. More...

intselectedGamepadIndex_ = 0

The currently selected index in the UI combo box (0-3). Maps to Gamepad::ONE through Gamepad::FOUR. More...

boolshowSettings_ = true

Flag to control visibility of the settings panel. More...

Description

A debug widget to visualize the state of a specific gamepad.

This widget provides a comprehensive visual overview of a connected gamepad's state. It includes:

  • **Connection Status:** Live indicator if the gamepad is connected.
  • **Stick Visualization:** 2D plot showing the position of left/right analog sticks within a circular boundary.
  • **Triggers:** Progress bars visualizing the pressure level of left/right triggers.
  • **Buttons:** Read-only checkboxes showing the current pressed state of all standard gamepad buttons.
  • **Settings Panel:** Integrated configuration for deadzone and axis inversion (toggle via button).

The widget allows switching between different Gamepad IDs (1-4) at runtime via a dropdown menu. Settings configuration is automatically available through the InputManager's InputAdapter.

info

This widget is not thread-safe. Use from the main/render thread only.

Definition at line 43 of file GamepadWidget.ixx.

Public Constructors

GamepadWidget()

helios::ext::imgui::widgets::GamepadWidget::GamepadWidget (helios::input::InputManager * inputManager)
inline explicit

Constructs the GamepadWidget.

Parameters
inputManager

Pointer to the InputManager to query states and settings from. Pass nullptr to render an empty/disabled widget.

Definition at line 180 of file GamepadWidget.ixx.

181 : inputManager_(inputManager) {}

Public Member Functions

draw()

void helios::ext::imgui::widgets::GamepadWidget::draw ()
inline virtual

Renders the gamepad debug interface using ImGui.

Definition at line 186 of file GamepadWidget.ixx.

186 void draw() override {
187 if (!inputManager_) return;
188
189 // Helper Lambda to draw read-only checkboxes.
190 // Solves the "address of r-value" error (C2102) by creating a temporary l-value.
191 auto DrawReadOnlyCheckbox = [](const char* label, bool isPressed) {
192 ImGui::BeginDisabled(); // Visually gray out to indicate read-only
193 bool tempValue = isPressed; // Create l-value copy
194 ImGui::Checkbox(label, &tempValue); // Pass address of l-value
195 ImGui::EndDisabled();
196 };
197
198 ImGui::SetNextWindowSize(ImVec2(450, 550), ImGuiCond_FirstUseEver);
199
200 if (ImGui::Begin("Gamepad Debugger", nullptr, ImGuiWindowFlags_NoCollapse)) {
201
202 // 1 Gamepad Selection
203 const char* items[] = { "Gamepad 1", "Gamepad 2", "Gamepad 3", "Gamepad 4" };
204 ImGui::Combo("Select ID", &selectedGamepadIndex_, items, IM_ARRAYSIZE(items));
205
206 auto gamepadId = indexToId(selectedGamepadIndex_);
207
208 // 2 Connection Status
209 bool connected = inputManager_->isConnected(gamepadId);
210 ImGui::SameLine();
211 if (connected) {
212 ImGui::TextColored(ImVec4(0, 1, 0, 1), "Connected");
213 } else {
214 ImGui::TextColored(ImVec4(1, 0, 0, 1), "Disconnected");
215 }
216
217 // Settings toggle button (below combobox)
218 if (ImGui::Button(showSettings_ ? "Hide Settings" : "Show Settings")) {
219 showSettings_ = !showSettings_;
220 }
221
222 ImGui::Separator();
223
224 // --- Settings Panel (collapsible) ---
225 if (showSettings_) {
226 if (ImGui::CollapsingHeader("Controller Settings", ImGuiTreeNodeFlags_DefaultOpen)) {
227 drawSettingsPanel(gamepadId);
228 }
229 ImGui::Separator();
230 }
231
232 if (connected) {
233 // Retrieve const reference to state.
234 const auto& state = inputManager_->gamepadState(gamepadId);
235
236 // Layout: 2 Columns for Sticks
237 ImGui::Columns(2, "sticks", false);
238
239 // --- Left Stick ---
240 drawStickVisualizer("L-Stick", state.left(), 40.0f);
241 DrawReadOnlyCheckbox("L-Thumb", state.buttonLeftThumb());
242
243 ImGui::NextColumn();
244
245 // --- Right Stick ---
246 drawStickVisualizer("R-Stick", state.right(), 40.0f);
247 DrawReadOnlyCheckbox("R-Thumb", state.buttonRightThumb());
248
249 ImGui::Columns(1);
250 ImGui::Separator();
251
252 // --- Triggers (Progress Bars) ---
253 ImGui::Text("Triggers");
254
255 ImGui::Text("L: %.2f", state.triggerLeft());
256 ImGui::SameLine();
257 // ProgressBar expects [0.0, 1.0]
258 ImGui::ProgressBar(state.triggerLeft(), ImVec2(100, 0), "");
259
260 ImGui::SameLine(220); // Spacing
261
262 ImGui::Text("R: %.2f", state.triggerRight());
263 ImGui::SameLine();
264 ImGui::ProgressBar(state.triggerRight(), ImVec2(100, 0), "");
265
266 ImGui::Separator();
267
268 // --- Buttons ---
269 // Layout: 2 Columns (D-Pad vs Face Buttons)
270 ImGui::Columns(2, "buttons", false);
271
272 ImGui::Text("D-Pad");
273 DrawReadOnlyCheckbox("Up", state.buttonDpadUp());
274 DrawReadOnlyCheckbox("Down", state.buttonDpadDown());
275 DrawReadOnlyCheckbox("Left", state.buttonDpadLeft());
276 DrawReadOnlyCheckbox("Right", state.buttonDpadRight());
277
278 ImGui::NextColumn();
279
280 ImGui::Text("Face Buttons");
281 DrawReadOnlyCheckbox("A", state.buttonA());
282 DrawReadOnlyCheckbox("B", state.buttonB());
283 DrawReadOnlyCheckbox("X", state.buttonX());
284 DrawReadOnlyCheckbox("Y", state.buttonY());
285
286 ImGui::Columns(1);
287 ImGui::Separator();
288
289 // --- Middle / Bumpers ---
290 ImGui::Text("Center & Bumpers");
291
292 // Use manual layout for horizontal arrangement
293 DrawReadOnlyCheckbox("LB", state.buttonLeftBumper());
294 ImGui::SameLine();
295 DrawReadOnlyCheckbox("Back", state.buttonBack());
296 ImGui::SameLine();
297 DrawReadOnlyCheckbox("Guide", state.buttonGuide());
298 ImGui::SameLine();
299 DrawReadOnlyCheckbox("Start", state.buttonStart());
300 ImGui::SameLine();
301 DrawReadOnlyCheckbox("RB", state.buttonRightBumper());
302 }
303 else {
304 ImGui::TextDisabled("No input data available. Please connect a controller.");
305 }
306 }
307 ImGui::End();
308 }

Private Member Functions

drawSettingsPanel()

void helios::ext::imgui::widgets::GamepadWidget::drawSettingsPanel (helios::input::types::Gamepad gamepadId)
inline

Draws the settings panel for the currently selected gamepad.

Parameters
gamepadId

The gamepad to configure.

Definition at line 121 of file GamepadWidget.ixx.

121 void drawSettingsPanel(helios::input::types::Gamepad gamepadId) {
122 auto& settings = inputManager_->inputAdapter().gamepadSettings(gamepadId);
123
124 ImGui::Spacing();
125
126 // --- Deadzone Configuration (Side by Side) ---
127 ImGui::Columns(2, "deadzoneColumns", false);
128
129 // Left Stick Column
130 ImGui::Text("Left Stick");
131 float leftDeadzone = settings.leftStickDeadzone();
132 if (ImGui::SliderFloat("##LeftDZ", &leftDeadzone, 0.0f, 0.9f, "%.2f")) {
133 settings.setLeftStickDeadzone(leftDeadzone);
134 }
135
136 bool invertLX = settings.invertLeftX();
137 bool invertLY = settings.invertLeftY();
138 if (ImGui::Checkbox("Invert X##L", &invertLX)) settings.setInvertLeftX(invertLX);
139 ImGui::SameLine();
140 if (ImGui::Checkbox("Invert Y##L", &invertLY)) settings.setInvertLeftY(invertLY);
141
142 ImGui::NextColumn();
143
144 // Right Stick Column
145 ImGui::Text("Right Stick");
146 float rightDeadzone = settings.rightStickDeadzone();
147 if (ImGui::SliderFloat("##RightDZ", &rightDeadzone, 0.0f, 0.9f, "%.2f")) {
148 settings.setRightStickDeadzone(rightDeadzone);
149 }
150
151 bool invertRX = settings.invertRightX();
152 bool invertRY = settings.invertRightY();
153 if (ImGui::Checkbox("Invert X##R", &invertRX)) settings.setInvertRightX(invertRX);
154 ImGui::SameLine();
155 if (ImGui::Checkbox("Invert Y##R", &invertRY)) settings.setInvertRightY(invertRY);
156
157 ImGui::Columns(1);
158
159 ImGui::Spacing();
160
161 // --- Reset ---
162 if (ImGui::Button("Reset Settings")) {
163 settings.setLeftStickDeadzone(0.0f);
164 settings.setRightStickDeadzone(0.0f);
165 settings.setInvertLeftX(false);
166 settings.setInvertLeftY(false);
167 settings.setInvertRightX(false);
168 settings.setInvertRightY(false);
169 }
170 }

drawStickVisualizer()

void helios::ext::imgui::widgets::GamepadWidget::drawStickVisualizer (const char * label, const helios::math::vec2f & value, float radius)
inline

Helper method to draw a visual representation of an analog stick.

Draws a circle representing the boundary and a dot representing the stick's position.

Parameters
label

The label to display below the visualizer.

value

The normalized (x, y) vector of the stick axis.

radius

The radius of the visualization circle in pixels.

Definition at line 88 of file GamepadWidget.ixx.

88 void drawStickVisualizer(const char* label, const helios::math::vec2f& value, float radius) {
89 ImVec2 p = ImGui::GetCursorScreenPos();
90 ImDrawList* draw_list = ImGui::GetWindowDrawList();
91
92 float center_x = p.x + radius;
93 float center_y = p.y + radius;
94
95 // Draw Background Circle (Dark Grey)
96 draw_list->AddCircleFilled(ImVec2(center_x, center_y), radius, IM_COL32(50, 50, 50, 255));
97 // Draw Boundary (White)
98 draw_list->AddCircle(ImVec2(center_x, center_y), radius, IM_COL32(255, 255, 255, 255));
99
100 // Calculate Dot Position
101 // ImGui coordinates: Y increases downwards.
102 // Standard Gamepad Y: Up is usually positive (or negative depending on normalization,
103 // but we visually want "Up" stick to be "Up" on screen).
104 // Assuming GamepadState provides standard Cartesian (Up=+Y), we subtract Y for screen coords.
105 float dot_x = center_x + (value[0] * radius);
106 float dot_y = center_y - (value[1] * radius);
107
108 // Draw Stick Position Dot (Green)
109 draw_list->AddCircleFilled(ImVec2(dot_x, dot_y), 4.0f, IM_COL32(0, 255, 0, 255));
110
111 // Advance cursor to reserve space for the drawing
112 ImGui::Dummy(ImVec2(radius * 2, radius * 2));
113 ImGui::Text("%s: (%.2f, %.2f)", label, value[0], value[1]);
114 }

indexToId()

helios::input::types::Gamepad helios::ext::imgui::widgets::GamepadWidget::indexToId (int index)
inline nodiscard noexcept

Helper to map an integer index (0-3) to a Gamepad enum ID.

Parameters
index

The index selected in the UI.

Returns

The corresponding Gamepad enum value.

Definition at line 69 of file GamepadWidget.ixx.

69 [[nodiscard]] helios::input::types::Gamepad indexToId(int index) noexcept {
70 switch (index) {
76 }
77 }

Private Member Attributes

inputManager_

helios::input::InputManager* helios::ext::imgui::widgets::GamepadWidget::inputManager_ = nullptr

Pointer to the InputManager used to query gamepad states and access settings. Non-owning pointer; must be valid for the lifetime of this widget.

Definition at line 50 of file GamepadWidget.ixx.

50 helios::input::InputManager* inputManager_ = nullptr;

selectedGamepadIndex_

int helios::ext::imgui::widgets::GamepadWidget::selectedGamepadIndex_ = 0

The currently selected index in the UI combo box (0-3). Maps to Gamepad::ONE through Gamepad::FOUR.

Definition at line 56 of file GamepadWidget.ixx.

56 int selectedGamepadIndex_ = 0;

showSettings_

bool helios::ext::imgui::widgets::GamepadWidget::showSettings_ = true

Flag to control visibility of the settings panel.

Definition at line 61 of file GamepadWidget.ixx.

61 bool showSettings_ = true;

The documentation for this class was generated from the following file:


Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.15.0.