diff --git a/laserstudio/laserstudio.py b/laserstudio/laserstudio.py index b1bed0a..6dbfb06 100644 --- a/laserstudio/laserstudio.py +++ b/laserstudio/laserstudio.py @@ -7,7 +7,7 @@ ) from typing import Optional, Any -from .widgets.viewer import Viewer +from .widgets.viewer import Viewer, IdMarker from .instruments.instruments import ( Instruments, PDMInstrument, @@ -246,6 +246,19 @@ def handle_position(self, pos: Optional[list[float]]) -> dict: self.instruments.stage.move_to(Vector(*pos), wait=True) return {"pos": self.instruments.stage.position.data} + def handle_markers(self) -> list[dict]: + """Handle a Markers API request to get the list of markers.""" + + return [ + { + "id": marker.id if isinstance(marker, IdMarker) else -1, + "pos": [marker.pos().x(), marker.pos().y()], + "color": + [marker.qfillcolor.redF(), marker.qfillcolor.greenF(), marker.qfillcolor.blueF(), marker.qfillcolor.alphaF()] + } + for marker in self.viewer.markers + ] + def handle_add_markers( self, positions: Optional[list[list[float]]], color: Optional[list[float]] ) -> dict: diff --git a/laserstudio/lsapi/lsapi.py b/laserstudio/lsapi/lsapi.py index c247366..682e2f8 100644 --- a/laserstudio/lsapi/lsapi.py +++ b/laserstudio/lsapi/lsapi.py @@ -69,6 +69,14 @@ def autofocus(self) -> List[float]: """ return self.send("motion/autofocus").json() + def markers(self) -> List[Dict[str, Union[int, Tuple[float, float]]]]: + """ + Get the list of markers in the scene. + + :return: A list of dictionaries, each containing the marker's id, position and RGBA color. + """ + return self.send("annotation/markers").json() + def marker( self, color: Union[Tuple[float, float, float], Tuple[float, float, float, float]] = ( diff --git a/laserstudio/lsapi/setup.py b/laserstudio/lsapi/setup.py index 0fbbae4..c8631a2 100644 --- a/laserstudio/lsapi/setup.py +++ b/laserstudio/lsapi/setup.py @@ -4,7 +4,7 @@ setup( name="lsapi", - version="1.1", + version="1.2", install_requires=["requests", "Pillow"], python_requires=">=3.7", ) diff --git a/laserstudio/restserver/server.py b/laserstudio/restserver/server.py index f7a3016..4773301 100644 --- a/laserstudio/restserver/server.py +++ b/laserstudio/restserver/server.py @@ -57,6 +57,10 @@ def handle_add_markers( ): return QVariant(self.laser_studio.handle_add_markers(pos, color)) + @pyqtSlot(result="QVariant") + def handle_markers(self): + return QVariant(self.laser_studio.handle_markers()) + @pyqtSlot(QVariant, result="QVariant") def handle_position(self, pos: Optional[List[float]]): return QVariant(self.laser_studio.handle_position(pos)) @@ -311,6 +315,11 @@ def post(self): qvar = RestServer.invoke("handle_add_markers", QVariant(pos), QVariant(color)) return cast(dict, qvar) +@annotations.route("/markers") +class Markers(Resource): + def get(self): + qvar = RestServer.invoke("handle_markers") + return cast(List[dict], qvar) # instruments = flask_api.namespace("instruments", description="Control instruments") diff --git a/laserstudio/widgets/marker.py b/laserstudio/widgets/marker.py index 38e1013..7d107b7 100644 --- a/laserstudio/widgets/marker.py +++ b/laserstudio/widgets/marker.py @@ -68,8 +68,13 @@ def size(self, value): self.__update_size() @property - def color(self): + def qcolor(self) -> QColor: """:return: Current color, as QColor.""" + return QColor(self.__color) + + @property + def color(self) -> Union[QColor, Qt.GlobalColor, int]: + """:return: Current color, as QColor, Qt.GlobalColor or int.""" return self.__color @color.setter @@ -86,6 +91,11 @@ def color(self, value: Union[QColor, Qt.GlobalColor, int]): self.__line2.setPen(self.__pen) self.update() + @property + def qfillcolor(self) -> QColor: + """:return: Current fill color, as QColor.""" + return QColor(self.__fillcolor) + @property def fillcolor(self): """:return: Current fill color, as QColor.""" @@ -139,7 +149,7 @@ class IdMarker(Marker): ID = 1 def __init__(self, parent=None, color=QColorConstants.Red) -> None: - super().__init__(parent, color=QColorConstants.Transparent, fillcolor=color) + super().__init__(parent, color=color, fillcolor=color) self._id = IdMarker.ID IdMarker.ID += 1 diff --git a/laserstudio/widgets/viewer.py b/laserstudio/widgets/viewer.py index 4c7e66e..2097cac 100644 --- a/laserstudio/widgets/viewer.py +++ b/laserstudio/widgets/viewer.py @@ -123,6 +123,10 @@ def __init__(self, parent=None): self.setMouseTracking(True) + @property + def markers(self) -> list[Marker]: + return self.__markers + def marker_size(self, value: float): self.default_marker_size = value for m in self.__markers: diff --git a/tests/test_lsapi.py b/tests/test_lsapi.py index 10eac18..f0386b7 100644 --- a/tests/test_lsapi.py +++ b/tests/test_lsapi.py @@ -5,7 +5,7 @@ def test_add_marker(): api = LSAPI() m = api.marker( - (random(), random(), random(), 0.7), p := (random() * 100, random() * 100) + (random(), random(), random(), 0.7), p := (random() * 3000, random() * 3000) ) assert list(p) == m["pos"] @@ -13,10 +13,10 @@ def test_add_marker(): def test_add_5000_markers_seq(): api = LSAPI() first = api.marker( - (random(), random(), random(), 0.7), (random() * 100, random() * 100) + (random(), random(), random(), 0.7), (random() * 3000, random() * 3000) ) col_pos = [ - ((random(), random(), random(), 0.7), (random() * 100, random() * 100)) + ((random(), random(), random(), 0.7), (random() * 3000, random() * 3000)) for _ in range(1, 5000) ] @@ -31,9 +31,9 @@ def test_add_5000_markers_batch_by100(): for _ in range(50): color = (random(), random(), random(), 0.7) first = api.marker( - color, (random() * 100, random() * 100) + color, (random() * 3000, random() * 3000) ) - positions = [(random() * 100, random() * 100) for _ in range(1, 100)] + positions = [(random() * 3000, random() * 3000) for _ in range(1, 100)] markers = api.marker(color, positions) for i, m in enumerate(markers["markers"]): @@ -44,14 +44,22 @@ def test_add_5000_markers_in_one(): api = LSAPI() color = (random(), random(), random(), 0.7) first = api.marker( - color, (random() * 100, random() * 100) + color, (random() * 3000, random() * 3000) ) - positions = [(random() * 100, random() * 100) for _ in range(1, 5000)] + positions = [(random() * 3000, random() * 3000) for _ in range(1, 5000)] markers = api.marker(color, positions) for i, m in enumerate(markers["markers"]): assert m["id"] == (1 + i) + first["id"] +def test_get_markers() -> None: + api = LSAPI() + markers = api.markers() + assert isinstance(markers, list) + assert all(isinstance(marker, dict) for marker in markers) + assert all("id" in marker for marker in markers) + assert all("pos" in marker for marker in markers) + assert all("color" in marker for marker in markers) def test_go_next(): api = LSAPI()