Per-metric ref lines with Hz spectrogram units; relative-time toggle; fixed font

Reference lines:
- Kept per metric (dict keyed by metric_id) so switching metrics and coming back
  preserves them, instead of clearing on every switch
- Spectrogram lines read/edit/drag in Hz: the renderer installs Hz<->row-index
  transforms (the heatmap y-axis is a row index), so value, label, the edit
  dialog, and the new-line default all speak frequency. Curve metrics stay
  identity. Round-trip verified (1000 Hz -> row -> 1000 Hz)
- Line label and drag-readback always in the metric's natural units

Controls:
- Relative-time abs/rel is now a checkbox toggle, not a dropdown
- Removed the font control panel; UI font is locked to M PLUS 1 Code @ 10pt via
  font_manager.apply_fixed_font (system-default fallback). Deleted
  font_control_widget.py

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Mikkeli Matlock
2026-06-14 01:05:23 +09:00
parent a45bd4ba9b
commit 22ecb67296
8 changed files with 132 additions and 387 deletions
+34 -3
View File
@@ -493,11 +493,42 @@ def initialize_fonts() -> bool:
def safe_title(title: str) -> str:
"""
Convenience function to get CJK-safe title.
Args:
title: Original title
Returns:
str: Safe title for display
"""
return get_font_manager().get_cjk_safe_title(title)
return get_font_manager().get_cjk_safe_title(title)
def apply_fixed_font(family: str = "M PLUS 1 Code", size: int = 10) -> str:
"""Lock the Qt application font to `family` at `size`pt.
Falls back to the system default family if `family` isn't available (loaded
from fonts/ or installed). pyqtgraph and the Qt widgets both read the app
font, so this is all the plot/UI need. Returns the family actually used.
"""
logger = logging.getLogger(__name__)
app = QCoreApplication.instance()
if app is None:
logger.warning("apply_fixed_font called before QApplication exists")
return family
try:
available = family in set(QFontDatabase().families())
except Exception:
available = False
if available:
font = QFont(family)
chosen = family
else:
font = QFont() # system default family
chosen = font.defaultFamily()
logger.info(f"Font '{family}' not found; using system default '{chosen}'")
font.setPointSize(size)
app.setFont(font)
logger.info(f"Application font locked to '{chosen}' at {size}pt")
return chosen