summaryrefslogtreecommitdiff
path: root/ui/windows
diff options
context:
space:
mode:
Diffstat (limited to 'ui/windows')
-rw-r--r--ui/windows/config_window.py88
1 files changed, 62 insertions, 26 deletions
diff --git a/ui/windows/config_window.py b/ui/windows/config_window.py
index 52612fc..a31397e 100644
--- a/ui/windows/config_window.py
+++ b/ui/windows/config_window.py
@@ -3,8 +3,12 @@ ui/windows/config_window.py
Unified Configuration window — Devices | Channels | Plot in one tabbed window.
+Devices tab layout (2 columns):
+ Left — physical devices (add/configure/remove)
+ Right — signal table (Device / Signal ID / Dir / On / Name / Unit / Min / Max)
+
Channels tab layout (2 columns):
- Left — signal table (Device / Signal ID / Dir / On / Name / Unit / Min / Max)
+ Left — Namespace browser (read-only reference: Signals / Channels / vars)
Right — derived / virtual channels — operations (filters/calibration/math/script)
are configured per Channel here, not on the Signals side.
"""
@@ -32,6 +36,7 @@ from ui.windows.plot_window import (
PlotWindow, LayoutConfig, LayoutCanvas, PaneBlock,
build_default_layout,
)
+from ui.namespace_panel import NamespacePanel
# ══════════════════════════════════════════════════════════════════════════════
@@ -300,11 +305,21 @@ class ConfigWindow(QWidget):
self.tabs.currentChanged.connect(self._on_tab_changed)
# ── Tab 0: Devices ───────────────────────────────────────────────────────
+ # Left — physical devices (add/configure/remove)
+ # Right — signal table (metadata + enable)
def _build_devices_tab(self):
w = QWidget()
lay = QVBoxLayout(w); lay.setContentsMargins(0, 0, 0, 0); lay.setSpacing(0)
+ splitter = QSplitter(Qt.Orientation.Horizontal)
+ splitter.setObjectName("deviceSplitter")
+ lay.addWidget(splitter, 1)
+
+ # Left: physical devices
+ dev_w = QWidget()
+ dev_l = QVBoxLayout(dev_w); dev_l.setContentsMargins(0, 0, 0, 0); dev_l.setSpacing(0)
+
bar = QWidget(); bar.setObjectName("cfgGlobalBar")
bl = QHBoxLayout(bar); bl.setContentsMargins(10, 7, 10, 7); bl.setSpacing(6)
lbl = QLabel("Physical Devices"); lbl.setObjectName("devWindowTitle")
@@ -312,10 +327,10 @@ class ConfigWindow(QWidget):
add_btn = QPushButton("+ Add Device"); add_btn.setObjectName("addDeviceButton")
add_btn.clicked.connect(self._on_add_device)
bl.addWidget(add_btn)
- lay.addWidget(bar)
+ dev_l.addWidget(bar)
div = QFrame(); div.setFrameShape(QFrame.Shape.HLine)
- div.setObjectName("devWindowDivider"); lay.addWidget(div)
+ div.setObjectName("devWindowDivider"); dev_l.addWidget(div)
scroll = QScrollArea(); scroll.setWidgetResizable(True)
scroll.setObjectName("deviceScroll")
@@ -325,7 +340,31 @@ class ConfigWindow(QWidget):
self._dev_inner.setContentsMargins(10, 10, 10, 10); self._dev_inner.setSpacing(6)
self._dev_inner.addStretch()
scroll.setWidget(self._dev_container)
- lay.addWidget(scroll, 1)
+ dev_l.addWidget(scroll, 1)
+ splitter.addWidget(dev_w)
+
+ # Right: signals table
+ sig_w = QWidget()
+ sig_l = QVBoxLayout(sig_w); sig_l.setContentsMargins(0, 0, 0, 0); sig_l.setSpacing(0)
+
+ sig_bar = QWidget(); sig_bar.setObjectName("cfgGlobalBar")
+ sb_lay = QHBoxLayout(sig_bar); sb_lay.setContentsMargins(10, 7, 10, 7); sb_lay.setSpacing(6)
+ sb_lbl = QLabel("Signals"); sb_lbl.setObjectName("devWindowTitle")
+ sb_lay.addWidget(sb_lbl, 1)
+ sig_l.addWidget(sig_bar)
+
+ sig_div = QFrame(); sig_div.setFrameShape(QFrame.Shape.HLine)
+ sig_div.setObjectName("devWindowDivider"); sig_l.addWidget(sig_div)
+
+ self._signals_tab = _SignalsTab(self.registry, self.processor)
+ self._signals_tab.channel_visibility_changed.connect(self._on_sig_visibility)
+ self._signals_tab.channel_name_changed.connect(self._on_sig_name)
+ self._signals_tab.channel_unit_changed.connect(self._on_sig_unit)
+ sig_l.addWidget(self._signals_tab, 1)
+ splitter.addWidget(sig_w)
+
+ splitter.setStretchFactor(0, 1)
+ splitter.setStretchFactor(1, 1)
self.tabs.addTab(w, " Devices ")
@@ -396,7 +435,7 @@ class ConfigWindow(QWidget):
self.device_removed.emit(device_id)
# ── Tab 1: Channels ──────────────────────────────────────────────────────
- # Left — signal table (metadata + enable + ⚙ pipeline button per row)
+ # Left — Namespace browser (read-only reference: Signals / Channels / vars)
# Right — derived / virtual channels (PipelineTab with physical side hidden)
def _build_channels_tab(self):
@@ -407,25 +446,23 @@ class ConfigWindow(QWidget):
splitter.setObjectName("channelSplitter")
lay.addWidget(splitter, 1)
- # Left: signals table
- sig_w = QWidget()
- sig_l = QVBoxLayout(sig_w); sig_l.setContentsMargins(0, 0, 0, 0); sig_l.setSpacing(0)
+ # Left: namespace browser
+ ns_w = QWidget()
+ ns_l = QVBoxLayout(ns_w); ns_l.setContentsMargins(0, 0, 0, 0); ns_l.setSpacing(0)
- sig_bar = QWidget(); sig_bar.setObjectName("cfgGlobalBar")
- sb_lay = QHBoxLayout(sig_bar); sb_lay.setContentsMargins(10, 7, 10, 7); sb_lay.setSpacing(6)
- sb_lbl = QLabel("Signals"); sb_lbl.setObjectName("devWindowTitle")
- sb_lay.addWidget(sb_lbl, 1)
- sig_l.addWidget(sig_bar)
+ ns_bar = QWidget(); ns_bar.setObjectName("cfgGlobalBar")
+ nb_lay = QHBoxLayout(ns_bar); nb_lay.setContentsMargins(10, 7, 10, 7); nb_lay.setSpacing(6)
+ nb_lbl = QLabel("Namespace"); nb_lbl.setObjectName("devWindowTitle")
+ nb_lay.addWidget(nb_lbl, 1)
+ ns_l.addWidget(ns_bar)
- sig_div = QFrame(); sig_div.setFrameShape(QFrame.Shape.HLine)
- sig_div.setObjectName("devWindowDivider"); sig_l.addWidget(sig_div)
+ ns_div = QFrame(); ns_div.setFrameShape(QFrame.Shape.HLine)
+ ns_div.setObjectName("devWindowDivider"); ns_l.addWidget(ns_div)
- self._signals_tab = _SignalsTab(self.registry, self.processor)
- self._signals_tab.channel_visibility_changed.connect(self._on_sig_visibility)
- self._signals_tab.channel_name_changed.connect(self._on_sig_name)
- self._signals_tab.channel_unit_changed.connect(self._on_sig_unit)
- sig_l.addWidget(self._signals_tab, 1)
- splitter.addWidget(sig_w)
+ self._namespace_panel = NamespacePanel(self.registry, self.processor)
+ self.processor.processed_data.connect(self._namespace_panel.on_processed_data)
+ ns_l.addWidget(self._namespace_panel, 1)
+ splitter.addWidget(ns_w)
# Right: derived channels only
self._pipeline_tab = PipelineTab(self.registry, self.processor)
@@ -439,8 +476,9 @@ class ConfigWindow(QWidget):
splitter.addWidget(self._pipeline_tab)
self._signals_tab.channel_created.connect(self._pipeline_tab.refresh_derived)
- splitter.setStretchFactor(0, 2)
- splitter.setStretchFactor(1, 1)
+ # Channels side larger by default
+ splitter.setStretchFactor(0, 1)
+ splitter.setStretchFactor(1, 3)
self.tabs.addTab(w, " Channels ")
@@ -494,9 +532,7 @@ class ConfigWindow(QWidget):
# ── Tab switch ───────────────────────────────────────────────────────────
def _on_tab_changed(self, idx: int):
- if idx == 1:
- self._signals_tab.refresh()
- elif idx == 2:
+ if idx == 2:
self._plot_tab.refresh_channels()
# ── Close ────────────────────────────────────────────────────────────────