diff --git a/docs/source/api/selectors/LinearRegionSelector.rst b/docs/source/api/selectors/LinearRegionSelector.rst index 9637dd8e1..6c8d2eefc 100644 --- a/docs/source/api/selectors/LinearRegionSelector.rst +++ b/docs/source/api/selectors/LinearRegionSelector.rst @@ -24,7 +24,9 @@ Properties LinearRegionSelector.axis LinearRegionSelector.block_events LinearRegionSelector.deleted + LinearRegionSelector.edge_color LinearRegionSelector.event_handlers + LinearRegionSelector.fill_color LinearRegionSelector.limits LinearRegionSelector.name LinearRegionSelector.offset @@ -33,6 +35,7 @@ Properties LinearRegionSelector.rotation LinearRegionSelector.selection LinearRegionSelector.supported_events + LinearRegionSelector.vertex_color LinearRegionSelector.visible LinearRegionSelector.world_object diff --git a/docs/source/api/selectors/LinearSelector.rst b/docs/source/api/selectors/LinearSelector.rst index c514f982c..b82e3c1df 100644 --- a/docs/source/api/selectors/LinearSelector.rst +++ b/docs/source/api/selectors/LinearSelector.rst @@ -24,7 +24,9 @@ Properties LinearSelector.axis LinearSelector.block_events LinearSelector.deleted + LinearSelector.edge_color LinearSelector.event_handlers + LinearSelector.fill_color LinearSelector.limits LinearSelector.name LinearSelector.offset @@ -33,6 +35,7 @@ Properties LinearSelector.rotation LinearSelector.selection LinearSelector.supported_events + LinearSelector.vertex_color LinearSelector.visible LinearSelector.world_object diff --git a/docs/source/api/selectors/RectangleSelector.rst b/docs/source/api/selectors/RectangleSelector.rst index 930e12c67..81c9afd66 100644 --- a/docs/source/api/selectors/RectangleSelector.rst +++ b/docs/source/api/selectors/RectangleSelector.rst @@ -24,7 +24,9 @@ Properties RectangleSelector.axis RectangleSelector.block_events RectangleSelector.deleted + RectangleSelector.edge_color RectangleSelector.event_handlers + RectangleSelector.fill_color RectangleSelector.limits RectangleSelector.name RectangleSelector.offset @@ -33,6 +35,7 @@ Properties RectangleSelector.rotation RectangleSelector.selection RectangleSelector.supported_events + RectangleSelector.vertex_color RectangleSelector.visible RectangleSelector.world_object diff --git a/fastplotlib/graphics/selectors/_base_selector.py b/fastplotlib/graphics/selectors/_base_selector.py index 30643bbe4..5158a9239 100644 --- a/fastplotlib/graphics/selectors/_base_selector.py +++ b/fastplotlib/graphics/selectors/_base_selector.py @@ -3,6 +3,7 @@ from functools import partial import numpy as np +import pygfx from pygfx import WorldObject, Line, Mesh, Points @@ -40,6 +41,70 @@ class BaseSelector(Graphic): def axis(self) -> str: return self._axis + @property + def fill_color(self) -> pygfx.Color: + """Returns the fill color of the selector, ``None`` if selector has no fill.""" + return self._fill_color + + @fill_color.setter + def fill_color(self, color: str | Sequence[float]): + """ + Set the fill color of the selector. + + Parameters + ---------- + color : str | Sequence[float] + String or sequence of floats that gets converted into a ``pygfx.Color`` object. + """ + color = pygfx.Color(color) + for fill in self._fill: + fill.material.color = color + self._original_colors[fill] = color + self._fill_color = color + + @property + def vertex_color(self) -> pygfx.Color: + """Returns the vertex color of the selector, ``None`` if selector has no vertices.""" + return self._vertex_color + + @vertex_color.setter + def vertex_color(self, color: str | Sequence[float]): + """ + Set the vertex color of the selector. + + Parameters + ---------- + color : str | Sequence[float] + String or sequence of floats that gets converted into a ``pygfx.Color`` object. + """ + color = pygfx.Color(color) + for vertex in self._vertices: + vertex.material.color = color + vertex.material.edge_color = color + self._original_colors[vertex] = color + self._vertex_color = color + + @property + def edge_color(self) -> pygfx.Color: + """Returns the edge color of the selector""" + return self._edge_color + + @edge_color.setter + def edge_color(self, color: str | Sequence[float]): + """ + Set the edge color of the selector. + + Parameters + ---------- + color : str | Sequence[float] + String or sequence of floats that gets converted into a ``pygfx.Color`` object. + """ + color = pygfx.Color(color) + for edge in self._edges: + edge.material.color = color + self._original_colors[edge] = color + self._edge_color = color + def __init__( self, edges: Tuple[Line, ...] = None, diff --git a/fastplotlib/graphics/selectors/_linear.py b/fastplotlib/graphics/selectors/_linear.py index dfe7aadab..fe57036a3 100644 --- a/fastplotlib/graphics/selectors/_linear.py +++ b/fastplotlib/graphics/selectors/_linear.py @@ -47,6 +47,27 @@ def limits(self, values: tuple[float, float]): ) # if values are close to zero things get weird so round them self.selection._limits = self._limits + @property + def edge_color(self) -> pygfx.Color: + """Returns the color of the linear selector.""" + return self._edge_color + + @edge_color.setter + def edge_color(self, color: str | Sequence[float]): + """ + Set the color of the linear selector. + + Parameters + ---------- + color : str | Sequence[float] + String or sequence of floats that gets converted into a ``pygfx.Color`` object. + """ + color = pygfx.Color(color) + # only want to change inner line color + self._edges[0].material.color = color + self._original_colors[self._edges[0]] = color + self._edge_color = color + # TODO: make `selection` arg in graphics data space not world space def __init__( self, @@ -56,7 +77,7 @@ def __init__( center: float, axis: str = "x", parent: Graphic = None, - color: str | Sequence[float] | np.ndarray = "w", + edge_color: str | Sequence[float] | np.ndarray = "w", thickness: float = 2.5, arrow_keys_modifier: str = "Shift", name: str = None, @@ -92,13 +113,16 @@ def __init__( thickness: float, default 2.5 thickness of the selector - color: str | tuple | np.ndarray, default "w" + edge_color: str | tuple | np.ndarray, default "w" color of the selector name: str, optional name of linear selector """ + self._fill_color = None + self._edge_color = pygfx.Color(edge_color) + self._vertex_color = None if len(limits) != 2: raise ValueError("limits must be a tuple of 2 integers, i.e. (int, int)") @@ -134,7 +158,7 @@ def __init__( line_inner = pygfx.Line( # self.data.feature_data because data is a Buffer geometry=pygfx.Geometry(positions=line_data), - material=material(thickness=thickness, color=color, pick_write=True), + material=material(thickness=thickness, color=edge_color, pick_write=True), ) self.line_outer = pygfx.Line( diff --git a/fastplotlib/graphics/selectors/_linear_region.py b/fastplotlib/graphics/selectors/_linear_region.py index db7788d00..c1e6095f8 100644 --- a/fastplotlib/graphics/selectors/_linear_region.py +++ b/fastplotlib/graphics/selectors/_linear_region.py @@ -114,6 +114,9 @@ def __init__( name of this selector graphic """ + self._edge_color = pygfx.Color(edge_color) + self._fill_color = pygfx.Color(fill_color) + self._vertex_color = None # lots of very close to zero values etc. so round them, otherwise things get weird if not len(selection) == 2: @@ -134,13 +137,17 @@ def __init__( if axis == "x": mesh = pygfx.Mesh( pygfx.box_geometry(1, size, 1), - pygfx.MeshBasicMaterial(color=pygfx.Color(fill_color), pick_write=True), + pygfx.MeshBasicMaterial( + color=pygfx.Color(self.fill_color), pick_write=True + ), ) elif axis == "y": mesh = pygfx.Mesh( pygfx.box_geometry(size, 1, 1), - pygfx.MeshBasicMaterial(color=pygfx.Color(fill_color), pick_write=True), + pygfx.MeshBasicMaterial( + color=pygfx.Color(self.fill_color), pick_write=True + ), ) else: raise ValueError("`axis` must be one of 'x' or 'y'") @@ -179,7 +186,7 @@ def __init__( positions=init_line_data.copy() ), # copy so the line buffer is isolated pygfx.LineMaterial( - thickness=edge_thickness, color=edge_color, pick_write=True + thickness=edge_thickness, color=self.edge_color, pick_write=True ), ) line1 = pygfx.Line( @@ -187,7 +194,7 @@ def __init__( positions=init_line_data.copy() ), # copy so the line buffer is isolated pygfx.LineMaterial( - thickness=edge_thickness, color=edge_color, pick_write=True + thickness=edge_thickness, color=self.edge_color, pick_write=True ), ) diff --git a/fastplotlib/graphics/selectors/_rectangle.py b/fastplotlib/graphics/selectors/_rectangle.py index 356b437d7..51c3209b1 100644 --- a/fastplotlib/graphics/selectors/_rectangle.py +++ b/fastplotlib/graphics/selectors/_rectangle.py @@ -117,6 +117,10 @@ def __init__( xmin, xmax, ymin, ymax = selection + self._fill_color = pygfx.Color(fill_color) + self._edge_color = pygfx.Color(edge_color) + self._vertex_color = pygfx.Color(vertex_color) + width = xmax - xmin height = ymax - ymin @@ -125,7 +129,9 @@ def __init__( self.fill = pygfx.Mesh( pygfx.box_geometry(width, height, 1), - pygfx.MeshBasicMaterial(color=pygfx.Color(fill_color), pick_write=True), + pygfx.MeshBasicMaterial( + color=pygfx.Color(self.fill_color), pick_write=True + ), ) self.fill.world.position = (0, 0, -2) @@ -142,7 +148,7 @@ def __init__( left_line = pygfx.Line( pygfx.Geometry(positions=left_line_data.copy()), - pygfx.LineMaterial(thickness=edge_thickness, color=edge_color), + pygfx.LineMaterial(thickness=edge_thickness, color=self.edge_color), ) # position data for the right edge line @@ -155,7 +161,7 @@ def __init__( right_line = pygfx.Line( pygfx.Geometry(positions=right_line_data.copy()), - pygfx.LineMaterial(thickness=edge_thickness, color=edge_color), + pygfx.LineMaterial(thickness=edge_thickness, color=self.edge_color), ) # position data for the left edge line @@ -168,7 +174,7 @@ def __init__( bottom_line = pygfx.Line( pygfx.Geometry(positions=bottom_line_data.copy()), - pygfx.LineMaterial(thickness=edge_thickness, color=edge_color), + pygfx.LineMaterial(thickness=edge_thickness, color=self.edge_color), ) # position data for the right edge line @@ -181,7 +187,7 @@ def __init__( top_line = pygfx.Line( pygfx.Geometry(positions=top_line_data.copy()), - pygfx.LineMaterial(thickness=edge_thickness, color=edge_color), + pygfx.LineMaterial(thickness=edge_thickness, color=self.edge_color), ) self.edges: Tuple[pygfx.Line, pygfx.Line, pygfx.Line, pygfx.Line] = ( @@ -207,9 +213,9 @@ def __init__( pygfx.PointsMarkerMaterial( marker="square", size=vertex_thickness, - color=vertex_color, + color=self.vertex_color, size_mode="vertex", - edge_color=vertex_color, + edge_color=self.vertex_color, ), ) @@ -218,9 +224,9 @@ def __init__( pygfx.PointsMarkerMaterial( marker="square", size=vertex_thickness, - color=vertex_color, + color=self.vertex_color, size_mode="vertex", - edge_color=vertex_color, + edge_color=self.vertex_color, ), ) @@ -231,9 +237,9 @@ def __init__( pygfx.PointsMarkerMaterial( marker="square", size=vertex_thickness, - color=vertex_color, + color=self.vertex_color, size_mode="vertex", - edge_color=vertex_color, + edge_color=self.vertex_color, ), ) @@ -244,9 +250,9 @@ def __init__( pygfx.PointsMarkerMaterial( marker="square", size=vertex_thickness, - color=vertex_color, + color=self.vertex_color, size_mode="vertex", - edge_color=vertex_color, + edge_color=self.vertex_color, ), )