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.
- RinUI/__init__.py +4 -0
- RinUI/__pycache__/__init__.cpython-38.pyc +0 -0
- RinUI/assets/fonts/FluentSystemIcons-Index.js +5256 -0
- RinUI/assets/fonts/FluentSystemIcons-Resizable.ttf +0 -0
- RinUI/assets/img/default_app_icon.png +0 -0
- RinUI/components/Base.qml +79 -0
- RinUI/components/BasicInput/Button.qml +148 -0
- RinUI/components/BasicInput/CheckBox.qml +99 -0
- RinUI/components/BasicInput/ComboBox.qml +160 -0
- RinUI/components/BasicInput/DropDownButton.qml +21 -0
- RinUI/components/BasicInput/Hyperlink.qml +18 -0
- RinUI/components/BasicInput/RadioButton.qml +95 -0
- RinUI/components/BasicInput/Slider.qml +212 -0
- RinUI/components/BasicInput/Switch.qml +102 -0
- RinUI/components/BasicInput/ToggleButton.qml +11 -0
- RinUI/components/BasicInput/ToolButton.qml +31 -0
- RinUI/components/ContextMenu.qml +184 -0
- RinUI/components/DateAndTime/PickerView.qml +217 -0
- RinUI/components/DateAndTime/TimePicker.qml +115 -0
- RinUI/components/DialogsAndFlyouts/Dialog.qml +106 -0
- RinUI/components/DialogsAndFlyouts/DialogButtonBox.qml +47 -0
- RinUI/components/DialogsAndFlyouts/Flyout.qml +144 -0
- RinUI/components/DialogsAndFlyouts/Popup.qml +106 -0
- RinUI/components/FocusIndicator.qml +33 -0
- RinUI/components/IconWidget.qml +52 -0
- RinUI/components/Indicator.qml +90 -0
- RinUI/components/Layout/Expander.qml +160 -0
- RinUI/components/Layout/SettingExpander.qml +67 -0
- RinUI/components/Layout/SettingItem.qml +71 -0
- RinUI/components/ListAndCollections/Clip.qml +22 -0
- RinUI/components/ListAndCollections/Frame.qml +44 -0
- RinUI/components/ListAndCollections/ListView.qml +105 -0
- RinUI/components/ListAndCollections/ListViewDelegate.qml +83 -0
- RinUI/components/ListAndCollections/SettingCard.qml +73 -0
- RinUI/components/ListAndCollections/TableView.qml +82 -0
- RinUI/components/ListAndCollections/TableViewDelegate.qml +89 -0
- RinUI/components/MenusAndToolbars/Menu.qml +149 -0
- RinUI/components/MenusAndToolbars/MenuBar.qml +43 -0
- RinUI/components/MenusAndToolbars/MenuItem.qml +119 -0
- RinUI/components/MenusAndToolbars/MenuItemGroup.qml +43 -0
- RinUI/components/MenusAndToolbars/MenuSeparator.qml +14 -0
- RinUI/components/MenusAndToolbars/ToolSeparator.qml +17 -0
- RinUI/components/Navigation/ErrorPage.qml +48 -0
- RinUI/components/Navigation/NavigationBar.qml +179 -0
- RinUI/components/Navigation/NavigationItem.qml +193 -0
- RinUI/components/Navigation/NavigationSubItem.qml +103 -0
- RinUI/components/Navigation/NavigationView.qml +210 -0
- RinUI/components/Navigation/SelectorBar.qml +58 -0
- RinUI/components/ScrollBar.qml +163 -0
- RinUI/components/ScrollView.qml +13 -0
- RinUI/components/Shadow.qml +48 -0
- RinUI/components/StatusAndInfo/InfoBadge.qml +78 -0
- RinUI/components/StatusAndInfo/InfoBar.qml +246 -0
- RinUI/components/StatusAndInfo/ProgressBar.qml +127 -0
- RinUI/components/StatusAndInfo/Toast.qml +237 -0
- RinUI/components/StatusAndInfo/ToolTip.qml +93 -0
- RinUI/components/Text/SpinBox.qml +134 -0
- RinUI/components/Text/Text.qml +44 -0
- RinUI/components/Text/TextField.qml +94 -0
- RinUI/components/Text/TextInput.qml +29 -0
- RinUI/components/Utils/Blur.qml +42 -0
- RinUI/components/qmldir +76 -0
- RinUI/config/rin_ui.json +8 -0
- RinUI/core/__init__.py +3 -0
- RinUI/core/__pycache__/__init__.cpython-38.pyc +0 -0
- RinUI/core/__pycache__/config.cpython-38.pyc +0 -0
- RinUI/core/__pycache__/launcher.cpython-38.pyc +0 -0
- RinUI/core/__pycache__/theme.cpython-38.pyc +0 -0
- RinUI/core/config.py +109 -0
- RinUI/core/launcher.py +144 -0
- RinUI/core/theme.py +342 -0
- RinUI/hooks/__init__.py +3 -0
- RinUI/hooks/hook-RinUI.py +3 -0
- RinUI/qmldir +92 -0
- RinUI/themes/dark.qml +137 -0
- RinUI/themes/light.qml +137 -0
- RinUI/themes/qmldir +7 -0
- RinUI/themes/theme.qml +126 -0
- RinUI/themes/utils.qml +28 -0
- RinUI/utils/Animation.qml +12 -0
- RinUI/utils/FloatLayer.qml +123 -0
- RinUI/utils/FontIconLoader.qml +14 -0
- RinUI/utils/Position.qml +19 -0
- RinUI/utils/Severity.qml +13 -0
- RinUI/utils/Typography.qml +17 -0
- RinUI/utils/qmldir +5 -0
- RinUI/windows/CtrlBtn.qml +119 -0
- RinUI/windows/FluentPage.qml +92 -0
- RinUI/windows/FluentWindow.qml +32 -0
- RinUI/windows/FluentWindowBase.qml +157 -0
- RinUI/windows/TitleBar.qml +132 -0
- RinUI/windows/qmldir +8 -0
- RinUI/windows/window/ApplicationWindow.qml +9 -0
- RinUI/windows/window/Window.qml +112 -0
- rinui-0.0.9.data/data/LICENSE +21 -0
- rinui-0.0.9.data/data/README.md +90 -0
- rinui-0.0.9.dist-info/LICENSE +21 -0
- rinui-0.0.9.dist-info/METADATA +105 -0
- rinui-0.0.9.dist-info/RECORD +102 -0
- rinui-0.0.9.dist-info/WHEEL +5 -0
- rinui-0.0.9.dist-info/entry_points.txt +2 -0
- 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
|
+
}
|