Python-FastUI-Widgets 1.0.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 (107) hide show
  1. fastuiwidgets/__init__.py +12 -0
  2. fastuiwidgets/_rc/__init__.py +0 -0
  3. fastuiwidgets/_rc/resource.py +98835 -0
  4. fastuiwidgets/common/__init__.py +12 -0
  5. fastuiwidgets/common/animation.py +530 -0
  6. fastuiwidgets/common/auto_wrap.py +164 -0
  7. fastuiwidgets/common/color.py +95 -0
  8. fastuiwidgets/common/config.py +423 -0
  9. fastuiwidgets/common/exception_handler.py +31 -0
  10. fastuiwidgets/common/font.py +38 -0
  11. fastuiwidgets/common/icon.py +703 -0
  12. fastuiwidgets/common/image_utils.py +198 -0
  13. fastuiwidgets/common/overload.py +47 -0
  14. fastuiwidgets/common/router.py +133 -0
  15. fastuiwidgets/common/screen.py +25 -0
  16. fastuiwidgets/common/smooth_scroll.py +141 -0
  17. fastuiwidgets/common/style_sheet.py +512 -0
  18. fastuiwidgets/common/theme_listener.py +27 -0
  19. fastuiwidgets/common/translator.py +14 -0
  20. fastuiwidgets/components/__init__.py +6 -0
  21. fastuiwidgets/components/date_time/__init__.py +4 -0
  22. fastuiwidgets/components/date_time/calendar_picker.py +121 -0
  23. fastuiwidgets/components/date_time/calendar_view.py +671 -0
  24. fastuiwidgets/components/date_time/date_picker.py +245 -0
  25. fastuiwidgets/components/date_time/fast_calendar_view.py +487 -0
  26. fastuiwidgets/components/date_time/picker_base.py +632 -0
  27. fastuiwidgets/components/date_time/time_picker.py +223 -0
  28. fastuiwidgets/components/dialog_box/__init__.py +6 -0
  29. fastuiwidgets/components/dialog_box/color_dialog.py +414 -0
  30. fastuiwidgets/components/dialog_box/dialog.py +167 -0
  31. fastuiwidgets/components/dialog_box/folder_list_dialog.py +307 -0
  32. fastuiwidgets/components/dialog_box/mask_dialog_base.py +120 -0
  33. fastuiwidgets/components/dialog_box/message_box_base.py +92 -0
  34. fastuiwidgets/components/dialog_box/message_dialog.py +65 -0
  35. fastuiwidgets/components/layout/__init__.py +3 -0
  36. fastuiwidgets/components/layout/expand_layout.py +96 -0
  37. fastuiwidgets/components/layout/flow_layout.py +236 -0
  38. fastuiwidgets/components/layout/v_box_layout.py +41 -0
  39. fastuiwidgets/components/material/__init__.py +6 -0
  40. fastuiwidgets/components/material/acrylic_combo_box.py +96 -0
  41. fastuiwidgets/components/material/acrylic_flyout.py +105 -0
  42. fastuiwidgets/components/material/acrylic_line_edit.py +27 -0
  43. fastuiwidgets/components/material/acrylic_menu.py +204 -0
  44. fastuiwidgets/components/material/acrylic_tool_tip.py +39 -0
  45. fastuiwidgets/components/material/acrylic_widget.py +42 -0
  46. fastuiwidgets/components/navigation/__init__.py +9 -0
  47. fastuiwidgets/components/navigation/breadcrumb.py +350 -0
  48. fastuiwidgets/components/navigation/navigation_bar.py +416 -0
  49. fastuiwidgets/components/navigation/navigation_interface.py +268 -0
  50. fastuiwidgets/components/navigation/navigation_panel.py +657 -0
  51. fastuiwidgets/components/navigation/navigation_widget.py +686 -0
  52. fastuiwidgets/components/navigation/pivot.py +272 -0
  53. fastuiwidgets/components/navigation/segmented_widget.py +174 -0
  54. fastuiwidgets/components/settings/__init__.py +8 -0
  55. fastuiwidgets/components/settings/custom_color_setting_card.py +139 -0
  56. fastuiwidgets/components/settings/expand_setting_card.py +390 -0
  57. fastuiwidgets/components/settings/folder_list_setting_card.py +134 -0
  58. fastuiwidgets/components/settings/options_setting_card.py +86 -0
  59. fastuiwidgets/components/settings/setting_card.py +449 -0
  60. fastuiwidgets/components/settings/setting_card_group.py +48 -0
  61. fastuiwidgets/components/widgets/__init__.py +41 -0
  62. fastuiwidgets/components/widgets/acrylic_label.py +261 -0
  63. fastuiwidgets/components/widgets/button.py +1059 -0
  64. fastuiwidgets/components/widgets/card_widget.py +369 -0
  65. fastuiwidgets/components/widgets/check_box.py +203 -0
  66. fastuiwidgets/components/widgets/combo_box.py +556 -0
  67. fastuiwidgets/components/widgets/command_bar.py +636 -0
  68. fastuiwidgets/components/widgets/cycle_list_widget.py +251 -0
  69. fastuiwidgets/components/widgets/flip_view.py +430 -0
  70. fastuiwidgets/components/widgets/flyout.py +521 -0
  71. fastuiwidgets/components/widgets/frameless_window.py +49 -0
  72. fastuiwidgets/components/widgets/icon_widget.py +53 -0
  73. fastuiwidgets/components/widgets/info_badge.py +483 -0
  74. fastuiwidgets/components/widgets/info_bar.py +596 -0
  75. fastuiwidgets/components/widgets/label.py +553 -0
  76. fastuiwidgets/components/widgets/line_edit.py +551 -0
  77. fastuiwidgets/components/widgets/list_view.py +158 -0
  78. fastuiwidgets/components/widgets/menu.py +1318 -0
  79. fastuiwidgets/components/widgets/pips_pager.py +331 -0
  80. fastuiwidgets/components/widgets/progress_bar.py +311 -0
  81. fastuiwidgets/components/widgets/progress_ring.py +212 -0
  82. fastuiwidgets/components/widgets/scroll_area.py +125 -0
  83. fastuiwidgets/components/widgets/scroll_bar.py +673 -0
  84. fastuiwidgets/components/widgets/separator.py +43 -0
  85. fastuiwidgets/components/widgets/slider.py +307 -0
  86. fastuiwidgets/components/widgets/spin_box.py +306 -0
  87. fastuiwidgets/components/widgets/stacked_widget.py +211 -0
  88. fastuiwidgets/components/widgets/state_tool_tip.py +188 -0
  89. fastuiwidgets/components/widgets/switch_button.py +312 -0
  90. fastuiwidgets/components/widgets/tab_view.py +804 -0
  91. fastuiwidgets/components/widgets/table_view.py +360 -0
  92. fastuiwidgets/components/widgets/teaching_tip.py +657 -0
  93. fastuiwidgets/components/widgets/tool_tip.py +460 -0
  94. fastuiwidgets/components/widgets/tree_view.py +216 -0
  95. fastuiwidgets/multimedia/__init__.py +3 -0
  96. fastuiwidgets/multimedia/media_play_bar.py +319 -0
  97. fastuiwidgets/multimedia/media_player.py +124 -0
  98. fastuiwidgets/multimedia/video_widget.py +93 -0
  99. fastuiwidgets/window/__init__.py +2 -0
  100. fastuiwidgets/window/fluent_window.py +413 -0
  101. fastuiwidgets/window/splash_screen.py +92 -0
  102. fastuiwidgets/window/stacked_widget.py +66 -0
  103. python_fastui_widgets-1.0.0.dist-info/METADATA +30 -0
  104. python_fastui_widgets-1.0.0.dist-info/RECORD +107 -0
  105. python_fastui_widgets-1.0.0.dist-info/WHEEL +5 -0
  106. python_fastui_widgets-1.0.0.dist-info/licenses/LICENSE +674 -0
  107. python_fastui_widgets-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,483 @@
1
+ # coding:utf-8
2
+ from enum import Enum
3
+ from typing import Union
4
+
5
+ from PySide6.QtCore import Qt, QEvent, QRectF, QPoint, QObject, QSize
6
+ from PySide6.QtGui import QPixmap, QPainter, QColor, QIcon
7
+ from PySide6.QtWidgets import QLabel, QWidget, QSizePolicy
8
+
9
+ from ...common.font import setFont
10
+ from ...common.icon import drawIcon, FluentIconBase, toQIcon
11
+ from ...common.overload import singledispatchmethod
12
+ from ...common.style_sheet import themeColor, FluentStyleSheet, isDarkTheme, Theme
13
+
14
+
15
+ class InfoLevel(Enum):
16
+ """ Info level """
17
+ INFOAMTION = 'Info'
18
+ SUCCESS = 'Success'
19
+ ATTENTION = 'Attension'
20
+ WARNING = "Warning"
21
+ ERROR = "Error"
22
+
23
+
24
+ class InfoBadgePosition(Enum):
25
+ """ Info badge position """
26
+ TOP_RIGHT = 0
27
+ BOTTOM_RIGHT = 1
28
+ RIGHT = 2
29
+ TOP_LEFT = 3
30
+ BOTTOM_LEFT = 4
31
+ LEFT = 5
32
+ NAVIGATION_ITEM = 6
33
+
34
+
35
+ class InfoBadge(QLabel):
36
+ """ Information badge
37
+
38
+ Constructors
39
+ ------------
40
+ * InfoBadge(`parent`: QWidget = None, `level`=InfoLevel.ATTENTION)
41
+ * InfoBadge(`text`: str, `parent`: QWidget = None, `level`=InfoLevel.ATTENTION)
42
+ * InfoBadge(`num`: int, `parent`: QWidget = None, `level`=InfoLevel.ATTENTION)
43
+ * InfoBadge(`num`: float, `parent`: QWidget = None, `level`=InfoLevel.ATTENTION)
44
+ """
45
+
46
+ @singledispatchmethod
47
+ def __init__(self, parent: QWidget = None, level=InfoLevel.ATTENTION):
48
+ super().__init__(parent=parent)
49
+ self.level = InfoLevel.INFOAMTION
50
+ self.lightBackgroundColor = None
51
+ self.darkBackgroundColor = None
52
+ self.manager = None # type: InfoBadgeManager
53
+ self.setLevel(level)
54
+
55
+ setFont(self, 11)
56
+ self.setAttribute(Qt.WA_TranslucentBackground)
57
+ self.setAttribute(Qt.WA_TransparentForMouseEvents)
58
+ self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
59
+ FluentStyleSheet.INFO_BADGE.apply(self)
60
+
61
+ @__init__.register
62
+ def _(self, text: str, parent: QWidget = None, level=InfoLevel.ATTENTION):
63
+ self.__init__(parent, level)
64
+ self.setText(text)
65
+
66
+ @__init__.register
67
+ def _(self, num: int, parent: QWidget = None, level=InfoLevel.ATTENTION):
68
+ self.__init__(parent, level)
69
+ self.setNum(num)
70
+
71
+ @__init__.register
72
+ def _(self, num: float, parent: QWidget = None, level=InfoLevel.ATTENTION):
73
+ self.__init__(parent, level)
74
+ self.setNum(num)
75
+
76
+ def setLevel(self, level: InfoLevel):
77
+ """ set infomation level """
78
+ if level == self.level:
79
+ return
80
+
81
+ self.level = level
82
+ self.setProperty('level', level.value)
83
+ self.update()
84
+
85
+ def setProperty(self, name: str, value):
86
+ super().setProperty(name, value)
87
+ if name != "level":
88
+ return
89
+
90
+ values = [i.value for i in InfoLevel._member_map_.values()]
91
+ if value in values:
92
+ self.level = InfoLevel(value)
93
+
94
+ def setCustomBackgroundColor(self, light, dark):
95
+ """ set the custom background color
96
+
97
+ Parameters
98
+ ----------
99
+ light, dark: str | Qt.GlobalColor | QColor
100
+ background color in light/dark theme mode
101
+ """
102
+ self.lightBackgroundColor = QColor(light)
103
+ self.darkBackgroundColor = QColor(dark)
104
+ self.update()
105
+
106
+ def paintEvent(self, e):
107
+ painter = QPainter(self)
108
+ painter.setRenderHints(QPainter.Antialiasing)
109
+ painter.setPen(Qt.NoPen)
110
+ painter.setBrush(self._backgroundColor())
111
+
112
+ r = self.height() / 2
113
+ painter.drawRoundedRect(self.rect(), r, r)
114
+
115
+ super().paintEvent(e)
116
+
117
+ def _backgroundColor(self):
118
+ isDark = isDarkTheme()
119
+
120
+ if self.lightBackgroundColor:
121
+ color = self.darkBackgroundColor if isDark else self.lightBackgroundColor
122
+ elif self.level == InfoLevel.INFOAMTION:
123
+ color = QColor(157, 157, 157) if isDark else QColor(138, 138, 138)
124
+ elif self.level == InfoLevel.SUCCESS:
125
+ color = QColor(108, 203, 95) if isDark else QColor(15, 123, 15)
126
+ elif self.level == InfoLevel.ATTENTION:
127
+ color = themeColor()
128
+ elif self.level == InfoLevel.WARNING:
129
+ color = QColor(255, 244, 206) if isDark else QColor(157, 93, 0)
130
+ else:
131
+ color = QColor(255, 153, 164) if isDark else QColor(196, 43, 28)
132
+
133
+ return color
134
+
135
+ @classmethod
136
+ def make(cls, text: Union[str, float], parent=None, level=InfoLevel.INFOAMTION, target: QWidget = None,
137
+ position=InfoBadgePosition.TOP_RIGHT):
138
+ w = InfoBadge(text, parent, level)
139
+ w.adjustSize()
140
+
141
+ if target:
142
+ w.manager = InfoBadgeManager.make(position, target, w)
143
+ w.move(w.manager.position())
144
+
145
+ return w
146
+
147
+ @classmethod
148
+ def info(cls, text: Union[str, float], parent=None, target: QWidget = None, position=InfoBadgePosition.TOP_RIGHT):
149
+ return cls.make(text, parent, InfoLevel.INFOAMTION, target, position)
150
+
151
+ @classmethod
152
+ def success(cls, text: Union[str, float], parent=None, target: QWidget = None, position=InfoBadgePosition.TOP_RIGHT):
153
+ return cls.make(text, parent, InfoLevel.SUCCESS, target, position)
154
+
155
+ @classmethod
156
+ def attension(cls, text: Union[str, float], parent=None, target: QWidget = None, position=InfoBadgePosition.TOP_RIGHT):
157
+ return cls.make(text, parent, InfoLevel.ATTENTION, target, position)
158
+
159
+ @classmethod
160
+ def warning(cls, text: Union[str, float], parent=None, target: QWidget = None, position=InfoBadgePosition.TOP_RIGHT):
161
+ return cls.make(text, parent, InfoLevel.WARNING, target, position)
162
+
163
+ @classmethod
164
+ def error(cls, text: Union[str, float], parent=None, target: QWidget = None, position=InfoBadgePosition.TOP_RIGHT):
165
+ return cls.make(text, parent, InfoLevel.ERROR, target, position)
166
+
167
+ @classmethod
168
+ def custom(cls, text: Union[str, float], light: QColor, dark: QColor, parent=None, target: QWidget = None,
169
+ position=InfoBadgePosition.TOP_RIGHT):
170
+ """ create a badge with custom background color
171
+
172
+ Parameters
173
+ ----------
174
+ text: str | float
175
+ the text of badge
176
+
177
+ light, dark: str | Qt.GlobalColor | QColor
178
+ background color in light/dark theme mode
179
+
180
+ parent: QWidget
181
+ parent widget
182
+
183
+ target: QWidget
184
+ target widget to show the badge
185
+
186
+ pos: InfoBadgePosition
187
+ the position relative to target
188
+ """
189
+ w = cls.make(text, parent, target=target, position=position)
190
+ w.setCustomBackgroundColor(light, dark)
191
+ return w
192
+
193
+
194
+ class DotInfoBadge(InfoBadge):
195
+ """ Dot info badge """
196
+
197
+ def __init__(self, parent=None, level=InfoLevel.ATTENTION):
198
+ super().__init__(parent, level)
199
+ self.setFixedSize(4, 4)
200
+
201
+ def paintEvent(self, e):
202
+ painter = QPainter(self)
203
+ painter.setRenderHints(QPainter.Antialiasing)
204
+ painter.setPen(Qt.NoPen)
205
+ painter.setBrush(self._backgroundColor())
206
+ painter.drawEllipse(self.rect())
207
+
208
+ @classmethod
209
+ def make(cls, parent=None, level=InfoLevel.INFOAMTION, target: QWidget = None,
210
+ position=InfoBadgePosition.TOP_RIGHT):
211
+ w = DotInfoBadge(parent, level)
212
+
213
+ if target:
214
+ w.manager = InfoBadgeManager.make(position, target, w)
215
+ w.move(w.manager.position())
216
+
217
+ return w
218
+
219
+ @classmethod
220
+ def info(cls, parent=None, target: QWidget = None, position=InfoBadgePosition.TOP_RIGHT):
221
+ return cls.make(parent, InfoLevel.INFOAMTION, target, position)
222
+
223
+ @classmethod
224
+ def success(cls, parent=None, target: QWidget = None, position=InfoBadgePosition.TOP_RIGHT):
225
+ return cls.make(parent, InfoLevel.SUCCESS, target, position)
226
+
227
+ @classmethod
228
+ def attension(cls, parent=None, target: QWidget = None, position=InfoBadgePosition.TOP_RIGHT):
229
+ return cls.make(parent, InfoLevel.ATTENTION, target, position)
230
+
231
+ @classmethod
232
+ def warning(cls, parent=None, target: QWidget = None, position=InfoBadgePosition.TOP_RIGHT):
233
+ return cls.make(parent, InfoLevel.WARNING, target, position)
234
+
235
+ @classmethod
236
+ def error(cls, parent=None, target: QWidget = None, position=InfoBadgePosition.TOP_RIGHT):
237
+ return cls.make(parent, InfoLevel.ERROR, target, position)
238
+
239
+ @classmethod
240
+ def custom(cls, light: QColor, dark: QColor, parent=None, target: QWidget = None,
241
+ position=InfoBadgePosition.TOP_RIGHT):
242
+ """ create a badge with custom background color
243
+
244
+ Parameters
245
+ ----------
246
+ light, dark: str | Qt.GlobalColor | QColor
247
+ background color in light/dark theme mode
248
+
249
+ parent: QWidget
250
+ parent widget
251
+ """
252
+ w = cls.make(parent, target=target, position=position)
253
+ w.setCustomBackgroundColor(light, dark)
254
+ return w
255
+
256
+
257
+ class IconInfoBadge(InfoBadge):
258
+ """ Icon icon badge
259
+
260
+ Constructors
261
+ ------------
262
+ * IconInfoBadge(`parent`: QWidget = None, `level`=InfoLevel.ATTENTION)
263
+ * IconInfoBadge(`icon`: QIcon | str | FluentIconBase, `parent`: QWidget = None, `level`=InfoLevel.ATTENTION)
264
+ """
265
+
266
+ @singledispatchmethod
267
+ def __init__(self, parent: QWidget = None, level=InfoLevel.ATTENTION):
268
+ super().__init__(parent=parent, level=level)
269
+ self._icon = QIcon()
270
+ self._iconSize = QSize(8, 8)
271
+ self.setFixedSize(16, 16)
272
+
273
+ @__init__.register
274
+ def _(self, icon: FluentIconBase, parent: QWidget = None, level=InfoLevel.ATTENTION):
275
+ self.__init__(parent, level)
276
+ self.setIcon(icon)
277
+
278
+ @__init__.register
279
+ def _(self, icon: QIcon, parent: QWidget = None, level=InfoLevel.ATTENTION):
280
+ self.__init__(parent, level)
281
+ self.setIcon(icon)
282
+
283
+ def setIcon(self, icon: Union[QIcon, FluentIconBase, str]):
284
+ """ set the icon of info badge """
285
+ self._icon = icon
286
+ self.update()
287
+
288
+ def icon(self):
289
+ return toQIcon(self._icon)
290
+
291
+ def iconSize(self):
292
+ return self._iconSize
293
+
294
+ def setIconSize(self, size: QSize):
295
+ self._iconSize = size
296
+ self.update()
297
+
298
+ def paintEvent(self, e):
299
+ painter = QPainter(self)
300
+ painter.setRenderHints(QPainter.Antialiasing)
301
+ painter.setPen(Qt.NoPen)
302
+ painter.setBrush(self._backgroundColor())
303
+ painter.drawEllipse(self.rect())
304
+
305
+ iw, ih = self.iconSize().width(), self.iconSize().height()
306
+ x, y = (self.width() - iw) / 2, (self.width() - ih) / 2
307
+ rect = QRectF(x, y, iw, ih)
308
+
309
+ if isinstance(self._icon, FluentIconBase):
310
+ theme = Theme.DARK if not isDarkTheme() else Theme.LIGHT
311
+ self._icon.render(painter, rect, theme)
312
+ else:
313
+ drawIcon(self._icon, painter, rect)
314
+
315
+ @classmethod
316
+ def make(cls, icon: Union[QIcon, FluentIconBase], parent=None, level=InfoLevel.INFOAMTION, target: QWidget = None,
317
+ position=InfoBadgePosition.TOP_RIGHT):
318
+ w = IconInfoBadge(icon, parent, level)
319
+
320
+ if target:
321
+ w.manager = InfoBadgeManager.make(position, target, w)
322
+ w.move(w.manager.position())
323
+
324
+ return w
325
+
326
+ @classmethod
327
+ def info(cls, icon: Union[QIcon, FluentIconBase], parent=None, target: QWidget = None,
328
+ position=InfoBadgePosition.TOP_RIGHT):
329
+ return cls.make(icon, parent, InfoLevel.INFOAMTION, target, position)
330
+
331
+ @classmethod
332
+ def success(cls, icon: Union[QIcon, FluentIconBase], parent=None, target: QWidget = None,
333
+ position=InfoBadgePosition.TOP_RIGHT):
334
+ return cls.make(icon, parent, InfoLevel.SUCCESS, target, position)
335
+
336
+ @classmethod
337
+ def attension(cls, icon: Union[QIcon, FluentIconBase], parent=None, target: QWidget = None,
338
+ position=InfoBadgePosition.TOP_RIGHT):
339
+ return cls.make(icon, parent, InfoLevel.ATTENTION, target, position)
340
+
341
+ @classmethod
342
+ def warning(cls, icon: Union[QIcon, FluentIconBase], parent=None, target: QWidget = None,
343
+ position=InfoBadgePosition.TOP_RIGHT):
344
+ return cls.make(icon, parent, InfoLevel.WARNING, target, position)
345
+
346
+ @classmethod
347
+ def error(cls, icon: Union[QIcon, FluentIconBase], parent=None, target: QWidget = None,
348
+ position=InfoBadgePosition.TOP_RIGHT):
349
+ return cls.make(icon, parent, InfoLevel.ERROR, target, position)
350
+
351
+ @classmethod
352
+ def custom(cls, icon: Union[QIcon, FluentIconBase], light: QColor, dark: QColor, parent=None,
353
+ target: QWidget = None, position=InfoBadgePosition.TOP_RIGHT):
354
+ """ create a badge with custom background color
355
+
356
+ Parameters
357
+ ----------
358
+ icon: QIcon | FluentIconBase
359
+ the icon of badge
360
+
361
+ light, dark: str | Qt.GlobalColor | QColor
362
+ background color in light/dark theme mode
363
+
364
+ parent: QWidget
365
+ parent widget
366
+ """
367
+ w = cls.make(icon, parent, target=target, position=position)
368
+ w.setCustomBackgroundColor(light, dark)
369
+ return w
370
+
371
+
372
+ class InfoBadgeManager(QObject):
373
+ """ Info badge manager """
374
+
375
+ managers = {}
376
+
377
+ def __init__(self, target: QWidget, badge: InfoBadge):
378
+ super().__init__()
379
+ self.target = target
380
+ self.badge = badge
381
+
382
+ self.target.installEventFilter(self)
383
+
384
+ def eventFilter(self, obj, e: QEvent):
385
+ if obj is self.target:
386
+ if e.type() in [QEvent.Resize, QEvent.Move]:
387
+ self.badge.move(self.position())
388
+
389
+ return super().eventFilter(obj, e)
390
+
391
+ @classmethod
392
+ def register(cls, name):
393
+ """ register menu animation manager
394
+
395
+ Parameters
396
+ ----------
397
+ name: Any
398
+ the name of manager, it should be unique
399
+ """
400
+ def wrapper(Manager):
401
+ if name not in cls.managers:
402
+ cls.managers[name] = Manager
403
+
404
+ return Manager
405
+
406
+ return wrapper
407
+
408
+ @classmethod
409
+ def make(cls, position: InfoBadgePosition, target: QWidget, badge: InfoBadge):
410
+ """ mask info badge manager """
411
+ if position not in cls.managers:
412
+ raise ValueError(f'`{position}` is an invalid animation type.')
413
+
414
+ return cls.managers[position](target, badge)
415
+
416
+ def position(self):
417
+ """ return the position of info badge """
418
+ return QPoint()
419
+
420
+
421
+ @InfoBadgeManager.register(InfoBadgePosition.TOP_RIGHT)
422
+ class TopRightInfoBadgeManager(InfoBadgeManager):
423
+ """ Top right info badge manager """
424
+
425
+ def position(self):
426
+ pos = self.target.geometry().topRight()
427
+ x = pos.x() - self.badge.width() // 2
428
+ y = pos.y() - self.badge.height() // 2
429
+ return QPoint(x, y)
430
+
431
+
432
+ @InfoBadgeManager.register(InfoBadgePosition.RIGHT)
433
+ class RightInfoBadgeManager(InfoBadgeManager):
434
+ """ Right info badge manager """
435
+
436
+ def position(self):
437
+ x = self.target.geometry().right() - self.badge.width() // 2
438
+ y = self.target.geometry().center().y() - self.badge.height() // 2
439
+ return QPoint(x, y)
440
+
441
+
442
+ @InfoBadgeManager.register(InfoBadgePosition.BOTTOM_RIGHT)
443
+ class BottomRightInfoBadgeManager(InfoBadgeManager):
444
+ """ Bottom right info badge manager """
445
+
446
+ def position(self):
447
+ pos = self.target.geometry().bottomRight()
448
+ x = pos.x() - self.badge.width() // 2
449
+ y = pos.y() - self.badge.height() // 2
450
+ return QPoint(x, y)
451
+
452
+
453
+ @InfoBadgeManager.register(InfoBadgePosition.TOP_LEFT)
454
+ class TopLeftInfoBadgeManager(InfoBadgeManager):
455
+ """ Top left info badge manager """
456
+
457
+ def position(self):
458
+ x = self.target.x() - self.badge.width() // 2
459
+ y = self.target.y() - self.badge.height() // 2
460
+ return QPoint(x, y)
461
+
462
+
463
+ @InfoBadgeManager.register(InfoBadgePosition.LEFT)
464
+ class LeftInfoBadgeManager(InfoBadgeManager):
465
+ """ Top left info badge manager """
466
+
467
+ def position(self):
468
+ x = self.target.x() - self.badge.width() // 2
469
+ y = self.target.geometry().center().y() - self.badge.height() // 2
470
+ return QPoint(x, y)
471
+
472
+
473
+ @InfoBadgeManager.register(InfoBadgePosition.BOTTOM_LEFT)
474
+ class BottomLeftInfoBadgeManager(InfoBadgeManager):
475
+ """ Bottom left info badge manager """
476
+
477
+ def position(self):
478
+ pos = self.target.geometry().bottomLeft()
479
+ x = pos.x() - self.badge.width() // 2
480
+ y = pos.y() - self.badge.height() // 2
481
+ return QPoint(x, y)
482
+
483
+