gui: add checkable constellation legend to filter sky plot by GNSS system

Replaces the static painted legend with real checkboxes (one per
GNSS system, color-swatched to match GNSS_COLORS) so users can
toggle which constellations show in the sky plot and satellite
table, mirroring the existing receiver-source filter checkboxes.
This commit is contained in:
2026-07-17 15:52:30 +02:00
parent eb18b1485f
commit f7af4e5b31
2 changed files with 35 additions and 24 deletions
+34 -4
View File
@@ -13,7 +13,7 @@ from PyQt5.QtWidgets import (
QSplitter, QGroupBox, QFrame, QCheckBox, QSpinBox,
)
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtGui import QColor, QBrush
from PyQt5.QtGui import QColor, QBrush, QIcon, QPixmap
from data_model import ReceiverManager, GNSS_NAMES, GNSS_COLORS
from sky_widget import SkyPlotWidget
@@ -37,6 +37,8 @@ class SkyTab(QWidget):
self._name_labels: dict = {} # rid -> QLabel (receiver display name)
self._trail: dict = {} # (rid, gnss_id, sv_id) -> deque[(elev, azim)]
self._hi_timers: dict = {} # (rid, gnss_id, sv_id) -> QTimer
self._gnss_checks: dict = {} # gnss_id -> QCheckBox
self._enabled_gnss: set = set(GNSS_NAMES.keys())
outer = QVBoxLayout(self)
outer.setContentsMargins(4, 4, 4, 4)
@@ -68,7 +70,28 @@ class SkyTab(QWidget):
self._trail_spin.setEnabled(False)
self._trail_spin.valueChanged.connect(self._on_trail_toggled)
src_bl.addWidget(self._trail_spin)
outer.addWidget(src_box)
# ── Constellation legend / filter ─────────────────────────────────────
const_box = QGroupBox("Constellations (check to show)")
const_box.setMaximumHeight(80)
const_bl = QHBoxLayout(const_box)
const_bl.setContentsMargins(4, 2, 4, 2)
const_bl.setSpacing(8)
for gid in sorted(GNSS_NAMES):
cb = QCheckBox(GNSS_NAMES[gid])
cb.setChecked(True)
pix = QPixmap(10, 10)
pix.fill(QColor(GNSS_COLORS.get(gid, '#9E9E9E')))
cb.setIcon(QIcon(pix))
cb.toggled.connect(lambda checked, g=gid: self._on_gnss_toggled(g, checked))
self._gnss_checks[gid] = cb
const_bl.addWidget(cb)
const_bl.addStretch()
filter_row = QHBoxLayout()
filter_row.addWidget(src_box)
filter_row.addWidget(const_box)
outer.addLayout(filter_row)
# ── Info bar (one card per receiver) ──────────────────────────────────
info_frame = QFrame()
@@ -181,7 +204,7 @@ class SkyTab(QWidget):
def _visible_sats(self) -> list:
selected = self._selected_rids()
return [(k[0], self._store[k])
for k in self._store if k[0] in selected]
for k in self._store if k[0] in selected and k[1] in self._enabled_gnss]
def _active_trails(self) -> dict:
if not self._trail_cb.isChecked():
@@ -192,7 +215,14 @@ class SkyTab(QWidget):
selected = self._selected_rids()
return {key: list(dq)[-n_points:]
for key, dq in self._trail.items()
if key[0] in selected}
if key[0] in selected and key[1] in self._enabled_gnss}
def _on_gnss_toggled(self, gid: int, checked: bool):
if checked:
self._enabled_gnss.add(gid)
else:
self._enabled_gnss.discard(gid)
self._refresh_immediate()
# ── Trail toggle ──────────────────────────────────────────────────────────