diff options
| author | Christian Kolset <ckolset@colostate.edu> | 2026-08-13 11:22:24 -0600 |
|---|---|---|
| committer | Christian Kolset <ckolset@colostate.edu> | 2026-08-13 11:22:24 -0600 |
| commit | 23802b2131fc0098243bab73df7be104ef9891d1 (patch) | |
| tree | f126dbd47f42ceac69f7da633c636fbf5004b871 /ui | |
| parent | 4d08be2656d5599caf60ab5163a9d2305b397daf (diff) | |
Updated configuration window design.
- Split device tab into pysical devices and signals.
- Replaced old Signals panel (under Channels tab) with namespace.
to make Channel creation easier.
Diffstat (limited to 'ui')
| -rw-r--r-- | ui/windows/config_window.py | 88 |
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 ──────────────────────────────────────────────────────────────── |
