Introduce a Metric ABC (compute on worker thread, render on GUI thread)
with a METRICS registry, and refactor the analysis pipeline around it.
RMS power (ported), raw waveform, and BS.1770 LUFS (via pyloudnorm) ship
as the initial three; new metrics drop in by appending to METRICS.
- metrics.py: Metric ABC + RMSPowerMetric, WaveformMetric (locked to
+/-1.1 y-range for float headroom), LUFSMetric (short-term 3 s window
+ integrated value, with streaming-target reference line).
- plot_control_widget.py: metric selector dropdown + Refresh Plot button
(moved out of FontControlWidget).
- analysis_results_manager.py: AnalysisResult caches the AudioFile and a
per-metric data dict; new MetricComputeWorker runs metric switches off
the GUI thread via metricComputeStarted/metricReady/metricComputeError
signals, so LUFS on a 12-minute track no longer stalls the UI.
- main.py: all redraw paths funnel through one _render_or_request helper;
stale-result guards keep slow computes from overwriting fresh selections.
- plotting_engine.py removed (metadata text moved onto AnalysisResult;
figure construction lives in each Metric).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add open file button for direct audio file selection
- Implement clustered FontControlWidget with font selector, size slider, and refresh controls
- Add auto-regeneration of matplotlib plots when fonts change
- Enhance FontManager with system font discovery and startup selection logic
- Replace individual font selector with comprehensive font control interface
- Support both custom fonts and system font candidates with proper prioritization
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>