From c6e9ba162c61b458ad233d0b289933bf3f7b6958 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Fri, 7 Aug 2026 21:48:31 -0400 Subject: [PATCH] fix(virtualhid_control): improve compact layout Make the control tool adapt better to narrower windows by stacking the device and control panels, reflowing the button grid, and allowing a smaller minimum/default width. The usage docs now note the compact responsive layout behavior. --- docs/usage.md | 2 ++ tools/virtualhid_control.cpp | 17 +++++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index 4056b6d..75b9b60 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -103,6 +103,8 @@ normalized gamepad output such as rumble, RGB LED, adaptive trigger, trigger rumble, and raw report events delivered through the normal callback path. Button controls are momentary by default so they behave like physical gamepad buttons; enable `Lock buttons` to keep the old click-to-toggle behavior for held inputs. +The resizable window supports a compact width. Its device and control panels +stack, and the button grid reflows, to keep controls usable when it is narrowed. The UI intentionally does not use gamepad navigation so virtual devices created by the tool cannot drive the tool's own controls. diff --git a/tools/virtualhid_control.cpp b/tools/virtualhid_control.cpp index 35def9d..41f50ee 100644 --- a/tools/virtualhid_control.cpp +++ b/tools/virtualhid_control.cpp @@ -271,11 +271,15 @@ namespace { ImGui::Begin("libvirtualhid control", nullptr, window_flags); const auto backend = backend_text(*runtime_); - ImGui::TextUnformatted(backend.c_str()); + ImGui::TextWrapped("%s", backend.c_str()); ImGui::Separator(); - if (ImGui::BeginTable("control-layout", 2, ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersInnerV)) { - ImGui::TableSetupColumn("Devices", ImGuiTableColumnFlags_WidthFixed, 330.0F); + if (ImGui::GetContentRegionAvail().x < 760.0F) { + render_device_panel(devices); + ImGui::Separator(); + render_control_panel(selected); + } else if (ImGui::BeginTable("control-layout", 2, ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersInnerV)) { + ImGui::TableSetupColumn("Devices", ImGuiTableColumnFlags_WidthFixed, 220.0F); ImGui::TableSetupColumn("Controls", ImGuiTableColumnFlags_WidthStretch); ImGui::TableNextRow(); @@ -459,7 +463,8 @@ namespace { button_active_.fill(false); } - if (ImGui::BeginTable("buttons", 4, ImGuiTableFlags_SizingStretchSame)) { + const auto column_count = ImGui::GetContentRegionAvail().x < 480.0F ? 3 : 4; + if (ImGui::BeginTable("buttons", column_count, ImGuiTableFlags_SizingStretchSame)) { for (std::size_t index = 0; index < button_choices.size(); ++index) { if (!visible_buttons[index]) { continue; @@ -955,9 +960,9 @@ namespace { main_scale = 1.0F; } - constexpr auto base_width = 1120; + constexpr auto base_width = 860; constexpr auto base_height = 760; - constexpr auto minimum_width = 980; + constexpr auto minimum_width = 600; constexpr auto minimum_height = 700; const auto window_flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY; auto *window = SDL_CreateWindow(