summaryrefslogtreecommitdiff
path: root/ui/windows/signals_window.py
diff options
context:
space:
mode:
Diffstat (limited to 'ui/windows/signals_window.py')
-rw-r--r--ui/windows/signals_window.py61
1 files changed, 54 insertions, 7 deletions
diff --git a/ui/windows/signals_window.py b/ui/windows/signals_window.py
index ff863af..0bf9dba 100644
--- a/ui/windows/signals_window.py
+++ b/ui/windows/signals_window.py
@@ -40,6 +40,8 @@ def _channel_combo(registry: DeviceRegistry,
cb = QComboBox(); cb.setObjectName("channelPickerCb")
for dev in registry.all_instances():
for ch in dev.info.channels:
+ if not ch.enabled:
+ continue
label = f"{dev.info.device_id} / {ch.channel_id} ({ch.name})"
if show_unit and ch.unit:
label += f" [{ch.unit}]"
@@ -255,7 +257,8 @@ class PipelineTab(QWidget):
super().__init__()
self.registry = registry
self.processor = processor
- self._shown: Set[Tuple[str,str]] = set() # (dev_id, ch_id)
+ self._shown: Set[Tuple[str,str]] = set()
+ self._blocks: dict[Tuple[str,str], ChannelPipelineBlock] = {}
self._build()
def _build(self):
@@ -285,10 +288,11 @@ class PipelineTab(QWidget):
scroll.setWidget(self._cont)
lay.addWidget(scroll, 1)
- # Populate with all device channels on startup
+ # Populate with enabled device channels on startup
for dev in self.registry.all_instances():
for ch in dev.info.channels:
- self._add_block(dev.info.device_id, ch.channel_id, ch.name, ch.unit)
+ if ch.enabled:
+ self._add_block(dev.info.device_id, ch.channel_id, ch.name, ch.unit)
self._refresh_avail_cb()
@@ -301,9 +305,29 @@ class PipelineTab(QWidget):
block = ChannelPipelineBlock(dev_id, ch_id, ch_name, unit, self.processor)
block.changed.connect(self.changed)
block.removed.connect(self._on_remove_block)
+ self._blocks[(dev_id, ch_id)] = block
# Insert before the trailing stretch
self._inner.insertWidget(self._inner.count() - 1, block)
+ def on_channel_enabled_changed(self, dev_id: str, ch_id: str, enabled: bool):
+ key = (dev_id, ch_id)
+ if enabled:
+ if key not in self._shown:
+ dev = self.registry.get_instance(dev_id)
+ if dev:
+ ch = dev.get_channel(ch_id)
+ if ch:
+ self._add_block(dev_id, ch_id, ch.name, ch.unit)
+ else:
+ block = self._blocks.get(key)
+ if block:
+ block.setVisible(True)
+ else:
+ block = self._blocks.get(key)
+ if block:
+ block.setVisible(False)
+ self._refresh_avail_cb()
+
def _on_add_channel(self):
data = self._avail_cb.currentData()
if not data:
@@ -319,7 +343,9 @@ class PipelineTab(QWidget):
self._refresh_avail_cb()
def _on_remove_block(self, block: ChannelPipelineBlock):
- self._shown.discard((block.dev_id, block.ch_id))
+ key = (block.dev_id, block.ch_id)
+ self._shown.discard(key)
+ self._blocks.pop(key, None)
self._inner.removeWidget(block)
block.deleteLater()
self._refresh_avail_cb()
@@ -328,6 +354,8 @@ class PipelineTab(QWidget):
self._avail_cb.clear()
for dev in self.registry.all_instances():
for ch in dev.info.channels:
+ if not ch.enabled:
+ continue
if (dev.info.device_id, ch.channel_id) not in self._shown:
label = f"{dev.info.device_id} / {ch.channel_id} ({ch.name})"
if ch.unit:
@@ -520,7 +548,8 @@ class DerivedBlock(QFrame):
# ══════════════════════════════════════════════════════════════════════════════
class SignalsTab(QWidget):
- changed = pyqtSignal()
+ changed = pyqtSignal()
+ channel_toggled = pyqtSignal(str, str, bool) # dev_id, ch_id, enabled
def __init__(self, registry: DeviceRegistry, processor: SignalProcessor):
super().__init__()
@@ -547,13 +576,19 @@ class SignalsTab(QWidget):
# Physical channels — flat list across all devices
for dev in self.registry.all_instances():
for ch in dev.info.channels:
+ dev_id_cap = dev.info.device_id
+ ch_id_cap = ch.channel_id
self._lay.addWidget(self._make_row(
color = ch.color,
name = f"{ch.channel_id} — {ch.name}",
unit = ch.unit,
- source = dev.info.device_id,
+ source = dev_id_cap,
enabled = ch.enabled,
- on_toggle = lambda v, c=ch: (setattr(c,"enabled",v), self.changed.emit()),
+ on_toggle = lambda v, c=ch, d=dev_id_cap, ci=ch_id_cap: (
+ setattr(c, "enabled", v),
+ self.changed.emit(),
+ self.channel_toggled.emit(d, ci, v),
+ ),
))
# Thin divider before derived (only if both sections have entries)
@@ -609,6 +644,7 @@ class SignalsWindow(QWidget):
pipeline_changed = pyqtSignal()
derived_changed = pyqtSignal()
visibility_changed = pyqtSignal()
+ channel_toggled = pyqtSignal(str, str, bool) # dev_id, ch_id, enabled
closed = pyqtSignal()
def __init__(self, registry: DeviceRegistry,
@@ -649,6 +685,7 @@ class SignalsWindow(QWidget):
# Tab 3: Flat signals list
self._vis_tab = SignalsTab(self.registry, self.processor)
self._vis_tab.changed.connect(self.visibility_changed)
+ self._vis_tab.channel_toggled.connect(self._on_vis_tab_toggled)
tabs.addTab(self._vis_tab, " Signals ")
# Keep Signals tab in sync when derived channels are added/removed
@@ -720,5 +757,15 @@ class SignalsWindow(QWidget):
self._color_idx = len(self._derived_blocks)
self._vis_tab.refresh()
+ def _on_vis_tab_toggled(self, dev_id: str, ch_id: str, enabled: bool):
+ """Signals tab toggled a channel — propagate to pipeline + chart without re-refreshing vis_tab."""
+ self._pip_tab.on_channel_enabled_changed(dev_id, ch_id, enabled)
+ self.channel_toggled.emit(dev_id, ch_id, enabled)
+
+ def on_channel_enabled_changed(self, dev_id: str, ch_id: str, enabled: bool):
+ """Called from outside (Devices window) — update pipeline block and sync vis_tab checkboxes."""
+ self._pip_tab.on_channel_enabled_changed(dev_id, ch_id, enabled)
+ self._vis_tab.refresh()
+
def closeEvent(self, e: QCloseEvent):
self.closed.emit(); e.accept()