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 <noreply@anthropic.com>
This commit is contained in:
2026-08-18 09:25:14 +02:00
committed by duan_j
co-authored by Claude Fable 5
parent 37bb25e705
commit 16b61b886b
3 changed files with 35 additions and 5 deletions
+3 -1
View File
@@ -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),
)
+7 -1
View File
@@ -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
+25 -3
View File
@@ -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))