Skip to content

Commit a745981

Browse files
committed
Customization of annotation information
1 parent 768f7ec commit a745981

2 files changed

Lines changed: 67 additions & 12 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66

77
* Added `AnnotatedPolygon` annotation to items
88
* Added `make.annotated_polygon` function to `plotpy.builder` module
9+
* Customization of annotation information:
10+
* Added `info_callback` argument to all annotation class constructors
11+
* Added `set_info_callback` method to all annotation classes
12+
* The `info_callback` is a function that takes the annotation object and returns a string with the information to display
13+
* Default `info_callback` is redirected to the `get_infos` method of the annotation object (this makes the feature backward compatible)
914

1015
## Version 2.6.3 ##
1116

plotpy/items/annotation.py

Lines changed: 62 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
from __future__ import annotations
1616

17-
from typing import TYPE_CHECKING
17+
from typing import TYPE_CHECKING, Callable
1818

1919
import numpy as np
2020
from guidata.configtools import get_icon
@@ -63,9 +63,20 @@ class AnnotatedShape(AbstractShape):
6363
SHAPE_CLASS: type[AbstractShape] = RectangleShape # to be overridden
6464
LABEL_ANCHOR: str = ""
6565

66-
def __init__(self, annotationparam: AnnotationParam | None = None) -> None:
66+
def __init__(
67+
self,
68+
annotationparam: AnnotationParam | None = None,
69+
info_callback: Callable[[AnnotatedShape], str] | None = None,
70+
) -> None:
6771
super().__init__()
6872
assert self.LABEL_ANCHOR is not None and len(self.LABEL_ANCHOR) != 0
73+
if info_callback is None:
74+
75+
def info_callback(annotation: AnnotatedShape) -> str:
76+
"""Return information on annotation"""
77+
return annotation.get_infos()
78+
79+
self.info_callback = info_callback
6980
self.shape: AbstractShape = self.create_shape()
7081
self.label = self.create_label()
7182
self.area_computations_visible = True
@@ -196,6 +207,14 @@ def update_label(self) -> None:
196207
"""Update the annotated shape's label contents"""
197208
self.label.update_text()
198209

210+
def set_info_callback(self, callback: Callable[[AnnotatedShape], str]) -> None:
211+
"""Set the callback function to get informations on current shape
212+
213+
Args:
214+
callback: Callback function to get informations on current shape
215+
"""
216+
self.info_callback = callback
217+
199218
def get_text(self) -> str:
200219
"""Return text associated to current shape
201220
(see :py:class:`.label.ObjectInfo`)
@@ -213,7 +232,7 @@ def get_text(self) -> str:
213232
text += "<br>"
214233
text += f"<i>{subtitle}</i>"
215234
if self.area_computations_visible:
216-
infos = self.get_infos()
235+
infos = self.info_callback(self)
217236
if infos:
218237
if text:
219238
text += "<br>"
@@ -469,8 +488,14 @@ class AnnotatedPoint(AnnotatedShape):
469488
SHAPE_CLASS = PointShape
470489
LABEL_ANCHOR = "TL"
471490

472-
def __init__(self, x=0, y=0, annotationparam=None):
473-
AnnotatedShape.__init__(self, annotationparam)
491+
def __init__(
492+
self,
493+
x=0,
494+
y=0,
495+
annotationparam: AnnotationParam | None = None,
496+
info_callback: Callable[[AnnotatedShape], str] | None = None,
497+
) -> None:
498+
super().__init__(annotationparam, info_callback)
474499
self.shape: PointShape
475500
self.set_pos(x, y)
476501
self.setIcon(get_icon("point_shape.png"))
@@ -525,8 +550,16 @@ class AnnotatedSegment(AnnotatedShape):
525550
SHAPE_CLASS = SegmentShape
526551
LABEL_ANCHOR = "C"
527552

528-
def __init__(self, x1=0, y1=0, x2=0, y2=0, annotationparam=None):
529-
AnnotatedShape.__init__(self, annotationparam)
553+
def __init__(
554+
self,
555+
x1=0,
556+
y1=0,
557+
x2=0,
558+
y2=0,
559+
annotationparam: AnnotationParam | None = None,
560+
info_callback: Callable[[AnnotatedShape], str] | None = None,
561+
) -> None:
562+
super().__init__(annotationparam, info_callback)
530563
self.shape: SegmentShape
531564
self.set_rect(x1, y1, x2, y2)
532565
self.setIcon(get_icon("segment.png"))
@@ -594,8 +627,9 @@ def __init__(
594627
points: list[tuple[float, float]] | None = None,
595628
closed: bool | None = None,
596629
annotationparam: AnnotationParam | None = None,
630+
info_callback: Callable[[AnnotatedShape], str] | None = None,
597631
) -> None:
598-
super().__init__(annotationparam)
632+
super().__init__(annotationparam, info_callback)
599633
self.shape: PolygonShape
600634
if points is not None:
601635
self.set_points(points)
@@ -671,8 +705,16 @@ class AnnotatedRectangle(AnnotatedShape):
671705
SHAPE_CLASS = RectangleShape
672706
LABEL_ANCHOR = "TL"
673707

674-
def __init__(self, x1=0, y1=0, x2=0, y2=0, annotationparam=None):
675-
AnnotatedShape.__init__(self, annotationparam)
708+
def __init__(
709+
self,
710+
x1=0,
711+
y1=0,
712+
x2=0,
713+
y2=0,
714+
annotationparam: AnnotationParam | None = None,
715+
info_callback: Callable[[AnnotatedShape], str] | None = None,
716+
) -> None:
717+
super().__init__(annotationparam, info_callback)
676718
self.shape: RectangleShape
677719
self.set_rect(x1, y1, x2, y2)
678720
self.setIcon(get_icon("rectangle.png"))
@@ -828,8 +870,16 @@ class AnnotatedEllipse(AnnotatedShape):
828870
SHAPE_CLASS = EllipseShape
829871
LABEL_ANCHOR = "C"
830872

831-
def __init__(self, x1=0, y1=0, x2=0, y2=0, annotationparam=None):
832-
AnnotatedShape.__init__(self, annotationparam)
873+
def __init__(
874+
self,
875+
x1=0,
876+
y1=0,
877+
x2=0,
878+
y2=0,
879+
annotationparam: AnnotationParam | None = None,
880+
info_callback: Callable[[AnnotatedShape], str] | None = None,
881+
) -> None:
882+
super().__init__(annotationparam, info_callback)
833883
self.shape: EllipseShape
834884
self.set_xdiameter(x1, y1, x2, y2)
835885
self.setIcon(get_icon("ellipse_shape.png"))

0 commit comments

Comments
 (0)