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,360 @@
1
+ # coding: utf-8
2
+ from typing import List, Union
3
+
4
+ from PySide6.QtCore import Qt, QMargins, QModelIndex, QItemSelectionModel, Property, QRectF, QEvent
5
+ from PySide6.QtGui import QHelpEvent, QPainter, QColor, QKeyEvent, QPalette, QBrush
6
+ from PySide6.QtWidgets import (QAbstractItemView, QStyledItemDelegate, QApplication, QStyleOptionViewItem,
7
+ QTableView, QTableWidget, QWidget, QTableWidgetItem, QStyle,
8
+ QStyleOptionButton)
9
+
10
+ from .check_box import CheckBoxIcon
11
+ from ...common.font import getFont
12
+ from ...common.color import autoFallbackThemeColor
13
+ from ...common.style_sheet import isDarkTheme, FluentStyleSheet, themeColor, setCustomStyleSheet
14
+ from .line_edit import LineEdit
15
+ from .scroll_bar import SmoothScrollDelegate
16
+ from .tool_tip import ItemViewToolTipDelegate, ItemViewToolTipType
17
+
18
+
19
+ class TableItemDelegate(QStyledItemDelegate):
20
+
21
+ def __init__(self, parent: QTableView):
22
+ super().__init__(parent)
23
+ self.margin = 2
24
+ self.hoverRow = -1
25
+ self.pressedRow = -1
26
+ self.selectedRows = set()
27
+ self.lightCheckedColor = QColor()
28
+ self.darkCheckedColor = QColor()
29
+
30
+ if isinstance(parent, QTableView):
31
+ self.tooltipDelegate = ItemViewToolTipDelegate(parent, 100, ItemViewToolTipType.TABLE)
32
+ else:
33
+ self.tooltipDelegate = ItemViewToolTipDelegate(parent, 100, ItemViewToolTipType.LIST)
34
+
35
+ def setHoverRow(self, row: int):
36
+ self.hoverRow = row
37
+
38
+ def setPressedRow(self, row: int):
39
+ self.pressedRow = row
40
+
41
+ def setSelectedRows(self, indexes: List[QModelIndex]):
42
+ self.selectedRows.clear()
43
+ for index in indexes:
44
+ self.selectedRows.add(index.row())
45
+ if index.row() == self.pressedRow:
46
+ self.pressedRow = -1
47
+
48
+ def sizeHint(self, option, index):
49
+ # increase original sizeHint to accommodate space needed for border
50
+ size = super().sizeHint(option, index)
51
+ size = size.grownBy(QMargins(0, self.margin, 0, self.margin))
52
+ return size
53
+
54
+ def createEditor(self, parent: QWidget, option: QStyleOptionViewItem, index: QModelIndex) -> QWidget:
55
+ lineEdit = LineEdit(parent)
56
+ lineEdit.setProperty("transparent", False)
57
+ lineEdit.setStyle(QApplication.style())
58
+ lineEdit.setText(option.text)
59
+ lineEdit.setClearButtonEnabled(True)
60
+ return lineEdit
61
+
62
+ def updateEditorGeometry(self, editor: QWidget, option: QStyleOptionViewItem, index: QModelIndex):
63
+ rect = option.rect
64
+ y = rect.y() + (rect.height() - editor.height()) // 2
65
+ x, w = max(8, rect.x()), rect.width()
66
+ if index.column() == 0:
67
+ w -= 8
68
+
69
+ editor.setGeometry(x, y, w, rect.height())
70
+
71
+ def setCheckedColor(self, light, dark):
72
+ """ set the color of indicator in checked status
73
+
74
+ Parameters
75
+ ----------
76
+ light, dark: str | QColor | Qt.GlobalColor
77
+ color in light/dark theme mode
78
+ """
79
+ self.lightCheckedColor = QColor(light)
80
+ self.darkCheckedColor = QColor(dark)
81
+ self.parent().viewport().update()
82
+
83
+ def _drawBackground(self, painter: QPainter, option: QStyleOptionViewItem, index: QModelIndex):
84
+ """ draw row background """
85
+ r = 5
86
+ if index.column() == 0:
87
+ rect = option.rect.adjusted(4, 0, r + 1, 0)
88
+ painter.drawRoundedRect(rect, r, r)
89
+ elif index.column() == index.model().columnCount(index.parent()) - 1:
90
+ rect = option.rect.adjusted(-r - 1, 0, -4, 0)
91
+ painter.drawRoundedRect(rect, r, r)
92
+ else:
93
+ rect = option.rect.adjusted(-1, 0, 1, 0)
94
+ painter.drawRect(rect)
95
+
96
+ def _drawIndicator(self, painter: QPainter, option: QStyleOptionViewItem, index: QModelIndex):
97
+ """ draw indicator """
98
+ y, h = option.rect.y(), option.rect.height()
99
+ ph = round(0.35*h if self.pressedRow == index.row() else 0.257*h)
100
+ painter.setBrush(autoFallbackThemeColor(self.lightCheckedColor, self.darkCheckedColor))
101
+ painter.drawRoundedRect(4, ph + y, 3, h - 2*ph, 1.5, 1.5)
102
+
103
+ def initStyleOption(self, option: QStyleOptionViewItem, index: QModelIndex):
104
+ super().initStyleOption(option, index)
105
+
106
+ # font
107
+ option.font = index.data(Qt.FontRole) or getFont(13)
108
+
109
+ # text color
110
+ textColor = Qt.white if isDarkTheme() else Qt.black
111
+ textBrush = index.data(Qt.ForegroundRole) # type: QBrush
112
+ if textBrush is not None:
113
+ textColor = textBrush.color()
114
+
115
+ option.palette.setColor(QPalette.Text, textColor)
116
+ option.palette.setColor(QPalette.HighlightedText, textColor)
117
+
118
+ def paint(self, painter, option, index):
119
+ painter.save()
120
+ painter.setPen(Qt.NoPen)
121
+ painter.setRenderHint(QPainter.Antialiasing)
122
+
123
+ # set clipping rect of painter to avoid painting outside the borders
124
+ painter.setClipping(True)
125
+ painter.setClipRect(option.rect)
126
+
127
+ # call original paint method where option.rect is adjusted to account for border
128
+ option.rect.adjust(0, self.margin, 0, -self.margin)
129
+
130
+ # draw highlight background
131
+ isHover = self.hoverRow == index.row()
132
+ isPressed = self.pressedRow == index.row()
133
+ isAlternate = index.row() % 2 == 0 and self.parent().alternatingRowColors()
134
+ isDark = isDarkTheme()
135
+
136
+ c = 255 if isDark else 0
137
+ alpha = 0
138
+
139
+ if index.row() not in self.selectedRows:
140
+ if isPressed:
141
+ alpha = 9 if isDark else 6
142
+ elif isHover:
143
+ alpha = 12
144
+ elif isAlternate:
145
+ alpha = 5
146
+ else:
147
+ if isPressed:
148
+ alpha = 15 if isDark else 9
149
+ elif isHover:
150
+ alpha = 25
151
+ else:
152
+ alpha = 17
153
+
154
+ if index.data(Qt.ItemDataRole.BackgroundRole):
155
+ painter.setBrush(index.data(Qt.ItemDataRole.BackgroundRole))
156
+ else:
157
+ painter.setBrush(QColor(c, c, c, alpha))
158
+
159
+ self._drawBackground(painter, option, index)
160
+
161
+ # draw indicator
162
+ if index.row() in self.selectedRows and index.column() == 0 and self.parent().horizontalScrollBar().value() == 0:
163
+ self._drawIndicator(painter, option, index)
164
+
165
+ if index.data(Qt.CheckStateRole) is not None:
166
+ self._drawCheckBox(painter, option, index)
167
+
168
+ painter.restore()
169
+ super().paint(painter, option, index)
170
+
171
+ def _drawCheckBox(self, painter: QPainter, option: QStyleOptionViewItem, index: QModelIndex):
172
+ painter.save()
173
+ checkState = Qt.CheckState(index.data(Qt.ItemDataRole.CheckStateRole))
174
+
175
+ isDark = isDarkTheme()
176
+
177
+ r = 4.5
178
+ x = option.rect.x() + 15
179
+ y = option.rect.center().y() - 9.5
180
+ rect = QRectF(x, y, 19, 19)
181
+
182
+ if checkState == Qt.CheckState.Unchecked:
183
+ painter.setBrush(QColor(0, 0, 0, 26) if isDark else QColor(0, 0, 0, 6))
184
+ painter.setPen(QColor(255, 255, 255, 142) if isDark else QColor(0, 0, 0, 122))
185
+ painter.drawRoundedRect(rect, r, r)
186
+ else:
187
+ color = autoFallbackThemeColor(self.lightCheckedColor, self.darkCheckedColor)
188
+ painter.setPen(color)
189
+ painter.setBrush(color)
190
+ painter.drawRoundedRect(rect, r, r)
191
+
192
+ if checkState == Qt.CheckState.Checked:
193
+ CheckBoxIcon.ACCEPT.render(painter, rect)
194
+ else:
195
+ CheckBoxIcon.PARTIAL_ACCEPT.render(painter, rect)
196
+
197
+ painter.restore()
198
+
199
+ def helpEvent(self, event: QHelpEvent, view: QAbstractItemView, option: QStyleOptionViewItem, index: QModelIndex) -> bool:
200
+ return self.tooltipDelegate.helpEvent(event, view, option, index)
201
+
202
+
203
+
204
+ class TableBase:
205
+ """ Table base class """
206
+
207
+ def __init__(self, *args, **kwargs):
208
+ super().__init__(*args, **kwargs)
209
+ self.delegate = TableItemDelegate(self)
210
+ self.scrollDelagate = SmoothScrollDelegate(self)
211
+ self._isSelectRightClickedRow = False
212
+
213
+ # set style sheet
214
+ FluentStyleSheet.TABLE_VIEW.apply(self)
215
+
216
+ self.setShowGrid(False)
217
+ self.setMouseTracking(True)
218
+ self.setAlternatingRowColors(True)
219
+ self.setItemDelegate(self.delegate)
220
+ self.setSelectionBehavior(TableWidget.SelectRows)
221
+ self.horizontalHeader().setHighlightSections(False)
222
+ self.verticalHeader().setHighlightSections(False)
223
+ self.verticalHeader().setDefaultSectionSize(38)
224
+
225
+ self.entered.connect(lambda i: self._setHoverRow(i.row()))
226
+ self.pressed.connect(lambda i: self._setPressedRow(i.row()))
227
+ self.verticalHeader().sectionClicked.connect(self.selectRow)
228
+
229
+ def setBorderVisible(self, isVisible: bool):
230
+ """ set the visibility of border """
231
+ self.setProperty("isBorderVisible", isVisible)
232
+ self.setStyle(QApplication.style())
233
+
234
+ def setBorderRadius(self, radius: int):
235
+ """ set the radius of border """
236
+ qss = f"QTableView{{border-radius: {radius}px}}"
237
+ setCustomStyleSheet(self, qss, qss)
238
+
239
+ def setCheckedColor(self, light, dark):
240
+ """ set the color in checked status
241
+
242
+ Parameters
243
+ ----------
244
+ light, dark: str | QColor | Qt.GlobalColor
245
+ color in light/dark theme mode
246
+ """
247
+ self.delegate.setCheckedColor(light, dark)
248
+
249
+ def _setHoverRow(self, row: int):
250
+ """ set hovered row """
251
+ self.delegate.setHoverRow(row)
252
+ self.viewport().update()
253
+
254
+ def _setPressedRow(self, row: int):
255
+ """ set pressed row """
256
+ if self.selectionMode() == QTableView.SelectionMode.NoSelection:
257
+ return
258
+
259
+ self.delegate.setPressedRow(row)
260
+ self.viewport().update()
261
+
262
+ def _setSelectedRows(self, indexes: List[QModelIndex]):
263
+ if self.selectionMode() == QTableView.SelectionMode.NoSelection:
264
+ return
265
+
266
+ self.delegate.setSelectedRows(indexes)
267
+ self.viewport().update()
268
+
269
+ def leaveEvent(self, e):
270
+ QTableView.leaveEvent(self, e)
271
+ self._setHoverRow(-1)
272
+
273
+ def resizeEvent(self, e):
274
+ QTableView.resizeEvent(self, e)
275
+ self.viewport().update()
276
+
277
+ def keyPressEvent(self, e: QKeyEvent):
278
+ QTableView.keyPressEvent(self, e)
279
+ self.updateSelectedRows()
280
+
281
+ def mousePressEvent(self, e):
282
+ if e.button() == Qt.LeftButton or self._isSelectRightClickedRow:
283
+ return QTableView.mousePressEvent(self, e)
284
+
285
+ index = self.indexAt(e.pos())
286
+ if index.isValid():
287
+ self._setPressedRow(index.row())
288
+
289
+ QWidget.mousePressEvent(self, e)
290
+
291
+ def mouseReleaseEvent(self, e):
292
+ QTableView.mouseReleaseEvent(self, e)
293
+ self.updateSelectedRows()
294
+
295
+ if self.indexAt(e.pos()).row() < 0 or e.button() == Qt.RightButton:
296
+ self._setPressedRow(-1)
297
+
298
+ def setItemDelegate(self, delegate: TableItemDelegate):
299
+ self.delegate = delegate
300
+ super().setItemDelegate(delegate)
301
+
302
+ def selectAll(self):
303
+ QTableView.selectAll(self)
304
+ self.updateSelectedRows()
305
+
306
+ def selectRow(self, row: int):
307
+ QTableView.selectRow(self, row)
308
+ self.updateSelectedRows()
309
+
310
+ def clearSelection(self):
311
+ QTableView.clearSelection(self)
312
+ self.updateSelectedRows()
313
+
314
+ def setCurrentIndex(self, index: QModelIndex):
315
+ QTableView.setCurrentIndex(self, index)
316
+ self.updateSelectedRows()
317
+
318
+ def updateSelectedRows(self):
319
+ self._setSelectedRows(self.selectedIndexes())
320
+
321
+
322
+ class TableWidget(TableBase, QTableWidget):
323
+ """ Table widget """
324
+
325
+ def __init__(self, parent=None):
326
+ super().__init__(parent)
327
+
328
+ def setCurrentCell(self, row: int, column: int, command=None):
329
+ self.setCurrentItem(self.item(row, column), command)
330
+
331
+ def setCurrentItem(self, item: QTableWidgetItem, command=None):
332
+ if not command:
333
+ super().setCurrentItem(item)
334
+ else:
335
+ super().setCurrentItem(item, command)
336
+
337
+ self.updateSelectedRows()
338
+
339
+ def isSelectRightClickedRow(self):
340
+ return self._isSelectRightClickedRow
341
+
342
+ def setSelectRightClickedRow(self, isSelect: bool):
343
+ self._isSelectRightClickedRow = isSelect
344
+
345
+ selectRightClickedRow = Property(bool, isSelectRightClickedRow, setSelectRightClickedRow)
346
+
347
+
348
+ class TableView(TableBase, QTableView):
349
+ """ Table view """
350
+
351
+ def __init__(self, parent=None):
352
+ super().__init__(parent)
353
+
354
+ def isSelectRightClickedRow(self):
355
+ return self._isSelectRightClickedRow
356
+
357
+ def setSelectRightClickedRow(self, isSelect: bool):
358
+ self._isSelectRightClickedRow = isSelect
359
+
360
+ selectRightClickedRow = Property(bool, isSelectRightClickedRow, setSelectRightClickedRow)