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,246 @@
1
+ import QtQuick 2.15
2
+ import QtQuick.Layouts 2.15
3
+ import "../../themes"
4
+ import "../../components"
5
+
6
+
7
+ Frame {
8
+ id: infoBar
9
+ property string title: ""
10
+ property string text: ""
11
+ property int severity: Severity.Info
12
+ property alias customContent: custom.data
13
+ property int timeout: -1
14
+ property int position: 0
15
+ property bool isDynamic: false // 动态创建
16
+ property bool closable: true // 显示关闭按钮
17
+ property bool iconVisible: true // 显示图标
18
+ property real startPosX: {
19
+ switch (position) {
20
+ case Position.TopLeft:
21
+ case Position.BottomLeft:
22
+ return -width / 2;
23
+ case Position.TopRight:
24
+ case Position.BottomRight:
25
+ return width / 2;
26
+ default:
27
+ return 0;
28
+ }
29
+ }
30
+
31
+ property real startPosY: 0
32
+ readonly property real endPosX: x
33
+
34
+
35
+ function calculateStartPosY() {
36
+ switch (position) {
37
+ case Position.Top:
38
+ return -height / 2 ;
39
+ case Position.Bottom:
40
+ return height / 2 ;
41
+ default:
42
+ return 0;
43
+ }
44
+ }
45
+
46
+ color: {
47
+ switch (severity) {
48
+ case Severity.Info: return Theme.currentTheme.colors.systemAttentionBackgroundColor;
49
+ case Severity.Success: return Theme.currentTheme.colors.systemSuccessBackgroundColor;
50
+ case Severity.Warning: return Theme.currentTheme.colors.systemCautionBackgroundColor;
51
+ case Severity.Error: return Theme.currentTheme.colors.systemCriticalBackgroundColor;
52
+ default: return Theme.currentTheme.colors.systemNeutralBackgroundColor;
53
+ }
54
+ }
55
+
56
+ // width: 200
57
+ Layout.fillWidth: true
58
+ padding: 5
59
+ leftPadding: 15
60
+ hoverable: false
61
+ opacity: 0
62
+
63
+ Timer {
64
+ id: autoCloseTimer
65
+ interval: timeout
66
+ running: timeout >= 0
67
+ repeat: false
68
+ onTriggered: {
69
+ // infoBar.visible = false
70
+ // infoBar.destroy()
71
+ exitAnimation.start()
72
+ }
73
+ }
74
+
75
+ RowLayout {
76
+ id: main
77
+ anchors.fill: parent
78
+ spacing: 13
79
+
80
+ IconWidget {
81
+ id: iconWidget
82
+ Layout.preferredHeight: 38
83
+ Layout.alignment: Qt.AlignTop
84
+ size: 18
85
+ icon: {
86
+ switch (severity) {
87
+ case Severity.Info: return "ic_fluent_info_20_filled";
88
+ case Severity.Success: return "ic_fluent_checkmark_circle_20_filled";
89
+ case Severity.Warning: return "ic_fluent_error_circle_20_filled";
90
+ case Severity.Error: return "ic_fluent_dismiss_circle_20_filled";
91
+ default: return "ic_fluent_question_circle_20_filled";
92
+ }
93
+ }
94
+ color: {
95
+ switch (severity) {
96
+ case Severity.Info: return Theme.currentTheme.colors.systemAttentionColor;
97
+ case Severity.Success: return Theme.currentTheme.colors.systemSuccessColor;
98
+ case Severity.Warning: return Theme.currentTheme.colors.systemCautionColor;
99
+ case Severity.Error: return Theme.currentTheme.colors.systemCriticalColor;
100
+ default: return Theme.currentTheme.colors.systemNeutralColor;
101
+ }
102
+ }
103
+ visible: iconVisible
104
+ }
105
+
106
+ Flow {
107
+ Layout.alignment: Qt.AlignTop
108
+ Layout.fillWidth: true
109
+ Layout.topMargin: 3
110
+ // Layout.bottomMargin: 8
111
+ spacing: bodyText.wrap ? 0 :12
112
+
113
+ Text {
114
+ id: titleText
115
+ typography: Typography.BodyStrong
116
+ text: infoBar.title
117
+ topPadding: 6
118
+ }
119
+ Text {
120
+ id: bodyText
121
+ property bool wrap: (parent.width - titleText.width - custom.width - 24) < implicitWidth
122
+ width: wrap ?
123
+ parent.width : implicitWidth
124
+ typography: Typography.Body
125
+ text: infoBar.text
126
+ topPadding: wrap? 0 : 6
127
+ }
128
+
129
+ Item {
130
+ width: parent.width
131
+ height: bodyText.wrap && custom.children.length > 0 ? 16 : 0
132
+ }
133
+ Row {
134
+ id: custom
135
+ spacing: 6
136
+ }
137
+ Item {
138
+ width: parent.width
139
+ height: bodyText.wrap ? 9 : 0
140
+ }
141
+ }
142
+
143
+ RowLayout {
144
+ id: rights
145
+ Layout.alignment: Qt.AlignTop
146
+
147
+ ToolButton {
148
+ Layout.alignment: Qt.AlignTop
149
+ id: closeButton
150
+ flat: true
151
+ icon.name: "ic_fluent_dismiss_20_regular"
152
+ size: 18
153
+ Layout.preferredWidth: 38
154
+ Layout.preferredHeight: 38
155
+ visible: closable
156
+ onClicked: {
157
+ exitAnimation.start()
158
+ // if (infoBar.isDynamic) {
159
+ // infoBar.destroy()
160
+ // } else {
161
+ // infoBar.visible = false
162
+ // }
163
+ }
164
+ ToolTip {
165
+ text: qsTr("Close")
166
+ parent: parent
167
+ visible: parent.hovered
168
+ }
169
+ }
170
+ }
171
+ }
172
+
173
+
174
+ // Animations
175
+ Component.onCompleted: {
176
+ startPosY = calculateStartPosY();
177
+ enterAnimation.start()
178
+ }
179
+
180
+ // Behavior on y { NumberAnimation { duration: Utils.animationSpeed; easing.type: Easing.OutQuint } }
181
+ transform: Translate {
182
+ id: slideTransform
183
+ y: 0
184
+ }
185
+
186
+ ParallelAnimation {
187
+ id: enterAnimation
188
+
189
+ NumberAnimation{
190
+ target: infoBar
191
+ property: "x"
192
+ from: infoBar.startPosX
193
+ to: infoBar.endPosX
194
+ easing.type: Easing.OutQuart
195
+ duration: Utils.animationSpeed
196
+ }
197
+ NumberAnimation {
198
+ target: slideTransform
199
+ property: "y"
200
+ from: infoBar.startPosY
201
+ to: 0
202
+ easing.type: Easing.OutCubic
203
+ duration: Utils.animationSpeed
204
+ }
205
+ NumberAnimation{
206
+ target: infoBar
207
+ property: "opacity"
208
+ from: 0
209
+ to: 1
210
+ duration: Utils.appearanceSpeed
211
+ }
212
+ }
213
+
214
+ SequentialAnimation{
215
+ id: exitAnimation
216
+
217
+ ParallelAnimation{
218
+ NumberAnimation{
219
+ target: infoBar
220
+ property: "y"
221
+ to: infoBar.startPosY
222
+ easing.type: Easing.OutQuart
223
+ duration: Utils.animationSpeed
224
+ running: false
225
+ }
226
+ NumberAnimation{
227
+ target: infoBar
228
+ property: "opacity"
229
+ from: 1
230
+ to: 0
231
+ duration: Utils.appearanceSpeed
232
+ }
233
+ }
234
+ ScriptAction{
235
+ script: {
236
+ if (infoBar.isDynamic) {
237
+ infoBar.destroy()
238
+ } else {
239
+ infoBar.visible = false
240
+ infoBar.opacity = 1
241
+ infoBar.y = 0
242
+ }
243
+ }
244
+ }
245
+ }
246
+ }
@@ -0,0 +1,127 @@
1
+ import QtQuick 2.15
2
+ import QtQuick.Controls.Basic 2.15
3
+ import Qt5Compat.GraphicalEffects 1.0
4
+ import "../../themes"
5
+ import "../../components"
6
+
7
+ ProgressBar {
8
+ id: root
9
+
10
+ property color backgroundColor: indeterminate
11
+ ? "transparent"
12
+ : Theme.currentTheme.colors.controlBorderStrongColor
13
+ property color primaryColor: Theme.currentTheme.colors.primaryColor
14
+ property int radius: 99
15
+ property int state: ProgressBar.Running
16
+ enum State {
17
+ Running,
18
+ Paused,
19
+ Error
20
+ }
21
+
22
+ // 尺寸规范
23
+ implicitWidth: 200
24
+ implicitHeight: 3
25
+ value: 0
26
+
27
+ // 背景轨道
28
+ background: Rectangle {
29
+ anchors.verticalCenter: parent.verticalCenter
30
+ width: parent.width
31
+ height: 1
32
+ radius: root.radius
33
+ color: backgroundColor
34
+ Text {
35
+ text: root.state
36
+ }
37
+ }
38
+
39
+ // 遮罩
40
+ layer.enabled: true
41
+ layer.smooth: true
42
+ layer.effect: OpacityMask {
43
+ maskSource: Rectangle {
44
+ width: root.width
45
+ height: root.height
46
+ radius: root.radius
47
+ }
48
+ }
49
+
50
+ // 进度指示
51
+ contentItem: Rectangle {
52
+ id: indicator
53
+ height: parent.height
54
+ radius: root.radius
55
+ color: root.state === 1 ? Theme.currentTheme.colors.systemCautionColor :
56
+ root.state === 2 ? Theme.currentTheme.colors.systemCriticalColor :
57
+ Theme.currentTheme.colors.primaryColor
58
+
59
+ width: indeterminate ? state === 0 ? root.width / 3 : parent.width : root.visualPosition * parent.width
60
+ x: indeterminate ? -indicator.width : 0
61
+
62
+ NumberAnimation {
63
+ target: indicator
64
+
65
+ property: "x"
66
+ from: -indicator.width
67
+ to: root.width
68
+ duration: Utils.progressBarAnimationSpeed
69
+ loops: Animation.Infinite
70
+ easing.type: Easing.InOutQuart
71
+
72
+ running: indeterminate && state === 0
73
+ }
74
+
75
+ // 进度动画
76
+ Behavior on width {
77
+ enabled: !indeterminate
78
+ NumberAnimation {
79
+ duration: Utils.animationSpeed // 175
80
+ easing.type: Easing.OutCubic
81
+ }
82
+ }
83
+ Behavior on color {
84
+ ColorAnimation {
85
+ duration: Utils.animationSpeed
86
+ easing.type: Easing.OutCubic
87
+ }
88
+ }
89
+ }
90
+
91
+ // 归位动画
92
+ SequentialAnimation {
93
+ running: indeterminate && state !== 0
94
+ NumberAnimation {
95
+ target: indicator
96
+ property: "width"
97
+ from: indicator.width
98
+ to: root.width / 10
99
+ duration: Utils.animationSpeedFaster
100
+ easing.type: Easing.InQuart
101
+ }
102
+ NumberAnimation {
103
+ target: indicator
104
+ property: "width"
105
+ from: 0
106
+ to: root.width
107
+ duration: Utils.animationSpeedMiddle
108
+ easing.type: Easing.OutQuint
109
+ }
110
+ }
111
+
112
+ onStateChanged: {
113
+ if (state !== 0 && indeterminate) {
114
+ indicator.x = 0
115
+ } else if (state === 0 && indeterminate) {
116
+ indicator.width = root.width / 3
117
+ }
118
+ }
119
+
120
+ Component.onCompleted: {
121
+ if (!indeterminate) {
122
+ indicator.width = root.visualPosition * root.width
123
+ } else {
124
+ indicator.width = state === 0 ? root.width / 3 : parent.width
125
+ }
126
+ }
127
+ }
@@ -0,0 +1,237 @@
1
+ import QtQuick 2.15
2
+ import QtQuick.Layouts 2.15
3
+ import "../../themes"
4
+ import "../../components"
5
+
6
+
7
+ Frame {
8
+ id: infoBar
9
+ property string title: ""
10
+ property string text: ""
11
+ property int timeout: -1
12
+ property int position: 0
13
+ property bool isDynamic: false // 动态创建
14
+ property bool closable: true // 显示关闭按钮
15
+ property bool iconVisible: true // 显示图标
16
+ property real startPosX: {
17
+ switch (position) {
18
+ case Position.TopLeft:
19
+ case Position.BottomLeft:
20
+ return -width / 2;
21
+ case Position.TopRight:
22
+ case Position.BottomRight:
23
+ return width / 2;
24
+ default:
25
+ return 0;
26
+ }
27
+ }
28
+
29
+ property real startPosY: 0
30
+ readonly property real endPosX: x
31
+
32
+
33
+ function calculateStartPosY() {
34
+ switch (position) {
35
+ case Position.Top:
36
+ return -height / 2 ;
37
+ case Position.Bottom:
38
+ return height / 2 ;
39
+ default:
40
+ return 0;
41
+ }
42
+ }
43
+
44
+ color: Theme.currentTheme.colors.backgroundAcrylicColor
45
+ borderColor: Theme.currentTheme.colors.flyoutBorderColor
46
+
47
+ // width: 200
48
+ Layout.fillWidth: true
49
+ padding: 5
50
+ leftPadding: 15
51
+ hoverable: false
52
+ opacity: 0
53
+
54
+ Timer {
55
+ id: autoCloseTimer
56
+ interval: timeout
57
+ running: timeout >= 0
58
+ repeat: false
59
+ onTriggered: {
60
+ // infoBar.visible = false
61
+ // infoBar.destroy()
62
+ exitAnimation.start()
63
+ }
64
+ }
65
+
66
+ RowLayout {
67
+ id: main
68
+ anchors.fill: parent
69
+ spacing: 13
70
+
71
+ IconWidget {
72
+ id: iconWidget
73
+ Layout.preferredHeight: 38
74
+ Layout.alignment: Qt.AlignTop
75
+ size: 18
76
+ icon: {
77
+ switch (severity) {
78
+ case Severity.Info: return "ic_fluent_info_20_filled";
79
+ case Severity.Success: return "ic_fluent_checkmark_circle_20_filled";
80
+ case Severity.Warning: return "ic_fluent_error_circle_20_filled";
81
+ case Severity.Error: return "ic_fluent_dismiss_circle_20_filled";
82
+ default: return "ic_fluent_question_circle_20_filled";
83
+ }
84
+ }
85
+ color: {
86
+ switch (severity) {
87
+ case Severity.Info: return Theme.currentTheme.colors.systemAttentionColor;
88
+ case Severity.Success: return Theme.currentTheme.colors.systemSuccessColor;
89
+ case Severity.Warning: return Theme.currentTheme.colors.systemCautionColor;
90
+ case Severity.Error: return Theme.currentTheme.colors.systemCriticalColor;
91
+ default: return Theme.currentTheme.colors.systemNeutralColor;
92
+ }
93
+ }
94
+ visible: iconVisible
95
+ }
96
+
97
+ Flow {
98
+ Layout.alignment: Qt.AlignTop
99
+ Layout.fillWidth: true
100
+ Layout.topMargin: 3
101
+ // Layout.bottomMargin: 8
102
+ spacing: bodyText.wrap ? 0 :12
103
+
104
+ Text {
105
+ id: titleText
106
+ typography: Typography.BodyStrong
107
+ text: infoBar.title
108
+ topPadding: 6
109
+ }
110
+ Text {
111
+ id: bodyText
112
+ property bool wrap: (parent.width - titleText.width - custom.width - 24) < implicitWidth
113
+ width: wrap ?
114
+ parent.width : implicitWidth
115
+ typography: Typography.Body
116
+ text: infoBar.text
117
+ topPadding: wrap? 0 : 6
118
+ }
119
+
120
+ Item {
121
+ width: parent.width
122
+ height: bodyText.wrap && custom.children.length > 0 ? 16 : 0
123
+ }
124
+ Row {
125
+ id: custom
126
+ spacing: 6
127
+ }
128
+ Item {
129
+ width: parent.width
130
+ height: bodyText.wrap ? 9 : 0
131
+ }
132
+ }
133
+
134
+ RowLayout {
135
+ id: rights
136
+ Layout.alignment: Qt.AlignTop
137
+
138
+ ToolButton {
139
+ Layout.alignment: Qt.AlignTop
140
+ id: closeButton
141
+ flat: true
142
+ icon.name: "ic_fluent_dismiss_20_regular"
143
+ size: 18
144
+ Layout.preferredWidth: 38
145
+ Layout.preferredHeight: 38
146
+ visible: closable
147
+ onClicked: {
148
+ exitAnimation.start()
149
+ // if (infoBar.isDynamic) {
150
+ // infoBar.destroy()
151
+ // } else {
152
+ // infoBar.visible = false
153
+ // }
154
+ }
155
+ ToolTip {
156
+ text: qsTr("Close")
157
+ parent: parent
158
+ visible: parent.hovered
159
+ }
160
+ }
161
+ }
162
+ }
163
+
164
+
165
+ // Animations
166
+ Component.onCompleted: {
167
+ startPosY = calculateStartPosY();
168
+ enterAnimation.start()
169
+ }
170
+
171
+ // Behavior on y { NumberAnimation { duration: Utils.animationSpeed; easing.type: Easing.OutQuint } }
172
+ transform: Translate {
173
+ id: slideTransform
174
+ y: 0
175
+ }
176
+
177
+ ParallelAnimation {
178
+ id: enterAnimation
179
+
180
+ NumberAnimation{
181
+ target: infoBar
182
+ property: "x"
183
+ from: infoBar.startPosX
184
+ to: infoBar.endPosX
185
+ easing.type: Easing.OutQuart
186
+ duration: Utils.animationSpeed
187
+ }
188
+ NumberAnimation {
189
+ target: slideTransform
190
+ property: "y"
191
+ from: infoBar.startPosY
192
+ to: 0
193
+ easing.type: Easing.OutCubic
194
+ duration: Utils.animationSpeed
195
+ }
196
+ NumberAnimation{
197
+ target: infoBar
198
+ property: "opacity"
199
+ from: 0
200
+ to: 1
201
+ duration: Utils.appearanceSpeed
202
+ }
203
+ }
204
+
205
+ SequentialAnimation{
206
+ id: exitAnimation
207
+
208
+ ParallelAnimation{
209
+ NumberAnimation{
210
+ target: infoBar
211
+ property: "y"
212
+ to: infoBar.startPosY
213
+ easing.type: Easing.OutQuart
214
+ duration: Utils.animationSpeed
215
+ running: false
216
+ }
217
+ NumberAnimation{
218
+ target: infoBar
219
+ property: "opacity"
220
+ from: 1
221
+ to: 0
222
+ duration: Utils.appearanceSpeed
223
+ }
224
+ }
225
+ ScriptAction{
226
+ script: {
227
+ if (infoBar.isDynamic) {
228
+ infoBar.destroy()
229
+ } else {
230
+ infoBar.visible = false
231
+ infoBar.opacity = 1
232
+ infoBar.y = 0
233
+ }
234
+ }
235
+ }
236
+ }
237
+ }
@@ -0,0 +1,93 @@
1
+ import QtQuick 2.15
2
+ import QtQuick.Controls.Basic 2.15
3
+ import QtQuick.Shapes 1.15
4
+ import "../../themes"
5
+ import "../../components"
6
+
7
+ ToolTip {
8
+ id: tooltip
9
+ timeout: -1 // 显示时长
10
+ text: "Tooltip"
11
+
12
+ // 公共属性 / Common Properties
13
+ property color backgroundColor: Theme.currentTheme.colors.backgroundAcrylicColor
14
+ property color borderColor: Theme.currentTheme.colors.cardBorderColor
15
+ property color textColor: Theme.currentTheme.colors.textColor
16
+ property real controlRadius: Theme.currentTheme.appearance.buttonRadius
17
+
18
+ function updateStyle() {
19
+ backgroundColor = Theme.currentTheme.colors.backgroundAcrylicColor
20
+ borderColor = Theme.currentTheme.colors.cardBorderColor
21
+ textColor = Theme.currentTheme.colors.textColor
22
+ controlRadius = Theme.currentTheme.appearance.buttonRadius
23
+ }
24
+
25
+ // 主题切换 / Theme Switching
26
+ Connections {
27
+ target: Theme
28
+ function onCurrentThemeChanged() {
29
+ updateStyle()
30
+ }
31
+ }
32
+
33
+ Component.onCompleted: updateStyle()
34
+
35
+
36
+ // 颜色动画 / Color Animation
37
+ Behavior on backgroundColor { ColorAnimation { duration: 150; easing.type: Easing.OutQuart } }
38
+ Behavior on textColor { ColorAnimation { duration: 150; easing.type: Easing.OutQuart } }
39
+ Behavior on borderColor { ColorAnimation { duration: 150; easing.type: Easing.OutQuart } }
40
+
41
+ property string tipText: text // 传递 tip 文字
42
+
43
+ contentItem: Text {
44
+ id: tooltipText
45
+ anchors.centerIn: background
46
+ typography: Typography.Caption
47
+ text: tipText
48
+ }
49
+
50
+ background: Rectangle {
51
+ id: background
52
+ width: tooltipText.width + 20
53
+ height: tooltipText.height + 13
54
+ anchors.horizontalCenter: parent.horizontalCenter
55
+ y: -6
56
+
57
+ radius: controlRadius
58
+ color: backgroundColor
59
+ border.color: borderColor
60
+
61
+ layer.enabled: true
62
+ layer.effect: Shadow {
63
+ style: "tooltip"
64
+ source: background
65
+ }
66
+ }
67
+
68
+ // 动画 / Animation //
69
+ enter: Transition {
70
+ ParallelAnimation {
71
+ NumberAnimation {
72
+ target: tooltip
73
+ property: "opacity"
74
+ from: 0
75
+ to: 1
76
+ duration: 250
77
+ easing.type: Easing.InOutQuart
78
+ }
79
+ }
80
+ }
81
+ exit: Transition {
82
+ ParallelAnimation {
83
+ NumberAnimation {
84
+ target: tooltip
85
+ property: "opacity"
86
+ from: 1
87
+ to: 0
88
+ duration: 300
89
+ easing.type: Easing.InOutQuart
90
+ }
91
+ }
92
+ }
93
+ }