feat: added crosshair and toggles

This commit is contained in:
2026-07-17 11:41:01 +02:00
parent 426edb8c1a
commit c8513d72a3
3 changed files with 104 additions and 19 deletions
+15
View File
@@ -638,6 +638,9 @@ class MainWindow(QMainWindow):
self.beamline.samcam.show_detection_polygons_changed.connect(
self.sample_camera.set_show_detection_polygons
)
for camera in self.__sample_cameras():
self.beamline.samcam.show_beam_marker_changed.connect(camera.set_show_beam_marker)
self.beamline.samcam.show_beam_crosshair_changed.connect(camera.set_show_beam_crosshair)
self.beamline.samcam.show_target_point_changed.connect(
self.sample_camera.set_show_target_point
)
@@ -936,10 +939,15 @@ class MainWindow(QMainWindow):
except Exception as e:
logger.warning(f"Failed to return to main view during shutdown: {e}")
def __sample_cameras(self):
return (self.sample_camera, self.compact_sample_camera, self.portrait_sample_camera)
def _restore_samcam_overlay_settings(self) -> None:
settings = QSettings("PSI", "AareGUI")
show_detections = settings.value("samcam/show_detections", True, type=bool)
show_detection_polygons = settings.value("samcam/show_detection_polygons", True, type=bool)
show_beam_marker = settings.value("samcam/show_beam_marker", True, type=bool)
show_beam_crosshair = settings.value("samcam/show_beam_crosshair", True, type=bool)
show_target_point = settings.value("samcam/show_target_point", True, type=bool)
show_target_coordinates = settings.value("samcam/show_target_coordinates", True, type=bool)
show_overlay_legend = settings.value("samcam/show_overlay_legend", True, type=bool)
@@ -949,12 +957,17 @@ class MainWindow(QMainWindow):
self.beamline.samcam.apply_overlay_settings(
show_detections=show_detections,
show_detection_polygons=show_detection_polygons,
show_beam_marker=show_beam_marker,
show_beam_crosshair=show_beam_crosshair,
show_target_point=show_target_point,
show_target_coordinates=show_target_coordinates,
show_overlay_legend=show_overlay_legend,
compact_overlay_legend=compact_overlay_legend,
target_color=target_color,
)
for camera in self.__sample_cameras():
camera.set_show_beam_marker(show_beam_marker)
camera.set_show_beam_crosshair(show_beam_crosshair)
self.sample_camera.set_show_detections(show_detections)
self.sample_camera.set_show_detection_polygons(show_detection_polygons)
self.sample_camera.set_show_target_point(show_target_point)
@@ -970,6 +983,8 @@ class MainWindow(QMainWindow):
settings.setValue(
"samcam/show_detection_polygons", overlay["show_detection_polygons"]
) # NEW
settings.setValue("samcam/show_beam_marker", overlay["show_beam_marker"])
settings.setValue("samcam/show_beam_crosshair", overlay["show_beam_crosshair"])
settings.setValue("samcam/show_target_point", overlay["show_target_point"])
settings.setValue("samcam/show_target_coordinates", overlay["show_target_coordinates"])
settings.setValue("samcam/show_overlay_legend", overlay["show_overlay_legend"])
+26
View File
@@ -20,6 +20,8 @@ class SamcamPanel(QWidget):
changed = Signal(SampleCameraSettings)
show_detections_changed = Signal(bool)
show_detection_polygons_changed = Signal(bool)
show_beam_marker_changed = Signal(bool)
show_beam_crosshair_changed = Signal(bool)
show_target_point_changed = Signal(bool)
show_target_coordinates_changed = Signal(bool)
show_overlay_legend_changed = Signal(bool)
@@ -102,6 +104,20 @@ class SamcamPanel(QWidget):
)
detection_polygons_layout.addWidget(self.show_detection_polygons_checkbox)
# Show beam marker checkbox
beam_marker_layout = QHBoxLayout()
self.show_beam_marker_checkbox = QCheckBox("Show beam marker")
self.show_beam_marker_checkbox.setChecked(True)
self.show_beam_marker_checkbox.toggled.connect(self.show_beam_marker_changed.emit)
beam_marker_layout.addWidget(self.show_beam_marker_checkbox)
# Show beam crosshair checkbox
beam_crosshair_layout = QHBoxLayout()
self.show_beam_crosshair_checkbox = QCheckBox("Show beam crosshair")
self.show_beam_crosshair_checkbox.setChecked(True)
self.show_beam_crosshair_checkbox.toggled.connect(self.show_beam_crosshair_changed.emit)
beam_crosshair_layout.addWidget(self.show_beam_crosshair_checkbox)
# Show target point checkbox
target_point_layout = QHBoxLayout()
self.show_target_point_checkbox = QCheckBox("Show target point")
@@ -153,6 +169,8 @@ class SamcamPanel(QWidget):
layout.addWidget(self.screenshot_button)
layout.addLayout(detections_layout)
layout.addLayout(detection_polygons_layout)
layout.addLayout(beam_marker_layout)
layout.addLayout(beam_crosshair_layout)
layout.addLayout(target_point_layout)
layout.addLayout(target_coords_layout)
layout.addLayout(legend_layout)
@@ -177,6 +195,8 @@ class SamcamPanel(QWidget):
*,
show_detections: bool,
show_detection_polygons: bool,
show_beam_marker: bool,
show_beam_crosshair: bool,
show_target_point: bool,
show_target_coordinates: bool,
show_overlay_legend: bool,
@@ -186,6 +206,8 @@ class SamcamPanel(QWidget):
for widget in (
self.show_detections_checkbox,
self.show_detection_polygons_checkbox,
self.show_beam_marker_checkbox,
self.show_beam_crosshair_checkbox,
self.show_target_point_checkbox,
self.show_target_coordinates_checkbox,
self.show_overlay_legend_checkbox,
@@ -196,6 +218,8 @@ class SamcamPanel(QWidget):
self.show_detections_checkbox.setChecked(show_detections)
self.show_detection_polygons_checkbox.setChecked(show_detection_polygons)
self.show_beam_marker_checkbox.setChecked(show_beam_marker)
self.show_beam_crosshair_checkbox.setChecked(show_beam_crosshair)
self.show_target_point_checkbox.setChecked(show_target_point)
self.show_target_coordinates_checkbox.setChecked(show_target_coordinates)
self.show_overlay_legend_checkbox.setChecked(show_overlay_legend)
@@ -205,6 +229,8 @@ class SamcamPanel(QWidget):
for widget in (
self.show_detections_checkbox,
self.show_detection_polygons_checkbox,
self.show_beam_marker_checkbox,
self.show_beam_crosshair_checkbox,
self.show_target_point_checkbox,
self.show_target_coordinates_checkbox,
self.show_overlay_legend_checkbox,
+63 -19
View File
@@ -44,6 +44,10 @@ from aare.gui.widgets.busy_overlay import BusyOverlayStyle, build_busy_overlay_s
logger = setup_logger(LOGGER_NAME)
# The crosshair spans half the beam marker. beam_size_pxl shrinks with camera zoom, so
# clamp to a floor that keeps the cross visible without overflowing a typical ~10 px marker.
BEAM_CROSSHAIR_MIN_SIZE_PXL = 6
class SampleCameraImageState(Enum):
IDLE = 0
@@ -103,6 +107,8 @@ class SampleCameraImageLabel(QGraphicsView):
self.__show_detections = True
self.__show_detection_polygons = True
self.__show_beam_marker = True
self.__show_beam_crosshair = True
self.__show_target_point = True
self.__show_target_coordinates = True
self.__show_overlay_legend = True
@@ -986,6 +992,16 @@ class SampleCameraImageLabel(QGraphicsView):
self.__show_detection_polygons = show
self.update()
@Slot(bool)
def set_show_beam_marker(self, show: bool):
self.__show_beam_marker = show
self.update()
@Slot(bool)
def set_show_beam_crosshair(self, show: bool):
self.__show_beam_crosshair = show
self.update()
@Slot(bool)
def set_show_target_point(self, show: bool):
self.__show_target_point = show
@@ -1013,6 +1029,8 @@ class SampleCameraImageLabel(QGraphicsView):
def target_overlay_settings(self) -> dict:
return {
"show_beam_marker": self.__show_beam_marker,
"show_beam_crosshair": self.__show_beam_crosshair,
"show_target_point": self.__show_target_point,
"show_target_coordinates": self.__show_target_coordinates,
"show_detections": self.__show_detections,
@@ -1038,30 +1056,56 @@ class SampleCameraImageLabel(QGraphicsView):
)
)
def __beam_color(self) -> QColor:
if self.__state == SampleCameraImageState.BEAM_MARKING:
return QColor(102, 51, 153)
if self.__shutter:
return QColor(0, 255, 0)
if self.__is_daq_busy is True:
# Use red color to indicate busy state
return QColor(255, 0, 0)
return QColor(245, 121, 0)
def __draw_beam_center(self, painter: QPainter):
beam_size_pxl = self.__geom.beam_size_pxl
if self.__state == SampleCameraImageState.BEAM_MARKING:
painter.setPen(QPen(QColor(102, 51, 153), 3, Qt.PenStyle.SolidLine))
elif self.__shutter:
painter.setPen(QPen(QColor(0, 255, 0), 3, Qt.PenStyle.SolidLine))
elif self.__is_daq_busy is True:
# Use red color to indicate busy state
painter.setPen(QPen(QColor(255, 0, 0), 3, Qt.PenStyle.SolidLine))
else:
painter.setPen(QPen(QColor(245, 121, 0), 3, Qt.PenStyle.SolidLine))
center = self.__geom.beam_location_pxl
color = self.__beam_color()
painter.setBrush(Qt.BrushStyle.NoBrush)
painter.drawRect(
QRect(
int(self.__geom.beam_location_pxl.x - beam_size_pxl.x / 2),
int(self.__geom.beam_location_pxl.y - beam_size_pxl.y / 2),
int(beam_size_pxl.x),
int(beam_size_pxl.y),
if self.__show_beam_marker:
painter.setPen(QPen(color, 3, Qt.PenStyle.SolidLine))
painter.drawRect(
QRect(
int(center.x - beam_size_pxl.x / 2),
int(center.y - beam_size_pxl.y / 2),
int(beam_size_pxl.x),
int(beam_size_pxl.y),
)
)
)
if self.__show_beam_crosshair:
arm_x = max(beam_size_pxl.x / 2, BEAM_CROSSHAIR_MIN_SIZE_PXL) / 2
arm_y = max(beam_size_pxl.y / 2, BEAM_CROSSHAIR_MIN_SIZE_PXL) / 2
painter.setPen(QPen(color, 2, Qt.PenStyle.SolidLine))
painter.drawLine(
QPointF(center.x - arm_x, center.y), QPointF(center.x + arm_x, center.y)
)
painter.drawLine(
QPointF(center.x, center.y - arm_y), QPointF(center.x, center.y + arm_y)
)
if not self.__show_beam_marker and not self.__show_beam_crosshair:
# Both overlays hidden: keep a minimal pip so the beam position is never lost.
painter.save()
painter.setRenderHint(QPainter.RenderHint.Antialiasing, True)
painter.setPen(Qt.PenStyle.NoPen)
painter.setBrush(QBrush(color))
painter.drawEllipse(QPointF(center.x, center.y), 2, 2)
painter.restore()
@staticmethod
def __draw_circle(painter, coord: Coordinate, color: QColor, radius=10):