bec-widgets 1.1.0__py3-none-any.whl → 1.2.0__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
@@ -1,6 +1,17 @@
1
1
  # CHANGELOG
2
2
 
3
3
 
4
+ ## v1.2.0 (2024-10-25)
5
+
6
+ ### Features
7
+
8
+ * feat(colors): evenly spaced color generation + new golden ratio calculation ([`40c9fea`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/40c9fea35f869ef52e05948dd1989bcd99f602e0))
9
+
10
+ ### Refactoring
11
+
12
+ * refactor: add bec_lib version to statusbox ([`5d4b86e`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/5d4b86e1c6e1800051afce4f991153e370767fa6))
13
+
14
+
4
15
  ## v1.1.0 (2024-10-25)
5
16
 
6
17
  ### Features
@@ -158,18 +169,3 @@ complete UI ([`49268e3`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/49268e38
158
169
  * fix: use new 'scan_axis' signal, to set_x and select x axis on waveform
159
170
 
160
171
  Fixes #361, do not try to change x axis when not permitted ([`efa2763`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/efa276358b0f5a45cce9fa84fa5f9aafaf4284f7))
161
-
162
- ### Features
163
-
164
- * feat: new 'scan_axis' signal
165
-
166
- Signal is emitted before "scan_started", to inform about scan positioner
167
- and (start, stop) positions. In case of multiple bundles, the signal
168
- is emitted multiple times. ([`f084e25`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/f084e2514bc9459cccaa951b79044bc25884e738))
169
-
170
-
171
- ## v0.113.0 (2024-10-02)
172
-
173
- ### Testing
174
-
175
- * test: add tests for scan_status_callback ([`dc0c825`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/dc0c825fd594c093a24543ff803d6c6564010e92))
PKG-INFO CHANGED
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec_widgets
3
- Version: 1.1.0
3
+ Version: 1.2.0
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
@@ -107,9 +107,98 @@ class Colors:
107
107
  angles.append(angle)
108
108
  return angles
109
109
 
110
+ @staticmethod
111
+ def set_theme_offset(theme: Literal["light", "dark"] | None = None, offset=0.2) -> tuple:
112
+ """
113
+ Set the theme offset to avoid colors too close to white or black with light or dark theme respectively for pyqtgraph plot background.
114
+
115
+ Args:
116
+ theme(str): The theme to be applied.
117
+ offset(float): Offset to avoid colors too close to white or black with light or dark theme respectively for pyqtgraph plot background.
118
+
119
+ Returns:
120
+ tuple: Tuple of min_pos and max_pos.
121
+
122
+ Raises:
123
+ ValueError: If theme_offset is not between 0 and 1.
124
+ """
125
+
126
+ if offset < 0 or offset > 1:
127
+ raise ValueError("theme_offset must be between 0 and 1")
128
+
129
+ if theme is None:
130
+ app = QApplication.instance()
131
+ if hasattr(app, "theme"):
132
+ theme = app.theme.theme
133
+
134
+ if theme == "light":
135
+ min_pos = 0.0
136
+ max_pos = 1 - offset
137
+ else:
138
+ min_pos = 0.0 + offset
139
+ max_pos = 1.0
140
+
141
+ return min_pos, max_pos
142
+
143
+ @staticmethod
144
+ def evenly_spaced_colors(
145
+ colormap: str,
146
+ num: int,
147
+ format: Literal["QColor", "HEX", "RGB"] = "QColor",
148
+ theme_offset=0.2,
149
+ theme: Literal["light", "dark"] | None = None,
150
+ ) -> list:
151
+ """
152
+ Extract `num` colors from the specified colormap, evenly spaced along its range,
153
+ and return them in the specified format.
154
+
155
+ Args:
156
+ colormap (str): Name of the colormap.
157
+ num (int): Number of requested colors.
158
+ format (Literal["QColor","HEX","RGB"]): The format of the returned colors ('RGB', 'HEX', 'QColor').
159
+ theme_offset (float): Has to be between 0-1. Offset to avoid colors too close to white or black with light or dark theme respectively for pyqtgraph plot background.
160
+ theme (Literal['light', 'dark'] | None): The theme to be applied. Overrides the QApplication theme if specified.
161
+
162
+ Returns:
163
+ list: List of colors in the specified format.
164
+
165
+ Raises:
166
+ ValueError: If theme_offset is not between 0 and 1.
167
+ """
168
+ if theme_offset < 0 or theme_offset > 1:
169
+ raise ValueError("theme_offset must be between 0 and 1")
170
+
171
+ cmap = pg.colormap.get(colormap)
172
+ min_pos, max_pos = Colors.set_theme_offset(theme, theme_offset)
173
+
174
+ # Generate positions that are evenly spaced within the acceptable range
175
+ if num == 1:
176
+ positions = np.array([(min_pos + max_pos) / 2])
177
+ else:
178
+ positions = np.linspace(min_pos, max_pos, num)
179
+
180
+ # Sample colors from the colormap at the calculated positions
181
+ colors = cmap.map(positions, mode="float")
182
+ color_list = []
183
+
184
+ for color in colors:
185
+ if format.upper() == "HEX":
186
+ color_list.append(QColor.fromRgbF(*color).name())
187
+ elif format.upper() == "RGB":
188
+ color_list.append(tuple((np.array(color) * 255).astype(int)))
189
+ elif format.upper() == "QCOLOR":
190
+ color_list.append(QColor.fromRgbF(*color))
191
+ else:
192
+ raise ValueError("Unsupported format. Please choose 'RGB', 'HEX', or 'QColor'.")
193
+ return color_list
194
+
110
195
  @staticmethod
111
196
  def golden_angle_color(
112
- colormap: str, num: int, format: Literal["QColor", "HEX", "RGB"] = "QColor"
197
+ colormap: str,
198
+ num: int,
199
+ format: Literal["QColor", "HEX", "RGB"] = "QColor",
200
+ theme_offset=0.2,
201
+ theme: Literal["dark", "light"] | None = None,
113
202
  ) -> list:
114
203
  """
115
204
  Extract num colors from the specified colormap following golden angle distribution and return them in the specified format.
@@ -118,45 +207,39 @@ class Colors:
118
207
  colormap (str): Name of the colormap.
119
208
  num (int): Number of requested colors.
120
209
  format (Literal["QColor","HEX","RGB"]): The format of the returned colors ('RGB', 'HEX', 'QColor').
210
+ theme_offset (float): Has to be between 0-1. Offset to avoid colors too close to white or black with light or dark theme respectively for pyqtgraph plot background.
121
211
 
122
212
  Returns:
123
213
  list: List of colors in the specified format.
124
214
 
125
215
  Raises:
126
- ValueError: If the number of requested colors is greater than the number of colors in the colormap.
216
+ ValueError: If theme_offset is not between 0 and 1.
127
217
  """
218
+
128
219
  cmap = pg.colormap.get(colormap)
129
- cmap_colors = cmap.getColors(mode="float")
130
- if num > len(cmap_colors):
131
- raise ValueError(
132
- f"Number of colors requested ({num}) is greater than the number of colors in the colormap ({len(cmap_colors)})"
133
- )
134
- angles = Colors.golden_ratio(len(cmap_colors))
135
- color_selection = np.round(np.interp(angles, (-np.pi, np.pi), (0, len(cmap_colors))))
136
- colors = []
137
- ii = 0
138
- while len(colors) < num:
139
- color_index = int(color_selection[ii])
140
- color = cmap_colors[color_index]
141
- app = QApplication.instance()
142
- if hasattr(app, "theme") and app.theme.theme == "light":
143
- background = 255
144
- else:
145
- background = 0
146
- if np.abs(np.mean(color[:3] * 255) - background) < 50:
147
- ii += 1
148
- continue
220
+ phi = (1 + np.sqrt(5)) / 2 # Golden ratio
221
+ golden_angle_conjugate = 1 - (1 / phi) # Approximately 0.38196601125
222
+
223
+ min_pos, max_pos = Colors.set_theme_offset(theme, theme_offset)
224
+
225
+ # Generate positions within the acceptable range
226
+ positions = np.mod(np.arange(num) * golden_angle_conjugate, 1)
227
+ positions = min_pos + positions * (max_pos - min_pos)
228
+
229
+ # Sample colors from the colormap at the calculated positions
230
+ colors = cmap.map(positions, mode="float")
231
+ color_list = []
149
232
 
233
+ for color in colors:
150
234
  if format.upper() == "HEX":
151
- colors.append(QColor.fromRgbF(*color).name())
235
+ color_list.append(QColor.fromRgbF(*color).name())
152
236
  elif format.upper() == "RGB":
153
- colors.append(tuple((np.array(color) * 255).astype(int)))
237
+ color_list.append(tuple((np.array(color) * 255).astype(int)))
154
238
  elif format.upper() == "QCOLOR":
155
- colors.append(QColor.fromRgbF(*color))
239
+ color_list.append(QColor.fromRgbF(*color))
156
240
  else:
157
241
  raise ValueError("Unsupported format. Please choose 'RGB', 'HEX', or 'QColor'.")
158
- ii += 1
159
- return colors
242
+ return color_list
160
243
 
161
244
  @staticmethod
162
245
  def hex_to_rgba(hex_color: str, alpha=255) -> tuple:
@@ -141,6 +141,7 @@ class StatusItem(QWidget):
141
141
  metrics_text = (
142
142
  f"<b>SERVICE:</b> {self.config.service_name}<br><b>STATUS:</b> {self.config.status}<br>"
143
143
  )
144
+ metrics_text += f"<b>BEC_LIB VERSION:</b> {self.config.info['version']}<br>"
144
145
  if self.config.metrics:
145
146
  for key, value in self.config.metrics.items():
146
147
  if key == "create_time":
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec_widgets
3
- Version: 1.1.0
3
+ Version: 1.2.0
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=Dc1iDjsc72UxdUtihx4uSZU0lrTQeR8hZwGx1MQBfKE,8432
3
3
  .pylintrc,sha256=eeY8YwSI74oFfq6IYIbCqnx3Vk8ZncKaatv96n_Y8Rs,18544
4
4
  .readthedocs.yaml,sha256=aSOc277LqXcsTI6lgvm_JY80lMlr69GbPKgivua2cS0,603
5
- CHANGELOG.md,sha256=xra2a7E9-SF_dZvKo7VE4DmOq-9C3ULljLjARaiI1ac,7679
5
+ CHANGELOG.md,sha256=3_0bPYAjcDl2neoJ8ImU4r8g9n_IM9EGNEoD9TRiGoM,7560
6
6
  LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
7
- PKG-INFO,sha256=Bk0gLKzqUUXZQcPleodkRm9Wo6Puls3HXHPW1cj8SRU,1332
7
+ PKG-INFO,sha256=KM4OB0J4rRxGsMYKqC8hDTlD589qR8qiw7jSRCCQrI4,1332
8
8
  README.md,sha256=Od69x-RS85Hph0-WwWACwal4yUd67XkEn4APEfHhHFw,2649
9
- pyproject.toml,sha256=0rwrEGkMBYMiW61bqPvjeiyLZkxK0ZbPCIjUj24keGY,2592
9
+ pyproject.toml,sha256=tIRsuL8VDjpXoSFHlVYosPz5TzLwc6t-TzGOV8vKP-Y,2592
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
@@ -60,7 +60,7 @@ bec_widgets/utils/bec_dispatcher.py,sha256=OFmkx9vOz4pA4Sdc14QreyDZ870QYskJ4B5da
60
60
  bec_widgets/utils/bec_signal_proxy.py,sha256=PKJ7v8pKrAaqA9XNDMZZBlhVtEInX-ae6_0m2cQhiEw,2107
61
61
  bec_widgets/utils/bec_table.py,sha256=nA2b8ukSeUfquFMAxGrUVOqdrzMoDYD6O_4EYbOG2zk,717
62
62
  bec_widgets/utils/bec_widget.py,sha256=1lrHNuvW6uOuPpr-cJBYJNbFekTsqpnQdfTo3P5tbWI,3330
63
- bec_widgets/utils/colors.py,sha256=aUQkDMTRjTjS9lQfgO5NrUllU2r4ygDTTSUROtTBX90,12838
63
+ bec_widgets/utils/colors.py,sha256=Lpwm9ayTQ_BxQ977HWDZatf1OM7n2kEWzyJKvdjng-Y,16048
64
64
  bec_widgets/utils/container_utils.py,sha256=0wr3ZfuMiAFKCrQHVjxjw-Vuk8wsHdridqcjy2eY840,1531
65
65
  bec_widgets/utils/crosshair.py,sha256=f13tn1v_8FJ6C0WOLyDUXHaG_Nfzj4nMlLVEGqvs5Zc,11838
66
66
  bec_widgets/utils/entry_validator.py,sha256=3skJIsUwTYicT76AMHm_M78RiWtUgyD2zb-Rxo2HdHQ,1313
@@ -99,7 +99,7 @@ bec_widgets/widgets/bec_status_box/bec_status_box.py,sha256=udxOoTqO_qVO08B8kmVz
99
99
  bec_widgets/widgets/bec_status_box/bec_status_box.pyproject,sha256=JWtx3Csfn2h7ODtk10HtyBNLf6tFIqyU6g04rMWOO1U,32
100
100
  bec_widgets/widgets/bec_status_box/bec_status_box_plugin.py,sha256=UmsXAmeHg7FRkzirOLBPi3LwbRbG75w8LglYt4jn6Fc,1412
101
101
  bec_widgets/widgets/bec_status_box/register_bec_status_box.py,sha256=EiQITnkNw7IU7hE776wAeXro97eZd9XlsB9essgCebE,481
102
- bec_widgets/widgets/bec_status_box/status_item.py,sha256=8ePcKMcj9GBSuczk-k0d98lL_zMiVtTF-RRTG-Khec0,5525
102
+ bec_widgets/widgets/bec_status_box/status_item.py,sha256=ZV0gqHCZ7mSui02NThSV7fHlIlYpH1kCoVf4LdAVUMY,5610
103
103
  bec_widgets/widgets/button_abort/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
104
104
  bec_widgets/widgets/button_abort/abort_button.pyproject,sha256=UtuaE0Lvs6uOGufhatUyJS_n2l6EBbYaGuILj_BNCLs,30
105
105
  bec_widgets/widgets/button_abort/abort_button_plugin.py,sha256=3q0a4UE2O9s96Jjg6wi03CpXdQ7CnOI20ep7etEdxMo,1285
@@ -284,8 +284,8 @@ bec_widgets/widgets/website/register_website_widget.py,sha256=LIQJpV9uqcBiPR9cEA
284
284
  bec_widgets/widgets/website/website.py,sha256=42pncCc_zI2eqeMArIurVmPUukRo5bTxa2h1Skah-io,3012
285
285
  bec_widgets/widgets/website/website_widget.pyproject,sha256=scOiV3cV1_BjbzpPzy2N8rIJL5P2qIZz8ObTJ-Uvdtg,25
286
286
  bec_widgets/widgets/website/website_widget_plugin.py,sha256=pz38_C2cZ0yvPPS02wdIPcmhFo_yiwUhflsASocAPQQ,1341
287
- bec_widgets-1.1.0.dist-info/METADATA,sha256=Bk0gLKzqUUXZQcPleodkRm9Wo6Puls3HXHPW1cj8SRU,1332
288
- bec_widgets-1.1.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
289
- bec_widgets-1.1.0.dist-info/entry_points.txt,sha256=dItMzmwA1wizJ1Itx15qnfJ0ZzKVYFLVJ1voxT7K7D4,214
290
- bec_widgets-1.1.0.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
291
- bec_widgets-1.1.0.dist-info/RECORD,,
287
+ bec_widgets-1.2.0.dist-info/METADATA,sha256=KM4OB0J4rRxGsMYKqC8hDTlD589qR8qiw7jSRCCQrI4,1332
288
+ bec_widgets-1.2.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
289
+ bec_widgets-1.2.0.dist-info/entry_points.txt,sha256=dItMzmwA1wizJ1Itx15qnfJ0ZzKVYFLVJ1voxT7K7D4,214
290
+ bec_widgets-1.2.0.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
291
+ bec_widgets-1.2.0.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 = "1.1.0"
7
+ version = "1.2.0"
8
8
  description = "BEC Widgets"
9
9
  requires-python = ">=3.10"
10
10
  classifiers = [