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,703 @@
1
+ # coding:utf-8
2
+ from enum import Enum
3
+ from typing import Union
4
+ import json
5
+
6
+ from PySide6.QtXml import QDomDocument
7
+ from PySide6.QtCore import QRectF, Qt, QFile, QObject, QRect
8
+ from PySide6.QtGui import QIcon, QIconEngine, QColor, QPixmap, QImage, QPainter, QFontDatabase, QFont, QAction, QPainterPath
9
+ from PySide6.QtSvg import QSvgRenderer
10
+ from PySide6.QtWidgets import QApplication
11
+
12
+ from .config import isDarkTheme, Theme
13
+ from .overload import singledispatchmethod
14
+
15
+
16
+ class FluentIconEngine(QIconEngine):
17
+ """ Fluent icon engine """
18
+
19
+ def __init__(self, icon, reverse=False):
20
+ """
21
+ Parameters
22
+ ----------
23
+ icon: QICon | Icon | FluentIconBase
24
+ the icon to be drawn
25
+
26
+ reverse: bool
27
+ whether to reverse the theme of icon
28
+ """
29
+ super().__init__()
30
+ self.icon = icon
31
+ self.isThemeReversed = reverse
32
+
33
+ def paint(self, painter, rect, mode, state):
34
+ painter.save()
35
+
36
+ if mode == QIcon.Disabled:
37
+ painter.setOpacity(0.5)
38
+ elif mode == QIcon.Selected:
39
+ painter.setOpacity(0.7)
40
+
41
+ # change icon color according to the theme
42
+ icon = self.icon
43
+
44
+ if not self.isThemeReversed:
45
+ theme = Theme.AUTO
46
+ else:
47
+ theme = Theme.LIGHT if isDarkTheme() else Theme.DARK
48
+
49
+ if isinstance(self.icon, Icon):
50
+ icon = self.icon.fluentIcon.icon(theme)
51
+ elif isinstance(self.icon, FluentIconBase):
52
+ icon = self.icon.icon(theme)
53
+
54
+ if rect.x() == 19:
55
+ rect = rect.adjusted(-1, 0, 0, 0)
56
+
57
+ icon.paint(painter, rect, Qt.AlignCenter, QIcon.Normal, state)
58
+ painter.restore()
59
+
60
+
61
+ class SvgIconEngine(QIconEngine):
62
+ """ Svg icon engine """
63
+
64
+ def __init__(self, svg: str):
65
+ super().__init__()
66
+ self.svg = svg
67
+
68
+ def paint(self, painter, rect, mode, state):
69
+ drawSvgIcon(self.svg.encode(), painter, rect)
70
+
71
+ def clone(self) -> QIconEngine:
72
+ return SvgIconEngine(self.svg)
73
+
74
+ def pixmap(self, size, mode, state):
75
+ image = QImage(size, QImage.Format_ARGB32)
76
+ image.fill(Qt.transparent)
77
+ pixmap = QPixmap.fromImage(image, Qt.NoFormatConversion)
78
+
79
+ painter = QPainter(pixmap)
80
+ rect = QRect(0, 0, size.width(), size.height())
81
+ self.paint(painter, rect, mode, state)
82
+ return pixmap
83
+
84
+
85
+ class FontIconEngine(QIconEngine):
86
+ """ Font icon engine """
87
+
88
+ def __init__(self, fontFamily: str, char: str, color, isBold):
89
+ super().__init__()
90
+ self.color = color
91
+ self.char = char
92
+ self.fontFamily = fontFamily
93
+ self.isBold = isBold
94
+
95
+ def paint(self, painter, rect, mode, state):
96
+ font = QFont(self.fontFamily)
97
+ font.setBold(self.isBold)
98
+ font.setPixelSize(round(rect.height()))
99
+ painter.setFont(font)
100
+ painter.setPen(Qt.PenStyle.NoPen)
101
+ painter.setBrush(self.color)
102
+ painter.setRenderHints(
103
+ QPainter.RenderHint.Antialiasing | QPainter.RenderHint.TextAntialiasing)
104
+
105
+ path = QPainterPath()
106
+ path.addText(rect.x(), rect.y() + rect.height(), font, self.char)
107
+ painter.drawPath(path)
108
+
109
+
110
+ def clone(self) -> QIconEngine:
111
+ return FontIconEngine(self.fontFamily, self.char, self.color, self.isBold)
112
+
113
+ def pixmap(self, size, mode, state):
114
+ image = QImage(size, QImage.Format_ARGB32)
115
+ image.fill(Qt.transparent)
116
+ pixmap = QPixmap.fromImage(image, Qt.NoFormatConversion)
117
+
118
+ painter = QPainter(pixmap)
119
+ rect = QRect(0, 0, size.width(), size.height())
120
+ self.paint(painter, rect, mode, state)
121
+ return pixmap
122
+
123
+
124
+ def getIconColor(theme=Theme.AUTO, reverse=False):
125
+ """ get the color of icon based on theme """
126
+ if not reverse:
127
+ lc, dc = "black", "white"
128
+ else:
129
+ lc, dc = "white", "black"
130
+
131
+ if theme == Theme.AUTO:
132
+ color = dc if isDarkTheme() else lc
133
+ else:
134
+ color = dc if theme == Theme.DARK else lc
135
+
136
+ return color
137
+
138
+
139
+ def drawSvgIcon(icon, painter, rect):
140
+ """ draw svg icon
141
+
142
+ Parameters
143
+ ----------
144
+ icon: str | bytes | QByteArray
145
+ the path or code of svg icon
146
+
147
+ painter: QPainter
148
+ painter
149
+
150
+ rect: QRect | QRectF
151
+ the rect to render icon
152
+ """
153
+ renderer = QSvgRenderer(icon)
154
+ renderer.render(painter, QRectF(rect))
155
+
156
+
157
+ def writeSvg(iconPath: str, indexes=None, **attributes):
158
+ """ write svg with specified attributes
159
+
160
+ Parameters
161
+ ----------
162
+ iconPath: str
163
+ svg icon path
164
+
165
+ indexes: List[int]
166
+ the path to be filled
167
+
168
+ **attributes:
169
+ the attributes of path
170
+
171
+ Returns
172
+ -------
173
+ svg: str
174
+ svg code
175
+ """
176
+ if not iconPath.lower().endswith('.svg'):
177
+ return ""
178
+
179
+ f = QFile(iconPath)
180
+ f.open(QFile.ReadOnly)
181
+
182
+ dom = QDomDocument()
183
+ dom.setContent(f.readAll())
184
+
185
+ f.close()
186
+
187
+ # change the color of each path
188
+ pathNodes = dom.elementsByTagName('path')
189
+ indexes = range(pathNodes.length()) if not indexes else indexes
190
+ for i in indexes:
191
+ element = pathNodes.at(i).toElement()
192
+
193
+ for k, v in attributes.items():
194
+ element.setAttribute(k, v)
195
+
196
+ return dom.toString()
197
+
198
+
199
+ def drawIcon(icon, painter, rect, state=QIcon.Off, **attributes):
200
+ """ draw icon
201
+
202
+ Parameters
203
+ ----------
204
+ icon: str | QIcon | FluentIconBaseBase
205
+ the icon to be drawn
206
+
207
+ painter: QPainter
208
+ painter
209
+
210
+ rect: QRect | QRectF
211
+ the rect to render icon
212
+
213
+ **attribute:
214
+ the attribute of svg icon
215
+ """
216
+ if isinstance(icon, FluentIconBase):
217
+ icon.render(painter, rect, **attributes)
218
+ elif isinstance(icon, Icon):
219
+ icon.fluentIcon.render(painter, rect, **attributes)
220
+ else:
221
+ icon = QIcon(icon)
222
+ icon.paint(painter, QRectF(rect).toRect(), Qt.AlignCenter, state=state)
223
+
224
+
225
+ class FluentIconBase:
226
+ """ Fluent icon base class """
227
+
228
+ def path(self, theme=Theme.AUTO) -> str:
229
+ """ get the path of icon
230
+
231
+ Parameters
232
+ ----------
233
+ theme: Theme
234
+ the theme of icon
235
+ * `Theme.Light`: black icon
236
+ * `Theme.DARK`: white icon
237
+ * `Theme.AUTO`: icon color depends on `config.theme`
238
+ """
239
+ raise NotImplementedError
240
+
241
+ def icon(self, theme=Theme.AUTO, color: QColor = None) -> QIcon:
242
+ """ create a fluent icon
243
+
244
+ Parameters
245
+ ----------
246
+ theme: Theme
247
+ the theme of icon
248
+ * `Theme.Light`: black icon
249
+ * `Theme.DARK`: white icon
250
+ * `Theme.AUTO`: icon color depends on `qconfig.theme`
251
+
252
+ color: QColor | Qt.GlobalColor | str
253
+ icon color, only applicable to svg icon
254
+ """
255
+ path = self.path(theme)
256
+
257
+ if not (path.endswith('.svg') and color):
258
+ return QIcon(self.path(theme))
259
+
260
+ color = QColor(color).name()
261
+ return QIcon(SvgIconEngine(writeSvg(path, fill=color)))
262
+
263
+ def colored(self, lightColor: QColor, darkColor: QColor) -> "ColoredFluentIcon":
264
+ """ create a colored fluent icon
265
+
266
+ Parameters
267
+ ----------
268
+ lightColor: str | QColor | Qt.GlobalColor
269
+ icon color in light mode
270
+
271
+ darkColor: str | QColor | Qt.GlobalColor
272
+ icon color in dark mode
273
+ """
274
+ return ColoredFluentIcon(self, lightColor, darkColor)
275
+
276
+ def qicon(self, reverse=False) -> QIcon:
277
+ """ convert to QIcon, the theme of icon will be updated synchronously with app
278
+
279
+ Parameters
280
+ ----------
281
+ reverse: bool
282
+ whether to reverse the theme of icon
283
+ """
284
+ return QIcon(FluentIconEngine(self, reverse))
285
+
286
+ def render(self, painter, rect, theme=Theme.AUTO, indexes=None, **attributes):
287
+ """ draw svg icon
288
+
289
+ Parameters
290
+ ----------
291
+ painter: QPainter
292
+ painter
293
+
294
+ rect: QRect | QRectF
295
+ the rect to render icon
296
+
297
+ theme: Theme
298
+ the theme of icon
299
+ * `Theme.Light`: black icon
300
+ * `Theme.DARK`: white icon
301
+ * `Theme.AUTO`: icon color depends on `config.theme`
302
+
303
+ indexes: List[int]
304
+ the svg path to be modified
305
+
306
+ **attributes:
307
+ the attributes of modified path
308
+ """
309
+ icon = self.path(theme)
310
+
311
+ if icon.endswith('.svg'):
312
+ if attributes:
313
+ icon = writeSvg(icon, indexes, **attributes).encode()
314
+
315
+ drawSvgIcon(icon, painter, rect)
316
+ else:
317
+ icon = QIcon(icon)
318
+ rect = QRectF(rect).toRect()
319
+ painter.drawPixmap(rect, icon.pixmap(QRectF(rect).toRect().size()))
320
+
321
+
322
+ class FluentFontIconBase(FluentIconBase):
323
+ """ Fluent font icon base class """
324
+
325
+ _isFontLoaded = False
326
+ fontId = None
327
+ fontFamily = None
328
+ _iconNames = {}
329
+
330
+ def __init__(self, char: str):
331
+ super().__init__()
332
+ self.char = char
333
+ self.lightColor = QColor(0, 0, 0)
334
+ self.darkColor = QColor(255, 255, 255)
335
+ self.isBold = False
336
+ self.loadFont()
337
+
338
+ @classmethod
339
+ def fromName(cls, name: str):
340
+ icon = cls("")
341
+ icon.char = cls._iconNames.get(name, "")
342
+ return icon
343
+
344
+ def bold(self):
345
+ self.isBold = True
346
+ return self
347
+
348
+ def icon(self, theme=Theme.AUTO, color: QColor = None) -> QIcon:
349
+ if not color:
350
+ color = self._getIconColor(theme)
351
+
352
+ return QIcon(FontIconEngine(self.fontFamily, self.char, color, self.isBold))
353
+
354
+ def colored(self, lightColor, darkColor):
355
+ self.lightColor = QColor(lightColor)
356
+ self.darkColor = QColor(darkColor)
357
+ return self
358
+
359
+ def render(self, painter: QPainter, rect, theme=Theme.AUTO, indexes=None, **attributes):
360
+ color = self._getIconColor(theme)
361
+
362
+ if "fill" in attributes:
363
+ color = QColor(attributes["fill"])
364
+
365
+ font = QFont(self.fontFamily)
366
+ font.setBold(self.isBold)
367
+ font.setPixelSize(round(rect.height()))
368
+ painter.setFont(font)
369
+ painter.setPen(Qt.PenStyle.NoPen)
370
+ painter.setBrush(color)
371
+ painter.setRenderHints(QPainter.RenderHint.Antialiasing | QPainter.RenderHint.TextAntialiasing)
372
+
373
+ path = QPainterPath()
374
+ path.addText(rect.x(), rect.y() + rect.height(), font, self.char)
375
+ painter.drawPath(path)
376
+
377
+ def iconNameMapPath(self) -> str:
378
+ return None
379
+
380
+ def loadFont(self):
381
+ """ Load icon font """
382
+ cls = self.__class__
383
+ if cls._isFontLoaded or not QApplication.instance():
384
+ return
385
+
386
+ file = QFile(self.path())
387
+ if not file.open(QFile.ReadOnly):
388
+ raise FileNotFoundError(f"Cannot open font file: {self.path()}")
389
+
390
+ data = file.readAll()
391
+ file.close()
392
+
393
+ cls.fontId = QFontDatabase.addApplicationFontFromData(data)
394
+ cls.fontFamily = QFontDatabase.applicationFontFamilies(cls.fontId)[0]
395
+
396
+ if self.iconNameMapPath():
397
+ self.loadIconNames()
398
+
399
+ def loadIconNames(self):
400
+ """ Load icon name map """
401
+ cls = self.__class__
402
+ cls._iconNames.clear()
403
+
404
+ file = QFile(self.iconNameMapPath())
405
+ if not file.open(QFile.ReadOnly):
406
+ raise FileNotFoundError(f"Cannot open font file: {self.iconNameMapPath()}")
407
+
408
+ cls._iconNames = json.loads(str(file.readAll(), encoding='utf-8'))
409
+ file.close()
410
+
411
+ def _getIconColor(self, theme):
412
+ if theme == Theme.AUTO:
413
+ color = self.darkColor if isDarkTheme() else self.lightColor
414
+ else:
415
+ color = self.darkColor if theme == Theme.DARK else self.lightColor
416
+
417
+ return color
418
+
419
+
420
+ class ColoredFluentIcon(FluentIconBase):
421
+ """ Colored fluent icon """
422
+
423
+ def __init__(self, icon: FluentIconBase, lightColor, darkColor):
424
+ """
425
+ Parameters
426
+ ----------
427
+ icon: FluentIconBase
428
+ the icon to be colored
429
+
430
+ lightColor: str | QColor | Qt.GlobalColor
431
+ icon color in light mode
432
+
433
+ darkColor: str | QColor | Qt.GlobalColor
434
+ icon color in dark mode
435
+ """
436
+ super().__init__()
437
+ self.fluentIcon = icon
438
+ self.lightColor = QColor(lightColor)
439
+ self.darkColor = QColor(darkColor)
440
+
441
+ def path(self, theme=Theme.AUTO) -> str:
442
+ return self.fluentIcon.path(theme)
443
+
444
+ def render(self, painter, rect, theme=Theme.AUTO, indexes=None, **attributes):
445
+ icon = self.path(theme)
446
+
447
+ if not icon.endswith('.svg'):
448
+ return self.fluentIcon.render(painter, rect, theme, indexes, attributes)
449
+
450
+ if theme == Theme.AUTO:
451
+ color = self.darkColor if isDarkTheme() else self.lightColor
452
+ else:
453
+ color = self.darkColor if theme == Theme.DARK else self.lightColor
454
+
455
+ attributes.update(fill=color.name())
456
+ icon = writeSvg(icon, indexes, **attributes).encode()
457
+ drawSvgIcon(icon, painter, rect)
458
+
459
+
460
+
461
+ class FluentIcon(FluentIconBase, Enum):
462
+ """ Fluent icon """
463
+
464
+ UP = "Up"
465
+ ADD = "Add"
466
+ BUS = "Bus"
467
+ CAR = "Car"
468
+ CUT = "Cut"
469
+ IOT = "IOT"
470
+ PIN = "Pin"
471
+ TAG = "Tag"
472
+ VPN = "VPN"
473
+ CAFE = "Cafe"
474
+ CHAT = "Chat"
475
+ COPY = "Copy"
476
+ CODE = "Code"
477
+ DOWN = "Down"
478
+ EDIT = "Edit"
479
+ FLAG = "Flag"
480
+ FONT = "Font"
481
+ GAME = "Game"
482
+ HELP = "Help"
483
+ HIDE = "Hide"
484
+ HOME = "Home"
485
+ INFO = "Info"
486
+ LEAF = "Leaf"
487
+ LINK = "Link"
488
+ MAIL = "Mail"
489
+ MENU = "Menu"
490
+ MUTE = "Mute"
491
+ MORE = "More"
492
+ MOVE = "Move"
493
+ PLAY = "Play"
494
+ SAVE = "Save"
495
+ SEND = "Send"
496
+ SYNC = "Sync"
497
+ UNIT = "Unit"
498
+ VIEW = "View"
499
+ WIFI = "Wifi"
500
+ ZOOM = "Zoom"
501
+ ALBUM = "Album"
502
+ BRUSH = "Brush"
503
+ BROOM = "Broom"
504
+ CLOSE = "Close"
505
+ CLOUD = "Cloud"
506
+ EMBED = "Embed"
507
+ GLOBE = "Globe"
508
+ HEART = "Heart"
509
+ LABEL = "Label"
510
+ MEDIA = "Media"
511
+ MOVIE = "Movie"
512
+ MUSIC = "Music"
513
+ ROBOT = "Robot"
514
+ PAUSE = "Pause"
515
+ PASTE = "Paste"
516
+ PHOTO = "Photo"
517
+ PHONE = "Phone"
518
+ PRINT = "Print"
519
+ SHARE = "Share"
520
+ TILES = "Tiles"
521
+ UNPIN = "Unpin"
522
+ VIDEO = "Video"
523
+ TRAIN = "Train"
524
+ ADD_TO ="AddTo"
525
+ ACCEPT = "Accept"
526
+ CAMERA = "Camera"
527
+ CANCEL = "Cancel"
528
+ DELETE = "Delete"
529
+ FOLDER = "Folder"
530
+ FILTER = "Filter"
531
+ MARKET = "Market"
532
+ SCROLL = "Scroll"
533
+ LAYOUT = "Layout"
534
+ GITHUB = "GitHub"
535
+ UPDATE = "Update"
536
+ REMOVE = "Remove"
537
+ RETURN = "Return"
538
+ PEOPLE = "People"
539
+ QRCODE = "QRCode"
540
+ RINGER = "Ringer"
541
+ ROTATE = "Rotate"
542
+ SEARCH = "Search"
543
+ VOLUME = "Volume"
544
+ FRIGID = "Frigid"
545
+ SAVE_AS = "SaveAs"
546
+ ZOOM_IN = "ZoomIn"
547
+ CONNECT ="Connect"
548
+ HISTORY = "History"
549
+ SETTING = "Setting"
550
+ PALETTE = "Palette"
551
+ MESSAGE = "Message"
552
+ FIT_PAGE = "FitPage"
553
+ ZOOM_OUT = "ZoomOut"
554
+ AIRPLANE = "Airplane"
555
+ ASTERISK = "Asterisk"
556
+ CALORIES = "Calories"
557
+ CALENDAR = "Calendar"
558
+ FEEDBACK = "Feedback"
559
+ LIBRARY = "BookShelf"
560
+ MINIMIZE = "Minimize"
561
+ CHECKBOX = "CheckBox"
562
+ DOCUMENT = "Document"
563
+ LANGUAGE = "Language"
564
+ DOWNLOAD = "Download"
565
+ QUESTION = "Question"
566
+ SPEAKERS = "Speakers"
567
+ DATE_TIME = "DateTime"
568
+ FONT_SIZE = "FontSize"
569
+ HOME_FILL = "HomeFill"
570
+ PAGE_LEFT = "PageLeft"
571
+ SAVE_COPY = "SaveCopy"
572
+ SEND_FILL = "SendFill"
573
+ SKIP_BACK = "SkipBack"
574
+ SPEED_OFF = "SpeedOff"
575
+ ALIGNMENT = "Alignment"
576
+ BLUETOOTH = "Bluetooth"
577
+ COMPLETED = "Completed"
578
+ CONSTRACT = "Constract"
579
+ HEADPHONE = "Headphone"
580
+ MEGAPHONE = "Megaphone"
581
+ PROJECTOR = "Projector"
582
+ EDUCATION = "Education"
583
+ LEFT_ARROW = "LeftArrow"
584
+ ERASE_TOOL = "EraseTool"
585
+ PAGE_RIGHT = "PageRight"
586
+ PLAY_SOLID = "PlaySolid"
587
+ BOOK_SHELF = "BookShelf"
588
+ HIGHTLIGHT = "Highlight"
589
+ FOLDER_ADD = "FolderAdd"
590
+ PAUSE_BOLD = "PauseBold"
591
+ PENCIL_INK = "PencilInk"
592
+ PIE_SINGLE = "PieSingle"
593
+ QUICK_NOTE = "QuickNote"
594
+ SPEED_HIGH = "SpeedHigh"
595
+ STOP_WATCH = "StopWatch"
596
+ ZIP_FOLDER = "ZipFolder"
597
+ BASKETBALL = "Basketball"
598
+ BRIGHTNESS = "Brightness"
599
+ DICTIONARY = "Dictionary"
600
+ MICROPHONE = "Microphone"
601
+ ARROW_DOWN = "ChevronDown"
602
+ FULL_SCREEN = "FullScreen"
603
+ MIX_VOLUMES = "MixVolumes"
604
+ REMOVE_FROM = "RemoveFrom"
605
+ RIGHT_ARROW = "RightArrow"
606
+ QUIET_HOURS ="QuietHours"
607
+ FINGERPRINT = "Fingerprint"
608
+ APPLICATION = "Application"
609
+ CERTIFICATE = "Certificate"
610
+ TRANSPARENT = "Transparent"
611
+ IMAGE_EXPORT = "ImageExport"
612
+ SPEED_MEDIUM = "SpeedMedium"
613
+ LIBRARY_FILL = "LibraryFill"
614
+ MUSIC_FOLDER = "MusicFolder"
615
+ POWER_BUTTON = "PowerButton"
616
+ SKIP_FORWARD = "SkipForward"
617
+ CARE_UP_SOLID = "CareUpSolid"
618
+ ACCEPT_MEDIUM = "AcceptMedium"
619
+ CANCEL_MEDIUM = "CancelMedium"
620
+ CHEVRON_RIGHT = "ChevronRight"
621
+ CLIPPING_TOOL = "ClippingTool"
622
+ SEARCH_MIRROR = "SearchMirror"
623
+ SHOPPING_CART = "ShoppingCart"
624
+ FONT_INCREASE = "FontIncrease"
625
+ BACK_TO_WINDOW = "BackToWindow"
626
+ COMMAND_PROMPT = "CommandPrompt"
627
+ CLOUD_DOWNLOAD = "CloudDownload"
628
+ DICTIONARY_ADD = "DictionaryAdd"
629
+ CARE_DOWN_SOLID = "CareDownSolid"
630
+ CARE_LEFT_SOLID = "CareLeftSolid"
631
+ CLEAR_SELECTION = "ClearSelection"
632
+ DEVELOPER_TOOLS = "DeveloperTools"
633
+ BACKGROUND_FILL = "BackgroundColor"
634
+ CARE_RIGHT_SOLID = "CareRightSolid"
635
+ CHEVRON_DOWN_MED = "ChevronDownMed"
636
+ CHEVRON_RIGHT_MED = "ChevronRightMed"
637
+ EMOJI_TAB_SYMBOLS = "EmojiTabSymbols"
638
+ EXPRESSIVE_INPUT_ENTRY = "ExpressiveInputEntry"
639
+
640
+ def path(self, theme=Theme.AUTO):
641
+ return f':/fastuiwidgets/images/icons/{self.value}_{getIconColor(theme)}.svg'
642
+
643
+
644
+ class Icon(QIcon):
645
+
646
+ def __init__(self, fluentIcon: FluentIcon):
647
+ super().__init__(fluentIcon.path())
648
+ self.fluentIcon = fluentIcon
649
+
650
+
651
+ def toQIcon(icon: Union[QIcon, FluentIconBase, str]) -> QIcon:
652
+ """ convet `icon` to `QIcon` """
653
+ if isinstance(icon, str):
654
+ return QIcon(icon)
655
+
656
+ if isinstance(icon, FluentIconBase):
657
+ return icon.icon()
658
+
659
+ return icon
660
+
661
+
662
+ class Action(QAction):
663
+ """ Fluent action
664
+
665
+ Constructors
666
+ ------------
667
+ * Action(`parent`: QWidget = None, `**kwargs`)
668
+ * Action(`text`: str, `parent`: QWidget = None, `**kwargs`)
669
+ * Action(`icon`: QIcon | FluentIconBase, `parent`: QWidget = None, `**kwargs`)
670
+ """
671
+
672
+ @singledispatchmethod
673
+ def __init__(self, parent: QObject = None, **kwargs):
674
+ super().__init__(parent, **kwargs)
675
+ self.fluentIcon = None
676
+
677
+ @__init__.register
678
+ def _(self, text: str, parent: QObject = None, **kwargs):
679
+ super().__init__(text, parent, **kwargs)
680
+ self.fluentIcon = None
681
+
682
+ @__init__.register
683
+ def _(self, icon: QIcon, text: str, parent: QObject = None, **kwargs):
684
+ super().__init__(icon, text, parent, **kwargs)
685
+ self.fluentIcon = None
686
+
687
+ @__init__.register
688
+ def _(self, icon: FluentIconBase, text: str, parent: QObject = None, **kwargs):
689
+ super().__init__(icon.icon(), text, parent, **kwargs)
690
+ self.fluentIcon = icon
691
+
692
+ def icon(self) -> QIcon:
693
+ if self.fluentIcon:
694
+ return Icon(self.fluentIcon)
695
+
696
+ return super().icon()
697
+
698
+ def setIcon(self, icon: Union[FluentIconBase, QIcon]):
699
+ if isinstance(icon, FluentIconBase):
700
+ self.fluentIcon = icon
701
+ icon = icon.icon()
702
+
703
+ super().setIcon(icon)