refactor: group viewport/zoom/pan state into a Viewport sub-struct
The visible-window + pan-anchor state was 10 flat fields (viewStart, viewEnd, freqView*, pan*) used densely throughout the zoom/pan/scrollbar code. Group them into a Viewport sub-struct (app.view.*). Rename anchored strictly to 'app.' so ScopeView's own view->viewStart/viewEnd (same field names) are untouched. Settled render verified pixel-identical (AE=0); End/zoom path verified via injected key input. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+17
-17
@@ -283,7 +283,7 @@ void DrawLabels(Rectangle bounds)
|
||||
// Time labels
|
||||
for (int i = 0; i <= 10; i++) {
|
||||
float t = (float)i / 10;
|
||||
float timeSec = (app.viewStart + t * (app.viewEnd - app.viewStart)) * app.signal.duration;
|
||||
float timeSec = (app.view.start + t * (app.view.end - app.view.start)) * app.signal.duration;
|
||||
float x = bounds.x + t * bounds.width;
|
||||
char label[32];
|
||||
if (timeSec >= 60) sprintf(label, "%d:%02d", (int)(timeSec / 60), (int)(timeSec) % 60);
|
||||
@@ -293,8 +293,8 @@ void DrawLabels(Rectangle bounds)
|
||||
|
||||
// Frequency labels adapted to current zoom level
|
||||
float maxFreq = (float)app.signal.sampleRate / 2.0f;
|
||||
float freqMin = app.freqViewStart * maxFreq;
|
||||
float freqMax = app.freqViewEnd * maxFreq;
|
||||
float freqMin = app.view.freqStart * maxFreq;
|
||||
float freqMax = app.view.freqEnd * maxFreq;
|
||||
|
||||
// Choose tick spacing based on zoom range
|
||||
float freqRange = freqMax - freqMin;
|
||||
@@ -348,13 +348,13 @@ void DrawSelection(Rectangle bounds)
|
||||
Color overlayColor = Fade(BLACK, 0.25f); // Lighter overlay
|
||||
|
||||
// Convert signal coordinates to viewport coordinates
|
||||
float viewWidth = app.viewEnd - app.viewStart;
|
||||
float freqWidth = app.freqViewEnd - app.freqViewStart;
|
||||
float viewWidth = app.view.end - app.view.start;
|
||||
float freqWidth = app.view.freqEnd - app.view.freqStart;
|
||||
|
||||
float selStartX = bounds.x + ((app.sel.timeStart - app.viewStart) / viewWidth) * bounds.width;
|
||||
float selEndX = bounds.x + ((app.sel.timeEnd - app.viewStart) / viewWidth) * bounds.width;
|
||||
float selStartY = bounds.y + bounds.height - ((app.sel.freqEnd - app.freqViewStart) / freqWidth) * bounds.height;
|
||||
float selEndY = bounds.y + bounds.height - ((app.sel.freqStart - app.freqViewStart) / freqWidth) * bounds.height;
|
||||
float selStartX = bounds.x + ((app.sel.timeStart - app.view.start) / viewWidth) * bounds.width;
|
||||
float selEndX = bounds.x + ((app.sel.timeEnd - app.view.start) / viewWidth) * bounds.width;
|
||||
float selStartY = bounds.y + bounds.height - ((app.sel.freqEnd - app.view.freqStart) / freqWidth) * bounds.height;
|
||||
float selEndY = bounds.y + bounds.height - ((app.sel.freqStart - app.view.freqStart) / freqWidth) * bounds.height;
|
||||
|
||||
// Clamp to viewport bounds
|
||||
selStartX = fmaxf(bounds.x, fminf(bounds.x + bounds.width, selStartX));
|
||||
@@ -443,13 +443,13 @@ void DrawSelectionDrag(Rectangle bounds)
|
||||
(app.sel.isDragging && !IsMouseButtonDown(MOUSE_LEFT_BUTTON))) return;
|
||||
|
||||
// Convert signal coordinates to viewport coordinates
|
||||
float viewWidth = app.viewEnd - app.viewStart;
|
||||
float freqWidth = app.freqViewEnd - app.freqViewStart;
|
||||
float viewWidth = app.view.end - app.view.start;
|
||||
float freqWidth = app.view.freqEnd - app.view.freqStart;
|
||||
|
||||
float selStartX = bounds.x + ((app.sel.timeStart - app.viewStart) / viewWidth) * bounds.width;
|
||||
float selEndX = bounds.x + ((app.sel.timeEnd - app.viewStart) / viewWidth) * bounds.width;
|
||||
float selStartY = bounds.y + bounds.height - ((app.sel.freqEnd - app.freqViewStart) / freqWidth) * bounds.height;
|
||||
float selEndY = bounds.y + bounds.height - ((app.sel.freqStart - app.freqViewStart) / freqWidth) * bounds.height;
|
||||
float selStartX = bounds.x + ((app.sel.timeStart - app.view.start) / viewWidth) * bounds.width;
|
||||
float selEndX = bounds.x + ((app.sel.timeEnd - app.view.start) / viewWidth) * bounds.width;
|
||||
float selStartY = bounds.y + bounds.height - ((app.sel.freqEnd - app.view.freqStart) / freqWidth) * bounds.height;
|
||||
float selEndY = bounds.y + bounds.height - ((app.sel.freqStart - app.view.freqStart) / freqWidth) * bounds.height;
|
||||
|
||||
// Clamp to viewport bounds
|
||||
selStartX = fmaxf(bounds.x, fminf(bounds.x + bounds.width, selStartX));
|
||||
@@ -539,8 +539,8 @@ void DrawPlayhead(Rectangle bounds)
|
||||
if (!app.isPlaying || app.playheadT < 0.0f || app.playheadT > 1.0f) return;
|
||||
|
||||
float timePos = app.sel.timeStart + app.playheadT * (app.sel.timeEnd - app.sel.timeStart);
|
||||
float viewWidth = app.viewEnd - app.viewStart;
|
||||
float t = (timePos - app.viewStart) / viewWidth;
|
||||
float viewWidth = app.view.end - app.view.start;
|
||||
float t = (timePos - app.view.start) / viewWidth;
|
||||
float x = bounds.x + t * bounds.width;
|
||||
|
||||
// Clamp to bounds
|
||||
|
||||
Reference in New Issue
Block a user