Fix sidebar layout: sidebar on left (320px), spectrogram on right. SPACE toggles play/stop. dB floor triggers immediate redraw.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
2026-03-30 21:07:47 -07:00
parent 87183cbe7d
commit 5e7841fa76
+52 -26
View File
@@ -103,7 +103,7 @@ typedef struct {
float panStartViewStart;
float panStartViewEnd;
Vector2 panStartPos;
// Cached visible texture
Texture2D visibleTexture;
int cachedVisibleStart;
@@ -115,7 +115,7 @@ typedef struct {
float amplitudeCeilingDb;
ColormapType colormap;
bool showGrid;
int fftSize; // Current FFT size (512-8192)
int fftSize; // Current FFT size (128-2048)
// File browser state
bool showFileBrowser;
@@ -126,6 +126,9 @@ typedef struct {
int browserScroll;
int browserSelected;
bool isBrowsing;
// Playback state
bool isPlaying;
} SpectrogramApp;
// ============================================================================
@@ -816,12 +819,16 @@ static void DrawSelection(Rectangle bounds)
static void DrawSidebar(void)
{
float sidebarWidth = 280;
float sidebarWidth = 300;
float x = 10;
float y = 10;
int fontSize = 12;
bool needsRegen = false;
// Dark sidebar background
DrawRectangle(0, 0, sidebarWidth + 20, GetScreenHeight(), (Color){ 35, 35, 40, 255 });
DrawLine(sidebarWidth + 10, 0, sidebarWidth + 10, GetScreenHeight(), GRAY);
// Title
DrawText("Spectrogram Controls", x, y, 14, WHITE); y += 25;
@@ -849,7 +856,7 @@ static void DrawSidebar(void)
DrawSlider(dbSlider, dbValue);
if (UpdateSlider(dbSlider, &dbValue)) {
app.amplitudeFloorDb = -100.0f + dbValue * 80.0f;
needsRegen = true;
needsRegen = true; // Trigger immediate redraw
}
y += 25;
@@ -894,11 +901,18 @@ static void DrawSidebar(void)
// Playback
Rectangle playButton = { x, y, sidebarWidth - 10, 35 };
if (CheckCollisionPointRec(GetMousePosition(), playButton) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) {
PlaySelectedRegion();
if (app.isPlaying && AudioPlaybackSound.frameCount > 0) {
StopSound(AudioPlaybackSound);
app.isPlaying = false;
} else {
PlaySelectedRegion();
app.isPlaying = true;
}
}
DrawRectangleRec(playButton, (Color){ 40, 100, 40, 255 });
DrawRectangleLinesEx(playButton, 1, GREEN);
DrawText("PLAY Selection (SPACE)", playButton.x + 10, playButton.y + 12, fontSize, WHITE);
const char* playText = app.isPlaying ? "STOP (SPACE)" : "PLAY (SPACE)";
DrawRectangleRec(playButton, app.isPlaying ? (Color){ 120, 40, 40, 255 } : (Color){ 40, 100, 40, 255 });
DrawRectangleLinesEx(playButton, 1, app.isPlaying ? RED : GREEN);
DrawText(playText, playButton.x + 10, playButton.y + 12, fontSize, WHITE);
y += 45;
// Reset/Clear buttons
@@ -937,6 +951,7 @@ static void DrawSidebar(void)
if (needsRegen && app.stftComputed) {
GenerateSpectrogramTexture(&app.stft, &app.spectrogramImage, &app.spectrogramTexture);
app.visibleTextureValid = false; // Force cache invalidation
}
}
@@ -995,6 +1010,7 @@ int main(int argc, char* argv[])
app.cachedVisibleEnd = -1;
app.visibleTextureValid = false;
app.fftSize = FFT_SIZE_DEFAULT;
app.isPlaying = false;
GenerateColormapTexture();
ScanDirectory(GetWorkingDirectory());
@@ -1050,10 +1066,11 @@ int main(int argc, char* argv[])
// View controls
if (app.loaded && !app.showFileBrowser) {
Rectangle viewBounds = { 100, 50, GetScreenWidth() - 150, GetScreenHeight() - 150 };
// Spectrogram area is to the right of sidebar (320px)
Rectangle viewBounds = { 330, 50, GetScreenWidth() - 380, GetScreenHeight() - 150 };
// Zoom with mouse wheel (zooms to cursor position)
if (CheckCollisionPointRec(GetMousePosition(), viewBounds)) {
if (GetMousePosition().x > 320 && CheckCollisionPointRec(GetMousePosition(), viewBounds)) {
int wheel = GetMouseWheelMove();
if (wheel != 0) {
// Calculate mouse position as normalized time (0-1)
@@ -1117,8 +1134,16 @@ int main(int argc, char* argv[])
}
}
// Keyboard shortcuts (SPACE for play, ESC for clear)
if (IsKeyPressed(KEY_SPACE) && !app.showFileBrowser) PlaySelectedRegion();
// Keyboard shortcuts (SPACE for play/stop toggle, ESC for clear)
if (IsKeyPressed(KEY_SPACE) && !app.showFileBrowser) {
if (app.isPlaying && AudioPlaybackSound.frameCount > 0) {
StopSound(AudioPlaybackSound);
app.isPlaying = false;
} else {
PlaySelectedRegion();
app.isPlaying = true;
}
}
if (IsKeyPressed(KEY_ESCAPE)) {
if (app.showFileBrowser) {
@@ -1132,11 +1157,11 @@ int main(int argc, char* argv[])
}
}
// Selection
Rectangle selBounds = { 100, 50, GetScreenWidth() - 150, GetScreenHeight() - 150 };
// Selection (only when mouse is in spectrogram area, not sidebar)
Rectangle selBounds = { 330, 50, GetScreenWidth() - 380, GetScreenHeight() - 150 };
Vector2 mousePos = GetMousePosition();
if (app.loaded && !app.showFileBrowser && CheckCollisionPointRec(mousePos, selBounds)) {
if (app.loaded && !app.showFileBrowser && mousePos.x > 320 && CheckCollisionPointRec(mousePos, selBounds)) {
bool shiftHeld = IsKeyDown(KEY_LEFT_SHIFT) || IsKeyDown(KEY_RIGHT_SHIFT);
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) && !app.isPanning) {
@@ -1194,9 +1219,13 @@ int main(int argc, char* argv[])
BeginDrawing();
ClearBackground((Color){ 30, 30, 30, 255 });
Rectangle viewBounds = { 100, 50, GetScreenWidth() - 150, GetScreenHeight() - 150 };
// Spectrogram area is to the right of sidebar (320px)
Rectangle viewBounds = { 330, 50, GetScreenWidth() - 380, GetScreenHeight() - 150 };
// Draw spectrogram first (background)
// Draw sidebar first (on top left)
DrawSidebar();
// Draw spectrogram (background, in its own area)
if (app.loaded && app.stftComputed) {
// Calculate visible region
@@ -1247,21 +1276,18 @@ int main(int argc, char* argv[])
DrawText(TextFormat("Frequency (Hz) - Max: %d", app.signal.sampleRate / 2),
viewBounds.x - 50, viewBounds.y + viewBounds.height / 2 - 10, 14, Fade(LIGHTGRAY, 0.7f));
} else if (!app.showFileBrowser) {
const char* msg1 = "Press 'O' for file browser or drag & drop WAV";
const char* msg2 = "Or use command line: ./rspektrum <file.wav>";
const char* msg1 = "Press 'O' or click 'Open File Browser' to load a WAV";
const char* msg2 = "Or drag & drop a file, or use: ./rspektrum <file.wav>";
Vector2 t1 = MeasureTextEx(GetFontDefault(), msg1, 24, 0);
Vector2 t2 = MeasureTextEx(GetFontDefault(), msg2, 18, 0);
DrawText(msg1, GetScreenWidth() / 2 - t1.x / 2, GetScreenHeight() / 2 - t1.y / 2 - 15, 24, LIGHTGRAY);
DrawText(msg2, GetScreenWidth() / 2 - t2.x / 2, GetScreenHeight() / 2 - t2.y / 2 + 15, 18, GRAY);
DrawText(msg1, 350 + (GetScreenWidth() - 380 - 350) / 2 - t1.x / 2, GetScreenHeight() / 2 - t1.y / 2 - 15, 24, LIGHTGRAY);
DrawText(msg2, 350 + (GetScreenWidth() - 380 - 350) / 2 - t2.x / 2, GetScreenHeight() / 2 - t2.y / 2 + 15, 18, GRAY);
}
// Draw file browser on top (if active)
if (app.showFileBrowser) DrawFileBrowser();
// Draw sidebar controls
DrawSidebar();
// Draw FPS
// Draw FPS in spectrogram area
DrawFPS(GetScreenWidth() - 80, 10);
EndDrawing();
}