diff options
Diffstat (limited to 'ui')
| -rw-r--r-- | ui/__pycache__/add_device_dialog.cpython-312.pyc | bin | 29737 -> 29737 bytes | |||
| -rw-r--r-- | ui/__pycache__/control_editor.cpython-312.pyc | bin | 20099 -> 20704 bytes | |||
| -rw-r--r-- | ui/__pycache__/control_panel.cpython-312.pyc | bin | 42162 -> 42676 bytes | |||
| -rw-r--r-- | ui/__pycache__/main_window.cpython-312.pyc | bin | 25329 -> 26317 bytes | |||
| -rw-r--r-- | ui/add_device_dialog.py | 2 | ||||
| -rw-r--r-- | ui/control_editor.py | 7 | ||||
| -rw-r--r-- | ui/control_panel.py | 14 | ||||
| -rw-r--r-- | ui/main_window.py | 14 | ||||
| -rw-r--r-- | ui/plot_builder.py | 4 |
9 files changed, 36 insertions, 5 deletions
diff --git a/ui/__pycache__/add_device_dialog.cpython-312.pyc b/ui/__pycache__/add_device_dialog.cpython-312.pyc Binary files differindex e9aab22..2da95a6 100644 --- a/ui/__pycache__/add_device_dialog.cpython-312.pyc +++ b/ui/__pycache__/add_device_dialog.cpython-312.pyc diff --git a/ui/__pycache__/control_editor.cpython-312.pyc b/ui/__pycache__/control_editor.cpython-312.pyc Binary files differindex 42855d5..ccecd3e 100644 --- a/ui/__pycache__/control_editor.cpython-312.pyc +++ b/ui/__pycache__/control_editor.cpython-312.pyc diff --git a/ui/__pycache__/control_panel.cpython-312.pyc b/ui/__pycache__/control_panel.cpython-312.pyc Binary files differindex 8761466..1c101a8 100644 --- a/ui/__pycache__/control_panel.cpython-312.pyc +++ b/ui/__pycache__/control_panel.cpython-312.pyc diff --git a/ui/__pycache__/main_window.cpython-312.pyc b/ui/__pycache__/main_window.cpython-312.pyc Binary files differindex a290571..d89b2e6 100644 --- a/ui/__pycache__/main_window.cpython-312.pyc +++ b/ui/__pycache__/main_window.cpython-312.pyc diff --git a/ui/add_device_dialog.py b/ui/add_device_dialog.py index 50f234d..7e8e935 100644 --- a/ui/add_device_dialog.py +++ b/ui/add_device_dialog.py @@ -401,7 +401,7 @@ class AddDeviceDialog(QDialog): self.created_device = None self.setWindowTitle("Add Device") self.setMinimumSize(480, 460) - self.resize(500, 520) + self.resize(500, 600) self._build() def _build(self): diff --git a/ui/control_editor.py b/ui/control_editor.py index 4d18aef..901d6f8 100644 --- a/ui/control_editor.py +++ b/ui/control_editor.py @@ -51,6 +51,7 @@ class ControlSpec: icon: str = "⏻" device_id: str = "" channel_id: str = "" + active_low: bool = False # Type-specific params unit: str = "" min_val: float = 0.0 @@ -206,6 +207,9 @@ class ControlEditorDialog(QDialog): self._ch_cb.setInsertPolicy(QComboBox.InsertPolicy.NoInsert) hw_form.addRow("Channel / Pin:", self._ch_cb) + self._active_low_chk = QCheckBox("Active-low output (ON sends LOW)") + hw_form.addRow("Polarity:", self._active_low_chk) + self._ch_hint = QLabel("") self._ch_hint.setObjectName("traceSource") self._ch_hint.setWordWrap(True) @@ -255,6 +259,7 @@ class ControlEditorDialog(QDialog): # Channel (populated after device selection) self._on_dev_changed() self._ch_cb.setCurrentText(self.spec.channel_id) + self._active_low_chk.setChecked(bool(self.spec.active_low)) # Params for name, panel in self._param_panels.items(): @@ -263,6 +268,7 @@ class ControlEditorDialog(QDialog): def _on_type_changed(self, type_name: str): idx = list(_PARAM_PANELS.keys()).index(type_name) self._stack.setCurrentIndex(idx) + self._active_low_chk.setEnabled(type_name == "On/Off Switch") # Auto-set title if still default if not self._title_edit.text() or \ self._title_edit.text() in CONTROL_TYPES: @@ -309,6 +315,7 @@ class ControlEditorDialog(QDialog): icon=CONTROL_ICONS.get(ctype, "⚙"), device_id=self._dev_cb.currentData() or "", channel_id=channel_id, + active_low=self._active_low_chk.isChecked(), ) # Save type-specific params panel = self._param_panels.get(ctype) diff --git a/ui/control_panel.py b/ui/control_panel.py index efd4f17..7a3e416 100644 --- a/ui/control_panel.py +++ b/ui/control_panel.py @@ -43,16 +43,24 @@ class ControlWidget(QFrame): def __init__(self, title: str, icon: str = "⚙", device_id: str = "", channel_id: str = "", - registry: Optional[DeviceRegistry] = None): + registry: Optional[DeviceRegistry] = None, + active_low: bool = False): super().__init__() self.title = title self.icon = icon self.device_id = device_id self.channel_id = channel_id self.registry = registry + self.active_low = active_low self.setObjectName("controlWidget") self._build_frame() + def _logic_level(self, enabled: bool) -> float: + """Map logical ON/OFF to electrical level, respecting active-low outputs.""" + if self.active_low: + return 0.0 if enabled else 1.0 + return 1.0 if enabled else 0.0 + def _build_frame(self): """Build the common outer frame; subclasses fill self._body.""" outer = QVBoxLayout(self) @@ -155,7 +163,7 @@ class OnOffSwitch(ControlWidget): # Re-polish so QSS picks up new objectName for w in (self._btn, self._indicator, self._state_lbl): w.style().unpolish(w); w.style().polish(w) - self._write(1.0 if checked else 0.0) + self._write(self._logic_level(checked)) # ══════════════════════════════════════════════════════════════════════════════ @@ -568,6 +576,7 @@ class ControlPanel(QWidget): spec = ControlSpec( title=widget.title, icon=widget.icon, device_id=widget.device_id, channel_id=widget.channel_id, + active_low=getattr(widget, "active_low", False), ) wrapper = self._make_wrapper(widget, spec) self._widgets.append(widget) @@ -673,6 +682,7 @@ def _build_widget_from_spec(spec, registry: DeviceRegistry) -> Optional[ControlW device_id=spec.device_id, channel_id=spec.channel_id, registry=registry, + active_low=getattr(spec, "active_low", False), ) t = spec.control_type ttl = spec.title diff --git a/ui/main_window.py b/ui/main_window.py index 9df7ef7..d4bb203 100644 --- a/ui/main_window.py +++ b/ui/main_window.py @@ -92,6 +92,12 @@ class MainWindow(QMainWindow): self._log_btn.setEnabled(False); self._log_btn.clicked.connect(self._toggle_log) tb.addWidget(self._log_btn) + self._clear_btn = QPushButton("⌫ Clear") + self._clear_btn.setObjectName("toolbarSectionBtn") + self._clear_btn.setToolTip("Clear plot history") + self._clear_btn.clicked.connect(self._clear_history) + tb.addWidget(self._clear_btn) + tb.addWidget(_sep()) dev_btn = QPushButton("⊞ Devices") @@ -265,12 +271,15 @@ class MainWindow(QMainWindow): processor=self.processor, control_panel=self._ctrl, settings_ref=self._settings, + engine=self.engine, ) if plot_cfg: self._chart.apply_layout(plot_cfg) else: self._chart.refresh() # Refresh open windows + if self._win_devices: + self._win_devices.refresh() if self._win_plot: self._win_plot.refresh_channels() self._status.setText(f"Profile loaded: {profile.name}") @@ -309,6 +318,11 @@ class MainWindow(QMainWindow): self._log_btn.setEnabled(False); self._clock.stop() self._status.setText("Stopped") + def _clear_history(self): + self.engine.clear_history() + self._chart.refresh() + self._status.setText("History cleared.") + def _toggle_log(self, c: bool): if c: p = self.engine.start_logging( diff --git a/ui/plot_builder.py b/ui/plot_builder.py index beda116..ad6d231 100644 --- a/ui/plot_builder.py +++ b/ui/plot_builder.py @@ -356,8 +356,8 @@ class PlotBuilderWindow(QWidget): else build_default_layout(registry, processor) self.setWindowTitle("Plot Builder") - self.setMinimumSize(700, 560) - self.resize(800, 680) + self.setMinimumSize(700, 780) + self.resize(800, 780) self._blocks: List[PlotBlock] = [] self._build() self._populate() |
