bec-widgets 1.12.0__py3-none-any.whl → 1.14.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.
Files changed (31) hide show
  1. .gitlab-ci.yml +1 -0
  2. CHANGELOG.md +5727 -0
  3. PKG-INFO +4 -3
  4. bec_widgets/cli/auto_updates.py +45 -61
  5. bec_widgets/cli/client.py +19 -2
  6. bec_widgets/cli/client_utils.py +142 -198
  7. bec_widgets/cli/generate_cli.py +2 -2
  8. bec_widgets/cli/rpc/__init__.py +0 -0
  9. bec_widgets/cli/rpc/rpc_base.py +177 -0
  10. bec_widgets/cli/server.py +66 -29
  11. bec_widgets/qt_utils/error_popups.py +4 -2
  12. bec_widgets/tests/utils.py +8 -0
  13. bec_widgets/utils/bec_connector.py +1 -1
  14. bec_widgets/utils/widget_io.py +85 -5
  15. bec_widgets/widgets/containers/dock/dock.py +1 -1
  16. bec_widgets/widgets/containers/dock/dock_area.py +40 -2
  17. bec_widgets/widgets/containers/layout_manager/layout_manager.py +1 -1
  18. bec_widgets/widgets/containers/main_window/main_window.py +33 -1
  19. bec_widgets/widgets/games/__init__.py +3 -0
  20. bec_widgets/widgets/games/minesweeper.py +413 -0
  21. bec_widgets/widgets/games/minesweeper.pyproject +1 -0
  22. bec_widgets/widgets/games/minesweeper_plugin.py +54 -0
  23. bec_widgets/widgets/games/register_minesweeper.py +15 -0
  24. {bec_widgets-1.12.0.dist-info → bec_widgets-1.14.0.dist-info}/METADATA +4 -3
  25. {bec_widgets-1.12.0.dist-info → bec_widgets-1.14.0.dist-info}/RECORD +31 -24
  26. {bec_widgets-1.12.0.dist-info → bec_widgets-1.14.0.dist-info}/WHEEL +1 -1
  27. pyproject.toml +2 -2
  28. /bec_widgets/cli/{rpc_register.py → rpc/rpc_register.py} +0 -0
  29. /bec_widgets/cli/{rpc_wigdet_handler.py → rpc/rpc_widget_handler.py} +0 -0
  30. {bec_widgets-1.12.0.dist-info → bec_widgets-1.14.0.dist-info}/entry_points.txt +0 -0
  31. {bec_widgets-1.12.0.dist-info → bec_widgets-1.14.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,413 @@
1
+ import enum
2
+ import random
3
+ import time
4
+
5
+ from bec_qthemes import material_icon
6
+ from qtpy.QtCore import QSize, Qt, QTimer, Signal, Slot
7
+ from qtpy.QtGui import QBrush, QColor, QPainter, QPen
8
+ from qtpy.QtWidgets import (
9
+ QApplication,
10
+ QComboBox,
11
+ QGridLayout,
12
+ QHBoxLayout,
13
+ QLabel,
14
+ QPushButton,
15
+ QVBoxLayout,
16
+ QWidget,
17
+ )
18
+
19
+ from bec_widgets.utils.bec_widget import BECWidget
20
+
21
+ NUM_COLORS = {
22
+ 1: QColor("#f44336"),
23
+ 2: QColor("#9C27B0"),
24
+ 3: QColor("#3F51B5"),
25
+ 4: QColor("#03A9F4"),
26
+ 5: QColor("#00BCD4"),
27
+ 6: QColor("#4CAF50"),
28
+ 7: QColor("#E91E63"),
29
+ 8: QColor("#FF9800"),
30
+ }
31
+
32
+ LEVELS: dict[str, tuple[int, int]] = {"1": (8, 10), "2": (16, 40), "3": (24, 99)}
33
+
34
+
35
+ class GameStatus(enum.Enum):
36
+ READY = 0
37
+ PLAYING = 1
38
+ FAILED = 2
39
+ SUCCESS = 3
40
+
41
+
42
+ class Pos(QWidget):
43
+ expandable = Signal(int, int)
44
+ clicked = Signal()
45
+ ohno = Signal()
46
+
47
+ def __init__(self, x, y, *args, **kwargs):
48
+ super().__init__(*args, **kwargs)
49
+
50
+ self.setFixedSize(QSize(20, 20))
51
+
52
+ self.x = x
53
+ self.y = y
54
+ self.is_start = False
55
+ self.is_mine = False
56
+ self.adjacent_n = 0
57
+ self.is_revealed = False
58
+ self.is_flagged = False
59
+
60
+ def reset(self):
61
+ """Restore the tile to its original state before mine status is assigned"""
62
+ self.is_start = False
63
+ self.is_mine = False
64
+ self.adjacent_n = 0
65
+
66
+ self.is_revealed = False
67
+ self.is_flagged = False
68
+
69
+ self.update()
70
+
71
+ def paintEvent(self, event):
72
+ p = QPainter(self)
73
+
74
+ r = event.rect()
75
+
76
+ if self.is_revealed:
77
+ color = self.palette().base().color()
78
+ outer, inner = color, color
79
+ else:
80
+ outer, inner = (self.palette().highlightedText().color(), self.palette().text().color())
81
+
82
+ p.fillRect(r, QBrush(inner))
83
+ pen = QPen(outer)
84
+ pen.setWidth(1)
85
+ p.setPen(pen)
86
+ p.drawRect(r)
87
+
88
+ if self.is_revealed:
89
+ if self.is_mine:
90
+ p.drawPixmap(r, material_icon("experiment", convert_to_pixmap=True, filled=True))
91
+
92
+ elif self.adjacent_n > 0:
93
+ pen = QPen(NUM_COLORS[self.adjacent_n])
94
+ p.setPen(pen)
95
+ f = p.font()
96
+ f.setBold(True)
97
+ p.setFont(f)
98
+ p.drawText(r, Qt.AlignHCenter | Qt.AlignVCenter, str(self.adjacent_n))
99
+
100
+ elif self.is_flagged:
101
+ p.drawPixmap(
102
+ r,
103
+ material_icon(
104
+ "flag",
105
+ size=(50, 50),
106
+ convert_to_pixmap=True,
107
+ filled=True,
108
+ color=self.palette().base().color(),
109
+ ),
110
+ )
111
+ p.end()
112
+
113
+ def flag(self):
114
+ self.is_flagged = not self.is_flagged
115
+ self.update()
116
+
117
+ self.clicked.emit()
118
+
119
+ def reveal(self):
120
+ self.is_revealed = True
121
+ self.update()
122
+
123
+ def click(self):
124
+ if not self.is_revealed:
125
+ self.reveal()
126
+ if self.adjacent_n == 0:
127
+ self.expandable.emit(self.x, self.y)
128
+
129
+ self.clicked.emit()
130
+
131
+ def mouseReleaseEvent(self, event):
132
+ if event.button() == Qt.MouseButton.RightButton and not self.is_revealed:
133
+ self.flag()
134
+ return
135
+
136
+ if event.button() == Qt.MouseButton.LeftButton:
137
+ self.click()
138
+ if self.is_mine:
139
+ self.ohno.emit()
140
+
141
+
142
+ class Minesweeper(BECWidget, QWidget):
143
+
144
+ PLUGIN = True
145
+ ICON_NAME = "videogame_asset"
146
+ USER_ACCESS = []
147
+
148
+ def __init__(self, parent=None, *args, **kwargs):
149
+ super().__init__(*args, **kwargs)
150
+ QWidget.__init__(self, parent=parent)
151
+
152
+ self._ui_initialised = False
153
+ self._timer_start_num_seconds = 0
154
+ self._set_level_params(LEVELS["1"])
155
+
156
+ self._init_ui()
157
+ self._init_map()
158
+
159
+ self.update_status(GameStatus.READY)
160
+ self.reset_map()
161
+ self.update_status(GameStatus.READY)
162
+
163
+ def _init_ui(self):
164
+ if self._ui_initialised:
165
+ return
166
+ self._ui_initialised = True
167
+
168
+ status_hb = QHBoxLayout()
169
+ self.mines = QLabel()
170
+ self.mines.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
171
+ f = self.mines.font()
172
+ f.setPointSize(24)
173
+ self.mines.setFont(f)
174
+
175
+ self.reset_button = QPushButton()
176
+ self.reset_button.setFixedSize(QSize(32, 32))
177
+ self.reset_button.setIconSize(QSize(32, 32))
178
+ self.reset_button.setFlat(True)
179
+ self.reset_button.pressed.connect(self.reset_button_pressed)
180
+
181
+ self.clock = QLabel()
182
+ self.clock.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
183
+ self.clock.setFont(f)
184
+ self._timer = QTimer()
185
+ self._timer.timeout.connect(self.update_timer)
186
+ self._timer.start(1000) # 1 second timer
187
+ self.mines.setText(f"{self.num_mines:03d}")
188
+ self.clock.setText("000")
189
+
190
+ status_hb.addWidget(self.mines)
191
+ status_hb.addWidget(self.reset_button)
192
+ status_hb.addWidget(self.clock)
193
+
194
+ level_hb = QHBoxLayout()
195
+ self.level_selector = QComboBox()
196
+ self.level_selector.addItems(list(LEVELS.keys()))
197
+ level_hb.addWidget(QLabel("Level: "))
198
+ level_hb.addWidget(self.level_selector)
199
+ self.level_selector.currentTextChanged.connect(self.change_level)
200
+
201
+ vb = QVBoxLayout()
202
+ vb.addLayout(level_hb)
203
+ vb.addLayout(status_hb)
204
+
205
+ self.grid = QGridLayout()
206
+ self.grid.setSpacing(5)
207
+
208
+ vb.addLayout(self.grid)
209
+ self.setLayout(vb)
210
+
211
+ def _init_map(self):
212
+ """Redraw the grid of mines"""
213
+
214
+ # Remove any previous grid items and reset the grid
215
+ for i in reversed(range(self.grid.count())):
216
+ w: Pos = self.grid.itemAt(i).widget()
217
+ w.clicked.disconnect(self.on_click)
218
+ w.expandable.disconnect(self.expand_reveal)
219
+ w.ohno.disconnect(self.game_over)
220
+ w.setParent(None)
221
+ w.deleteLater()
222
+
223
+ # Add positions to the map
224
+ for x in range(0, self.b_size):
225
+ for y in range(0, self.b_size):
226
+ w = Pos(x, y)
227
+ self.grid.addWidget(w, y, x)
228
+ # Connect signal to handle expansion.
229
+ w.clicked.connect(self.on_click)
230
+ w.expandable.connect(self.expand_reveal)
231
+ w.ohno.connect(self.game_over)
232
+
233
+ def reset_map(self):
234
+ """
235
+ Reset the map and add new mines.
236
+ """
237
+ # Clear all mine positions
238
+ for x in range(0, self.b_size):
239
+ for y in range(0, self.b_size):
240
+ w = self.grid.itemAtPosition(y, x).widget()
241
+ w.reset()
242
+
243
+ # Add mines to the positions
244
+ positions = []
245
+ while len(positions) < self.num_mines:
246
+ x, y = (random.randint(0, self.b_size - 1), random.randint(0, self.b_size - 1))
247
+ if (x, y) not in positions:
248
+ w = self.grid.itemAtPosition(y, x).widget()
249
+ w.is_mine = True
250
+ positions.append((x, y))
251
+
252
+ def get_adjacency_n(x, y):
253
+ positions = self.get_surrounding(x, y)
254
+ num_mines = sum(1 if w.is_mine else 0 for w in positions)
255
+
256
+ return num_mines
257
+
258
+ # Add adjacencies to the positions
259
+ for x in range(0, self.b_size):
260
+ for y in range(0, self.b_size):
261
+ w = self.grid.itemAtPosition(y, x).widget()
262
+ w.adjacent_n = get_adjacency_n(x, y)
263
+
264
+ # Place starting marker
265
+ while True:
266
+ x, y = (random.randint(0, self.b_size - 1), random.randint(0, self.b_size - 1))
267
+ w = self.grid.itemAtPosition(y, x).widget()
268
+ # We don't want to start on a mine.
269
+ if (x, y) not in positions:
270
+ w = self.grid.itemAtPosition(y, x).widget()
271
+ w.is_start = True
272
+
273
+ # Reveal all positions around this, if they are not mines either.
274
+ for w in self.get_surrounding(x, y):
275
+ if not w.is_mine:
276
+ w.click()
277
+ break
278
+
279
+ def get_surrounding(self, x, y):
280
+ positions = []
281
+ for xi in range(max(0, x - 1), min(x + 2, self.b_size)):
282
+ for yi in range(max(0, y - 1), min(y + 2, self.b_size)):
283
+ positions.append(self.grid.itemAtPosition(yi, xi).widget())
284
+ return positions
285
+
286
+ def get_num_hidden(self) -> int:
287
+ """
288
+ Get the number of hidden positions.
289
+ """
290
+ return sum(
291
+ 1
292
+ for x in range(0, self.b_size)
293
+ for y in range(0, self.b_size)
294
+ if not self.grid.itemAtPosition(y, x).widget().is_revealed
295
+ )
296
+
297
+ def get_num_remaining_flags(self) -> int:
298
+ """
299
+ Get the number of remaining flags.
300
+ """
301
+ return self.num_mines - sum(
302
+ 1
303
+ for x in range(0, self.b_size)
304
+ for y in range(0, self.b_size)
305
+ if self.grid.itemAtPosition(y, x).widget().is_flagged
306
+ )
307
+
308
+ def reset_button_pressed(self):
309
+ match self.status:
310
+ case GameStatus.PLAYING:
311
+ self.game_over()
312
+ case GameStatus.FAILED | GameStatus.SUCCESS:
313
+ self.reset_map()
314
+
315
+ def reveal_map(self):
316
+ for x in range(0, self.b_size):
317
+ for y in range(0, self.b_size):
318
+ w = self.grid.itemAtPosition(y, x).widget()
319
+ w.reveal()
320
+
321
+ @Slot(str)
322
+ def change_level(self, level: str):
323
+ self._set_level_params(LEVELS[level])
324
+ self._init_map()
325
+ self.reset_map()
326
+
327
+ @Slot(int, int)
328
+ def expand_reveal(self, x, y):
329
+ """
330
+ Expand the reveal to the surrounding
331
+
332
+ Args:
333
+ x (int): The x position.
334
+ y (int): The y position.
335
+ """
336
+ for xi in range(max(0, x - 1), min(x + 2, self.b_size)):
337
+ for yi in range(max(0, y - 1), min(y + 2, self.b_size)):
338
+ w = self.grid.itemAtPosition(yi, xi).widget()
339
+ if not w.is_mine:
340
+ w.click()
341
+
342
+ @Slot()
343
+ def on_click(self):
344
+ """
345
+ Handle the click event. If the game is not started, start the game.
346
+ """
347
+ self.update_available_flags()
348
+ if self.status != GameStatus.PLAYING:
349
+ # First click.
350
+ self.update_status(GameStatus.PLAYING)
351
+ # Start timer.
352
+ self._timer_start_num_seconds = int(time.time())
353
+ return
354
+ self.check_win()
355
+
356
+ def update_available_flags(self):
357
+ """
358
+ Update the number of available flags.
359
+ """
360
+ self.mines.setText(f"{self.get_num_remaining_flags():03d}")
361
+
362
+ def check_win(self):
363
+ """
364
+ Check if the game is won.
365
+ """
366
+ if self.get_num_hidden() == self.num_mines:
367
+ self.update_status(GameStatus.SUCCESS)
368
+
369
+ def update_status(self, status: GameStatus):
370
+ """
371
+ Update the status of the game.
372
+
373
+ Args:
374
+ status (GameStatus): The status of the game.
375
+ """
376
+ self.status = status
377
+ match status:
378
+ case GameStatus.READY:
379
+ icon = material_icon(icon_name="add", convert_to_pixmap=False)
380
+ case GameStatus.PLAYING:
381
+ icon = material_icon(icon_name="smart_toy", convert_to_pixmap=False)
382
+ case GameStatus.FAILED:
383
+ icon = material_icon(icon_name="error", convert_to_pixmap=False)
384
+ case GameStatus.SUCCESS:
385
+ icon = material_icon(icon_name="celebration", convert_to_pixmap=False)
386
+ self.reset_button.setIcon(icon)
387
+
388
+ def update_timer(self):
389
+ """
390
+ Update the timer.
391
+ """
392
+ if self.status == GameStatus.PLAYING:
393
+ num_seconds = int(time.time()) - self._timer_start_num_seconds
394
+ self.clock.setText(f"{num_seconds:03d}")
395
+
396
+ def game_over(self):
397
+ """Cause the game to end early"""
398
+ self.reveal_map()
399
+ self.update_status(GameStatus.FAILED)
400
+
401
+ def _set_level_params(self, level: tuple[int, int]):
402
+ self.b_size, self.num_mines = level
403
+
404
+
405
+ if __name__ == "__main__":
406
+ from bec_widgets.utils.colors import set_theme
407
+
408
+ app = QApplication([])
409
+ set_theme("light")
410
+ widget = Minesweeper()
411
+ widget.show()
412
+
413
+ app.exec_()
@@ -0,0 +1 @@
1
+ {'files': ['minesweeper.py']}
@@ -0,0 +1,54 @@
1
+ # Copyright (C) 2022 The Qt Company Ltd.
2
+ # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
3
+
4
+ from qtpy.QtDesigner import QDesignerCustomWidgetInterface
5
+
6
+ from bec_widgets.utils.bec_designer import designer_material_icon
7
+ from bec_widgets.widgets.games.minesweeper import Minesweeper
8
+
9
+ DOM_XML = """
10
+ <ui language='c++'>
11
+ <widget class='Minesweeper' name='minesweeper'>
12
+ </widget>
13
+ </ui>
14
+ """
15
+
16
+
17
+ class MinesweeperPlugin(QDesignerCustomWidgetInterface): # pragma: no cover
18
+ def __init__(self):
19
+ super().__init__()
20
+ self._form_editor = None
21
+
22
+ def createWidget(self, parent):
23
+ t = Minesweeper(parent)
24
+ return t
25
+
26
+ def domXml(self):
27
+ return DOM_XML
28
+
29
+ def group(self):
30
+ return "BEC Games"
31
+
32
+ def icon(self):
33
+ return designer_material_icon(Minesweeper.ICON_NAME)
34
+
35
+ def includeFile(self):
36
+ return "minesweeper"
37
+
38
+ def initialize(self, form_editor):
39
+ self._form_editor = form_editor
40
+
41
+ def isContainer(self):
42
+ return False
43
+
44
+ def isInitialized(self):
45
+ return self._form_editor is not None
46
+
47
+ def name(self):
48
+ return "Minesweeper"
49
+
50
+ def toolTip(self):
51
+ return "Minesweeper"
52
+
53
+ def whatsThis(self):
54
+ return self.toolTip()
@@ -0,0 +1,15 @@
1
+ def main(): # pragma: no cover
2
+ from qtpy import PYSIDE6
3
+
4
+ if not PYSIDE6:
5
+ print("PYSIDE6 is not available in the environment. Cannot patch designer.")
6
+ return
7
+ from PySide6.QtDesigner import QPyDesignerCustomWidgetCollection
8
+
9
+ from bec_widgets.widgets.games.minesweeper_plugin import MinesweeperPlugin
10
+
11
+ QPyDesignerCustomWidgetCollection.addCustomWidget(MinesweeperPlugin())
12
+
13
+
14
+ if __name__ == "__main__": # pragma: no cover
15
+ main()
@@ -1,9 +1,10 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: bec_widgets
3
- Version: 1.12.0
3
+ Version: 1.14.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
7
+ License-File: LICENSE
7
8
  Classifier: Development Status :: 3 - Alpha
8
9
  Classifier: Programming Language :: Python :: 3
9
10
  Classifier: Topic :: Scientific/Engineering
@@ -21,7 +22,7 @@ Requires-Dist: qtpy~=2.4
21
22
  Provides-Extra: dev
22
23
  Requires-Dist: coverage~=7.0; extra == 'dev'
23
24
  Requires-Dist: fakeredis>=2.23.2,~=2.23; extra == 'dev'
24
- Requires-Dist: pytest-bec-e2e~=2.16; extra == 'dev'
25
+ Requires-Dist: pytest-bec-e2e<=4.0,>=2.21.4; extra == 'dev'
25
26
  Requires-Dist: pytest-qt~=4.4; extra == 'dev'
26
27
  Requires-Dist: pytest-random-order~=1.1; extra == 'dev'
27
28
  Requires-Dist: pytest-timeout~=2.2; extra == 'dev'
@@ -1,12 +1,12 @@
1
1
  .gitignore,sha256=cMQ1MLmnoR88aMCCJwUyfoTnufzl4-ckmHtlFUqHcT4,3253
2
- .gitlab-ci.yml,sha256=bAWGX_NR9rQZmv_bmyLXkEMRreWp0JzVNpsNTxk0NwE,8637
2
+ .gitlab-ci.yml,sha256=CLlFGYRGKp4FxCPTkyF9p-7qx67KmbM9Yok9JQEU_Ls,8677
3
3
  .pylintrc,sha256=eeY8YwSI74oFfq6IYIbCqnx3Vk8ZncKaatv96n_Y8Rs,18544
4
4
  .readthedocs.yaml,sha256=aSOc277LqXcsTI6lgvm_JY80lMlr69GbPKgivua2cS0,603
5
- CHANGELOG.md,sha256=YUN7cYN4D404UHmCrAwMrlL-4mVl5OViGPzlLVCnYn0,7625
5
+ CHANGELOG.md,sha256=Rc-zc5BJB4vWIPHMUsT7bdzkN5RrtzfDwA3YgiAtnBY,220774
6
6
  LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
7
- PKG-INFO,sha256=1-7w2AujTo1NIogqL1USRHIzs8GGvH5d49N-1KP90kk,1309
7
+ PKG-INFO,sha256=DBQ-UnU53mpLhIv0ZOmSUfTaKlGOqtLCRlv23r7biaY,1339
8
8
  README.md,sha256=Od69x-RS85Hph0-WwWACwal4yUd67XkEn4APEfHhHFw,2649
9
- pyproject.toml,sha256=flzI-4819-LvKYP0njUAltnkKXfJisdhtnUNtCryTXI,2587
9
+ pyproject.toml,sha256=xSU1IRtunmyKG3w3TpROqsjoUj6KdjW1go9sO8JLoHs,2596
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
@@ -23,13 +23,15 @@ bec_widgets/assets/app_icons/BEC-General-App.png,sha256=hc2ktly53DZAbl_rE3cb-vdR
23
23
  bec_widgets/assets/app_icons/alignment_1d.png,sha256=5VouaWieb4lVv3wUBNHaO5ovUW2Fk25aTKYQzOWy0mg,2071069
24
24
  bec_widgets/assets/app_icons/bec_widgets_icon.png,sha256=K8dgGwIjalDh9PRHUsSQBqgdX7a00nM3igZdc20pkYM,1747017
25
25
  bec_widgets/cli/__init__.py,sha256=d0Q6Fn44e7wFfLabDOBxpcJ1DPKWlFunGYDUBmO-4hA,22
26
- bec_widgets/cli/auto_updates.py,sha256=DwzRChcFIWPH2kCYvp8H7dXvyYSKGYv6LwCmK2sDR2E,5676
27
- bec_widgets/cli/client.py,sha256=smVHOupX4BfpdPMgLDA1maGCFcXMPKJiIIgG4lIvjAY,98625
28
- bec_widgets/cli/client_utils.py,sha256=5qlMFOh-7J6CclEKMj0BD09cNA4XCp1d1Wj2Z5hPpnA,14106
29
- bec_widgets/cli/generate_cli.py,sha256=YyYEPBpu5v9plCFQZHnyvEeFKoeHatpplPGil_D8DJM,6643
30
- bec_widgets/cli/rpc_register.py,sha256=8s-YJxqYoKc2K7jRLvs0TjW6_OnhaRYCK00RIok_4qE,2252
31
- bec_widgets/cli/rpc_wigdet_handler.py,sha256=C-HK8bXOGmbFb98ekMvfHYghU6mdjwMw6QVYBqVC_xk,1515
32
- bec_widgets/cli/server.py,sha256=rRrCcgy0VluiHycr1zL8EMf3siLN7gWxo6aMOZRzZQ8,9000
26
+ bec_widgets/cli/auto_updates.py,sha256=Pj8OHlSlKN3JOAmuuBC5oUMzdfC8TYRY7QKT5BQ2cZo,5171
27
+ bec_widgets/cli/client.py,sha256=8JLY18GiUYMlIw4I4WXnNWiGmJ40P5TylrbyUAIv3ik,98833
28
+ bec_widgets/cli/client_utils.py,sha256=DXHHw1LNkKVCApbWmOAdZqU_qdvvqx28QiWV-Uf-jos,12207
29
+ bec_widgets/cli/generate_cli.py,sha256=2BFNgxM_0XLy2OXxG_SX0rgPHFc27oq0_yoOI2h2Rgw,6605
30
+ bec_widgets/cli/server.py,sha256=j5S3-HUCcKE_rip4PDP7nNBAMObO6Ja6D66zhYxXmsE,10693
31
+ bec_widgets/cli/rpc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
+ bec_widgets/cli/rpc/rpc_base.py,sha256=1qxtzUuxy77Z0jX8my5EmbS3vE-bYlTp5RvZ2zjSDCA,6002
33
+ bec_widgets/cli/rpc/rpc_register.py,sha256=8s-YJxqYoKc2K7jRLvs0TjW6_OnhaRYCK00RIok_4qE,2252
34
+ bec_widgets/cli/rpc/rpc_widget_handler.py,sha256=C-HK8bXOGmbFb98ekMvfHYghU6mdjwMw6QVYBqVC_xk,1515
33
35
  bec_widgets/examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
36
  bec_widgets/examples/general_app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
37
  bec_widgets/examples/general_app/general_app.py,sha256=PoFCTuA_1yqrpgthASpYFgH7JDUZTcXAPZ5h0e3XZfc,3053
@@ -47,7 +49,7 @@ bec_widgets/examples/plugin_example_pyside/tictactoetaskmenu.py,sha256=V6OVnBTS-
47
49
  bec_widgets/qt_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
48
50
  bec_widgets/qt_utils/collapsible_panel_manager.py,sha256=tvv77-9YTfYpsU6M_Le3bHR6wtANC83DEOrJ2Hhj6rs,14201
49
51
  bec_widgets/qt_utils/compact_popup.py,sha256=3yeb-GJ1PUla5Q_hT0XDKqvyIEH9yV_eGidf1t8Dbbw,10234
50
- bec_widgets/qt_utils/error_popups.py,sha256=gd63kggSOHRmh9HzSPH2jjQznUecRBhhCtvoGIlh7xA,9253
52
+ bec_widgets/qt_utils/error_popups.py,sha256=Bm5-Gjl_vELFo12f8KgGRlk4hCCT9hfwGM7ggmvfCFs,9323
51
53
  bec_widgets/qt_utils/palette_viewer.py,sha256=--B0x7aE7bniHIeuuLY_pH8yBDrTTXaE0IDrC_AM1mo,6326
52
54
  bec_widgets/qt_utils/redis_message_waiter.py,sha256=fvL_QgC0cTDv_FPJdRyp5AKjf401EJU4z3r38p47ydY,1745
53
55
  bec_widgets/qt_utils/round_frame.py,sha256=Ba_sTzYB_vYDepBBMPPqU8XDwKOAiU6ClZ3xUqiveK0,5734
@@ -55,9 +57,9 @@ bec_widgets/qt_utils/settings_dialog.py,sha256=NhtzTer_xzlB2lLLrGklkI1QYLJEWQpJo
55
57
  bec_widgets/qt_utils/side_panel.py,sha256=5XtHIGfEJJj5m7cvkm-Vaxzz1TQogwglrmBaVcmcngY,12332
56
58
  bec_widgets/qt_utils/toolbar.py,sha256=RcWoWjibhlpL26Bnbft-uWA1q2WCglJRnO6U3hGMBw8,13277
57
59
  bec_widgets/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
58
- bec_widgets/tests/utils.py,sha256=D1v3JLzzbnX3HXBQCjoFlNz5cYhjqrRkFcjx3yptMJA,6687
60
+ bec_widgets/tests/utils.py,sha256=GbQtN7qf9n-8FoAfNddZ4aAqA7oBo_hGAlnKELd6Xzw,6943
59
61
  bec_widgets/utils/__init__.py,sha256=1930ji1Jj6dVuY81Wd2kYBhHYNV-2R0bN_L4o9zBj1U,533
60
- bec_widgets/utils/bec_connector.py,sha256=g40KPxhfuSHLlAa6dyO1PtC-9cQpN8ZGgn_IAEU_xD4,10070
62
+ bec_widgets/utils/bec_connector.py,sha256=78QAlC7uAtxUW-7KTxoMUJu2aFve7IqnGkURYYNGFDo,10074
61
63
  bec_widgets/utils/bec_designer.py,sha256=XBy38NbNMoRDpvRx5lGP2XnJNG34YKZ7I-ARFkn-gzs,5017
62
64
  bec_widgets/utils/bec_dispatcher.py,sha256=OFmkx9vOz4pA4Sdc14QreyDZ870QYskJ4B5daVVeYg4,6325
63
65
  bec_widgets/utils/bec_signal_proxy.py,sha256=PKJ7v8pKrAaqA9XNDMZZBlhVtEInX-ae6_0m2cQhiEw,2107
@@ -80,15 +82,15 @@ bec_widgets/utils/rpc_decorator.py,sha256=pIvtqySQLnuS7l2Ti_UAe4WX7CRivZnsE5ZdKA
80
82
  bec_widgets/utils/thread_checker.py,sha256=rDNuA3X6KQyA7JPb67mccTg0z8YkInynLAENQDQpbuE,1607
81
83
  bec_widgets/utils/ui_loader.py,sha256=6z0Qvt99XWoIk_YMACShwQ1p7PbDh6uJ9wS6e2wZs0w,4878
82
84
  bec_widgets/utils/validator_delegate.py,sha256=Emj1WF6W8Ke1ruBWUfmHdVJpmOSPezuOt4zvQTay_44,442
83
- bec_widgets/utils/widget_io.py,sha256=7xSgzq37T7azzLhAMd6yOYNGGf7P04DLDVcNYjwAGEA,12256
85
+ bec_widgets/utils/widget_io.py,sha256=R-ZYQyEVigHNH1AD4cNYmCV1DoO0XNidTZpiCSSND2c,15232
84
86
  bec_widgets/utils/yaml_dialog.py,sha256=T6UyGNGdmpXW74fa_7Nk6b99T5pp2Wvyw3AOauRc8T8,2407
85
87
  bec_widgets/utils/plugin_templates/plugin.template,sha256=DWtJdHpdsVtbiTTOniH3zBe5a40ztQ20o_-Hclyu38s,1266
86
88
  bec_widgets/utils/plugin_templates/register.template,sha256=XyL3OZPT_FTArLAM8tHd5qMqv2ZuAbJAZLsNNnHcagU,417
87
89
  bec_widgets/widgets/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
88
90
  bec_widgets/widgets/containers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
89
91
  bec_widgets/widgets/containers/dock/__init__.py,sha256=B7foHt02gnhM7mFksa7GJVwT7n0j_JvYDCt6wc6XR5g,61
90
- bec_widgets/widgets/containers/dock/dock.py,sha256=iQqPtjylG0LEmDSimogSD8Ks1WOr_JZMxLhyKjuhZmo,10375
91
- bec_widgets/widgets/containers/dock/dock_area.py,sha256=7IXfGiymWiHETxLHYbFoBsKd6L3_P48vyJO0fRShjlU,16705
92
+ bec_widgets/widgets/containers/dock/dock.py,sha256=_cw5bbqCLZxaD5LmosHNmm_eXelMDoTyxFdTnSWkoOI,10379
93
+ bec_widgets/widgets/containers/dock/dock_area.py,sha256=0LstkvXHSjizZrjpvICnh76amjMa-xQNaj9f7yBJyfw,17958
92
94
  bec_widgets/widgets/containers/dock/dock_area.pyproject,sha256=URW0UrDXCnkzk80rbQmUMgF6Uqay2TjHsq8Dq0g1j-c,37
93
95
  bec_widgets/widgets/containers/dock/dock_area_plugin.py,sha256=fDVXKPZuHr85B2fLfAYf_Ic5d9mZQpnZrODTDquzZpM,1331
94
96
  bec_widgets/widgets/containers/dock/register_dock_area.py,sha256=L7BL4qknCjtqsDP-RMQzk2qRPpcYuzXWlb7sJB_0DDM,475
@@ -110,9 +112,9 @@ bec_widgets/widgets/containers/figure/plots/waveform/__init__.py,sha256=47DEQpj8
110
112
  bec_widgets/widgets/containers/figure/plots/waveform/waveform.py,sha256=6j-3hg0tVtpCnDgbYObTYwiNI7ciuWgQ5L1TlAN0Kg8,57543
111
113
  bec_widgets/widgets/containers/figure/plots/waveform/waveform_curve.py,sha256=9rOFHIxRjz0-G6f-mpw0FNmX846ZPwGn8yrJ3FpxlVc,8725
112
114
  bec_widgets/widgets/containers/layout_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
113
- bec_widgets/widgets/containers/layout_manager/layout_manager.py,sha256=LJFEjzi10mzo0wxD84Iud1A-jKahqAf8nJ5qIBx1MfE,33757
115
+ bec_widgets/widgets/containers/layout_manager/layout_manager.py,sha256=1PmY73yvjmakKOHXv2ga4NziojNTuziIc4OX2gI5H_M,33761
114
116
  bec_widgets/widgets/containers/main_window/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
115
- bec_widgets/widgets/containers/main_window/main_window.py,sha256=A2IAux-lqupMCVZOQu7AUt1AEaeIG3Eza85eN0bknlI,272
117
+ bec_widgets/widgets/containers/main_window/main_window.py,sha256=YwHXA4bliPvuHicE0ur4QctNcZv5hnWbas83tAPkUf4,1649
116
118
  bec_widgets/widgets/control/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
117
119
  bec_widgets/widgets/control/buttons/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
118
120
  bec_widgets/widgets/control/buttons/button_abort/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -223,6 +225,11 @@ bec_widgets/widgets/editors/website/register_website_widget.py,sha256=VSVrZRCZoI
223
225
  bec_widgets/widgets/editors/website/website.py,sha256=VFFdrFX3P0Pf1V21oXrjGyCNrNp7fCsfbWPuRp9xEd8,3030
224
226
  bec_widgets/widgets/editors/website/website_widget.pyproject,sha256=scOiV3cV1_BjbzpPzy2N8rIJL5P2qIZz8ObTJ-Uvdtg,25
225
227
  bec_widgets/widgets/editors/website/website_widget_plugin.py,sha256=-YezP8dDqWZ9Xjjl-e5QTZuBPxxKyY4Lqcs7iaetIa8,1349
228
+ bec_widgets/widgets/games/__init__.py,sha256=jWW-3K3f3gqYM48Tp8rBxPebwPqxAcb7Q4dm_eE7FwI,89
229
+ bec_widgets/widgets/games/minesweeper.py,sha256=WQpyKwkNLCcH0t8InnFLM9TOiQSkbfOKp1uq3wwsPFo,12373
230
+ bec_widgets/widgets/games/minesweeper.pyproject,sha256=wHrLKY3H8uNiVgb9BIrj4S0Jeet9fjoR0BTnKzpx-vY,29
231
+ bec_widgets/widgets/games/minesweeper_plugin.py,sha256=oPEjSTpdIIkvuGThHxhVS8Rp47DWiaXHROtm8NJWYwo,1255
232
+ bec_widgets/widgets/games/register_minesweeper.py,sha256=8fgMBD3yB-5_eGqhG_qxpj3igXDK9WZfHrdYcA1aqz8,467
226
233
  bec_widgets/widgets/plots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
227
234
  bec_widgets/widgets/plots/image/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
228
235
  bec_widgets/widgets/plots/image/bec_image_widget.pyproject,sha256=PHisdBo5_5UCApd27GkizzqgfdjsDx2bFZa_p9LiSW8,30
@@ -318,8 +325,8 @@ bec_widgets/widgets/utility/visual/dark_mode_button/dark_mode_button.py,sha256=Z
318
325
  bec_widgets/widgets/utility/visual/dark_mode_button/dark_mode_button.pyproject,sha256=Lbi9zb6HNlIq14k6hlzR-oz6PIFShBuF7QxE6d87d64,34
319
326
  bec_widgets/widgets/utility/visual/dark_mode_button/dark_mode_button_plugin.py,sha256=CzChz2SSETYsR8-36meqWnsXCT-FIy_J_xeU5coWDY8,1350
320
327
  bec_widgets/widgets/utility/visual/dark_mode_button/register_dark_mode_button.py,sha256=rMpZ1CaoucwobgPj1FuKTnt07W82bV1GaSYdoqcdMb8,521
321
- bec_widgets-1.12.0.dist-info/METADATA,sha256=1-7w2AujTo1NIogqL1USRHIzs8GGvH5d49N-1KP90kk,1309
322
- bec_widgets-1.12.0.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
323
- bec_widgets-1.12.0.dist-info/entry_points.txt,sha256=dItMzmwA1wizJ1Itx15qnfJ0ZzKVYFLVJ1voxT7K7D4,214
324
- bec_widgets-1.12.0.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
325
- bec_widgets-1.12.0.dist-info/RECORD,,
328
+ bec_widgets-1.14.0.dist-info/METADATA,sha256=DBQ-UnU53mpLhIv0ZOmSUfTaKlGOqtLCRlv23r7biaY,1339
329
+ bec_widgets-1.14.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
330
+ bec_widgets-1.14.0.dist-info/entry_points.txt,sha256=dItMzmwA1wizJ1Itx15qnfJ0ZzKVYFLVJ1voxT7K7D4,214
331
+ bec_widgets-1.14.0.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
332
+ bec_widgets-1.14.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.26.3
2
+ Generator: hatchling 1.27.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "bec_widgets"
7
- version = "1.12.0"
7
+ version = "1.14.0"
8
8
  description = "BEC Widgets"
9
9
  requires-python = ">=3.10"
10
10
  classifiers = [
@@ -30,7 +30,7 @@ dependencies = [
30
30
  dev = [
31
31
  "coverage~=7.0",
32
32
  "fakeredis~=2.23, >=2.23.2",
33
- "pytest-bec-e2e~=2.16",
33
+ "pytest-bec-e2e>=2.21.4, <=4.0",
34
34
  "pytest-qt~=4.4",
35
35
  "pytest-random-order~=1.1",
36
36
  "pytest-timeout~=2.2",