diff --git a/bec_widgets/cli/client.py b/bec_widgets/cli/client.py index 86284b23..d9cc8d48 100644 --- a/bec_widgets/cli/client.py +++ b/bec_widgets/cli/client.py @@ -602,6 +602,16 @@ class BaseROI(RPCBase): ndarray: Pixel data inside the ROI, or (data, coords) if *returnMappedCoords* is True. """ + @rpc_call + def set_position(self, x: "float", y: "float"): + """ + Sets the position of the ROI. + + Args: + x (float): The x-coordinate of the new position. + y (float): The y-coordinate of the new position. + """ + class CircularROI(RPCBase): """Circular Region of Interest with center/diameter tracking and auto-labeling.""" @@ -701,6 +711,16 @@ class CircularROI(RPCBase): ndarray: Pixel data inside the ROI, or (data, coords) if *returnMappedCoords* is True. """ + @rpc_call + def set_position(self, x: "float", y: "float"): + """ + Sets the position of the ROI. + + Args: + x (float): The x-coordinate of the new position. + y (float): The y-coordinate of the new position. + """ + class Curve(RPCBase): @rpc_call @@ -2652,6 +2672,16 @@ class RectangularROI(RPCBase): ndarray: Pixel data inside the ROI, or (data, coords) if *returnMappedCoords* is True. """ + @rpc_call + def set_position(self, x: "float", y: "float"): + """ + Sets the position of the ROI. + + Args: + x (float): The x-coordinate of the new position. + y (float): The y-coordinate of the new position. + """ + class ResetButton(RPCBase): """A button that resets the scan queue.""" diff --git a/bec_widgets/widgets/plots/roi/image_roi.py b/bec_widgets/widgets/plots/roi/image_roi.py index 670b1ce4..388e8dd1 100644 --- a/bec_widgets/widgets/plots/roi/image_roi.py +++ b/bec_widgets/widgets/plots/roi/image_roi.py @@ -113,6 +113,7 @@ class BaseROI(BECConnector): "line_width.setter", "get_coordinates", "get_data_from_image", + "set_position", ] def __init__( @@ -333,6 +334,16 @@ class BaseROI(BECConnector): def add_scale_handle(self): return + def set_position(self, x: float, y: float): + """ + Sets the position of the ROI. + + Args: + x (float): The x-coordinate of the new position. + y (float): The y-coordinate of the new position. + """ + self.setPos(x, y) + def remove(self): handles = self.handles for i in range(len(handles)): diff --git a/tests/unit_tests/test_image_rois.py b/tests/unit_tests/test_image_rois.py index d64e38df..df8c9e0b 100644 --- a/tests/unit_tests/test_image_rois.py +++ b/tests/unit_tests/test_image_rois.py @@ -188,3 +188,20 @@ def test_roi_controller_get_roi_methods(qtbot, mocked_client): assert controller.get_roi(1) == r2 assert controller.get_roi(99) is None assert controller.get_roi_by_name("notfound") is None + + +def test_roi_set_position(bec_image_widget_with_roi): + """Test that set_position updates the ROI position and coordinates.""" + widget, roi, _ = bec_image_widget_with_roi + # Save original coordinates + orig_coords = roi.get_coordinates(typed=False) + # Move ROI by a known offset + roi.set_position(10, 15) + new_coords = roi.get_coordinates(typed=False) + # The new position should reflect the set_position call + assert new_coords != orig_coords + # The first coordinate should match the new position + if hasattr(roi, "pos"): + pos = roi.pos() + assert int(pos.x()) == 10 + assert int(pos.y()) == 15