Compare commits
52 Commits
1.7.7
...
a9ceff8f6f
Author | SHA1 | Date | |
---|---|---|---|
a9ceff8f6f | |||
8ab0cde2e9 | |||
0b371ecd3f | |||
0171c3609a | |||
489526988d | |||
9d32e8e13b | |||
c9e0732f99 | |||
4920407ed7 | |||
3647197d3b | |||
a72ff03eeb | |||
3eaaa228d8 | |||
e0892fdb66 | |||
8f5fbb4053 | |||
b5295ffe4c | |||
875bba2bd6 | |||
d82e0ed529 | |||
5c63b7b73a | |||
77a5c347fc | |||
add1a86376 | |||
e771293269 | |||
4420c6c608 | |||
a3b4c6cb28 | |||
29fe40002c | |||
1797276e52 | |||
d07de0d33c | |||
fb8c0b79b3 | |||
80eadd5d19 | |||
8ef4bbe322 | |||
901ca8077e | |||
8de79d3336 | |||
dbde052d4a | |||
9716c3c98c | |||
8f8a1a6124 | |||
12300ef081 | |||
5ea71e2c1a | |||
a26f643ba3 | |||
4b49fb1340 | |||
3e28c42e1c | |||
50b89e7eb2 | |||
893000e40f | |||
f2eca9a2b9 | |||
76f40a6265 | |||
86f347edad | |||
b6c7afc744 | |||
f099d3c737 | |||
cfbaf44a05 | |||
0f5e16464c | |||
13bfae4681 | |||
2ee9bfed73 | |||
4a457e15fa | |||
b723cfec4e | |||
1b92928487 |
2
.github/workflows/macos.yml
vendored
@ -60,7 +60,7 @@ jobs:
|
||||
# 拷贝依赖
|
||||
sudo macdeployqt bin/Release/${targetName}.app -qmldir=. -dmg
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.targetName }}_${{ matrix.os }}_${{matrix.qt_ver}}
|
||||
path: bin/release/${{ env.targetName }}.app
|
||||
|
2
.github/workflows/ubuntu.yml
vendored
@ -77,7 +77,7 @@ jobs:
|
||||
linuxdeploy-x86_64.AppImage --plugin=qt --output=appimage --create-desktop-file --icon-file=${targetName}.svg --executable=bin/Release/${targetName} --appdir bin/release/
|
||||
mv ${{ env.targetName }}-*.AppImage ${{ env.targetName }}.AppImage
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.targetName }}_${{ matrix.os }}_${{matrix.qt_ver}}
|
||||
path: ${{ env.targetName }}.AppImage
|
||||
|
2
.github/workflows/windows-mingw.yml
vendored
@ -82,7 +82,7 @@ jobs:
|
||||
$name = ${env:archiveName}
|
||||
echo "::set-output name=packageName::$name"
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ steps.package.outputs.packageName }}
|
||||
path: dist
|
||||
|
2
.github/workflows/windows-qt5.yml
vendored
@ -69,7 +69,7 @@ jobs:
|
||||
$name = ${env:archiveName}
|
||||
echo "::set-output name=packageName::$name"
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ steps.package.outputs.packageName }}
|
||||
path: dist
|
||||
|
2
.github/workflows/windows.yml
vendored
@ -76,7 +76,7 @@ jobs:
|
||||
$name = ${env:archiveName}
|
||||
echo "::set-output name=packageName::$name"
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ steps.package.outputs.packageName }}
|
||||
path: dist
|
||||
|
@ -1,3 +1,6 @@
|
||||
# ATTENTION! THIS REPO HAS BEEN DEPRECATED!
|
||||
# PLEASE USE THE BRAND NEW [FluentUI2](https://github.com/zhuzichu520/FluentUI2) INSTEAD!
|
||||
# THIS REPO IS NO LONGER MAINTAINED.
|
||||
<div align=center>
|
||||
<img width=64 src="doc/preview/fluent_design.svg">
|
||||
|
||||
|
@ -639,7 +639,7 @@
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="95"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="339"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="337"/>
|
||||
<source>Cancel</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -659,57 +659,57 @@
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="304"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="302"/>
|
||||
<source>Finish</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="305"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="303"/>
|
||||
<source>Next</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="306"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="304"/>
|
||||
<source>Previous</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="310"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="308"/>
|
||||
<source>Dark Mode</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="310"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="308"/>
|
||||
<source>Here you can switch to night mode.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="312"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="310"/>
|
||||
<source>Hide Easter eggs</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="312"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="310"/>
|
||||
<source>Try a few more clicks!!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="336"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="334"/>
|
||||
<source>Upgrade Tips</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="337"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="335"/>
|
||||
<source>FluentUI is currently up to date </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="337"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="335"/>
|
||||
<source> -- The current app version</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="337"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="335"/>
|
||||
<source>
|
||||
Now go and download the new version?
|
||||
|
||||
@ -718,17 +718,17 @@ Updated content:
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="340"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="338"/>
|
||||
<source>OK</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="367"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="365"/>
|
||||
<source>The current version is already the latest</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="374"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="372"/>
|
||||
<source>The network is abnormal</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -902,7 +902,7 @@ Updated content:
|
||||
<location filename="qml/page/T_Buttons.qml" line="199"/>
|
||||
<location filename="qml/page/T_Buttons.qml" line="320"/>
|
||||
<location filename="qml/page/T_Buttons.qml" line="368"/>
|
||||
<location filename="qml/page/T_Buttons.qml" line="421"/>
|
||||
<location filename="qml/page/T_Buttons.qml" line="422"/>
|
||||
<source>Disabled</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -1017,17 +1017,17 @@ Updated content:
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Buttons.qml" line="404"/>
|
||||
<location filename="qml/page/T_Buttons.qml" line="405"/>
|
||||
<source>Radio Button_1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Buttons.qml" line="408"/>
|
||||
<location filename="qml/page/T_Buttons.qml" line="409"/>
|
||||
<source>Radio Button_2</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Buttons.qml" line="412"/>
|
||||
<location filename="qml/page/T_Buttons.qml" line="413"/>
|
||||
<source>Radio Button_3</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -1494,27 +1494,27 @@ My only desire is to be permitted to drive out the traitors and restore the Han.
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="64"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="74"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="84"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="75"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="85"/>
|
||||
<source>close '%1'</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="64"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="74"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="84"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="75"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="85"/>
|
||||
<source>show '%1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="70"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="80"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="90"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="81"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="91"/>
|
||||
<source>This is an '%1'</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="94"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="95"/>
|
||||
<source>clear all info</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -2092,7 +2092,7 @@ Some contents...</source>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="176"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="508"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="503"/>
|
||||
<source>Name</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -2112,67 +2112,67 @@ Some contents...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="364"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="359"/>
|
||||
<source>Age</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="439"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="434"/>
|
||||
<source>Clear All</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="446"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="441"/>
|
||||
<source>Delete Selection</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="469"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="464"/>
|
||||
<source>Add a row of Data</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="475"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="470"/>
|
||||
<source>Insert a Row</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="482"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="477"/>
|
||||
<source>Focus not acquired: Please click any item in the form as the target for insertion!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="513"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="508"/>
|
||||
<source>Avatar</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="527"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="522"/>
|
||||
<source>Address</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="535"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="530"/>
|
||||
<source>Nickname</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="542"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="537"/>
|
||||
<source>Long String</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="550"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="545"/>
|
||||
<source>Options</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="568"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="563"/>
|
||||
<source><Previous</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="569"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="564"/>
|
||||
<source>Next></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -2262,8 +2262,29 @@ Some contents...</source>
|
||||
<message>
|
||||
<location filename="qml/page/T_Theme.qml" line="123"/>
|
||||
<source>Open Blur Window</source>
|
||||
<oldsource>Rounded Window</oldsource>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Theme.qml" line="158"/>
|
||||
<source>window tintOpacity</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Theme.qml" line="175"/>
|
||||
<source>window blurRadius</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Theme.qml" line="135"/>
|
||||
<source>window effect</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Theme.qml" line="178"/>
|
||||
<source></source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>T_TimePicker</name>
|
||||
|
@ -616,7 +616,7 @@
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="310"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="308"/>
|
||||
<source>Dark Mode</source>
|
||||
<translation type="unfinished">夜间模式</translation>
|
||||
</message>
|
||||
@ -648,7 +648,7 @@
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="95"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="339"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="337"/>
|
||||
<source>Cancel</source>
|
||||
<translation type="unfinished">取消</translation>
|
||||
</message>
|
||||
@ -668,52 +668,52 @@
|
||||
<translation type="unfinished">搜索</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="304"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="302"/>
|
||||
<source>Finish</source>
|
||||
<translation type="unfinished">完成</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="305"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="303"/>
|
||||
<source>Next</source>
|
||||
<translation type="unfinished">下一步</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="306"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="304"/>
|
||||
<source>Previous</source>
|
||||
<translation type="unfinished">上一步</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="310"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="308"/>
|
||||
<source>Here you can switch to night mode.</source>
|
||||
<translation type="unfinished">在这里,您可以切换到夜间模式。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="312"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="310"/>
|
||||
<source>Hide Easter eggs</source>
|
||||
<translation type="unfinished">隐藏彩蛋</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="312"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="310"/>
|
||||
<source>Try a few more clicks!!</source>
|
||||
<translation type="unfinished">再试几下!!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="336"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="334"/>
|
||||
<source>Upgrade Tips</source>
|
||||
<translation type="unfinished">升级提示</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="337"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="335"/>
|
||||
<source>FluentUI is currently up to date </source>
|
||||
<translation type="unfinished">FluentUI 目前最新版本 </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="337"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="335"/>
|
||||
<source> -- The current app version</source>
|
||||
<translation type="unfinished"> -- 当前应用版本</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="337"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="335"/>
|
||||
<source>
|
||||
Now go and download the new version?
|
||||
|
||||
@ -726,17 +726,17 @@ Updated content:
|
||||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="340"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="338"/>
|
||||
<source>OK</source>
|
||||
<translation type="unfinished">确定</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="367"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="365"/>
|
||||
<source>The current version is already the latest</source>
|
||||
<translation type="unfinished">当前版本已经是最新版本</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/window/MainWindow.qml" line="374"/>
|
||||
<location filename="qml/window/MainWindow.qml" line="372"/>
|
||||
<source>The network is abnormal</source>
|
||||
<translation type="unfinished">网络异常</translation>
|
||||
</message>
|
||||
@ -929,7 +929,7 @@ Updated content:
|
||||
<location filename="qml/page/T_Buttons.qml" line="199"/>
|
||||
<location filename="qml/page/T_Buttons.qml" line="320"/>
|
||||
<location filename="qml/page/T_Buttons.qml" line="368"/>
|
||||
<location filename="qml/page/T_Buttons.qml" line="421"/>
|
||||
<location filename="qml/page/T_Buttons.qml" line="422"/>
|
||||
<source>Disabled</source>
|
||||
<translation type="unfinished">禁用</translation>
|
||||
</message>
|
||||
@ -1044,17 +1044,17 @@ Updated content:
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Buttons.qml" line="404"/>
|
||||
<location filename="qml/page/T_Buttons.qml" line="405"/>
|
||||
<source>Radio Button_1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Buttons.qml" line="408"/>
|
||||
<location filename="qml/page/T_Buttons.qml" line="409"/>
|
||||
<source>Radio Button_2</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Buttons.qml" line="412"/>
|
||||
<location filename="qml/page/T_Buttons.qml" line="413"/>
|
||||
<source>Radio Button_3</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -1092,7 +1092,7 @@ Updated content:
|
||||
<message>
|
||||
<location filename="qml/page/T_Captcha.qml" line="52"/>
|
||||
<source>The verification code is correct</source>
|
||||
<translation type="unfinished">验证码错误</translation>
|
||||
<translation type="unfinished">验证成功</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Captcha.qml" line="54"/>
|
||||
@ -1620,27 +1620,27 @@ My only desire is to be permitted to drive out the traitors and restore the Han.
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="64"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="74"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="84"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="75"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="85"/>
|
||||
<source>close '%1'</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="64"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="74"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="84"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="75"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="85"/>
|
||||
<source>show '%1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="70"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="80"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="90"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="81"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="91"/>
|
||||
<source>This is an '%1'</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="94"/>
|
||||
<location filename="qml/page/T_InfoBar.qml" line="95"/>
|
||||
<source>clear all info</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -2274,7 +2274,7 @@ Some contents...</source>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="176"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="508"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="503"/>
|
||||
<source>Name</source>
|
||||
<translation type="unfinished">名称</translation>
|
||||
</message>
|
||||
@ -2294,67 +2294,67 @@ Some contents...</source>
|
||||
<translation type="unfinished">全选</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="364"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="359"/>
|
||||
<source>Age</source>
|
||||
<translation type="unfinished">年龄</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="439"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="434"/>
|
||||
<source>Clear All</source>
|
||||
<translation type="unfinished">清除所有</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="475"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="470"/>
|
||||
<source>Insert a Row</source>
|
||||
<translation type="unfinished">插入一行</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="482"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="477"/>
|
||||
<source>Focus not acquired: Please click any item in the form as the target for insertion!</source>
|
||||
<translation type="unfinished">焦点未获取:请点击表格中的任意一项,作为插入的靶点!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="513"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="508"/>
|
||||
<source>Avatar</source>
|
||||
<translation type="unfinished">头像</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="527"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="522"/>
|
||||
<source>Address</source>
|
||||
<translation type="unfinished">地址</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="535"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="530"/>
|
||||
<source>Nickname</source>
|
||||
<translation type="unfinished">昵称</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="542"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="537"/>
|
||||
<source>Long String</source>
|
||||
<translation type="unfinished">长字符串</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="550"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="545"/>
|
||||
<source>Options</source>
|
||||
<translation type="unfinished">操作</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="568"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="563"/>
|
||||
<source><Previous</source>
|
||||
<translation type="unfinished"><上一页</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="569"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="564"/>
|
||||
<source>Next></source>
|
||||
<translation type="unfinished">下一页></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="446"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="441"/>
|
||||
<source>Delete Selection</source>
|
||||
<translation type="unfinished">删除选中</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_TableView.qml" line="469"/>
|
||||
<location filename="qml/page/T_TableView.qml" line="464"/>
|
||||
<source>Add a row of Data</source>
|
||||
<translation type="unfinished">添加一行数据</translation>
|
||||
</message>
|
||||
@ -2444,7 +2444,28 @@ Some contents...</source>
|
||||
<message>
|
||||
<location filename="qml/page/T_Theme.qml" line="123"/>
|
||||
<source>Open Blur Window</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<oldsource>Rounded Window</oldsource>
|
||||
<translation>亚克力背景</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Theme.qml" line="158"/>
|
||||
<source>window tintOpacity</source>
|
||||
<translation>背景透明度</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Theme.qml" line="175"/>
|
||||
<source>window blurRadius</source>
|
||||
<translation>背景模糊度</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Theme.qml" line="135"/>
|
||||
<source>window effect</source>
|
||||
<translation>窗口效果</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="qml/page/T_Theme.qml" line="178"/>
|
||||
<source></source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import QtQuick 2.15
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQuick.Window 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
@ -265,7 +265,7 @@ FluScrollablePage{
|
||||
}
|
||||
FluIconButton{
|
||||
disabled: icon_button_switch.checked
|
||||
iconDelegate: Image{ sourceSize: Qt.size(40,40) ; width: 20; height: 20; source: "qrc:/example/res/image/ic_home_github.png" }
|
||||
iconDelegate: FluImage{ sourceSize: Qt.size(40,40) ; width: 20; height: 20; source: "qrc:/example/res/image/ic_home_github.png" }
|
||||
onClicked:{
|
||||
showSuccess(qsTr("Click IconButton"))
|
||||
}
|
||||
@ -395,6 +395,7 @@ FluScrollablePage{
|
||||
Layout.topMargin: 20
|
||||
FluRadioButtons{
|
||||
spacing: 8
|
||||
disabled: radio_button_switch.checked
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
|
@ -68,6 +68,7 @@ FluScrollablePage{
|
||||
return
|
||||
}
|
||||
info1 = showInfo(qsTr("This is an '%1'").arg("info1"), 0)
|
||||
info1.close()
|
||||
}
|
||||
}
|
||||
FluButton{
|
||||
|
@ -315,12 +315,7 @@ FluContentPage{
|
||||
radius: [20,20,20,20]
|
||||
Image{
|
||||
anchors.fill: parent
|
||||
source: {
|
||||
if(options && options.avatar){
|
||||
return options.avatar
|
||||
}
|
||||
return ""
|
||||
}
|
||||
source: options && options.avatar ? options.avatar : ""
|
||||
sourceSize: Qt.size(80,80)
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ FluScrollablePage{
|
||||
|
||||
FluFrame{
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 408
|
||||
Layout.fillHeight: true
|
||||
padding: 10
|
||||
|
||||
ColumnLayout{
|
||||
@ -124,12 +124,69 @@ FluScrollablePage{
|
||||
Layout.topMargin: 20
|
||||
}
|
||||
FluToggleSwitch{
|
||||
id: toggle_blur
|
||||
Layout.topMargin: 5
|
||||
checked: FluTheme.blurBehindWindowEnabled
|
||||
onClicked: {
|
||||
FluTheme.blurBehindWindowEnabled = !FluTheme.blurBehindWindowEnabled
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text: qsTr("window effect")
|
||||
Layout.topMargin: 20
|
||||
}
|
||||
Row{
|
||||
spacing: 10
|
||||
Repeater{
|
||||
model: window.availableEffects
|
||||
delegate: FluRadioButton{
|
||||
checked: window.effect === modelData
|
||||
text: qsTr(`${modelData}`)
|
||||
clickListener:function(){
|
||||
window.effect = modelData
|
||||
if(window.effective){
|
||||
FluTheme.blurBehindWindowEnabled = false
|
||||
toggle_blur.checked = Qt.binding( function() {return FluTheme.blurBehindWindowEnabled})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
visible: FluTheme.blurBehindWindowEnabled || window.effect === "dwm-blur"
|
||||
text: qsTr("window tintOpacity")
|
||||
Layout.topMargin: 20
|
||||
}
|
||||
FluSlider{
|
||||
visible: FluTheme.blurBehindWindowEnabled || window.effect === "dwm-blur"
|
||||
Layout.topMargin: 5
|
||||
to:1
|
||||
stepSize:0.1
|
||||
onValueChanged: {
|
||||
window.tintOpacity = value
|
||||
}
|
||||
Component.onCompleted: {
|
||||
value = window.tintOpacity
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
visible: FluTheme.blurBehindWindowEnabled
|
||||
text: qsTr("window blurRadius")
|
||||
Layout.topMargin: 20
|
||||
}
|
||||
FluSlider{
|
||||
visible: FluTheme.blurBehindWindowEnabled
|
||||
Layout.topMargin: 5
|
||||
to:100
|
||||
stepSize:1
|
||||
onValueChanged: {
|
||||
window.blurRadius = value
|
||||
}
|
||||
Component.onCompleted: {
|
||||
value = window.blurRadius
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CodeExpander{
|
||||
|
@ -236,6 +236,7 @@ FluWindow {
|
||||
id: reveal
|
||||
target: window.containerItem()
|
||||
anchors.fill: parent
|
||||
darkToLight: FluTheme.dark
|
||||
onAnimationFinished:{
|
||||
//动画结束后释放资源
|
||||
loader_reveal.sourceComponent = undefined
|
||||
@ -256,17 +257,14 @@ FluWindow {
|
||||
}
|
||||
|
||||
function handleDarkChanged(button){
|
||||
if(!FluTheme.animationEnabled || window.fitsAppBarWindows === false){
|
||||
if(FluTools.isMacos() || !FluTheme.animationEnabled){
|
||||
changeDark()
|
||||
}else{
|
||||
if(loader_reveal.sourceComponent){
|
||||
return
|
||||
}
|
||||
loader_reveal.sourceComponent = com_reveal
|
||||
var target = window.containerItem()
|
||||
var pos = button.mapToItem(target,0,0)
|
||||
var mouseX = pos.x
|
||||
var mouseY = pos.y
|
||||
var mouseX = pos.x + button.width / 2
|
||||
var mouseY = pos.y + button.height / 2
|
||||
var radius = Math.max(distance(mouseX,mouseY,0,0),distance(mouseX,mouseY,target.width,0),distance(mouseX,mouseY,0,target.height),distance(mouseX,mouseY,target.width,target.height))
|
||||
var reveal = loader_reveal.item
|
||||
reveal.start(reveal.width*Screen.devicePixelRatio,reveal.height*Screen.devicePixelRatio,Qt.point(mouseX,mouseY),radius)
|
||||
|
@ -72,11 +72,6 @@ install(TARGETS ${PROJECT_NAME}
|
||||
BUNDLE DESTINATION .
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
||||
if(QT_VERSION_MAJOR EQUAL 6)
|
||||
qt_import_qml_plugins(${PROJECT_NAME})
|
||||
qt_finalize_executable(${PROJECT_NAME})
|
||||
endif()
|
||||
|
||||
if (CMAKE_BUILD_TYPE MATCHES "Release")
|
||||
if (APPLE)
|
||||
find_program(QT_DEPLOY_QT NAMES macdeployqt)
|
||||
|
@ -25,13 +25,32 @@ void CircularReveal::paint(QPainter *painter) {
|
||||
path.moveTo(_center.x(), _center.y());
|
||||
path.addEllipse(QPointF(_center.x(), _center.y()), _radius, _radius);
|
||||
painter->setCompositionMode(QPainter::CompositionMode_Clear);
|
||||
painter->fillPath(path, Qt::black);
|
||||
if(_darkToLight){
|
||||
painter->fillPath(path, Qt::white);
|
||||
}else{
|
||||
QPainterPath outerRect;
|
||||
outerRect.addRect(0, 0, width(), height());
|
||||
outerRect = outerRect.subtracted(path);
|
||||
painter->fillPath(outerRect, Qt::black);
|
||||
}
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
[[maybe_unused]] void CircularReveal::start(int w, int h, const QPoint ¢er, int radius) {
|
||||
_anim->setStartValue(0);
|
||||
_anim->setEndValue(radius);
|
||||
if (_anim->state() == QAbstractAnimation::Running) {
|
||||
_anim->stop();
|
||||
int currentRadius = _radius;
|
||||
_anim->setStartValue(currentRadius);
|
||||
_anim->setEndValue(_darkToLight ? 0 : radius);
|
||||
} else {
|
||||
if(_darkToLight){
|
||||
_anim->setStartValue(radius);
|
||||
_anim->setEndValue(0);
|
||||
}else{
|
||||
_anim->setStartValue(0);
|
||||
_anim->setEndValue(radius);
|
||||
}
|
||||
}
|
||||
_center = center;
|
||||
_grabResult = _target->grabToImage(QSize(w, h));
|
||||
connect(_grabResult.data(), &QQuickItemGrabResult::ready, this,
|
||||
|
@ -10,6 +10,7 @@ class CircularReveal : public QQuickPaintedItem {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY_AUTO_P(QQuickItem *, target)
|
||||
Q_PROPERTY_AUTO(int, radius)
|
||||
Q_PROPERTY_AUTO(bool, darkToLight)
|
||||
public:
|
||||
explicit CircularReveal(QQuickItem *parent = nullptr);
|
||||
void paint(QPainter *painter) override;
|
||||
|
@ -227,7 +227,7 @@ target_include_directories(${PROJECT_NAME} PRIVATE
|
||||
if ((${QT_VERSION_MAJOR} LESS_EQUAL 6) AND (CMAKE_BUILD_TYPE MATCHES "Release"))
|
||||
find_program(QML_PLUGIN_DUMP NAMES qmlplugindump)
|
||||
add_custom_target(Script-Generate-QmlTypes
|
||||
COMMAND ${QML_PLUGIN_DUMP} -nonrelocatable FluentUI 1.0 ${CMAKE_CURRENT_BINARY_DIR} > ${CMAKE_CURRENT_SOURCE_DIR}/Qt5/imports/FluentUI/plugins.qmltypes
|
||||
COMMAND ${QML_PLUGIN_DUMP} -nonrelocatable -noinstantiate FluentUI 1.0 ${CMAKE_CURRENT_BINARY_DIR} > ${CMAKE_CURRENT_SOURCE_DIR}/Qt5/imports/FluentUI/plugins.qmltypes
|
||||
COMMENT "Generate qmltypes........."
|
||||
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Qt5/imports/FluentUI/plugins.qmltypes
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
|
@ -4,32 +4,156 @@
|
||||
#include <QGuiApplication>
|
||||
#include <QScreen>
|
||||
#include <QDateTime>
|
||||
#include <optional>
|
||||
#include "FluTools.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
|
||||
#pragma comment (lib, "user32.lib")
|
||||
#pragma comment (lib, "dwmapi.lib")
|
||||
static DwmSetWindowAttributeFunc pDwmSetWindowAttribute = nullptr;
|
||||
static DwmExtendFrameIntoClientAreaFunc pDwmExtendFrameIntoClientArea = nullptr;
|
||||
static DwmIsCompositionEnabledFunc pDwmIsCompositionEnabled = nullptr;
|
||||
static DwmEnableBlurBehindWindowFunc pDwmEnableBlurBehindWindow = nullptr;
|
||||
static SetWindowCompositionAttributeFunc pSetWindowCompositionAttribute = nullptr;
|
||||
static GetDpiForWindowFunc pGetDpiForWindow = nullptr;
|
||||
static GetSystemMetricsForDpiFunc pGetSystemMetricsForDpi = nullptr;
|
||||
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <dwmapi.h>
|
||||
static RTL_OSVERSIONINFOW GetRealOSVersionImpl() {
|
||||
HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll");
|
||||
using RtlGetVersionPtr = NTSTATUS(WINAPI *)(PRTL_OSVERSIONINFOW);
|
||||
auto pRtlGetVersion =
|
||||
reinterpret_cast<RtlGetVersionPtr>(::GetProcAddress(hMod, "RtlGetVersion"));
|
||||
RTL_OSVERSIONINFOW rovi{};
|
||||
rovi.dwOSVersionInfoSize = sizeof(rovi);
|
||||
pRtlGetVersion(&rovi);
|
||||
return rovi;
|
||||
}
|
||||
|
||||
RTL_OSVERSIONINFOW GetRealOSVersion() {
|
||||
static const auto result = GetRealOSVersionImpl();
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline bool isWin8OrGreater() {
|
||||
RTL_OSVERSIONINFOW rovi = GetRealOSVersion();
|
||||
return (rovi.dwMajorVersion > 6) || (rovi.dwMajorVersion == 6 && rovi.dwMinorVersion >= 2);
|
||||
}
|
||||
|
||||
static inline bool isWin8Point1OrGreater() {
|
||||
RTL_OSVERSIONINFOW rovi = GetRealOSVersion();
|
||||
return (rovi.dwMajorVersion > 6) || (rovi.dwMajorVersion == 6 && rovi.dwMinorVersion >= 3);
|
||||
}
|
||||
|
||||
static inline bool isWin10OrGreater() {
|
||||
RTL_OSVERSIONINFOW rovi = GetRealOSVersion();
|
||||
return (rovi.dwMajorVersion > 10) || (rovi.dwMajorVersion == 10 && rovi.dwMinorVersion >= 0);
|
||||
}
|
||||
|
||||
static inline bool isWin101809OrGreater() {
|
||||
RTL_OSVERSIONINFOW rovi = GetRealOSVersion();
|
||||
return (rovi.dwMajorVersion > 10) ||
|
||||
(rovi.dwMajorVersion == 10 && rovi.dwMinorVersion >= 0 && rovi.dwBuildNumber >= 17763);
|
||||
}
|
||||
|
||||
static inline bool isWin101903OrGreater() {
|
||||
RTL_OSVERSIONINFOW rovi = GetRealOSVersion();
|
||||
return (rovi.dwMajorVersion > 10) ||
|
||||
(rovi.dwMajorVersion == 10 && rovi.dwMinorVersion >= 0 && rovi.dwBuildNumber >= 18362);
|
||||
}
|
||||
|
||||
static inline bool isWin11OrGreater() {
|
||||
RTL_OSVERSIONINFOW rovi = GetRealOSVersion();
|
||||
return (rovi.dwMajorVersion > 10) ||
|
||||
(rovi.dwMajorVersion == 10 && rovi.dwMinorVersion >= 0 && rovi.dwBuildNumber >= 22000);
|
||||
}
|
||||
|
||||
static inline bool isWin1122H2OrGreater() {
|
||||
RTL_OSVERSIONINFOW rovi = GetRealOSVersion();
|
||||
return (rovi.dwMajorVersion > 10) ||
|
||||
(rovi.dwMajorVersion == 10 && rovi.dwMinorVersion >= 0 && rovi.dwBuildNumber >= 22621);
|
||||
}
|
||||
|
||||
static inline bool isWin10Only() {
|
||||
return isWin10OrGreater() && !isWin11OrGreater();
|
||||
}
|
||||
|
||||
static inline bool isWin7Only() {
|
||||
RTL_OSVERSIONINFOW rovi = GetRealOSVersion();
|
||||
return rovi.dwMajorVersion == 7;
|
||||
}
|
||||
|
||||
static inline QByteArray qtNativeEventType() {
|
||||
static const auto result = "windows_generic_MSG";
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline bool isCompositionEnabled() {
|
||||
typedef HRESULT (WINAPI *DwmIsCompositionEnabledPtr)(BOOL *pfEnabled);
|
||||
HMODULE module = ::LoadLibraryW(L"dwmapi.dll");
|
||||
static inline bool initializeFunctionPointers() {
|
||||
HMODULE module = LoadLibraryW(L"dwmapi.dll");
|
||||
if (module) {
|
||||
BOOL composition_enabled = false;
|
||||
DwmIsCompositionEnabledPtr dwm_is_composition_enabled;
|
||||
dwm_is_composition_enabled = reinterpret_cast<DwmIsCompositionEnabledPtr>(::GetProcAddress(module, "DwmIsCompositionEnabled"));
|
||||
if (dwm_is_composition_enabled) {
|
||||
dwm_is_composition_enabled(&composition_enabled);
|
||||
if (!pDwmSetWindowAttribute) {
|
||||
pDwmSetWindowAttribute = reinterpret_cast<DwmSetWindowAttributeFunc>(
|
||||
GetProcAddress(module, "DwmSetWindowAttribute"));
|
||||
if (!pDwmSetWindowAttribute) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!pDwmExtendFrameIntoClientArea) {
|
||||
pDwmExtendFrameIntoClientArea = reinterpret_cast<DwmExtendFrameIntoClientAreaFunc>(
|
||||
GetProcAddress(module, "DwmExtendFrameIntoClientArea"));
|
||||
if (!pDwmExtendFrameIntoClientArea) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!pDwmIsCompositionEnabled) {
|
||||
pDwmIsCompositionEnabled = reinterpret_cast<DwmIsCompositionEnabledFunc>(
|
||||
::GetProcAddress(module, "DwmIsCompositionEnabled"));
|
||||
if (!pDwmIsCompositionEnabled) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!pDwmEnableBlurBehindWindow) {
|
||||
pDwmEnableBlurBehindWindow = reinterpret_cast<DwmEnableBlurBehindWindowFunc>(
|
||||
GetProcAddress(module, "DwmEnableBlurBehindWindow"));
|
||||
if (!pDwmEnableBlurBehindWindow) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HMODULE user32 = LoadLibraryW(L"user32.dll");
|
||||
if (module) {
|
||||
if (!pSetWindowCompositionAttribute) {
|
||||
pSetWindowCompositionAttribute = reinterpret_cast<SetWindowCompositionAttributeFunc>(
|
||||
GetProcAddress(user32, "SetWindowCompositionAttribute"));
|
||||
if (!pSetWindowCompositionAttribute) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pGetDpiForWindow) {
|
||||
pGetDpiForWindow =
|
||||
reinterpret_cast<GetDpiForWindowFunc>(GetProcAddress(user32, "GetDpiForWindow"));
|
||||
if (!pGetDpiForWindow) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pGetSystemMetricsForDpi) {
|
||||
pGetSystemMetricsForDpi = reinterpret_cast<GetSystemMetricsForDpiFunc>(
|
||||
GetProcAddress(user32, "GetSystemMetricsForDpi"));
|
||||
if (!pGetSystemMetricsForDpi) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool isCompositionEnabled() {
|
||||
if (initializeFunctionPointers()) {
|
||||
BOOL composition_enabled = false;
|
||||
pDwmIsCompositionEnabled(&composition_enabled);
|
||||
return composition_enabled;
|
||||
}
|
||||
return false;
|
||||
@ -37,15 +161,195 @@ static inline bool isCompositionEnabled() {
|
||||
|
||||
static inline void setShadow(HWND hwnd) {
|
||||
const MARGINS shadow = {1, 0, 0, 0};
|
||||
typedef HRESULT (WINAPI *DwmExtendFrameIntoClientAreaPtr)(HWND hWnd, const MARGINS *pMarInset);
|
||||
HMODULE module = LoadLibraryW(L"dwmapi.dll");
|
||||
if (module) {
|
||||
DwmExtendFrameIntoClientAreaPtr dwm_extendframe_into_client_area_;
|
||||
dwm_extendframe_into_client_area_ = reinterpret_cast<DwmExtendFrameIntoClientAreaPtr>(GetProcAddress(module, "DwmExtendFrameIntoClientArea"));
|
||||
if (dwm_extendframe_into_client_area_) {
|
||||
dwm_extendframe_into_client_area_(hwnd, &shadow);
|
||||
if (initializeFunctionPointers()) {
|
||||
pDwmExtendFrameIntoClientArea(hwnd, &shadow);
|
||||
}
|
||||
if (isWin7Only()) {
|
||||
SetClassLong(hwnd, GCL_STYLE, GetClassLong(hwnd, GCL_STYLE) | CS_DROPSHADOW);
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool setWindowDarkMode(HWND hwnd, const BOOL enable) {
|
||||
if (!initializeFunctionPointers()) {
|
||||
return false;
|
||||
}
|
||||
return bool(pDwmSetWindowAttribute(hwnd, 20, &enable, sizeof(BOOL)));
|
||||
}
|
||||
|
||||
static inline std::optional<MONITORINFOEXW> getMonitorForWindow(const HWND hwnd) {
|
||||
Q_ASSERT(hwnd);
|
||||
if (!hwnd) {
|
||||
return std::nullopt;
|
||||
}
|
||||
const HMONITOR monitor = ::MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
|
||||
if (!monitor) {
|
||||
return std::nullopt;
|
||||
}
|
||||
MONITORINFOEXW monitorInfo;
|
||||
::SecureZeroMemory(&monitorInfo, sizeof(monitorInfo));
|
||||
monitorInfo.cbSize = sizeof(monitorInfo);
|
||||
if (::GetMonitorInfoW(monitor, &monitorInfo) == FALSE) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return monitorInfo;
|
||||
};
|
||||
|
||||
static inline bool isFullScreen(const HWND hwnd) {
|
||||
RECT windowRect = {};
|
||||
if (::GetWindowRect(hwnd, &windowRect) == FALSE) {
|
||||
return false;
|
||||
}
|
||||
const std::optional<MONITORINFOEXW> mi = getMonitorForWindow(hwnd);
|
||||
if (!mi.has_value()) {
|
||||
return false;
|
||||
}
|
||||
RECT rcMonitor = mi.value().rcMonitor;
|
||||
return windowRect.top == rcMonitor.top && windowRect.left == rcMonitor.left &&
|
||||
windowRect.right == rcMonitor.right && windowRect.bottom == rcMonitor.bottom;
|
||||
}
|
||||
|
||||
static inline bool isMaximized(const HWND hwnd) {
|
||||
WINDOWPLACEMENT wp;
|
||||
::GetWindowPlacement(hwnd, &wp);
|
||||
return wp.showCmd == SW_MAXIMIZE;
|
||||
}
|
||||
|
||||
static inline quint32 getDpiForWindow(const HWND hwnd, const bool horizontal) {
|
||||
if (const UINT dpi = pGetDpiForWindow(hwnd)) {
|
||||
return dpi;
|
||||
}
|
||||
if (const HDC hdc = ::GetDC(hwnd)) {
|
||||
bool valid = false;
|
||||
const int dpiX = ::GetDeviceCaps(hdc, LOGPIXELSX);
|
||||
const int dpiY = ::GetDeviceCaps(hdc, LOGPIXELSY);
|
||||
if ((dpiX > 0) && (dpiY > 0)) {
|
||||
valid = true;
|
||||
}
|
||||
::ReleaseDC(hwnd, hdc);
|
||||
if (valid) {
|
||||
return (horizontal ? dpiX : dpiY);
|
||||
}
|
||||
}
|
||||
return 96;
|
||||
}
|
||||
|
||||
static inline int getSystemMetrics(const HWND hwnd, const int index, const bool horizontal) {
|
||||
const UINT dpi = getDpiForWindow(hwnd, horizontal);
|
||||
if (const int result = pGetSystemMetricsForDpi(index, dpi); result > 0) {
|
||||
return result;
|
||||
}
|
||||
return ::GetSystemMetrics(index);
|
||||
}
|
||||
|
||||
static inline quint32 getResizeBorderThickness(const HWND hwnd, const bool horizontal,
|
||||
const qreal devicePixelRatio) {
|
||||
auto frame = horizontal ? SM_CXSIZEFRAME : SM_CYSIZEFRAME;
|
||||
auto result =
|
||||
getSystemMetrics(hwnd, frame, horizontal) + getSystemMetrics(hwnd, 92, horizontal);
|
||||
if (result > 0) {
|
||||
return result;
|
||||
}
|
||||
int thickness = isCompositionEnabled() ? 8 : 4;
|
||||
return qRound(thickness * devicePixelRatio);
|
||||
}
|
||||
|
||||
static inline bool setWindowEffect(HWND hwnd, const QString &key, const bool &enable) {
|
||||
static constexpr const MARGINS extendedMargins = {-1, -1, -1, -1};
|
||||
if (key == QStringLiteral("mica")) {
|
||||
if (!isWin11OrGreater() || !initializeFunctionPointers()) {
|
||||
return false;
|
||||
}
|
||||
if (enable) {
|
||||
pDwmExtendFrameIntoClientArea(hwnd, &extendedMargins);
|
||||
if (isWin1122H2OrGreater()) {
|
||||
const DWORD backdropType = _DWMSBT_MAINWINDOW;
|
||||
pDwmSetWindowAttribute(hwnd, 38, &backdropType, sizeof(backdropType));
|
||||
} else {
|
||||
const BOOL enable = TRUE;
|
||||
pDwmSetWindowAttribute(hwnd, 1029, &enable, sizeof(enable));
|
||||
}
|
||||
} else {
|
||||
if (isWin1122H2OrGreater()) {
|
||||
const DWORD backdropType = _DWMSBT_AUTO;
|
||||
pDwmSetWindowAttribute(hwnd, 38, &backdropType, sizeof(backdropType));
|
||||
} else {
|
||||
const BOOL enable = FALSE;
|
||||
pDwmSetWindowAttribute(hwnd, 1029, &enable, sizeof(enable));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (key == QStringLiteral("mica-alt")) {
|
||||
if (!isWin1122H2OrGreater() || !initializeFunctionPointers()) {
|
||||
return false;
|
||||
}
|
||||
if (enable) {
|
||||
pDwmExtendFrameIntoClientArea(hwnd, &extendedMargins);
|
||||
const DWORD backdropType = _DWMSBT_TABBEDWINDOW;
|
||||
pDwmSetWindowAttribute(hwnd, 38, &backdropType, sizeof(backdropType));
|
||||
} else {
|
||||
const DWORD backdropType = _DWMSBT_AUTO;
|
||||
pDwmSetWindowAttribute(hwnd, 38, &backdropType, sizeof(backdropType));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (key == QStringLiteral("acrylic")) {
|
||||
if (!isWin11OrGreater() || !initializeFunctionPointers()) {
|
||||
return false;
|
||||
}
|
||||
if (enable) {
|
||||
pDwmExtendFrameIntoClientArea(hwnd, &extendedMargins);
|
||||
DWORD system_backdrop_type = _DWMSBT_TRANSIENTWINDOW;
|
||||
pDwmSetWindowAttribute(hwnd, 38, &system_backdrop_type, sizeof(DWORD));
|
||||
} else {
|
||||
const DWORD backdropType = _DWMSBT_AUTO;
|
||||
pDwmSetWindowAttribute(hwnd, 38, &backdropType, sizeof(backdropType));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (key == QStringLiteral("dwm-blur")) {
|
||||
if ((isWin7Only() && !isCompositionEnabled()) || !initializeFunctionPointers()) {
|
||||
return false;
|
||||
}
|
||||
if (enable) {
|
||||
if (isWin8OrGreater()) {
|
||||
ACCENT_POLICY policy{};
|
||||
policy.dwAccentState = ACCENT_ENABLE_BLURBEHIND;
|
||||
policy.dwAccentFlags = ACCENT_NONE;
|
||||
WINDOWCOMPOSITIONATTRIBDATA wcad{};
|
||||
wcad.Attrib = WCA_ACCENT_POLICY;
|
||||
wcad.pvData = &policy;
|
||||
wcad.cbData = sizeof(policy);
|
||||
pSetWindowCompositionAttribute(hwnd, &wcad);
|
||||
} else {
|
||||
DWM_BLURBEHIND bb{};
|
||||
bb.fEnable = TRUE;
|
||||
bb.dwFlags = DWM_BB_ENABLE;
|
||||
pDwmEnableBlurBehindWindow(hwnd, &bb);
|
||||
}
|
||||
} else {
|
||||
if (isWin8OrGreater()) {
|
||||
ACCENT_POLICY policy{};
|
||||
policy.dwAccentState = ACCENT_DISABLED;
|
||||
policy.dwAccentFlags = ACCENT_NONE;
|
||||
WINDOWCOMPOSITIONATTRIBDATA wcad{};
|
||||
wcad.Attrib = WCA_ACCENT_POLICY;
|
||||
wcad.pvData = &policy;
|
||||
wcad.cbData = sizeof(policy);
|
||||
pSetWindowCompositionAttribute(hwnd, &wcad);
|
||||
} else {
|
||||
DWM_BLURBEHIND bb{};
|
||||
bb.fEnable = FALSE;
|
||||
bb.dwFlags = DWM_BB_ENABLE;
|
||||
pDwmEnableBlurBehindWindow(hwnd, &bb);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -70,6 +374,8 @@ FluFrameless::FluFrameless(QQuickItem *parent) : QQuickItem{parent} {
|
||||
_closeButton = nullptr;
|
||||
_topmost = false;
|
||||
_disabled = false;
|
||||
_effect = "normal";
|
||||
_effective = false;
|
||||
_isWindows11OrGreater = FluTools::getInstance()->isWindows11OrGreater();
|
||||
}
|
||||
|
||||
@ -80,16 +386,62 @@ FluFrameless::~FluFrameless() = default;
|
||||
}
|
||||
|
||||
void FluFrameless::componentComplete() {
|
||||
#ifdef Q_OS_WIN
|
||||
HWND hwnd = reinterpret_cast<HWND>(window()->winId());
|
||||
if (isWin11OrGreater()) {
|
||||
availableEffects({"mica", "mica-alt", "acrylic", "dwm-blur", "normal"});
|
||||
} else {
|
||||
availableEffects({"dwm-blur", "normal"});
|
||||
}
|
||||
if (!_effect.isEmpty() && _useSystemEffect) {
|
||||
effective(setWindowEffect(hwnd, _effect, true));
|
||||
if (effective()) {
|
||||
_currentEffect = effect();
|
||||
}
|
||||
}
|
||||
connect(this, &FluFrameless::effectChanged, this, [hwnd, this] {
|
||||
if (effect() == _currentEffect) {
|
||||
return;
|
||||
}
|
||||
if (effective()) {
|
||||
setWindowEffect(hwnd, _currentEffect, false);
|
||||
}
|
||||
effective(setWindowEffect(hwnd, effect(), true));
|
||||
if (effective()) {
|
||||
_currentEffect = effect();
|
||||
_useSystemEffect = true;
|
||||
} else {
|
||||
_effect = "normal";
|
||||
_currentEffect = "normal";
|
||||
_useSystemEffect = false;
|
||||
}
|
||||
});
|
||||
connect(this, &FluFrameless::useSystemEffectChanged, this, [this] {
|
||||
if (!_useSystemEffect) {
|
||||
effect("normal");
|
||||
}
|
||||
});
|
||||
connect(this, &FluFrameless::isDarkModeChanged, this, [hwnd, this] {
|
||||
if (effective() && !_currentEffect.isEmpty() && _currentEffect != "normal") {
|
||||
setWindowDarkMode(hwnd, _isDarkMode);
|
||||
}
|
||||
});
|
||||
#endif
|
||||
if (_disabled) {
|
||||
return;
|
||||
}
|
||||
int w = window()->width();
|
||||
int h = window()->height();
|
||||
_current = window()->winId();
|
||||
window()->setFlags((window()->flags()) | Qt::CustomizeWindowHint | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint);
|
||||
if (!_fixSize) {
|
||||
window()->setFlag(Qt::WindowMaximizeButtonHint);
|
||||
}
|
||||
#ifdef Q_OS_MACOS
|
||||
window()->setFlag(Qt::FramelessWindowHint, true);
|
||||
window()->setProperty("__borderWidth", 1);
|
||||
#endif
|
||||
#ifdef Q_OS_LINUX
|
||||
window()->setFlag(Qt::CustomizeWindowHint, true);
|
||||
window()->setFlag(Qt::FramelessWindowHint, true);
|
||||
window()->setProperty("__borderWidth", 1);
|
||||
#endif
|
||||
window()->installEventFilter(this);
|
||||
QGuiApplication::instance()->installNativeEventFilter(this);
|
||||
if (_maximizeButton) {
|
||||
@ -102,24 +454,36 @@ void FluFrameless::componentComplete() {
|
||||
setHitTestVisible(_closeButton);
|
||||
}
|
||||
#ifdef Q_OS_WIN
|
||||
#if (QT_VERSION == QT_VERSION_CHECK(6, 5, 3))
|
||||
qWarning()<<"Qt's own frameless bug, currently only exist in 6.5.3, please use other versions";
|
||||
#endif
|
||||
HWND hwnd = reinterpret_cast<HWND>(window()->winId());
|
||||
# if (QT_VERSION == QT_VERSION_CHECK(6, 5, 3))
|
||||
qWarning()
|
||||
<< "Qt's own frameless bug, currently only exist in 6.5.3, please use other versions";
|
||||
# endif
|
||||
if (!hwnd) {
|
||||
hwnd = reinterpret_cast<HWND>(window()->winId());
|
||||
}
|
||||
DWORD style = ::GetWindowLongPtr(hwnd, GWL_STYLE);
|
||||
# if (QT_VERSION == QT_VERSION_CHECK(6, 7, 2))
|
||||
style &= ~(WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU);
|
||||
# endif
|
||||
if (_fixSize) {
|
||||
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_THICKFRAME | WS_CAPTION);;
|
||||
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_THICKFRAME | WS_CAPTION);
|
||||
;
|
||||
for (int i = 0; i <= QGuiApplication::screens().count() - 1; ++i) {
|
||||
connect(QGuiApplication::screens().at(i), &QScreen::logicalDotsPerInchChanged, this, [=] {
|
||||
SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_FRAMECHANGED);
|
||||
});
|
||||
connect(
|
||||
QGuiApplication::screens().at(i), &QScreen::logicalDotsPerInchChanged, this, [=] {
|
||||
SetWindowPos(hwnd, nullptr, 0, 0, 0, 0,
|
||||
SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_FRAMECHANGED);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CAPTION);
|
||||
}
|
||||
SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
|
||||
SetWindowPos(hwnd, nullptr, 0, 0, 0, 0,
|
||||
SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
|
||||
connect(window(), &QQuickWindow::screenChanged, this, [hwnd] {
|
||||
::SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOOWNERZORDER);
|
||||
::SetWindowPos(hwnd, nullptr, 0, 0, 0, 0,
|
||||
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED |
|
||||
SWP_NOOWNERZORDER);
|
||||
::RedrawWindow(hwnd, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW);
|
||||
});
|
||||
if (!window()->property("_hideShadow").toBool()) {
|
||||
@ -136,13 +500,12 @@ void FluFrameless::componentComplete() {
|
||||
window()->setMaximumHeight(window()->maximumHeight() + appBarHeight);
|
||||
}
|
||||
window()->resize(QSize(w, h));
|
||||
connect(this, &FluFrameless::topmostChanged, this, [this] {
|
||||
_setWindowTopmost(topmost());
|
||||
});
|
||||
connect(this, &FluFrameless::topmostChanged, this, [this] { _setWindowTopmost(topmost()); });
|
||||
_setWindowTopmost(topmost());
|
||||
}
|
||||
|
||||
[[maybe_unused]] bool FluFrameless::nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result) {
|
||||
[[maybe_unused]] bool FluFrameless::nativeEventFilter(const QByteArray &eventType, void *message,
|
||||
QT_NATIVE_EVENT_RESULT_TYPE *result) {
|
||||
#ifdef Q_OS_WIN
|
||||
if ((eventType != qtNativeEventType()) || !message) {
|
||||
return false;
|
||||
@ -163,19 +526,71 @@ void FluFrameless::componentComplete() {
|
||||
auto *wp = reinterpret_cast<WINDOWPOS *>(lParam);
|
||||
if (wp != nullptr && (wp->flags & SWP_NOSIZE) == 0) {
|
||||
wp->flags |= SWP_NOCOPYBITS;
|
||||
*result = static_cast<QT_NATIVE_EVENT_RESULT_TYPE>(::DefWindowProcW(hwnd, uMsg, wParam, lParam));
|
||||
*result = static_cast<QT_NATIVE_EVENT_RESULT_TYPE>(
|
||||
::DefWindowProcW(hwnd, uMsg, wParam, lParam));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} else if (uMsg == WM_NCCALCSIZE && wParam == TRUE) {
|
||||
bool isMaximum = ::IsZoomed(hwnd);
|
||||
if (isMaximum) {
|
||||
window()->setProperty("__margins",7);
|
||||
}else{
|
||||
window()->setProperty("__margins",0);
|
||||
const auto clientRect =
|
||||
((wParam == FALSE) ? reinterpret_cast<LPRECT>(lParam)
|
||||
: &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(lParam))->rgrc[0]);
|
||||
bool isMax = ::isMaximized(hwnd);
|
||||
bool isFull = ::isFullScreen(hwnd);
|
||||
if (isMax && !isFull) {
|
||||
auto ty = getResizeBorderThickness(hwnd, false, window()->devicePixelRatio());
|
||||
clientRect->top += ty;
|
||||
clientRect->bottom -= ty;
|
||||
auto tx = getResizeBorderThickness(hwnd, true, window()->devicePixelRatio());
|
||||
clientRect->left += tx;
|
||||
clientRect->right -= tx;
|
||||
}
|
||||
_setMaximizeHovered(false);
|
||||
*result = WVR_REDRAW;
|
||||
if (isMax || isFull) {
|
||||
APPBARDATA abd;
|
||||
SecureZeroMemory(&abd, sizeof(abd));
|
||||
abd.cbSize = sizeof(abd);
|
||||
const UINT taskbarState = ::SHAppBarMessage(ABM_GETSTATE, &abd);
|
||||
if (taskbarState & ABS_AUTOHIDE) {
|
||||
bool top = false, bottom = false, left = false, right = false;
|
||||
int edge = -1;
|
||||
APPBARDATA abd2;
|
||||
SecureZeroMemory(&abd2, sizeof(abd2));
|
||||
abd2.cbSize = sizeof(abd2);
|
||||
abd2.hWnd = ::FindWindowW(L"Shell_TrayWnd", nullptr);
|
||||
if (abd2.hWnd) {
|
||||
const HMONITOR windowMonitor =
|
||||
::MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
|
||||
if (windowMonitor) {
|
||||
const HMONITOR taskbarMonitor =
|
||||
::MonitorFromWindow(abd2.hWnd, MONITOR_DEFAULTTOPRIMARY);
|
||||
if (taskbarMonitor) {
|
||||
if (taskbarMonitor == windowMonitor) {
|
||||
::SHAppBarMessage(ABM_GETTASKBARPOS, &abd2);
|
||||
edge = abd2.uEdge;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
top = (edge == ABE_TOP);
|
||||
bottom = (edge == ABE_BOTTOM);
|
||||
left = (edge == ABE_LEFT);
|
||||
right = (edge == ABE_RIGHT);
|
||||
if (top) {
|
||||
clientRect->top += 1;
|
||||
} else if (bottom) {
|
||||
clientRect->bottom -= 1;
|
||||
} else if (left) {
|
||||
clientRect->left += 1;
|
||||
} else if (right) {
|
||||
clientRect->right -= 1;
|
||||
} else {
|
||||
clientRect->bottom -= 1;
|
||||
}
|
||||
} else {
|
||||
clientRect->bottom += 1;
|
||||
}
|
||||
}
|
||||
*result = 0;
|
||||
return true;
|
||||
} else if (uMsg == WM_NCHITTEST) {
|
||||
if (_isWindows11OrGreater) {
|
||||
@ -231,21 +646,29 @@ void FluFrameless::componentComplete() {
|
||||
*result = HTCLIENT;
|
||||
return true;
|
||||
} else if (uMsg == WM_NCPAINT) {
|
||||
if (isCompositionEnabled() && !this->_isFullScreen()) {
|
||||
return false;
|
||||
}
|
||||
*result = FALSE;
|
||||
return false;
|
||||
return true;
|
||||
} else if (uMsg == WM_NCACTIVATE) {
|
||||
*result = TRUE;
|
||||
if (isCompositionEnabled()) {
|
||||
return false;
|
||||
}
|
||||
*result = true;
|
||||
return true;
|
||||
} else if (_isWindows11OrGreater && (uMsg == WM_NCLBUTTONDBLCLK || uMsg == WM_NCLBUTTONDOWN)) {
|
||||
if (_hitMaximizeButton()) {
|
||||
QMouseEvent event = QMouseEvent(QEvent::MouseButtonPress, QPoint(), QPoint(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
|
||||
QMouseEvent event = QMouseEvent(QEvent::MouseButtonPress, QPoint(), QPoint(),
|
||||
Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
|
||||
QGuiApplication::sendEvent(_maximizeButton, &event);
|
||||
_setMaximizePressed(true);
|
||||
return true;
|
||||
}
|
||||
} else if (_isWindows11OrGreater && (uMsg == WM_NCLBUTTONUP || uMsg == WM_NCRBUTTONUP)) {
|
||||
if (_hitMaximizeButton()) {
|
||||
QMouseEvent event = QMouseEvent(QEvent::MouseButtonRelease, QPoint(), QPoint(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
|
||||
QMouseEvent event = QMouseEvent(QEvent::MouseButtonRelease, QPoint(), QPoint(),
|
||||
Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
|
||||
QGuiApplication::sendEvent(_maximizeButton, &event);
|
||||
_setMaximizePressed(false);
|
||||
return true;
|
||||
@ -300,7 +723,8 @@ void FluFrameless::_showSystemMenu(QPoint point) {
|
||||
return;
|
||||
}
|
||||
const QPoint origin = screen->geometry().topLeft();
|
||||
auto nativePos = QPointF(QPointF(point - origin) * window()->devicePixelRatio()).toPoint() + origin;
|
||||
auto nativePos =
|
||||
QPointF(QPointF(point - origin) * window()->devicePixelRatio()).toPoint() + origin;
|
||||
HWND hwnd = reinterpret_cast<HWND>(window()->winId());
|
||||
auto hMenu = ::GetSystemMenu(hwnd, FALSE);
|
||||
if (_isMaximized() || _isFullScreen()) {
|
||||
@ -317,8 +741,10 @@ void FluFrameless::_showSystemMenu(QPoint point) {
|
||||
::EnableMenuItem(hMenu, SC_SIZE, MFS_DISABLED);
|
||||
::EnableMenuItem(hMenu, SC_MAXIMIZE, MFS_DISABLED);
|
||||
}
|
||||
const int result = ::TrackPopupMenu(hMenu, (TPM_RETURNCMD | (QGuiApplication::isRightToLeft() ? TPM_RIGHTALIGN : TPM_LEFTALIGN)), nativePos.x(),
|
||||
nativePos.y(), 0, hwnd, nullptr);
|
||||
const int result = ::TrackPopupMenu(
|
||||
hMenu,
|
||||
(TPM_RETURNCMD | (QGuiApplication::isRightToLeft() ? TPM_RIGHTALIGN : TPM_LEFTALIGN)),
|
||||
nativePos.x(), nativePos.y(), 0, hwnd, nullptr);
|
||||
if (result) {
|
||||
::PostMessageW(hwnd, WM_SYSCOMMAND, result, 0);
|
||||
}
|
||||
@ -359,27 +785,27 @@ void FluFrameless::_setMaximizeHovered(bool val) {
|
||||
|
||||
void FluFrameless::_updateCursor(int edges) {
|
||||
switch (edges) {
|
||||
case 0:
|
||||
window()->setCursor(Qt::ArrowCursor);
|
||||
break;
|
||||
case Qt::LeftEdge:
|
||||
case Qt::RightEdge:
|
||||
window()->setCursor(Qt::SizeHorCursor);
|
||||
break;
|
||||
case Qt::TopEdge:
|
||||
case Qt::BottomEdge:
|
||||
window()->setCursor(Qt::SizeVerCursor);
|
||||
break;
|
||||
case Qt::LeftEdge | Qt::TopEdge:
|
||||
case Qt::RightEdge | Qt::BottomEdge:
|
||||
window()->setCursor(Qt::SizeFDiagCursor);
|
||||
break;
|
||||
case Qt::RightEdge | Qt::TopEdge:
|
||||
case Qt::LeftEdge | Qt::BottomEdge:
|
||||
window()->setCursor(Qt::SizeBDiagCursor);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case 0:
|
||||
window()->setCursor(Qt::ArrowCursor);
|
||||
break;
|
||||
case Qt::LeftEdge:
|
||||
case Qt::RightEdge:
|
||||
window()->setCursor(Qt::SizeHorCursor);
|
||||
break;
|
||||
case Qt::TopEdge:
|
||||
case Qt::BottomEdge:
|
||||
window()->setCursor(Qt::SizeVerCursor);
|
||||
break;
|
||||
case Qt::LeftEdge | Qt::TopEdge:
|
||||
case Qt::RightEdge | Qt::BottomEdge:
|
||||
window()->setCursor(Qt::SizeFDiagCursor);
|
||||
break;
|
||||
case Qt::RightEdge | Qt::TopEdge:
|
||||
case Qt::LeftEdge | Qt::BottomEdge:
|
||||
window()->setCursor(Qt::SizeBDiagCursor);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -424,79 +850,80 @@ void FluFrameless::_setWindowTopmost(bool topmost) {
|
||||
::SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
||||
}
|
||||
#else
|
||||
window()->setFlag(Qt::WindowStaysOnTopHint,topmost);
|
||||
window()->setFlag(Qt::WindowStaysOnTopHint, topmost);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FluFrameless::eventFilter(QObject *obj, QEvent *ev) {
|
||||
#ifndef Q_OS_WIN
|
||||
switch (ev->type()) {
|
||||
case QEvent::MouseButtonPress:
|
||||
if(_edges!=0){
|
||||
QMouseEvent *event = static_cast<QMouseEvent*>(ev);
|
||||
if(event->button() == Qt::LeftButton){
|
||||
_updateCursor(_edges);
|
||||
window()->startSystemResize(Qt::Edges(_edges));
|
||||
}
|
||||
}else{
|
||||
if(_hitAppBar()){
|
||||
qint64 clickTimer = QDateTime::currentMSecsSinceEpoch();
|
||||
qint64 offset = clickTimer - this->_clickTimer;
|
||||
this->_clickTimer = clickTimer;
|
||||
if(offset<300){
|
||||
if(_isMaximized()){
|
||||
showNormal();
|
||||
}else{
|
||||
showMaximized();
|
||||
case QEvent::MouseButtonPress:
|
||||
if (_edges != 0) {
|
||||
QMouseEvent *event = static_cast<QMouseEvent *>(ev);
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
_updateCursor(_edges);
|
||||
window()->startSystemResize(Qt::Edges(_edges));
|
||||
}
|
||||
} else {
|
||||
if (_hitAppBar()) {
|
||||
qint64 clickTimer = QDateTime::currentMSecsSinceEpoch();
|
||||
qint64 offset = clickTimer - this->_clickTimer;
|
||||
this->_clickTimer = clickTimer;
|
||||
if (offset < 300) {
|
||||
if (_isMaximized()) {
|
||||
showNormal();
|
||||
} else {
|
||||
showMaximized();
|
||||
}
|
||||
} else {
|
||||
window()->startSystemMove();
|
||||
}
|
||||
}else{
|
||||
window()->startSystemMove();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QEvent::MouseButtonRelease:
|
||||
_edges = 0;
|
||||
break;
|
||||
case QEvent::MouseMove: {
|
||||
if(_isMaximized() || _isFullScreen()){
|
||||
break;
|
||||
}
|
||||
if(_fixSize){
|
||||
case QEvent::MouseButtonRelease:
|
||||
_edges = 0;
|
||||
break;
|
||||
}
|
||||
QMouseEvent *event = static_cast<QMouseEvent*>(ev);
|
||||
QPoint p =
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
|
||||
event->pos();
|
||||
#else
|
||||
event->position().toPoint();
|
||||
#endif
|
||||
if(p.x() >= _margins && p.x() <= (window()->width() - _margins) && p.y() >= _margins && p.y() <= (window()->height() - _margins)){
|
||||
if(_edges != 0){
|
||||
_edges = 0;
|
||||
_updateCursor(_edges);
|
||||
case QEvent::MouseMove: {
|
||||
if (_isMaximized() || _isFullScreen()) {
|
||||
break;
|
||||
}
|
||||
if (_fixSize) {
|
||||
break;
|
||||
}
|
||||
QMouseEvent *event = static_cast<QMouseEvent *>(ev);
|
||||
QPoint p =
|
||||
# if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
event->pos();
|
||||
# else
|
||||
event->position().toPoint();
|
||||
# endif
|
||||
if (p.x() >= _margins && p.x() <= (window()->width() - _margins) && p.y() >= _margins &&
|
||||
p.y() <= (window()->height() - _margins)) {
|
||||
if (_edges != 0) {
|
||||
_edges = 0;
|
||||
_updateCursor(_edges);
|
||||
}
|
||||
break;
|
||||
}
|
||||
_edges = 0;
|
||||
if (p.x() < _margins) {
|
||||
_edges |= Qt::LeftEdge;
|
||||
}
|
||||
if (p.x() > (window()->width() - _margins)) {
|
||||
_edges |= Qt::RightEdge;
|
||||
}
|
||||
if (p.y() < _margins) {
|
||||
_edges |= Qt::TopEdge;
|
||||
}
|
||||
if (p.y() > (window()->height() - _margins)) {
|
||||
_edges |= Qt::BottomEdge;
|
||||
}
|
||||
_updateCursor(_edges);
|
||||
break;
|
||||
}
|
||||
_edges = 0;
|
||||
if ( p.x() < _margins ) {
|
||||
_edges |= Qt::LeftEdge;
|
||||
}
|
||||
if ( p.x() > (window()->width() - _margins) ) {
|
||||
_edges |= Qt::RightEdge;
|
||||
}
|
||||
if ( p.y() < _margins ) {
|
||||
_edges |= Qt::TopEdge;
|
||||
}
|
||||
if ( p.y() > (window()->height() - _margins) ) {
|
||||
_edges |= Qt::BottomEdge;
|
||||
}
|
||||
_updateCursor(_edges);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return QObject::eventFilter(obj, ev);
|
||||
|
@ -6,6 +6,102 @@
|
||||
#include <QQmlProperty>
|
||||
#include "stdafx.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
|
||||
# pragma comment(lib, "user32.lib")
|
||||
# pragma comment(lib, "dwmapi.lib")
|
||||
|
||||
# include <windows.h>
|
||||
# include <windowsx.h>
|
||||
# include <dwmapi.h>
|
||||
enum _DWM_SYSTEMBACKDROP_TYPE {
|
||||
_DWMSBT_AUTO, // [Default] Let DWM automatically decide the system-drawn backdrop for this
|
||||
// window.
|
||||
_DWMSBT_NONE, // [Disable] Do not draw any system backdrop.
|
||||
_DWMSBT_MAINWINDOW, // [Mica] Draw the backdrop material effect corresponding to a
|
||||
// long-lived window.
|
||||
_DWMSBT_TRANSIENTWINDOW, // [Acrylic] Draw the backdrop material effect corresponding to a
|
||||
// transient window.
|
||||
_DWMSBT_TABBEDWINDOW, // [Mica Alt] Draw the backdrop material effect corresponding to a
|
||||
// window with a tabbed title bar.
|
||||
};
|
||||
enum WINDOWCOMPOSITIONATTRIB {
|
||||
WCA_UNDEFINED = 0,
|
||||
WCA_NCRENDERING_ENABLED = 1,
|
||||
WCA_NCRENDERING_POLICY = 2,
|
||||
WCA_TRANSITIONS_FORCEDISABLED = 3,
|
||||
WCA_ALLOW_NCPAINT = 4,
|
||||
WCA_CAPTION_BUTTON_BOUNDS = 5,
|
||||
WCA_NONCLIENT_RTL_LAYOUT = 6,
|
||||
WCA_FORCE_ICONIC_REPRESENTATION = 7,
|
||||
WCA_EXTENDED_FRAME_BOUNDS = 8,
|
||||
WCA_HAS_ICONIC_BITMAP = 9,
|
||||
WCA_THEME_ATTRIBUTES = 10,
|
||||
WCA_NCRENDERING_EXILED = 11,
|
||||
WCA_NCADORNMENTINFO = 12,
|
||||
WCA_EXCLUDED_FROM_LIVEPREVIEW = 13,
|
||||
WCA_VIDEO_OVERLAY_ACTIVE = 14,
|
||||
WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 15,
|
||||
WCA_DISALLOW_PEEK = 16,
|
||||
WCA_CLOAK = 17,
|
||||
WCA_CLOAKED = 18,
|
||||
WCA_ACCENT_POLICY = 19,
|
||||
WCA_FREEZE_REPRESENTATION = 20,
|
||||
WCA_EVER_UNCLOAKED = 21,
|
||||
WCA_VISUAL_OWNER = 22,
|
||||
WCA_HOLOGRAPHIC = 23,
|
||||
WCA_EXCLUDED_FROM_DDA = 24,
|
||||
WCA_PASSIVEUPDATEMODE = 25,
|
||||
WCA_USEDARKMODECOLORS = 26,
|
||||
WCA_CORNER_STYLE = 27,
|
||||
WCA_PART_COLOR = 28,
|
||||
WCA_DISABLE_MOVESIZE_FEEDBACK = 29,
|
||||
WCA_LAST = 30
|
||||
};
|
||||
|
||||
enum ACCENT_STATE {
|
||||
ACCENT_DISABLED = 0,
|
||||
ACCENT_ENABLE_GRADIENT = 1,
|
||||
ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
|
||||
ACCENT_ENABLE_BLURBEHIND = 3, // Traditional DWM blur
|
||||
ACCENT_ENABLE_ACRYLICBLURBEHIND = 4, // RS4 1803
|
||||
ACCENT_ENABLE_HOST_BACKDROP = 5, // RS5 1809
|
||||
ACCENT_INVALID_STATE = 6 // Using this value will remove the window background
|
||||
};
|
||||
|
||||
enum ACCENT_FLAG {
|
||||
ACCENT_NONE = 0,
|
||||
ACCENT_ENABLE_ACRYLIC = 1,
|
||||
ACCENT_ENABLE_ACRYLIC_WITH_LUMINOSITY = 482
|
||||
};
|
||||
|
||||
struct ACCENT_POLICY {
|
||||
DWORD dwAccentState;
|
||||
DWORD dwAccentFlags;
|
||||
DWORD dwGradientColor; // #AABBGGRR
|
||||
DWORD dwAnimationId;
|
||||
};
|
||||
using PACCENT_POLICY = ACCENT_POLICY *;
|
||||
struct WINDOWCOMPOSITIONATTRIBDATA {
|
||||
WINDOWCOMPOSITIONATTRIB Attrib;
|
||||
PVOID pvData;
|
||||
SIZE_T cbData;
|
||||
};
|
||||
using PWINDOWCOMPOSITIONATTRIBDATA = WINDOWCOMPOSITIONATTRIBDATA *;
|
||||
|
||||
typedef HRESULT(WINAPI *DwmSetWindowAttributeFunc)(HWND hwnd, DWORD dwAttribute,
|
||||
LPCVOID pvAttribute, DWORD cbAttribute);
|
||||
typedef HRESULT(WINAPI *DwmExtendFrameIntoClientAreaFunc)(HWND hwnd, const MARGINS *pMarInset);
|
||||
typedef HRESULT(WINAPI *DwmIsCompositionEnabledFunc)(BOOL *pfEnabled);
|
||||
typedef HRESULT(WINAPI *DwmEnableBlurBehindWindowFunc)(HWND hWnd,
|
||||
const DWM_BLURBEHIND *pBlurBehind);
|
||||
typedef BOOL(WINAPI *SetWindowCompositionAttributeFunc)(HWND hwnd,
|
||||
const WINDOWCOMPOSITIONATTRIBDATA *);
|
||||
typedef UINT(WINAPI *GetDpiForWindowFunc)(HWND hWnd);
|
||||
typedef int(WINAPI *GetSystemMetricsForDpiFunc)(int nIndex, UINT dpi);
|
||||
|
||||
#endif
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
using QT_NATIVE_EVENT_RESULT_TYPE = qintptr;
|
||||
using QT_ENTER_EVENT_TYPE = QEnterEvent;
|
||||
@ -23,6 +119,11 @@ class FluFrameless : public QQuickItem, QAbstractNativeEventFilter {
|
||||
Q_PROPERTY_AUTO(bool, topmost)
|
||||
Q_PROPERTY_AUTO(bool, disabled)
|
||||
Q_PROPERTY_AUTO(bool, fixSize)
|
||||
Q_PROPERTY_AUTO(QString, effect)
|
||||
Q_PROPERTY_READONLY_AUTO(bool, effective)
|
||||
Q_PROPERTY_READONLY_AUTO(QStringList, availableEffects)
|
||||
Q_PROPERTY_AUTO(bool, isDarkMode)
|
||||
Q_PROPERTY_AUTO(bool, useSystemEffect)
|
||||
QML_NAMED_ELEMENT(FluFrameless)
|
||||
public:
|
||||
explicit FluFrameless(QQuickItem *parent = nullptr);
|
||||
@ -68,6 +169,7 @@ private:
|
||||
|
||||
void _setMaximizeHovered(bool val);
|
||||
|
||||
|
||||
private:
|
||||
quint64 _current = 0;
|
||||
int _edges = 0;
|
||||
@ -75,4 +177,5 @@ private:
|
||||
quint64 _clickTimer = 0;
|
||||
bool _isWindows11OrGreater = false;
|
||||
QList<QPointer<QQuickItem>> _hitTestList;
|
||||
QString _currentEffect;
|
||||
};
|
||||
|
@ -162,31 +162,41 @@ void FluentUI::registerTypes(const char *uri) const {
|
||||
qmlRegisterUncreatableMetaObject(FluTimelineType::staticMetaObject, uri, major, minor, "FluTimelineType", "Access to enums & flags only");
|
||||
qmlRegisterUncreatableMetaObject(FluSheetType::staticMetaObject, uri, major, minor, "FluSheetType", "Access to enums & flags only");
|
||||
|
||||
qmlRegisterSingletonType(uri, major, minor, "FluApp", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QJSValue {
|
||||
Q_UNUSED(engine)
|
||||
return scriptEngine->newQObject(FluApp::getInstance());
|
||||
});
|
||||
qmlRegisterSingletonType(uri, major, minor, "FluColors", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QJSValue {
|
||||
Q_UNUSED(engine)
|
||||
return scriptEngine->newQObject(FluColors::getInstance());
|
||||
});
|
||||
qmlRegisterSingletonType(uri, major, minor, "FluTheme", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QJSValue {
|
||||
Q_UNUSED(engine)
|
||||
return scriptEngine->newQObject(FluTheme::getInstance());
|
||||
});
|
||||
qmlRegisterSingletonType(uri, major, minor, "FluTools", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QJSValue {
|
||||
Q_UNUSED(engine)
|
||||
return scriptEngine->newQObject(FluTools::getInstance());
|
||||
});
|
||||
qmlRegisterSingletonType(uri, major, minor, "FluTextStyle", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QJSValue {
|
||||
Q_UNUSED(engine)
|
||||
return scriptEngine->newQObject(FluTextStyle::getInstance());
|
||||
});
|
||||
// qmlRegisterSingletonInstance(uri, major, minor, "FluApp", FluApp::getInstance());
|
||||
// qmlRegisterSingletonInstance(uri, major, minor, "FluColors", FluColors::getInstance());
|
||||
// qmlRegisterSingletonInstance(uri, major, minor, "FluTheme", FluTheme::getInstance());
|
||||
// qmlRegisterSingletonInstance(uri, major, minor, "FluTools", FluTools::getInstance());
|
||||
// qmlRegisterSingletonInstance(uri, major, minor, "FluTextStyle", FluTextStyle::getInstance());
|
||||
qmlRegisterSingletonType<FluApp>(uri, major, minor, "FluApp",
|
||||
[](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject* {
|
||||
Q_UNUSED(scriptEngine)
|
||||
QObject *instance = FluApp::getInstance();
|
||||
engine->setObjectOwnership(instance, QQmlEngine::CppOwnership);
|
||||
return instance;
|
||||
});
|
||||
qmlRegisterSingletonType<FluColors>(uri, major, minor, "FluColors",
|
||||
[](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject* {
|
||||
Q_UNUSED(scriptEngine)
|
||||
QObject *instance = FluColors::getInstance();
|
||||
engine->setObjectOwnership(instance, QQmlEngine::CppOwnership);
|
||||
return instance;
|
||||
});
|
||||
qmlRegisterSingletonType<FluTheme>(uri, major, minor, "FluTheme",
|
||||
[](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject* {
|
||||
Q_UNUSED(scriptEngine)
|
||||
QObject *instance = FluTheme::getInstance();
|
||||
engine->setObjectOwnership(instance, QQmlEngine::CppOwnership);
|
||||
return instance;
|
||||
});
|
||||
qmlRegisterSingletonType<FluTools>(uri, major, minor, "FluTools",
|
||||
[](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject* {
|
||||
Q_UNUSED(scriptEngine)
|
||||
QObject *instance = FluTools::getInstance();
|
||||
engine->setObjectOwnership(instance, QQmlEngine::CppOwnership);
|
||||
return instance;
|
||||
});
|
||||
qmlRegisterSingletonType<FluTextStyle>(uri, major, minor, "FluTextStyle",
|
||||
[](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject* {
|
||||
Q_UNUSED(scriptEngine)
|
||||
QObject *instance = FluTextStyle::getInstance();
|
||||
engine->setObjectOwnership(instance, QQmlEngine::CppOwnership);
|
||||
return instance;
|
||||
});
|
||||
qmlRegisterModule(uri, major, minor);
|
||||
#endif
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ Rectangle{
|
||||
text:{
|
||||
if(count<100)
|
||||
return count
|
||||
return count+"+"
|
||||
return "100+"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import QtQuick 2.15
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import FluentUI 1.0
|
||||
|
||||
@ -11,17 +11,11 @@ Button {
|
||||
property color dividerColor: FluTheme.dark ? Qt.rgba(80/255,80/255,80/255,1) : Qt.rgba(233/255,233/255,233/255,1)
|
||||
property color textColor: {
|
||||
if(FluTheme.dark){
|
||||
if(!enabled){
|
||||
return Qt.rgba(131/255,131/255,131/255,1)
|
||||
}
|
||||
if(pressed){
|
||||
return Qt.rgba(162/255,162/255,162/255,1)
|
||||
}
|
||||
return Qt.rgba(1,1,1,1)
|
||||
}else{
|
||||
if(!enabled){
|
||||
return Qt.rgba(160/255,160/255,160/255,1)
|
||||
}
|
||||
if(pressed){
|
||||
return Qt.rgba(96/255,96/255,96/255,1)
|
||||
}
|
||||
@ -59,6 +53,6 @@ Button {
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font: control.font
|
||||
color: control.textColor
|
||||
textColor: control.textColor
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,9 @@ Canvas {
|
||||
function animateToNewData()
|
||||
{
|
||||
chartAnimationProgress = 0.1;
|
||||
d.jsChart.update();
|
||||
if (d.jsChart) {
|
||||
d.jsChart.update();
|
||||
}
|
||||
chartAnimator.restart();
|
||||
}
|
||||
QtObject{
|
||||
|
@ -107,7 +107,7 @@ T.ComboBox {
|
||||
y: control.height
|
||||
width: control.width
|
||||
height: Math.min(contentItem.implicitHeight, control.Window.height - topMargin - bottomMargin)
|
||||
topMargin: 6
|
||||
topMargin: 32
|
||||
bottomMargin: 6
|
||||
modal: true
|
||||
contentItem: ListView {
|
||||
|
@ -41,7 +41,7 @@ FluPopup {
|
||||
FluText{
|
||||
id:text_message
|
||||
font: FluTextStyle.Body
|
||||
wrapMode: Text.WrapAnywhere
|
||||
wrapMode: Text.WordWrap
|
||||
text:message
|
||||
width: parent.width
|
||||
topPadding: 4
|
||||
@ -67,7 +67,7 @@ FluPopup {
|
||||
topPadding: 20
|
||||
leftPadding: 20
|
||||
rightPadding: 20
|
||||
wrapMode: Text.WrapAnywhere
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
FluLoader{
|
||||
sourceComponent: com_message
|
||||
|
@ -1,4 +1,4 @@
|
||||
import QtQuick 2.15
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import FluentUI 1.0
|
||||
|
||||
@ -11,7 +11,8 @@ Text {
|
||||
font.pixelSize: iconSize
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: iconColor
|
||||
color: enabled ? iconColor : Qt.rgba(iconColor.r, iconColor.g, iconColor.b, iconColor.a * 0.5)
|
||||
|
||||
text: (String.fromCharCode(iconSource).toString(16))
|
||||
opacity: iconSource>0
|
||||
FontLoader{
|
||||
|
@ -1,4 +1,4 @@
|
||||
import QtQuick 2.15
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import FluentUI 1.0
|
||||
@ -26,14 +26,8 @@ Button {
|
||||
}
|
||||
property color iconColor: {
|
||||
if(FluTheme.dark){
|
||||
if(!enabled){
|
||||
return Qt.rgba(130/255,130/255,130/255,1)
|
||||
}
|
||||
return Qt.rgba(1,1,1,1)
|
||||
}else{
|
||||
if(!enabled){
|
||||
return Qt.rgba(161/255,161/255,161/255,1)
|
||||
}
|
||||
return Qt.rgba(0,0,0,1)
|
||||
}
|
||||
}
|
||||
@ -82,7 +76,7 @@ Button {
|
||||
text:control.text
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
visible: display !== Button.IconOnly
|
||||
color: control.textColor
|
||||
textColor: control.textColor
|
||||
font: control.font
|
||||
}
|
||||
}
|
||||
@ -99,7 +93,7 @@ Button {
|
||||
text:control.text
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
visible: display !== Button.IconOnly
|
||||
color: control.textColor
|
||||
textColor: control.textColor
|
||||
font: control.font
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import QtQuick 2.15
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import FluentUI 1.0
|
||||
|
||||
@ -11,6 +11,7 @@ Image {
|
||||
property Component errorItem : com_error
|
||||
property Component loadingItem: com_loading
|
||||
id: control
|
||||
opacity: enabled ? 1 : 0.5
|
||||
FluLoader{
|
||||
anchors.fill: parent
|
||||
sourceComponent: {
|
||||
|
@ -190,13 +190,13 @@ FluObject {
|
||||
spacing: 5
|
||||
FluText{
|
||||
text:_super.text
|
||||
wrapMode: Text.WrapAnywhere
|
||||
wrapMode: Text.WordWrap
|
||||
width: Math.min(implicitWidth,mcontrol.maxWidth)
|
||||
}
|
||||
FluText{
|
||||
text: _super.moremsg
|
||||
visible: _super.moremsg
|
||||
wrapMode : Text.WrapAnywhere
|
||||
wrapMode : Text.WordWrap
|
||||
textColor: FluColors.Grey120
|
||||
width: Math.min(implicitWidth,mcontrol.maxWidth)
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import QtQuick 2.15
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import FluentUI 1.0
|
||||
|
||||
@ -13,7 +13,7 @@ FluButton {
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font: control.font
|
||||
color: control.textColor
|
||||
textColor: control.textColor
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
Item{
|
||||
|
@ -20,7 +20,7 @@ TextArea{
|
||||
return normalColor
|
||||
}
|
||||
font:FluTextStyle.Body
|
||||
wrapMode: Text.WrapAnywhere
|
||||
wrapMode: Text.WordWrap
|
||||
padding: 8
|
||||
leftPadding: padding+4
|
||||
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
|
||||
|
@ -41,13 +41,15 @@ ProgressBar{
|
||||
height: parent.height
|
||||
radius: d._radius
|
||||
color: control.color
|
||||
PropertyAnimation on x {
|
||||
id:animator_x
|
||||
SequentialAnimation on x {
|
||||
id: animator_x
|
||||
running: control.indeterminate && control.visible
|
||||
from: -rect_progress.width
|
||||
to:control.width+rect_progress.width
|
||||
loops: Animation.Infinite
|
||||
duration: control.duration
|
||||
PropertyAnimation {
|
||||
from: -rect_progress.width
|
||||
to: control.width + rect_progress.width
|
||||
duration: control.duration
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,11 @@ import QtQuick.Controls 2.15
|
||||
import FluentUI 1.0
|
||||
|
||||
FluPage {
|
||||
property bool autoResetScroll: false
|
||||
default property alias content: container.data
|
||||
|
||||
Flickable{
|
||||
id: flickable
|
||||
clip: true
|
||||
anchors.fill: parent
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
@ -17,4 +20,14 @@ FluPage {
|
||||
width: parent.width
|
||||
}
|
||||
}
|
||||
|
||||
function resetScroll() {
|
||||
flickable.contentY = 0;
|
||||
}
|
||||
|
||||
StackView.onActivated: {
|
||||
if (autoResetScroll) {
|
||||
resetScroll(); // Call this function to reset the scroll position to the top
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
import QtQuick 2.15
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import FluentUI 1.0
|
||||
|
||||
Text {
|
||||
property color textColor: FluTheme.fontPrimaryColor
|
||||
id:text
|
||||
color: textColor
|
||||
color: enabled ? textColor : Qt.rgba(textColor.r, textColor.g, textColor.b, textColor.a * 0.7)
|
||||
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
|
||||
font: FluTextStyle.Body
|
||||
}
|
||||
|
@ -335,7 +335,7 @@ FluButton {
|
||||
if (hours === "12") {
|
||||
hours24 = (period === control.amText) ? 0 : 12;
|
||||
} else {
|
||||
hours24 = (period === control.pmText) ? hours24 : hours24 + 12;
|
||||
hours24 = (period === control.pmText) ? hours24 + 12 : hours24;
|
||||
}
|
||||
}
|
||||
date.setHours(hours24);
|
||||
|
@ -98,7 +98,7 @@ Item{
|
||||
Component{
|
||||
id:com_lable
|
||||
FluText{
|
||||
wrapMode: Text.WrapAnywhere
|
||||
wrapMode: Text.WordWrap
|
||||
horizontalAlignment: isRight ? Qt.AlignRight : Qt.AlignLeft
|
||||
text: {
|
||||
if(modelData.lable){
|
||||
@ -113,7 +113,7 @@ Item{
|
||||
Component{
|
||||
id:com_text
|
||||
FluText{
|
||||
wrapMode: Text.WrapAnywhere
|
||||
wrapMode: Text.WordWrap
|
||||
horizontalAlignment: isRight ? Qt.AlignRight : Qt.AlignLeft
|
||||
text: modelData.text
|
||||
textFormat: Text.RichText
|
||||
|
@ -175,7 +175,7 @@ Popup{
|
||||
FluText{
|
||||
id: text_desc
|
||||
font: FluTextStyle.Body
|
||||
wrapMode: Text.WrapAnywhere
|
||||
wrapMode: Text.WordWrap
|
||||
maximumLineCount: 4
|
||||
elide: Text.ElideRight
|
||||
text: {
|
||||
|
@ -13,6 +13,11 @@ Window {
|
||||
property bool fixSize: false
|
||||
property Component loadingItem: com_loading
|
||||
property bool fitsAppBarWindows: false
|
||||
property var tintOpacity: FluTheme.dark ? 0.80 : 0.75
|
||||
property int blurRadius: 60
|
||||
property alias effect: frameless.effect
|
||||
readonly property alias effective: frameless.effective
|
||||
readonly property alias availableEffects: frameless.availableEffects
|
||||
property Item appBar: FluAppBar {
|
||||
title: window.title
|
||||
height: 30
|
||||
@ -24,6 +29,15 @@ Window {
|
||||
icon: window.windowIcon
|
||||
}
|
||||
property color backgroundColor: {
|
||||
if(frameless.effective && active){
|
||||
var backcolor
|
||||
if(frameless.effect==="dwm-blur"){
|
||||
backcolor = FluTools.withOpacity(FluTheme.windowActiveBackgroundColor, window.tintOpacity)
|
||||
}else{
|
||||
backcolor = "transparent"
|
||||
}
|
||||
return backcolor
|
||||
}
|
||||
if(active){
|
||||
return FluTheme.windowActiveBackgroundColor
|
||||
}
|
||||
@ -100,6 +114,8 @@ Window {
|
||||
fixSize: window.fixSize
|
||||
topmost: window.stayTop
|
||||
disabled: FluApp.useSystemAppBar
|
||||
isDarkMode: FluTheme.dark
|
||||
useSystemEffect: !FluTheme.blurBehindWindowEnabled
|
||||
Component.onCompleted: {
|
||||
frameless.setHitTestVisible(appBar.layoutMacosButtons)
|
||||
frameless.setHitTestVisible(appBar.layoutStandardbuttons)
|
||||
@ -107,6 +123,11 @@ Window {
|
||||
Component.onDestruction: {
|
||||
frameless.onDestruction()
|
||||
}
|
||||
onEffectiveChanged: {
|
||||
if(effective){
|
||||
FluTheme.blurBehindWindowEnabled = false
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_background
|
||||
@ -162,8 +183,8 @@ Window {
|
||||
FluAcrylic{
|
||||
anchors.fill: parent
|
||||
target: img_back
|
||||
tintOpacity: FluTheme.dark ? 0.80 : 0.75
|
||||
blurRadius: 64
|
||||
tintOpacity: window.tintOpacity
|
||||
blurRadius: window.blurRadius
|
||||
visible: window.active && FluTheme.blurBehindWindowEnabled
|
||||
tintColor: FluTheme.dark ? Qt.rgba(0, 0, 0, 1) : Qt.rgba(1, 1, 1, 1)
|
||||
targetRect: Qt.rect(window.x-window.screen.virtualX,window.y-window.screen.virtualY,window.width,window.height)
|
||||
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 473 B |
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 389 B |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 434 B |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 535 B |
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 409 B |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 559 B |
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 416 B |
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 395 B |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 437 B |
Before Width: | Height: | Size: 266 KiB After Width: | Height: | Size: 142 KiB |
@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
|
||||
// It is used for QML tooling purposes only.
|
||||
//
|
||||
// This file was auto-generated by:
|
||||
// 'qmlplugindump -nonrelocatable FluentUI 1.0 D:/QtProjects/build-FluentUI-Desktop_Qt_5_15_2_MSVC2019_64bit-Release/src'
|
||||
// 'qmlplugindump -nonrelocatable -noinstantiate FluentUI 1.0 F:/FluentUI/build/Desktop_Qt_5_15_2_MSVC2019_32bit-Release/src'
|
||||
|
||||
Module {
|
||||
dependencies: ["QtQuick 2.0"]
|
||||
@ -150,6 +150,11 @@ Module {
|
||||
Property { name: "topmost"; type: "bool" }
|
||||
Property { name: "disabled"; type: "bool" }
|
||||
Property { name: "fixSize"; type: "bool" }
|
||||
Property { name: "effect"; type: "string" }
|
||||
Property { name: "effective"; type: "bool"; isReadonly: true }
|
||||
Property { name: "availableEffects"; type: "QStringList"; isReadonly: true }
|
||||
Property { name: "isDarkMode"; type: "bool" }
|
||||
Property { name: "useSystemEffect"; type: "bool" }
|
||||
Method { name: "showFullScreen" }
|
||||
Method { name: "showMaximized" }
|
||||
Method { name: "showMinimized" }
|
||||
@ -669,12 +674,12 @@ Module {
|
||||
}
|
||||
}
|
||||
Component {
|
||||
name: "Fluent_Icons"
|
||||
name: "FluentIcons"
|
||||
exports: ["FluentUI/FluentIcons 1.0"]
|
||||
isCreatable: false
|
||||
exportMetaObjectRevisions: [0]
|
||||
Enum {
|
||||
name: "Fluent_IconType"
|
||||
name: "Type"
|
||||
values: {
|
||||
"GlobalNavButton": 59136,
|
||||
"Wifi": 59137,
|
||||
@ -2449,6 +2454,240 @@ Module {
|
||||
Method { name: "clear" }
|
||||
Method { name: "invalidate" }
|
||||
}
|
||||
Component {
|
||||
name: "QmlQCustomPlot::Axis"
|
||||
prototype: "QObject"
|
||||
exports: ["FluentUI/Axis 1.0"]
|
||||
isCreatable: false
|
||||
exportMetaObjectRevisions: [0]
|
||||
Enum {
|
||||
name: "TickerType"
|
||||
values: {
|
||||
"Fixed": 0,
|
||||
"Log": 1,
|
||||
"Pi": 2,
|
||||
"Text": 3,
|
||||
"DateTime": 4,
|
||||
"Time": 5
|
||||
}
|
||||
}
|
||||
Property { name: "visible"; type: "bool" }
|
||||
Property { name: "label"; type: "string" }
|
||||
Property { name: "upper"; type: "float" }
|
||||
Property { name: "lower"; type: "float" }
|
||||
Property { name: "grid"; type: "QmlQCustomPlot::Grid"; isReadonly: true; isPointer: true }
|
||||
Property { name: "ticker"; type: "QmlQCustomPlot::Ticker"; isReadonly: true; isPointer: true }
|
||||
Signal {
|
||||
name: "visibleChanged"
|
||||
Parameter { type: "bool" }
|
||||
}
|
||||
Signal {
|
||||
name: "labelChanged"
|
||||
Parameter { type: "string" }
|
||||
}
|
||||
Signal {
|
||||
name: "upperChanged"
|
||||
Parameter { type: "float" }
|
||||
}
|
||||
Signal {
|
||||
name: "lowerChanged"
|
||||
Parameter { type: "float" }
|
||||
}
|
||||
Signal {
|
||||
name: "gridChanged"
|
||||
Parameter { type: "QmlQCustomPlot::Grid"; isPointer: true }
|
||||
}
|
||||
Signal {
|
||||
name: "tickerChanged"
|
||||
Parameter { type: "QmlQCustomPlot::Ticker"; isPointer: true }
|
||||
}
|
||||
Method {
|
||||
name: "setTickerType"
|
||||
Parameter { name: "type"; type: "TickerType" }
|
||||
}
|
||||
Method {
|
||||
name: "setRange"
|
||||
Parameter { name: "position"; type: "float" }
|
||||
Parameter { name: "size"; type: "float" }
|
||||
Parameter { name: "align"; type: "Qt::AlignmentFlag" }
|
||||
}
|
||||
Method {
|
||||
name: "setRange"
|
||||
Parameter { name: "lower"; type: "float" }
|
||||
Parameter { name: "upper"; type: "float" }
|
||||
}
|
||||
}
|
||||
Component {
|
||||
name: "QmlQCustomPlot::BasePlot"
|
||||
defaultProperty: "data"
|
||||
prototype: "QQuickPaintedItem"
|
||||
exports: ["FluentUI/BasePlot 1.0"]
|
||||
exportMetaObjectRevisions: [0]
|
||||
Property { name: "backgroundColor"; type: "QColor" }
|
||||
Property { name: "xAxis"; type: "QmlQCustomPlot::Axis"; isReadonly: true; isPointer: true }
|
||||
Property { name: "x1Axis"; type: "QmlQCustomPlot::Axis"; isReadonly: true; isPointer: true }
|
||||
Property { name: "yAxis"; type: "QmlQCustomPlot::Axis"; isReadonly: true; isPointer: true }
|
||||
Property { name: "y1Axis"; type: "QmlQCustomPlot::Axis"; isReadonly: true; isPointer: true }
|
||||
Property { name: "graphs"; type: "QVariantMap"; isReadonly: true }
|
||||
Signal {
|
||||
name: "backgroundColorChanged"
|
||||
Parameter { type: "QColor" }
|
||||
}
|
||||
Signal {
|
||||
name: "xAxisChanged"
|
||||
Parameter { type: "QmlQCustomPlot::Axis"; isPointer: true }
|
||||
}
|
||||
Signal {
|
||||
name: "x1AxisChanged"
|
||||
Parameter { type: "QmlQCustomPlot::Axis"; isPointer: true }
|
||||
}
|
||||
Signal {
|
||||
name: "yAxisChanged"
|
||||
Parameter { type: "QmlQCustomPlot::Axis"; isPointer: true }
|
||||
}
|
||||
Signal {
|
||||
name: "y1AxisChanged"
|
||||
Parameter { type: "QmlQCustomPlot::Axis"; isPointer: true }
|
||||
}
|
||||
Method {
|
||||
name: "addGraph"
|
||||
Parameter { name: "key"; type: "string" }
|
||||
}
|
||||
Method {
|
||||
name: "removeGraph"
|
||||
Parameter { name: "key"; type: "string" }
|
||||
}
|
||||
Method {
|
||||
name: "rescaleAxes"
|
||||
Parameter { name: "onlyVisiblePlottables"; type: "bool" }
|
||||
}
|
||||
Method { name: "rescaleAxes" }
|
||||
}
|
||||
Component {
|
||||
name: "QmlQCustomPlot::Grid"
|
||||
prototype: "QObject"
|
||||
exports: ["FluentUI/PlotGrid 1.0"]
|
||||
isCreatable: false
|
||||
exportMetaObjectRevisions: [0]
|
||||
Enum {
|
||||
name: "LineType"
|
||||
values: {
|
||||
"NoPen": 0,
|
||||
"SolidLine": 1,
|
||||
"DashLine": 2,
|
||||
"DotLine": 3,
|
||||
"DashDotLine": 4,
|
||||
"DashDotDotLine": 5
|
||||
}
|
||||
}
|
||||
Property { name: "visible"; type: "bool" }
|
||||
Property { name: "subVisible"; type: "bool" }
|
||||
Property { name: "lineWidth"; type: "int" }
|
||||
Property { name: "lineColor"; type: "QColor" }
|
||||
Property { name: "lineType"; type: "LineType" }
|
||||
Property { name: "subLineWidth"; type: "int" }
|
||||
Property { name: "subLineColor"; type: "QColor" }
|
||||
Property { name: "subLineType"; type: "LineType" }
|
||||
Signal {
|
||||
name: "visibleChanged"
|
||||
Parameter { type: "bool" }
|
||||
}
|
||||
Signal {
|
||||
name: "subVisibleChanged"
|
||||
Parameter { type: "bool" }
|
||||
}
|
||||
Signal {
|
||||
name: "lineWidthChanged"
|
||||
Parameter { type: "int" }
|
||||
}
|
||||
Signal {
|
||||
name: "lineColorChanged"
|
||||
Parameter { type: "QColor" }
|
||||
}
|
||||
Signal {
|
||||
name: "lineTypeChanged"
|
||||
Parameter { type: "LineType" }
|
||||
}
|
||||
Signal {
|
||||
name: "subLineWidthChanged"
|
||||
Parameter { type: "int" }
|
||||
}
|
||||
Signal {
|
||||
name: "subLineColorChanged"
|
||||
Parameter { type: "QColor" }
|
||||
}
|
||||
Signal {
|
||||
name: "subLineTypeChanged"
|
||||
Parameter { type: "LineType" }
|
||||
}
|
||||
}
|
||||
Component {
|
||||
name: "QmlQCustomPlot::Ticker"
|
||||
prototype: "QObject"
|
||||
exports: ["FluentUI/Ticker 1.0"]
|
||||
isCreatable: false
|
||||
exportMetaObjectRevisions: [0]
|
||||
Property { name: "ticks"; type: "bool" }
|
||||
Property { name: "subTicks"; type: "bool" }
|
||||
Property { name: "tickCount"; type: "int" }
|
||||
Property { name: "baseWidth"; type: "int" }
|
||||
Property { name: "baseColor"; type: "QColor" }
|
||||
Property { name: "tickColor"; type: "QColor" }
|
||||
Property { name: "subTickColor"; type: "QColor" }
|
||||
Signal {
|
||||
name: "ticksChanged"
|
||||
Parameter { type: "bool" }
|
||||
}
|
||||
Signal {
|
||||
name: "subTicksChanged"
|
||||
Parameter { type: "bool" }
|
||||
}
|
||||
Signal {
|
||||
name: "tickCountChanged"
|
||||
Parameter { type: "int" }
|
||||
}
|
||||
Signal {
|
||||
name: "baseWidthChanged"
|
||||
Parameter { type: "int" }
|
||||
}
|
||||
Signal {
|
||||
name: "baseColorChanged"
|
||||
Parameter { type: "QColor" }
|
||||
}
|
||||
Signal {
|
||||
name: "tickColorChanged"
|
||||
Parameter { type: "QColor" }
|
||||
}
|
||||
Signal {
|
||||
name: "subTickColorChanged"
|
||||
Parameter { type: "QColor" }
|
||||
}
|
||||
}
|
||||
Component {
|
||||
name: "QmlQCustomPlot::TimePlot"
|
||||
defaultProperty: "data"
|
||||
prototype: "QmlQCustomPlot::BasePlot"
|
||||
exports: ["FluentUI/TimePlot 1.0"]
|
||||
exportMetaObjectRevisions: [0]
|
||||
Property { name: "plotTimeRangeInMilliseconds"; type: "int" }
|
||||
Signal {
|
||||
name: "plotTimeRangeInMillisecondsChanged"
|
||||
Parameter { type: "int" }
|
||||
}
|
||||
Method {
|
||||
name: "setTimeFormat"
|
||||
Parameter { name: "format"; type: "string" }
|
||||
}
|
||||
Method {
|
||||
name: "addCurrentTimeValue"
|
||||
Parameter { name: "name"; type: "string" }
|
||||
Parameter { name: "value"; type: "double" }
|
||||
}
|
||||
Method {
|
||||
name: "addCurrentTimeValues"
|
||||
Parameter { name: "values"; type: "QVariantMap" }
|
||||
}
|
||||
}
|
||||
Component {
|
||||
prototype: "QQuickItem"
|
||||
name: "FluentUI/FluAcrylic 1.0"
|
||||
@ -2507,37 +2746,37 @@ Module {
|
||||
Property { name: "darkClickListener"; type: "QVariant" }
|
||||
Property {
|
||||
name: "buttonStayTop"
|
||||
type: "FluIconButton_QMLTYPE_18"
|
||||
type: "FluIconButton_QMLTYPE_19"
|
||||
isReadonly: true
|
||||
isPointer: true
|
||||
}
|
||||
Property {
|
||||
name: "buttonMinimize"
|
||||
type: "FluIconButton_QMLTYPE_18"
|
||||
type: "FluIconButton_QMLTYPE_19"
|
||||
isReadonly: true
|
||||
isPointer: true
|
||||
}
|
||||
Property {
|
||||
name: "buttonMaximize"
|
||||
type: "FluIconButton_QMLTYPE_18"
|
||||
type: "FluIconButton_QMLTYPE_19"
|
||||
isReadonly: true
|
||||
isPointer: true
|
||||
}
|
||||
Property {
|
||||
name: "buttonClose"
|
||||
type: "FluIconButton_QMLTYPE_18"
|
||||
type: "FluIconButton_QMLTYPE_19"
|
||||
isReadonly: true
|
||||
isPointer: true
|
||||
}
|
||||
Property {
|
||||
name: "buttonDark"
|
||||
type: "FluIconButton_QMLTYPE_18"
|
||||
type: "FluIconButton_QMLTYPE_19"
|
||||
isReadonly: true
|
||||
isPointer: true
|
||||
}
|
||||
Property {
|
||||
name: "layoutMacosButtons"
|
||||
type: "FluLoader_QMLTYPE_16"
|
||||
type: "FluLoader_QMLTYPE_11"
|
||||
isReadonly: true
|
||||
isPointer: true
|
||||
}
|
||||
@ -3230,15 +3469,15 @@ Module {
|
||||
defaultProperty: "data"
|
||||
Property { name: "logo"; type: "QUrl" }
|
||||
Property { name: "title"; type: "string" }
|
||||
Property { name: "items"; type: "FluObject_QMLTYPE_164"; isPointer: true }
|
||||
Property { name: "footerItems"; type: "FluObject_QMLTYPE_164"; isPointer: true }
|
||||
Property { name: "items"; type: "FluObject_QMLTYPE_176"; isPointer: true }
|
||||
Property { name: "footerItems"; type: "FluObject_QMLTYPE_176"; isPointer: true }
|
||||
Property { name: "displayMode"; type: "int" }
|
||||
Property { name: "autoSuggestBox"; type: "QQmlComponent"; isPointer: true }
|
||||
Property { name: "actionItem"; type: "QQmlComponent"; isPointer: true }
|
||||
Property { name: "topPadding"; type: "int" }
|
||||
Property { name: "pageMode"; type: "int" }
|
||||
Property { name: "navItemRightMenu"; type: "FluMenu_QMLTYPE_36"; isPointer: true }
|
||||
Property { name: "navItemExpanderRightMenu"; type: "FluMenu_QMLTYPE_36"; isPointer: true }
|
||||
Property { name: "navItemRightMenu"; type: "FluMenu_QMLTYPE_48"; isPointer: true }
|
||||
Property { name: "navItemExpanderRightMenu"; type: "FluMenu_QMLTYPE_48"; isPointer: true }
|
||||
Property { name: "navCompactWidth"; type: "int" }
|
||||
Property { name: "navTopMargin"; type: "int" }
|
||||
Property { name: "cellHeight"; type: "int" }
|
||||
@ -3246,13 +3485,13 @@ Module {
|
||||
Property { name: "hideNavAppBar"; type: "bool" }
|
||||
Property {
|
||||
name: "buttonMenu"
|
||||
type: "FluIconButton_QMLTYPE_18"
|
||||
type: "FluIconButton_QMLTYPE_19"
|
||||
isReadonly: true
|
||||
isPointer: true
|
||||
}
|
||||
Property {
|
||||
name: "buttonBack"
|
||||
type: "FluIconButton_QMLTYPE_18"
|
||||
type: "FluIconButton_QMLTYPE_19"
|
||||
isReadonly: true
|
||||
isPointer: true
|
||||
}
|
||||
@ -3620,7 +3859,7 @@ Module {
|
||||
Method {
|
||||
name: "removeWindow"
|
||||
type: "QVariant"
|
||||
Parameter { name: "window"; type: "QVariant" }
|
||||
Parameter { name: "win"; type: "QVariant" }
|
||||
}
|
||||
Method {
|
||||
name: "exit"
|
||||
@ -4138,6 +4377,9 @@ Module {
|
||||
Property { name: "fixSize"; type: "bool" }
|
||||
Property { name: "loadingItem"; type: "QQmlComponent"; isPointer: true }
|
||||
Property { name: "fitsAppBarWindows"; type: "bool" }
|
||||
Property { name: "tintOpacity"; type: "QVariant" }
|
||||
Property { name: "blurRadius"; type: "int" }
|
||||
Property { name: "availableEffects"; type: "QVariant"; isReadonly: true }
|
||||
Property { name: "appBar"; type: "QQuickItem"; isPointer: true }
|
||||
Property { name: "backgroundColor"; type: "QColor" }
|
||||
Property { name: "stayTop"; type: "bool" }
|
||||
@ -4151,6 +4393,7 @@ Module {
|
||||
Property { name: "autoCenter"; type: "bool" }
|
||||
Property { name: "autoDestroy"; type: "bool" }
|
||||
Property { name: "useSystemAppBar"; type: "bool" }
|
||||
Property { name: "__margins"; type: "int" }
|
||||
Property { name: "resizeBorderColor"; type: "QColor" }
|
||||
Property { name: "resizeBorderWidth"; type: "int" }
|
||||
Property { name: "closeListener"; type: "QVariant" }
|
||||
@ -4158,6 +4401,8 @@ Module {
|
||||
Property { name: "_route"; type: "string" }
|
||||
Property { name: "_hideShadow"; type: "bool" }
|
||||
Property { name: "contentData"; type: "QObject"; isList: true; isReadonly: true }
|
||||
Property { name: "effect"; type: "string" }
|
||||
Property { name: "effective"; type: "bool"; isReadonly: true }
|
||||
Signal {
|
||||
name: "initArgument"
|
||||
Parameter { name: "argument"; type: "QVariant" }
|
||||
@ -4195,11 +4440,6 @@ Module {
|
||||
Method { name: "clearAllInfo"; type: "QVariant" }
|
||||
Method { name: "moveWindowToDesktopCenter"; type: "QVariant" }
|
||||
Method { name: "fixWindowSize"; type: "QVariant" }
|
||||
Method {
|
||||
name: "registerForWindowResult"
|
||||
type: "QVariant"
|
||||
Parameter { name: "path"; type: "QVariant" }
|
||||
}
|
||||
Method {
|
||||
name: "setResult"
|
||||
type: "QVariant"
|
||||
@ -4219,6 +4459,8 @@ Module {
|
||||
type: "QVariant"
|
||||
Parameter { name: "val"; type: "QVariant" }
|
||||
}
|
||||
Method { name: "deleteLater"; type: "QVariant" }
|
||||
Method { name: "containerItem"; type: "QVariant" }
|
||||
}
|
||||
Component {
|
||||
prototype: "QQuickWindowQmlImpl"
|
||||
@ -4241,6 +4483,9 @@ Module {
|
||||
Property { name: "fixSize"; type: "bool" }
|
||||
Property { name: "loadingItem"; type: "QQmlComponent"; isPointer: true }
|
||||
Property { name: "fitsAppBarWindows"; type: "bool" }
|
||||
Property { name: "tintOpacity"; type: "QVariant" }
|
||||
Property { name: "blurRadius"; type: "int" }
|
||||
Property { name: "availableEffects"; type: "QVariant"; isReadonly: true }
|
||||
Property { name: "appBar"; type: "QQuickItem"; isPointer: true }
|
||||
Property { name: "backgroundColor"; type: "QColor" }
|
||||
Property { name: "stayTop"; type: "bool" }
|
||||
@ -4254,6 +4499,7 @@ Module {
|
||||
Property { name: "autoCenter"; type: "bool" }
|
||||
Property { name: "autoDestroy"; type: "bool" }
|
||||
Property { name: "useSystemAppBar"; type: "bool" }
|
||||
Property { name: "__margins"; type: "int" }
|
||||
Property { name: "resizeBorderColor"; type: "QColor" }
|
||||
Property { name: "resizeBorderWidth"; type: "int" }
|
||||
Property { name: "closeListener"; type: "QVariant" }
|
||||
@ -4261,6 +4507,8 @@ Module {
|
||||
Property { name: "_route"; type: "string" }
|
||||
Property { name: "_hideShadow"; type: "bool" }
|
||||
Property { name: "contentData"; type: "QObject"; isList: true; isReadonly: true }
|
||||
Property { name: "effect"; type: "string" }
|
||||
Property { name: "effective"; type: "bool"; isReadonly: true }
|
||||
Signal {
|
||||
name: "initArgument"
|
||||
Parameter { name: "argument"; type: "QVariant" }
|
||||
@ -4298,11 +4546,6 @@ Module {
|
||||
Method { name: "clearAllInfo"; type: "QVariant" }
|
||||
Method { name: "moveWindowToDesktopCenter"; type: "QVariant" }
|
||||
Method { name: "fixWindowSize"; type: "QVariant" }
|
||||
Method {
|
||||
name: "registerForWindowResult"
|
||||
type: "QVariant"
|
||||
Parameter { name: "path"; type: "QVariant" }
|
||||
}
|
||||
Method {
|
||||
name: "setResult"
|
||||
type: "QVariant"
|
||||
@ -4322,6 +4565,8 @@ Module {
|
||||
type: "QVariant"
|
||||
Parameter { name: "val"; type: "QVariant" }
|
||||
}
|
||||
Method { name: "deleteLater"; type: "QVariant" }
|
||||
Method { name: "containerItem"; type: "QVariant" }
|
||||
}
|
||||
Component {
|
||||
prototype: "QQuickItem"
|
||||
|
@ -73,7 +73,7 @@ Rectangle{
|
||||
text:{
|
||||
if(count<100)
|
||||
return count
|
||||
return count+"+"
|
||||
return "100+"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,9 @@ Canvas {
|
||||
function animateToNewData()
|
||||
{
|
||||
chartAnimationProgress = 0.1;
|
||||
d.jsChart.update();
|
||||
if (d.jsChart) {
|
||||
d.jsChart.update();
|
||||
}
|
||||
chartAnimator.restart();
|
||||
}
|
||||
QtObject{
|
||||
|
@ -107,7 +107,7 @@ T.ComboBox {
|
||||
y: control.height
|
||||
width: control.width
|
||||
height: Math.min(contentItem.implicitHeight, control.Window.height - topMargin - bottomMargin)
|
||||
topMargin: 6
|
||||
topMargin: 32
|
||||
bottomMargin: 6
|
||||
modal: true
|
||||
contentItem: ListView {
|
||||
|
@ -41,7 +41,7 @@ FluPopup {
|
||||
FluText{
|
||||
id:text_message
|
||||
font: FluTextStyle.Body
|
||||
wrapMode: Text.WrapAnywhere
|
||||
wrapMode: Text.WordWrap
|
||||
text:message
|
||||
width: parent.width
|
||||
topPadding: 4
|
||||
@ -67,7 +67,7 @@ FluPopup {
|
||||
topPadding: 20
|
||||
leftPadding: 20
|
||||
rightPadding: 20
|
||||
wrapMode: Text.WrapAnywhere
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
FluLoader{
|
||||
sourceComponent: com_message
|
||||
|
@ -190,13 +190,13 @@ FluObject {
|
||||
spacing: 5
|
||||
FluText{
|
||||
text:_super.text
|
||||
wrapMode: Text.WrapAnywhere
|
||||
wrapMode: Text.WordWrap
|
||||
width: Math.min(implicitWidth,mcontrol.maxWidth)
|
||||
}
|
||||
FluText{
|
||||
text: _super.moremsg
|
||||
visible: _super.moremsg
|
||||
wrapMode : Text.WrapAnywhere
|
||||
wrapMode : Text.WordWrap
|
||||
textColor: FluColors.Grey120
|
||||
width: Math.min(implicitWidth,mcontrol.maxWidth)
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ TextArea{
|
||||
return normalColor
|
||||
}
|
||||
font:FluTextStyle.Body
|
||||
wrapMode: Text.WrapAnywhere
|
||||
wrapMode: Text.WordWrap
|
||||
padding: 8
|
||||
leftPadding: padding+4
|
||||
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
|
||||
|
@ -42,13 +42,15 @@ ProgressBar{
|
||||
height: parent.height
|
||||
radius: d._radius
|
||||
color: control.color
|
||||
PropertyAnimation on x {
|
||||
id:animator_x
|
||||
SequentialAnimation on x {
|
||||
id: animator_x
|
||||
running: control.indeterminate && control.visible
|
||||
from: -rect_progress.width
|
||||
to:control.width+rect_progress.width
|
||||
loops: Animation.Infinite
|
||||
duration: control.duration
|
||||
PropertyAnimation {
|
||||
from: -rect_progress.width
|
||||
to: control.width + rect_progress.width
|
||||
duration: control.duration
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,11 @@ import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
FluPage {
|
||||
property bool autoResetScroll: false
|
||||
default property alias content: container.data
|
||||
|
||||
Flickable{
|
||||
id: flickable
|
||||
clip: true
|
||||
anchors.fill: parent
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
@ -17,4 +20,14 @@ FluPage {
|
||||
width: parent.width
|
||||
}
|
||||
}
|
||||
|
||||
function resetScroll() {
|
||||
flickable.contentY = 0;
|
||||
}
|
||||
|
||||
StackView.onActivated: {
|
||||
if (autoResetScroll) {
|
||||
resetScroll(); // Call this function to reset the scroll position to the top
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -335,7 +335,7 @@ FluButton {
|
||||
if (hours === "12") {
|
||||
hours24 = (period === control.amText) ? 0 : 12;
|
||||
} else {
|
||||
hours24 = (period === control.pmText) ? hours24 : hours24 + 12;
|
||||
hours24 = (period === control.pmText) ? hours24 + 12 : hours24;
|
||||
}
|
||||
}
|
||||
date.setHours(hours24);
|
||||
|
@ -98,7 +98,7 @@ Item{
|
||||
Component{
|
||||
id:com_lable
|
||||
FluText{
|
||||
wrapMode: Text.WrapAnywhere
|
||||
wrapMode: Text.WordWrap
|
||||
horizontalAlignment: isRight ? Qt.AlignRight : Qt.AlignLeft
|
||||
text: {
|
||||
if(modelData.lable){
|
||||
@ -113,7 +113,7 @@ Item{
|
||||
Component{
|
||||
id:com_text
|
||||
FluText{
|
||||
wrapMode: Text.WrapAnywhere
|
||||
wrapMode: Text.WordWrap
|
||||
horizontalAlignment: isRight ? Qt.AlignRight : Qt.AlignLeft
|
||||
text: modelData.text
|
||||
textFormat: Text.RichText
|
||||
|
@ -175,7 +175,7 @@ Popup{
|
||||
FluText{
|
||||
id: text_desc
|
||||
font: FluTextStyle.Body
|
||||
wrapMode: Text.WrapAnywhere
|
||||
wrapMode: Text.WordWrap
|
||||
maximumLineCount: 4
|
||||
elide: Text.ElideRight
|
||||
text: {
|
||||
|
@ -12,6 +12,11 @@ Window {
|
||||
property bool fixSize: false
|
||||
property Component loadingItem: com_loading
|
||||
property bool fitsAppBarWindows: false
|
||||
property var tintOpacity: FluTheme.dark ? 0.80 : 0.75
|
||||
property int blurRadius: 60
|
||||
property alias effect: frameless.effect
|
||||
readonly property alias effective: frameless.effective
|
||||
readonly property alias availableEffects: frameless.availableEffects
|
||||
property Item appBar: FluAppBar {
|
||||
title: window.title
|
||||
height: 30
|
||||
@ -23,6 +28,15 @@ Window {
|
||||
icon: window.windowIcon
|
||||
}
|
||||
property color backgroundColor: {
|
||||
if(frameless.effective && active){
|
||||
var backcolor
|
||||
if(frameless.effect==="dwm-blur"){
|
||||
backcolor = FluTools.withOpacity(FluTheme.windowActiveBackgroundColor, window.tintOpacity)
|
||||
}else{
|
||||
backcolor = "transparent"
|
||||
}
|
||||
return backcolor
|
||||
}
|
||||
if(active){
|
||||
return FluTheme.windowActiveBackgroundColor
|
||||
}
|
||||
@ -99,6 +113,8 @@ Window {
|
||||
fixSize: window.fixSize
|
||||
topmost: window.stayTop
|
||||
disabled: FluApp.useSystemAppBar
|
||||
isDarkMode: FluTheme.dark
|
||||
useSystemEffect: !FluTheme.blurBehindWindowEnabled
|
||||
Component.onCompleted: {
|
||||
frameless.setHitTestVisible(appBar.layoutMacosButtons)
|
||||
frameless.setHitTestVisible(appBar.layoutStandardbuttons)
|
||||
@ -106,6 +122,11 @@ Window {
|
||||
Component.onDestruction: {
|
||||
frameless.onDestruction()
|
||||
}
|
||||
onEffectiveChanged: {
|
||||
if(effective){
|
||||
FluTheme.blurBehindWindowEnabled = false
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_background
|
||||
@ -161,8 +182,8 @@ Window {
|
||||
FluAcrylic{
|
||||
anchors.fill: parent
|
||||
target: img_back
|
||||
tintOpacity: FluTheme.dark ? 0.80 : 0.75
|
||||
blurRadius: 64
|
||||
tintOpacity: window.tintOpacity
|
||||
blurRadius: window.blurRadius
|
||||
visible: window.active && FluTheme.blurBehindWindowEnabled
|
||||
tintColor: FluTheme.dark ? Qt.rgba(0, 0, 0, 1) : Qt.rgba(1, 1, 1, 1)
|
||||
targetRect: Qt.rect(window.x-window.screen.virtualX,window.y-window.screen.virtualY,window.width,window.height)
|
||||
@ -274,7 +295,7 @@ Window {
|
||||
sourceComponent: window.useSystemAppBar ? undefined : com_app_bar
|
||||
}
|
||||
Item{
|
||||
id:layout_content
|
||||
id: layout_content
|
||||
anchors{
|
||||
top: loader_app_bar.bottom
|
||||
left: parent.left
|
||||
@ -293,7 +314,6 @@ Window {
|
||||
id:info_bar
|
||||
root: layout_container
|
||||
}
|
||||
|
||||
FluLoader{
|
||||
id:loader_border
|
||||
anchors.fill: parent
|
||||
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 473 B |
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 389 B |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 434 B |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 535 B |
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 409 B |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 559 B |
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 416 B |
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 395 B |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 437 B |
Before Width: | Height: | Size: 266 KiB After Width: | Height: | Size: 142 KiB |