feat: show the mounted sample name on the camera view
A "Currently mounted: <sample_name>" HUD line in the top-left corner of the sample camera, driven by the DAQ status (clears when nothing is mounted). Painted like the other camera HUDs and sized through the text zoom, which QSS cannot reach here. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -59,6 +59,7 @@ from aare.gui.styles import (
|
||||
THEME_SUNSET,
|
||||
TOOLTIP_TEXT,
|
||||
WHITE,
|
||||
font_scale,
|
||||
qcolor,
|
||||
)
|
||||
from aare.gui.widgets.busy_overlay import (
|
||||
@@ -130,6 +131,7 @@ class SampleCameraImageLabel(QGraphicsView):
|
||||
self._tell_state = None
|
||||
self._auto_centering = False
|
||||
self._busy_overlay_style: BusyOverlayStyle | None = None
|
||||
self._mounted_sample_name: str | None = None
|
||||
|
||||
self._geom = geom
|
||||
self._bookmarks: SmargonBookmarkList = SmargonBookmarkList()
|
||||
@@ -459,6 +461,7 @@ class SampleCameraImageLabel(QGraphicsView):
|
||||
self._draw_detections(painter, rect)
|
||||
self._draw_target_point(painter)
|
||||
self._draw_overlay_legend(painter)
|
||||
self._draw_mounted_sample(painter)
|
||||
self._draw_hover_hud(painter)
|
||||
self._draw_help_overlay(painter)
|
||||
|
||||
@@ -803,6 +806,11 @@ class SampleCameraImageLabel(QGraphicsView):
|
||||
self._bounding_box = s.box
|
||||
self._tell_state = s.tell_state
|
||||
|
||||
new_name = s.sample.sample_name if s.sample is not None else None
|
||||
if new_name != self._mounted_sample_name:
|
||||
self._mounted_sample_name = new_name
|
||||
self.viewport().update()
|
||||
|
||||
new_session_state = s.session.session if hasattr(s, "session") else None
|
||||
if new_session_state != self._session_state:
|
||||
self._session_state = new_session_state
|
||||
@@ -1269,6 +1277,32 @@ class SampleCameraImageLabel(QGraphicsView):
|
||||
label = f"{bar_um / 1000.0:g} mm" if bar_um >= 1000.0 else f"{bar_um:g} µm"
|
||||
return bar_um, label
|
||||
|
||||
def _draw_mounted_sample(self, painter: QPainter):
|
||||
# Top-left HUD line (legend sits bottom-left, scale bar bottom-right):
|
||||
# which sample is on the gonio, readable without leaving the camera.
|
||||
if not self._mounted_sample_name:
|
||||
return
|
||||
|
||||
painter.save()
|
||||
painter.resetTransform()
|
||||
painter.setRenderHint(QPainter.RenderHint.Antialiasing, True)
|
||||
|
||||
font = QFont()
|
||||
# Follows the Ctrl+plus/minus text zoom — painted HUDs bypass QSS.
|
||||
font.setPointSize(round(10 * font_scale()))
|
||||
font.setBold(True)
|
||||
painter.setFont(font)
|
||||
fm = QFontMetrics(font)
|
||||
|
||||
margin = 18
|
||||
text = f"Currently mounted: {self._mounted_sample_name}"
|
||||
baseline = margin + fm.ascent()
|
||||
painter.setPen(QPen(qcolor(SHADOW, 200)))
|
||||
painter.drawText(QPointF(margin + 1, baseline + 1), text)
|
||||
painter.setPen(QPen(qcolor(WHITE)))
|
||||
painter.drawText(QPointF(margin, baseline), text)
|
||||
painter.restore()
|
||||
|
||||
def _draw_hover_hud(self, painter: QPainter):
|
||||
# Bottom-right HUD: grey scale bar over the hovered pixel coordinates.
|
||||
if self._hover_pos is None or self.pixmap_item is None:
|
||||
|
||||
@@ -297,3 +297,30 @@ def test_unknown_session_paints_the_viewing_mode_badge(camera):
|
||||
assert camera._busy_overlay_style is None
|
||||
camera.grab()
|
||||
assert camera._session_badge_rect is not None
|
||||
|
||||
|
||||
def test_mounted_sample_hud_follows_status(camera):
|
||||
from aarecommon.models.models import DewarAddress, SampleShortInfo
|
||||
|
||||
# No sample in the status -> no HUD line, draw path skips cleanly.
|
||||
assert camera._mounted_sample_name is None
|
||||
camera.grab()
|
||||
|
||||
sample = SampleShortInfo(
|
||||
db_id=7,
|
||||
puck_name="puck1",
|
||||
dewar_name="dewar",
|
||||
sample_name="lyso_007",
|
||||
run_number=1,
|
||||
user="p123",
|
||||
pin=1,
|
||||
location=DewarAddress(segment="A", pos=1),
|
||||
)
|
||||
status = _status(busy=False, session=SessionsStateEnum.OwnedByYou)
|
||||
camera.update_daq_status(status.model_copy(update={"sample": sample}))
|
||||
assert camera._mounted_sample_name == "lyso_007"
|
||||
camera.grab() # paints the top-left "Currently mounted:" line
|
||||
|
||||
# Unmount (sample gone from the status) clears the line again.
|
||||
camera.update_daq_status(status)
|
||||
assert camera._mounted_sample_name is None
|
||||
|
||||
Reference in New Issue
Block a user