From 16b61b886b2c97664c148f0e52cdbca70856ec80 Mon Sep 17 00:00:00 2001 From: Dawn Date: Mon, 17 Aug 2026 18:23:45 +0200 Subject: [PATCH] fix: no BEAMLINE BUSY overlay during Sample alignment Same exception as the motion watch: busy in Sample alignment is the alignment itself, and the sample motion is watched in these very views - the curtain hid exactly what the user needed to see. Gated at both style call sites (sample camera and the Axis views); the session-driven 'In viewing mode' badge is unaffected. Co-Authored-By: Claude Fable 5 --- src/aare/gui/main_window.py | 4 +++- src/aare/gui/widgets/camera_image.py | 8 +++++++- tests/unit/gui/test_camera_image.py | 28 +++++++++++++++++++++++++--- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/aare/gui/main_window.py b/src/aare/gui/main_window.py index 115c080c..3282a738 100644 --- a/src/aare/gui/main_window.py +++ b/src/aare/gui/main_window.py @@ -2734,8 +2734,10 @@ class MainWindow(QMainWindow): if hasattr(self, "gonio_camera_thread") and self.gonio_camera_thread is not None: self.gonio_camera_thread.set_busy(s.busy) + # Sample alignment busy is the alignment itself (same exception as + # the motion watch below) — no BEAMLINE BUSY curtain on any view. busy_style = build_busy_overlay_style( - is_busy=bool(s.busy), + is_busy=bool(s.busy) and s.state != BeamlineStateEnum.SampleAlignment, tell_state=s.tell_state, session_state=getattr(getattr(s, "session", None), "session", None), ) diff --git a/src/aare/gui/widgets/camera_image.py b/src/aare/gui/widgets/camera_image.py index 423a3bb5..b8e4171d 100644 --- a/src/aare/gui/widgets/camera_image.py +++ b/src/aare/gui/widgets/camera_image.py @@ -804,8 +804,14 @@ class SampleCameraImageLabel(QGraphicsView): self._session_state = new_session_state self.update() + # Same exception as the main window's motion watch: busy during + # Sample alignment IS the alignment, and the sample motion is watched + # right here — no BEAMLINE BUSY curtain over it. The "In viewing + # mode" badge is session-driven and unaffected by the gate. new_busy_style = build_busy_overlay_style( - is_busy=bool(s.busy), tell_state=s.tell_state, session_state=self._session_state + is_busy=bool(s.busy) and s.state != BeamlineStateEnum.SampleAlignment, + tell_state=s.tell_state, + session_state=self._session_state, ) if new_busy_style != self._busy_overlay_style: self._busy_overlay_style = new_busy_style diff --git a/tests/unit/gui/test_camera_image.py b/tests/unit/gui/test_camera_image.py index 4730fb6e..b35ebbda 100644 --- a/tests/unit/gui/test_camera_image.py +++ b/tests/unit/gui/test_camera_image.py @@ -31,7 +31,12 @@ def _geom() -> SampleGeometryModel: ) -def _status(*, busy: bool, session: SessionsStateEnum) -> DAQStatusModel: +def _status( + *, + busy: bool, + session: SessionsStateEnum, + state: BeamlineStateEnum = BeamlineStateEnum.SampleAlignment, +) -> DAQStatusModel: return DAQStatusModel( geom=_geom(), diffraction=DiffractionGeometry( @@ -61,7 +66,7 @@ def _status(*, busy: bool, session: SessionsStateEnum) -> DAQStatusModel: dtz_min=120.0, dtz_max=1600.0, ), - state=BeamlineStateEnum.SampleAlignment, + state=state, busy=busy, session=SessionStatus(session=session, current_pgroup="p123", staff=True), crystal_size=CrystalSize(x=0, y=0, z=0), @@ -122,13 +127,30 @@ def test_camera_error_message_rewords_and_draws(camera): def test_busy_warning_is_not_a_click_target(camera): - camera.update_daq_status(_status(busy=True, session=SessionsStateEnum.OwnedByYou)) + camera.update_daq_status( + _status( + busy=True, + session=SessionsStateEnum.OwnedByYou, + state=BeamlineStateEnum.DataCollection, + ) + ) style = camera._busy_overlay_style assert style is not None assert style.text == "BEAMLINE BUSY" camera.grab() assert camera._session_badge_rect is None + # Sample alignment is the exception: its busy moves ARE the alignment, + # watched in this very view — no BEAMLINE BUSY curtain over it. + camera.update_daq_status( + _status( + busy=True, + session=SessionsStateEnum.OwnedByYou, + state=BeamlineStateEnum.SampleAlignment, + ) + ) + assert camera._busy_overlay_style is None + def test_vacant_badge_hover_click_and_theme(camera, qtbot): camera.update_daq_status(_status(busy=False, session=SessionsStateEnum.Vacant))