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