RinUI 0.0.9__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 (102) hide show
  1. RinUI/__init__.py +4 -0
  2. RinUI/__pycache__/__init__.cpython-38.pyc +0 -0
  3. RinUI/assets/fonts/FluentSystemIcons-Index.js +5256 -0
  4. RinUI/assets/fonts/FluentSystemIcons-Resizable.ttf +0 -0
  5. RinUI/assets/img/default_app_icon.png +0 -0
  6. RinUI/components/Base.qml +79 -0
  7. RinUI/components/BasicInput/Button.qml +148 -0
  8. RinUI/components/BasicInput/CheckBox.qml +99 -0
  9. RinUI/components/BasicInput/ComboBox.qml +160 -0
  10. RinUI/components/BasicInput/DropDownButton.qml +21 -0
  11. RinUI/components/BasicInput/Hyperlink.qml +18 -0
  12. RinUI/components/BasicInput/RadioButton.qml +95 -0
  13. RinUI/components/BasicInput/Slider.qml +212 -0
  14. RinUI/components/BasicInput/Switch.qml +102 -0
  15. RinUI/components/BasicInput/ToggleButton.qml +11 -0
  16. RinUI/components/BasicInput/ToolButton.qml +31 -0
  17. RinUI/components/ContextMenu.qml +184 -0
  18. RinUI/components/DateAndTime/PickerView.qml +217 -0
  19. RinUI/components/DateAndTime/TimePicker.qml +115 -0
  20. RinUI/components/DialogsAndFlyouts/Dialog.qml +106 -0
  21. RinUI/components/DialogsAndFlyouts/DialogButtonBox.qml +47 -0
  22. RinUI/components/DialogsAndFlyouts/Flyout.qml +144 -0
  23. RinUI/components/DialogsAndFlyouts/Popup.qml +106 -0
  24. RinUI/components/FocusIndicator.qml +33 -0
  25. RinUI/components/IconWidget.qml +52 -0
  26. RinUI/components/Indicator.qml +90 -0
  27. RinUI/components/Layout/Expander.qml +160 -0
  28. RinUI/components/Layout/SettingExpander.qml +67 -0
  29. RinUI/components/Layout/SettingItem.qml +71 -0
  30. RinUI/components/ListAndCollections/Clip.qml +22 -0
  31. RinUI/components/ListAndCollections/Frame.qml +44 -0
  32. RinUI/components/ListAndCollections/ListView.qml +105 -0
  33. RinUI/components/ListAndCollections/ListViewDelegate.qml +83 -0
  34. RinUI/components/ListAndCollections/SettingCard.qml +73 -0
  35. RinUI/components/ListAndCollections/TableView.qml +82 -0
  36. RinUI/components/ListAndCollections/TableViewDelegate.qml +89 -0
  37. RinUI/components/MenusAndToolbars/Menu.qml +149 -0
  38. RinUI/components/MenusAndToolbars/MenuBar.qml +43 -0
  39. RinUI/components/MenusAndToolbars/MenuItem.qml +119 -0
  40. RinUI/components/MenusAndToolbars/MenuItemGroup.qml +43 -0
  41. RinUI/components/MenusAndToolbars/MenuSeparator.qml +14 -0
  42. RinUI/components/MenusAndToolbars/ToolSeparator.qml +17 -0
  43. RinUI/components/Navigation/ErrorPage.qml +48 -0
  44. RinUI/components/Navigation/NavigationBar.qml +179 -0
  45. RinUI/components/Navigation/NavigationItem.qml +193 -0
  46. RinUI/components/Navigation/NavigationSubItem.qml +103 -0
  47. RinUI/components/Navigation/NavigationView.qml +210 -0
  48. RinUI/components/Navigation/SelectorBar.qml +58 -0
  49. RinUI/components/ScrollBar.qml +163 -0
  50. RinUI/components/ScrollView.qml +13 -0
  51. RinUI/components/Shadow.qml +48 -0
  52. RinUI/components/StatusAndInfo/InfoBadge.qml +78 -0
  53. RinUI/components/StatusAndInfo/InfoBar.qml +246 -0
  54. RinUI/components/StatusAndInfo/ProgressBar.qml +127 -0
  55. RinUI/components/StatusAndInfo/Toast.qml +237 -0
  56. RinUI/components/StatusAndInfo/ToolTip.qml +93 -0
  57. RinUI/components/Text/SpinBox.qml +134 -0
  58. RinUI/components/Text/Text.qml +44 -0
  59. RinUI/components/Text/TextField.qml +94 -0
  60. RinUI/components/Text/TextInput.qml +29 -0
  61. RinUI/components/Utils/Blur.qml +42 -0
  62. RinUI/components/qmldir +76 -0
  63. RinUI/config/rin_ui.json +8 -0
  64. RinUI/core/__init__.py +3 -0
  65. RinUI/core/__pycache__/__init__.cpython-38.pyc +0 -0
  66. RinUI/core/__pycache__/config.cpython-38.pyc +0 -0
  67. RinUI/core/__pycache__/launcher.cpython-38.pyc +0 -0
  68. RinUI/core/__pycache__/theme.cpython-38.pyc +0 -0
  69. RinUI/core/config.py +109 -0
  70. RinUI/core/launcher.py +144 -0
  71. RinUI/core/theme.py +342 -0
  72. RinUI/hooks/__init__.py +3 -0
  73. RinUI/hooks/hook-RinUI.py +3 -0
  74. RinUI/qmldir +92 -0
  75. RinUI/themes/dark.qml +137 -0
  76. RinUI/themes/light.qml +137 -0
  77. RinUI/themes/qmldir +7 -0
  78. RinUI/themes/theme.qml +126 -0
  79. RinUI/themes/utils.qml +28 -0
  80. RinUI/utils/Animation.qml +12 -0
  81. RinUI/utils/FloatLayer.qml +123 -0
  82. RinUI/utils/FontIconLoader.qml +14 -0
  83. RinUI/utils/Position.qml +19 -0
  84. RinUI/utils/Severity.qml +13 -0
  85. RinUI/utils/Typography.qml +17 -0
  86. RinUI/utils/qmldir +5 -0
  87. RinUI/windows/CtrlBtn.qml +119 -0
  88. RinUI/windows/FluentPage.qml +92 -0
  89. RinUI/windows/FluentWindow.qml +32 -0
  90. RinUI/windows/FluentWindowBase.qml +157 -0
  91. RinUI/windows/TitleBar.qml +132 -0
  92. RinUI/windows/qmldir +8 -0
  93. RinUI/windows/window/ApplicationWindow.qml +9 -0
  94. RinUI/windows/window/Window.qml +112 -0
  95. rinui-0.0.9.data/data/LICENSE +21 -0
  96. rinui-0.0.9.data/data/README.md +90 -0
  97. rinui-0.0.9.dist-info/LICENSE +21 -0
  98. rinui-0.0.9.dist-info/METADATA +105 -0
  99. rinui-0.0.9.dist-info/RECORD +102 -0
  100. rinui-0.0.9.dist-info/WHEEL +5 -0
  101. rinui-0.0.9.dist-info/entry_points.txt +2 -0
  102. rinui-0.0.9.dist-info/top_level.txt +1 -0
@@ -0,0 +1,103 @@
1
+ import QtQuick 2.15
2
+ import QtQuick.Controls 2.15
3
+ import "../../themes"
4
+ import "../../components"
5
+
6
+
7
+ ItemDelegate {
8
+ id: root
9
+ property var itemData
10
+ property int parentIndex: -1
11
+ property var currentPage
12
+ highlighted: String(navigationBar.currentPage) === String(itemData.page)
13
+
14
+ height: 40
15
+
16
+ focusPolicy: collapsed ? Qt.NoFocus : Qt.StrongFocus // to get keyboard focus
17
+
18
+ // accessibility
19
+ FocusIndicator {
20
+ control: parent
21
+ anchors.margins: 2
22
+ }
23
+
24
+ width: parent ? parent.width : 200
25
+
26
+ background: Rectangle {
27
+ id: itemBg
28
+ anchors.fill: parent
29
+ anchors.topMargin: 2
30
+ anchors.bottomMargin: 2
31
+ clip: true
32
+ radius: Theme.currentTheme.appearance.buttonRadius / 2
33
+ color: pressed
34
+ ? Theme.currentTheme.colors.subtleTertiaryColor
35
+ : (root.highlighted || root.hovered)
36
+ ? Theme.currentTheme.colors.subtleSecondaryColor
37
+ : Theme.currentTheme.colors.subtleColor
38
+
39
+ Row {
40
+ id: left
41
+ spacing: 16
42
+ anchors.left: parent.left
43
+ anchors.verticalCenter: parent.verticalCenter
44
+ anchors.leftMargin: 11 + 34
45
+ anchors.topMargin: 6
46
+ anchors.bottomMargin: 8
47
+
48
+ IconWidget {
49
+ id: icon
50
+ anchors.verticalCenter: parent.verticalCenter
51
+ size: itemData.icon || itemData.source ? 19 : 0
52
+ icon: itemData.icon || ""
53
+ source: itemData.source || ""
54
+ }
55
+
56
+ Text {
57
+ id: text
58
+ anchors.verticalCenter: parent.verticalCenter
59
+ typography: Typography.Body
60
+ text: itemData.title
61
+ clip: true
62
+ opacity: navigationBar.collapsed ? 0 : 1
63
+ wrapMode: Text.NoWrap
64
+ horizontalAlignment: Text.AlignLeft
65
+
66
+ Behavior on x {
67
+ NumberAnimation {
68
+ duration: Utils.appearanceSpeed
69
+ easing.type: Easing.InOutQuint
70
+ }
71
+ }
72
+
73
+ Behavior on opacity {
74
+ NumberAnimation {
75
+ duration: Utils.appearanceSpeed
76
+ }
77
+ }
78
+ }
79
+ }
80
+
81
+ Indicator {
82
+ id: indicator
83
+ y: root.height / 2 - indicator.height / 2 -2
84
+ currentItemHeight: root.height
85
+ visible: highlighted ? 1 : 0
86
+ width: 3
87
+ }
88
+
89
+ Behavior on color {
90
+ ColorAnimation {
91
+ duration: Utils.appearanceSpeed
92
+ easing.type: Easing.InOutQuart
93
+ }
94
+ }
95
+ }
96
+
97
+ onClicked: {
98
+ if (itemData.page && currentPage && !root.highlighted && !collapsed) {
99
+ // 记录上一次的索引
100
+ navigationView.safePush(itemData.page)
101
+ }
102
+ }
103
+ }
@@ -0,0 +1,210 @@
1
+ import QtQuick 2.15
2
+ import QtQuick.Controls 2.15
3
+ import QtQuick.Layouts 2.15
4
+ import "../../themes"
5
+ import "../../components"
6
+ import "../../windows"
7
+
8
+
9
+ RowLayout {
10
+ // 外观 / Appearance //
11
+ property bool appLayerEnabled: true // 应用层背景
12
+ property alias navExpandWidth: navigationBar.expandWidth // 导航栏宽度
13
+ property alias navMinimumExpandWidth: navigationBar.minimumExpandWidth // 导航栏保持展开时窗口的最小宽度
14
+
15
+ property alias navigationItems: navigationBar.navigationItems // 导航栏item
16
+ property string defaultPage: "" // 默认索引项
17
+ property var lastPages: [] // 上个页面索引
18
+ property int pushEnterFromY: height
19
+ property var window: parent // 窗口对象
20
+
21
+ id: navigationView
22
+ anchors.fill: parent
23
+
24
+ Connections {
25
+ target: window
26
+ function onWidthChanged() {
27
+ navigationBar.collapsed = navigationBar.isNotOverMinimumWidth() // 判断窗口是否小于最小宽度
28
+ }
29
+ }
30
+
31
+ NavigationBar {
32
+ id: navigationBar
33
+ windowTitle: window.title
34
+ windowIcon: window.icon
35
+ windowWidth: window.width
36
+ stackView: stackView
37
+ z: 999
38
+ Layout.fillHeight: true
39
+ }
40
+
41
+ // 主体内容区域
42
+ Item {
43
+ Layout.fillWidth: true
44
+ Layout.fillHeight: true
45
+ // clip: true
46
+
47
+ Rectangle {
48
+ id: appLayer
49
+ width: parent.width + Utils.windowDragArea + radius
50
+ height: parent.height + Utils.windowDragArea + radius
51
+ color: Theme.currentTheme.colors.layerColor
52
+ border.color: Theme.currentTheme.colors.cardBorderColor
53
+ border.width: 1
54
+ opacity: window.appLayerEnabled
55
+ radius: Theme.currentTheme.appearance.windowRadius
56
+ }
57
+
58
+
59
+ StackView {
60
+ id: stackView
61
+ anchors.fill: parent
62
+ anchors.leftMargin: 1
63
+ anchors.topMargin: 1
64
+
65
+
66
+ // 切换动画 / Page Transition //
67
+ pushEnter : Transition {
68
+ PropertyAnimation {
69
+ property: "opacity"
70
+ from: 0
71
+ to: 1
72
+ duration: Utils.animationSpeed
73
+ easing.type: Easing.InOutQuad
74
+ }
75
+
76
+ PropertyAnimation {
77
+ property: "y"
78
+ from: pushEnterFromY
79
+ to: 0
80
+ duration: Utils.animationSpeedMiddle
81
+ easing.type: Easing.OutQuint
82
+ }
83
+ }
84
+
85
+ pushExit : Transition {
86
+ PropertyAnimation {
87
+ property: "opacity"
88
+ from: 1
89
+ to: 0
90
+ duration: Utils.animationSpeed
91
+ easing.type: Easing.InOutQuad
92
+ }
93
+ }
94
+
95
+ popExit : Transition {
96
+ PropertyAnimation {
97
+ property: "opacity"
98
+ from: 1
99
+ to: 0
100
+ duration: Utils.animationSpeed
101
+ easing.type: Easing.InOutQuad
102
+ }
103
+
104
+ PropertyAnimation {
105
+ property: "y"
106
+ from: 0
107
+ to: pushEnterFromY
108
+ duration: Utils.animationSpeedMiddle
109
+ easing.type: Easing.InOutQuint
110
+ }
111
+ }
112
+
113
+ popEnter : Transition {
114
+ SequentialAnimation {
115
+ PauseAnimation { // 延时 200ms
116
+ duration: Utils.animationSpeed
117
+ }
118
+ PropertyAnimation {
119
+ property: "opacity"
120
+ from: 0
121
+ to: 1
122
+ duration: Utils.appearanceSpeed
123
+ easing.type: Easing.InOutQuad
124
+ }
125
+ }
126
+ }
127
+
128
+ initialItem: Item {}
129
+
130
+ }
131
+
132
+ // 导航切换逻辑
133
+ // Connections {
134
+ // target: navigationBar
135
+ // function onCurrentIndexChanged() {
136
+ // let index = navigationBar.currentIndex
137
+ // let page = navigationItems[index].page
138
+ // console.log("Pushing Page:", page, "Index:", index)
139
+ // if (stackView.depth === 0 || stackView.currentItem.objectName !== page) {
140
+ // checkPage(page)
141
+ // }
142
+ // }
143
+ // }
144
+
145
+
146
+ Component.onCompleted: {
147
+ if (navigationItems.length > 0) {
148
+ if (defaultPage !== "") {
149
+ safePush(defaultPage, false)
150
+ } else {
151
+ safePush(navigationItems[0].page, false) // 推送默认页面
152
+ } // 推送页面
153
+ }
154
+ }
155
+ }
156
+
157
+ function safePop() {
158
+ console.log("Popping Page; Depth:", stackView.depth)
159
+ if (navigationBar.lastPages.length > 1) {
160
+ navigationBar.currentPage = navigationBar.lastPages.pop() // Retrieve and remove the last page
161
+ navigationBar.lastPages = navigationBar.lastPages // refresh
162
+ stackView.pop()
163
+ } else {
164
+ console.log("Can't pop: only root page left")
165
+ }
166
+ }
167
+
168
+ function safePush(page, reload) {
169
+ // 无效检测
170
+ if (!(typeof page === "object" || typeof page === "string" || page instanceof Component)) {
171
+ console.error("Invalid page:", page)
172
+ return
173
+ }
174
+
175
+ // 重复检测
176
+ if (navigationBar.currentPage === page && !reload) {
177
+ console.log("Page already loaded:", page)
178
+ return
179
+ }
180
+
181
+ navigationBar.lastPages.push(navigationBar.currentPage) // 记录当前页面
182
+ navigationBar.lastPages = navigationBar.lastPages // refresh
183
+ navigationBar.currentPage = page.toString()
184
+
185
+ if (page instanceof Component) {
186
+ // let obj = page.createObject(stackView)
187
+ stackView.push(page)
188
+
189
+ } else if (typeof page === "object" || typeof page === "string" ) {
190
+ let component = Qt.createComponent(page) // 页面转控件
191
+
192
+ if (component.status === Component.Ready) {
193
+ console.log("Depth:", stackView.depth)
194
+ stackView.push(component)
195
+
196
+ } else if (component.status === Component.Error) {
197
+ console.error("Failed to load:", page, component.errorString())
198
+ stackView.push("ErrorPage.qml", {
199
+ errorMessage: component.errorString(), // 传参
200
+ page: page,
201
+ })
202
+ }
203
+ }
204
+ }
205
+
206
+ function findPageByKey(key) {
207
+ const item = menuItems.find(i => i.key === key);
208
+ return item ? item.page : null;
209
+ }
210
+ }
@@ -0,0 +1,58 @@
1
+ import QtQuick 2.15
2
+ import QtQuick.Controls 2.15
3
+ import QtQuick.Layouts 2.15
4
+ import "../../components"
5
+ import "../../themes"
6
+
7
+
8
+ RowLayout {
9
+ id: root
10
+ property var model: []
11
+ property int currentIndex: -1
12
+ property bool enabled: true
13
+ // 自动检测模型类型
14
+ readonly property string modelType: {
15
+ if (!model) return "null";
16
+ if (Array.isArray(model) && typeof model[0] === "object") return "array-with-role";
17
+ if (Array.isArray(model)) return "array";
18
+ if (model instanceof ListModel) return "listmodel";
19
+ if (typeof model === "object" && "count" in model) return "listmodel-like";
20
+ return "unknown";
21
+ }
22
+
23
+ implicitHeight: 40
24
+ spacing: 0
25
+
26
+ Repeater {
27
+ model: root.model
28
+ delegate: Button {
29
+ Layout.fillWidth: true
30
+ Layout.fillHeight: true
31
+ Layout.preferredHeight: 40
32
+ flat: true
33
+
34
+ background: Item {}
35
+
36
+ text: {
37
+ switch (root.modelType) {
38
+ case "array": return modelData;
39
+ case "array-with-role": return modelData["text"] || modelData || "";
40
+ case "listmodel":
41
+ case "listmodel-like":
42
+ return model["text"] || modelData || "";
43
+ default: return "";
44
+ }
45
+ }
46
+ icon.name: root.modelType === "array-with-role" ? modelData["icon"] : ""
47
+ icon.source: root.modelType === "array-with-role" ? modelData["source"] : ""
48
+
49
+ onClicked: root.currentIndex = index
50
+ enabled: root.enabled
51
+
52
+ Indicator {
53
+ orientation: Qt.Horizontal
54
+ visible: index === root.currentIndex
55
+ }
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,163 @@
1
+ import QtQuick 2.15
2
+ import QtQuick.Templates 2.15 // 从Templates导入ScrollBar,否则qt6强制用原生样式……byd我看了大半天
3
+ import "../themes"
4
+ import "../components"
5
+
6
+ ScrollBar {
7
+ id: scrollBar
8
+
9
+ property int minimumWidth: Theme.currentTheme.appearance.scrollBarMinWidth
10
+ property int expandWidth: Theme.currentTheme.appearance.scrollBarWidth
11
+
12
+ // 宽高
13
+ implicitWidth: horizontal ? parent.width
14
+ : (implicitContentWidth + leftPadding + rightPadding)
15
+ implicitHeight: vertical ? parent.height
16
+ : (implicitContentHeight + topPadding + bottomPadding)
17
+
18
+ // 锚点 //
19
+ anchors.verticalCenter: vertical ? parent.verticalCenter : undefined
20
+ anchors.horizontalCenter: horizontal ? parent.horizontalCenter : undefined
21
+ anchors.right: vertical ? parent.right : undefined
22
+ anchors.bottom: horizontal ? parent.bottom : undefined
23
+
24
+ verticalPadding : vertical ? 15 : 3
25
+ horizontalPadding : horizontal ? 15 : 3
26
+ enabled: size < 1.0
27
+
28
+
29
+ // 内容 / Content //
30
+ contentItem: Item {
31
+ id: item
32
+ // collapsed / 收缩状态 //
33
+ property bool collapsed: (
34
+ scrollBar.policy === ScrollBar.AlwaysOn || (scrollBar.active)
35
+ ) // 当滚动条处于AlwaysOn状态或处于激活状态且尺寸小于1.0时,则为收缩状态
36
+
37
+ // 最小尺寸 / Minimum Size //
38
+ implicitWidth: scrollBar.interactive ? scrollBar.expandWidth : scrollBar.minimumWidth
39
+ implicitHeight: scrollBar.interactive ? scrollBar.expandWidth : scrollBar.minimumWidth
40
+
41
+ Rectangle{
42
+ id: bar
43
+ width: vertical ? scrollBar.minimumWidth : parent.width
44
+ height: horizontal ? scrollBar.minimumWidth : parent.height
45
+ color: Theme.currentTheme.colors.controlStrongColor
46
+ anchors{
47
+ right: vertical ? parent.right : undefined
48
+ bottom: horizontal ? parent.bottom : undefined
49
+ }
50
+ radius: 9999
51
+ visible: scrollBar.size < 1.0
52
+
53
+ Behavior on color {
54
+ ColorAnimation {
55
+ duration: Utils.appearanceSpeed
56
+ easing.type: Easing.OutCubic
57
+ }
58
+ }
59
+ }
60
+
61
+ states: [
62
+ State{
63
+ name: "collapsed"
64
+ when: contentItem.collapsed
65
+ PropertyChanges {
66
+ target: bar
67
+ width: vertical ? scrollBar.expandWidth : parent.width
68
+ height: horizontal ? scrollBar.expandWidth : parent.height
69
+ }
70
+ },
71
+ State{
72
+ name: "minimum"
73
+ when: !contentItem.collapsed
74
+ PropertyChanges {
75
+ target: bar
76
+ width: vertical ? scrollBar.minimumWidth : parent.width
77
+ height: horizontal ? scrollBar.minimumWidth : parent.height
78
+ }
79
+ }
80
+ ]
81
+ transitions:[
82
+ Transition {
83
+ to: "minimum"
84
+ SequentialAnimation {
85
+ PauseAnimation { duration: 450 } // 等待时长
86
+ NumberAnimation {
87
+ target: bar
88
+ properties: vertical ? "width" : "height"
89
+ duration: 167
90
+ easing.type: Easing.OutCubic
91
+ }
92
+ }
93
+ },
94
+ Transition {
95
+ to: "collapsed"
96
+ SequentialAnimation {
97
+ PauseAnimation { duration: 150 }
98
+ NumberAnimation {
99
+ target: bar
100
+ properties: vertical ? "width" : "height"
101
+ duration: 167
102
+ easing.type: Easing.OutCubic
103
+ }
104
+ }
105
+ }
106
+ ]
107
+ }
108
+ // 背景 / Background //
109
+ background: Rectangle{
110
+ id: background
111
+ radius: 5
112
+ color: Theme.currentTheme.colors.backgroundAcrylicColor
113
+ opacity: 0
114
+ visible: scrollBar.size < 1.0
115
+
116
+ states: [
117
+ State{
118
+ name: "show"
119
+ when: contentItem.collapsed
120
+ PropertyChanges {
121
+ target: background
122
+ opacity: 1
123
+ }
124
+ },
125
+ State{
126
+ name: "hide"
127
+ when: !contentItem.collapsed
128
+ PropertyChanges {
129
+ target: background
130
+ opacity: 0
131
+ }
132
+ }
133
+ ]
134
+
135
+ // 动画
136
+ transitions:[
137
+ Transition {
138
+ to: "hide"
139
+ SequentialAnimation {
140
+ PauseAnimation { duration: 450 } // 等待时长
141
+ NumberAnimation {
142
+ target: background
143
+ properties: "opacity"
144
+ duration: 167
145
+ easing.type: Easing.OutCubic
146
+ }
147
+ }
148
+ },
149
+ Transition {
150
+ to: "show"
151
+ SequentialAnimation {
152
+ PauseAnimation { duration: 150 }
153
+ NumberAnimation {
154
+ target: background
155
+ properties: "opacity"
156
+ duration: 167
157
+ easing.type: Easing.OutCubic
158
+ }
159
+ }
160
+ }
161
+ ]
162
+ }
163
+ }
@@ -0,0 +1,13 @@
1
+ import QtQuick 2.15
2
+ import QtQuick.Templates 2.15
3
+ import "../themes"
4
+ import "../components"
5
+
6
+ ScrollView {
7
+ ScrollBar.vertical: ScrollBar {
8
+ policy: ScrollBar.AsNeeded
9
+ }
10
+ ScrollBar.horizontal: ScrollBar {
11
+ policy: ScrollBar.AsNeeded
12
+ }
13
+ }
@@ -0,0 +1,48 @@
1
+ import QtQuick 2.15
2
+ import QtQuick.Controls 2.15
3
+ import Qt5Compat.GraphicalEffects
4
+ import "../themes"
5
+
6
+ DropShadow {
7
+ property string style: "cardRest" // shadow style
8
+
9
+ anchors.fill: source
10
+ horizontalOffset: 0
11
+ verticalOffset: Theme.currentTheme.shadows[style].offsetY
12
+ radius: Theme.currentTheme.shadows[style].blur
13
+ color: Theme.currentTheme.shadows[style].color
14
+ samples: 1 + radius * 2
15
+ // source: sourceItem
16
+ cached: true
17
+ }
18
+
19
+ // Repeater {
20
+ // id: shadowRepeater
21
+ // property string style: "cardRest"
22
+ // property int blurRadius: Theme.currentTheme.shadows[style].blur
23
+ // property int offsetY: Theme.currentTheme.shadows[style].offsetY
24
+ // property real intensity: 1.5 // 阴影强度系数
25
+ // property real spreadRatio: 1 // 阴影扩散系数
26
+ // property real controlRadius: 8 // 控制半径
27
+ // readonly property color shadowColor: Theme.currentTheme.shadows[style].color
28
+ //
29
+ // model: Math.max(blurRadius, 16) // 保证最小8层渲染
30
+ //
31
+ // Rectangle {
32
+ // anchors {
33
+ // fill: parent
34
+ // margins: -index * spreadRatio // 非线性扩散
35
+ // topMargin: -index * spreadRatio + (offsetY) // 动态偏移分配
36
+ // }
37
+ //
38
+ // color: "transparent"
39
+ // radius: controlRadius + (index * spreadRatio) // 优化半径增长曲线
40
+ // border.width: 1
41
+ // border.color: shadowColor
42
+ //
43
+ // // 非线性透明度衰减
44
+ // opacity: (0.011 * (count - index + 1)) * shadowRepeater.opacity
45
+ //
46
+ // z: -1
47
+ // }
48
+ // }
@@ -0,0 +1,78 @@
1
+ import QtQuick 2.15
2
+ import QtQuick.Controls.Basic 2.15
3
+ import QtQuick.Layouts 2.15
4
+ import "../../themes"
5
+ import "../../components"
6
+
7
+
8
+ Rectangle {
9
+ id: root
10
+ property int count: -1
11
+ property string text: {
12
+ if (root.count < 0)
13
+ return ""
14
+ else if (root.count > maxCount)
15
+ return maxCount + "+"
16
+ else
17
+ return count.toString()
18
+ }
19
+ property int maxCount: 99
20
+ property string icon: {
21
+ switch (severity) {
22
+ case Severity.Info: return "ic_fluent_text_asterisk_20_filled";
23
+ case Severity.Success: return "ic_fluent_checkmark_20_filled";
24
+ case Severity.Warning: return "!";
25
+ case Severity.Error: return "ic_fluent_dismiss_20_filled";
26
+ default: return "";
27
+ }
28
+ }
29
+ property bool dot: false
30
+ property int severity: Severity.Info
31
+
32
+ property bool solid: true
33
+ property color primaryColor: {
34
+ switch (severity) {
35
+ case Severity.Info: return Theme.currentTheme.colors.systemAttentionColor;
36
+ case Severity.Success: return Theme.currentTheme.colors.systemSuccessColor;
37
+ case Severity.Warning: return Theme.currentTheme.colors.systemCautionColor;
38
+ case Severity.Error: return Theme.currentTheme.colors.systemCriticalColor;
39
+ default: return Theme.currentTheme.colors.systemNeutralColor;
40
+ }
41
+ }
42
+
43
+ width: dot ? 4 : Math.max(contents.width + 6, 16) + !solid * 2
44
+ height: dot ? 4 : 16 + !solid * 2
45
+ radius: height / 2
46
+
47
+ RowLayout {
48
+ id: contents
49
+ anchors.centerIn: parent
50
+ spacing: 4
51
+ visible: !root.dot
52
+
53
+ IconWidget {
54
+ icon: root.icon
55
+ size: 10
56
+ color: solid ? Theme.currentTheme.colors.textOnAccentColor : primaryColor
57
+ visible: !root.text
58
+ }
59
+
60
+ Text {
61
+ typography: Typography.Caption
62
+ text: root.text
63
+ color: solid ? Theme.currentTheme.colors.textOnAccentColor : primaryColor
64
+ visible: root.text
65
+ }
66
+ }
67
+
68
+ color: solid ? primaryColor : "transparent"
69
+ border.width: Theme.currentTheme.appearance.borderWidth
70
+ border.color: solid ? "transparent" : primaryColor
71
+
72
+ Behavior on color {
73
+ ColorAnimation {
74
+ duration: Utils.appearanceSpeed
75
+ easing.type: Easing.OutQuint
76
+ }
77
+ }
78
+ }