Rebalance overlay layout and fix the layout-on-launch overlap

Feedback from real use: the center column was far too wide and Injection/Log too
narrow; Audio was too tall while Controllers/Video were too short; and the layout
overlapped on launch until "Reset layout" was pressed.

- Columns are now proportional: Injection (left) and Log (right) take 36% each of the
  usable width, the center control column 28% -- so the wide panels are wide and the
  control panels narrow.
- The center stack heights are evened out (Controllers 30% / Video 38% / Audio 32% of
  the column), so Audio no longer hogs it.
- The default layout is now forced (ImGuiCond_Always) for the first few frames after
  launch, because the viewport WorkSize isn't trustworthy on frame 0 -- FirstUseEver
  was locking in those wrong (overlapping) positions until a manual Reset layout.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-21 10:41:58 +02:00
parent 784c31a9b5
commit 1493ce08e5

View File

@@ -13,6 +13,10 @@ namespace
// Set by "View -> Reset layout"; true for the one frame in which panels re-apply
// their default position/size, then cleared by apply_layout_end_frame().
bool g_layout_reset = false;
// Force the computed layout for the first few frames after launch: the viewport
// WorkSize isn't trustworthy on frame 0, and FirstUseEver would otherwise lock in
// those wrong positions (overlapping) until the user pressed Reset layout.
int g_startup_force = 4;
} // namespace
void request_layout_reset()
@@ -23,6 +27,10 @@ void request_layout_reset()
void apply_layout_end_frame()
{
g_layout_reset = false;
if (g_startup_force > 0)
{
--g_startup_force;
}
}
void apply_panel_layout(Panel panel)
@@ -33,43 +41,52 @@ void apply_panel_layout(Panel panel)
const float m = 12.0f; // outer margin
const float gap = 10.0f; // between panels
const float left_w = 440.0f; // Injection (window list + hook diagnostics)
const float right_w = 380.0f; // Log
const float center_x = o.x + m + left_w + gap;
const float right_x = o.x + s.x - right_w - m;
const float center_w = std::max(360.0f, right_x - gap - center_x);
// Three columns: Injection (left) and Log (right) are the wide ones (window list
// titles / log lines); the center control-panel column is the narrow one.
const float usable_w = std::max(600.0f, s.x - 2.0f * m - 2.0f * gap);
const float left_w = usable_w * 0.36f;
const float center_w = usable_w * 0.28f;
const float right_w = usable_w * 0.36f;
const float left_x = o.x + m;
const float center_x = left_x + left_w + gap;
const float right_x = center_x + center_w + gap;
const float top = o.y + m;
const float full_h = std::max(200.0f, s.y - 2.0f * m);
const float ctrl_h = 210.0f; // Controllers
const float vid_h = 250.0f; // Video mirror
const float audio_y = o.y + m + ctrl_h + gap + vid_h + gap;
const float bottom = o.y + m + full_h;
// Center column stacks Controllers / Video / Audio at roughly even heights (Video
// a touch taller for its graphs), so Audio no longer hogs the column.
const float stack_avail = std::max(150.0f, full_h - 2.0f * gap);
const float ctrl_h = stack_avail * 0.30f;
const float vid_h = stack_avail * 0.38f;
const float audio_h = stack_avail * 0.32f;
ImVec2 pos, size;
switch (panel)
{
case Panel::Injection:
pos = ImVec2(o.x + m, o.y + m);
pos = ImVec2(left_x, top);
size = ImVec2(left_w, full_h);
break;
case Panel::Controllers:
pos = ImVec2(center_x, o.y + m);
pos = ImVec2(center_x, top);
size = ImVec2(center_w, ctrl_h);
break;
case Panel::Video:
pos = ImVec2(center_x, o.y + m + ctrl_h + gap);
pos = ImVec2(center_x, top + ctrl_h + gap);
size = ImVec2(center_w, vid_h);
break;
case Panel::Audio:
pos = ImVec2(center_x, audio_y);
size = ImVec2(center_w, std::max(180.0f, bottom - audio_y));
pos = ImVec2(center_x, top + ctrl_h + gap + vid_h + gap);
size = ImVec2(center_w, audio_h);
break;
case Panel::Log:
pos = ImVec2(right_x, o.y + m);
pos = ImVec2(right_x, top);
size = ImVec2(right_w, full_h);
break;
}
const ImGuiCond cond = g_layout_reset ? ImGuiCond_Always : ImGuiCond_FirstUseEver;
const ImGuiCond cond = (g_layout_reset || g_startup_force > 0) ? ImGuiCond_Always : ImGuiCond_FirstUseEver;
ImGui::SetNextWindowPos(pos, cond);
ImGui::SetNextWindowSize(size, cond);
}