feat: scroll the sidebar controls with the mouse wheel when they overflow

The left-hand control panel is laid out top-to-bottom with a running y; with
annotations expanded or a short window, the bottom buttons (export, signal
info, about) ran off the bottom and were unreachable. Offset the content by a
sidebarScroll amount, measure the laid-out height, and let the wheel scroll it
(clamped) when the cursor is over the sidebar and no modal is open. No visible
scrollbar; the spectrogram's wheel-zoom already ignores the sidebar column so
the two never both fire.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-05 16:09:38 -07:00
parent b95cafdf3b
commit b72e1cef18
2 changed files with 28 additions and 2 deletions
+3
View File
@@ -187,6 +187,9 @@ typedef struct {
// Overlays
bool showAbout; // About / help dialog
// Sidebar scroll offset (px), for when controls overflow a short window
float sidebarScroll;
// File browser state
bool showFileBrowser;
char browserPath[512];
+25 -2
View File
@@ -336,11 +336,15 @@ void DrawSidebar(void)
float scale = GetUIScale();
float sidebarWidth = 300 * scale;
float x = 10 * scale;
float y = 10 * scale;
float topMargin = 10 * scale;
// Content is laid out top-to-bottom from `y`; shift it up by the scroll
// offset so controls that overflow a short window can be reached. Clicks and
// sliders track automatically since their rects are derived from `y`.
float y = topMargin - app.sidebarScroll;
int fontSize = (int)(12 * scale);
bool needsRegen = false;
// Dark sidebar background
// Dark sidebar background (fixed; does not scroll)
DrawRectangle(0, 0, (int)(sidebarWidth + 20 * scale), GetScreenHeight(), (Color){ 35, 35, 40, 255 });
DrawLine((int)(sidebarWidth + 10 * scale), 0, (int)(sidebarWidth + 10 * scale), GetScreenHeight(), GRAY);
@@ -644,6 +648,25 @@ void DrawSidebar(void)
ColorizeSpectrogram(&app.spectrogramImage, &app.spectrogramTexture);
app.visibleTextureValid = false; // Force cache invalidation
}
// ---- Scroll handling ----
// `y` now sits at the bottom of the laid-out content (in screen space).
// Its natural position (scroll == 0) is y + sidebarScroll; allow scrolling
// until that bottom, plus a small pad, reaches the window's bottom edge.
float contentBottom = y + app.sidebarScroll;
float maxScroll = contentBottom + topMargin - GetScreenHeight();
if (maxScroll < 0) maxScroll = 0;
// Wheel scrolls the sidebar only when the cursor is over it and no modal is
// up. The spectrogram's own wheel-zoom already ignores the sidebar column,
// so the two never both fire.
bool overSidebar = GetMousePosition().x < (sidebarWidth + 20 * scale);
if (overSidebar && !UiModalOpen()) {
float wheel = GetMouseWheelMove();
if (wheel != 0.0f) app.sidebarScroll -= wheel * 40 * scale;
}
if (app.sidebarScroll > maxScroll) app.sidebarScroll = maxScroll;
if (app.sidebarScroll < 0.0f) app.sidebarScroll = 0.0f;
}
static void DrawSlider(Rectangle bounds, float value)