bec-widgets 0.57.7__py3-none-any.whl → 0.58.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
CHANGELOG.md CHANGED
@@ -2,6 +2,34 @@
2
2
 
3
3
 
4
4
 
5
+ ## v0.58.1 (2024-06-07)
6
+
7
+ ### Fix
8
+
9
+ * fix(dock): new dock can be detached upon creation ([`02a2608`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/02a26086c4540127a11c235cba30afc4fd712007))
10
+
11
+
12
+ ## v0.58.0 (2024-06-07)
13
+
14
+ ### Feature
15
+
16
+ * feat(utils.colors): general color validators ([`3094632`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/30946321348abc349fb4003dc39d0232dc19606c))
17
+
18
+ ### Fix
19
+
20
+ * fix: bar colormap dynamic setting ([`67fd5e8`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/67fd5e8581f60fe64027ac57f1f12cefa4d28343))
21
+
22
+ * fix: formatting isort ([`bf699ec`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/bf699ec1fbe2aacd31854e84fb0438c336840fcf))
23
+
24
+ * fix(curve): 2D scatter updated if color_map_z is changed ([`6985ff0`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/6985ff0fcef9791b53198206ec8cbccd1d65ef99))
25
+
26
+ * fix(curve): color_map_z setting works ([`33f7be4`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/33f7be42c512402dab3fdd9781a8234e3ec5f4ba))
27
+
28
+ ### Test
29
+
30
+ * test(color): validation tests added ([`c0ddece`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/c0ddeceeeabacbf33019a8f24b18821926dc17ac))
31
+
32
+
5
33
  ## v0.57.7 (2024-06-07)
6
34
 
7
35
  ### Documentation
@@ -125,36 +153,8 @@
125
153
 
126
154
  ## v0.56.2 (2024-06-05)
127
155
 
128
- ### Documentation
129
-
130
- * docs: restructured docs layout ([`3c9181d`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/3c9181d93d68faa4efb3b91c486ca9ca935975a0))
131
-
132
156
  ### Fix
133
157
 
134
158
  * fix(bar): ring saves current value in config ([`9648e3e`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/9648e3ea96a4109be6be694d855151ed6d3ad661))
135
159
 
136
160
  * fix(dock): dock saves configs of all children widgets ([`4be756a`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/4be756a8676421c3a3451458995232407295df84))
137
-
138
- * fix(dock_area): save/restore state is saved in config ([`46face0`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/46face0ee59122f04cb383da685a6658beeeb389))
139
-
140
- * fix(figure): added correct types of configs to subplot widgets ([`6f3b1ea`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/6f3b1ea985c18929b9bab54239eeb600f03b274a))
141
-
142
-
143
- ## v0.56.1 (2024-06-04)
144
-
145
- ### Fix
146
-
147
- * fix(spiral_progress_bar/rings): config min/max values added check for floats ([`9d615c9`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/9d615c915c8f7cc2ea8f1dc17993b98fe462c682))
148
-
149
- * fix(spiral_progress_bar): Endpoint is always stored as a string in the RingConnection Config ([`d253991`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/d2539918b296559e1d684344e179775a2423daa9))
150
-
151
-
152
- ## v0.56.0 (2024-05-29)
153
-
154
- ### Documentation
155
-
156
- * docs(examples): example apps section deleted ([`ad208a5`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/ad208a5ef8495c45a8b83a4850ba9a1041b42717))
157
-
158
- ### Fix
159
-
160
- * fix(examples): outdated examples removed (mca_plot.py, stream_plot.py, motor_example.py) ([`ddc9510`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/ddc9510c2ba8dadf291809eeb5b135a105259492))
PKG-INFO CHANGED
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec_widgets
3
- Version: 0.57.7
3
+ Version: 0.58.1
4
4
  Summary: BEC Widgets
5
5
  Project-URL: Bug Tracker, https://gitlab.psi.ch/bec/bec_widgets/issues
6
6
  Project-URL: Homepage, https://gitlab.psi.ch/bec/bec_widgets
bec_widgets/cli/client.py CHANGED
@@ -753,7 +753,7 @@ class BECCurve(RPCBase):
753
753
  """
754
754
 
755
755
  @rpc_call
756
- def set_colormap(self, colormap: "str"):
756
+ def set_colormap_z(self, colormap: "str"):
757
757
  """
758
758
  Set the colormap for the scatter plot z gradient.
759
759
 
@@ -86,9 +86,10 @@ class JupyterConsoleWindow(QWidget): # pragma: no cover:
86
86
  self.console_layout.addWidget(self.console)
87
87
 
88
88
  def _init_figure(self):
89
- self.figure.plot(x_name="samx", y_name="bpm4d")
89
+ self.figure.plot(x_name="samx", y_name="samy", z_name="bpm4i", color_map_z="cividis")
90
90
  self.figure.motor_map("samx", "samy")
91
91
  self.figure.image("eiger", color_map="viridis", vrange=(0, 100))
92
+ self.figure.add_plot(x_name="samx", y_name="samy", z_name="bpm4i", color_map_z="magma")
92
93
 
93
94
  self.figure.change_layout(2, 2)
94
95
 
@@ -97,8 +98,6 @@ class JupyterConsoleWindow(QWidget): # pragma: no cover:
97
98
  self.w3 = self.figure[1, 0]
98
99
 
99
100
  # curves for w1
100
- self.w1.plot(x_name="samx", y_name="samy", z_name="bpm4i")
101
- self.w1.plot(x_name="samx", y_name="samy", z_name="bpm3a")
102
101
  self.c1 = self.w1.get_config()
103
102
 
104
103
  def _init_dock(self):
@@ -1,11 +1,14 @@
1
+ import re
1
2
  from typing import Literal
2
3
 
3
4
  import numpy as np
4
5
  import pyqtgraph as pg
6
+ from pydantic_core import PydanticCustomError
5
7
  from qtpy.QtGui import QColor
6
8
 
7
9
 
8
10
  class Colors:
11
+
9
12
  @staticmethod
10
13
  def golden_ratio(num: int) -> list:
11
14
  """Calculate the golden ratio for a given number of angles.
@@ -63,3 +66,211 @@ class Colors:
63
66
  else:
64
67
  raise ValueError("Unsupported format. Please choose 'RGB', 'HEX', or 'QColor'.")
65
68
  return colors
69
+
70
+ @staticmethod
71
+ def validate_color(color: tuple | str) -> tuple | str:
72
+ """
73
+ Validate the color input if it is HEX or RGBA compatible. Can be used in any pydantic model as a field validator.
74
+
75
+ Args:
76
+ color(tuple|str): The color to be validated. Can be a tuple of RGBA values or a HEX string.
77
+
78
+ Returns:
79
+ tuple|str: The validated color.
80
+ """
81
+ CSS_COLOR_NAMES = {
82
+ "aliceblue",
83
+ "antiquewhite",
84
+ "aqua",
85
+ "aquamarine",
86
+ "azure",
87
+ "beige",
88
+ "bisque",
89
+ "black",
90
+ "blanchedalmond",
91
+ "blue",
92
+ "blueviolet",
93
+ "brown",
94
+ "burlywood",
95
+ "cadetblue",
96
+ "chartreuse",
97
+ "chocolate",
98
+ "coral",
99
+ "cornflowerblue",
100
+ "cornsilk",
101
+ "crimson",
102
+ "cyan",
103
+ "darkblue",
104
+ "darkcyan",
105
+ "darkgoldenrod",
106
+ "darkgray",
107
+ "darkgreen",
108
+ "darkgrey",
109
+ "darkkhaki",
110
+ "darkmagenta",
111
+ "darkolivegreen",
112
+ "darkorange",
113
+ "darkorchid",
114
+ "darkred",
115
+ "darksalmon",
116
+ "darkseagreen",
117
+ "darkslateblue",
118
+ "darkslategray",
119
+ "darkslategrey",
120
+ "darkturquoise",
121
+ "darkviolet",
122
+ "deeppink",
123
+ "deepskyblue",
124
+ "dimgray",
125
+ "dimgrey",
126
+ "dodgerblue",
127
+ "firebrick",
128
+ "floralwhite",
129
+ "forestgreen",
130
+ "fuchsia",
131
+ "gainsboro",
132
+ "ghostwhite",
133
+ "gold",
134
+ "goldenrod",
135
+ "gray",
136
+ "green",
137
+ "greenyellow",
138
+ "grey",
139
+ "honeydew",
140
+ "hotpink",
141
+ "indianred",
142
+ "indigo",
143
+ "ivory",
144
+ "khaki",
145
+ "lavender",
146
+ "lavenderblush",
147
+ "lawngreen",
148
+ "lemonchiffon",
149
+ "lightblue",
150
+ "lightcoral",
151
+ "lightcyan",
152
+ "lightgoldenrodyellow",
153
+ "lightgray",
154
+ "lightgreen",
155
+ "lightgrey",
156
+ "lightpink",
157
+ "lightsalmon",
158
+ "lightseagreen",
159
+ "lightskyblue",
160
+ "lightslategray",
161
+ "lightslategrey",
162
+ "lightsteelblue",
163
+ "lightyellow",
164
+ "lime",
165
+ "limegreen",
166
+ "linen",
167
+ "magenta",
168
+ "maroon",
169
+ "mediumaquamarine",
170
+ "mediumblue",
171
+ "mediumorchid",
172
+ "mediumpurple",
173
+ "mediumseagreen",
174
+ "mediumslateblue",
175
+ "mediumspringgreen",
176
+ "mediumturquoise",
177
+ "mediumvioletred",
178
+ "midnightblue",
179
+ "mintcream",
180
+ "mistyrose",
181
+ "moccasin",
182
+ "navajowhite",
183
+ "navy",
184
+ "oldlace",
185
+ "olive",
186
+ "olivedrab",
187
+ "orange",
188
+ "orangered",
189
+ "orchid",
190
+ "palegoldenrod",
191
+ "palegreen",
192
+ "paleturquoise",
193
+ "palevioletred",
194
+ "papayawhip",
195
+ "peachpuff",
196
+ "peru",
197
+ "pink",
198
+ "plum",
199
+ "powderblue",
200
+ "purple",
201
+ "red",
202
+ "rosybrown",
203
+ "royalblue",
204
+ "saddlebrown",
205
+ "salmon",
206
+ "sandybrown",
207
+ "seagreen",
208
+ "seashell",
209
+ "sienna",
210
+ "silver",
211
+ "skyblue",
212
+ "slateblue",
213
+ "slategray",
214
+ "slategrey",
215
+ "snow",
216
+ "springgreen",
217
+ "steelblue",
218
+ "tan",
219
+ "teal",
220
+ "thistle",
221
+ "tomato",
222
+ "turquoise",
223
+ "violet",
224
+ "wheat",
225
+ "white",
226
+ "whitesmoke",
227
+ "yellow",
228
+ "yellowgreen",
229
+ }
230
+ if isinstance(color, str):
231
+ hex_pattern = re.compile(r"^#(?:[0-9a-fA-F]{3}){1,2}$")
232
+ if hex_pattern.match(color):
233
+ return color
234
+ elif color.lower() in CSS_COLOR_NAMES:
235
+ return color
236
+ else:
237
+ raise PydanticCustomError(
238
+ "unsupported color",
239
+ "The color must be a valid HEX string or CSS Color.",
240
+ {"wrong_value": color},
241
+ )
242
+ elif isinstance(color, tuple):
243
+ if len(color) != 4:
244
+ raise PydanticCustomError(
245
+ "unsupported color",
246
+ "The color must be a tuple of 4 elements (R, G, B, A).",
247
+ {"wrong_value": color},
248
+ )
249
+ for value in color:
250
+ if not 0 <= value <= 255:
251
+ raise PydanticCustomError(
252
+ "unsupported color",
253
+ f"The color values must be between 0 and 255 in RGBA format (R,G,B,A)",
254
+ {"wrong_value": color},
255
+ )
256
+ return color
257
+
258
+ @staticmethod
259
+ def validate_color_map(color_map: str) -> str:
260
+ """
261
+ Validate the colormap input if it is supported by pyqtgraph. Can be used in any pydantic model as a field validator. If validation fails it prints all available colormaps from pyqtgraph instance.
262
+
263
+ Args:
264
+ color_map(str): The colormap to be validated.
265
+
266
+ Returns:
267
+ str: The validated colormap.
268
+ """
269
+ available_colormaps = pg.colormap.listMaps()
270
+ if color_map not in available_colormaps:
271
+ raise PydanticCustomError(
272
+ "unsupported colormap",
273
+ f"Colormap '{color_map}' not found in the current installation of pyqtgraph. Choose on the following: {available_colormaps}.",
274
+ {"wrong_value": color_map},
275
+ )
276
+ return color_map
@@ -153,38 +153,6 @@ class BECDock(BECConnector, Dock):
153
153
  """
154
154
  return list(RPCWidgetHandler.widget_classes.keys())
155
155
 
156
- # def add_widget_bec(
157
- # self,
158
- # widget_type: str,
159
- # row=None,
160
- # col=0,
161
- # rowspan=1,
162
- # colspan=1,
163
- # shift: Literal["down", "up", "left", "right"] = "down",
164
- # ):
165
- # """
166
- # Add a widget to the dock.
167
- #
168
- # Args:
169
- # widget_type(str): The widget to add. Only BEC RPC widgets from RPCWidgetHandler are allowed.
170
- # row(int): The row to add the widget to. If None, the widget will be added to the next available row.
171
- # col(int): The column to add the widget to.
172
- # rowspan(int): The number of rows the widget should span.
173
- # colspan(int): The number of columns the widget should span.
174
- # shift(Literal["down", "up", "left", "right"]): The direction to shift the widgets if the position is occupied.
175
- # """
176
- # if row is None:
177
- # row = self.layout.rowCount()
178
- #
179
- # if self.layout_manager.is_position_occupied(row, col):
180
- # self.layout_manager.shift_widgets(shift, start_row=row)
181
- #
182
- # widget = RPCWidgetHandler.create_widget(widget_type)
183
- # self.addWidget(widget, row=row, col=col, rowspan=rowspan, colspan=colspan)
184
- # self.config.widgets[widget.gui_id] = widget.config
185
- #
186
- # return widget
187
-
188
156
  def add_widget(
189
157
  self,
190
158
  widget: BECConnector | str,
@@ -137,6 +137,7 @@ class BECDockArea(BECConnector, DockArea):
137
137
  position: Literal["bottom", "top", "left", "right", "above", "below"] = None,
138
138
  relative_to: BECDock | None = None,
139
139
  closable: bool = False,
140
+ floating: bool = False,
140
141
  prefix: str = "dock",
141
142
  widget: str | QWidget | None = None,
142
143
  row: int = None,
@@ -152,6 +153,7 @@ class BECDockArea(BECConnector, DockArea):
152
153
  position(Literal["bottom", "top", "left", "right", "above", "below"]): The position of the dock.
153
154
  relative_to(BECDock): The dock to which the new dock should be added relative to.
154
155
  closable(bool): Whether the dock is closable.
156
+ floating(bool): Whether the dock is detached after creating.
155
157
  prefix(str): The prefix for the dock name if no name is provided.
156
158
  widget(str|QWidget|None): The widget to be added to the dock. While using RPC, only BEC RPC widgets from RPCWidgetHandler are allowed.
157
159
  row(int): The row of the added widget.
@@ -192,6 +194,8 @@ class BECDockArea(BECConnector, DockArea):
192
194
  if self._instructions_visible:
193
195
  self._instructions_visible = False
194
196
  self.update()
197
+ if floating:
198
+ dock.detach()
195
199
  return dock
196
200
 
197
201
  def detach_dock(self, dock_name: str) -> BECDock:
@@ -364,7 +364,7 @@ class BECWaveform(BECPlotBase):
364
364
  parent_id=self.gui_id,
365
365
  label=label,
366
366
  color=color,
367
- color_map=color_map_z,
367
+ color_map_z=color_map_z,
368
368
  source=curve_source,
369
369
  signals=Signal(
370
370
  source=curve_source,
@@ -396,7 +396,7 @@ class BECWaveform(BECPlotBase):
396
396
  Returns:
397
397
  BECCurve: The curve object.
398
398
  """
399
- curve = BECCurve(config=config, name=name, parent_item=self.plot_item)
399
+ curve = BECCurve(config=config, name=name, parent_item=self)
400
400
  self._curves_data[source][name] = curve
401
401
  self.plot_item.addItem(curve)
402
402
  self.config.curves[name] = curve.config
@@ -564,7 +564,7 @@ class BECWaveform(BECPlotBase):
564
564
  if curve.config.signals.z:
565
565
  data_z = data[z_name][z_entry].val
566
566
  color_z = self._make_z_gradient(
567
- data_z, curve.config.colormap
567
+ data_z, curve.config.color_map_z
568
568
  ) # TODO decide how to implement custom gradient
569
569
  except TypeError:
570
570
  continue
@@ -1,12 +1,16 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import Any, Literal, Optional
3
+ from typing import TYPE_CHECKING, Any, Literal, Optional
4
4
 
5
5
  import pyqtgraph as pg
6
- from pydantic import BaseModel, Field
6
+ from pydantic import BaseModel, Field, field_validator
7
+ from pydantic_core import PydanticCustomError
7
8
  from qtpy import QtCore
8
9
 
9
- from bec_widgets.utils import BECConnector, ConnectionConfig
10
+ from bec_widgets.utils import BECConnector, Colors, ConnectionConfig
11
+
12
+ if TYPE_CHECKING:
13
+ from bec_widgets.widgets.figure.plots.waveform import BECWaveform1D
10
14
 
11
15
 
12
16
  class SignalData(BaseModel):
@@ -33,9 +37,11 @@ class Signal(BaseModel):
33
37
  class CurveConfig(ConnectionConfig):
34
38
  parent_id: Optional[str] = Field(None, description="The parent plot of the curve.")
35
39
  label: Optional[str] = Field(None, description="The label of the curve.")
36
- color: Optional[Any] = Field(None, description="The color of the curve.")
40
+ color: Optional[str | tuple] = Field(None, description="The color of the curve.")
37
41
  symbol: Optional[str] = Field("o", description="The symbol of the curve.")
38
- symbol_color: Optional[str] = Field(None, description="The color of the symbol of the curve.")
42
+ symbol_color: Optional[str | tuple] = Field(
43
+ None, description="The color of the symbol of the curve."
44
+ )
39
45
  symbol_size: Optional[int] = Field(5, description="The size of the symbol of the curve.")
40
46
  pen_width: Optional[int] = Field(2, description="The width of the pen of the curve.")
41
47
  pen_style: Optional[Literal["solid", "dash", "dot", "dashdot"]] = Field(
@@ -43,7 +49,15 @@ class CurveConfig(ConnectionConfig):
43
49
  )
44
50
  source: Optional[str] = Field(None, description="The source of the curve.")
45
51
  signals: Optional[Signal] = Field(None, description="The signal of the curve.")
46
- colormap: Optional[str] = Field("plasma", description="The colormap of the curves z gradient.")
52
+ color_map_z: Optional[str] = Field(
53
+ "plasma", description="The colormap of the curves z gradient.", validate_default=True
54
+ )
55
+
56
+ model_config: dict = {"validate_assignment": True}
57
+
58
+ _validate_color_map_z = field_validator("color_map_z")(Colors.validate_color_map)
59
+ _validate_color = field_validator("color")(Colors.validate_color)
60
+ _validate_symbol_color = field_validator("symbol_color")(Colors.validate_color)
47
61
 
48
62
 
49
63
  class BECCurve(BECConnector, pg.PlotDataItem):
@@ -54,7 +68,7 @@ class BECCurve(BECConnector, pg.PlotDataItem):
54
68
  "set",
55
69
  "set_data",
56
70
  "set_color",
57
- "set_colormap",
71
+ "set_colormap_z",
58
72
  "set_symbol",
59
73
  "set_symbol_color",
60
74
  "set_symbol_size",
@@ -68,7 +82,7 @@ class BECCurve(BECConnector, pg.PlotDataItem):
68
82
  name: Optional[str] = None,
69
83
  config: Optional[CurveConfig] = None,
70
84
  gui_id: Optional[str] = None,
71
- parent_item: Optional[pg.PlotItem] = None,
85
+ parent_item: Optional[BECWaveform1D] = None,
72
86
  **kwargs,
73
87
  ):
74
88
  if config is None:
@@ -130,7 +144,7 @@ class BECCurve(BECConnector, pg.PlotDataItem):
130
144
  # Mapping of keywords to setter methods
131
145
  method_map = {
132
146
  "color": self.set_color,
133
- "colormap": self.set_colormap,
147
+ "color_map_z": self.set_color_map_z,
134
148
  "symbol": self.set_symbol,
135
149
  "symbol_color": self.set_symbol_color,
136
150
  "symbol_size": self.set_symbol_size,
@@ -205,14 +219,16 @@ class BECCurve(BECConnector, pg.PlotDataItem):
205
219
  self.config.pen_style = pen_style
206
220
  self.apply_config()
207
221
 
208
- def set_colormap(self, colormap: str):
222
+ def set_color_map_z(self, colormap: str):
209
223
  """
210
224
  Set the colormap for the scatter plot z gradient.
211
225
 
212
226
  Args:
213
227
  colormap(str): Colormap for the scatter plot.
214
228
  """
215
- self.config.colormap = colormap
229
+ self.config.color_map_z = colormap
230
+ self.apply_config()
231
+ self.parent_item.scan_history(-1)
216
232
 
217
233
  def get_data(self) -> tuple[np.ndarray, np.ndarray]:
218
234
  """
@@ -15,7 +15,9 @@ from bec_widgets.widgets.spiral_progress_bar.ring import Ring, RingConfig
15
15
 
16
16
 
17
17
  class SpiralProgressBarConfig(ConnectionConfig):
18
- color_map: str | None = Field("magma", description="Color scheme for the progress bars.")
18
+ color_map: Optional[str] = Field(
19
+ "magma", description="Color scheme for the progress bars.", validate_default=True
20
+ )
19
21
  min_number_of_bars: int | None = Field(
20
22
  1, description="Minimum number of progress bars to display."
21
23
  )
@@ -59,16 +61,7 @@ class SpiralProgressBarConfig(ConnectionConfig):
59
61
  )
60
62
  return v
61
63
 
62
- @field_validator("color_map")
63
- def validate_color_map(cls, v, values):
64
- if v is not None and v != "":
65
- if v not in pg.colormap.listMaps():
66
- raise PydanticCustomError(
67
- "unsupported colormap",
68
- f"Colormap '{v}' not found in the current installation of pyqtgraph",
69
- {"wrong_value": v},
70
- )
71
- return v
64
+ _validate_colormap = field_validator("color_map")(Colors.validate_color_map)
72
65
 
73
66
 
74
67
  class SpiralProgressBar(BECConnector, QWidget):
@@ -368,7 +361,6 @@ class SpiralProgressBar(BECConnector, QWidget):
368
361
  colors = self._adjust_list_to_bars(colors)
369
362
  for ring, color in zip(self._rings, colors):
370
363
  ring.set_color(color)
371
- self.config.color_map = None
372
364
  self.update()
373
365
 
374
366
  def set_line_widths(self, widths: int | list[int], bar_index: int = None):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec_widgets
3
- Version: 0.57.7
3
+ Version: 0.58.1
4
4
  Summary: BEC Widgets
5
5
  Project-URL: Bug Tracker, https://gitlab.psi.ch/bec/bec_widgets/issues
6
6
  Project-URL: Homepage, https://gitlab.psi.ch/bec/bec_widgets
@@ -2,11 +2,11 @@
2
2
  .gitlab-ci.yml,sha256=RF2JeGh8tG09DyAOwEu991IZy3C8Vm6lI8O_4Dr9B9Q,12239
3
3
  .pylintrc,sha256=OstrgmEyP0smNFBKoIN5_26-UmNZgMHnbjvAWX0UrLs,18535
4
4
  .readthedocs.yaml,sha256=aSOc277LqXcsTI6lgvm_JY80lMlr69GbPKgivua2cS0,603
5
- CHANGELOG.md,sha256=X9H-BklqBJf16uGegYy57e9XnyvJMb5ogZs3K0ymAqc,7072
5
+ CHANGELOG.md,sha256=F3oE4DHkbux-acWCO5g04vsozT6PFW8O8QuHatjak50,6887
6
6
  LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
7
- PKG-INFO,sha256=c40eu7rvlul5AMf-lodtHO4hJ3auFJg22eqkir9PYpE,1178
7
+ PKG-INFO,sha256=Wp-jNfe3gv_ps9mcKGp_pyG5CW3_-47xzLQopZWKblo,1178
8
8
  README.md,sha256=y4jB6wvArS7N8_iTbKWnSM_oRAqLA2GqgzUR-FMh5sU,2645
9
- pyproject.toml,sha256=6xrwVPUUPoFrPwURWqR8v6Kr5XAsx8hXChcpP4F3ayg,1822
9
+ pyproject.toml,sha256=gevJbxgjyaxZhW9okMre-0DdthcX1iulEUjhV1r3Si4,1822
10
10
  .git_hooks/pre-commit,sha256=n3RofIZHJl8zfJJIUomcMyYGFi_rwq4CC19z0snz3FI,286
11
11
  .gitlab/issue_templates/bug_report_template.md,sha256=gAuyEwl7XlnebBrkiJ9AqffSNOywmr8vygUFWKTuQeI,386
12
12
  .gitlab/issue_templates/documentation_update_template.md,sha256=FHLdb3TS_D9aL4CYZCjyXSulbaW5mrN2CmwTaeLPbNw,860
@@ -17,7 +17,7 @@ bec_widgets/assets/bec_widgets_icon.png,sha256=K8dgGwIjalDh9PRHUsSQBqgdX7a00nM3i
17
17
  bec_widgets/assets/terminal_icon.png,sha256=bJl7Tft4Fi2uxvuXI8o14uMHnI9eAWKSU2uftXCH9ws,3889
18
18
  bec_widgets/cli/__init__.py,sha256=tLD8HWgyURhMjYlKZ43pBu-qvGD1LI5o3n3rEieg-70,43
19
19
  bec_widgets/cli/auto_updates.py,sha256=0sd7HiqOMn1jCbgVG3-H1nmQgdOMRwSjx6FAvdtVf1k,4747
20
- bec_widgets/cli/client.py,sha256=3GiSipBcjFvQunvevSgxGgriK1dslqpu-0A5WWFN_fA,55076
20
+ bec_widgets/cli/client.py,sha256=wSKL4tw6g4Q2gQeHEGv_6_4W5L8kfJk3BQ4pBv05cFg,55078
21
21
  bec_widgets/cli/client_utils.py,sha256=7u8P9EYgLPJuAcHxnFiZi-gCZohO3vAn0W7dqsSrs4M,10660
22
22
  bec_widgets/cli/generate_cli.py,sha256=tBt-F4Xccg9Pj2zuDEGHd0Ho1fKLfCf3PuSa8KmelQk,4431
23
23
  bec_widgets/cli/rpc_register.py,sha256=QxXUZu5XNg00Yf5O3UHWOXg3-f_pzKjjoZYMOa-MOJc,2216
@@ -25,7 +25,7 @@ bec_widgets/cli/rpc_wigdet_handler.py,sha256=OXHoiDFJPzbQ5RO0bzIX5aUXeMMlJTwAiTm
25
25
  bec_widgets/cli/server.py,sha256=rsj31Vsx6ayThNe4PQelQFahGjYXFZjfrNyB2fnm6Ro,5737
26
26
  bec_widgets/examples/__init__.py,sha256=WWQ0cu7m8sA4Ehy-DWdTIqSISjaHsbxhsNmNrMnhDZU,202
27
27
  bec_widgets/examples/jupyter_console/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
- bec_widgets/examples/jupyter_console/jupyter_console_window.py,sha256=Rnr6bO-cue1AuT5IyUsBw5gXGeyuEQFqLpA1sx_-Kcs,5339
28
+ bec_widgets/examples/jupyter_console/jupyter_console_window.py,sha256=lViKNC3TOh6_-SztcKaRnYkf-V_EQ9T1cuyORskVX6c,5339
29
29
  bec_widgets/examples/jupyter_console/jupyter_console_window.ui,sha256=2A2mNTUMZBYygz8K4qWzrcjnNqZBMVyeHm26iLZVRWI,1473
30
30
  bec_widgets/examples/motor_movement/__init__.py,sha256=LzPJkxLAxOsZCbXR-fRCPmeYobp7Yqds6tDxW4W1gSw,214
31
31
  bec_widgets/examples/motor_movement/motor_control_compilations.py,sha256=8rpA7a2xVZTDMrx7YQIj3IJew78J1gcVMkHvloS0U_Q,9055
@@ -34,7 +34,7 @@ bec_widgets/utils/__init__.py,sha256=B7OZ2ArjyFaGNh4XYIbk49agnYCz704ltuFSalLCjSA
34
34
  bec_widgets/utils/bec_connector.py,sha256=CLrf30dW-0iYiQo4cwH7qSfsog-1ypfKMjQxJJjKpmw,5340
35
35
  bec_widgets/utils/bec_dispatcher.py,sha256=nLdcj2u4dy8-ZR03XioCzr7hBg9Wq4Kw58OU6sDorT4,5593
36
36
  bec_widgets/utils/bec_table.py,sha256=nA2b8ukSeUfquFMAxGrUVOqdrzMoDYD6O_4EYbOG2zk,717
37
- bec_widgets/utils/colors.py,sha256=JsLxzkxbw-I8GIuvnIKyiM83n0edhyMG2Fa4Ffm62ww,2392
37
+ bec_widgets/utils/colors.py,sha256=GYSDe0ZxsJSwxvuy-yG2BH17qlf_Sjq8dhDcyp9IhBI,8532
38
38
  bec_widgets/utils/container_utils.py,sha256=m3VUyAYmSWkEwApP9tBvKxPYVtc2kHw4toxIpMryJy4,1495
39
39
  bec_widgets/utils/crosshair.py,sha256=SubY4FQCI6vUKsmMYGKHR7uYdGQJ6vhoYLuC1XlKS9I,9626
40
40
  bec_widgets/utils/entry_validator.py,sha256=IqmtResXQtnmMvWVSl8IrnggqSzXLp4cSggn6WdSTpE,1298
@@ -48,8 +48,8 @@ bec_widgets/utils/widget_io.py,sha256=f36198CvT_EzWQ_cg2G-4tRRsaMdJ3yVqsZWKJCQEf
48
48
  bec_widgets/utils/yaml_dialog.py,sha256=cMVif-39SB9WjwGH5FWBJcFs4tnfFJFs5cacydRyhy0,1853
49
49
  bec_widgets/widgets/__init__.py,sha256=LKgIuY3CI-NHCa_bY9pThYhxLH0MHDo8iNEJDDVIVmw,172
50
50
  bec_widgets/widgets/dock/__init__.py,sha256=B7foHt02gnhM7mFksa7GJVwT7n0j_JvYDCt6wc6XR5g,61
51
- bec_widgets/widgets/dock/dock.py,sha256=HCr0MeXljzIFOSuHuWfTz_B5str03pjkKXPX8PCrJ9c,9010
52
- bec_widgets/widgets/dock/dock_area.py,sha256=zupu05KHrrdUlNNQe-x9zC-bXDk-qPXvr_mONCm-JwI,7759
51
+ bec_widgets/widgets/dock/dock.py,sha256=npSJijKdaPZk6T4LrWQ-Q8PfJMgIniqo1UYLahPowA0,7695
52
+ bec_widgets/widgets/dock/dock_area.py,sha256=9c_tLzyBRllLfc4H5o9-4bvasWp5hWe1NWg4mupXVtU,7911
53
53
  bec_widgets/widgets/figure/__init__.py,sha256=3hGx_KOV7QHCYAV06aNuUgKq4QIYCjUTad-DrwkUaBM,44
54
54
  bec_widgets/widgets/figure/figure.py,sha256=O--r3dyeOPXndV2400wpE9lPdBezzd0ZUt7yA2u2n0A,31468
55
55
  bec_widgets/widgets/figure/plots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -61,8 +61,8 @@ bec_widgets/widgets/figure/plots/image/image_processor.py,sha256=TOnHbdq9rK5--L5
61
61
  bec_widgets/widgets/figure/plots/motor_map/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
62
62
  bec_widgets/widgets/figure/plots/motor_map/motor_map.py,sha256=Ff2WoNHxO_A3ggsbSd_AVUP1JeOWMuJs-0GLskxn-94,15267
63
63
  bec_widgets/widgets/figure/plots/waveform/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
- bec_widgets/widgets/figure/plots/waveform/waveform.py,sha256=DgnUdH3wj0uyvZvK9jqdDKaRwPoadf14VZ4g1TOXY5A,23511
65
- bec_widgets/widgets/figure/plots/waveform/waveform_curve.py,sha256=Ynvgbc202TXaeAUkHyGYWmRBcDD2Wx5dTRyd9HjVE3o,7339
64
+ bec_widgets/widgets/figure/plots/waveform/waveform.py,sha256=xJkBsl1FIWBWsGaC_7nTy44ztp4xaJX-uAYU0MmV7Oc,23506
65
+ bec_widgets/widgets/figure/plots/waveform/waveform_curve.py,sha256=gFXt6v4P-kHterXUqkZx0eofWlYHxo32I8Kh0zYDLik,7969
66
66
  bec_widgets/widgets/jupyter_console/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
67
  bec_widgets/widgets/jupyter_console/jupyter_console.py,sha256=ioLYJL31RdBoAOGFSS8PVSnUhkWPWmLC3tiKp7CouO8,2251
68
68
  bec_widgets/widgets/motor_control/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -83,7 +83,7 @@ bec_widgets/widgets/scan_control/__init__.py,sha256=IOfHl15vxb_uC6KN62-PeUzbBha_
83
83
  bec_widgets/widgets/scan_control/scan_control.py,sha256=B5n2U2iVtTCY3Tx93JyBqzGCDCmWhWwAOhbPelLI-bs,17168
84
84
  bec_widgets/widgets/spiral_progress_bar/__init__.py,sha256=4efbtcqCToMIw5bkQrTzy2TzuBCXvlhuUPh1bYC_Yzg,51
85
85
  bec_widgets/widgets/spiral_progress_bar/ring.py,sha256=7i5oKpW8eUQGvLyKce2-2rlaGDVLec__DoWp6hfJlRw,10524
86
- bec_widgets/widgets/spiral_progress_bar/spiral_progress_bar.py,sha256=OQzJiR0Fd4fWop4ojykEKtXVqeLL0WLNSBdhf7JvLsc,24386
86
+ bec_widgets/widgets/spiral_progress_bar/spiral_progress_bar.py,sha256=cMi4g7zNTLrkkzZ9ChiIBTaqigDCYwzrgA2iRmq9dUI,24050
87
87
  bec_widgets/widgets/toolbar/__init__.py,sha256=d-TP4_cr_VbpwreMM4ePnfZ5YXsEPQ45ibEf75nuGoE,36
88
88
  bec_widgets/widgets/toolbar/toolbar.py,sha256=e0zCD_0q7K4NVhrzD8001Qvfxt-VhqHTgofchS9NgCM,5125
89
89
  docs/Makefile,sha256=i2WHuFlgfyAPEW4ssEP8NY4cOibDJrVjvzSEU8_Ggwc,634
@@ -138,6 +138,7 @@ tests/unit_tests/test_bec_dock.py,sha256=x1mgeNvgu9yVuZvgUkfD60F7FLANGQsXSBhF3n8
138
138
  tests/unit_tests/test_bec_figure.py,sha256=xYAftY8bI_EH-SlNPD0Tjd7FS_47ouZ1E4hrpjPt7O4,8002
139
139
  tests/unit_tests/test_bec_motor_map.py,sha256=AfD_9-x6VV3TPnkQgNfFYRndPHDsGx-a_YknFeDr6hc,4588
140
140
  tests/unit_tests/test_client_utils.py,sha256=eViJ1Tz-HX9TkMvQH6W8cO-c3_1I8bUc4_Yen6LOc0E,830
141
+ tests/unit_tests/test_color_validation.py,sha256=csdvVKAohENZIRY-JQ97Hv-TShb1erj4oKMX7QRwo78,1883
141
142
  tests/unit_tests/test_crosshair.py,sha256=3OMAJ2ZaISYXMOtkXf1rPdy94vCr8njeLi6uHblBL9Q,5045
142
143
  tests/unit_tests/test_generate_cli_client.py,sha256=J7CFoO67txGu_u1Mwk32EejRX204FRuvmVg_yhAr1WM,2397
143
144
  tests/unit_tests/test_motor_control.py,sha256=NBekcGALo5mYkuyBJvBhvJkWiQDV82hI4GmsobRzjTI,20770
@@ -145,7 +146,7 @@ tests/unit_tests/test_plot_base.py,sha256=bOdlgAxh9oKk5PwiQ_MSFmzr44uJ61Tlg242RC
145
146
  tests/unit_tests/test_rpc_register.py,sha256=hECjZEimd440mwRrO0rg7L3PKN7__3DgjmESN6wx3bo,1179
146
147
  tests/unit_tests/test_scan_control.py,sha256=7dtGpE0g4FqUhhQeCkyJl-9o7NH3DFZJgEaqDmBYbBc,7551
147
148
  tests/unit_tests/test_spiral_progress_bar.py,sha256=yak3N9-TmEM3lQZPSROL4cAx9mior__se1XADlMScks,12418
148
- tests/unit_tests/test_waveform1d.py,sha256=Xi9TdZmxoMmmje37lq03FG9lytEdZCTUEjtOC0LvZjA,15263
149
+ tests/unit_tests/test_waveform1d.py,sha256=j9-CCE0BkFVI3Gnv8pjV1gc9HwA5PYG0_ox1oZ60F6w,15272
149
150
  tests/unit_tests/test_widget_io.py,sha256=FeL3ZYSBQnRt6jxj8VGYw1cmcicRQyHKleahw7XIyR0,3475
150
151
  tests/unit_tests/test_yaml_dialog.py,sha256=HNrqferkdg02-9ieOhhI2mr2Qvt7GrYgXmQ061YCTbg,5794
151
152
  tests/unit_tests/test_configs/config_device.yaml,sha256=h3zNb5ZaT_sA59Sf-24qsXs54MgUsspo-GOJmKWHx3o,695
@@ -153,7 +154,7 @@ tests/unit_tests/test_configs/config_device_no_entry.yaml,sha256=hdvue9KLc_kfNzG
153
154
  tests/unit_tests/test_configs/config_scan.yaml,sha256=vo484BbWOjA_e-h6bTjSV9k7QaQHrlAvx-z8wtY-P4E,1915
154
155
  tests/unit_tests/test_msgs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
155
156
  tests/unit_tests/test_msgs/available_scans_message.py,sha256=m_z97hIrjHXXMa2Ex-UvsPmTxOYXfjxyJaGkIY6StTY,46532
156
- bec_widgets-0.57.7.dist-info/METADATA,sha256=c40eu7rvlul5AMf-lodtHO4hJ3auFJg22eqkir9PYpE,1178
157
- bec_widgets-0.57.7.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
158
- bec_widgets-0.57.7.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
159
- bec_widgets-0.57.7.dist-info/RECORD,,
157
+ bec_widgets-0.58.1.dist-info/METADATA,sha256=Wp-jNfe3gv_ps9mcKGp_pyG5CW3_-47xzLQopZWKblo,1178
158
+ bec_widgets-0.58.1.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
159
+ bec_widgets-0.58.1.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
160
+ bec_widgets-0.58.1.dist-info/RECORD,,
pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "bec_widgets"
7
- version = "0.57.7"
7
+ version = "0.58.1"
8
8
  description = "BEC Widgets"
9
9
  requires-python = ">=3.10"
10
10
  classifiers = [
@@ -0,0 +1,60 @@
1
+ import pytest
2
+ from pydantic import ValidationError
3
+
4
+ from bec_widgets.utils import Colors
5
+ from bec_widgets.widgets.figure.plots.waveform.waveform_curve import CurveConfig
6
+
7
+
8
+ def test_color_validation_CSS():
9
+ # Test valid color
10
+ color = Colors.validate_color("teal")
11
+ assert color == "teal"
12
+
13
+ # Test invalid color
14
+ with pytest.raises(ValidationError) as excinfo:
15
+ CurveConfig(color="invalid_color")
16
+
17
+ errors = excinfo.value.errors()
18
+ assert len(errors) == 1
19
+ assert errors[0]["type"] == ("unsupported color")
20
+ assert "The color must be a valid HEX string or CSS Color." in str(excinfo.value)
21
+
22
+
23
+ def test_color_validation_hex():
24
+ # Test valid color
25
+ color = Colors.validate_color("#ff0000")
26
+ assert color == "#ff0000"
27
+
28
+ # Test invalid color
29
+ with pytest.raises(ValidationError) as excinfo:
30
+ CurveConfig(color="#ff00000")
31
+
32
+ errors = excinfo.value.errors()
33
+ assert len(errors) == 1
34
+ assert errors[0]["type"] == ("unsupported color")
35
+ assert "The color must be a valid HEX string or CSS Color." in str(excinfo.value)
36
+
37
+
38
+ def test_color_validation_RGBA():
39
+ # Test valid color
40
+ color = Colors.validate_color((255, 0, 0, 255))
41
+ assert color == (255, 0, 0, 255)
42
+
43
+ # Test invalid color
44
+ with pytest.raises(ValidationError) as excinfo:
45
+ CurveConfig(color=(255, 0, 0))
46
+
47
+ errors = excinfo.value.errors()
48
+ assert len(errors) == 1
49
+ assert errors[0]["type"] == ("unsupported color")
50
+ assert "The color must be a tuple of 4 elements (R, G, B, A)." in str(excinfo.value)
51
+
52
+ with pytest.raises(ValidationError) as excinfo:
53
+ CurveConfig(color=(255, 0, 0, 355))
54
+
55
+ errors = excinfo.value.errors()
56
+ assert len(errors) == 1
57
+ assert errors[0]["type"] == ("unsupported color")
58
+ assert "The color values must be between 0 and 255 in RGBA format (R,G,B,A)" in str(
59
+ excinfo.value
60
+ )
@@ -73,7 +73,7 @@ def test_create_waveform1D_by_config(bec_figure):
73
73
  "parent_id": "widget_1",
74
74
  "label": "bpm4i-bpm4i",
75
75
  "color": "#cc4778",
76
- "colormap": "plasma",
76
+ "color_map_z": "plasma",
77
77
  "symbol": "o",
78
78
  "symbol_color": None,
79
79
  "symbol_size": 5,
@@ -105,7 +105,7 @@ def test_create_waveform1D_by_config(bec_figure):
105
105
  "parent_id": "widget_1",
106
106
  "label": "curve-custom",
107
107
  "color": "blue",
108
- "colormap": "plasma",
108
+ "color_map_z": "plasma",
109
109
  "symbol": "o",
110
110
  "symbol_color": None,
111
111
  "symbol_size": 5,
@@ -360,7 +360,7 @@ def test_curve_add_by_config(bec_figure):
360
360
  "parent_id": "widget_1",
361
361
  "label": "bpm4i-bpm4i",
362
362
  "color": "#cc4778",
363
- "colormap": "plasma",
363
+ "color_map_z": "plasma",
364
364
  "symbol": "o",
365
365
  "symbol_color": None,
366
366
  "symbol_size": 5,