Compare commits

..

96 Commits
1.6.0 ... 1.6.3

Author SHA1 Message Date
4f60459166 update 2023-11-30 11:13:01 +08:00
29749a5761 update 2023-11-30 10:59:09 +08:00
1b3344e9f9 update 2023-11-30 01:12:57 +08:00
394d0ab244 remove FluHttp 2023-11-29 21:35:06 +08:00
6a925bdad3 update network 2023-11-29 18:10:56 +08:00
6999067a80 Merge branch 'main' of https://github.com/zhuzichu520/FluentUI 2023-11-29 10:42:09 +08:00
1047fac4d6 update 2023-11-29 10:41:48 +08:00
3b2982a95e Merge pull request #358 from weypro/main
调整亚克力效果的噪点占比
2023-11-29 09:12:38 +08:00
wey
e37d47f629 调整亚克力效果的噪点占比
参考官方figma winui3设计稿,噪点图像占比为2%,不然看起来噪点太明显
2023-11-28 23:02:39 +08:00
d07383ba46 update 2023-11-28 20:09:44 +08:00
ce3da2e92f fix bug #357 2023-11-27 20:43:17 +08:00
2e8be5f133 update 2023-11-27 18:23:36 +08:00
8662eb97aa update 2023-11-27 16:45:37 +08:00
55a77eba4b Merge branch 'main' of https://github.com/zhuzichu520/FluentUI 2023-11-27 15:30:35 +08:00
5dd3320f66 fix bug #356 2023-11-27 15:29:54 +08:00
3b4c327528 update 2023-11-24 22:05:53 +08:00
412842d844 Merge pull request #336 from Pemvin/main
Update FluTour.qml
2023-11-24 21:19:06 +08:00
2242ffc367 update network 2023-11-24 18:04:26 +08:00
d485ec9e3b fix bug #351 2023-11-24 15:41:44 +08:00
05251e085c fix bug #351 2023-11-24 15:36:34 +08:00
78f5dd0a61 update FluNetwork 2023-11-24 15:35:40 +08:00
2f3ed2bd0f update 2023-11-23 19:58:54 +08:00
35d85aa801 update 2023-11-23 18:18:28 +08:00
542ea0a7b9 update 2023-11-21 18:12:11 +08:00
b981ecca7d update FluWindow 2023-11-21 14:28:37 +08:00
a7552e2b5c Update FluTour.qml 2023-11-17 10:06:53 +08:00
637a0f312e Merge branch 'zhuzichu520:main' into main 2023-11-17 09:16:32 +08:00
e3e4592ea4 update macos action 2023-11-16 10:10:50 +08:00
71c238e62b update 2023-11-16 00:22:55 +08:00
77ae88f518 update 2023-11-15 23:54:38 +08:00
2f9090858b update 2023-11-15 17:18:24 +08:00
5d11064011 Update FluTour.qml
Automatic place tour boxes above or below targets
2023-11-09 17:38:07 +08:00
dfb80e70ee fix bug #335 2023-11-08 17:05:09 +08:00
7618fe0f37 update 2023-11-08 13:44:11 +08:00
cbebb51d62 update 2023-11-08 10:30:22 +08:00
f0227c5686 Merge branch 'main' of https://github.com/zhuzichu520/FluentUI 2023-11-07 14:01:51 +08:00
24c8644d79 update 2023-11-07 14:01:28 +08:00
40ce63e1df Merge pull request #330 from kevinlq/main
FluNavigationView 组件增加了 tooltip 提示,交互更友好些。
2023-11-07 10:48:59 +08:00
cc4abbf79f feat:The FluNavigationView component adds a Tooltip prompt to make the interaction more friendly. 2023-11-06 23:25:22 +08:00
35921ed900 update 2023-11-05 17:24:08 +08:00
661529f1f4 update 2023-11-04 22:06:05 +08:00
139c5c455d update 2023-11-04 21:58:21 +08:00
3460b59839 update 2023-11-04 21:46:31 +08:00
bdbd5d295e update 2023-11-04 11:12:54 +08:00
51637fceca update 2023-11-04 10:50:26 +08:00
7f542edba7 update 2023-11-03 13:21:15 +08:00
0b124ec9ee update 2023-11-02 23:07:55 +08:00
fa77ed6163 update 2023-11-02 23:02:08 +08:00
eef46a2dac update 2023-11-02 22:14:00 +08:00
f856fd44c1 update 2023-11-02 20:22:23 +08:00
35bfb8021f update 2023-11-02 17:14:07 +08:00
29012f0b68 update 2023-11-02 16:56:29 +08:00
54b98c8e05 update 2023-11-02 15:33:59 +08:00
20852ac6bf update 2023-11-02 11:34:02 +08:00
636dddaa84 update 2023-11-01 21:06:56 +08:00
50a6103584 update 2023-10-30 14:45:22 +08:00
a693db76c8 update 2023-10-22 12:33:19 +08:00
25e385c06e Merge pull request #321 from kevinlq/main
优化FluComboBox.qml 下拉框显示效果
2023-10-21 22:16:29 +08:00
777459e35d Merge branch 'main' of https://github.com/kevinlq/FluentUI 2023-10-21 22:07:11 +08:00
9bdc6c45cd feat: Fixed the problem that the Flu ComboBox quick drop-down display is empty, and the ListView cancels the rebound effect. 2023-10-21 22:06:25 +08:00
fc618e96c5 update 2023-10-21 22:03:26 +08:00
cac1864d65 update 2023-10-21 11:57:35 +08:00
9846415838 update 2023-10-21 00:26:15 +08:00
840ae7ec2f update 2023-10-21 00:19:47 +08:00
05f51c788e update 2023-10-21 00:02:56 +08:00
19a5883e76 update 2023-10-20 23:52:34 +08:00
da0184f70e update 2023-10-20 22:19:46 +08:00
ea79becd08 update 2023-10-20 22:12:10 +08:00
1e5c70c7b4 update 2023-10-20 21:32:11 +08:00
c6a43c41db update 2023-10-20 21:28:51 +08:00
5f6d66b6ce update 2023-10-20 18:04:58 +08:00
83f94630f1 update 2023-10-19 22:52:36 +08:00
ac63514451 update 2023-10-19 15:25:07 +08:00
4d197d2697 update 2023-10-18 22:45:01 +08:00
b78aaaad48 update 2023-10-18 22:37:01 +08:00
3784a86936 update 2023-10-18 15:18:38 +08:00
0ee0c8c68f update 2023-10-17 23:26:04 +08:00
ec2ddc24eb update 2023-10-17 23:13:57 +08:00
baf5438262 update 2023-10-17 23:04:41 +08:00
b452218e79 update 2023-10-17 23:02:45 +08:00
cb5b9d8541 update 2023-10-17 22:38:04 +08:00
4ec772fff2 Merge branch 'main' of https://github.com/zhuzichu520/FluentUI 2023-10-17 22:18:15 +08:00
8f9c529153 update 2023-10-17 22:18:12 +08:00
483c5f8e09 Merge pull request #316 from imaben/hotfix-pivot-style
optimize style for FluPivot
2023-10-17 22:15:46 +08:00
0402b07dba optimize style for FluPivot 2023-10-17 21:53:36 +08:00
ee071ee451 update 2023-10-17 16:27:44 +08:00
487cbefd82 update 2023-10-17 16:11:09 +08:00
b836b25028 update 2023-10-17 15:17:05 +08:00
0eacc177d0 update 2023-10-17 14:30:43 +08:00
9b5167d92e fix bug #315 2023-10-17 12:26:17 +08:00
3a775a8bb2 update 2023-10-17 10:34:37 +08:00
0030c44a6c fix bug #314 2023-10-17 09:23:23 +08:00
83cd2873c6 Merge pull request #313 from imaben/hotfix-ptr-check
fixed invalid pointer check
2023-10-17 09:12:46 +08:00
f385e34d23 fixed invalid pointer check 2023-10-16 19:24:25 +08:00
fc1b62d4a3 update 2023-10-16 17:31:59 +08:00
9985053f82 update 2023-10-16 13:56:09 +08:00
167 changed files with 3777 additions and 3272 deletions

View File

@ -58,8 +58,8 @@ if (${QMLPLUGIN_LIBTYPE} MATCHES "SHARED")
set(INSTALL_QMLDIR_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_LIST_DIR}/Qt5/${QMLPLUGIN_QMLDIR}/qmldir ${QMLPLUGIN_BINARY_DIR}/qmldir) set(INSTALL_QMLDIR_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_LIST_DIR}/Qt5/${QMLPLUGIN_QMLDIR}/qmldir ${QMLPLUGIN_BINARY_DIR}/qmldir)
set(COPY_QMLTYPES_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_LIST_DIR}/Qt5/${QMLPLUGIN_QMLDIR}/plugins.qmltypes $<TARGET_FILE_DIR:${TARGET}>/${QMLPLUGIN_URI}/plugins.qmltypes) set(COPY_QMLTYPES_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_LIST_DIR}/Qt5/${QMLPLUGIN_QMLDIR}/plugins.qmltypes $<TARGET_FILE_DIR:${TARGET}>/${QMLPLUGIN_URI}/plugins.qmltypes)
set(INSTALL_QMLTYPES_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_LIST_DIR}/Qt5/${QMLPLUGIN_QMLDIR}/plugins.qmltypes ${QMLPLUGIN_BINARY_DIR}/plugins.qmltypes) set(INSTALL_QMLTYPES_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_LIST_DIR}/Qt5/${QMLPLUGIN_QMLDIR}/plugins.qmltypes ${QMLPLUGIN_BINARY_DIR}/plugins.qmltypes)
set(COPY_LIBRARY_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/$<TARGET_FILE_NAME:${TARGET}> $<TARGET_FILE_DIR:${TARGET}>/${QMLPLUGIN_URI}) set(COPY_LIBRARY_COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE_DIR:${TARGET}>/$<TARGET_FILE_NAME:${TARGET}> $<TARGET_FILE_DIR:${TARGET}>/${QMLPLUGIN_URI})
set(INSTALL_LIBRARY_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/$<TARGET_FILE_NAME:${TARGET}> ${QMLPLUGIN_BINARY_DIR}) set(INSTALL_LIBRARY_COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE_DIR:${TARGET}>/$<TARGET_FILE_NAME:${TARGET}> ${QMLPLUGIN_BINARY_DIR})
if(QMLPLUGIN_QMLDIR) if(QMLPLUGIN_QMLDIR)
set(COPY_QMLFILES_COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/Qt5/${QMLPLUGIN_QMLDIR} $<TARGET_FILE_DIR:${TARGET}>/${QMLPLUGIN_URI}) set(COPY_QMLFILES_COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/Qt5/${QMLPLUGIN_QMLDIR} $<TARGET_FILE_DIR:${TARGET}>/${QMLPLUGIN_URI})
else() else()

View File

@ -31,4 +31,4 @@ BEGIN
END END
END END
IDI_ICON1 ICON DISCARDABLE "${CMAKE_SOURCE_DIR}/example/favicon.ico" IDI_ICON1 ICON DISCARDABLE "${FLUENTUI_DIRECTORY}/example/favicon.ico"

View File

@ -21,8 +21,8 @@ jobs:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
matrix: matrix:
os: [macos-12] os: [macos-13]
qt_ver: [6.5.0] qt_ver: [6.6.0]
qt_arch: [clang_64] qt_arch: [clang_64]
env: env:
targetName: example targetName: example
@ -50,17 +50,17 @@ jobs:
cmake --version cmake --version
mkdir build mkdir build
cd build cd build
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=/Users/runner/work/FluentUI/Qt/6.5.0/macos -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -GNinja .. cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=/Users/runner/work/FluentUI/Qt/6.6.0/macos -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -GNinja ..
cmake --build . --target all --config Release --parallel cmake --build . --target all --config Release --parallel
- name: package - name: package
run: | run: |
# 拷贝依赖 # 拷贝依赖
macdeployqt bin/release/${targetName}.app -qmldir=. -verbose=1 -dmg sudo macdeployqt bin/release/${targetName}.app -qmldir=. -dmg
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v2
with: with:
name: ${{ env.targetName }}_${{ matrix.os }}_${{matrix.qt_ver}}.zip name: ${{ env.targetName }}_${{ matrix.os }}_${{matrix.qt_ver}}
path: bin/release/${{ env.targetName }}.app path: bin/release/${{ env.targetName }}.app
- name: uploadRelease - name: uploadRelease

View File

@ -23,7 +23,7 @@ jobs:
strategy: strategy:
matrix: matrix:
os: [ubuntu-20.04] os: [ubuntu-20.04]
qt_ver: [6.5.0] qt_ver: [6.6.0]
qt_arch: [gcc_64] qt_arch: [gcc_64]
env: env:
targetName: example targetName: example
@ -55,7 +55,7 @@ jobs:
cmake --version cmake --version
mkdir build mkdir build
cd build cd build
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=/home/runner/work/FluentUI/Qt/6.5.0/gcc_64 -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Release -GNinja .. cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=/home/runner/work/FluentUI/Qt/6.6.0/gcc_64 -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Release -GNinja ..
cmake --build . --target all --config Release --parallel cmake --build . --target all --config Release --parallel
- name: install QT linux deploy - name: install QT linux deploy

View File

@ -24,7 +24,7 @@ jobs:
os: [windows-2022] os: [windows-2022]
include: include:
- qt_arch: win64_mingw - qt_arch: win64_mingw
qt_ver: 6.5.0 qt_ver: 6.6.0
qt_tools: "tools_mingw,9.0.0-1-202203221220,qt.tools.win64_mingw900" qt_tools: "tools_mingw,9.0.0-1-202203221220,qt.tools.win64_mingw900"
qt_tools_mingw_install: mingw900_64 qt_tools_mingw_install: mingw900_64
env: env:
@ -69,7 +69,7 @@ jobs:
mkdir build mkdir build
cd build cd build
ninja --version ninja --version
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=D:\a\FluentUI\Qt\6.5.0\mingw_64 -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Release -GNinja .. cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=D:\a\FluentUI\Qt\6.6.0\mingw_64 -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Release -GNinja ..
cmake --build . --target all --config Release --parallel cmake --build . --target all --config Release --parallel
- name: package - name: package

View File

@ -23,7 +23,7 @@ jobs:
matrix: matrix:
os: [windows-2019] os: [windows-2019]
include: include:
- qt_ver: 6.5.0 - qt_ver: 6.6.0
qt_arch: win64_msvc2019_64 qt_arch: win64_msvc2019_64
msvc_arch: x64 msvc_arch: x64
qt_arch_install: msvc2019_64 qt_arch_install: msvc2019_64
@ -52,7 +52,7 @@ jobs:
ninja --version ninja --version
mkdir build mkdir build
cd build cd build
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=D:\a\FluentUI\Qt\6.5.0\msvc2019_64 -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl -DCMAKE_BUILD_TYPE=Release -GNinja .. cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=D:\a\FluentUI\Qt\6.6.0\msvc2019_64 -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl -DCMAKE_BUILD_TYPE=Release -GNinja ..
cmake --build . --target all --config Release --parallel cmake --build . --target all --config Release --parallel
echo winSdkDir=%WindowsSdkDir% >> %GITHUB_ENV% echo winSdkDir=%WindowsSdkDir% >> %GITHUB_ENV%
echo winSdkVer=%WindowsSdkVersion% >> %GITHUB_ENV% echo winSdkVer=%WindowsSdkVersion% >> %GITHUB_ENV%

View File

@ -18,9 +18,9 @@ endif()
#设置可执行文件输出目录 #设置可执行文件输出目录
if(CMAKE_BUILD_TYPE STREQUAL "Debug") if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/debug) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY $<1:${FLUENTUI_DIRECTORY}/bin/debug>)
else() else()
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/release) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY $<1:${FLUENTUI_DIRECTORY}/bin/release>)
endif() endif()
#获取文件路径分隔符(解决执行命令的时候有些平台会报错) #获取文件路径分隔符(解决执行命令的时候有些平台会报错)
@ -81,7 +81,7 @@ if(WIN32)
) )
configure_file( configure_file(
${FLUENTUI_DIRECTORY}/.cmake/InstallerScript.iss.in ${FLUENTUI_DIRECTORY}/.cmake/InstallerScript.iss.in
${CMAKE_SOURCE_DIR}/action-cli/InstallerScript.iss ${FLUENTUI_DIRECTORY}/action-cli/InstallerScript.iss
) )
endif() endif()
@ -139,7 +139,7 @@ target_include_directories(example PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src/component ${CMAKE_CURRENT_SOURCE_DIR}/src/component
) )
#如是静态库则需要手动注册插件导入FluentUI.h头文件 #如是静态库则需要手动注册插件导入FluentUI.h头文件
if(FLUENTUI_BUILD_STATIC_LIB) if(FLUENTUI_BUILD_STATIC_LIB)
target_include_directories(example PRIVATE target_include_directories(example PRIVATE
${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/src

View File

@ -143,7 +143,6 @@
<file>qml/page/T_Expander.qml</file> <file>qml/page/T_Expander.qml</file>
<file>qml/page/T_FlipView.qml</file> <file>qml/page/T_FlipView.qml</file>
<file>qml/page/T_Home.qml</file> <file>qml/page/T_Home.qml</file>
<file>qml/page/T_Http.qml</file>
<file>qml/page/T_Image.qml</file> <file>qml/page/T_Image.qml</file>
<file>qml/page/T_InfoBar.qml</file> <file>qml/page/T_InfoBar.qml</file>
<file>qml/page/T_Menu.qml</file> <file>qml/page/T_Menu.qml</file>
@ -189,5 +188,6 @@
<file>qml/page/T_Clip.qml</file> <file>qml/page/T_Clip.qml</file>
<file>qml/page/T_3D.qml</file> <file>qml/page/T_3D.qml</file>
<file>qml/global/Lang.qml</file> <file>qml/global/Lang.qml</file>
<file>qml/page/T_Network.qml</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -4,9 +4,8 @@ import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import FluentUI import FluentUI
Window { Item {
id: app id: app
flags: Qt.SplashScreen
Connections{ Connections{
target: FluTheme target: FluTheme
@ -20,26 +19,17 @@ Window {
function onVsyncChanged(){ function onVsyncChanged(){
SettingsHelper.saveVsync(FluApp.vsync) SettingsHelper.saveVsync(FluApp.vsync)
} }
} function onUseSystemAppBarChanged(){
SettingsHelper.saveUseSystemAppBar(FluApp.useSystemAppBar)
FluHttpInterceptor{
id:interceptor
function onIntercept(request){
if(request.method === "get"){
request.params["method"] = "get"
}
if(request.method === "post"){
request.params["method"] = "post"
}
request.headers["token"] ="yyds"
request.headers["os"] ="pc"
console.debug(JSON.stringify(request))
return request
} }
} }
Component.onCompleted: { Component.onCompleted: {
FluNetwork.setInterceptor(function(param){
param.addHeader("Token","000000000000000000000")
})
FluApp.init(app) FluApp.init(app)
FluApp.useSystemAppBar = SettingsHelper.getUseSystemAppBar()
FluApp.vsync = SettingsHelper.getVsync() FluApp.vsync = SettingsHelper.getVsync()
FluTheme.darkMode = SettingsHelper.getDarkMode() FluTheme.darkMode = SettingsHelper.getDarkMode()
FluTheme.enableAnimation = true FluTheme.enableAnimation = true
@ -54,7 +44,6 @@ Window {
"/pageWindow":"qrc:/example/qml/window/PageWindow.qml" "/pageWindow":"qrc:/example/qml/window/PageWindow.qml"
} }
FluApp.initialRoute = "/" FluApp.initialRoute = "/"
FluApp.httpInterceptor = interceptor
FluApp.run() FluApp.run()
} }
} }

View File

@ -130,7 +130,6 @@ FluExpander{
"FluRadioButtons", "FluRadioButtons",
"FluImage", "FluImage",
"FluSpinBox", "FluSpinBox",
"FluHttp",
"FluWatermark", "FluWatermark",
"FluTour", "FluTour",
"FluQRCode", "FluQRCode",
@ -140,7 +139,8 @@ FluExpander{
"FluStaggeredView", "FluStaggeredView",
"FluProgressButton", "FluProgressButton",
"FluLoadingButton", "FluLoadingButton",
"FluClip" "FluClip",
"FluNetwork"
]; ];
code = code.replace(/\n/g, "<br>"); code = code.replace(/\n/g, "<br>");
code = code.replace(/ /g, "&nbsp;"); code = code.replace(/ /g, "&nbsp;");

View File

@ -6,6 +6,7 @@ import FluentUI
FluObject{ FluObject{
property var navigationView property var navigationView
property var paneItemMenu
id:footer_items id:footer_items
@ -14,7 +15,6 @@ FluObject{
FluPaneItem{ FluPaneItem{
title:Lang.about title:Lang.about
icon:FluentIcons.Contact icon:FluentIcons.Contact
onDropped: { FluApp.navigate("/about") }
onTapListener:function(){ onTapListener:function(){
FluApp.navigate("/about") FluApp.navigate("/about")
} }
@ -22,9 +22,9 @@ FluObject{
FluPaneItem{ FluPaneItem{
title:Lang.settings title:Lang.settings
menuDelegate: paneItemMenu
icon:FluentIcons.Settings icon:FluentIcons.Settings
url:"qrc:/example/qml/page/T_Settings.qml" url:"qrc:/example/qml/page/T_Settings.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ onTap:{
navigationView.push(url) navigationView.push(url)
} }

View File

@ -6,6 +6,7 @@ import FluentUI
FluObject{ FluObject{
property var navigationView property var navigationView
property var paneItemMenu
function rename(item, newName){ function rename(item, newName){
if(newName && newName.trim().length>0){ if(newName && newName.trim().length>0){
@ -17,32 +18,18 @@ FluObject{
id:item_home id:item_home
count: 9 count: 9
title:Lang.home title:Lang.home
menuDelegate: paneItemMenu
infoBadge:FluBadge{ infoBadge:FluBadge{
count: item_home.count count: item_home.count
} }
icon:FluentIcons.Home icon:FluentIcons.Home
url:"qrc:/example/qml/page/T_Home.qml" url:"qrc:/example/qml/page/T_Home.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ onTap:{
if(navigationView.getCurrentUrl()){ if(navigationView.getCurrentUrl()){
item_home.count = 0 item_home.count = 0
} }
navigationView.push(url) navigationView.push(url)
} }
editDelegate: FluTextBox{
text:item_home.title
}
menuDelegate: FluMenu{
id:nav_item_right_menu
width: 120
FluMenuItem{
text: "重命名"
visible: true
onClicked: {
item_home.showEdit = true
}
}
}
} }
FluPaneItemExpander{ FluPaneItemExpander{
@ -55,18 +42,6 @@ FluObject{
id:item_expander_basic_input id:item_expander_basic_input
title:Lang.basic_input title:Lang.basic_input
icon:FluentIcons.CheckboxComposite icon:FluentIcons.CheckboxComposite
editDelegate: FluTextBox{
text:item_expander_basic_input.title
}
menuDelegate: FluMenu{
FluMenuItem{
text: "重命名"
visible: true
onClicked: {
item_expander_basic_input.showEdit = true
}
}
}
FluPaneItem{ FluPaneItem{
id:item_buttons id:item_buttons
count: 99 count: 99
@ -74,11 +49,11 @@ FluObject{
count: item_buttons.count count: item_buttons.count
} }
title:"Buttons" title:"Buttons"
menuDelegate: paneItemMenu
image:"qrc:/example/res/image/control/Button.png" image:"qrc:/example/res/image/control/Button.png"
recentlyUpdated:true recentlyUpdated:true
desc:"A control that responds to user input and raisesa Click event." desc:"A control that responds to user input and raisesa Click event."
url:"qrc:/example/qml/page/T_Buttons.qml" url:"qrc:/example/qml/page/T_Buttons.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ onTap:{
item_buttons.count = 0 item_buttons.count = 0
navigationView.push(url) navigationView.push(url)
@ -87,13 +62,13 @@ FluObject{
FluPaneItem{ FluPaneItem{
id:item_text id:item_text
title:"Text" title:"Text"
menuDelegate: paneItemMenu
count: 5 count: 5
infoBadge:FluBadge{ infoBadge:FluBadge{
count: item_text.count count: item_text.count
color: Qt.rgba(82/255,196/255,26/255,1) color: Qt.rgba(82/255,196/255,26/255,1)
} }
url:"qrc:/example/qml/page/T_Text.qml" url:"qrc:/example/qml/page/T_Text.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ onTap:{
item_text.count = 0 item_text.count = 0
navigationView.push(url) navigationView.push(url)
@ -101,38 +76,38 @@ FluObject{
} }
FluPaneItem{ FluPaneItem{
title:"Image" title:"Image"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Image.qml" url:"qrc:/example/qml/page/T_Image.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Slider" title:"Slider"
menuDelegate: paneItemMenu
image:"qrc:/example/res/image/control/Slider.png" image:"qrc:/example/res/image/control/Slider.png"
recentlyUpdated:true recentlyUpdated:true
desc:"A control that lets the user select from a rangeof values by moving a Thumb control along atrack." desc:"A control that lets the user select from a rangeof values by moving a Thumb control along atrack."
url:"qrc:/example/qml/page/T_Slider.qml" url:"qrc:/example/qml/page/T_Slider.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"CheckBox" title:"CheckBox"
menuDelegate: paneItemMenu
image:"qrc:/example/res/image/control/Checkbox.png" image:"qrc:/example/res/image/control/Checkbox.png"
recentlyUpdated:true recentlyUpdated:true
desc:"A control that a user can select or clear." desc:"A control that a user can select or clear."
url:"qrc:/example/qml/page/T_CheckBox.qml" url:"qrc:/example/qml/page/T_CheckBox.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"RadioButton" title:"RadioButton"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_RadioButton.qml" url:"qrc:/example/qml/page/T_RadioButton.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"ToggleSwitch" title:"ToggleSwitch"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_ToggleSwitch.qml" url:"qrc:/example/qml/page/T_ToggleSwitch.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
@ -147,32 +122,32 @@ FluObject{
icon:FluentIcons.GridView icon:FluentIcons.GridView
FluPaneItem{ FluPaneItem{
title:"TextBox" title:"TextBox"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_TextBox.qml" url:"qrc:/example/qml/page/T_TextBox.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"TimePicker" title:"TimePicker"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_TimePicker.qml" url:"qrc:/example/qml/page/T_TimePicker.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"DatePicker" title:"DatePicker"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_DatePicker.qml" url:"qrc:/example/qml/page/T_DatePicker.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"CalendarPicker" title:"CalendarPicker"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_CalendarPicker.qml" url:"qrc:/example/qml/page/T_CalendarPicker.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"ColorPicker" title:"ColorPicker"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_ColorPicker.qml" url:"qrc:/example/qml/page/T_ColorPicker.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
} }
@ -182,71 +157,71 @@ FluObject{
icon:FluentIcons.SurfaceHub icon:FluentIcons.SurfaceHub
FluPaneItem{ FluPaneItem{
title:"InfoBar" title:"InfoBar"
menuDelegate: paneItemMenu
image:"qrc:/example/res/image/control/InfoBar.png" image:"qrc:/example/res/image/control/InfoBar.png"
recentlyUpdated:true recentlyUpdated:true
desc:"An inline message to display app-wide statuschange information." desc:"An inline message to display app-wide statuschange information."
url:"qrc:/example/qml/page/T_InfoBar.qml" url:"qrc:/example/qml/page/T_InfoBar.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Progress" title:"Progress"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Progress.qml" url:"qrc:/example/qml/page/T_Progress.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"RatingControl" title:"RatingControl"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_RatingControl.qml" url:"qrc:/example/qml/page/T_RatingControl.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Badge" title:"Badge"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Badge.qml" url:"qrc:/example/qml/page/T_Badge.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Rectangle" title:"Rectangle"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Rectangle.qml" url:"qrc:/example/qml/page/T_Rectangle.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Clip" title:"Clip"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Clip.qml" url:"qrc:/example/qml/page/T_Clip.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"StatusView" title:"StatusView"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_StatusView.qml" url:"qrc:/example/qml/page/T_StatusView.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Carousel" title:"Carousel"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Carousel.qml" url:"qrc:/example/qml/page/T_Carousel.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Expander" title:"Expander"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Expander.qml" url:"qrc:/example/qml/page/T_Expander.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"StaggeredView" title:"StaggeredView"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_StaggeredView.qml" url:"qrc:/example/qml/page/T_StaggeredView.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Watermark" title:"Watermark"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Watermark.qml" url:"qrc:/example/qml/page/T_Watermark.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
} }
@ -256,20 +231,20 @@ FluObject{
icon:FluentIcons.ButtonMenu icon:FluentIcons.ButtonMenu
FluPaneItem{ FluPaneItem{
title:"Dialog" title:"Dialog"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Dialog.qml" url:"qrc:/example/qml/page/T_Dialog.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
id:item_combobox id:item_combobox
title:"ComboBox" title:"ComboBox"
menuDelegate: paneItemMenu
count: 9 count: 9
infoBadge:FluBadge{ infoBadge:FluBadge{
count: item_combobox.count count: item_combobox.count
color: Qt.rgba(250/255,173/255,20/255,1) color: Qt.rgba(250/255,173/255,20/255,1)
} }
url:"qrc:/example/qml/page/T_ComboBox.qml" url:"qrc:/example/qml/page/T_ComboBox.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ onTap:{
item_combobox.count = 0 item_combobox.count = 0
navigationView.push("qrc:/example/qml/page/T_ComboBox.qml") navigationView.push("qrc:/example/qml/page/T_ComboBox.qml")
@ -277,14 +252,14 @@ FluObject{
} }
FluPaneItem{ FluPaneItem{
title:"Tooltip" title:"Tooltip"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Tooltip.qml" url:"qrc:/example/qml/page/T_Tooltip.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Menu" title:"Menu"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Menu.qml" url:"qrc:/example/qml/page/T_Menu.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
} }
@ -294,66 +269,66 @@ FluObject{
icon:FluentIcons.AllApps icon:FluentIcons.AllApps
FluPaneItem{ FluPaneItem{
title:"Pivot" title:"Pivot"
menuDelegate: paneItemMenu
image:"qrc:/example/res/image/control/Pivot.png" image:"qrc:/example/res/image/control/Pivot.png"
recentlyAdded:true recentlyAdded:true
order:3 order:3
desc:"Presents information from different sources in atabbed view." desc:"Presents information from different sources in atabbed view."
url:"qrc:/example/qml/page/T_Pivot.qml" url:"qrc:/example/qml/page/T_Pivot.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"BreadcrumbBar" title:"BreadcrumbBar"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_BreadcrumbBar.qml" url:"qrc:/example/qml/page/T_BreadcrumbBar.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"TabView" title:"TabView"
menuDelegate: paneItemMenu
image:"qrc:/example/res/image/control/TabView.png" image:"qrc:/example/res/image/control/TabView.png"
recentlyAdded:true recentlyAdded:true
order:1 order:1
desc:"A control that displays a collection of tabs thatcan be used to display several documents." desc:"A control that displays a collection of tabs thatcan be used to display several documents."
url:"qrc:/example/qml/page/T_TabView.qml" url:"qrc:/example/qml/page/T_TabView.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"TreeView" title:"TreeView"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_TreeView.qml" url:"qrc:/example/qml/page/T_TreeView.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"TableView" title:"TableView"
menuDelegate: paneItemMenu
image:"qrc:/example/res/image/control/DataGrid.png" image:"qrc:/example/res/image/control/DataGrid.png"
recentlyAdded:true recentlyAdded:true
order:4 order:4
desc:"The TableView control provides a flexible way to display a collection of data in rows and columns" desc:"The TableView control provides a flexible way to display a collection of data in rows and columns"
url:"qrc:/example/qml/page/T_TableView.qml" url:"qrc:/example/qml/page/T_TableView.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Pagination" title:"Pagination"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Pagination.qml" url:"qrc:/example/qml/page/T_Pagination.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"MultiWindow" title:"MultiWindow"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_MultiWindow.qml" url:"qrc:/example/qml/page/T_MultiWindow.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"FlipView" title:"FlipView"
menuDelegate: paneItemMenu
image:"qrc:/example/res/image/control/FlipView.png" image:"qrc:/example/res/image/control/FlipView.png"
recentlyAdded:true recentlyAdded:true
order:2 order:2
desc:"Presents a collection of items that the user canflip through, one item at a time." desc:"Presents a collection of items that the user canflip through, one item at a time."
url:"qrc:/example/qml/page/T_FlipView.qml" url:"qrc:/example/qml/page/T_FlipView.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
} }
@ -363,26 +338,26 @@ FluObject{
icon:FluentIcons.Brightness icon:FluentIcons.Brightness
FluPaneItem{ FluPaneItem{
title:"Acrylic" title:"Acrylic"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Acrylic.qml" url:"qrc:/example/qml/page/T_Acrylic.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Theme" title:"Theme"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Theme.qml" url:"qrc:/example/qml/page/T_Theme.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Typography" title:"Typography"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Typography.qml" url:"qrc:/example/qml/page/T_Typography.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Awesome" title:"Awesome"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Awesome.qml" url:"qrc:/example/qml/page/T_Awesome.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
} }
@ -397,56 +372,56 @@ FluObject{
icon:FluentIcons.Shop icon:FluentIcons.Shop
FluPaneItem{ FluPaneItem{
title:"QRCode" title:"QRCode"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_QRCode.qml" url:"qrc:/example/qml/page/T_QRCode.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Tour" title:"Tour"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Tour.qml" url:"qrc:/example/qml/page/T_Tour.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Timeline" title:"Timeline"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Timeline.qml" url:"qrc:/example/qml/page/T_Timeline.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Screenshot(Todo)" title:"Screenshot(Todo)"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Screenshot.qml" url:"qrc:/example/qml/page/T_Screenshot.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Captcha" title:"Captcha"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Captcha.qml" url:"qrc:/example/qml/page/T_Captcha.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Chart" title:"Chart"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Chart.qml" url:"qrc:/example/qml/page/T_Chart.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Http" title:"Network"
url:"qrc:/example/qml/page/T_Http.qml" menuDelegate: paneItemMenu
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) } url:"qrc:/example/qml/page/T_Network.qml"
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
id:item_other id:item_other
title:"RemoteLoader" title:"RemoteLoader"
menuDelegate: paneItemMenu
count: 99 count: 99
infoBadge:FluBadge{ infoBadge:FluBadge{
count: item_other.count count: item_other.count
color: Qt.rgba(82/255,196/255,26/255,1) color: Qt.rgba(82/255,196/255,26/255,1)
} }
url:"qrc:/example/qml/page/T_RemoteLoader.qml" url:"qrc:/example/qml/page/T_RemoteLoader.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ onTap:{
item_other.count = 0 item_other.count = 0
navigationView.push("qrc:/example/qml/page/T_RemoteLoader.qml") navigationView.push("qrc:/example/qml/page/T_RemoteLoader.qml")
@ -457,12 +432,11 @@ FluObject{
onTapListener:function(){ onTapListener:function(){
FluApp.navigate("/hotload") FluApp.navigate("/hotload")
} }
onDropped:{ FluApp.navigate("/hotload") }
} }
FluPaneItem{ FluPaneItem{
title:"3D" title:"3D"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_3D.qml" url:"qrc:/example/qml/page/T_3D.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
} }

View File

@ -43,6 +43,7 @@ FluScrollablePage{
FluTextBox{ FluTextBox{
id:text_box id:text_box
placeholderText: "请输入验证码" placeholderText: "请输入验证码"
Layout.preferredWidth: 240
} }
FluButton{ FluButton{
text:"verify" text:"verify"

View File

@ -77,7 +77,7 @@ FluScrollablePage{
Rectangle{ Rectangle{
anchors.fill: parent anchors.fill: parent
radius: 5 radius: 5
color:FluTheme.dark ? Qt.rgba(1,1,1,0.03) : Qt.rgba(0,0,0,0.03) color:FluTheme.itemHoverColor
visible: item_mouse.containsMouse visible: item_mouse.containsMouse
} }
Rectangle{ Rectangle{
@ -172,17 +172,10 @@ FluScrollablePage{
anchors.fill: parent anchors.fill: parent
radius: 8 radius: 8
color:{ color:{
if(FluTheme.dark){ if(item_mouse.containsMouse){
if(item_mouse.containsMouse){ return FluTheme.itemHoverColor
return Qt.rgba(1,1,1,0.03)
}
return Qt.rgba(0,0,0,0)
}else{
if(item_mouse.containsMouse){
return Qt.rgba(0,0,0,0.03)
}
return Qt.rgba(0,0,0,0)
} }
return FluTheme.itemNormalColor
} }
} }
Image{ Image{
@ -227,7 +220,7 @@ FluScrollablePage{
height: 12 height: 12
width: 12 width: 12
radius: 6 radius: 6
color: FluTheme.primaryColor.dark color: FluTheme.primaryColor
anchors{ anchors{
right: parent.right right: parent.right
top: parent.top top: parent.top

View File

@ -1,405 +0,0 @@
import QtQuick
import Qt.labs.platform
import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import QtQuick.Dialogs
import FluentUI
import "qrc:///example/qml/component"
FluContentPage{
title:"Http"
property string cacheDirPath: StandardPaths.writableLocation(StandardPaths.AppLocalDataLocation) + "/cache/http"
property bool isDownCompleted: false
FluHttp{
id:http
cacheDir:cacheDirPath
}
FluHttp{
id:http_breakpoint_download
cacheDir:cacheDirPath
breakPointDownload: true
}
FluHttp{
id:http_cache_ifnonecacherequest
cacheMode:FluHttpType.IfNoneCacheRequest
cacheDir:cacheDirPath
}
FluHttp{
id:http_cache_requestfailedreadcache
cacheMode:FluHttpType.RequestFailedReadCache
cacheDir:cacheDirPath
}
FluHttp{
id:http_cache_firstcachethenrequest
cacheMode:FluHttpType.FirstCacheThenRequest
cacheDir:cacheDirPath
}
HttpCallable{
id:callable
onStart: {
showLoading()
}
onFinish: {
hideLoading()
}
onError:
(status,errorString,result)=>{
console.debug(status+";"+errorString+";"+result)
}
onSuccess:
(result)=>{
text_info.text = result
}
onCache:
(result)=>{
text_info.text = result
}
}
Flickable{
id:layout_flick
width: 200
clip: true
anchors{
top: parent.top
topMargin: 20
bottom: parent.bottom
left: parent.left
}
ScrollBar.vertical: FluScrollBar {}
contentHeight:layout_column.height
Column{
spacing: 2
id:layout_column
width: parent.width
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Get请求"
onClicked: {
var request = http.newRequest("https://httpbingo.org/get")
http.get(request,callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Post表单请求"
onClicked: {
var request = http.newRequest("https://httpbingo.org/post")
var params = {}
params.custname = "朱子楚"
params.custtel = "1234567890"
params.custemail = "zhuzichu520@gmail.com"
request.params = params
var headers = {}
headers.test = "123456789456465321354"
request.headers = headers
http.post(request,callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Post Json请求"
onClicked: {
var request = http.newRequest("https://httpbingo.org/post")
var params = {}
params.custname = "朱子楚"
params.custtel = "1234567890"
params.custemail = "zhuzichu520@gmail.com"
request.params = params
http.postJson(request,callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Post String请求"
onClicked: {
var request = http.newRequest("https://httpbingo.org/post")
request.params = "我命由我不由天"
http.postString(request,callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Delete请求"
onClicked: {
var request = http.newRequest("https://httpbingo.org/delete")
http.deleteResource(request,callable)
}
}
FluProgressButton{
id:btn_download
implicitWidth: parent.width
implicitHeight: 36
text: "下载文件"
onClicked: {
folder_dialog.open()
}
}
FluProgressButton{
property bool downloading: false
id:btn_breakpoint_download
implicitWidth: parent.width
implicitHeight: 36
text: {
if(downloading){
return "暂停下载"
}
if(progress === 0){
return "断点下载文件"
}else if(progress === 1){
return "打开文件"
}else{
return "继续下载"
}
}
HttpRequest{
id:request_breakpoint_download
url: "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"
downloadSavePath: FluTools.getApplicationDirPath()+ "/download/big_buck_bunny.mp4"
}
HttpCallable{
id:callable_breakpoint_download
onStart: {
btn_breakpoint_download.downloading = true
}
onFinish: {
btn_breakpoint_download.downloading = false
}
onError:
(status,errorString,result)=>{
console.debug(status+";"+errorString+";"+result)
}
onSuccess:
(result)=>{
if(!isDownCompleted){
tour.open()
isDownCompleted = true
}
showSuccess(result)
}
onDownloadProgress:
(recv,total)=>{
btn_breakpoint_download.progress = recv/total
}
}
Component.onCompleted: {
progress = http_breakpoint_download.getBreakPointProgress(request_breakpoint_download)
}
onClicked: {
if(downloading){
http_breakpoint_download.cancel()
return
}
if(progress === 1){
FluTools.showFileInFolder(request_breakpoint_download.downloadSavePath)
}else{
http_breakpoint_download.download(request_breakpoint_download,callable_breakpoint_download)
}
}
FluMenu{
id:menu_breakpoint_download
width: 120
FluMenuItem{
text: "删除文件"
onClicked: {
if(FluTools.removeFile(request_breakpoint_download.downloadSavePath)){
btn_breakpoint_download.progress = 0
}
}
}
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton
onClicked: {
if(btn_breakpoint_download.progress === 1){
menu_breakpoint_download.popup()
}
}
}
}
FluProgressButton{
id:btn_upload
implicitWidth: parent.width
implicitHeight: 36
text: "文件上传"
onClicked: {
file_dialog.open()
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "FirstCacheThenRequest缓存"
onClicked: {
var request = http.newRequest("https://httpbingo.org/post")
request.params = {cacheMode:"FirstCacheThenRequest"}
http_cache_firstcachethenrequest.post(request,callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "RequestFailedReadCache缓存"
onClicked: {
var request = http.newRequest("https://httpbingo.org/post")
request.params = {cacheMode:"RequestFailedReadCache"}
http_cache_requestfailedreadcache.post(request,callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "IfNoneCacheRequest缓存"
onClicked: {
var request = http.newRequest("https://httpbingo.org/post")
request.params = {cacheMode:"IfNoneCacheRequest"}
http_cache_ifnonecacherequest.post(request,callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "打开缓存路径"
onClicked: {
Qt.openUrlExternally(cacheDirPath)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "删除缓存"
onClicked: {
console.debug(FluTools.removeDir(cacheDirPath))
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "清空右边数据"
onClicked: {
text_info.text = ""
}
}
}
}
FluTour{
id:tour
steps:[
{title:"友情提示",description: "下载已完成,左击这里可以打开文件所在路径,右击可以弹出菜单删除文件!",target:()=>btn_breakpoint_download}
]
}
HttpCallable{
id:callable_upload
onStart: {
btn_upload.disabled = true
}
onFinish: {
btn_upload.disabled = false
}
onError:
(status,errorString,result)=>{
btn_upload.progress = 0
text_info.text = result
console.debug(result)
}
onSuccess:
(result)=>{
text_info.text = result
}
onUploadProgress:
(sent,total)=>{
btn_upload.progress = sent/total
}
}
FileDialog {
id: file_dialog
onAccepted: {
var request = http.newRequest("https://httpbingo.org/post")
var params = {}
for(var i=0;i<selectedFiles.length;i++){
var fileUrl = selectedFiles[i]
var fileName = FluTools.getFileNameByUrl(fileUrl)
var filePath = FluTools.toLocalPath(fileUrl)
params[fileName] = filePath
}
request.params = params
http.upload(request,callable_upload)
}
}
HttpCallable{
id:callable_download
onStart: {
btn_download.progress = 0
btn_download.disabled = true
}
onFinish: {
btn_download.disabled = false
}
onError:
(status,errorString,result)=>{
btn_download.progress = 0
showError(errorString)
console.debug(status+";"+errorString+";"+result)
}
onSuccess:
(result)=>{
showSuccess(result)
}
onDownloadProgress:
(recv,total)=>{
btn_download.progress = recv/total
}
}
FolderDialog {
id: folder_dialog
currentFolder: StandardPaths.standardLocations(StandardPaths.DownloadLocation)[0]
onAccepted: {
var request = http.newRequest("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
request.downloadSavePath = FluTools.toLocalPath(currentFolder)+ "/big_buck_bunny.mp4"
http.download(request,callable_download)
}
}
FluArea{
anchors{
top: layout_flick.top
bottom: layout_flick.bottom
left: layout_flick.right
right: parent.right
leftMargin: 8
}
Flickable{
clip: true
id:scrollview
boundsBehavior:Flickable.StopAtBounds
width: parent.width
height: parent.height
contentWidth: width
contentHeight: text_info.height
ScrollBar.vertical: FluScrollBar {}
FluText{
id:text_info
width: scrollview.width
wrapMode: Text.WrapAnywhere
padding: 14
}
}
}
}

View File

@ -0,0 +1,531 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import FluentUI
import Qt.labs.platform
import "qrc:///example/qml/component"
FluContentPage{
id:root
title:"Network"
FluNetworkCallable{
id:callable
onStart: {
showLoading()
}
onFinish: {
hideLoading()
}
onError:
(status,errorString,result)=>{
console.debug(status+";"+errorString+";"+result)
}
onCache:
(result)=>{
text_info.text = result
}
onSuccess:
(result)=>{
text_info.text = result
}
}
Flickable{
id:layout_flick
width: 200
clip: true
anchors{
top: parent.top
topMargin: 20
bottom: parent.bottom
left: parent.left
}
boundsBehavior: Flickable.StopAtBounds
ScrollBar.vertical: FluScrollBar {}
contentHeight:layout_column.height
Column{
spacing: 2
id:layout_column
width: parent.width
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Get"
onClicked: {
text_info.text = ""
FluNetwork.get("https://httpbingo.org/get")
.addQuery("name","孙悟空")
.addQuery("age",500)
.addQuery("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Post Body"
onClicked: {
text_info.text = ""
FluNetwork.postBody("https://httpbingo.org/post")
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Post Form"
onClicked: {
text_info.text = ""
FluNetwork.postForm("https://httpbingo.org/post")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Post JSON"
onClicked: {
text_info.text = ""
FluNetwork.postJson("https://httpbingo.org/post")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Post JSON Array"
onClicked: {
text_info.text = ""
FluNetwork.postJsonArray("https://httpbingo.org/post")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Put Body"
onClicked: {
text_info.text = ""
FluNetwork.putBody("https://httpbingo.org/put")
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Put Form"
onClicked: {
text_info.text = ""
FluNetwork.putForm("https://httpbingo.org/put")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Put JSON"
onClicked: {
text_info.text = ""
FluNetwork.putJson("https://httpbingo.org/put")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Put JSON Array"
onClicked: {
text_info.text = ""
FluNetwork.putJsonArray("https://httpbingo.org/put")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Patch Body"
onClicked: {
text_info.text = ""
FluNetwork.patchBody("https://httpbingo.org/patch")
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Patch Form"
onClicked: {
text_info.text = ""
FluNetwork.patchForm("https://httpbingo.org/patch")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Patch JSON"
onClicked: {
text_info.text = ""
FluNetwork.patchJson("https://httpbingo.org/patch")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Patch JSON Array"
onClicked: {
text_info.text = ""
FluNetwork.patchJsonArray("https://httpbingo.org/patch")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Delete Body"
onClicked: {
text_info.text = ""
FluNetwork.deleteBody("https://httpbingo.org/delete")
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Delete Form"
onClicked: {
text_info.text = ""
FluNetwork.deleteForm("https://httpbingo.org/delete")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Delete JSON"
onClicked: {
text_info.text = ""
FluNetwork.deleteJson("https://httpbingo.org/delete")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Delete JSON Array"
onClicked: {
text_info.text = ""
FluNetwork.deleteJsonArray("https://httpbingo.org/delete")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Custom Header"
onClicked: {
text_info.text = ""
FluNetwork.postJson("https://httpbingo.org/post")
.addHeader("os","PC")
.addHeader("version","1.0.0")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "RequestFailedReadCache"
onClicked: {
text_info.text = ""
FluNetwork.postJson("https://httpbingo.org/post")
.setCacheMode(FluNetworkType.RequestFailedReadCache)
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.add("cacheMode","RequestFailedReadCache")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "IfNoneCacheRequest"
onClicked: {
text_info.text = ""
FluNetwork.postJson("https://httpbingo.org/post")
.setCacheMode(FluNetworkType.IfNoneCacheRequest)
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.add("cacheMode","IfNoneCacheRequest")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "FirstCacheThenRequest"
onClicked: {
text_info.text = ""
FluNetwork.postJson("https://httpbingo.org/post")
.setCacheMode(FluNetworkType.FirstCacheThenRequest)
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.add("cacheMode","FirstCacheThenRequest")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Timeout And Retry"
onClicked: {
text_info.text = ""
FluNetwork.postJson("https://httpbingo.org/post")
.setTimeout(5000)
.setRetry(3)
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.add("timeout","5000")
.add("retry","3")
.bind(root)
.go(callable)
}
}
FluProgressButton{
id:btn_upload
implicitWidth: parent.width
implicitHeight: 36
text: "Upload File"
onClicked: {
file_dialog.open()
}
}
FluProgressButton{
id:btn_download
implicitWidth: parent.width
implicitHeight: 36
text: "Download File"
onClicked: {
folder_dialog.showDialog(function(path){
FluNetwork.get("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
.toDownload(path)
.bind(root)
.go(callable_download_file)
})
}
}
FluProgressButton{
id:btn_download_breakpoint
implicitWidth: parent.width
implicitHeight: 36
text: "Breakpoint Download File"
onClicked: {
folder_dialog.showDialog(function(path){
FluNetwork.get("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
.toDownload(path,true)
.bind(root)
.go(callable_breakpoint_download_file)
})
}
}
}
}
FluNetworkCallable{
id:callable_upload_file
onStart: {
btn_upload.disabled = true
}
onFinish: {
btn_upload.disabled = false
}
onError:
(status,errorString,result)=>{
btn_upload.progress = 0
text_info.text = result
console.debug(status+";"+errorString+";"+result)
}
onSuccess:
(result)=>{
text_info.text = result
}
onUploadProgress:
(sent,total)=>{
btn_upload.progress = sent/total
}
}
FluNetworkCallable{
id:callable_download_file
onStart: {
btn_download.progress = 0
btn_download.disabled = true
}
onFinish: {
btn_download.disabled = false
}
onError:
(status,errorString,result)=>{
btn_download.progress = 0
showError(errorString)
console.debug(status+";"+errorString+";"+result)
}
onSuccess:
(result)=>{
showSuccess(result)
}
onDownloadProgress:
(recv,total)=>{
btn_download.progress = recv/total
}
}
FluNetworkCallable{
id:callable_breakpoint_download_file
onStart: {
btn_download_breakpoint.progress = 0
btn_download_breakpoint.disabled = true
}
onFinish: {
btn_download_breakpoint.disabled = false
}
onError:
(status,errorString,result)=>{
btn_download_breakpoint.progress = 0
showError(errorString)
console.debug(status+";"+errorString+";"+result)
}
onSuccess:
(result)=>{
showSuccess(result)
}
onDownloadProgress:
(recv,total)=>{
btn_download_breakpoint.progress = recv/total
}
}
FileDialog {
id: file_dialog
onAccepted: {
FluNetwork.postForm("https://httpbingo.org/post")
.setRetry(1)//只请求一次
.add("accessToken","12345678")
.addFile("file",FluTools.toLocalPath(file_dialog.currentFile))
.bind(root)
.go(callable_upload_file)
}
}
FileDialog {
property var onSelectListener
id: folder_dialog
folder: StandardPaths.standardLocations(StandardPaths.DownloadLocation)[0]
currentFile: StandardPaths.standardLocations(StandardPaths.DownloadLocation)[0]+"/big_buck_bunny.mp4"
fileMode: FileDialog.SaveFile
onAccepted: {
folder_dialog.onSelectListener(FluTools.toLocalPath(folder_dialog.currentFile))
}
function showDialog(listener){
folder_dialog.onSelectListener = listener
folder_dialog.open()
}
}
FluArea{
anchors{
top: layout_flick.top
bottom: layout_flick.bottom
left: layout_flick.right
right: parent.right
leftMargin: 8
}
Flickable{
clip: true
id:scrollview
boundsBehavior:Flickable.StopAtBounds
width: parent.width
height: parent.height
contentWidth: width
contentHeight: text_info.height
ScrollBar.vertical: FluScrollBar {}
FluText{
id:text_info
width: scrollview.width
wrapMode: Text.WrapAnywhere
padding: 14
}
}
}
}

View File

@ -31,6 +31,7 @@ FluScrollablePage{
FluTextBox{ FluTextBox{
id:text_box id:text_box
text:"会磨刀的小猪" text:"会磨刀的小猪"
Layout.preferredWidth: 240
} }
} }

View File

@ -35,7 +35,7 @@ FluScrollablePage{
color: FluTheme.dark ? FluColors.Black : FluColors.White color: FluTheme.dark ? FluColors.Black : FluColors.White
FluShadow{ FluShadow{
radius: 4 radius: 4
color: FluTheme.primaryColor.dark color: FluTheme.primaryColor
} }
Image{ Image{
id:image id:image

View File

@ -72,6 +72,36 @@ FluScrollablePage{
} }
} }
FluArea{
Layout.fillWidth: true
Layout.topMargin: 20
height: 50
paddings: 10
FluCheckBox{
text:"Use System AppBar"
checked: FluApp.useSystemAppBar
anchors.verticalCenter: parent.verticalCenter
onClicked: {
FluApp.useSystemAppBar = !FluApp.useSystemAppBar
dialog_restart.open()
}
}
}
FluArea{
Layout.fillWidth: true
Layout.topMargin: 20
height: 50
paddings: 10
FluCheckBox{
text:"fitsAppBarWindows"
checked: window.fitsAppBarWindows
anchors.verticalCenter: parent.verticalCenter
onClicked: {
window.fitsAppBarWindows = !window.fitsAppBarWindows
}
}
}
FluArea{ FluArea{
Layout.fillWidth: true Layout.fillWidth: true
@ -199,5 +229,4 @@ FluScrollablePage{
} }
} }
} }
} }

View File

@ -66,7 +66,7 @@ FluScrollablePage{
} }
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
color:FluTheme.primaryColor.dark color:FluTheme.primaryColor
} }
} }
} }
@ -78,7 +78,7 @@ FluScrollablePage{
statusMode: FluStatusViewType.Loading statusMode: FluStatusViewType.Loading
Rectangle{ Rectangle{
anchors.fill: parent anchors.fill: parent
color:FluTheme.primaryColor.dark color:FluTheme.primaryColor
} }
}' }'
} }

View File

@ -181,7 +181,7 @@ FluContentPage{
iconSource: FluentIcons.ChevronUp iconSource: FluentIcons.ChevronUp
iconColor: { iconColor: {
if(1 === root.sortType){ if(1 === root.sortType){
return FluTheme.primaryColor.dark return FluTheme.primaryColor
} }
return FluTheme.dark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1) return FluTheme.dark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1)
} }
@ -202,7 +202,7 @@ FluContentPage{
iconSource: FluentIcons.ChevronDown iconSource: FluentIcons.ChevronDown
iconColor: { iconColor: {
if(2 === root.sortType){ if(2 === root.sortType){
return FluTheme.primaryColor.dark return FluTheme.primaryColor
} }
return FluTheme.dark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1) return FluTheme.dark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1)
} }

View File

@ -32,7 +32,7 @@ FluScrollablePage{
anchors.centerIn: parent anchors.centerIn: parent
iconSource: FluentIcons.AcceptMedium iconSource: FluentIcons.AcceptMedium
iconSize: 15 iconSize: 15
visible: modelData === FluTheme.primaryColor visible: modelData === FluTheme.themeColor
color: FluTheme.dark ? Qt.rgba(0,0,0,1) : Qt.rgba(1,1,1,1) color: FluTheme.dark ? Qt.rgba(0,0,0,1) : Qt.rgba(1,1,1,1)
} }
MouseArea{ MouseArea{
@ -40,7 +40,7 @@ FluScrollablePage{
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
onClicked: { onClicked: {
FluTheme.primaryColor = modelData FluTheme.themeColor = modelData
} }
} }
} }
@ -88,7 +88,7 @@ FluScrollablePage{
CodeExpander{ CodeExpander{
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: -1 Layout.topMargin: -1
code:'FluTheme.primaryColor = FluColors.Orange code:'FluTheme.themeColor = FluColors.Orange
FluTheme.dark = true FluTheme.dark = true

View File

@ -110,6 +110,7 @@ FluScrollablePage{
FluTextBox{ FluTextBox{
id:text_box id:text_box
text:"Technical testing 2015-09-01" text:"Technical testing 2015-09-01"
Layout.preferredWidth: 240
} }
FluFilledButton{ FluFilledButton{
text:"Append" text:"Append"

View File

@ -29,6 +29,7 @@ FluContentPage{
FluTextBox{ FluTextBox{
id:text_box id:text_box
text:"会磨刀的小猪" text:"会磨刀的小猪"
Layout.preferredWidth: 240
} }
} }

View File

@ -4,6 +4,7 @@ import FluentUI
FluViewModel{ FluViewModel{
objectName: "SettingsViewModel" objectName: "SettingsViewModel"
scope: FluViewModelType.Application
property int displayMode property int displayMode
onInitData: { onInitData: {

View File

@ -60,11 +60,11 @@ FluWindow {
event.accepted = false event.accepted = false
return return
} }
if (event.urls.length !== 1) { var url = getUrlByEvent(event)
if(url === ""){
event.accepted = false event.accepted = false
return return
} }
var url = event.urls[0].toString()
var fileExtension = url.substring(url.lastIndexOf(".") + 1) var fileExtension = url.substring(url.lastIndexOf(".") + 1)
if (fileExtension !== "qml") { if (fileExtension !== "qml") {
event.accepted = false event.accepted = false
@ -74,12 +74,24 @@ FluWindow {
} }
onDropped: onDropped:
(event)=>{ (event)=>{
var path = event.urls[0].toString() var url = getUrlByEvent(event)
loader.source = path if(url !== ""){
watcher.path = path loader.source = url
loader.reload() watcher.path = url
loader.reload()
}
} }
} }
} }
function getUrlByEvent(event){
var url = ""
if (event.urls.length === 0) {
url = "file:///"+event.getDataAsString("text/plain")
}else{
url = event.urls[0].toString()
}
return url
}
} }

View File

@ -15,22 +15,24 @@ FluWindow {
title: "FluentUI" title: "FluentUI"
width: 1000 width: 1000
height: 640 height: 640
closeDestory:false
minimumWidth: 520 minimumWidth: 520
minimumHeight: 200 minimumHeight: 200
launchMode: FluWindowType.SingleTask launchMode: FluWindowType.SingleTask
fitsAppBarWindows: true
appBar: undefined appBar: FluAppBar {
width: window.width
height: 30
darkText: Lang.dark_mode
showDark: true
darkClickListener:(button)=>handleDarkChanged(button)
closeClickListener: ()=>{dialog_close.open()}
z:7
}
SettingsViewModel{ SettingsViewModel{
id:viewmodel_settings id:viewmodel_settings
} }
closeListener:function(event){
dialog_close.open()
event.accepted = false
}
FluEvent{ FluEvent{
id:event_checkupdate id:event_checkupdate
name: "checkUpdate" name: "checkUpdate"
@ -38,9 +40,12 @@ FluWindow {
checkUpdate(false) checkUpdate(false)
} }
} }
Component.onCompleted: {
FluTools.setQuitOnLastWindowClosed(false) onFirstVisible: {
tour.open() tour.open()
}
Component.onCompleted: {
checkUpdate(true) checkUpdate(true)
FluEventBus.registerEvent(event_checkupdate) FluEventBus.registerEvent(event_checkupdate)
} }
@ -85,7 +90,22 @@ FluWindow {
positiveText:"退出" positiveText:"退出"
neutralText:"取消" neutralText:"取消"
onPositiveClicked:{ onPositiveClicked:{
FluApp.exit() FluApp.exit(0)
}
}
Component{
id:nav_item_right_menu
FluMenu{
id:menu
width: 130
FluMenuItem{
text: "在独立窗口打开"
visible: true
onClicked: {
FluApp.navigate("/pageWindow",{title:modelData.title,url:modelData.url})
}
}
} }
} }
@ -112,18 +132,8 @@ FluWindow {
back: Item{ back: Item{
anchors.fill: flipable anchors.fill: flipable
visible: flipable.flipAngle !== 0 visible: flipable.flipAngle !== 0
FluAppBar {
anchors {
top: parent.top
left: parent.left
right: parent.right
}
darkText: Lang.dark_mode
showDark: true
z:7
darkClickListener:(button)=>handleDarkChanged(button)
}
Row{ Row{
id:layout_back_buttons
z:8 z:8
anchors{ anchors{
top: parent.top top: parent.top
@ -154,25 +164,13 @@ FluWindow {
id:loader id:loader
lazy: true lazy: true
anchors.fill: parent anchors.fill: parent
source: "https://zhu-zichu.gitee.io/Qt6_156_LieflatPage.qml" source: "https://zhu-zichu.gitee.io/Qt_163_LieflatPage.qml"
} }
} }
front: Item{ front: Item{
id:page_front id:page_front
visible: flipable.flipAngle !== 180 visible: flipable.flipAngle !== 180
anchors.fill: flipable anchors.fill: flipable
FluAppBar {
id:app_bar_front
anchors {
top: parent.top
left: parent.left
right: parent.right
}
darkText: Lang.dark_mode
showDark: true
darkClickListener:(button)=>handleDarkChanged(button)
z:7
}
FluNavigationView{ FluNavigationView{
property int clickCount: 0 property int clickCount: 0
id:nav_view id:nav_view
@ -209,7 +207,9 @@ FluWindow {
} }
Component.onCompleted: { Component.onCompleted: {
ItemsOriginal.navigationView = nav_view ItemsOriginal.navigationView = nav_view
ItemsOriginal.paneItemMenu = nav_item_right_menu
ItemsFooter.navigationView = nav_view ItemsFooter.navigationView = nav_view
ItemsFooter.paneItemMenu = nav_item_right_menu
setCurrentIndex(0) setCurrentIndex(0)
} }
} }
@ -232,7 +232,7 @@ FluWindow {
} }
} }
Loader{ FluLoader{
id:loader_reveal id:loader_reveal
anchors.fill: parent anchors.fill: parent
} }
@ -242,7 +242,7 @@ FluWindow {
} }
function handleDarkChanged(button){ function handleDarkChanged(button){
if(FluTools.isMacos() || !FluTheme.enableAnimation){ if(!FluTheme.enableAnimation || window.fitsAppBarWindows === false){
changeDark() changeDark()
}else{ }else{
loader_reveal.sourceComponent = com_reveal loader_reveal.sourceComponent = com_reveal
@ -284,14 +284,14 @@ FluWindow {
FluTour{ FluTour{
id:tour id:tour
steps:[ steps:{
{title:"夜间模式",description: "这里可以切换夜间模式.",target:()=>app_bar_front.darkButton()}, var data = []
{title:"隐藏彩蛋",description: "多点几下试试!!",target:()=>nav_view.logoButton()} if(!window.useSystemAppBar){
] data.push({title:"夜间模式",description: "这里可以切换夜间模式.",target:()=>appBar.darkButton()})
} }
data.push({title:"隐藏彩蛋",description: "多点几下试试!!",target:()=>nav_view.logoButton()})
FluHttp{ return data
id:http }
} }
FpsItem{ FpsItem{
@ -323,7 +323,7 @@ FluWindow {
} }
} }
HttpCallable{ FluNetworkCallable{
id:callable id:callable
property bool silent: true property bool silent: true
onStart: { onStart: {
@ -359,8 +359,8 @@ FluWindow {
function checkUpdate(silent){ function checkUpdate(silent){
callable.silent = silent callable.silent = silent
var request = http.newRequest("https://api.github.com/repos/zhuzichu520/FluentUI/releases/latest") FluNetwork.get("https://api.github.com/repos/zhuzichu520/FluentUI/releases/latest")
http.get(request,callable); .go(callable)
} }
} }

View File

@ -18,7 +18,7 @@ FluWindow {
window.title = arg.title window.title = arg.title
loader.setSource( arg.url,{animDisabled:true}) loader.setSource( arg.url,{animDisabled:true})
} }
Loader{ FluLoader{
id: loader id: loader
anchors.fill: parent anchors.fill: parent
} }

View File

@ -4,9 +4,8 @@ import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import FluentUI 1.0 import FluentUI 1.0
Window { Item {
id: app id: app
flags: Qt.SplashScreen
Connections{ Connections{
target: FluTheme target: FluTheme
@ -20,26 +19,17 @@ Window {
function onVsyncChanged(){ function onVsyncChanged(){
SettingsHelper.saveVsync(FluApp.vsync) SettingsHelper.saveVsync(FluApp.vsync)
} }
} function onUseSystemAppBarChanged(){
SettingsHelper.saveUseSystemAppBar(FluApp.useSystemAppBar)
FluHttpInterceptor{
id:interceptor
function onIntercept(request){
if(request.method === "get"){
request.params["method"] = "get"
}
if(request.method === "post"){
request.params["method"] = "post"
}
request.headers["token"] ="yyds"
request.headers["os"] ="pc"
console.debug(JSON.stringify(request))
return request
} }
} }
Component.onCompleted: { Component.onCompleted: {
FluNetwork.setInterceptor(function(param){
param.addHeader("Token","000000000000000000000")
})
FluApp.init(app) FluApp.init(app)
FluApp.useSystemAppBar = SettingsHelper.getUseSystemAppBar()
FluApp.vsync = SettingsHelper.getVsync() FluApp.vsync = SettingsHelper.getVsync()
FluTheme.darkMode = SettingsHelper.getDarkMode() FluTheme.darkMode = SettingsHelper.getDarkMode()
FluTheme.enableAnimation = true FluTheme.enableAnimation = true
@ -54,7 +44,6 @@ Window {
"/pageWindow":"qrc:/example/qml/window/PageWindow.qml" "/pageWindow":"qrc:/example/qml/window/PageWindow.qml"
} }
FluApp.initialRoute = "/" FluApp.initialRoute = "/"
FluApp.httpInterceptor = interceptor
FluApp.run() FluApp.run()
} }
} }

View File

@ -130,7 +130,6 @@ FluExpander{
"FluRadioButtons", "FluRadioButtons",
"FluImage", "FluImage",
"FluSpinBox", "FluSpinBox",
"FluHttp",
"FluWatermark", "FluWatermark",
"FluTour", "FluTour",
"FluQRCode", "FluQRCode",
@ -140,7 +139,8 @@ FluExpander{
"FluStaggeredView", "FluStaggeredView",
"FluProgressButton", "FluProgressButton",
"FluLoadingButton", "FluLoadingButton",
"FluClip" "FluClip",
"FluNetwork"
]; ];
code = code.replace(/\n/g, "<br>"); code = code.replace(/\n/g, "<br>");
code = code.replace(/ /g, "&nbsp;"); code = code.replace(/ /g, "&nbsp;");

View File

@ -6,6 +6,7 @@ import FluentUI 1.0
FluObject{ FluObject{
property var navigationView property var navigationView
property var paneItemMenu
id:footer_items id:footer_items
@ -14,7 +15,6 @@ FluObject{
FluPaneItem{ FluPaneItem{
title:Lang.about title:Lang.about
icon:FluentIcons.Contact icon:FluentIcons.Contact
onDropped: { FluApp.navigate("/about") }
onTapListener:function(){ onTapListener:function(){
FluApp.navigate("/about") FluApp.navigate("/about")
} }
@ -22,9 +22,9 @@ FluObject{
FluPaneItem{ FluPaneItem{
title:Lang.settings title:Lang.settings
menuDelegate: paneItemMenu
icon:FluentIcons.Settings icon:FluentIcons.Settings
url:"qrc:/example/qml/page/T_Settings.qml" url:"qrc:/example/qml/page/T_Settings.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ onTap:{
navigationView.push(url) navigationView.push(url)
} }

View File

@ -6,6 +6,7 @@ import FluentUI 1.0
FluObject{ FluObject{
property var navigationView property var navigationView
property var paneItemMenu
function rename(item, newName){ function rename(item, newName){
if(newName && newName.trim().length>0){ if(newName && newName.trim().length>0){
@ -17,32 +18,18 @@ FluObject{
id:item_home id:item_home
count: 9 count: 9
title:Lang.home title:Lang.home
menuDelegate: paneItemMenu
infoBadge:FluBadge{ infoBadge:FluBadge{
count: item_home.count count: item_home.count
} }
icon:FluentIcons.Home icon:FluentIcons.Home
url:"qrc:/example/qml/page/T_Home.qml" url:"qrc:/example/qml/page/T_Home.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ onTap:{
if(navigationView.getCurrentUrl()){ if(navigationView.getCurrentUrl()){
item_home.count = 0 item_home.count = 0
} }
navigationView.push(url) navigationView.push(url)
} }
editDelegate: FluTextBox{
text:item_home.title
}
menuDelegate: FluMenu{
id:nav_item_right_menu
width: 120
FluMenuItem{
text: "重命名"
visible: true
onClicked: {
item_home.showEdit = true
}
}
}
} }
FluPaneItemExpander{ FluPaneItemExpander{
@ -55,18 +42,6 @@ FluObject{
id:item_expander_basic_input id:item_expander_basic_input
title:Lang.basic_input title:Lang.basic_input
icon:FluentIcons.CheckboxComposite icon:FluentIcons.CheckboxComposite
editDelegate: FluTextBox{
text:item_expander_basic_input.title
}
menuDelegate: FluMenu{
FluMenuItem{
text: "重命名"
visible: true
onClicked: {
item_expander_basic_input.showEdit = true
}
}
}
FluPaneItem{ FluPaneItem{
id:item_buttons id:item_buttons
count: 99 count: 99
@ -74,11 +49,11 @@ FluObject{
count: item_buttons.count count: item_buttons.count
} }
title:"Buttons" title:"Buttons"
menuDelegate: paneItemMenu
image:"qrc:/example/res/image/control/Button.png" image:"qrc:/example/res/image/control/Button.png"
recentlyUpdated:true recentlyUpdated:true
desc:"A control that responds to user input and raisesa Click event." desc:"A control that responds to user input and raisesa Click event."
url:"qrc:/example/qml/page/T_Buttons.qml" url:"qrc:/example/qml/page/T_Buttons.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ onTap:{
item_buttons.count = 0 item_buttons.count = 0
navigationView.push(url) navigationView.push(url)
@ -87,13 +62,13 @@ FluObject{
FluPaneItem{ FluPaneItem{
id:item_text id:item_text
title:"Text" title:"Text"
menuDelegate: paneItemMenu
count: 5 count: 5
infoBadge:FluBadge{ infoBadge:FluBadge{
count: item_text.count count: item_text.count
color: Qt.rgba(82/255,196/255,26/255,1) color: Qt.rgba(82/255,196/255,26/255,1)
} }
url:"qrc:/example/qml/page/T_Text.qml" url:"qrc:/example/qml/page/T_Text.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ onTap:{
item_text.count = 0 item_text.count = 0
navigationView.push(url) navigationView.push(url)
@ -101,38 +76,38 @@ FluObject{
} }
FluPaneItem{ FluPaneItem{
title:"Image" title:"Image"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Image.qml" url:"qrc:/example/qml/page/T_Image.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Slider" title:"Slider"
menuDelegate: paneItemMenu
image:"qrc:/example/res/image/control/Slider.png" image:"qrc:/example/res/image/control/Slider.png"
recentlyUpdated:true recentlyUpdated:true
desc:"A control that lets the user select from a rangeof values by moving a Thumb control along atrack." desc:"A control that lets the user select from a rangeof values by moving a Thumb control along atrack."
url:"qrc:/example/qml/page/T_Slider.qml" url:"qrc:/example/qml/page/T_Slider.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"CheckBox" title:"CheckBox"
menuDelegate: paneItemMenu
image:"qrc:/example/res/image/control/Checkbox.png" image:"qrc:/example/res/image/control/Checkbox.png"
recentlyUpdated:true recentlyUpdated:true
desc:"A control that a user can select or clear." desc:"A control that a user can select or clear."
url:"qrc:/example/qml/page/T_CheckBox.qml" url:"qrc:/example/qml/page/T_CheckBox.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"RadioButton" title:"RadioButton"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_RadioButton.qml" url:"qrc:/example/qml/page/T_RadioButton.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"ToggleSwitch" title:"ToggleSwitch"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_ToggleSwitch.qml" url:"qrc:/example/qml/page/T_ToggleSwitch.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
@ -147,32 +122,32 @@ FluObject{
icon:FluentIcons.GridView icon:FluentIcons.GridView
FluPaneItem{ FluPaneItem{
title:"TextBox" title:"TextBox"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_TextBox.qml" url:"qrc:/example/qml/page/T_TextBox.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"TimePicker" title:"TimePicker"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_TimePicker.qml" url:"qrc:/example/qml/page/T_TimePicker.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"DatePicker" title:"DatePicker"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_DatePicker.qml" url:"qrc:/example/qml/page/T_DatePicker.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"CalendarPicker" title:"CalendarPicker"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_CalendarPicker.qml" url:"qrc:/example/qml/page/T_CalendarPicker.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"ColorPicker" title:"ColorPicker"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_ColorPicker.qml" url:"qrc:/example/qml/page/T_ColorPicker.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
} }
@ -182,71 +157,71 @@ FluObject{
icon:FluentIcons.SurfaceHub icon:FluentIcons.SurfaceHub
FluPaneItem{ FluPaneItem{
title:"InfoBar" title:"InfoBar"
menuDelegate: paneItemMenu
image:"qrc:/example/res/image/control/InfoBar.png" image:"qrc:/example/res/image/control/InfoBar.png"
recentlyUpdated:true recentlyUpdated:true
desc:"An inline message to display app-wide statuschange information." desc:"An inline message to display app-wide statuschange information."
url:"qrc:/example/qml/page/T_InfoBar.qml" url:"qrc:/example/qml/page/T_InfoBar.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Progress" title:"Progress"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Progress.qml" url:"qrc:/example/qml/page/T_Progress.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"RatingControl" title:"RatingControl"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_RatingControl.qml" url:"qrc:/example/qml/page/T_RatingControl.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Badge" title:"Badge"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Badge.qml" url:"qrc:/example/qml/page/T_Badge.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Rectangle" title:"Rectangle"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Rectangle.qml" url:"qrc:/example/qml/page/T_Rectangle.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Clip" title:"Clip"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Clip.qml" url:"qrc:/example/qml/page/T_Clip.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"StatusView" title:"StatusView"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_StatusView.qml" url:"qrc:/example/qml/page/T_StatusView.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Carousel" title:"Carousel"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Carousel.qml" url:"qrc:/example/qml/page/T_Carousel.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Expander" title:"Expander"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Expander.qml" url:"qrc:/example/qml/page/T_Expander.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"StaggeredView" title:"StaggeredView"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_StaggeredView.qml" url:"qrc:/example/qml/page/T_StaggeredView.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Watermark" title:"Watermark"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Watermark.qml" url:"qrc:/example/qml/page/T_Watermark.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
} }
@ -256,20 +231,20 @@ FluObject{
icon:FluentIcons.ButtonMenu icon:FluentIcons.ButtonMenu
FluPaneItem{ FluPaneItem{
title:"Dialog" title:"Dialog"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Dialog.qml" url:"qrc:/example/qml/page/T_Dialog.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
id:item_combobox id:item_combobox
title:"ComboBox" title:"ComboBox"
menuDelegate: paneItemMenu
count: 9 count: 9
infoBadge:FluBadge{ infoBadge:FluBadge{
count: item_combobox.count count: item_combobox.count
color: Qt.rgba(250/255,173/255,20/255,1) color: Qt.rgba(250/255,173/255,20/255,1)
} }
url:"qrc:/example/qml/page/T_ComboBox.qml" url:"qrc:/example/qml/page/T_ComboBox.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ onTap:{
item_combobox.count = 0 item_combobox.count = 0
navigationView.push("qrc:/example/qml/page/T_ComboBox.qml") navigationView.push("qrc:/example/qml/page/T_ComboBox.qml")
@ -277,14 +252,14 @@ FluObject{
} }
FluPaneItem{ FluPaneItem{
title:"Tooltip" title:"Tooltip"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Tooltip.qml" url:"qrc:/example/qml/page/T_Tooltip.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Menu" title:"Menu"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Menu.qml" url:"qrc:/example/qml/page/T_Menu.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
} }
@ -294,66 +269,66 @@ FluObject{
icon:FluentIcons.AllApps icon:FluentIcons.AllApps
FluPaneItem{ FluPaneItem{
title:"Pivot" title:"Pivot"
menuDelegate: paneItemMenu
image:"qrc:/example/res/image/control/Pivot.png" image:"qrc:/example/res/image/control/Pivot.png"
recentlyAdded:true recentlyAdded:true
order:3 order:3
desc:"Presents information from different sources in atabbed view." desc:"Presents information from different sources in atabbed view."
url:"qrc:/example/qml/page/T_Pivot.qml" url:"qrc:/example/qml/page/T_Pivot.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"BreadcrumbBar" title:"BreadcrumbBar"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_BreadcrumbBar.qml" url:"qrc:/example/qml/page/T_BreadcrumbBar.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"TabView" title:"TabView"
menuDelegate: paneItemMenu
image:"qrc:/example/res/image/control/TabView.png" image:"qrc:/example/res/image/control/TabView.png"
recentlyAdded:true recentlyAdded:true
order:1 order:1
desc:"A control that displays a collection of tabs thatcan be used to display several documents." desc:"A control that displays a collection of tabs thatcan be used to display several documents."
url:"qrc:/example/qml/page/T_TabView.qml" url:"qrc:/example/qml/page/T_TabView.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"TreeView" title:"TreeView"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_TreeView.qml" url:"qrc:/example/qml/page/T_TreeView.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"TableView" title:"TableView"
menuDelegate: paneItemMenu
image:"qrc:/example/res/image/control/DataGrid.png" image:"qrc:/example/res/image/control/DataGrid.png"
recentlyAdded:true recentlyAdded:true
order:4 order:4
desc:"The TableView control provides a flexible way to display a collection of data in rows and columns" desc:"The TableView control provides a flexible way to display a collection of data in rows and columns"
url:"qrc:/example/qml/page/T_TableView.qml" url:"qrc:/example/qml/page/T_TableView.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Pagination" title:"Pagination"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Pagination.qml" url:"qrc:/example/qml/page/T_Pagination.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"MultiWindow" title:"MultiWindow"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_MultiWindow.qml" url:"qrc:/example/qml/page/T_MultiWindow.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"FlipView" title:"FlipView"
menuDelegate: paneItemMenu
image:"qrc:/example/res/image/control/FlipView.png" image:"qrc:/example/res/image/control/FlipView.png"
recentlyAdded:true recentlyAdded:true
order:2 order:2
desc:"Presents a collection of items that the user canflip through, one item at a time." desc:"Presents a collection of items that the user canflip through, one item at a time."
url:"qrc:/example/qml/page/T_FlipView.qml" url:"qrc:/example/qml/page/T_FlipView.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
} }
@ -363,26 +338,26 @@ FluObject{
icon:FluentIcons.Brightness icon:FluentIcons.Brightness
FluPaneItem{ FluPaneItem{
title:"Acrylic" title:"Acrylic"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Acrylic.qml" url:"qrc:/example/qml/page/T_Acrylic.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Theme" title:"Theme"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Theme.qml" url:"qrc:/example/qml/page/T_Theme.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Typography" title:"Typography"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Typography.qml" url:"qrc:/example/qml/page/T_Typography.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Awesome" title:"Awesome"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Awesome.qml" url:"qrc:/example/qml/page/T_Awesome.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
} }
@ -397,56 +372,56 @@ FluObject{
icon:FluentIcons.Shop icon:FluentIcons.Shop
FluPaneItem{ FluPaneItem{
title:"QRCode" title:"QRCode"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_QRCode.qml" url:"qrc:/example/qml/page/T_QRCode.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Tour" title:"Tour"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Tour.qml" url:"qrc:/example/qml/page/T_Tour.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Timeline" title:"Timeline"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Timeline.qml" url:"qrc:/example/qml/page/T_Timeline.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Screenshot(Todo)" title:"Screenshot(Todo)"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Screenshot.qml" url:"qrc:/example/qml/page/T_Screenshot.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Captcha" title:"Captcha"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Captcha.qml" url:"qrc:/example/qml/page/T_Captcha.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Chart" title:"Chart"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_Chart.qml" url:"qrc:/example/qml/page/T_Chart.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title:"Http" title:"Network"
url:"qrc:/example/qml/page/T_Http.qml" menuDelegate: paneItemMenu
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) } url:"qrc:/example/qml/page/T_Network.qml"
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
id:item_other id:item_other
title:"RemoteLoader" title:"RemoteLoader"
menuDelegate: paneItemMenu
count: 99 count: 99
infoBadge:FluBadge{ infoBadge:FluBadge{
count: item_other.count count: item_other.count
color: Qt.rgba(82/255,196/255,26/255,1) color: Qt.rgba(82/255,196/255,26/255,1)
} }
url:"qrc:/example/qml/page/T_RemoteLoader.qml" url:"qrc:/example/qml/page/T_RemoteLoader.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ onTap:{
item_other.count = 0 item_other.count = 0
navigationView.push("qrc:/example/qml/page/T_RemoteLoader.qml") navigationView.push("qrc:/example/qml/page/T_RemoteLoader.qml")
@ -457,12 +432,11 @@ FluObject{
onTapListener:function(){ onTapListener:function(){
FluApp.navigate("/hotload") FluApp.navigate("/hotload")
} }
onDropped:{ FluApp.navigate("/hotload") }
} }
FluPaneItem{ FluPaneItem{
title:"3D" title:"3D"
menuDelegate: paneItemMenu
url:"qrc:/example/qml/page/T_3D.qml" url:"qrc:/example/qml/page/T_3D.qml"
onDropped:{ FluApp.navigate("/pageWindow",{title:title,url:url}) }
onTap:{ navigationView.push(url) } onTap:{ navigationView.push(url) }
} }
} }

View File

@ -44,6 +44,7 @@ FluScrollablePage{
FluTextBox{ FluTextBox{
id:text_box id:text_box
placeholderText: "请输入验证码" placeholderText: "请输入验证码"
Layout.preferredWidth: 240
} }
FluButton{ FluButton{
text:"verify" text:"verify"

View File

@ -2,7 +2,6 @@ import QtQuick 2.15
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import QtQuick.Window 2.15 import QtQuick.Window 2.15
import QtQuick.Controls 2.15 import QtQuick.Controls 2.15
import QtGraphicalEffects 1.0
import "qrc:///example/qml/global" import "qrc:///example/qml/global"
import FluentUI 1.0 import FluentUI 1.0
@ -78,7 +77,7 @@ FluScrollablePage{
Rectangle{ Rectangle{
anchors.fill: parent anchors.fill: parent
radius: 5 radius: 5
color:FluTheme.dark ? Qt.rgba(1,1,1,0.03) : Qt.rgba(0,0,0,0.03) color:FluTheme.itemHoverColor
visible: item_mouse.containsMouse visible: item_mouse.containsMouse
} }
Rectangle{ Rectangle{
@ -173,17 +172,10 @@ FluScrollablePage{
anchors.fill: parent anchors.fill: parent
radius: 8 radius: 8
color:{ color:{
if(FluTheme.dark){ if(item_mouse.containsMouse){
if(item_mouse.containsMouse){ return FluTheme.itemHoverColor
return Qt.rgba(1,1,1,0.03)
}
return Qt.rgba(0,0,0,0)
}else{
if(item_mouse.containsMouse){
return Qt.rgba(0,0,0,0.03)
}
return Qt.rgba(0,0,0,0)
} }
return FluTheme.itemNormalColor
} }
} }
Image{ Image{
@ -228,7 +220,7 @@ FluScrollablePage{
height: 12 height: 12
width: 12 width: 12
radius: 6 radius: 6
color: FluTheme.primaryColor.dark color: FluTheme.primaryColor
anchors{ anchors{
right: parent.right right: parent.right
top: parent.top top: parent.top

View File

@ -1,406 +0,0 @@
import QtQuick 2.15
import Qt.labs.platform 1.1
import QtQuick.Layouts 1.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import QtQuick.Dialogs 1.3
import FluentUI 1.0
import "qrc:///example/qml/component"
import "../component"
FluContentPage{
title:"Http"
property string cacheDirPath: StandardPaths.writableLocation(StandardPaths.AppLocalDataLocation) + "/cache/http"
property bool isDownCompleted: false
FluHttp{
id:http
cacheDir:cacheDirPath
}
FluHttp{
id:http_breakpoint_download
cacheDir:cacheDirPath
breakPointDownload: true
}
FluHttp{
id:http_cache_ifnonecacherequest
cacheMode:FluHttpType.IfNoneCacheRequest
cacheDir:cacheDirPath
}
FluHttp{
id:http_cache_requestfailedreadcache
cacheMode:FluHttpType.RequestFailedReadCache
cacheDir:cacheDirPath
}
FluHttp{
id:http_cache_firstcachethenrequest
cacheMode:FluHttpType.FirstCacheThenRequest
cacheDir:cacheDirPath
}
HttpCallable{
id:callable
onStart: {
showLoading()
}
onFinish: {
hideLoading()
}
onError:
(status,errorString,result)=>{
console.debug(status+";"+errorString+";"+result)
}
onSuccess:
(result)=>{
text_info.text = result
}
onCache:
(result)=>{
text_info.text = result
}
}
Flickable{
id:layout_flick
width: 200
clip: true
anchors{
top: parent.top
topMargin: 20
bottom: parent.bottom
left: parent.left
}
ScrollBar.vertical: FluScrollBar {}
contentHeight:layout_column.height
Column{
spacing: 2
id:layout_column
width: parent.width
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Get请求"
onClicked: {
var request = http.newRequest("https://httpbingo.org/get")
http.get(request,callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Post表单请求"
onClicked: {
var request = http.newRequest("https://httpbingo.org/post")
var params = {}
params.custname = "朱子楚"
params.custtel = "1234567890"
params.custemail = "zhuzichu520@gmail.com"
request.params = params
var headers = {}
headers.test = "123456789456465321354"
request.headers = headers
http.post(request,callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Post Json请求"
onClicked: {
var request = http.newRequest("https://httpbingo.org/post")
var params = {}
params.custname = "朱子楚"
params.custtel = "1234567890"
params.custemail = "zhuzichu520@gmail.com"
request.params = params
http.postJson(request,callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Post String请求"
onClicked: {
var request = http.newRequest("https://httpbingo.org/post")
request.params = "我命由我不由天"
http.postString(request,callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Delete请求"
onClicked: {
var request = http.newRequest("https://httpbingo.org/delete")
http.deleteResource(request,callable)
}
}
FluProgressButton{
id:btn_download
implicitWidth: parent.width
implicitHeight: 36
text: "下载文件"
onClicked: {
folder_dialog.open()
}
}
FluProgressButton{
property bool downloading: false
id:btn_breakpoint_download
implicitWidth: parent.width
implicitHeight: 36
text: {
if(downloading){
return "暂停下载"
}
if(progress === 0){
return "断点下载文件"
}else if(progress === 1){
return "打开文件"
}else{
return "继续下载"
}
}
HttpRequest{
id:request_breakpoint_download
url: "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"
downloadSavePath: FluTools.getApplicationDirPath()+ "/download/big_buck_bunny.mp4"
}
HttpCallable{
id:callable_breakpoint_download
onStart: {
btn_breakpoint_download.downloading = true
}
onFinish: {
btn_breakpoint_download.downloading = false
}
onError:
(status,errorString,result)=>{
console.debug(status+";"+errorString+";"+result)
}
onSuccess:
(result)=>{
if(!isDownCompleted){
tour.open()
isDownCompleted = true
}
showSuccess(result)
}
onDownloadProgress:
(recv,total)=>{
btn_breakpoint_download.progress = recv/total
}
}
Component.onCompleted: {
progress = http_breakpoint_download.getBreakPointProgress(request_breakpoint_download)
}
onClicked: {
if(downloading){
http_breakpoint_download.cancel()
return
}
if(progress === 1){
FluTools.showFileInFolder(request_breakpoint_download.downloadSavePath)
}else{
http_breakpoint_download.download(request_breakpoint_download,callable_breakpoint_download)
}
}
FluMenu{
id:menu_breakpoint_download
width: 120
FluMenuItem{
text: "删除文件"
onClicked: {
if(FluTools.removeFile(request_breakpoint_download.downloadSavePath)){
btn_breakpoint_download.progress = 0
}
}
}
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton
onClicked: {
if(btn_breakpoint_download.progress === 1){
menu_breakpoint_download.popup()
}
}
}
}
FluProgressButton{
id:btn_upload
implicitWidth: parent.width
implicitHeight: 36
text: "文件上传"
onClicked: {
file_dialog.open()
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "FirstCacheThenRequest缓存"
onClicked: {
var request = http.newRequest("https://httpbingo.org/post")
request.params = {cacheMode:"FirstCacheThenRequest"}
http_cache_firstcachethenrequest.post(request,callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "RequestFailedReadCache缓存"
onClicked: {
var request = http.newRequest("https://httpbingo.org/post")
request.params = {cacheMode:"RequestFailedReadCache"}
http_cache_requestfailedreadcache.post(request,callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "IfNoneCacheRequest缓存"
onClicked: {
var request = http.newRequest("https://httpbingo.org/post")
request.params = {cacheMode:"IfNoneCacheRequest"}
http_cache_ifnonecacherequest.post(request,callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "打开缓存路径"
onClicked: {
Qt.openUrlExternally(cacheDirPath)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "删除缓存"
onClicked: {
console.debug(FluTools.removeDir(cacheDirPath))
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "清空右边数据"
onClicked: {
text_info.text = ""
}
}
}
}
FluTour{
id:tour
steps:[
{title:"友情提示",description: "下载已完成,左击这里可以打开文件所在路径,右击可以弹出菜单删除文件!",target:()=>btn_breakpoint_download}
]
}
HttpCallable{
id:callable_upload
onStart: {
btn_upload.disabled = true
}
onFinish: {
btn_upload.disabled = false
}
onError:
(status,errorString,result)=>{
btn_upload.progress = 0
text_info.text = result
console.debug(result)
}
onSuccess:
(result)=>{
text_info.text = result
}
onUploadProgress:
(sent,total)=>{
btn_upload.progress = sent/total
}
}
FileDialog {
id: file_dialog
onAccepted: {
var request = http.newRequest("https://httpbingo.org/post")
var params = {}
for(var i=0;i<selectedFiles.length;i++){
var fileUrl = selectedFiles[i]
var fileName = FluTools.getFileNameByUrl(fileUrl)
var filePath = FluTools.toLocalPath(fileUrl)
params[fileName] = filePath
}
request.params = params
http.upload(request,callable_upload)
}
}
HttpCallable{
id:callable_download
onStart: {
btn_download.progress = 0
btn_download.disabled = true
}
onFinish: {
btn_download.disabled = false
}
onError:
(status,errorString,result)=>{
btn_download.progress = 0
showError(errorString)
console.debug(status+";"+errorString+";"+result)
}
onSuccess:
(result)=>{
showSuccess(result)
}
onDownloadProgress:
(recv,total)=>{
btn_download.progress = recv/total
}
}
FolderDialog {
id: folder_dialog
currentFolder: StandardPaths.standardLocations(StandardPaths.DownloadLocation)[0]
onAccepted: {
var request = http.newRequest("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
request.downloadSavePath = FluTools.toLocalPath(currentFolder)+ "/big_buck_bunny.mp4"
http.download(request,callable_download)
}
}
FluArea{
anchors{
top: layout_flick.top
bottom: layout_flick.bottom
left: layout_flick.right
right: parent.right
leftMargin: 8
}
Flickable{
clip: true
id:scrollview
boundsBehavior:Flickable.StopAtBounds
width: parent.width
height: parent.height
contentWidth: width
contentHeight: text_info.height
ScrollBar.vertical: FluScrollBar {}
FluText{
id:text_info
width: scrollview.width
wrapMode: Text.WrapAnywhere
padding: 14
}
}
}
}

View File

@ -0,0 +1,532 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import FluentUI 1.0
import Qt.labs.platform 1.0
import "qrc:///example/qml/component"
import "../component"
FluContentPage{
id:root
title:"Network"
FluNetworkCallable{
id:callable
onStart: {
showLoading()
}
onFinish: {
hideLoading()
}
onError:
(status,errorString,result)=>{
console.debug(status+";"+errorString+";"+result)
}
onCache:
(result)=>{
text_info.text = result
}
onSuccess:
(result)=>{
text_info.text = result
}
}
Flickable{
id:layout_flick
width: 200
clip: true
anchors{
top: parent.top
topMargin: 20
bottom: parent.bottom
left: parent.left
}
boundsBehavior: Flickable.StopAtBounds
ScrollBar.vertical: FluScrollBar {}
contentHeight:layout_column.height
Column{
spacing: 2
id:layout_column
width: parent.width
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Get"
onClicked: {
text_info.text = ""
FluNetwork.get("https://httpbingo.org/get")
.addQuery("name","孙悟空")
.addQuery("age",500)
.addQuery("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Post Body"
onClicked: {
text_info.text = ""
FluNetwork.postBody("https://httpbingo.org/post")
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Post Form"
onClicked: {
text_info.text = ""
FluNetwork.postForm("https://httpbingo.org/post")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Post JSON"
onClicked: {
text_info.text = ""
FluNetwork.postJson("https://httpbingo.org/post")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Post JSON Array"
onClicked: {
text_info.text = ""
FluNetwork.postJsonArray("https://httpbingo.org/post")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Put Body"
onClicked: {
text_info.text = ""
FluNetwork.putBody("https://httpbingo.org/put")
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Put Form"
onClicked: {
text_info.text = ""
FluNetwork.putForm("https://httpbingo.org/put")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Put JSON"
onClicked: {
text_info.text = ""
FluNetwork.putJson("https://httpbingo.org/put")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Put JSON Array"
onClicked: {
text_info.text = ""
FluNetwork.putJsonArray("https://httpbingo.org/put")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Patch Body"
onClicked: {
text_info.text = ""
FluNetwork.patchBody("https://httpbingo.org/patch")
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Patch Form"
onClicked: {
text_info.text = ""
FluNetwork.patchForm("https://httpbingo.org/patch")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Patch JSON"
onClicked: {
text_info.text = ""
FluNetwork.patchJson("https://httpbingo.org/patch")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Patch JSON Array"
onClicked: {
text_info.text = ""
FluNetwork.patchJsonArray("https://httpbingo.org/patch")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Delete Body"
onClicked: {
text_info.text = ""
FluNetwork.deleteBody("https://httpbingo.org/delete")
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Delete Form"
onClicked: {
text_info.text = ""
FluNetwork.deleteForm("https://httpbingo.org/delete")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Delete JSON"
onClicked: {
text_info.text = ""
FluNetwork.deleteJson("https://httpbingo.org/delete")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Delete JSON Array"
onClicked: {
text_info.text = ""
FluNetwork.deleteJsonArray("https://httpbingo.org/delete")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Custom Header"
onClicked: {
text_info.text = ""
FluNetwork.postJson("https://httpbingo.org/post")
.addHeader("os","PC")
.addHeader("version","1.0.0")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "RequestFailedReadCache"
onClicked: {
text_info.text = ""
FluNetwork.postJson("https://httpbingo.org/post")
.setCacheMode(FluNetworkType.RequestFailedReadCache)
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.add("cacheMode","RequestFailedReadCache")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "IfNoneCacheRequest"
onClicked: {
text_info.text = ""
FluNetwork.postJson("https://httpbingo.org/post")
.setCacheMode(FluNetworkType.IfNoneCacheRequest)
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.add("cacheMode","IfNoneCacheRequest")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "FirstCacheThenRequest"
onClicked: {
text_info.text = ""
FluNetwork.postJson("https://httpbingo.org/post")
.setCacheMode(FluNetworkType.FirstCacheThenRequest)
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.add("cacheMode","FirstCacheThenRequest")
.bind(root)
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Timeout And Retry"
onClicked: {
text_info.text = ""
FluNetwork.postJson("https://httpbingo.org/post")
.setTimeout(5000)
.setRetry(3)
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.add("timeout","5000")
.add("retry","3")
.bind(root)
.go(callable)
}
}
FluProgressButton{
id:btn_upload
implicitWidth: parent.width
implicitHeight: 36
text: "Upload File"
onClicked: {
file_dialog.open()
}
}
FluProgressButton{
id:btn_download
implicitWidth: parent.width
implicitHeight: 36
text: "Download File"
onClicked: {
folder_dialog.showDialog(function(path){
FluNetwork.get("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
.toDownload(path)
.bind(root)
.go(callable_download_file)
})
}
}
FluProgressButton{
id:btn_download_breakpoint
implicitWidth: parent.width
implicitHeight: 36
text: "Breakpoint Download File"
onClicked: {
folder_dialog.showDialog(function(path){
FluNetwork.get("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
.toDownload(path,true)
.bind(root)
.go(callable_breakpoint_download_file)
})
}
}
}
}
FluNetworkCallable{
id:callable_upload_file
onStart: {
btn_upload.disabled = true
}
onFinish: {
btn_upload.disabled = false
}
onError:
(status,errorString,result)=>{
btn_upload.progress = 0
text_info.text = result
console.debug(status+";"+errorString+";"+result)
}
onSuccess:
(result)=>{
text_info.text = result
}
onUploadProgress:
(sent,total)=>{
btn_upload.progress = sent/total
}
}
FluNetworkCallable{
id:callable_download_file
onStart: {
btn_download.progress = 0
btn_download.disabled = true
}
onFinish: {
btn_download.disabled = false
}
onError:
(status,errorString,result)=>{
btn_download.progress = 0
showError(errorString)
console.debug(status+";"+errorString+";"+result)
}
onSuccess:
(result)=>{
showSuccess(result)
}
onDownloadProgress:
(recv,total)=>{
btn_download.progress = recv/total
}
}
FluNetworkCallable{
id:callable_breakpoint_download_file
onStart: {
btn_download_breakpoint.progress = 0
btn_download_breakpoint.disabled = true
}
onFinish: {
btn_download_breakpoint.disabled = false
}
onError:
(status,errorString,result)=>{
btn_download_breakpoint.progress = 0
showError(errorString)
console.debug(status+";"+errorString+";"+result)
}
onSuccess:
(result)=>{
showSuccess(result)
}
onDownloadProgress:
(recv,total)=>{
btn_download_breakpoint.progress = recv/total
}
}
FileDialog {
id: file_dialog
onAccepted: {
FluNetwork.postForm("https://httpbingo.org/post")
.setRetry(1)//只请求一次
.add("accessToken","12345678")
.addFile("file",FluTools.toLocalPath(file_dialog.currentFile))
.bind(root)
.go(callable_upload_file)
}
}
FileDialog {
property var onSelectListener
id: folder_dialog
folder: StandardPaths.standardLocations(StandardPaths.DownloadLocation)[0]
currentFile: StandardPaths.standardLocations(StandardPaths.DownloadLocation)[0]+"/big_buck_bunny.mp4"
fileMode: FileDialog.SaveFile
onAccepted: {
folder_dialog.onSelectListener(FluTools.toLocalPath(folder_dialog.currentFile))
}
function showDialog(listener){
folder_dialog.onSelectListener = listener
folder_dialog.open()
}
}
FluArea{
anchors{
top: layout_flick.top
bottom: layout_flick.bottom
left: layout_flick.right
right: parent.right
leftMargin: 8
}
Flickable{
clip: true
id:scrollview
boundsBehavior:Flickable.StopAtBounds
width: parent.width
height: parent.height
contentWidth: width
contentHeight: text_info.height
ScrollBar.vertical: FluScrollBar {}
FluText{
id:text_info
width: scrollview.width
wrapMode: Text.WrapAnywhere
padding: 14
}
}
}
}

View File

@ -32,6 +32,7 @@ FluScrollablePage{
FluTextBox{ FluTextBox{
id:text_box id:text_box
text:"会磨刀的小猪" text:"会磨刀的小猪"
Layout.preferredWidth: 240
} }
} }

View File

@ -36,7 +36,7 @@ FluScrollablePage{
color: FluTheme.dark ? FluColors.Black : FluColors.White color: FluTheme.dark ? FluColors.Black : FluColors.White
FluShadow{ FluShadow{
radius: 4 radius: 4
color: FluTheme.primaryColor.dark color: FluTheme.primaryColor
} }
Image{ Image{
id:image id:image

View File

@ -75,6 +75,36 @@ FluScrollablePage{
} }
} }
FluArea{
Layout.fillWidth: true
Layout.topMargin: 20
height: 50
paddings: 10
FluCheckBox{
text:"Use System AppBar"
checked: FluApp.useSystemAppBar
anchors.verticalCenter: parent.verticalCenter
onClicked: {
FluApp.useSystemAppBar = !FluApp.useSystemAppBar
dialog_restart.open()
}
}
}
FluArea{
Layout.fillWidth: true
Layout.topMargin: 20
height: 50
paddings: 10
FluCheckBox{
text:"fitsAppBarWindows"
checked: window.fitsAppBarWindows
anchors.verticalCenter: parent.verticalCenter
onClicked: {
window.fitsAppBarWindows = !window.fitsAppBarWindows
}
}
}
FluArea{ FluArea{
Layout.fillWidth: true Layout.fillWidth: true
@ -202,5 +232,4 @@ FluScrollablePage{
} }
} }
} }
} }

View File

@ -67,7 +67,7 @@ FluScrollablePage{
} }
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
color:FluTheme.primaryColor.dark color:FluTheme.primaryColor
} }
} }
} }
@ -79,7 +79,7 @@ FluScrollablePage{
statusMode: FluStatusViewType.Loading statusMode: FluStatusViewType.Loading
Rectangle{ Rectangle{
anchors.fill: parent anchors.fill: parent
color:FluTheme.primaryColor.dark color:FluTheme.primaryColor
} }
}' }'
} }

View File

@ -182,7 +182,7 @@ FluContentPage{
iconSource: FluentIcons.ChevronUp iconSource: FluentIcons.ChevronUp
iconColor: { iconColor: {
if(1 === root.sortType){ if(1 === root.sortType){
return FluTheme.primaryColor.dark return FluTheme.primaryColor
} }
return FluTheme.dark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1) return FluTheme.dark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1)
} }
@ -203,7 +203,7 @@ FluContentPage{
iconSource: FluentIcons.ChevronDown iconSource: FluentIcons.ChevronDown
iconColor: { iconColor: {
if(2 === root.sortType){ if(2 === root.sortType){
return FluTheme.primaryColor.dark return FluTheme.primaryColor
} }
return FluTheme.dark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1) return FluTheme.dark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1)
} }

View File

@ -33,7 +33,7 @@ FluScrollablePage{
anchors.centerIn: parent anchors.centerIn: parent
iconSource: FluentIcons.AcceptMedium iconSource: FluentIcons.AcceptMedium
iconSize: 15 iconSize: 15
visible: modelData === FluTheme.primaryColor visible: modelData === FluTheme.themeColor
color: FluTheme.dark ? Qt.rgba(0,0,0,1) : Qt.rgba(1,1,1,1) color: FluTheme.dark ? Qt.rgba(0,0,0,1) : Qt.rgba(1,1,1,1)
} }
MouseArea{ MouseArea{
@ -41,7 +41,7 @@ FluScrollablePage{
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
onClicked: { onClicked: {
FluTheme.primaryColor = modelData FluTheme.themeColor = modelData
} }
} }
} }
@ -89,7 +89,7 @@ FluScrollablePage{
CodeExpander{ CodeExpander{
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: -1 Layout.topMargin: -1
code:'FluTheme.primaryColor = FluColors.Orange code:'FluTheme.themeColor = FluColors.Orange
FluTheme.dark = true FluTheme.dark = true

View File

@ -111,6 +111,7 @@ FluScrollablePage{
FluTextBox{ FluTextBox{
id:text_box id:text_box
text:"Technical testing 2015-09-01" text:"Technical testing 2015-09-01"
Layout.preferredWidth: 240
} }
FluFilledButton{ FluFilledButton{
text:"Append" text:"Append"

View File

@ -30,6 +30,7 @@ FluContentPage{
FluTextBox{ FluTextBox{
id:text_box id:text_box
text:"会磨刀的小猪" text:"会磨刀的小猪"
Layout.preferredWidth: 240
} }
} }

View File

@ -4,6 +4,7 @@ import FluentUI 1.0
FluViewModel{ FluViewModel{
objectName: "SettingsViewModel" objectName: "SettingsViewModel"
scope: FluViewModelType.Application
property int displayMode property int displayMode
onInitData: { onInitData: {

View File

@ -61,11 +61,11 @@ FluWindow {
event.accepted = false event.accepted = false
return return
} }
if (event.urls.length !== 1) { var url = getUrlByEvent(event)
if(url === ""){
event.accepted = false event.accepted = false
return return
} }
var url = event.urls[0].toString()
var fileExtension = url.substring(url.lastIndexOf(".") + 1) var fileExtension = url.substring(url.lastIndexOf(".") + 1)
if (fileExtension !== "qml") { if (fileExtension !== "qml") {
event.accepted = false event.accepted = false
@ -75,12 +75,24 @@ FluWindow {
} }
onDropped: onDropped:
(event)=>{ (event)=>{
var path = event.urls[0].toString() var url = getUrlByEvent(event)
loader.source = path if(url !== ""){
watcher.path = path loader.source = url
loader.reload() watcher.path = url
loader.reload()
}
} }
} }
} }
function getUrlByEvent(event){
var url = ""
if (event.urls.length === 0) {
url = "file:///"+event.getDataAsString("text/plain")
}else{
url = event.urls[0].toString()
}
return url
}
} }

View File

@ -18,21 +18,24 @@ FluWindow {
title: "FluentUI" title: "FluentUI"
width: 1000 width: 1000
height: 640 height: 640
closeDestory:false
minimumWidth: 520 minimumWidth: 520
minimumHeight: 200 minimumHeight: 200
launchMode: FluWindowType.SingleTask launchMode: FluWindowType.SingleTask
appBar: undefined fitsAppBarWindows: true
appBar: FluAppBar {
width: window.width
height: 30
darkText: Lang.dark_mode
showDark: true
darkClickListener:(button)=>handleDarkChanged(button)
closeClickListener: ()=>{dialog_close.open()}
z:7
}
SettingsViewModel{ SettingsViewModel{
id:viewmodel_settings id:viewmodel_settings
} }
closeListener:function(event){
dialog_close.open()
event.accepted = false
}
FluEvent{ FluEvent{
id:event_checkupdate id:event_checkupdate
name: "checkUpdate" name: "checkUpdate"
@ -41,9 +44,11 @@ FluWindow {
} }
} }
Component.onCompleted: { onFirstVisible: {
FluTools.setQuitOnLastWindowClosed(false)
tour.open() tour.open()
}
Component.onCompleted: {
checkUpdate(true) checkUpdate(true)
FluEventBus.registerEvent(event_checkupdate) FluEventBus.registerEvent(event_checkupdate)
} }
@ -88,7 +93,22 @@ FluWindow {
positiveText:"退出" positiveText:"退出"
neutralText:"取消" neutralText:"取消"
onPositiveClicked:{ onPositiveClicked:{
FluApp.exit() FluApp.exit(0)
}
}
Component{
id:nav_item_right_menu
FluMenu{
id:menu
width: 130
FluMenuItem{
text: "在独立窗口打开"
visible: true
onClicked: {
FluApp.navigate("/pageWindow",{title:modelData.title,url:modelData.url})
}
}
} }
} }
@ -115,18 +135,8 @@ FluWindow {
back: Item{ back: Item{
anchors.fill: flipable anchors.fill: flipable
visible: flipable.flipAngle !== 0 visible: flipable.flipAngle !== 0
FluAppBar {
anchors {
top: parent.top
left: parent.left
right: parent.right
}
darkText: Lang.dark_mode
showDark: true
z:7
darkClickListener:(button)=>handleDarkChanged(button)
}
Row{ Row{
id:layout_back_buttons
z:8 z:8
anchors{ anchors{
top: parent.top top: parent.top
@ -157,25 +167,13 @@ FluWindow {
id:loader id:loader
lazy: true lazy: true
anchors.fill: parent anchors.fill: parent
source: "https://zhu-zichu.gitee.io/Qt5_156_LieflatPage.qml" source: "https://zhu-zichu.gitee.io/Qt_163_LieflatPage.qml"
} }
} }
front: Item{ front: Item{
id:page_front id:page_front
visible: flipable.flipAngle !== 180 visible: flipable.flipAngle !== 180
anchors.fill: flipable anchors.fill: flipable
FluAppBar {
id:app_bar_front
anchors {
top: parent.top
left: parent.left
right: parent.right
}
darkText: Lang.dark_mode
showDark: true
darkClickListener:(button)=>handleDarkChanged(button)
z:7
}
FluNavigationView{ FluNavigationView{
property int clickCount: 0 property int clickCount: 0
id:nav_view id:nav_view
@ -212,7 +210,9 @@ FluWindow {
} }
Component.onCompleted: { Component.onCompleted: {
ItemsOriginal.navigationView = nav_view ItemsOriginal.navigationView = nav_view
ItemsOriginal.paneItemMenu = nav_item_right_menu
ItemsFooter.navigationView = nav_view ItemsFooter.navigationView = nav_view
ItemsFooter.paneItemMenu = nav_item_right_menu
setCurrentIndex(0) setCurrentIndex(0)
} }
} }
@ -235,7 +235,7 @@ FluWindow {
} }
} }
Loader{ FluLoader{
id:loader_reveal id:loader_reveal
anchors.fill: parent anchors.fill: parent
} }
@ -245,7 +245,7 @@ FluWindow {
} }
function handleDarkChanged(button){ function handleDarkChanged(button){
if(FluTools.isMacos() || !FluTheme.enableAnimation){ if(!FluTheme.enableAnimation || window.fitsAppBarWindows === false){
changeDark() changeDark()
}else{ }else{
loader_reveal.sourceComponent = com_reveal loader_reveal.sourceComponent = com_reveal
@ -287,14 +287,14 @@ FluWindow {
FluTour{ FluTour{
id:tour id:tour
steps:[ steps:{
{title:"夜间模式",description: "这里可以切换夜间模式.",target:()=>app_bar_front.darkButton()}, var data = []
{title:"隐藏彩蛋",description: "多点几下试试!!",target:()=>nav_view.logoButton()} if(!window.useSystemAppBar){
] data.push({title:"夜间模式",description: "这里可以切换夜间模式.",target:()=>appBar.darkButton()})
} }
data.push({title:"隐藏彩蛋",description: "多点几下试试!!",target:()=>nav_view.logoButton()})
FluHttp{ return data
id:http }
} }
FpsItem{ FpsItem{
@ -326,7 +326,7 @@ FluWindow {
} }
} }
HttpCallable{ FluNetworkCallable{
id:callable id:callable
property bool silent: true property bool silent: true
onStart: { onStart: {
@ -362,8 +362,8 @@ FluWindow {
function checkUpdate(silent){ function checkUpdate(silent){
callable.silent = silent callable.silent = silent
var request = http.newRequest("https://api.github.com/repos/zhuzichu520/FluentUI/releases/latest") FluNetwork.get("https://api.github.com/repos/zhuzichu520/FluentUI/releases/latest")
http.get(request,callable); .go(callable)
} }
} }

View File

@ -19,7 +19,7 @@ FluWindow {
window.title = arg.title window.title = arg.title
loader.setSource( arg.url,{animDisabled:true}) loader.setSource( arg.url,{animDisabled:true})
} }
Loader{ FluLoader{
id: loader id: loader
anchors.fill: parent anchors.fill: parent
} }

View File

@ -19,10 +19,10 @@ void SettingsHelper::save(const QString& key,QVariant val)
m_settings->setValue(key, data); m_settings->setValue(key, data);
} }
QVariant SettingsHelper::get(const QString& key){ QVariant SettingsHelper::get(const QString& key,QVariant def){
const QByteArray data = m_settings->value(key).toByteArray(); const QByteArray data = m_settings->value(key).toByteArray();
if (data.isEmpty()) { if (data.isEmpty()) {
return {}; return def;
} }
QDataStream stream(data); QDataStream stream(data);
stream.setVersion(QDataStream::Qt_5_6); stream.setVersion(QDataStream::Qt_5_6);

View File

@ -19,15 +19,17 @@ public:
SINGLETONG(SettingsHelper) SINGLETONG(SettingsHelper)
~SettingsHelper() override; ~SettingsHelper() override;
void init(char *argv[]); void init(char *argv[]);
Q_INVOKABLE void saveRender(const QString& render){save("render",render);} Q_INVOKABLE void saveRender(const QVariant& render){save("render",render);}
Q_INVOKABLE QString getRender(){return get("render").toString();} Q_INVOKABLE QVariant getRender(){return get("render");}
Q_INVOKABLE void saveDarkMode(int darkModel){save("darkMode",darkModel);} Q_INVOKABLE void saveDarkMode(int darkModel){save("darkMode",darkModel);}
Q_INVOKABLE int getDarkMode(){return get("darkMode").toInt(0);} Q_INVOKABLE QVariant getDarkMode(){return get("darkMode",QVariant(0));}
Q_INVOKABLE void saveVsync(bool vsync){save("vsync",vsync);} Q_INVOKABLE void saveVsync(bool vsync){save("vsync",vsync);}
Q_INVOKABLE bool getVsync(){return get("vsync").toBool();} Q_INVOKABLE QVariant getVsync(){return get("vsync",QVariant(true));}
Q_INVOKABLE void saveUseSystemAppBar(bool useSystemAppBar){save("useSystemAppBar",useSystemAppBar);}
Q_INVOKABLE QVariant getUseSystemAppBar(){return get("useSystemAppBar",QVariant(false));}
private: private:
void save(const QString& key,QVariant val); void save(const QString& key,QVariant val);
QVariant get(const QString& key); QVariant get(const QString& key,QVariant def={});
private: private:
QScopedPointer<QSettings> m_settings; QScopedPointer<QSettings> m_settings;
}; };

View File

@ -14,7 +14,7 @@ Q_ENUM_NS(Scope)
QML_NAMED_ELEMENT(FluViewModelType) QML_NAMED_ELEMENT(FluViewModelType)
} }
namespace FluHttpType { namespace FluNetworkType {
Q_NAMESPACE Q_NAMESPACE
enum CacheMode { enum CacheMode {
NoCache = 0x0000, NoCache = 0x0000,
@ -23,7 +23,7 @@ enum CacheMode {
FirstCacheThenRequest = 0x0004, FirstCacheThenRequest = 0x0004,
}; };
Q_ENUM_NS(CacheMode) Q_ENUM_NS(CacheMode)
QML_NAMED_ELEMENT(FluHttpType) QML_NAMED_ELEMENT(FluNetworkType)
} }
namespace FluScreenshotType { namespace FluScreenshotType {

View File

@ -14,26 +14,19 @@
FRAMELESSHELPER_USE_NAMESPACE FRAMELESSHELPER_USE_NAMESPACE
FluApp::FluApp(QObject *parent):QObject{parent}{ FluApp::FluApp(QObject *parent):QObject{parent}{
vsync(false); connect(this,&FluApp::useSystemAppBarChanged,this,[=]{FramelessConfig::instance()->set(Global::Option::UseSystemAppBar,_useSystemAppBar);});
httpInterceptor(nullptr); vsync(true);
useSystemAppBar(false);
} }
FluApp::~FluApp(){ FluApp::~FluApp(){
} }
void FluApp::init(QQuickWindow *window){ void FluApp::init(QObject *application){
this->_application = window; this->_application = application;
FramelessHelper::Quick::initialize(); FramelessHelper::Quick::initialize();
FramelessConfig::instance()->set(Global::Option::DisableLazyInitializationForMicaMaterial); FramelessConfig::instance()->set(Global::Option::DisableLazyInitializationForMicaMaterial);
FramelessConfig::instance()->set(Global::Option::CenterWindowBeforeShow); FramelessConfig::instance()->set(Global::Option::CenterWindowBeforeShow);
FramelessConfig::instance()->set(Global::Option::ForceNonNativeBackgroundBlur);
FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow);
#ifdef Q_OS_WIN
FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow,false);
#endif
#ifdef Q_OS_MACOS
FramelessConfig::instance()->set(Global::Option::ForceNonNativeBackgroundBlur,false);
#endif
QQmlEngine *engine = qmlEngine(_application); QQmlEngine *engine = qmlEngine(_application);
FramelessHelper::Quick::registerTypes(engine); FramelessHelper::Quick::registerTypes(engine);
} }
@ -88,6 +81,7 @@ void FluApp::navigate(const QString& route,const QJsonObject& argument,FluRegist
void FluApp::exit(int retCode){ void FluApp::exit(int retCode){
for (const auto& pair : _windows.toStdMap()) { for (const auto& pair : _windows.toStdMap()) {
pair.second->close();
removeWindow(pair.second); removeWindow(pair.second);
} }
qApp->exit(retCode); qApp->exit(retCode);

View File

@ -9,7 +9,6 @@
#include <QJsonObject> #include <QJsonObject>
#include <QQmlEngine> #include <QQmlEngine>
#include "FluRegister.h" #include "FluRegister.h"
#include "FluHttpInterceptor.h"
#include "stdafx.h" #include "stdafx.h"
#include "singleton.h" #include "singleton.h"
@ -22,7 +21,7 @@ class FluApp : public QObject
Q_PROPERTY_AUTO(bool,vsync) Q_PROPERTY_AUTO(bool,vsync)
Q_PROPERTY_AUTO(QString,initialRoute); Q_PROPERTY_AUTO(QString,initialRoute);
Q_PROPERTY_AUTO(QJsonObject,routes); Q_PROPERTY_AUTO(QJsonObject,routes);
Q_PROPERTY_AUTO(FluHttpInterceptor*,httpInterceptor); Q_PROPERTY_AUTO(bool,useSystemAppBar);
QML_NAMED_ELEMENT(FluApp) QML_NAMED_ELEMENT(FluApp)
QML_SINGLETON QML_SINGLETON
private: private:
@ -33,13 +32,13 @@ public:
static FluApp *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return getInstance();} static FluApp *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return getInstance();}
Q_INVOKABLE void run(); Q_INVOKABLE void run();
Q_INVOKABLE void navigate(const QString& route,const QJsonObject& argument = {},FluRegister* fluRegister = nullptr); Q_INVOKABLE void navigate(const QString& route,const QJsonObject& argument = {},FluRegister* fluRegister = nullptr);
Q_INVOKABLE void init(QQuickWindow *window); Q_INVOKABLE void init(QObject *window);
Q_INVOKABLE void exit(int retCode = 0); Q_INVOKABLE void exit(int retCode = 0);
void addWindow(QQuickWindow* window); void addWindow(QQuickWindow* window);
void removeWindow(QQuickWindow* window); void removeWindow(QQuickWindow* window);
private: private:
QMap<quint64, QQuickWindow*> _windows; QMap<quint64, QQuickWindow*> _windows;
QWindow* _application; QObject* _application;
}; };
#endif // FLUAPP_H #endif // FLUAPP_H

View File

@ -1,681 +0,0 @@
#include "FluHttp.h"
#include <QThreadPool>
#include <QEventLoop>
#include <QNetworkReply>
#include <QUrlQuery>
#include <QHttpMultiPart>
#include <QGuiApplication>
#include <QJsonDocument>
#include <QStandardPaths>
#include <QTextStream>
#include <QDir>
#include "Def.h"
#include "FluApp.h"
#include "FluTools.h"
HttpRequest::HttpRequest(QObject *parent):QObject{parent}{
}
QMap<QString, QVariant> HttpRequest::toMap(){
QVariant _params;
bool isPostString = method() == "postString";
if(params().isNull()){
if(isPostString){
_params = "";
}else{
_params = QMap<QString,QVariant>();
}
}else{
_params = params();
}
QVariant _headers;
if(headers().isNull()){
_headers = QMap<QString,QVariant>();
}else{
_headers = headers();
}
QMap<QString, QVariant> request = {
{"url",url()},
{"headers",_headers.toMap()},
{"method",method()},
{"downloadSavePath",downloadSavePath()}
};
if(isPostString){
request.insert("params",_params.toString());
}else{
request.insert("params",_params.toMap());
}
return request;
}
QString HttpRequest::httpId(){
return FluTools::getInstance()->sha256(QJsonDocument::fromVariant(QVariant(toMap())).toJson(QJsonDocument::Compact));
}
HttpCallable::HttpCallable(QObject *parent):QObject{parent}{
}
FluHttp::FluHttp(QObject *parent):QObject{parent}{
retry(3);
timeout(15000);
cacheMode(FluHttpType::CacheMode::NoCache);
cacheDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)+"/httpcache");
breakPointDownload(false);
}
FluHttp::~FluHttp(){
cancel();
}
void FluHttp::cancel(){
foreach (QPointer<QNetworkReply> item, _cacheReply) {
if(item){
item->abort();
}
}
}
void FluHttp::post(HttpRequest* r,HttpCallable* c){
auto request = QPointer(r);
auto callable = QPointer(c);
request->method("post");
auto requestMap = request->toMap();
auto httpId = request->httpId();
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
QThreadPool::globalInstance()->start([=](){
onStart(callable);
if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(httpId)){
onCache(callable,readCache(httpId));
onFinish(callable,request);
return;
}
if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest && cacheExists(httpId)){
onCache(callable,readCache(httpId));
}
QNetworkAccessManager manager;
manager.setTransferTimeout(timeout());
for (int i = 0; i < retry(); ++i) {
QUrl url(request->url());
QNetworkRequest req(url);
addHeaders(&req,data["headers"].toMap());
QHttpMultiPart multiPart(QHttpMultiPart::FormDataType);
for (const auto& each : data["params"].toMap().toStdMap())
{
const QString& key = each.first;
const QString& value = each.second.toString();
QString dispositionHeader = QString("form-data; name=\"%1\"").arg(key);
QHttpPart part;
part.setHeader(QNetworkRequest::ContentDispositionHeader, dispositionHeader);
part.setBody(value.toUtf8());
multiPart.append(part);
}
QNetworkReply* reply = manager.post(req,&multiPart);
if(!QPointer(qApp)){
reply->deleteLater();
reply = nullptr;
return;
}
_cacheReply.append(reply);
QEventLoop loop;
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
loop.exec();
QString result = QString::fromUtf8(reply->readAll());
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString errorString = reply->errorString();
QNetworkReply::NetworkError error = reply->error();
bool isSuccess = error == QNetworkReply::NoError;
reply->deleteLater();
reply = nullptr;
if (isSuccess) {
handleCache(httpId,result);
onSuccess(callable,result);
break;
}else{
if(i == retry()-1){
if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache && cacheExists(httpId)){
onCache(callable,readCache(httpId));
}
onError(callable,status,errorString,result);
}
}
if(error == QNetworkReply::OperationCanceledError){
break;
}
}
onFinish(callable,request);
});
}
void FluHttp::postString(HttpRequest* r,HttpCallable* c){
auto request = QPointer(r);
auto callable = QPointer(c);
request->method("postString");
auto requestMap = request->toMap();
auto httpId = request->httpId();
QString params = request->params().toString();
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
QThreadPool::globalInstance()->start([=](){
onStart(callable);
if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(httpId)){
onCache(callable,readCache(httpId));
onFinish(callable,request);
return;
}
if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest && cacheExists(httpId)){
onCache(callable,readCache(httpId));
}
QNetworkAccessManager manager;
manager.setTransferTimeout(timeout());
for (int i = 0; i < retry(); ++i) {
QUrl url(request->url());
QNetworkRequest req(url);
addHeaders(&req,data["headers"].toMap());
QString contentType = QString("text/plain;charset=utf-8");
req.setHeader(QNetworkRequest::ContentTypeHeader, contentType);
QNetworkReply* reply = manager.post(req,params.toUtf8());
if(!QPointer(qApp)){
reply->deleteLater();
reply = nullptr;
return;
}
_cacheReply.append(reply);
QEventLoop loop;
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
loop.exec();
QString result = QString::fromUtf8(reply->readAll());
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString errorString = reply->errorString();
QNetworkReply::NetworkError error = reply->error();
bool isSuccess = error == QNetworkReply::NoError;
reply->deleteLater();
reply = nullptr;
if (isSuccess) {
handleCache(httpId,result);
onSuccess(callable,result);
break;
}else{
if(i == retry()-1){
if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache && cacheExists(httpId)){
onCache(callable,readCache(httpId));
}
onError(callable,status,errorString,result);
}
}
if(error == QNetworkReply::OperationCanceledError){
break;
}
}
onFinish(callable,request);
});
}
void FluHttp::postJson(HttpRequest* r,HttpCallable* c){
auto request = QPointer(r);
auto callable = QPointer(c);
request->method("postJson");
auto requestMap = request->toMap();
auto httpId = request->httpId();
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
QThreadPool::globalInstance()->start([=](){
onStart(callable);
if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(httpId)){
onCache(callable,readCache(httpId));
onFinish(callable,request);
return;
}
if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest && cacheExists(httpId)){
onCache(callable,readCache(httpId));
}
QNetworkAccessManager manager;
manager.setTransferTimeout(timeout());
for (int i = 0; i < retry(); ++i) {
QUrl url(request->url());
QNetworkRequest req(url);
addHeaders(&req,data["headers"].toMap());
QString contentType = QString("application/json;charset=utf-8");
req.setHeader(QNetworkRequest::ContentTypeHeader, contentType);
QNetworkReply* reply = manager.post(req,QJsonDocument::fromVariant(data["params"]).toJson());
if(!QPointer(qApp)){
reply->deleteLater();
reply = nullptr;
return;
}
_cacheReply.append(reply);
QEventLoop loop;
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
loop.exec();
QString result = QString::fromUtf8(reply->readAll());
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString errorString = reply->errorString();
QNetworkReply::NetworkError error = reply->error();
bool isSuccess = error == QNetworkReply::NoError;
reply->deleteLater();
reply = nullptr;
if (isSuccess) {
handleCache(httpId,result);
onSuccess(callable,result);
break;
}else{
if(i == retry()-1){
if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache && cacheExists(httpId)){
onCache(callable,readCache(httpId));
}
onError(callable,status,errorString,result);
}
}
if(error == QNetworkReply::OperationCanceledError){
break;
}
}
onFinish(callable,request);
});
}
void FluHttp::get(HttpRequest* r,HttpCallable* c){
auto request = QPointer(r);
auto callable = QPointer(c);
request->method("get");
auto requestMap = request->toMap();
auto httpId = request->httpId();
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
QThreadPool::globalInstance()->start([=](){
onStart(callable);
if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest && cacheExists(httpId)){
onCache(callable,readCache(httpId));
}
if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(httpId)){
onCache(callable,readCache(httpId));
onFinish(callable,request);
return;
}
QNetworkAccessManager manager;
manager.setTransferTimeout(timeout());
for (int i = 0; i < retry(); ++i) {
QUrl url(request->url());
addQueryParam(&url,data["params"].toMap());
QNetworkRequest req(url);
addHeaders(&req,data["headers"].toMap());
QNetworkReply* reply = manager.get(req);
if(!QPointer(qApp)){
reply->deleteLater();
reply = nullptr;
return;
}
_cacheReply.append(reply);
QEventLoop loop;
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
loop.exec();
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString errorString = reply->errorString();
QNetworkReply::NetworkError error = reply->error();
bool isSuccess = error == QNetworkReply::NoError;
QString result = QString::fromUtf8(reply->readAll());
if (isSuccess) {
handleCache(httpId,result);
onSuccess(callable,result);
break;
}else{
if(i == retry()-1){
if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache && cacheExists(httpId)){
onCache(callable,readCache(httpId));
}
onError(callable,status,errorString,result);
}
}
reply->deleteLater();
reply = nullptr;
if(error == QNetworkReply::OperationCanceledError){
break;
}
}
onFinish(callable,request);
});
}
void FluHttp::download(HttpRequest* r,HttpCallable* c){
auto request = QPointer(r);
auto callable = QPointer(c);
request->method("download");
auto requestMap = request->toMap();
auto httpId = request->httpId();
auto savePath = request->downloadSavePath();
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
QThreadPool::globalInstance()->start([=](){
onStart(callable);
QNetworkAccessManager manager;
QUrl url(request->url());
addQueryParam(&url,data["params"].toMap());
QNetworkRequest req(url);
addHeaders(&req,data["headers"].toMap());
QSharedPointer<QFile> file(new QFile(savePath));
QDir dir = QFileInfo(savePath).path();
if (!dir.exists(dir.path())){
dir.mkpath(dir.path());
}
qint64 seek = 0;
auto filePath = getCacheFilePath(httpId);
QSharedPointer<QFile> fileCache(new QFile(filePath));
if(fileCache->exists() && file->exists() && _breakPointDownload){
QJsonObject cacheInfo = QJsonDocument::fromJson(readCache(httpId).toUtf8()).object();
qint64 fileSize = cacheInfo.value("fileSize").toDouble();
qint64 contentLength = cacheInfo.value("contentLength").toDouble();
if(fileSize == contentLength && file->size() == contentLength){
onDownloadProgress(callable,fileSize,contentLength);
onSuccess(callable,savePath);
onFinish(callable,request);
return;
}
if(fileSize==file->size()){
req.setRawHeader("Range", QString("bytes=%1-").arg(fileSize).toUtf8());
seek = fileSize;
file->open(QIODevice::WriteOnly|QIODevice::Append);
}else{
file->open(QIODevice::WriteOnly|QIODevice::Truncate);
}
}else{
file->open(QIODevice::WriteOnly|QIODevice::Truncate);
}
QNetworkReply* reply = manager.get(req);
if(!QPointer(qApp)){
reply->deleteLater();
reply = nullptr;
return;
}
_cacheReply.append(reply);
QEventLoop loop;
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
if (!fileCache->open(QIODevice::WriteOnly|QIODevice::Truncate))
{
qDebug()<<"FileCache Error";
}
connect(reply,&QNetworkReply::readyRead,reply,[reply,file,fileCache,requestMap,callable,seek,this]{
if (!reply || !file || reply->error() != QNetworkReply::NoError)
{
return;
}
QMap<QString, QVariant> downMap = requestMap;
qint64 contentLength = reply->header(QNetworkRequest::ContentLengthHeader).toLongLong()+seek;
downMap.insert("contentLength",contentLength);
QString eTag = reply->header(QNetworkRequest::ETagHeader).toString();
downMap.insert("eTag",eTag);
file->write(reply->readAll());
file->flush();
downMap.insert("fileSize",file->size());
fileCache->resize(0);
fileCache->write(FluTools::getInstance()->toBase64(QJsonDocument::fromVariant(QVariant(downMap)).toJson()).toUtf8());
fileCache->flush();
onDownloadProgress(callable,file->size(),contentLength);
});
loop.exec();
if (reply->error() == QNetworkReply::NoError) {
onSuccess(callable,savePath);
}else{
onError(callable,reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(),reply->errorString(),"");
}
reply->deleteLater();
reply = nullptr;
onFinish(callable,request);
});
}
void FluHttp::upload(HttpRequest* request,HttpCallable* callable){
request->method("upload");
auto requestMap = request->toMap();
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
QThreadPool::globalInstance()->start([=](){
onStart(callable);
QNetworkAccessManager manager;
manager.setTransferTimeout(timeout());
QUrl url(request->url());
QNetworkRequest req(url);
addHeaders(&req,data["headers"].toMap());
QHttpMultiPart multiPart(QHttpMultiPart::FormDataType);
for (const auto& each : data["params"].toMap().toStdMap())
{
const QString& key = each.first;
const QString& filePath = each.second.toString();
QFile *file = new QFile(filePath);
file->open(QIODevice::ReadOnly);
file->setParent(&multiPart);
QString dispositionHeader = QString("form-data; name=\"%1\"; filename=\"%2\"").arg(key,filePath);
QHttpPart part;
part.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
part.setHeader(QNetworkRequest::ContentDispositionHeader, dispositionHeader);
part.setBodyDevice(file);
multiPart.append(part);
}
QNetworkReply* reply = manager.post(req,&multiPart);
if(!QPointer(qApp)){
reply->deleteLater();
reply = nullptr;
return;
}
_cacheReply.append(reply);
QEventLoop loop;
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
connect(reply,&QNetworkReply::uploadProgress,reply,[=](qint64 bytesSent, qint64 bytesTotal){
onUploadProgress(callable,bytesSent,bytesTotal);
});
loop.exec();
QString result = QString::fromUtf8(reply->readAll());
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString errorString = reply->errorString();
bool isSuccess = reply->error() == QNetworkReply::NoError;
reply->deleteLater();
reply = nullptr;
if (isSuccess) {
onSuccess(callable,result);
}else{
onError(callable,status,errorString,result);
}
onFinish(callable,request);
});
}
void FluHttp::deleteResource(HttpRequest* request,HttpCallable* callable)
{
request->method("deleteResource");
auto requestMap = request->toMap();
auto httpId = request->httpId();
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
QThreadPool::globalInstance()->start([=](){
onStart(callable);
if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest && cacheExists(httpId)){
onCache(callable,readCache(httpId));
}
if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(httpId)){
onCache(callable,readCache(httpId));
onFinish(callable,request);
return;
}
QNetworkAccessManager manager;
manager.setTransferTimeout(timeout());
for (int i = 0; i < retry(); ++i) {
QUrl url(request->url());
addQueryParam(&url,data["params"].toMap());
QNetworkRequest req(url);
addHeaders(&req,data["headers"].toMap());
QEventLoop loop;
QNetworkReply* reply = manager.deleteResource(req);
_cacheReply.append(reply);
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop](){loop.quit();});
loop.exec();
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString errorString = reply->errorString();
bool isSuccess = reply->error() == QNetworkReply::NoError;
QString result = QString::fromUtf8(reply->readAll());
if (isSuccess) {
handleCache(httpId,result);
onSuccess(callable,result);
break;
}else{
if(i == retry()-1){
if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache && cacheExists(httpId)){
onCache(callable,readCache(httpId));
}
onError(callable,status,errorString,result);
}
}
QNetworkReply::NetworkError error = reply->error();
if(error == QNetworkReply::OperationCanceledError){
break;
}
reply->deleteLater();
reply = nullptr;
}
onFinish(callable,request);
});
}
QVariant FluHttp::invokeIntercept(QMap<QString, QVariant> request){
if(!FluApp::getInstance()->httpInterceptor()){
return request;
}
QVariant target;
QMetaObject::invokeMethod(FluApp::getInstance()->httpInterceptor(), "onIntercept",Q_RETURN_ARG(QVariant,target),Q_ARG(QVariant, request));
return target;
}
void FluHttp::addQueryParam(QUrl* url,const QMap<QString, QVariant>& params){
QMapIterator<QString, QVariant> iter(params);
QUrlQuery urlQuery(*url);
while (iter.hasNext())
{
iter.next();
urlQuery.addQueryItem(iter.key(), iter.value().toString());
}
url->setQuery(urlQuery);
}
void FluHttp::addHeaders(QNetworkRequest* request,const QMap<QString, QVariant>& headers){
QMapIterator<QString, QVariant> iter(headers);
while (iter.hasNext())
{
iter.next();
request->setRawHeader(iter.key().toUtf8(), iter.value().toString().toUtf8());
}
}
QString FluHttp::readCache(const QString& httpId){
auto filePath = getCacheFilePath(httpId);
QString result;
QFile file(filePath);
if(!file.exists()){
return result;
}
if (file.open(QIODevice::ReadOnly)) {
QTextStream stream(&file);
result = FluTools::getInstance()->fromBase64(stream.readAll().toUtf8());
}
return result;
}
bool FluHttp::cacheExists(const QString& httpId){
return QFile(getCacheFilePath(httpId)).exists();
}
QString FluHttp::getCacheFilePath(const QString& httpId){
QString path = FluTools::getInstance()->toLocalPath(QUrl(_cacheDir));
QDir dir = path;
if (!dir.exists(path)){
dir.mkpath(path);
}
auto filePath = path+"/"+httpId;
return filePath;
}
void FluHttp::handleCache(const QString& httpId,const QString& result){
if(_cacheMode==FluHttpType::CacheMode::NoCache){
return;
}
auto filePath = getCacheFilePath(httpId);
QSharedPointer<QFile> file(new QFile(filePath));
QIODevice::OpenMode mode = QIODevice::WriteOnly|QIODevice::Truncate;
if (!file->open(mode))
{
return;
}
file->write(FluTools::getInstance()->toBase64(result).toUtf8());
}
qreal FluHttp::getBreakPointProgress(HttpRequest* request){
request->method("download");
auto httpId = request->httpId();
QSharedPointer<QFile> file(new QFile(request->downloadSavePath()));
auto filePath = getCacheFilePath(httpId);
QSharedPointer<QFile> fileCache(new QFile(filePath));
if(fileCache->exists() && file->exists() && _breakPointDownload){
QJsonObject cacheInfo = QJsonDocument::fromJson(readCache(httpId).toUtf8()).object();
double fileSize = cacheInfo.value("fileSize").toDouble();
double contentLength = cacheInfo.value("contentLength").toDouble();
if(fileSize == contentLength && file->size() == contentLength){
return 1;
}
if(fileSize==file->size()){
return fileSize/contentLength;
}else{
return 0;
}
}else{
return 0;
}
}
HttpRequest* FluHttp::newRequest(QString url){
HttpRequest* request = new HttpRequest(this);
request->url(url);
return request;
}
void FluHttp::onStart(QPointer<HttpCallable> callable){
if(callable){
Q_EMIT callable->start();
}
}
void FluHttp::onFinish(QPointer<HttpCallable> callable,QPointer<HttpRequest> request){
if(callable){
Q_EMIT callable->finish();
}
if(request&&request->parent()->inherits("FluHttp")){
request->deleteLater();
}
}
void FluHttp::onError(QPointer<HttpCallable> callable,int status,QString errorString,QString result){
if(callable){
Q_EMIT callable->error(status,errorString,result);
}
}
void FluHttp::onSuccess(QPointer<HttpCallable> callable,QString result){
if(callable){
Q_EMIT callable->success(result);
}
}
void FluHttp::onCache(QPointer<HttpCallable> callable,QString result){
if(callable){
Q_EMIT callable->cache(result);
}
}
void FluHttp::onDownloadProgress(QPointer<HttpCallable> callable,qint64 recv,qint64 total){
if(callable){
Q_EMIT callable->downloadProgress(recv,total);
}
}
void FluHttp::onUploadProgress(QPointer<HttpCallable> callable,qint64 sent,qint64 total){
if(callable){
Q_EMIT callable->uploadProgress(sent,total);
}
}

View File

@ -1,79 +0,0 @@
#ifndef FLUHTTP_H
#define FLUHTTP_H
#include <QObject>
#include <QtQml/qqml.h>
#include <QFile>
#include <QNetworkAccessManager>
#include "stdafx.h"
class HttpRequest : public QObject{
Q_OBJECT
Q_PROPERTY_AUTO(QString,url);
Q_PROPERTY_AUTO(QVariant,params);
Q_PROPERTY_AUTO(QVariant,headers);
Q_PROPERTY_AUTO(QString,method);
Q_PROPERTY_AUTO(QString,downloadSavePath);
QML_NAMED_ELEMENT(HttpRequest)
public:
explicit HttpRequest(QObject *parent = nullptr);
QMap<QString, QVariant> toMap();
Q_INVOKABLE QString httpId();
};
class HttpCallable : public QObject{
Q_OBJECT
QML_NAMED_ELEMENT(HttpCallable)
public:
explicit HttpCallable(QObject *parent = nullptr);
Q_SIGNAL void start();
Q_SIGNAL void finish();
Q_SIGNAL void error(int status,QString errorString,QString result);
Q_SIGNAL void success(QString result);
Q_SIGNAL void cache(QString result);
Q_SIGNAL void downloadProgress(qint64 recv, qint64 total);
Q_SIGNAL void uploadProgress(qint64 sent, qint64 total);
};
class FluHttp : public QObject
{
Q_OBJECT
Q_PROPERTY_AUTO(int,retry);
Q_PROPERTY_AUTO(int,timeout)
Q_PROPERTY_AUTO(int,cacheMode);
Q_PROPERTY_AUTO(QString,cacheDir);
Q_PROPERTY_AUTO(bool,breakPointDownload);
QML_NAMED_ELEMENT(FluHttp)
private:
QVariant invokeIntercept(QMap<QString, QVariant> request);
void addQueryParam(QUrl* url,const QMap<QString, QVariant>& params);
void addHeaders(QNetworkRequest* request,const QMap<QString, QVariant>& params);
void handleCache(const QString& httpId, const QString& result);
QString readCache(const QString& httpId);
bool cacheExists(const QString& httpId);
QString getCacheFilePath(const QString& httpId);
void onStart(QPointer<HttpCallable> callable);
void onFinish(QPointer<HttpCallable> callable,QPointer<HttpRequest> request);
void onError(QPointer<HttpCallable> callable,int status,QString errorString,QString result);
void onSuccess(QPointer<HttpCallable> callable,QString result);
void onCache(QPointer<HttpCallable> callable,QString result);
void onDownloadProgress(QPointer<HttpCallable> callable,qint64 recv,qint64 total);
void onUploadProgress(QPointer<HttpCallable> callable,qint64 sent,qint64 total);
public:
explicit FluHttp(QObject *parent = nullptr);
~FluHttp();
Q_INVOKABLE HttpRequest* newRequest(QString url = "");
Q_INVOKABLE void get(HttpRequest* request,HttpCallable* callable);
Q_INVOKABLE void post(HttpRequest* request,HttpCallable* callable);
Q_INVOKABLE void postString(HttpRequest* request,HttpCallable* callable);
Q_INVOKABLE void postJson(HttpRequest* request,HttpCallable* callable);
Q_INVOKABLE void download(HttpRequest* request,HttpCallable* callable);
Q_INVOKABLE void upload(HttpRequest* request,HttpCallable* callable);
Q_INVOKABLE void deleteResource(HttpRequest* request,HttpCallable* callable);
Q_INVOKABLE qreal getBreakPointProgress(HttpRequest* request);
Q_INVOKABLE void cancel();
private:
QList<QPointer<QNetworkReply>> _cacheReply;
};
#endif // FLUHTTP_H

View File

@ -1,4 +0,0 @@
#include "FluHttpInterceptor.h"
FluHttpInterceptor::FluHttpInterceptor(QObject *parent):QObject{parent}{
}

View File

@ -1,15 +0,0 @@
#ifndef FLUHTTPINTERCEPTOR_H
#define FLUHTTPINTERCEPTOR_H
#include <QObject>
#include <QtQml/qqml.h>
class FluHttpInterceptor : public QObject
{
Q_OBJECT
QML_NAMED_ELEMENT(FluHttpInterceptor)
public:
explicit FluHttpInterceptor(QObject *parent = nullptr);
};
#endif // FLUHTTPINTERCEPTOR_H

574
src/FluNetwork.cpp Normal file
View File

@ -0,0 +1,574 @@
#include "FluNetwork.h"
#include <QUrlQuery>
#include <QBuffer>
#include <QHttpMultiPart>
#include <QJsonDocument>
#include <QNetworkReply>
#include <QJsonObject>
#include <QNetworkDiskCache>
#include <QQmlEngine>
#include <QQmlContext>
#include <QJSEngine>
#include <QJsonArray>
#include <QStandardPaths>
#include <QThreadPool>
#include <QDir>
#include <QEventLoop>
#include <QGuiApplication>
NetworkCallable::NetworkCallable(QObject *parent):QObject{parent}{
}
QString NetworkParams::method2String(){
switch (_method) {
case METHOD_GET:
return "GET";
case METHOD_HEAD:
return "HEAD";
case METHOD_POST:
return "POST";
case METHOD_PUT:
return "PUT";
case METHOD_PATCH:
return "PATCH";
case METHOD_DELETE:
return "DELETE";
default:
return "";
}
}
int NetworkParams::getTimeout(){
if(_timeout != -1){
return _timeout;
}
return FluNetwork::getInstance()->timeout();
}
int NetworkParams::getRetry(){
if(_retry != -1){
return _retry;
}
return FluNetwork::getInstance()->retry();
}
DownloadParam::DownloadParam(QObject *parent)
: QObject{parent}
{
}
DownloadParam::DownloadParam(QString destPath,bool append,QObject *parent)
: QObject{parent}
{
this->_destPath = destPath;
this->_append = append;
}
NetworkParams::NetworkParams(QObject *parent)
: QObject{parent}
{
}
NetworkParams::NetworkParams(QString url,Type type,Method method,QObject *parent)
: QObject{parent}
{
this->_method = method;
this->_url = url;
this->_type = type;
}
NetworkParams* NetworkParams::add(QString key,QVariant val){
_paramMap.insert(key,val);
return this;
}
NetworkParams* NetworkParams::addFile(QString key,QVariant val){
_fileMap.insert(key,val);
return this;
}
NetworkParams* NetworkParams::addHeader(QString key,QVariant val){
_headerMap.insert(key,val);
return this;
}
NetworkParams* NetworkParams::addQuery(QString key,QVariant val){
_queryMap.insert(key,val);
return this;
}
NetworkParams* NetworkParams::setBody(QString val){
_body = val;
return this;
}
NetworkParams* NetworkParams::setTimeout(int val){
_timeout = val;
return this;
}
NetworkParams* NetworkParams::setRetry(int val){
_retry = val;
return this;
}
NetworkParams* NetworkParams::setCacheMode(int val){
_cacheMode = val;
return this;
}
NetworkParams* NetworkParams::toDownload(QString destPath,bool append){
_downloadParam = new DownloadParam(destPath,append,this);
return this;
}
NetworkParams* NetworkParams::bind(QObject* target){
_target = target;
return this;
}
QString NetworkParams::buildCacheKey(){
QJsonObject obj;
obj.insert("url",_url);
obj.insert("method",method2String());
obj.insert("body",_body);
obj.insert("query",QJsonDocument::fromVariant(_queryMap).object());
obj.insert("param",QJsonDocument::fromVariant(_paramMap).object());
obj.insert("header",QJsonDocument::fromVariant(_headerMap).object());
obj.insert("file",QJsonDocument::fromVariant(_fileMap).object());
if(_downloadParam){
QJsonObject downObj;
downObj.insert("destPath",_downloadParam->_destPath);
downObj.insert("append",_downloadParam->_append);
obj.insert("download",downObj);
}
QByteArray data = QJsonDocument(obj).toJson(QJsonDocument::Compact);
return QCryptographicHash::hash(data, QCryptographicHash::Sha256).toHex();
}
void NetworkParams::go(NetworkCallable* callable){
QJSValueList data;
data<<qjsEngine(FluNetwork::getInstance())->newQObject(this);
FluNetwork::getInstance()->_interceptor.call(data);
if(_downloadParam){
FluNetwork::getInstance()->handleDownload(this,callable);
}else{
FluNetwork::getInstance()->handle(this,callable);
}
}
void FluNetwork::handle(NetworkParams* params,NetworkCallable* c){
QPointer<NetworkCallable> callable(c);
QThreadPool::globalInstance()->start([=](){
if(!callable.isNull()){
callable->start();
}
QString cacheKey = params->buildCacheKey();
if(params->_cacheMode == FluNetworkType::CacheMode::FirstCacheThenRequest && cacheExists(cacheKey)){
if(!callable.isNull()){
callable->cache(readCache(cacheKey));
}
}
if(params->_cacheMode == FluNetworkType::CacheMode::IfNoneCacheRequest && cacheExists(cacheKey)){
if(!callable.isNull()){
callable->cache(readCache(cacheKey));
callable->finish();
params->deleteLater();
}
return;
}
QNetworkAccessManager manager;
manager.setTransferTimeout(params->getTimeout());
QEventLoop loop;
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
for (int i = 0; i < params->getRetry(); ++i) {
QUrl url(params->_url);
addQueryParam(&url,params->_queryMap);
QNetworkRequest request(url);
addHeaders(&request,params->_headerMap);
QNetworkReply* reply;
sendRequest(&manager,request,params,reply,callable);
if(!QPointer(qApp)){
reply->deleteLater();
reply = nullptr;
return;
}
auto abortCallable = [&loop,reply,&i,params]{
if(reply){
i = params->getRetry();
reply->abort();
}
};
QMetaObject::Connection conn_destoryed = {};
QMetaObject::Connection conn_quit = {};
if(params->_target){
conn_destoryed = connect(params->_target,&QObject::destroyed,&manager,abortCallable);
}
conn_quit = connect(qApp,&QGuiApplication::aboutToQuit,&manager, abortCallable);
loop.exec();
if(conn_destoryed){
disconnect(conn_destoryed);
}
if(conn_quit){
disconnect(conn_quit);
}
QString response;
if(reply->isOpen()){
response = QString::fromUtf8(reply->readAll());
}
QNetworkReply::NetworkError error = reply->error();
if(error == QNetworkReply::NoError){
if(!callable.isNull()){
if(params->_cacheMode != FluNetworkType::CacheMode::NoCache){
saveResponse(cacheKey,response);
}
callable->success(response);
}
break;
}else{
if(i == params->getRetry()-1){
if(!callable.isNull()){
int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if(params->_cacheMode == FluNetworkType::CacheMode::RequestFailedReadCache && cacheExists(cacheKey)){
if(!callable.isNull()){
callable->cache(readCache(cacheKey));
}
}
callable->error(httpStatus,reply->errorString(),response);
}
}
}
reply->deleteLater();
}
params->deleteLater();
if(!callable.isNull()){
callable->finish();
}
});
}
void FluNetwork::handleDownload(NetworkParams* params,NetworkCallable* c){
QPointer<NetworkCallable> callable(c);
QThreadPool::globalInstance()->start([=](){
if(!callable.isNull()){
callable->start();
}
QString cacheKey = params->buildCacheKey();
QUrl url(params->_url);
QNetworkAccessManager manager;
manager.setTransferTimeout(params->getTimeout());
addQueryParam(&url,params->_queryMap);
QNetworkRequest request(url);
addHeaders(&request,params->_headerMap);
QString cachePath = getCacheFilePath(cacheKey);
QString destPath = params->_downloadParam->_destPath;
QFile* destFile = new QFile(destPath);
QFile* cacheFile = new QFile(cachePath);
bool isOpen = false;
qint64 seek = 0;
if(cacheFile->exists() && destFile->exists() && params->_downloadParam->_append){
QJsonObject cacheInfo = QJsonDocument::fromJson(readCache(cacheKey).toUtf8()).object();
qint64 fileSize = cacheInfo.value("fileSize").toDouble();
qint64 contentLength = cacheInfo.value("contentLength").toDouble();
if(fileSize == contentLength && destFile->size() == contentLength){
if(!callable.isNull()){
callable->downloadProgress(fileSize,contentLength);
callable->success(destPath);
callable->finish();
}
return;
}
if(fileSize==destFile->size()){
request.setRawHeader("Range", QString("bytes=%1-").arg(fileSize).toUtf8());
seek = fileSize;
isOpen = destFile->open(QIODevice::WriteOnly|QIODevice::Append);
}else{
isOpen = destFile->open(QIODevice::WriteOnly|QIODevice::Truncate);
}
}else{
isOpen = destFile->open(QIODevice::WriteOnly|QIODevice::Truncate);
}
if(!isOpen){
if(!callable.isNull()){
callable->error(-1,"device not open","");
callable->finish();
}
return;
}
if(params->_downloadParam->_append){
if (!cacheFile->open(QIODevice::WriteOnly|QIODevice::Truncate))
{
if(!callable.isNull()){
callable->error(-1,"cache file device not open","");
callable->finish();
}
return;
}
}
QEventLoop loop;
QNetworkReply *reply = manager.get(request);
destFile->setParent(reply);
cacheFile->setParent(reply);
auto abortCallable = [&loop,reply,params]{
if(reply){
reply->abort();
}
};
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
QMetaObject::Connection conn_destoryed = {};
QMetaObject::Connection conn_quit = {};
if(params->_target){
conn_destoryed = connect(params->_target,&QObject::destroyed,&manager,abortCallable);
}
conn_quit = connect(qApp,&QGuiApplication::aboutToQuit,&manager, abortCallable);
connect(reply,&QNetworkReply::readyRead,reply,[reply,seek,destFile,cacheFile,callable]{
if (!reply || !destFile || reply->error() != QNetworkReply::NoError)
{
return;
}
QMap<QString, QVariant> downInfo;
qint64 contentLength = reply->header(QNetworkRequest::ContentLengthHeader).toLongLong()+seek;
downInfo.insert("contentLength",contentLength);
QString eTag = reply->header(QNetworkRequest::ETagHeader).toString();
downInfo.insert("eTag",eTag);
destFile->write(reply->readAll());
destFile->flush();
downInfo.insert("fileSize",destFile->size());
if(cacheFile->isOpen()){
cacheFile->resize(0);
cacheFile->write(QJsonDocument::fromVariant(QVariant(downInfo)).toJson().toBase64());
cacheFile->flush();
}
if(!callable.isNull()){
callable->downloadProgress(destFile->size(),contentLength);
}
});
loop.exec();
if(conn_destoryed){
disconnect(conn_destoryed);
}
if(conn_quit){
disconnect(conn_quit);
}
params->deleteLater();
reply->deleteLater();
if(!callable.isNull()){
callable->finish();
}
});
}
QString FluNetwork::readCache(const QString& key){
auto filePath = getCacheFilePath(key);
QString result;
QFile file(filePath);
if(!file.exists()){
return result;
}
if (file.open(QIODevice::ReadOnly)) {
QTextStream stream(&file);
result = QString(QByteArray::fromBase64(stream.readAll().toUtf8()));
}
return result;
}
bool FluNetwork::cacheExists(const QString& key){
return QFile(getCacheFilePath(key)).exists();
}
QString FluNetwork::getCacheFilePath(const QString& key){
QDir cacheDir(_cacheDir);
if(!cacheDir.exists()){
cacheDir.mkpath(_cacheDir);
}
return cacheDir.absoluteFilePath(key);
}
void FluNetwork::sendRequest(QNetworkAccessManager* manager,QNetworkRequest request,NetworkParams* params,QNetworkReply*& reply,QPointer<NetworkCallable> callable){
QByteArray verb = params->method2String().toUtf8();
switch (params->_type) {
case NetworkParams::TYPE_FORM:{
QHttpMultiPart *multiPart = new QHttpMultiPart();
multiPart->setContentType(QHttpMultiPart::FormDataType);
for (const auto& each : params->_paramMap.toStdMap())
{
QHttpPart part;
part.setHeader(QNetworkRequest::ContentDispositionHeader, QString("form-data; name=\"%1\"").arg(each.first));
part.setBody(each.second.toByteArray());
multiPart->append(part);
}
for (const auto& each : params->_fileMap.toStdMap())
{
QString filePath = each.second.toString();
QString name = each.first;
QFile *file = new QFile(filePath);
QString fileName = QFileInfo(filePath).fileName();
file->open(QIODevice::ReadOnly);
file->setParent(multiPart);
QHttpPart part;
part.setHeader(QNetworkRequest::ContentDispositionHeader, QString("form-data; name=\"%1\"; filename=\"%2\"").arg(name,fileName));
part.setBodyDevice(file);
multiPart->append(part);
}
reply = manager->sendCustomRequest(request,verb,multiPart);
multiPart->setParent(reply);
if(!params->_fileMap.isEmpty()){
connect(reply,&QNetworkReply::uploadProgress,reply,[callable](qint64 bytesSent, qint64 bytesTotal){
if(!callable.isNull() && bytesSent!=0 && bytesTotal!=0){
callable->uploadProgress(bytesSent,bytesTotal);
}
});
}
break;
}
case NetworkParams::TYPE_JSON:{
request.setHeader(QNetworkRequest::ContentTypeHeader, QString("application/json;charset=utf-8"));
QJsonObject json;
for (const auto& each : params->_paramMap.toStdMap())
{
json.insert(each.first,each.second.toJsonValue());
}
QByteArray data = QJsonDocument(json).toJson(QJsonDocument::Compact);
reply = manager->sendCustomRequest(request,verb,data);
break;
}
case NetworkParams::TYPE_JSONARRAY:{
request.setHeader(QNetworkRequest::ContentTypeHeader, QString("application/json;charset=utf-8"));
QJsonArray jsonArray;
for (const auto& each : params->_paramMap.toStdMap())
{
QJsonObject json;
json.insert(each.first,each.second.toJsonValue());
jsonArray.append(json);
}
QByteArray data = QJsonDocument(jsonArray).toJson(QJsonDocument::Compact);
reply = manager->sendCustomRequest(request,params->method2String().toUtf8(),data);
break;
}
case NetworkParams::TYPE_BODY:{
request.setHeader(QNetworkRequest::ContentTypeHeader, QString("text/plain;charset=utf-8"));
QByteArray data = params->_body.toUtf8();
reply = manager->sendCustomRequest(request,verb,data);
break;
}
default:
reply = manager->sendCustomRequest(request,verb);
break;
}
}
void FluNetwork::saveResponse(QString key,QString response){
QSharedPointer<QFile> file(new QFile(getCacheFilePath(key)));
QIODevice::OpenMode mode = QIODevice::WriteOnly|QIODevice::Truncate;
if (!file->open(mode))
{
return;
}
file->write(response.toUtf8().toBase64());
}
void FluNetwork::addHeaders(QNetworkRequest* request,const QMap<QString, QVariant>& headers){
QMapIterator<QString, QVariant> iter(headers);
while (iter.hasNext())
{
iter.next();
request->setRawHeader(iter.key().toUtf8(), iter.value().toString().toUtf8());
}
}
void FluNetwork::addQueryParam(QUrl* url,const QMap<QString, QVariant>& params){
QMapIterator<QString, QVariant> iter(params);
QUrlQuery urlQuery(*url);
while (iter.hasNext())
{
iter.next();
urlQuery.addQueryItem(iter.key(), iter.value().toString());
}
url->setQuery(urlQuery);
}
FluNetwork::FluNetwork(QObject *parent): QObject{parent}
{
timeout(5000);
retry(3);
cacheDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation).append(QDir::separator()).append("network"));
}
NetworkParams* FluNetwork::get(const QString& url){
return new NetworkParams(url,NetworkParams::TYPE_NONE,NetworkParams::METHOD_GET,this);
}
NetworkParams* FluNetwork::head(const QString& url){
return new NetworkParams(url,NetworkParams::TYPE_NONE,NetworkParams::METHOD_HEAD,this);
}
NetworkParams* FluNetwork::postBody(const QString& url){
return new NetworkParams(url,NetworkParams::TYPE_BODY,NetworkParams::METHOD_POST,this);
}
NetworkParams* FluNetwork::putBody(const QString& url){
return new NetworkParams(url,NetworkParams::TYPE_BODY,NetworkParams::METHOD_PUT,this);
}
NetworkParams* FluNetwork::patchBody(const QString& url){
return new NetworkParams(url,NetworkParams::TYPE_BODY,NetworkParams::METHOD_PATCH,this);
}
NetworkParams* FluNetwork::deleteBody(const QString& url){
return new NetworkParams(url,NetworkParams::TYPE_BODY,NetworkParams::METHOD_DELETE,this);
}
NetworkParams* FluNetwork::postForm(const QString& url){
return new NetworkParams(url,NetworkParams::TYPE_FORM,NetworkParams::METHOD_POST,this);
}
NetworkParams* FluNetwork::putForm(const QString& url){
return new NetworkParams(url,NetworkParams::TYPE_FORM,NetworkParams::METHOD_PUT,this);
}
NetworkParams* FluNetwork::patchForm(const QString& url){
return new NetworkParams(url,NetworkParams::TYPE_FORM,NetworkParams::METHOD_PATCH,this);
}
NetworkParams* FluNetwork::deleteForm(const QString& url){
return new NetworkParams(url,NetworkParams::TYPE_FORM,NetworkParams::METHOD_DELETE,this);
}
NetworkParams* FluNetwork::postJson(const QString& url){
return new NetworkParams(url,NetworkParams::TYPE_JSON,NetworkParams::METHOD_POST,this);
}
NetworkParams* FluNetwork::putJson(const QString& url){
return new NetworkParams(url,NetworkParams::TYPE_JSON,NetworkParams::METHOD_PUT,this);
}
NetworkParams* FluNetwork::patchJson(const QString& url){
return new NetworkParams(url,NetworkParams::TYPE_JSON,NetworkParams::METHOD_PATCH,this);
}
NetworkParams* FluNetwork::deleteJson(const QString& url){
return new NetworkParams(url,NetworkParams::TYPE_JSON,NetworkParams::METHOD_DELETE,this);
}
NetworkParams* FluNetwork::postJsonArray(const QString& url){
return new NetworkParams(url,NetworkParams::TYPE_JSONARRAY,NetworkParams::METHOD_POST,this);
}
NetworkParams* FluNetwork::putJsonArray(const QString& url){
return new NetworkParams(url,NetworkParams::TYPE_JSONARRAY,NetworkParams::METHOD_PUT,this);
}
NetworkParams* FluNetwork::patchJsonArray(const QString& url){
return new NetworkParams(url,NetworkParams::TYPE_JSONARRAY,NetworkParams::METHOD_PATCH,this);
}
NetworkParams* FluNetwork::deleteJsonArray(const QString& url){
return new NetworkParams(url,NetworkParams::TYPE_JSONARRAY,NetworkParams::METHOD_DELETE,this);
}
void FluNetwork::setInterceptor(QJSValue interceptor){
this->_interceptor = interceptor;
}

137
src/FluNetwork.h Normal file
View File

@ -0,0 +1,137 @@
#ifndef FLUNETWORK_H
#define FLUNETWORK_H
#include <QObject>
#include <QtQml/qqml.h>
#include <QFile>
#include <QJsonValue>
#include <QJSValue>
#include <QNetworkAccessManager>
#include "Def.h"
#include "stdafx.h"
#include "singleton.h"
class NetworkCallable : public QObject{
Q_OBJECT
QML_NAMED_ELEMENT(FluNetworkCallable)
public:
explicit NetworkCallable(QObject *parent = nullptr);
Q_SIGNAL void start();
Q_SIGNAL void finish();
Q_SIGNAL void error(int status,QString errorString,QString result);
Q_SIGNAL void success(QString result);
Q_SIGNAL void cache(QString result);
Q_SIGNAL void uploadProgress(qint64 sent, qint64 total);
Q_SIGNAL void downloadProgress(qint64 recv, qint64 total);
};
class DownloadParam : public QObject{
Q_OBJECT
public:
explicit DownloadParam(QObject *parent = nullptr);
DownloadParam(QString destPath,bool append,QObject *parent = nullptr);
public:
QString _destPath;
bool _append;
};
class NetworkParams : public QObject
{
Q_OBJECT
QML_NAMED_ELEMENT(FluNetworkParams)
public:
enum Method{
METHOD_GET,
METHOD_HEAD,
METHOD_POST,
METHOD_PUT,
METHOD_PATCH,
METHOD_DELETE
};
enum Type{
TYPE_NONE,
TYPE_FORM,
TYPE_JSON,
TYPE_JSONARRAY,
TYPE_BODY
};
explicit NetworkParams(QObject *parent = nullptr);
NetworkParams(QString url,Type type,Method method,QObject *parent = nullptr);
Q_INVOKABLE NetworkParams* addQuery(QString key,QVariant val);
Q_INVOKABLE NetworkParams* addHeader(QString key,QVariant val);
Q_INVOKABLE NetworkParams* add(QString key,QVariant val);
Q_INVOKABLE NetworkParams* addFile(QString key,QVariant val);
Q_INVOKABLE NetworkParams* setBody(QString val);
Q_INVOKABLE NetworkParams* setTimeout(int val);
Q_INVOKABLE NetworkParams* setRetry(int val);
Q_INVOKABLE NetworkParams* setCacheMode(int val);
Q_INVOKABLE NetworkParams* toDownload(QString destPath,bool append = false);
Q_INVOKABLE NetworkParams* bind(QObject* target);
Q_INVOKABLE void go(NetworkCallable* result);
QString buildCacheKey();
QString method2String();
int getTimeout();
int getRetry();
public:
DownloadParam* _downloadParam = nullptr;
QObject* _target = nullptr;
Method _method;
Type _type;
QString _url;
QString _body;
QMap<QString, QVariant> _queryMap;
QMap<QString, QVariant> _headerMap;
QMap<QString, QVariant> _paramMap;
QMap<QString, QVariant> _fileMap;
int _timeout = -1;
int _retry = -1;
int _cacheMode = FluNetworkType::CacheMode::NoCache;
};
class FluNetwork : public QObject
{
Q_OBJECT
Q_PROPERTY_AUTO(int,timeout)
Q_PROPERTY_AUTO(int,retry)
Q_PROPERTY_AUTO(QString,cacheDir)
QML_NAMED_ELEMENT(FluNetwork)
QML_SINGLETON
private:
explicit FluNetwork(QObject *parent = nullptr);
public:
SINGLETONG(FluNetwork)
static FluNetwork *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return getInstance();}
Q_INVOKABLE NetworkParams* get(const QString& url);
Q_INVOKABLE NetworkParams* head(const QString& url);
Q_INVOKABLE NetworkParams* postBody(const QString& url);
Q_INVOKABLE NetworkParams* putBody(const QString& url);
Q_INVOKABLE NetworkParams* patchBody(const QString& url);
Q_INVOKABLE NetworkParams* deleteBody(const QString& url);
Q_INVOKABLE NetworkParams* postForm(const QString& url);
Q_INVOKABLE NetworkParams* putForm(const QString& url);
Q_INVOKABLE NetworkParams* patchForm(const QString& url);
Q_INVOKABLE NetworkParams* deleteForm(const QString& url);
Q_INVOKABLE NetworkParams* postJson(const QString& url);
Q_INVOKABLE NetworkParams* putJson(const QString& url);
Q_INVOKABLE NetworkParams* patchJson(const QString& url);
Q_INVOKABLE NetworkParams* deleteJson(const QString& url);
Q_INVOKABLE NetworkParams* postJsonArray(const QString& url);
Q_INVOKABLE NetworkParams* putJsonArray(const QString& url);
Q_INVOKABLE NetworkParams* patchJsonArray(const QString& url);
Q_INVOKABLE NetworkParams* deleteJsonArray(const QString& url);
Q_INVOKABLE void setInterceptor(QJSValue interceptor);
void handle(NetworkParams* params,NetworkCallable* result);
void handleDownload(NetworkParams* params,NetworkCallable* result);
private:
void sendRequest(QNetworkAccessManager* manager,QNetworkRequest request,NetworkParams* params,QNetworkReply*& reply,QPointer<NetworkCallable> callable);
void addQueryParam(QUrl* url,const QMap<QString, QVariant>& params);
void addHeaders(QNetworkRequest* request,const QMap<QString, QVariant>& headers);
void saveResponse(QString key,QString response);
QString readCache(const QString& key);
bool cacheExists(const QString& key);
QString getCacheFilePath(const QString& key);
public:
QJSValue _interceptor;
};
#endif // FLUNETWORK_H

View File

@ -16,14 +16,31 @@ FluTheme::FluTheme(QObject *parent):QObject{parent}{
connect(this,&FluTheme::darkModeChanged,this,[=]{ connect(this,&FluTheme::darkModeChanged,this,[=]{
Q_EMIT darkChanged(); Q_EMIT darkChanged();
}); });
primaryColor(FluColors::getInstance()->Blue()); connect(this,&FluTheme::darkChanged,this,[=]{refreshColors();});
connect(this,&FluTheme::themeColorChanged,this,[=]{refreshColors();});
themeColor(FluColors::getInstance()->Blue());
darkMode(FluThemeType::DarkMode::Light);
nativeText(false); nativeText(false);
enableAnimation(true); enableAnimation(true);
darkMode(FluThemeType::DarkMode::Light);
_systemDark = systemDark(); _systemDark = systemDark();
qApp->installEventFilter(this); qApp->installEventFilter(this);
} }
void FluTheme::refreshColors(){
auto isDark = dark();
primaryColor(isDark ? _themeColor->lighter() : _themeColor->dark());
backgroundColor(isDark ? QColor(0,0,0,255) : QColor(1,1,1,255));
windowBackgroundColor(isDark ? QColor(32,32,32,255) : QColor(237,237,237,255));
windowActiveBackgroundColor(isDark ? QColor(26,26,26,255) : QColor(243,243,243,255));
fontPrimaryColor(isDark ? QColor(248,248,248,255) : QColor(7,7,7,255));
fontSecondaryColor(isDark ? QColor(222,222,222,255) : QColor(102,102,102,255));
fontTertiaryColor(isDark ? QColor(200,200,200,255) : QColor(153,153,153,255));
itemNormalColor(isDark ? QColor(255,255,255,0) : QColor(0,0,0,0));
itemHoverColor(isDark ? QColor(255,255,255,255*0.03) : QColor(0,0,0,255*0.03));
itemPressColor(isDark ? QColor(255,255,255,255*0.06) : QColor(0,0,0,255*0.06));
itemCheckColor(isDark ? QColor(255,255,255,255*0.09) : QColor(0,0,0,255*0.09));
}
bool FluTheme::eventFilter(QObject *obj, QEvent *event){ bool FluTheme::eventFilter(QObject *obj, QEvent *event){
Q_UNUSED(obj); Q_UNUSED(obj);
if (event->type() == QEvent::ApplicationPaletteChange || event->type() == QEvent::ThemeChange) if (event->type() == QEvent::ApplicationPaletteChange || event->type() == QEvent::ThemeChange)

View File

@ -5,6 +5,7 @@
#include <QtQml/qqml.h> #include <QtQml/qqml.h>
#include <QJsonArray> #include <QJsonArray>
#include <QJsonObject> #include <QJsonObject>
#include <QColor>
#include "FluColorSet.h" #include "FluColorSet.h"
#include "stdafx.h" #include "stdafx.h"
#include "singleton.h" #include "singleton.h"
@ -16,7 +17,18 @@ class FluTheme : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool dark READ dark NOTIFY darkChanged) Q_PROPERTY(bool dark READ dark NOTIFY darkChanged)
Q_PROPERTY_AUTO(FluColorSet*,primaryColor) Q_PROPERTY_AUTO(FluColorSet*,themeColor);
Q_PROPERTY_AUTO(QColor,primaryColor);
Q_PROPERTY_AUTO(QColor,backgroundColor);
Q_PROPERTY_AUTO(QColor,windowBackgroundColor);
Q_PROPERTY_AUTO(QColor,windowActiveBackgroundColor);
Q_PROPERTY_AUTO(QColor,fontPrimaryColor);
Q_PROPERTY_AUTO(QColor,fontSecondaryColor);
Q_PROPERTY_AUTO(QColor,fontTertiaryColor);
Q_PROPERTY_AUTO(QColor,itemNormalColor);
Q_PROPERTY_AUTO(QColor,itemHoverColor);
Q_PROPERTY_AUTO(QColor,itemPressColor);
Q_PROPERTY_AUTO(QColor,itemCheckColor);
Q_PROPERTY_AUTO(int,darkMode); Q_PROPERTY_AUTO(int,darkMode);
Q_PROPERTY_AUTO(bool,nativeText); Q_PROPERTY_AUTO(bool,nativeText);
Q_PROPERTY_AUTO(bool,enableAnimation); Q_PROPERTY_AUTO(bool,enableAnimation);
@ -26,6 +38,7 @@ private:
explicit FluTheme(QObject *parent = nullptr); explicit FluTheme(QObject *parent = nullptr);
bool eventFilter(QObject *obj, QEvent *event); bool eventFilter(QObject *obj, QEvent *event);
bool systemDark(); bool systemDark();
void refreshColors();
public: public:
SINGLETONG(FluTheme) SINGLETONG(FluTheme)
Q_INVOKABLE QJsonArray awesomeList(const QString& keyword = ""); Q_INVOKABLE QJsonArray awesomeList(const QString& keyword = "");
@ -33,7 +46,6 @@ public:
static FluTheme *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return getInstance();} static FluTheme *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return getInstance();}
bool dark(); bool dark();
private: private:
bool _dark;
bool _systemDark; bool _systemDark;
}; };

View File

@ -35,7 +35,9 @@ bool ViewModelManager::exist(const QString& key){
void ViewModelManager::refreshViewModel(FluViewModel* viewModel,QString key,QVariant value){ void ViewModelManager::refreshViewModel(FluViewModel* viewModel,QString key,QVariant value){
foreach (auto item, _viewmodel) { foreach (auto item, _viewmodel) {
if(item->getKey() == viewModel->getKey()){ if(item->getKey() == viewModel->getKey()){
item->setProperty(key.toStdString().c_str(),value); item->enablePropertyChange = false;
item->setProperty(key.toLatin1().constData(),value);
item->enablePropertyChange = true;
} }
} }
} }
@ -51,14 +53,16 @@ PropertyObserver::~PropertyObserver(){
} }
void PropertyObserver::_propertyChange(){ void PropertyObserver::_propertyChange(){
auto value = _property.read(); auto viewModel = (FluViewModel*)parent();
_model->setProperty(_name.toStdString().c_str(),value); if(viewModel->enablePropertyChange){
ViewModelManager::getInstance()->refreshViewModel((FluViewModel*)parent(),_name,value); auto value = _property.read();
_model->setProperty(_name.toLatin1().constData(),value);
ViewModelManager::getInstance()->refreshViewModel(viewModel,_name,value);
}
} }
FluViewModel::FluViewModel(QObject *parent):QObject{parent}{ FluViewModel::FluViewModel(QObject *parent):QObject{parent}{
scope(FluViewModelType::Scope::Window); scope(FluViewModelType::Scope::Window);
target(nullptr);
ViewModelManager::getInstance()->insertViewModel(this); ViewModelManager::getInstance()->insertViewModel(this);
} }
@ -77,7 +81,7 @@ void FluViewModel::componentComplete(){
} }
const QMetaObject* obj = metaObject(); const QMetaObject* obj = metaObject();
if(_scope == FluViewModelType::Scope::Window){ if(_scope == FluViewModelType::Scope::Window){
_key = property("objectName_").toString()+QString::number(reinterpret_cast<qulonglong>(_window), 16); _key = property("objectName").toString()+"-"+QString::number(reinterpret_cast<qulonglong>(_window), 16);
}else{ }else{
_key = property("objectName").toString(); _key = property("objectName").toString();
} }
@ -93,7 +97,7 @@ void FluViewModel::componentComplete(){
const QMetaProperty property = obj->property(i); const QMetaProperty property = obj->property(i);
QString propertyName = property.name(); QString propertyName = property.name();
auto value = property.read(this); auto value = property.read(this);
model->setProperty(propertyName.toStdString().c_str(),value); model->setProperty(propertyName.toLatin1().constData(),value);
new PropertyObserver(propertyName,model,this); new PropertyObserver(propertyName,model,this);
} }
ViewModelManager::getInstance()->insert(_key,model); ViewModelManager::getInstance()->insert(_key,model);

View File

@ -20,7 +20,6 @@ class FluViewModel : public QObject, public QQmlParserStatus
Q_OBJECT Q_OBJECT
Q_INTERFACES(QQmlParserStatus) Q_INTERFACES(QQmlParserStatus)
Q_PROPERTY_AUTO(int,scope); Q_PROPERTY_AUTO(int,scope);
Q_PROPERTY_AUTO(QObject*,target);
QML_NAMED_ELEMENT(FluViewModel) QML_NAMED_ELEMENT(FluViewModel)
public: public:
explicit FluViewModel(QObject *parent = nullptr); explicit FluViewModel(QObject *parent = nullptr);
@ -29,6 +28,7 @@ public:
void componentComplete() override; void componentComplete() override;
Q_SIGNAL void initData(); Q_SIGNAL void initData();
QString getKey(); QString getKey();
bool enablePropertyChange = true;
private: private:
QObject* _window = nullptr; QObject* _window = nullptr;
QString _key = ""; QString _key = "";

View File

@ -8,8 +8,6 @@
#include "FluTheme.h" #include "FluTheme.h"
#include "FluTools.h" #include "FluTools.h"
#include "FluTextStyle.h" #include "FluTextStyle.h"
#include "FluHttp.h"
#include "FluHttpInterceptor.h"
#include "FluWatermark.h" #include "FluWatermark.h"
#include "FluCaptcha.h" #include "FluCaptcha.h"
#include "FluEventBus.h" #include "FluEventBus.h"
@ -17,22 +15,9 @@
#include "FluViewModel.h" #include "FluViewModel.h"
#include "Screenshot.h" #include "Screenshot.h"
#include "FluRectangle.h" #include "FluRectangle.h"
#include "FluNetwork.h"
#include "QRCode.h" #include "QRCode.h"
int major = 1;
int minor = 0;
auto uri = "FluentUI";
FluentUI* FluentUI::m_instance = nullptr;
FluentUI *FluentUI::getInstance()
{
if(FluentUI::m_instance == nullptr){
FluentUI::m_instance = new FluentUI;
}
return FluentUI::m_instance;
}
void FluentUI::registerTypes(QQmlEngine *engine){ void FluentUI::registerTypes(QQmlEngine *engine){
initializeEngine(engine,uri); initializeEngine(engine,uri);
registerTypes(uri); registerTypes(uri);
@ -49,14 +34,12 @@ void FluentUI::registerTypes(const char *uri){
qmlRegisterType<ScreenshotBackground>(uri,major,minor,"ScreenshotBackground"); qmlRegisterType<ScreenshotBackground>(uri,major,minor,"ScreenshotBackground");
qmlRegisterType<Screenshot>(uri,major,minor,"Screenshot"); qmlRegisterType<Screenshot>(uri,major,minor,"Screenshot");
qmlRegisterType<FluColorSet>(uri,major,minor,"FluColorSet"); qmlRegisterType<FluColorSet>(uri,major,minor,"FluColorSet");
qmlRegisterType<FluHttpInterceptor>(uri,major,minor,"FluHttpInterceptor");
qmlRegisterType<FluHttp>(uri,major,minor,"FluHttp");
qmlRegisterType<HttpCallable>(uri,major,minor,"HttpCallable");
qmlRegisterType<HttpRequest>(uri,major,minor,"HttpRequest");
qmlRegisterType<FluEvent>(uri,major,minor,"FluEvent"); qmlRegisterType<FluEvent>(uri,major,minor,"FluEvent");
qmlRegisterType<FluViewModel>(uri,major,minor,"FluViewModel"); qmlRegisterType<FluViewModel>(uri,major,minor,"FluViewModel");
qmlRegisterType<FluTreeModel>(uri,major,minor,"FluTreeModel"); qmlRegisterType<FluTreeModel>(uri,major,minor,"FluTreeModel");
qmlRegisterType<FluRectangle>(uri,major,minor,"FluRectangle"); qmlRegisterType<FluRectangle>(uri,major,minor,"FluRectangle");
qmlRegisterType<NetworkCallable>(uri,major,minor,"FluNetworkCallable");
qmlRegisterType<NetworkParams>(uri,major,minor,"FluNetworkParams");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/ColorPicker/ColorPicker.qml"),uri,major,minor,"ColorPicker"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/ColorPicker/ColorPicker.qml"),uri,major,minor,"ColorPicker");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/ColorPicker/Content/Checkerboard.qml"),uri,major,minor,"Checkerboard"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/ColorPicker/Content/Checkerboard.qml"),uri,major,minor,"Checkerboard");
@ -151,9 +134,10 @@ void FluentUI::registerTypes(const char *uri){
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluProgressButton.qml"),uri,major,minor,"FluProgressButton"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluProgressButton.qml"),uri,major,minor,"FluProgressButton");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluLoadingButton.qml"),uri,major,minor,"FluLoadingButton"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluLoadingButton.qml"),uri,major,minor,"FluLoadingButton");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluClip.qml"),uri,major,minor,"FluClip"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluClip.qml"),uri,major,minor,"FluClip");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluLoader.qml"),uri,major,minor,"FluLoader");
qmlRegisterUncreatableMetaObject(Fluent_Awesome::staticMetaObject, uri,major,minor,"FluentIcons", "Access to enums & flags only"); qmlRegisterUncreatableMetaObject(Fluent_Awesome::staticMetaObject, uri,major,minor,"FluentIcons", "Access to enums & flags only");
qmlRegisterUncreatableMetaObject(FluHttpType::staticMetaObject, uri,major,minor,"FluHttpType", "Access to enums & flags only");
qmlRegisterUncreatableMetaObject(FluThemeType::staticMetaObject, uri,major,minor,"FluThemeType", "Access to enums & flags only"); qmlRegisterUncreatableMetaObject(FluThemeType::staticMetaObject, uri,major,minor,"FluThemeType", "Access to enums & flags only");
qmlRegisterUncreatableMetaObject(FluPageType::staticMetaObject, uri,major,minor,"FluPageType", "Access to enums & flags only"); qmlRegisterUncreatableMetaObject(FluPageType::staticMetaObject, uri,major,minor,"FluPageType", "Access to enums & flags only");
qmlRegisterUncreatableMetaObject(FluWindowType::staticMetaObject, uri,major,minor,"FluWindowType", "Access to enums & flags only"); qmlRegisterUncreatableMetaObject(FluWindowType::staticMetaObject, uri,major,minor,"FluWindowType", "Access to enums & flags only");
@ -167,6 +151,7 @@ void FluentUI::registerTypes(const char *uri){
qmlRegisterUncreatableMetaObject(FluTimelineType::staticMetaObject, uri,major,minor,"FluTimelineType", "Access to enums & flags only"); qmlRegisterUncreatableMetaObject(FluTimelineType::staticMetaObject, uri,major,minor,"FluTimelineType", "Access to enums & flags only");
qmlRegisterUncreatableMetaObject(FluScreenshotType::staticMetaObject, uri,major,minor,"FluScreenshotType", "Access to enums & flags only"); qmlRegisterUncreatableMetaObject(FluScreenshotType::staticMetaObject, uri,major,minor,"FluScreenshotType", "Access to enums & flags only");
qmlRegisterUncreatableMetaObject(FluViewModelType::staticMetaObject, uri,major,minor,"FluViewModelType", "Access to enums & flags only"); qmlRegisterUncreatableMetaObject(FluViewModelType::staticMetaObject, uri,major,minor,"FluViewModelType", "Access to enums & flags only");
qmlRegisterUncreatableMetaObject(FluNetworkType::staticMetaObject, uri,major,minor,"FluNetworkType", "Access to enums & flags only");
qmlRegisterModule(uri,major,minor); qmlRegisterModule(uri,major,minor);
} }
@ -189,5 +174,7 @@ void FluentUI::initializeEngine(QQmlEngine *engine, const char *uri){
engine->rootContext()->setContextProperty("FluTextStyle",textStyle); engine->rootContext()->setContextProperty("FluTextStyle",textStyle);
FluEventBus* eventBus = FluEventBus::getInstance(); FluEventBus* eventBus = FluEventBus::getInstance();
engine->rootContext()->setContextProperty("FluEventBus",eventBus); engine->rootContext()->setContextProperty("FluEventBus",eventBus);
FluNetwork* network = FluNetwork::getInstance();
engine->rootContext()->setContextProperty("FluNetwork",network);
engine->addImportPath("qrc:/qt/qml"); engine->addImportPath("qrc:/qt/qml");
} }

View File

@ -3,17 +3,20 @@
#include <QObject> #include <QObject>
#include <QQmlEngine> #include <QQmlEngine>
#include "singleton.h"
class FluentUI : public QObject class FluentUI : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
static FluentUI *getInstance(); SINGLETONG(FluentUI)
Q_DECL_EXPORT void registerTypes(QQmlEngine *engine); Q_DECL_EXPORT void registerTypes(QQmlEngine *engine);
void registerTypes(const char *uri); void registerTypes(const char *uri);
void initializeEngine(QQmlEngine *engine, const char *uri); void initializeEngine(QQmlEngine *engine, const char *uri);
private: private:
static FluentUI* m_instance; const int major = 1;
const int minor = 0;
const char *uri = "FluentUI";
}; };
#endif // FLUENTUI_H #endif // FLUENTUI_H

View File

@ -4,13 +4,14 @@ import FluentUI 1.0
Item { Item {
id: control id: control
property color tintColor: Qt.rgba(1,1,1,1) property color tintColor: Qt.rgba(1, 1, 1, 1)
property real tintOpacity: 0.65 property real tintOpacity: 0.65
property real luminosity: 0.01 property real luminosity: 0.01
property real noiseOpacity : 0.066 property real noiseOpacity: 0.02
property alias target : effect_source.sourceItem property alias target: effect_source.sourceItem
property int blurRadius: 32 property int blurRadius: 32
property rect targetRect : Qt.rect(control.x, control.y, control.width, control.height) property rect targetRect: Qt.rect(control.x, control.y, control.width,
control.height)
ShaderEffectSource { ShaderEffectSource {
id: effect_source id: effect_source
anchors.fill: parent anchors.fill: parent
@ -18,20 +19,20 @@ Item {
sourceRect: control.targetRect sourceRect: control.targetRect
} }
FastBlur { FastBlur {
id:fast_blur id: fast_blur
anchors.fill: parent anchors.fill: parent
source: effect_source source: effect_source
radius: control.blurRadius radius: control.blurRadius
} }
Rectangle{ Rectangle {
anchors.fill: parent anchors.fill: parent
color: Qt.rgba(1, 1, 1, luminosity) color: Qt.rgba(1, 1, 1, luminosity)
} }
Rectangle{ Rectangle {
anchors.fill: parent anchors.fill: parent
color: Qt.rgba(tintColor.r, tintColor.g, tintColor.b, tintOpacity) color: Qt.rgba(tintColor.r, tintColor.g, tintColor.b, tintOpacity)
} }
Image{ Image {
anchors.fill: parent anchors.fill: parent
source: "../Image/noise.png" source: "../Image/noise.png"
fillMode: Image.Tile fillMode: Image.Tile

View File

@ -11,13 +11,15 @@ Rectangle{
property string restoreText : "向下还原" property string restoreText : "向下还原"
property string maximizeText : "最大化" property string maximizeText : "最大化"
property string closeText : "关闭" property string closeText : "关闭"
property string stayTopText : "置顶"
property string stayTopCancelText : "取消置顶"
property color textColor: FluTheme.dark ? "#FFFFFF" : "#000000" property color textColor: FluTheme.dark ? "#FFFFFF" : "#000000"
property color minimizeNormalColor: Qt.rgba(0,0,0,0) property color minimizeNormalColor: FluTheme.itemNormalColor
property color minimizeHoverColor: FluTheme.dark ? Qt.rgba(1,1,1,0.03) : Qt.rgba(0,0,0,0.03) property color minimizeHoverColor: FluTheme.itemHoverColor
property color minimizePressColor: FluTheme.dark ? Qt.rgba(1,1,1,0.06) : Qt.rgba(0,0,0,0.06) property color minimizePressColor: FluTheme.itemPressColor
property color maximizeNormalColor: Qt.rgba(0,0,0,0) property color maximizeNormalColor: FluTheme.itemNormalColor
property color maximizeHoverColor: FluTheme.dark ? Qt.rgba(1,1,1,0.03) : Qt.rgba(0,0,0,0.03) property color maximizeHoverColor: FluTheme.itemHoverColor
property color maximizePressColor: FluTheme.dark ? Qt.rgba(1,1,1,0.06) : Qt.rgba(0,0,0,0.06) property color maximizePressColor: FluTheme.itemPressColor
property color closeNormalColor: Qt.rgba(0,0,0,0) property color closeNormalColor: Qt.rgba(0,0,0,0)
property color closeHoverColor: Qt.rgba(251/255,115/255,115/255,1) property color closeHoverColor: Qt.rgba(251/255,115/255,115/255,1)
property color closePressColor: Qt.rgba(251/255,115/255,115/255,0.8) property color closePressColor: Qt.rgba(251/255,115/255,115/255,0.8)
@ -25,11 +27,12 @@ Rectangle{
property bool showClose: true property bool showClose: true
property bool showMinimize: true property bool showMinimize: true
property bool showMaximize: true property bool showMaximize: true
property bool showStayTop: true
property bool titleVisible: true property bool titleVisible: true
property url icon property url icon
property int iconSize: 20 property int iconSize: 20
property bool isMac: FluTools.isMacos() property bool isMac: FluTools.isMacos()
property color borerlessColor : FluTheme.dark ? FluTheme.primaryColor.lighter : FluTheme.primaryColor.dark property color borerlessColor : FluTheme.primaryColor
property var maxClickListener : function(){ property var maxClickListener : function(){
if (d.win.visibility === Window.Maximized) if (d.win.visibility === Window.Maximized)
d.win.visibility = Window.Windowed d.win.visibility = Window.Windowed
@ -42,6 +45,11 @@ Rectangle{
property var closeClickListener : function(){ property var closeClickListener : function(){
d.win.close() d.win.close()
} }
property var stayTopClickListener: function(){
if(d.win instanceof FluWindow){
d.win.stayTop = !d.win.stayTop
}
}
property var darkClickListener: function(){ property var darkClickListener: function(){
if(FluTheme.dark){ if(FluTheme.dark){
FluTheme.darkMode = FluThemeType.Light FluTheme.darkMode = FluThemeType.Light
@ -57,11 +65,17 @@ Rectangle{
Item{ Item{
id:d id:d
property var win: Window.window property var win: Window.window
property bool stayTop: {
if(d.win instanceof FluWindow){
return d.win.stayTop
}
return false
}
property bool isRestore: win && Window.Maximized === win.visibility property bool isRestore: win && Window.Maximized === win.visibility
property bool resizable: win && !(win.minimumHeight === win.maximumHeight && win.maximumWidth === win.minimumWidth) property bool resizable: win && !(win.height === win.maximumHeight && win.height === win.minimumHeight && win.width === win.maximumWidth && win.width === win.minimumWidth)
} }
TapHandler { TapHandler {
onTapped: if (tapCount === 2) btn_maximize.clicked() onTapped: if (tapCount === 2 && d.resizable) btn_maximize.clicked()
gesturePolicy: TapHandler.DragThreshold gesturePolicy: TapHandler.DragThreshold
} }
DragHandler { DragHandler {
@ -106,6 +120,24 @@ Rectangle{
textRight: false textRight: false
clickListener:()=> darkClickListener(btn_dark) clickListener:()=> darkClickListener(btn_dark)
} }
FluIconButton{
id:btn_stay_top
Layout.preferredWidth: 40
Layout.preferredHeight: 30
iconSource : FluentIcons.Pinned
Layout.alignment: Qt.AlignVCenter
iconSize: 13
visible: {
if(!(d.win instanceof FluWindow)){
return false
}
return showStayTop
}
text:d.stayTop ? control.stayTopCancelText : control.stayTopText
radius: 0
iconColor: d.stayTop ? FluTheme.primaryColor : control.textColor
onClicked: stayTopClickListener()
}
FluIconButton{ FluIconButton{
id:btn_minimize id:btn_minimize
Layout.preferredWidth: 40 Layout.preferredWidth: 40
@ -164,6 +196,9 @@ Rectangle{
onClicked: closeClickListener() onClicked: closeClickListener()
} }
} }
function stayTopButton(){
return btn_stay_top
}
function minimizeButton(){ function minimizeButton(){
return btn_minimize return btn_minimize
} }

View File

@ -33,7 +33,7 @@ Item {
properties: "opacity" properties: "opacity"
from: 1 from: 1
to: 0 to: 0
duration: FluTheme.enableAnimation ? 83 : 0 duration: FluTheme.enableAnimation ? 83 : 1
} }
} }
add: Transition { add: Transition {
@ -41,7 +41,7 @@ Item {
properties: "opacity" properties: "opacity"
from: 0 from: 0
to: 1 to: 1
duration: FluTheme.enableAnimation ? 83 : 0 duration: FluTheme.enableAnimation ? 83 : 1
} }
} }
delegate: Item{ delegate: Item{

View File

@ -65,7 +65,7 @@ Item {
height: 50 height: 50
radius: 25 radius: 25
visible: isYear visible: isYear
color: FluTheme.primaryColor.dark color: FluTheme.primaryColor
} }
FluText{ FluText{
text:date.getFullYear() text:date.getFullYear()
@ -124,7 +124,7 @@ Item {
height: 50 height: 50
radius: 25 radius: 25
visible: isMonth visible: isMonth
color: FluTheme.primaryColor.dark color: FluTheme.primaryColor
} }
FluText{ FluText{
text:(date.getMonth()+1)+"月" text:(date.getMonth()+1)+"月"
@ -184,7 +184,7 @@ Item {
radius: 18 radius: 18
color:"#00000000" color:"#00000000"
visible: isDay visible: isDay
border.color: FluTheme.primaryColor.dark border.color: FluTheme.primaryColor
border.width: 1 border.width: 1
} }
Rectangle{ Rectangle{
@ -194,7 +194,7 @@ Item {
height: 30 height: 30
radius: 15 radius: 15
visible: isToDay visible: isToDay
color: FluTheme.primaryColor.dark color: FluTheme.primaryColor
} }
FluText{ FluText{
text:date.getDate() text:date.getDate()
@ -331,7 +331,7 @@ Item {
cellWidth: displayMode === FluCalendarViewType.Month ? 40 : 70 cellWidth: displayMode === FluCalendarViewType.Month ? 40 : 70
clip: true clip: true
boundsBehavior:Flickable.StopAtBounds boundsBehavior:Flickable.StopAtBounds
delegate: Loader{ delegate: FluLoader{
property var modelData : model property var modelData : model
property var name : model.name property var name : model.name
property var date : model.date property var date : model.date

View File

@ -75,7 +75,7 @@ Item {
return 0 return 0
return index-1 return index-1
} }
Loader{ FluLoader{
property int displayIndex : item_control.displayIndex property int displayIndex : item_control.displayIndex
property var model: list_view.model.get(index) property var model: list_view.model.get(index)
anchors.fill: parent anchors.fill: parent
@ -124,9 +124,9 @@ Item {
radius: 4 radius: 4
} }
scale: checked ? 1.2 : 1 scale: checked ? 1.2 : 1
color: checked ? FluTheme.primaryColor.dark : Qt.rgba(1,1,1,0.7) color: checked ? FluTheme.primaryColor : Qt.rgba(1,1,1,0.7)
border.width: mouse_item.containsMouse ? 1 : 0 border.width: mouse_item.containsMouse ? 1 : 0
border.color: FluTheme.primaryColor.dark border.color: FluTheme.primaryColor
MouseArea{ MouseArea{
id:mouse_item id:mouse_item
hoverEnabled: true hoverEnabled: true
@ -156,7 +156,7 @@ Item {
Repeater{ Repeater{
id:repeater_indicator id:repeater_indicator
model: list_view.count model: list_view.count
Loader{ FluLoader{
property int displayIndex: { property int displayIndex: {
if(index === 0) if(index === 0)
return list_view.count-3 return list_view.count-3

View File

@ -7,12 +7,12 @@ Button {
property bool disabled: false property bool disabled: false
property string contentDescription: "" property string contentDescription: ""
property color borderNormalColor: FluTheme.dark ? Qt.rgba(160/255,160/255,160/255,1) : Qt.rgba(136/255,136/255,136/255,1) property color borderNormalColor: FluTheme.dark ? Qt.rgba(160/255,160/255,160/255,1) : Qt.rgba(136/255,136/255,136/255,1)
property color bordercheckedColor: FluTheme.dark ? FluTheme.primaryColor.lighter : FluTheme.primaryColor.dark property color bordercheckedColor: FluTheme.primaryColor
property color borderHoverColor: FluTheme.dark ? Qt.rgba(167/255,167/255,167/255,1) : Qt.rgba(135/255,135/255,135/255,1) property color borderHoverColor: FluTheme.dark ? Qt.rgba(167/255,167/255,167/255,1) : Qt.rgba(135/255,135/255,135/255,1)
property color borderDisableColor: FluTheme.dark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(199/255,199/255,199/255,1) property color borderDisableColor: FluTheme.dark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(199/255,199/255,199/255,1)
property color borderPressedColor: FluTheme.dark ? Qt.rgba(90/255,90/255,90/255,1) : Qt.rgba(191/255,191/255,191/255,1) property color borderPressedColor: FluTheme.dark ? Qt.rgba(90/255,90/255,90/255,1) : Qt.rgba(191/255,191/255,191/255,1)
property color normalColor: FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(247/255,247/255,247/255,1) property color normalColor: FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(247/255,247/255,247/255,1)
property color checkedColor: FluTheme.dark ? FluTheme.primaryColor.lighter : FluTheme.primaryColor.dark property color checkedColor: FluTheme.primaryColor
property color hoverColor: FluTheme.dark ? Qt.rgba(72/255,72/255,72/255,1) : Qt.rgba(236/255,236/255,236/255,1) property color hoverColor: FluTheme.dark ? Qt.rgba(72/255,72/255,72/255,1) : Qt.rgba(236/255,236/255,236/255,1)
property color checkedHoverColor: FluTheme.dark ? Qt.darker(checkedColor,1.15) : Qt.lighter(checkedColor,1.15) property color checkedHoverColor: FluTheme.dark ? Qt.darker(checkedColor,1.15) : Qt.lighter(checkedColor,1.15)
property color checkedPreesedColor: FluTheme.dark ? Qt.darker(checkedColor,1.3) : Qt.lighter(checkedColor,1.3) property color checkedPreesedColor: FluTheme.dark ? Qt.darker(checkedColor,1.3) : Qt.lighter(checkedColor,1.3)

View File

@ -19,7 +19,7 @@ Button{
color:"#00000000" color:"#00000000"
border.color: { border.color: {
if(hovered) if(hovered)
return FluTheme.primaryColor.light return FluTheme.primaryColor
return FluTheme.dark ? Qt.rgba(100/255,100/255,100/255,1) : Qt.rgba(200/255,200/255,200/255,1) return FluTheme.dark ? Qt.rgba(100/255,100/255,100/255,1) : Qt.rgba(200/255,200/255,200/255,1)
} }
border.width: 1 border.width: 1

View File

@ -45,7 +45,7 @@ T.ComboBox {
topPadding: 6 - control.padding topPadding: 6 - control.padding
bottomPadding: 6 - control.padding bottomPadding: 6 - control.padding
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
selectionColor: FluTools.colorAlpha(FluTheme.primaryColor.lightest,0.6) selectionColor: FluTools.colorAlpha(FluTheme.primaryColor,0.5)
selectedTextColor: color selectedTextColor: color
text: control.editable ? control.editText : control.displayText text: control.editable ? control.editText : control.displayText
enabled: control.editable enabled: control.editable
@ -108,6 +108,7 @@ T.ComboBox {
model: control.delegateModel model: control.delegateModel
currentIndex: control.highlightedIndex currentIndex: control.highlightedIndex
highlightMoveDuration: 0 highlightMoveDuration: 0
boundsMovement: Flickable.StopAtBounds
T.ScrollIndicator.vertical: ScrollIndicator { } T.ScrollIndicator.vertical: ScrollIndicator { }
} }
enter: Transition { enter: Transition {

View File

@ -25,9 +25,6 @@ FluPopup {
anchors.fill: parent anchors.fill: parent
color: 'transparent' color: 'transparent'
radius:5 radius:5
FluShadow{
radius: 5
}
FluText{ FluText{
id:text_title id:text_title
font: FluTextStyle.TitleLarge font: FluTextStyle.TitleLarge

View File

@ -17,7 +17,7 @@ TextEdit {
selectByMouse: true selectByMouse: true
selectedTextColor: color selectedTextColor: color
bottomPadding: 0 bottomPadding: 0
selectionColor: FluTools.colorAlpha(FluTheme.primaryColor.lightest,0.6) selectionColor: FluTools.colorAlpha(FluTheme.primaryColor,0.5)
font:FluTextStyle.Body font:FluTextStyle.Body
onSelectedTextChanged: { onSelectedTextChanged: {
control.forceActiveFocus() control.forceActiveFocus()

View File

@ -169,11 +169,7 @@ Rectangle {
anchors.rightMargin: 5 anchors.rightMargin: 5
color: { color: {
if(getListView().currentIndex === position){ if(getListView().currentIndex === position){
if(FluTheme.dark){ return item_mouse.containsMouse ? Qt.lighter(FluTheme.primaryColor,1.1): FluTheme.primaryColor
return item_mouse.containsMouse ? Qt.darker(FluTheme.primaryColor.lighter,1.1) : FluTheme.primaryColor.lighter
}else{
return item_mouse.containsMouse ? Qt.lighter(FluTheme.primaryColor.dark,1.1): FluTheme.primaryColor.dark
}
} }
if(item_mouse.containsMouse){ if(item_mouse.containsMouse){
return FluTheme.dark ? Qt.rgba(63/255,60/255,61/255,1) : Qt.rgba(237/255,237/255,242/255,1) return FluTheme.dark ? Qt.rgba(63/255,60/255,61/255,1) : Qt.rgba(237/255,237/255,242/255,1)
@ -236,7 +232,7 @@ Rectangle {
preferredHighlightEnd: 0 preferredHighlightEnd: 0
highlightMoveDuration: 0 highlightMoveDuration: 0
visible: showYear visible: showYear
delegate: Loader{ delegate: FluLoader{
property var model: modelData property var model: modelData
property int type:0 property int type:0
property int position:index property int position:index
@ -258,7 +254,7 @@ Rectangle {
preferredHighlightEnd: 0 preferredHighlightEnd: 0
highlightMoveDuration: 0 highlightMoveDuration: 0
boundsBehavior:Flickable.StopAtBounds boundsBehavior:Flickable.StopAtBounds
delegate: Loader{ delegate: FluLoader{
property var model: modelData property var model: modelData
property int type:1 property int type:1
property int position:index property int position:index
@ -281,7 +277,7 @@ Rectangle {
ScrollBar.vertical: FluScrollBar {} ScrollBar.vertical: FluScrollBar {}
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
boundsBehavior:Flickable.StopAtBounds boundsBehavior:Flickable.StopAtBounds
delegate: Loader{ delegate: FluLoader{
property var model: modelData property var model: modelData
property int type:2 property int type:2
property int position:index property int position:index

View File

@ -2,16 +2,26 @@ import QtQuick 2.15
import QtQuick.Window 2.15 import QtQuick.Window 2.15
import FluentUI 1.0 import FluentUI 1.0
Rectangle {
property real spacing Item {
property alias separatorHeight:separator.height
id:control id:control
color:Qt.rgba(0,0,0,0) property int orientation: Qt.Horizontal
height: spacing*2+separator.height property int spacing:0
property int size: 1
QtObject{
id:d
property bool isVertical : orientation === Qt.Vertical
}
width: d.isVertical ? spacing*2+size : parent.width
height: d.isVertical ? parent.height : spacing*2+size
FluRectangle{ FluRectangle{
id:separator
color: FluTheme.dark ? Qt.rgba(80/255,80/255,80/255,1) : Qt.rgba(210/255,210/255,210/255,1) color: FluTheme.dark ? Qt.rgba(80/255,80/255,80/255,1) : Qt.rgba(210/255,210/255,210/255,1)
width:parent.width width: d.isVertical ? size : parent.width
height: d.isVertical ? parent.height : size
anchors.centerIn: parent anchors.centerIn: parent
} }
} }

View File

@ -5,7 +5,7 @@ import FluentUI 1.0
Button { Button {
property bool disabled: false property bool disabled: false
property string contentDescription: "" property string contentDescription: ""
property color normalColor: FluTheme.dark ? FluTheme.primaryColor.lighter : FluTheme.primaryColor.dark property color normalColor: FluTheme.primaryColor
property color hoverColor: FluTheme.dark ? Qt.darker(normalColor,1.1) : Qt.lighter(normalColor,1.1) property color hoverColor: FluTheme.dark ? Qt.darker(normalColor,1.1) : Qt.lighter(normalColor,1.1)
property color disableColor: FluTheme.dark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(199/255,199/255,199/255,1) property color disableColor: FluTheme.dark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(199/255,199/255,199/255,1)
property color pressedColor: FluTheme.dark ? Qt.darker(normalColor,1.2) : Qt.lighter(normalColor,1.2) property color pressedColor: FluTheme.dark ? Qt.darker(normalColor,1.2) : Qt.lighter(normalColor,1.2)

View File

@ -10,10 +10,10 @@ Button {
property bool disabled: false property bool disabled: false
property int radius:4 property int radius:4
property string contentDescription: "" property string contentDescription: ""
property color hoverColor: FluTheme.dark ? Qt.rgba(1,1,1,0.03) : Qt.rgba(0,0,0,0.03) property color hoverColor: FluTheme.itemHoverColor
property color pressedColor: FluTheme.dark ? Qt.rgba(1,1,1,0.06) : Qt.rgba(0,0,0,0.06) property color pressedColor: FluTheme.itemPressColor
property color normalColor: FluTheme.dark ? Qt.rgba(0,0,0,0) : Qt.rgba(0,0,0,0) property color normalColor: FluTheme.itemNormalColor
property color disableColor: FluTheme.dark ? Qt.rgba(0,0,0,0) : Qt.rgba(0,0,0,0) property color disableColor: FluTheme.itemNormalColor
property Component iconDelegate: com_icon property Component iconDelegate: com_icon
property color color: { property color color: {
if(!enabled){ if(!enabled){
@ -37,6 +37,7 @@ Button {
return Qt.rgba(0,0,0,1) return Qt.rgba(0,0,0,1)
} }
} }
property color textColor: FluTheme.fontPrimaryColor
Accessible.role: Accessible.Button Accessible.role: Accessible.Button
Accessible.name: control.text Accessible.name: control.text
Accessible.description: contentDescription Accessible.description: contentDescription
@ -47,6 +48,7 @@ Button {
verticalPadding: 8 verticalPadding: 8
horizontalPadding: 8 horizontalPadding: 8
enabled: !disabled enabled: !disabled
font:FluTextStyle.Caption
background: Rectangle{ background: Rectangle{
implicitWidth: 30 implicitWidth: 30
implicitHeight: 30 implicitHeight: 30
@ -71,7 +73,7 @@ Button {
Component{ Component{
id:com_row id:com_row
RowLayout{ RowLayout{
Loader{ FluLoader{
sourceComponent: iconDelegate sourceComponent: iconDelegate
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
visible: display !== Button.TextOnly visible: display !== Button.TextOnly
@ -80,13 +82,15 @@ Button {
text:control.text text:control.text
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
visible: display !== Button.IconOnly visible: display !== Button.IconOnly
color: control.textColor
font: control.font
} }
} }
} }
Component{ Component{
id:com_column id:com_column
ColumnLayout{ ColumnLayout{
Loader{ FluLoader{
sourceComponent: iconDelegate sourceComponent: iconDelegate
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
visible: display !== Button.TextOnly visible: display !== Button.TextOnly
@ -95,10 +99,12 @@ Button {
text:control.text text:control.text
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
visible: display !== Button.IconOnly visible: display !== Button.IconOnly
color: control.textColor
font: control.font
} }
} }
} }
contentItem:Loader{ contentItem:FluLoader{
sourceComponent: { sourceComponent: {
if(display === Button.TextUnderIcon){ if(display === Button.TextUnderIcon){
return com_column return com_column

View File

@ -11,7 +11,7 @@ Image {
property Component errorItem : com_error property Component errorItem : com_error
property Component loadingItem: com_loading property Component loadingItem: com_loading
id: control id: control
Loader{ FluLoader{
anchors.fill: parent anchors.fill: parent
sourceComponent: { sourceComponent: {
if(control.status === Image.Loading){ if(control.status === Image.Loading){
@ -26,7 +26,7 @@ Image {
Component{ Component{
id:com_loading id:com_loading
Rectangle{ Rectangle{
color: FluTheme.dark ? Qt.rgba(1,1,1,0.03) : Qt.rgba(0,0,0,0.03) color: FluTheme.itemHoverColor
FluProgressRing{ FluProgressRing{
anchors.centerIn: parent anchors.centerIn: parent
visible: control.status === Image.Loading visible: control.status === Image.Loading
@ -36,7 +36,7 @@ Image {
Component{ Component{
id:com_error id:com_error
Rectangle{ Rectangle{
color: FluTheme.dark ? Qt.rgba(1,1,1,0.03) : Qt.rgba(0,0,0,0.03) color: FluTheme.itemHoverColor
FluFilledButton{ FluFilledButton{
text: control.errorButtonText text: control.errorButtonText
anchors.centerIn: parent anchors.centerIn: parent

View File

@ -86,7 +86,7 @@ FluObject {
interval: duration; running: duration > 0; repeat: duration > 0 interval: duration; running: duration > 0; repeat: duration > 0
onTriggered: content.close(); onTriggered: content.close();
} }
Loader{ FluLoader{
id:loader; id:loader;
x:(parent.width - width) / 2; x:(parent.width - width) / 2;
property var _super: content; property var _super: content;
@ -170,7 +170,7 @@ FluObject {
switch(_super.type){ switch(_super.type){
case mcontrol.const_success: return Qt.rgba(108/255,203/255,95/255,1); case mcontrol.const_success: return Qt.rgba(108/255,203/255,95/255,1);
case mcontrol.const_warning: return Qt.rgba(252/255,225/255,0/255,1); case mcontrol.const_warning: return Qt.rgba(252/255,225/255,0/255,1);
case mcontrol.const_info: return FluTheme.primaryColor.lighter; case mcontrol.const_info: return FluTheme.primaryColor;
case mcontrol.const_error: return Qt.rgba(255/255,153/255,164/255,1); case mcontrol.const_error: return Qt.rgba(255/255,153/255,164/255,1);
} }
return "#FFFFFF" return "#FFFFFF"
@ -213,7 +213,7 @@ FluObject {
switch(_super.type){ switch(_super.type){
case mcontrol.const_success: return Qt.rgba(108/255,203/255,95/255,1); case mcontrol.const_success: return Qt.rgba(108/255,203/255,95/255,1);
case mcontrol.const_warning: return Qt.rgba(252/255,225/255,0/255,1); case mcontrol.const_warning: return Qt.rgba(252/255,225/255,0/255,1);
case mcontrol.const_info: return FluTheme.primaryColor.lighter; case mcontrol.const_info: return FluTheme.primaryColor;
case mcontrol.const_error: return Qt.rgba(255/255,153/255,164/255,1); case mcontrol.const_error: return Qt.rgba(255/255,153/255,164/255,1);
} }
return "#FFFFFF" return "#FFFFFF"

View File

@ -0,0 +1,5 @@
import QtQuick 2.15
Loader {
Component.onDestruction: sourceComponent = undefined
}

View File

@ -47,23 +47,13 @@ T.MenuBarItem {
implicitHeight: 30 implicitHeight: 30
radius: 3 radius: 3
color: { color: {
if(FluTheme.dark){ if(control.highlighted){
if(control.highlighted){ return FluTheme.itemCheckColor
return Qt.rgba(1,1,1,0.06)
}
if(control.hovered){
return Qt.rgba(1,1,1,0.03)
}
return Qt.rgba(0,0,0,0)
}else{
if(control.highlighted){
return Qt.rgba(0,0,0,0.06)
}
if(control.hovered){
return Qt.rgba(0,0,0,0.03)
}
return Qt.rgba(0,0,0,0)
} }
if(control.hovered){
return FluTheme.itemHoverColor
}
return FluTheme.itemNormalColor
} }
} }
} }

View File

@ -60,7 +60,7 @@ T.MenuItem {
right: parent.right right: parent.right
rightMargin: (control.mirrored ? indicatorPadding : arrowPadding)+5 rightMargin: (control.mirrored ? indicatorPadding : arrowPadding)+5
} }
Loader{ FluLoader{
id:loader_icon id:loader_icon
sourceComponent: iconDelegate sourceComponent: iconDelegate
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@ -98,17 +98,10 @@ T.MenuItem {
anchors.margins: 3 anchors.margins: 3
radius: 4 radius: 4
color:{ color:{
if(FluTheme.dark){ if(control.highlighted){
if(control.highlighted){ return FluTheme.itemCheckColor
return Qt.rgba(1,1,1,0.06)
}
return Qt.rgba(0,0,0,0)
}else{
if(control.highlighted){
return Qt.rgba(0,0,0,0.06)
}
return Qt.rgba(0,0,0,0)
} }
return FluTheme.itemNormalColor
} }
} }
} }

View File

@ -10,6 +10,7 @@ TextArea{
property color placeholderNormalColor: FluTheme.dark ? Qt.rgba(210/255,210/255,210/255,1) : Qt.rgba(96/255,96/255,96/255,1) property color placeholderNormalColor: FluTheme.dark ? Qt.rgba(210/255,210/255,210/255,1) : Qt.rgba(96/255,96/255,96/255,1)
property color placeholderFocusColor: FluTheme.dark ? Qt.rgba(152/255,152/255,152/255,1) : Qt.rgba(141/255,141/255,141/255,1) property color placeholderFocusColor: FluTheme.dark ? Qt.rgba(152/255,152/255,152/255,1) : Qt.rgba(141/255,141/255,141/255,1)
property color placeholderDisableColor: FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1) property color placeholderDisableColor: FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
property bool isCtrlEnterForNewline: false
id:control id:control
enabled: !disabled enabled: !disabled
color: { color: {
@ -20,11 +21,11 @@ TextArea{
} }
font:FluTextStyle.Body font:FluTextStyle.Body
wrapMode: Text.WrapAnywhere wrapMode: Text.WrapAnywhere
padding: 7 padding: 8
leftPadding: padding+4 leftPadding: padding+4
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
selectedTextColor: color selectedTextColor: color
selectionColor: FluTools.colorAlpha(FluTheme.primaryColor.lightest,0.6) selectionColor: FluTools.colorAlpha(FluTheme.primaryColor,0.5)
placeholderTextColor: { placeholderTextColor: {
if(!enabled){ if(!enabled){
return placeholderDisableColor return placeholderDisableColor
@ -35,21 +36,28 @@ TextArea{
return placeholderNormalColor return placeholderNormalColor
} }
selectByMouse: true selectByMouse: true
width: background.implicitWidth width: 240
background: FluTextBoxBackground{ background: FluTextBoxBackground{
inputItem: control inputItem: control
implicitWidth: 240
} }
Keys.onEnterPressed: (event)=> d.handleCommit(event) Keys.onEnterPressed: (event)=> d.handleCommit(event)
Keys.onReturnPressed:(event)=> d.handleCommit(event) Keys.onReturnPressed:(event)=> d.handleCommit(event)
QtObject{ QtObject{
id:d id:d
function handleCommit(event){ function handleCommit(event){
if(event.modifiers & Qt.ControlModifier){ if(isCtrlEnterForNewline){
if(event.modifiers & Qt.ControlModifier){
insert(control.cursorPosition, "\n")
return
}
control.commit(control.text)
}else{
if(event.modifiers & Qt.ControlModifier){
control.commit(control.text)
return
}
insert(control.cursorPosition, "\n") insert(control.cursorPosition, "\n")
return
} }
control.commit(control.text)
} }
} }
MouseArea{ MouseArea{

View File

@ -16,8 +16,11 @@ Item {
property int pageMode: FluNavigationViewType.Stack property int pageMode: FluNavigationViewType.Stack
property FluMenu navItemRightMenu property FluMenu navItemRightMenu
property FluMenu navItemExpanderRightMenu property FluMenu navItemExpanderRightMenu
property int navCompactWidth: 50
property int navTopMargin: 0
property int cellHeight: 38 property int cellHeight: 38
property int cellWidth: 300 property int cellWidth: 300
property bool hideNavAppBar: false
signal logoClicked signal logoClicked
id:control id:control
Item{ Item{
@ -120,7 +123,7 @@ Item {
} }
return 1 return 1
} }
separatorHeight: { size: {
if(!model){ if(!model){
return 1 return 1
} }
@ -176,6 +179,11 @@ Item {
leftMargin: 6 leftMargin: 6
rightMargin: 6 rightMargin: 6
} }
FluTooltip {
text: model.title
visible: item_control.hovered && model.title && d.isCompact
delay: 800
}
MouseArea{ MouseArea{
anchors.fill: parent anchors.fill: parent
acceptedButtons: Qt.RightButton acceptedButtons: Qt.RightButton
@ -184,7 +192,9 @@ Item {
if (mouse.button === Qt.RightButton) { if (mouse.button === Qt.RightButton) {
if(model.menuDelegate){ if(model.menuDelegate){
loader_item_menu.sourceComponent = model.menuDelegate loader_item_menu.sourceComponent = model.menuDelegate
loader_item_menu.item.popup() connection_item_menu.target = loader_item_menu.item
loader_item_menu.modelData = model
loader_item_menu.item.popup();
} }
} }
} }
@ -197,7 +207,7 @@ Item {
if(h+y>control.height){ if(h+y>control.height){
y = control.height - h y = control.height - h
} }
control_popup.showPopup(Qt.point(50,y),h,model.children) control_popup.showPopup(Qt.point(control.navCompactWidth,y),h,model.children)
return return
} }
model.isExpand = !model.isExpand model.isExpand = !model.isExpand
@ -237,7 +247,7 @@ Item {
width: 3 width: 3
height: 18 height: 18
radius: 1.5 radius: 1.5
color: FluTheme.primaryColor.dark color: FluTheme.primaryColor
visible: { visible: {
if(!model){ if(!model){
return false return false
@ -289,25 +299,15 @@ Item {
} }
color: { color: {
if(!item_control.enabled){ if(!item_control.enabled){
return Qt.rgba(0,0,0,0) return FluTheme.itemNormalColor
} }
if(FluTheme.dark){ if(nav_list.currentIndex === _idx&&type===0){
if((nav_list.currentIndex === _idx)&&type===0){ return FluTheme.itemCheckColor
return Qt.rgba(1,1,1,0.06)
}
if(item_control.hovered){
return Qt.rgba(1,1,1,0.03)
}
return Qt.rgba(0,0,0,0)
}else{
if(nav_list.currentIndex === _idx&&type===0){
return Qt.rgba(0,0,0,0.06)
}
if(item_control.hovered){
return Qt.rgba(0,0,0,0.03)
}
return Qt.rgba(0,0,0,0)
} }
if(item_control.hovered){
return FluTheme.itemHoverColor
}
return FluTheme.itemNormalColor
} }
Component{ Component{
id:com_icon id:com_icon
@ -338,11 +338,11 @@ Item {
return true return true
} }
anchors{ anchors{
verticalCenter: parent.verticalCenter
left:parent.left left:parent.left
leftMargin: 3 verticalCenter: parent.verticalCenter
leftMargin: d.isCompactAndNotPanel ? (parent.width - 30)/2 : 3
} }
Loader{ FluLoader{
anchors.centerIn: parent anchors.centerIn: parent
sourceComponent: { sourceComponent: {
if(model&&model.iconDelegate){ if(model&&model.iconDelegate){
@ -388,7 +388,7 @@ Item {
return FluTheme.dark ? FluColors.White : FluColors.Grey220 return FluTheme.dark ? FluColors.White : FluColors.Grey220
} }
} }
Loader{ FluLoader{
id:item_edit_loader id:item_edit_loader
anchors{ anchors{
top: parent.top top: parent.top
@ -404,7 +404,7 @@ Item {
return model&&model.showEdit ? model.editDelegate : undefined return model&&model.showEdit ? model.editDelegate : undefined
} }
onStatusChanged: { onStatusChanged: {
if(status === Loader.Ready){ if(status === FluLoader.Ready){
item.forceActiveFocus() item.forceActiveFocus()
item_connection_edit_focus.target = item item_connection_edit_focus.target = item
} }
@ -463,10 +463,11 @@ Item {
leftMargin: 6 leftMargin: 6
rightMargin: 6 rightMargin: 6
} }
Drag.active: item_mouse.drag.active FluTooltip {
Drag.hotSpot.x: item_control.width / 2 text: model.title
Drag.hotSpot.y: item_control.height / 2 visible: item_control.hovered && model.title && d.isCompact
Drag.dragType: Drag.Automatic delay: 800
}
onClicked:{ onClicked:{
if(type === 0){ if(type === 0){
if(model.onTapListener){ if(model.onTapListener){
@ -496,23 +497,13 @@ Item {
id:item_mouse id:item_mouse
anchors.fill: parent anchors.fill: parent
acceptedButtons: Qt.RightButton | Qt.LeftButton acceptedButtons: Qt.RightButton | Qt.LeftButton
drag.target: item_control
onPositionChanged: {
parent.grabToImage(function(result) {
parent.Drag.imageSource = result.url;
})
}
drag.onActiveChanged:
if (active) {
parent.grabToImage(function(result) {
parent.Drag.imageSource = result.url;
})
}
onClicked: onClicked:
(mouse)=>{ (mouse)=>{
if (mouse.button === Qt.RightButton) { if (mouse.button === Qt.RightButton) {
if(model.menuDelegate){ if(model.menuDelegate){
loader_item_menu.sourceComponent = model.menuDelegate loader_item_menu.sourceComponent = model.menuDelegate
connection_item_menu.target = loader_item_menu.item
loader_item_menu.modelData = model
loader_item_menu.item.popup(); loader_item_menu.item.popup();
} }
}else{ }else{
@ -525,37 +516,21 @@ Item {
anchors.fill: parent anchors.fill: parent
color: { color: {
if(!item_control.enabled){ if(!item_control.enabled){
return Qt.rgba(0,0,0,0) return FluTheme.itemNormalColor
} }
if(FluTheme.dark){ if(type===0){
if(type===0){ if(nav_list.currentIndex === _idx){
if(nav_list.currentIndex === _idx){ return FluTheme.itemCheckColor
return Qt.rgba(1,1,1,0.06)
}
}else{
if(nav_list.currentIndex === (nav_list.count-layout_footer.count+_idx)){
return Qt.rgba(1,1,1,0.06)
}
} }
if(item_control.hovered){
return Qt.rgba(1,1,1,0.03)
}
return Qt.rgba(0,0,0,0)
}else{ }else{
if(type===0){ if(nav_list.currentIndex === (nav_list.count-layout_footer.count+_idx)){
if(nav_list.currentIndex === _idx){ return FluTheme.itemCheckColor
return Qt.rgba(0,0,0,0.06)
}
}else{
if(nav_list.currentIndex === (nav_list.count-layout_footer.count+_idx)){
return Qt.rgba(0,0,0,0.06)
}
} }
if(item_control.hovered){
return Qt.rgba(0,0,0,0.03)
}
return Qt.rgba(0,0,0,0)
} }
if(item_control.hovered){
return FluTheme.itemHoverColor
}
return FluTheme.itemNormalColor
} }
Component{ Component{
id:com_icon id:com_icon
@ -586,11 +561,11 @@ Item {
return true return true
} }
anchors{ anchors{
verticalCenter: parent.verticalCenter
left:parent.left left:parent.left
leftMargin: 3 verticalCenter: parent.verticalCenter
leftMargin: d.isCompactAndNotPanel ? (parent.width - 30)/2 : 3
} }
Loader{ FluLoader{
anchors.centerIn: parent anchors.centerIn: parent
sourceComponent: { sourceComponent: {
if(model&&model.iconDelegate){ if(model&&model.iconDelegate){
@ -636,7 +611,7 @@ Item {
right: item_dot_loader.left right: item_dot_loader.left
} }
} }
Loader{ FluLoader{
id:item_edit_loader id:item_edit_loader
anchors{ anchors{
top: parent.top top: parent.top
@ -655,7 +630,7 @@ Item {
return model.showEdit ? model.editDelegate : undefined return model.showEdit ? model.editDelegate : undefined
} }
onStatusChanged: { onStatusChanged: {
if(status === Loader.Ready){ if(status === FluLoader.Ready){
item.forceActiveFocus() item.forceActiveFocus()
item_connection_edit_focus.target = item item_connection_edit_focus.target = item
} }
@ -674,7 +649,7 @@ Item {
} }
} }
} }
Loader{ FluLoader{
id:item_dot_loader id:item_dot_loader
property bool isDot: (item_dot_loader.item&&item_dot_loader.item.isDot) property bool isDot: (item_dot_loader.item&&item_dot_loader.item.isDot)
anchors{ anchors{
@ -705,11 +680,12 @@ Item {
Item { Item {
id:nav_app_bar id:nav_app_bar
width: parent.width width: parent.width
height: 40 height: visible ? 40 : 0
anchors{ anchors{
top: parent.top top: parent.top
topMargin: control.topPadding topMargin: control.topPadding
} }
visible: !control.hideNavAppBar
z:999 z:999
RowLayout{ RowLayout{
height:parent.height height:parent.height
@ -818,7 +794,7 @@ Item {
} }
return 0 return 0
} }
Loader{ FluLoader{
id:loader_action id:loader_action
anchors.centerIn: parent anchors.centerIn: parent
sourceComponent: actionItem sourceComponent: actionItem
@ -860,16 +836,7 @@ Item {
} }
} }
} }
DropArea{ FluLoader{
anchors.fill: loader_content
onDropped:
(drag)=>{
if(drag.source.modelData){
drag.source.modelData.dropped(drag)
}
}
}
Loader{
id:loader_content id:loader_content
anchors{ anchors{
left: parent.left left: parent.left
@ -881,7 +848,7 @@ Item {
return 0 return 0
} }
if(d.isCompact){ if(d.isCompact){
return 50 return control.navCompactWidth
} }
return control.cellWidth return control.cellWidth
} }
@ -909,12 +876,13 @@ Item {
id:layout_list id:layout_list
width: { width: {
if(d.isCompactAndNotPanel){ if(d.isCompactAndNotPanel){
return 50 return control.navCompactWidth
} }
return control.cellWidth return control.cellWidth
} }
anchors{ anchors{
top: parent.top top: parent.top
topMargin: control.navTopMargin
bottom: parent.bottom bottom: parent.bottom
} }
border.color: FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,230/255,234/255,1) border.color: FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,230/255,234/255,1)
@ -955,7 +923,7 @@ Item {
clip: true clip: true
y:nav_app_bar.height+control.topPadding y:nav_app_bar.height+control.topPadding
height: autoSuggestBox ? 38 : 0 height: autoSuggestBox ? 38 : 0
Loader{ FluLoader{
id:loader_auto_suggest_box id:loader_auto_suggest_box
sourceComponent: autoSuggestBox sourceComponent: autoSuggestBox
anchors{ anchors{
@ -974,13 +942,13 @@ Item {
} }
FluIconButton{ FluIconButton{
visible:d.isCompactAndNotPanel visible:d.isCompactAndNotPanel
hoverColor: FluTheme.dark ? Qt.rgba(1,1,1,0.03) : Qt.rgba(0,0,0,0.03) anchors{
pressedColor: FluTheme.dark ? Qt.rgba(1,1,1,0.03) : Qt.rgba(0,0,0,0.03) fill: parent
normalColor: FluTheme.dark ? Qt.rgba(0,0,0,0) : Qt.rgba(0,0,0,0) leftMargin: 6
width:38 rightMargin: 6
height:34 topMargin: 2
x:6 bottomMargin: 2
y:2 }
iconSize: 15 iconSize: 15
iconSource: { iconSource: {
if(loader_auto_suggest_box.item){ if(loader_auto_suggest_box.item){
@ -1008,7 +976,6 @@ Item {
ScrollBar.vertical: FluScrollBar {} ScrollBar.vertical: FluScrollBar {}
ListView{ ListView{
id:nav_list id:nav_list
clip: true
displaced: Transition { displaced: Transition {
NumberAnimation { NumberAnimation {
properties: "x,y" properties: "x,y"
@ -1025,7 +992,7 @@ Item {
Rectangle{ Rectangle{
height: 18 height: 18
radius: 1.5 radius: 1.5
color: FluTheme.primaryColor.dark color: FluTheme.primaryColor
width: 3 width: 3
anchors{ anchors{
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
@ -1035,7 +1002,7 @@ Item {
} }
} }
currentIndex: -1 currentIndex: -1
delegate: Loader{ delegate: FluLoader{
property var model: modelData property var model: modelData
property var _idx: index property var _idx: index
property int type: 0 property int type: 0
@ -1083,7 +1050,7 @@ Item {
Rectangle{ Rectangle{
height: 18 height: 18
radius: 1.5 radius: 1.5
color: FluTheme.primaryColor.dark color: FluTheme.primaryColor
width: 3 width: 3
anchors{ anchors{
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
@ -1092,7 +1059,7 @@ Item {
} }
} }
} }
delegate: Loader{ delegate: FluLoader{
property var model: modelData property var model: modelData
property var _idx: index property var _idx: index
property int type: 1 property int type: 1
@ -1138,6 +1105,7 @@ Item {
clip: true clip: true
currentIndex: -1 currentIndex: -1
model: control_popup.childModel model: control_popup.childModel
boundsBehavior: ListView.StopAtBounds
ScrollBar.vertical: FluScrollBar {} ScrollBar.vertical: FluScrollBar {}
delegate:Button{ delegate:Button{
id:item_button id:item_button
@ -1146,24 +1114,17 @@ Item {
focusPolicy:Qt.TabFocus focusPolicy:Qt.TabFocus
background: Rectangle{ background: Rectangle{
color: { color: {
if(FluTheme.dark){ if(item_button.hovered){
if(item_button.hovered){ return FluTheme.itemHoverColor
return Qt.rgba(1,1,1,0.06)
}
return Qt.rgba(0,0,0,0)
}else{
if(item_button.hovered){
return Qt.rgba(0,0,0,0.03)
}
return Qt.rgba(0,0,0,0)
} }
return FluTheme.itemNormalColor
} }
FluFocusRectangle{ FluFocusRectangle{
visible: item_button.activeFocus visible: item_button.activeFocus
radius:4 radius:4
} }
Loader{ FluLoader{
id:item_dot_loader id:item_dot_loader
anchors{ anchors{
right: parent.right right: parent.right
@ -1220,9 +1181,18 @@ Item {
control_popup.open() control_popup.open()
} }
} }
Loader{ FluLoader{
property var modelData
id:loader_item_menu id:loader_item_menu
} }
Connections{
id:connection_item_menu
function onVisibleChanged(visible){
if(target.visible === false){
loader_item_menu.sourceComponent = undefined
}
}
}
Component{ Component{
id:com_placeholder id:com_placeholder
Item{ Item{

View File

@ -25,6 +25,4 @@ QtObject {
property Component editDelegate property Component editDelegate
property bool showEdit property bool showEdit
signal tap signal tap
signal dropped(var drag)
} }

View File

@ -25,7 +25,7 @@ TextField{
leftPadding: padding+4 leftPadding: padding+4
echoMode:btn_reveal.pressed ? TextField.Normal : TextField.Password echoMode:btn_reveal.pressed ? TextField.Normal : TextField.Password
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
selectionColor: FluTools.colorAlpha(FluTheme.primaryColor.lightest,0.6) selectionColor: FluTools.colorAlpha(FluTheme.primaryColor,0.5)
selectedTextColor: color selectedTextColor: color
placeholderTextColor: { placeholderTextColor: {
if(!enabled){ if(!enabled){
@ -37,9 +37,9 @@ TextField{
return placeholderNormalColor return placeholderNormalColor
} }
selectByMouse: true selectByMouse: true
width: 240
background: FluTextBoxBackground{ background: FluTextBoxBackground{
inputItem: control inputItem: control
implicitWidth: 240
} }
Keys.onEnterPressed: (event)=> d.handleCommit(event) Keys.onEnterPressed: (event)=> d.handleCommit(event)
Keys.onReturnPressed:(event)=> d.handleCommit(event) Keys.onReturnPressed:(event)=> d.handleCommit(event)

View File

@ -36,7 +36,7 @@ Page {
Rectangle{ Rectangle{
height: 3 height: 3
radius: 1.5 radius: 1.5
color: FluTheme.primaryColor.dark color: FluTheme.primaryColor
width: nav_list.currentItem ? nav_list.currentItem.width : 0 width: nav_list.currentItem ? nav_list.currentItem.width : 0
y:d.tabY y:d.tabY
Behavior on width { Behavior on width {
@ -84,7 +84,7 @@ Page {
anchors.fill: parent anchors.fill: parent
Repeater{ Repeater{
model:d.children model:d.children
Loader{ FluLoader{
property var argument: modelData.argument property var argument: modelData.argument
anchors.fill: parent anchors.fill: parent
sourceComponent: modelData.contentItem sourceComponent: modelData.contentItem

View File

@ -11,13 +11,6 @@ Popup {
anchors.centerIn: Overlay.overlay anchors.centerIn: Overlay.overlay
closePolicy: Popup.CloseOnEscape closePolicy: Popup.CloseOnEscape
enter: Transition { enter: Transition {
NumberAnimation {
properties: "scale"
from:1.2
to:1
duration: FluTheme.enableAnimation ? 83 : 0
easing.type: Easing.OutCubic
}
NumberAnimation { NumberAnimation {
property: "opacity" property: "opacity"
duration: FluTheme.enableAnimation ? 83 : 0 duration: FluTheme.enableAnimation ? 83 : 0
@ -26,13 +19,6 @@ Popup {
} }
} }
exit:Transition { exit:Transition {
NumberAnimation {
properties: "scale"
from:1
to:1.2
duration: FluTheme.enableAnimation ? 83 : 0
easing.type: Easing.OutCubic
}
NumberAnimation { NumberAnimation {
property: "opacity" property: "opacity"
duration: FluTheme.enableAnimation ? 83 : 0 duration: FluTheme.enableAnimation ? 83 : 0
@ -43,5 +29,8 @@ Popup {
background: FluRectangle{ background: FluRectangle{
radius: [5,5,5,5] radius: [5,5,5,5]
color: FluTheme.dark ? Qt.rgba(43/255,43/255,43/255,1) : Qt.rgba(1,1,1,1) color: FluTheme.dark ? Qt.rgba(43/255,43/255,43/255,1) : Qt.rgba(1,1,1,1)
FluShadow{
radius: 5
}
} }
} }

View File

@ -5,7 +5,7 @@ import FluentUI 1.0
ProgressBar{ ProgressBar{
property real strokeWidth: 6 property real strokeWidth: 6
property bool progressVisible: false property bool progressVisible: false
property color color: FluTheme.dark ? FluTheme.primaryColor.lighter : FluTheme.primaryColor.dark property color color: FluTheme.primaryColor
property color backgroundColor : FluTheme.dark ? Qt.rgba(99/255,99/255,99/255,1) : Qt.rgba(214/255,214/255,214/255,1) property color backgroundColor : FluTheme.dark ? Qt.rgba(99/255,99/255,99/255,1) : Qt.rgba(214/255,214/255,214/255,1)
id:control id:control
indeterminate : true indeterminate : true

View File

@ -12,7 +12,7 @@ Button {
} }
property color normalColor: { property color normalColor: {
if(d.checked){ if(d.checked){
return FluTheme.dark ? FluTheme.primaryColor.lighter : FluTheme.primaryColor.dark return FluTheme.primaryColor
}else{ }else{
return FluTheme.dark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(254/255,254/255,254/255,1) return FluTheme.dark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(254/255,254/255,254/255,1)
} }
@ -66,7 +66,7 @@ Button {
width: parent.width * control.progress width: parent.width * control.progress
height: control.progress === 1 ? background.height : 3 height: control.progress === 1 ? background.height : 3
visible: !d.checked visible: !d.checked
color: FluTheme.dark ? FluTheme.primaryColor.lighter : FluTheme.primaryColor.dark color: FluTheme.primaryColor
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
Behavior on height{ Behavior on height{
enabled: control.progress !== 1 enabled: control.progress !== 1

View File

@ -6,7 +6,7 @@ import FluentUI 1.0
ProgressBar{ ProgressBar{
property real strokeWidth: 6 property real strokeWidth: 6
property bool progressVisible: false property bool progressVisible: false
property color color: FluTheme.dark ? FluTheme.primaryColor.lighter : FluTheme.primaryColor.dark property color color: FluTheme.primaryColor
property color backgroundColor : FluTheme.dark ? Qt.rgba(99/255,99/255,99/255,1) : Qt.rgba(214/255,214/255,214/255,1) property color backgroundColor : FluTheme.dark ? Qt.rgba(99/255,99/255,99/255,1) : Qt.rgba(214/255,214/255,214/255,1)
id:control id:control
indeterminate : true indeterminate : true

View File

@ -6,7 +6,7 @@ import FluentUI 1.0
Button { Button {
property string contentDescription: "" property string contentDescription: ""
property bool disabled: false property bool disabled: false
property color borderNormalColor: checked ? FluTheme.dark ? FluTheme.primaryColor.lighter : FluTheme.primaryColor.dark : FluTheme.dark ? Qt.rgba(161/255,161/255,161/255,1) : Qt.rgba(141/255,141/255,141/255,1) property color borderNormalColor: checked ? FluTheme.primaryColor : FluTheme.dark ? Qt.rgba(161/255,161/255,161/255,1) : Qt.rgba(141/255,141/255,141/255,1)
property color borderDisableColor: FluTheme.dark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(198/255,198/255,198/255,1) property color borderDisableColor: FluTheme.dark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(198/255,198/255,198/255,1)
property color normalColor: FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(1,1,1,1) property color normalColor: FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(1,1,1,1)
property color hoverColor: checked ? FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(1,1,1,1) : FluTheme.dark ? Qt.rgba(43/255,43/255,43/255,1) : Qt.rgba(222/255,222/255,222/255,1) property color hoverColor: checked ? FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(1,1,1,1) : FluTheme.dark ? Qt.rgba(43/255,43/255,43/255,1) : Qt.rgba(222/255,222/255,222/255,1)

View File

@ -41,7 +41,7 @@ T.RangeSlider {
} }
return control.first.hovered ? 1.2 : 1 return control.first.hovered ? 1.2 : 1
} }
iconColor:FluTheme.dark ? FluTheme.primaryColor.lighter :FluTheme.primaryColor.dark iconColor: FluTheme.primaryColor
anchors.centerIn: parent anchors.centerIn: parent
Behavior on scale{ Behavior on scale{
NumberAnimation{ NumberAnimation{
@ -72,7 +72,7 @@ T.RangeSlider {
} }
return control.second.hovered ? 1.2 : 1 return control.second.hovered ? 1.2 : 1
} }
iconColor:FluTheme.dark ? FluTheme.primaryColor.lighter :FluTheme.primaryColor.dark iconColor: FluTheme.primaryColor
anchors.centerIn: parent anchors.centerIn: parent
Behavior on scale{ Behavior on scale{
NumberAnimation{ NumberAnimation{
@ -101,7 +101,7 @@ T.RangeSlider {
y: control.horizontal ? 0 : control.second.visualPosition * parent.height + 3 y: control.horizontal ? 0 : control.second.visualPosition * parent.height + 3
width: control.horizontal ? control.second.position * parent.width - control.first.position * parent.width - 6 : 6 width: control.horizontal ? control.second.position * parent.width - control.first.position * parent.width - 6 : 6
height: control.horizontal ? 6 : control.second.position * parent.height - control.first.position * parent.height - 6 height: control.horizontal ? 6 : control.second.position * parent.height - control.first.position * parent.height - 6
color:FluTheme.dark ? FluTheme.primaryColor.lighter :FluTheme.primaryColor.dark color: FluTheme.primaryColor
} }
} }
FluTooltip{ FluTooltip{

View File

@ -32,7 +32,7 @@ Item {
} }
iconSize: control.size iconSize: control.size
iconSource: isSelected ? FluentIcons.FavoriteStarFill : FluentIcons.FavoriteStar iconSource: isSelected ? FluentIcons.FavoriteStarFill : FluentIcons.FavoriteStar
iconColor: isSelected ? FluTheme.primaryColor.dark : (FluTheme.dark ? "#FFFFFF" : "#000000") iconColor: isSelected ? FluTheme.primaryColor : (FluTheme.dark ? "#FFFFFF" : "#000000")
anchors.centerIn: parent anchors.centerIn: parent
} }
} }

View File

@ -15,7 +15,7 @@ FluStatusView {
loader.source = control.source loader.source = control.source
} }
} }
Loader{ FluLoader{
id:loader id:loader
anchors.fill: parent anchors.fill: parent
asynchronous: true asynchronous: true

View File

@ -11,7 +11,7 @@ Item{
property int dotSize: 5 property int dotSize: 5
property int borderSize: 1 property int borderSize: 1
property var saveFolder: StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0] property var saveFolder: StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0]
property color borderColor: FluTheme.primaryColor.dark property color borderColor: FluTheme.primaryColor
signal captrueCompleted(var captrue) signal captrueCompleted(var captrue)
QtObject{ QtObject{
id:d id:d
@ -508,7 +508,7 @@ Item{
} }
FluIconButton{ FluIconButton{
iconSource: FluentIcons.AcceptMedium iconSource: FluentIcons.AcceptMedium
iconColor: FluTheme.primaryColor.dark iconColor: FluTheme.primaryColor
onClicked: { onClicked: {
screenshot_background.capture(screenshot.start,screenshot.end) screenshot_background.capture(screenshot.start,screenshot.end)
} }

View File

@ -39,7 +39,7 @@ T.Slider {
} }
return control.hovered ? 1.2 : 1 return control.hovered ? 1.2 : 1
} }
iconColor:FluTheme.dark ? FluTheme.primaryColor.lighter :FluTheme.primaryColor.dark iconColor: FluTheme.primaryColor
anchors.centerIn: parent anchors.centerIn: parent
} }
} }
@ -62,7 +62,7 @@ T.Slider {
width: control.horizontal ? control.position * parent.width : 6 width: control.horizontal ? control.position * parent.width : 6
height: control.horizontal ? 6 : control.position * parent.height height: control.horizontal ? 6 : control.position * parent.height
radius: 3 radius: 3
color:FluTheme.dark ? FluTheme.primaryColor.lighter :FluTheme.primaryColor.dark color: FluTheme.primaryColor
} }
} }
FluTooltip{ FluTooltip{

Some files were not shown because too many files have changed in this diff Show More