From f688ca53193e3b3d6ba472544ffa481d6dca0fab Mon Sep 17 00:00:00 2001 From: appleb_m Date: Fri, 26 Jun 2026 12:05:58 +0200 Subject: [PATCH] new_gui: ABR->staff align-CoR only, Go-to-Home, 6-level zoom, remove manual run-plan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ABR extracted to widgets/abr_control.py; shown only in the staff Align-centre- of-rotation procedure (removed from the shared MotorsPanel) - SMARGON: '⌂ Go to Home' button -> move_smargon(0,0,18) (home_requested) - ZOOM: real settings (motor values) 1.0/2.0/3.5/5.8/7.5/12.5x in a 3-col grid; emit the motor value (was the magnification); camera shows the magnification label via zoom_label() - remove the RUN PLAN chip row from the manual cockpit (runner uses default protocol); readable combos/spinboxes already global - input contrast fix + mounted card from prior commit Co-Authored-By: Claude Opus 4.8 (1M context) --- src/aare/gui/new_gui/README.md | 16 +-- src/aare/gui/new_gui/dev_seed.py | 2 +- src/aare/gui/new_gui/main_window.py | 18 ++- src/aare/gui/new_gui/manual_view.py | 7 +- src/aare/gui/new_gui/staff_view.py | 19 ++- src/aare/gui/new_gui/widgets/abr_control.py | 108 ++++++++++++++++++ src/aare/gui/new_gui/widgets/camera.py | 8 +- src/aare/gui/new_gui/widgets/motors_panel.py | 105 ++++++----------- .../gui/new_gui/widgets/pipeline_panel.py | 43 ------- 9 files changed, 190 insertions(+), 136 deletions(-) create mode 100644 src/aare/gui/new_gui/widgets/abr_control.py diff --git a/src/aare/gui/new_gui/README.md b/src/aare/gui/new_gui/README.md index 5f13ee3c..1553d9e7 100644 --- a/src/aare/gui/new_gui/README.md +++ b/src/aare/gui/new_gui/README.md @@ -62,9 +62,12 @@ Backend contract is documented in the `new-gui-backend-paths` memory. (switch the beamline state where one exists; CoR uses Sample alignment + omega + smargon + ABR). Centre = camera (beam-centre marker) / XRF spectrum; right = full motors (omega/smargon/ABR/zoom/light). -- **Motors panel**: compact SMARGON with **editable Chi/Phi** + **Focus (Z)** jog - (new — smargon-z move), staff-only **ABR** (GMX/GMY/GMZ + save/goto) under - SMARGON. Energy lives in the staff Tools dialog (not the motors panel). +- **Motors panel**: compact SMARGON with **editable Chi/Phi**, a **⌂ Go to Home** + button (smargon → 0,0,18), **Focus (Z)** jog, **ZOOM** as a 6-level grid + (1.0×/2.0×/3.5×/5.8×/7.5×/12.5×; the button sends the zoom-motor value, the + camera shows the magnification label), and LIGHT. **ABR** is NOT here — it lives + only in the staff **Align centre of rotation** procedure. Energy lives in the + staff Tools dialog. - **Camera exp/gain** are inline in the camera tab strip (Exp/Gain → `samcam_settings`). - **Prediction metrics** dialog (per-class counts, confidence, FPS) and a **live smargon-trace** dialog (ΔX/ΔY/ΔZ + distance from a reference, fed by the status @@ -100,13 +103,12 @@ Backend contract is documented in the `new-gui-backend-paths` memory. - **Preconditions**: data-collection actions are gated by a ring/shutter/hutch warning (1-hour snooze); mounting is hard-blocked by the hutch PSS; `sample_missing` shows a modal (suppressed during automation). -- **Pausable pipeline** (mounted): a **RUN PLAN** chip row toggles which stages - ▶ Play executes (Center/Raster/XRF/Collect). Play runs the lit stages in order, +- **Pausable pipeline** (mounted): ▶ Play runs the protocol stages in order, advancing as each completes (`raster_scan_completed`/`standard_scan_completed`, else a `status.busy` True→False edge, else ⏭ Skip) and **pausing before any stage flagged with a ⚑ breakpoint**; ▶ resumes, ❚❚ pauses after the current - stage, ⏹ ends. (Automation pauses between samples; per-stage control inside a - sample is **GUI-driven** — see below.) + stage, ⏹ ends. (The visible run-plan chips were removed from Manual; the runner + uses the default protocol. Automation has the GUI-driven per-stage runner below.) - **Automation** (queue page): **GUI-driven per-stage runner** drives each queued sample through mount → its enabled protocol stages → unmount, firing the per-stage backend ops and advancing on completion (raster/standard signals, diff --git a/src/aare/gui/new_gui/dev_seed.py b/src/aare/gui/new_gui/dev_seed.py index 989be650..74659a54 100644 --- a/src/aare/gui/new_gui/dev_seed.py +++ b/src/aare/gui/new_gui/dev_seed.py @@ -95,7 +95,7 @@ class DevSeed(QObject): bl=SimpleNamespace( flux_ph_s=4.0e11, ring_current_mA=401.0, cryojet_K=100.1, shutter_open=False, exp_shutter_open=True, transmission=0.1, - zoom=2.0, front_light=80, back_light=45, + zoom=280.0, front_light=80, back_light=45, sample_camera=SimpleNamespace(gain=1.0, exposure=0.02), pss_prohibited=True, pss_alarm=False), geom=geom, diff --git a/src/aare/gui/new_gui/main_window.py b/src/aare/gui/new_gui/main_window.py index ccd8f0f6..a8b678b6 100644 --- a/src/aare/gui/new_gui/main_window.py +++ b/src/aare/gui/new_gui/main_window.py @@ -359,6 +359,13 @@ class MainWindow(QWidget): if hasattr(self.daq, "beam_mark_clear"): self.staff.beam_mark_clear.connect(self.daq.beam_mark_clear) self._wire_motors(self.staff.motors) + # ABR lives only in the staff Align-centre-of-rotation procedure + if hasattr(self.daq, "abr_tweak"): + self.staff.abr.abr_tweak.connect(self.daq.abr_tweak) + if hasattr(self.daq, "abr_save"): + self.staff.abr.abr_save.connect(self.daq.abr_save) + if hasattr(self.daq, "abr_goto_meas"): + self.staff.abr.abr_goto.connect(self.daq.abr_goto_meas) sp2 = self.staff.spectrum sp2.start_clicked.connect(self.daq.fluorimeter_start) sp2.stop_clicked.connect(self.daq.fluorimeter_stop) @@ -406,12 +413,11 @@ class MainWindow(QWidget): m.back_light_changed.connect(self.daq.back_light) m.smargon_jog.connect(self._on_smargon_jog) m.smargon_angles.connect(self._on_smargon_angles) - if hasattr(self.daq, "abr_tweak"): - m.abr_tweak.connect(self.daq.abr_tweak) - if hasattr(self.daq, "abr_save"): - m.abr_save.connect(self.daq.abr_save) - if hasattr(self.daq, "abr_goto_meas"): - m.abr_goto.connect(self.daq.abr_goto_meas) + m.home_requested.connect(self._on_home) + + def _on_home(self) -> None: + from aare.common.coordinate import Coordinate, SmargonCoordinate + self.daq.move_smargon(SmargonCoordinate(sh_mm=Coordinate(x=0.0, y=0.0, z=18.0))) @Slot(str) def _on_mode_changed(self, mode: str) -> None: diff --git a/src/aare/gui/new_gui/manual_view.py b/src/aare/gui/new_gui/manual_view.py index 943e5b53..3642f0d5 100644 --- a/src/aare/gui/new_gui/manual_view.py +++ b/src/aare/gui/new_gui/manual_view.py @@ -176,9 +176,6 @@ class ManualView(QWidget): t.end.connect(self._on_end) t.unmount.connect(s.unmount) - # run plan (which stages the auto-run executes) - self.pipeline.run_plan.toggled.connect(s.toggle_protocol) - # bookmarks bm = self.pipeline.bookmarks bm.bookmark_add.connect(self._on_bookmark_add) @@ -606,7 +603,6 @@ class ManualView(QWidget): def _refresh_pipe(self) -> None: self.pipeline.update_from_state(self._state) - self.pipeline.run_plan.set_protocol(self._state.protocol) # enable grid-draw affordance only while the raster stage is selected if self._state.stage != "raster": self.pipeline.settings.set_draw_active(False) @@ -638,7 +634,8 @@ class ManualView(QWidget): self._project_bookmarks() bl = getattr(s, "bl", None) if bl is not None and getattr(bl, "zoom", None) is not None: - self.camera.set_zoom(bl.zoom) + from aare.gui.new_gui.widgets.motors_panel import zoom_label + self.camera.set_zoom_text(zoom_label(bl.zoom)) if bl is not None: self.camera.set_beam_state( getattr(bl, "shutter_open", False), getattr(s, "busy", False)) diff --git a/src/aare/gui/new_gui/staff_view.py b/src/aare/gui/new_gui/staff_view.py index 9499a143..51ac5d75 100644 --- a/src/aare/gui/new_gui/staff_view.py +++ b/src/aare/gui/new_gui/staff_view.py @@ -20,6 +20,7 @@ from PySide6.QtWidgets import ( ) from aare.gui.new_gui.theme import CHANGER_W, Palette +from aare.gui.new_gui.widgets.abr_control import AbrControl from aare.gui.new_gui.widgets.camera import CameraViewport from aare.gui.new_gui.widgets.common import micro_label, section_label from aare.gui.new_gui.widgets.motors_panel import MotorsPanel @@ -91,7 +92,7 @@ class StaffView(QWidget): # --- right: alignment motors (omega / smargon / ABR / zoom / light) --- self.motors = MotorsPanel(palette) - self.motors.set_staff(True) # ABR always available in staff view + self.motors.set_staff(True) root.addWidget(self.motors) self._select("beam") @@ -125,9 +126,20 @@ class StaffView(QWidget): self.ctx.addWidget(self._note_panel( # 1 "Switch to the Beamline camera and adjust the beamstop hardware until " "centred on the beam.")) - self.ctx.addWidget(self._note_panel( # 2 + # centre of rotation: guidance note + ABR control (staff-only, here only) + cor = QWidget() # 2 + col = QHBoxLayout(cor) + col.setContentsMargins(0, 0, 0, 0) + col.setSpacing(18) + note = QLabel( "Rotate ω (right panel) and re-centre the sample with the smargon jog " - "and ABR focus so it stays on the rotation axis at all angles.")) + "and ABR so it stays on the rotation axis at all angles.") + note.setWordWrap(True) + note.setStyleSheet(f"font-size:12px; color:{self._p.text_muted};") + col.addWidget(note, 1) + self.abr = AbrControl(self._p) + col.addWidget(self.abr) + self.ctx.addWidget(cor) # flux — spectrum controls live in the SpectrumView itself self.ctx.addWidget(self._note_panel( # 3 @@ -172,6 +184,7 @@ class StaffView(QWidget): def update_daq_status(self, s) -> None: self._last_status = s self.motors.update_daq_status(s) + self.abr.update_daq_status(s) geom = getattr(s, "geom", None) beam = getattr(geom, "beam_location_pxl", None) if geom else None if beam is not None: diff --git a/src/aare/gui/new_gui/widgets/abr_control.py b/src/aare/gui/new_gui/widgets/abr_control.py new file mode 100644 index 00000000..97ef70ce --- /dev/null +++ b/src/aare/gui/new_gui/widgets/abr_control.py @@ -0,0 +1,108 @@ +"""ABR (aerotech beam reference) control — staff Align-centre-of-rotation only. + +Tweak the ABR measurement position (GMX/GMY/GMZ), Save it, or Goto it. Lives in +the staff view's centre-of-rotation procedure, not the general motors panel. +""" + +from __future__ import annotations + +from PySide6.QtCore import Qt, Signal +from PySide6.QtWidgets import ( + QDoubleSpinBox, + QGridLayout, + QHBoxLayout, + QLabel, + QPushButton, + QVBoxLayout, + QWidget, +) + +from aare.common.coordinate import AerotechCoordinate, Coordinate +from aare.gui.new_gui.theme import FONT_MONO_FALLBACK, Palette +from aare.gui.new_gui.widgets.common import section_label + + +class AbrControl(QWidget): + abr_tweak = Signal(object) # AerotechCoordinate + abr_save = Signal() + abr_goto = Signal() + + def __init__(self, palette: Palette, parent=None): + super().__init__(parent) + self._p = palette + lay = QVBoxLayout(self) + lay.setContentsMargins(0, 0, 0, 0) + lay.setSpacing(6) + lay.addWidget(section_label("ABR · meas. pos")) + + steprow = QHBoxLayout() + steprow.addWidget(self._lbl("Step")) + self._step = QDoubleSpinBox() + self._step.setRange(1, 1000) + self._step.setValue(10) + self._step.setSuffix(" µm") + self._step.setFixedWidth(90) + steprow.addWidget(self._step) + steprow.addStretch(1) + lay.addLayout(steprow) + + grid = QGridLayout() + grid.setSpacing(5) + self._labels: dict[str, QLabel] = {} + for r, axis in enumerate(("x", "y", "z")): + grid.addWidget(self._lbl(f"GM{axis.upper()}"), r, 0) + minus, plus = self._btn("−"), self._btn("+") + minus.clicked.connect(lambda _=False, a=axis: self._tweak(a, -1)) + plus.clicked.connect(lambda _=False, a=axis: self._tweak(a, +1)) + val = QLabel("—") + val.setStyleSheet(f"font-family:{FONT_MONO_FALLBACK}; font-size:11px;" + f" color:{palette.text_primary};") + self._labels[axis] = val + grid.addWidget(minus, r, 1) + grid.addWidget(plus, r, 2) + grid.addWidget(val, r, 3) + grid.setColumnStretch(3, 1) + lay.addLayout(grid) + + btns = QHBoxLayout() + save = self._btn("Save", wide=True) + goto = self._btn("Goto", wide=True) + save.clicked.connect(self.abr_save) + goto.clicked.connect(self.abr_goto) + btns.addWidget(save) + btns.addWidget(goto) + lay.addLayout(btns) + + def _lbl(self, text: str) -> QLabel: + lbl = QLabel(text) + lbl.setStyleSheet(f"font-size:10.5px; color:{self._p.text_faint};") + return lbl + + def _btn(self, text: str, wide: bool = False) -> QPushButton: + b = QPushButton(text) + b.setCursor(Qt.PointingHandCursor) + if not wide: + b.setFixedWidth(30) + b.setStyleSheet( + f"QPushButton {{ background:{self._p.surface};" + f" border:1px solid {self._p.border_control}; border-radius:6px;" + f" padding:5px 8px; font-size:12px; color:{self._p.text_secondary}; }}" + f" QPushButton:hover {{ border-color:{self._p.accent};" + f" color:{self._p.accent}; }}") + return b + + def _tweak(self, axis: str, sign: int) -> None: + step_mm = self._step.value() / 1000.0 * sign + kw = {"x": 0.0, "y": 0.0, "z": 0.0} + kw[axis] = step_mm + self.abr_tweak.emit(AerotechCoordinate(at_mm=Coordinate(**kw), omega_deg=None)) + + def update_daq_status(self, s) -> None: + geom = getattr(s, "geom", None) + meas = getattr(geom, "aerotech_meas", None) if geom else None + if meas is None: + return + for axis in ("x", "y", "z"): + v = getattr(meas, axis, None) + if v is not None: + self._labels[axis].setText(f"{v:.4f}") diff --git a/src/aare/gui/new_gui/widgets/camera.py b/src/aare/gui/new_gui/widgets/camera.py index 8d8ee926..cbd83443 100644 --- a/src/aare/gui/new_gui/widgets/camera.py +++ b/src/aare/gui/new_gui/widgets/camera.py @@ -52,7 +52,7 @@ class CameraViewport(QWidget): self._p = palette self._pixmap: QPixmap | None = None self._fps: float = 0.0 - self._zoom: float = 2.0 + self._zoom_text: str = "—" self._mode = "empty" self._target_point: QPoint | None = None # image-pixel coords self._beam_px: QPoint | None = None # beam centre, image-pixel coords @@ -234,8 +234,8 @@ class CameraViewport(QWidget): self._fps = fps self.update() - def set_zoom(self, zoom: float) -> None: - self._zoom = zoom + def set_zoom_text(self, text: str) -> None: + self._zoom_text = text or "—" self.update() def update_target_point(self, data: dict) -> None: @@ -491,7 +491,7 @@ class CameraViewport(QWidget): f.setPixelSize(11) painter.setFont(f) fps = "-" if self._fps != self._fps else f"{self._fps:.0f}" # NaN-safe - text = f"SAMCAM · {fps} fps · {self._zoom:.1f}×" + text = f"SAMCAM · {fps} fps · {self._zoom_text}" painter.drawText(QRect(0, 8, r.width() - 14, 16), Qt.AlignRight | Qt.AlignTop, text) diff --git a/src/aare/gui/new_gui/widgets/motors_panel.py b/src/aare/gui/new_gui/widgets/motors_panel.py index 28af055d..03acdbac 100644 --- a/src/aare/gui/new_gui/widgets/motors_panel.py +++ b/src/aare/gui/new_gui/widgets/motors_panel.py @@ -21,15 +21,24 @@ from PySide6.QtWidgets import ( QWidget, ) -from aare.common.coordinate import AerotechCoordinate, Coordinate from aare.gui.new_gui.theme import FONT_MONO_FALLBACK, MOTORS_W, Palette from aare.gui.new_gui.widgets.common import hline, section_label OMEGA_STEPS = (-90, -45, -10, 10, 45, 90) -ZOOM_LEVELS = (1.0, 2.0, 3.5, 5.8) +# (label, zoom-motor value) — the value is a motor position, NOT a magnification. +ZOOM_SETTINGS = (("1.0×", 1.0), ("2.0×", 280.0), ("3.5×", 500.0), + ("5.8×", 700.0), ("7.5×", 800.0), ("12.5×", 1000.0)) JOG_STEPS_UM = (10, 50, 100, 500) +def zoom_label(value) -> str: + """Map a zoom-motor value back to its magnification label (for the camera).""" + if value is None: + return "—" + name, _ = min(ZOOM_SETTINGS, key=lambda nv: abs(nv[1] - value)) + return name + + class MotorsPanel(QWidget): omega_rel = Signal(float) # degrees, relative smargon_jog = Signal(float, float, float) # dx_mm, dy_mm, dz_mm (beamline frame) @@ -37,9 +46,7 @@ class MotorsPanel(QWidget): zoom_changed = Signal(float) front_light_changed = Signal(int) back_light_changed = Signal(int) - abr_tweak = Signal(object) # AerotechCoordinate (staff) - abr_save = Signal() - abr_goto = Signal() + home_requested = Signal() # move smargon to home (0,0,18) def __init__(self, palette: Palette, parent=None): super().__init__(parent) @@ -109,6 +116,19 @@ class MotorsPanel(QWidget): lay.addLayout(ang) lay.addSpacing(8) + home = QPushButton("⌂ Go to Home") + home.setCursor(Qt.PointingHandCursor) + home.setToolTip("Move the sample holder to the home position (0, 0, 18 mm)") + home.setStyleSheet( + f"QPushButton {{ background:{palette.surface};" + f" border:1px solid {palette.border_control}; border-radius:8px;" + f" padding:7px 12px; font-size:12px; color:{palette.text_secondary}; }}" + f" QPushButton:hover {{ border-color:{palette.accent};" + f" color:{palette.accent}; }}") + home.clicked.connect(self.home_requested) + lay.addWidget(home) + lay.addSpacing(8) + # XY jog pad + focus (Z) padrow = QHBoxLayout() pad = QGridLayout() @@ -142,68 +162,29 @@ class MotorsPanel(QWidget): padrow.addLayout(foc) lay.addLayout(padrow) - # ---- ABR (staff only) ---- - self._abr_section = QWidget() - ab = QVBoxLayout(self._abr_section) - ab.setContentsMargins(0, 0, 0, 0) - ab.setSpacing(0) - ab.addSpacing(14) - ab.addWidget(hline(palette)) - ab.addSpacing(14) - ab.addWidget(section_label("ABR · meas. pos")) - ab.addSpacing(6) - steprow = QHBoxLayout() - steprow.addWidget(self._small_label("Step")) - self._abr_step = QDoubleSpinBox(); self._abr_step.setRange(1, 1000) - self._abr_step.setValue(10); self._abr_step.setSuffix(" µm") - steprow.addWidget(self._abr_step); steprow.addStretch(1) - ab.addLayout(steprow) - abr_grid = QGridLayout(); abr_grid.setSpacing(5) - self._abr_labels = {} - for r, axis in enumerate(("x", "y", "z")): - abr_grid.addWidget(self._small_label(f"GM{axis.upper()}"), r, 0) - m = self._jog_btn("−"); p = self._jog_btn("+") - m.clicked.connect(lambda _=False, a=axis: self._abr(a, -1)) - p.clicked.connect(lambda _=False, a=axis: self._abr(a, +1)) - val = QLabel("—") - val.setStyleSheet(f"font-family:{FONT_MONO_FALLBACK}; font-size:11px;") - self._abr_labels[axis] = val - abr_grid.addWidget(m, r, 1); abr_grid.addWidget(p, r, 2); abr_grid.addWidget(val, r, 3) - ab.addLayout(abr_grid) - abr_btns = QHBoxLayout() - save = QPushButton("Save"); save.clicked.connect(self.abr_save) - goto = QPushButton("Goto"); goto.clicked.connect(self.abr_goto) - for b in (save, goto): - b.setCursor(Qt.PointingHandCursor) - abr_btns.addWidget(save); abr_btns.addWidget(goto) - ab.addLayout(abr_btns) - self._abr_section.setVisible(False) - lay.addWidget(self._abr_section) - lay.addSpacing(14) lay.addWidget(hline(palette)) lay.addSpacing(14) - # ---- ZOOM ---- + # ---- ZOOM (3-col grid of all magnification presets) ---- lay.addWidget(section_label("ZOOM")) lay.addSpacing(8) - zoom_row = QHBoxLayout() - zoom_row.setSpacing(6) + zoom_grid = QGridLayout() + zoom_grid.setSpacing(6) self._zoom_group = QButtonGroup(self) self._zoom_group.setExclusive(True) self._zoom_btns: dict[float, QPushButton] = {} - for z in ZOOM_LEVELS: - b = QPushButton(f"{z:.1f}×") + for i, (name, value) in enumerate(ZOOM_SETTINGS): + b = QPushButton(name) b.setCheckable(True) b.setCursor(Qt.PointingHandCursor) - b.clicked.connect(lambda _=False, zz=z: self.zoom_changed.emit(zz)) + b.clicked.connect(lambda _=False, v=value: self.zoom_changed.emit(v)) b.toggled.connect(lambda _on, bb=b: self._restyle_zoom(bb)) self._zoom_group.addButton(b) - self._zoom_btns[z] = b - zoom_row.addWidget(b) + self._zoom_btns[value] = b + zoom_grid.addWidget(b, i // 3, i % 3) self._restyle_zoom(b) - zoom_row.addStretch(1) - lay.addLayout(zoom_row) + lay.addLayout(zoom_grid) lay.addSpacing(14) lay.addWidget(hline(palette)) @@ -218,7 +199,9 @@ class MotorsPanel(QWidget): lay.addStretch(1) def set_staff(self, is_staff: bool) -> None: - self._abr_section.setVisible(is_staff) + # ABR moved to the staff Align-centre-of-rotation procedure; nothing + # staff-gated remains in the motors panel. + pass # -------- helpers -------- def _small_label(self, text: str) -> QLabel: @@ -292,12 +275,6 @@ class MotorsPanel(QWidget): step_mm = JOG_STEPS_UM[self._jog_idx] / 1000.0 self.smargon_jog.emit(sx * step_mm, sy * step_mm, sz * step_mm) - def _abr(self, axis: str, sign: int) -> None: - step_mm = self._abr_step.value() / 1000.0 * sign - kw = {"x": 0.0, "y": 0.0, "z": 0.0} - kw[axis] = step_mm - self.abr_tweak.emit(AerotechCoordinate(at_mm=Coordinate(**kw), omega_deg=None)) - # -------- live updates -------- def update_daq_status(self, s) -> None: geom = getattr(s, "geom", None) @@ -309,12 +286,6 @@ class MotorsPanel(QWidget): if smg is not None: self._sync_spin(self._chi, getattr(smg, "chi_deg", None)) self._sync_spin(self._phi, getattr(smg, "phi_deg", None)) - meas = getattr(geom, "aerotech_meas", None) - if meas is not None: - for axis in ("x", "y", "z"): - v = getattr(meas, axis, None) - if v is not None: - self._abr_labels[axis].setText(f"{v:.4f}") bl = getattr(s, "bl", None) if bl is not None: zoom = getattr(bl, "zoom", None) @@ -332,7 +303,7 @@ class MotorsPanel(QWidget): spin.blockSignals(False) def _sync_zoom(self, zoom: float) -> None: - nearest = min(ZOOM_LEVELS, key=lambda z: abs(z - zoom)) + nearest = min(ZOOM_SETTINGS, key=lambda nv: abs(nv[1] - zoom))[1] btn = self._zoom_btns.get(nearest) if btn and not btn.isChecked(): btn.blockSignals(True) diff --git a/src/aare/gui/new_gui/widgets/pipeline_panel.py b/src/aare/gui/new_gui/widgets/pipeline_panel.py index a2bc25bb..3f6bc1a9 100644 --- a/src/aare/gui/new_gui/widgets/pipeline_panel.py +++ b/src/aare/gui/new_gui/widgets/pipeline_panel.py @@ -28,7 +28,6 @@ from PySide6.QtWidgets import ( from aare.gui.new_gui.theme import FONT_MONO_FALLBACK, Palette from aare.gui.new_gui.widgets.common import ( - Chip, micro_label, mono_label, vline, @@ -36,43 +35,6 @@ from aare.gui.new_gui.widgets.common import ( from aare.gui.new_gui.widgets.heatmap import METRICS from aare.gui.new_gui.widgets.pipeline import PipelineTracker -_RUN_PLAN_STAGES = (("center", "Center"), ("raster", "Raster"), - ("xrf", "XRF"), ("collect", "Collect")) - - -class RunPlanRow(QWidget): - """Toggle which stages ▶ Play runs. ⚑ on a node pauses before that stage.""" - - toggled = Signal(str) - - def __init__(self, palette: Palette, parent=None): - super().__init__(parent) - lay = QHBoxLayout(self) - lay.setContentsMargins(0, 0, 0, 0) - lay.setSpacing(6) - lay.addWidget(micro_label("RUN PLAN")) - self._chips: dict[str, Chip] = {} - for key, label in _RUN_PLAN_STAGES: - c = Chip(label, palette, checked=False, mono=False) - c.clicked.connect(lambda _=False, k=key: self.toggled.emit(k)) - self._chips[key] = c - lay.addWidget(c) - hint = QLabel("▶ runs the lit stages · tap a stage's ⚑ to pause before it") - hint.setStyleSheet(f"font-size:10.5px; color:{palette.text_faint};") - lay.addSpacing(6) - lay.addWidget(hint) - lay.addStretch(1) - - def set_protocol(self, protocol: dict) -> None: - for key, chip in self._chips.items(): - on = bool(protocol.get(key)) - if chip.isChecked() != on: - chip.blockSignals(True) - chip.setChecked(on) - chip.blockSignals(False) - chip._restyle() - - def _primary_button(text: str, palette: Palette) -> QPushButton: b = QPushButton(text) b.setObjectName("Primary") @@ -697,10 +659,6 @@ class PipelinePanel(QWidget): self.settings = ContextualSettings(palette, defaults) lay.addWidget(self.settings) - # run plan (which stages ▶ Play runs) - self.run_plan = RunPlanRow(palette) - lay.addWidget(self.run_plan) - # transport self.transport = TransportRow(palette) lay.addWidget(self.transport) @@ -716,7 +674,6 @@ class PipelinePanel(QWidget): self._mounted = mounted self._badge.setVisible(mounted) self.bookmarks.setVisible(mounted) - self.run_plan.setVisible(mounted) self.transport.setVisible(mounted) self.settings.set_run_enabled(mounted) self.tracker.set_preview(not mounted)