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:
+50
-24
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user