Compare commits

..

No commits in common. "d2fdd086043222e7ee2871be94fd317f101baf10" and "f0f00b9ebaca8891bf4a6a0c52dab62176e3fad7" have entirely different histories.

131 changed files with 6694 additions and 8227 deletions

View File

@ -91,14 +91,14 @@ jobs:
if: startsWith(github.event.ref, 'refs/tags/') if: startsWith(github.event.ref, 'refs/tags/')
uses: zhuzichu520/inno-setup-action@v1.0.1 uses: zhuzichu520/inno-setup-action@v1.0.1
with: with:
filepath: ./package/InstallerScript.iss filepath: ./action-cli/InstallerScript.iss
- name: uploadRelease - name: uploadRelease
if: startsWith(github.event.ref, 'refs/tags/') if: startsWith(github.event.ref, 'refs/tags/')
uses: svenstaro/upload-release-action@v2 uses: svenstaro/upload-release-action@v2
with: with:
repo_token: ${{ secrets.GITHUB_TOKEN }} repo_token: ${{ secrets.GITHUB_TOKEN }}
file: ./package/installer.exe file: ./action-cli/installer.exe
asset_name: ${{ env.fileName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}.exe asset_name: ${{ env.fileName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}.exe
tag: ${{ github.ref }} tag: ${{ github.ref }}
overwrite: true overwrite: true

View File

@ -78,14 +78,14 @@ jobs:
if: startsWith(github.event.ref, 'refs/tags/') if: startsWith(github.event.ref, 'refs/tags/')
uses: zhuzichu520/inno-setup-action@v1.0.1 uses: zhuzichu520/inno-setup-action@v1.0.1
with: with:
filepath: ./package/InstallerScript.iss filepath: ./action-cli/InstallerScript.iss
- name: uploadRelease - name: uploadRelease
if: startsWith(github.event.ref, 'refs/tags/') if: startsWith(github.event.ref, 'refs/tags/')
uses: svenstaro/upload-release-action@v2 uses: svenstaro/upload-release-action@v2
with: with:
repo_token: ${{ secrets.GITHUB_TOKEN }} repo_token: ${{ secrets.GITHUB_TOKEN }}
file: ./package/installer.exe file: ./action-cli/installer.exe
asset_name: ${{ env.fileName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}.exe asset_name: ${{ env.fileName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}.exe
tag: ${{ github.ref }} tag: ${{ github.ref }}
overwrite: true overwrite: true

View File

@ -85,14 +85,14 @@ jobs:
if: startsWith(github.event.ref, 'refs/tags/') if: startsWith(github.event.ref, 'refs/tags/')
uses: zhuzichu520/inno-setup-action@v1.0.1 uses: zhuzichu520/inno-setup-action@v1.0.1
with: with:
filepath: ./package/InstallerScript.iss filepath: ./action-cli/InstallerScript.iss
- name: uploadRelease - name: uploadRelease
if: startsWith(github.event.ref, 'refs/tags/') if: startsWith(github.event.ref, 'refs/tags/')
uses: svenstaro/upload-release-action@v2 uses: svenstaro/upload-release-action@v2
with: with:
repo_token: ${{ secrets.GITHUB_TOKEN }} repo_token: ${{ secrets.GITHUB_TOKEN }}
file: ./package/installer.exe file: ./action-cli/installer.exe
asset_name: ${{ env.fileName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}.exe asset_name: ${{ env.fileName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}.exe
tag: ${{ github.ref }} tag: ${{ github.ref }}
overwrite: true overwrite: true

4
.gitignore vendored
View File

@ -36,8 +36,10 @@ bin
build build
cmake-build-* cmake-build-*
.idea .idea
package
example/Version.h example/Version.h
action-cli
dist dist
*.qm *.qm

View File

@ -2,13 +2,13 @@ cmake_minimum_required(VERSION 3.20)
project(FluentUI VERSION 1.0) project(FluentUI VERSION 1.0)
if (MSVC) if(MSVC)
#Releasepdb #Releasepdb
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF") set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF") set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF")
endif () endif()
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/.cmake/) list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/.cmake/)
include(GetGitRevisionDescription) include(GetGitRevisionDescription)

View File

@ -10,18 +10,18 @@ set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
#FluentUI #FluentUI
if (FLUENTUI_BUILD_STATIC_LIB) if(FLUENTUI_BUILD_STATIC_LIB)
add_definitions(-DFLUENTUI_BUILD_STATIC_LIB) add_definitions(-DFLUENTUI_BUILD_STATIC_LIB)
endif () endif()
# #
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/${CMAKE_BUILD_TYPE}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/${CMAKE_BUILD_TYPE})
if (APPLE) if(APPLE)
set(APPLICATION_DIR_PATH ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${PROJECT_NAME}.app/Contents/MacOS) set(APPLICATION_DIR_PATH ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${PROJECT_NAME}.app/Contents/MacOS)
else () else()
set(APPLICATION_DIR_PATH ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) set(APPLICATION_DIR_PATH ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
endif () endif()
#Qt #Qt
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Quick Svg Network) find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Quick Svg Network)
@ -50,28 +50,28 @@ configure_file(
#Cpp #Cpp
file(GLOB_RECURSE CPP_FILES *.cpp *.h) file(GLOB_RECURSE CPP_FILES *.cpp *.h)
foreach (filepath ${CPP_FILES}) foreach(filepath ${CPP_FILES})
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" filename ${filepath}) string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" filename ${filepath})
list(APPEND sources_files ${filename}) list(APPEND sources_files ${filename})
endforeach (filepath) endforeach(filepath)
if (WIN32) if(WIN32)
list(APPEND sources_files "src/app_dmp.h") list(APPEND sources_files "src/app_dmp.h")
endif () endif()
#Windowsrcinno setup #Windowsrcinno setup
set(EXAMPLE_VERSION_RC_PATH "") set(EXAMPLE_VERSION_RC_PATH "")
if (WIN32) if(WIN32)
set(EXAMPLE_VERSION_RC_PATH ${CMAKE_CURRENT_BINARY_DIR}/version_${PROJECT_NAME}.rc) set(EXAMPLE_VERSION_RC_PATH ${CMAKE_CURRENT_BINARY_DIR}/version_${PROJECT_NAME}.rc)
configure_file( configure_file(
${CMAKE_SOURCE_DIR}/.cmake/version_exe.rc.in ${CMAKE_SOURCE_DIR}/.cmake/version_exe.rc.in
${EXAMPLE_VERSION_RC_PATH} ${EXAMPLE_VERSION_RC_PATH}
) )
configure_file( configure_file(
${CMAKE_SOURCE_DIR}/.cmake/InstallerScript.iss.in ${CMAKE_SOURCE_DIR}/.cmake/InstallerScript.iss.in
${CMAKE_SOURCE_DIR}/package/InstallerScript.iss ${CMAKE_SOURCE_DIR}/action-cli/InstallerScript.iss
) )
endif () endif()
#qrc #qrc
qt_add_big_resources(QRC_RESOURCES ${PROJECT_NAME}.qrc) qt_add_big_resources(QRC_RESOURCES ${PROJECT_NAME}.qrc)
@ -80,34 +80,34 @@ set_property(SOURCE ${PROJECT_NAME}.qrc PROPERTY SKIP_AUTORCC ON)
list(APPEND sources_files ${QRC_RESOURCES}) list(APPEND sources_files ${QRC_RESOURCES})
# #
if (WIN32) if(WIN32)
list(APPEND sources_files ${EXAMPLE_VERSION_RC_PATH}) list(APPEND sources_files ${EXAMPLE_VERSION_RC_PATH})
endif () endif()
if (${QT_VERSION_MAJOR} GREATER_EQUAL 6) if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
qt_add_executable(${PROJECT_NAME} qt_add_executable(${PROJECT_NAME}
MANUAL_FINALIZATION MANUAL_FINALIZATION
${sources_files} ${sources_files}
) )
else () else()
add_executable(${PROJECT_NAME} add_executable(${PROJECT_NAME}
${sources_files} ${sources_files}
) )
endif () endif()
add_dependencies(${PROJECT_NAME} Script-UpdateTranslations) add_dependencies(${PROJECT_NAME} Script-UpdateTranslations)
# #
if (WIN32) if(WIN32)
if (MSVC) if(MSVC)
if (CMAKE_SIZEOF_VOID_P EQUAL 4) if(CMAKE_SIZEOF_VOID_P EQUAL 4)
file(GLOB_RECURSE 3RDPARTY_DLL_DIR ${CMAKE_SOURCE_DIR}/3rdparty/msvc/x86/*.dll) file(GLOB_RECURSE 3RDPARTY_DLL_DIR ${CMAKE_SOURCE_DIR}/3rdparty/msvc/x86/*.dll)
elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
file(GLOB_RECURSE 3RDPARTY_DLL_DIR ${CMAKE_SOURCE_DIR}/3rdparty/msvc/x64/*.dll) file(GLOB_RECURSE 3RDPARTY_DLL_DIR ${CMAKE_SOURCE_DIR}/3rdparty/msvc/x64/*.dll)
endif () endif()
elseif (MINGW) elseif(MINGW)
file(GLOB_RECURSE 3RDPARTY_DLL_DIR ${CMAKE_SOURCE_DIR}/3rdparty/mingw/*.dll) file(GLOB_RECURSE 3RDPARTY_DLL_DIR ${CMAKE_SOURCE_DIR}/3rdparty/mingw/*.dll)
endif () endif()
file(COPY ${3RDPARTY_DLL_DIR} DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) file(COPY ${3RDPARTY_DLL_DIR} DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
endif () endif()
#FluentUI #FluentUI
file(MAKE_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/source/) file(MAKE_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/source/)
@ -119,11 +119,11 @@ target_include_directories(${PROJECT_NAME} PRIVATE
) )
#FluentUI.h #FluentUI.h
if (FLUENTUI_BUILD_STATIC_LIB) if(FLUENTUI_BUILD_STATIC_LIB)
target_include_directories(${PROJECT_NAME} PRIVATE target_include_directories(${PROJECT_NAME} PRIVATE
${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/src
) )
endif () endif()
# #
set_target_properties(${PROJECT_NAME} PROPERTIES set_target_properties(${PROJECT_NAME} PROPERTIES
@ -160,8 +160,8 @@ if (CMAKE_BUILD_TYPE MATCHES "Release")
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
) )
endif () endif()
if (WIN32) if(WIN32)
find_program(QT_DEPLOY_QT NAMES windeployqt) find_program(QT_DEPLOY_QT NAMES windeployqt)
add_custom_target(Script-DeployRelease add_custom_target(Script-DeployRelease
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_SOURCE_DIR}/dist COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_SOURCE_DIR}/dist
@ -171,5 +171,5 @@ if (CMAKE_BUILD_TYPE MATCHES "Release")
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
) )
endif () endif()
endif () endif()

View File

@ -127,6 +127,7 @@
<file>qml/global/ItemsOriginal.qml</file> <file>qml/global/ItemsOriginal.qml</file>
<file>qml/global/qmldir</file> <file>qml/global/qmldir</file>
<file>qml/page/T_Acrylic.qml</file> <file>qml/page/T_Acrylic.qml</file>
<file>qml/page/T_Awesome.qml</file>
<file>qml/page/T_Badge.qml</file> <file>qml/page/T_Badge.qml</file>
<file>qml/page/T_BreadcrumbBar.qml</file> <file>qml/page/T_BreadcrumbBar.qml</file>
<file>qml/page/T_Buttons.qml</file> <file>qml/page/T_Buttons.qml</file>
@ -180,6 +181,7 @@
<file>qml/window/PageWindow.qml</file> <file>qml/window/PageWindow.qml</file>
<file>qml/page/T_StaggeredLayout.qml</file> <file>qml/page/T_StaggeredLayout.qml</file>
<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_Network.qml</file> <file>qml/page/T_Network.qml</file>
<file>qml/page/T_ShortcutPicker.qml</file> <file>qml/page/T_ShortcutPicker.qml</file>
<file>qml/chart/T_BarChart.qml</file> <file>qml/chart/T_BarChart.qml</file>
@ -207,8 +209,5 @@
<file>qml/page/T_GroupBox.qml</file> <file>qml/page/T_GroupBox.qml</file>
<file>res/image/bg_scenic.jpg</file> <file>res/image/bg_scenic.jpg</file>
<file>qml/window/FluentInitializrWindow.qml</file> <file>qml/window/FluentInitializrWindow.qml</file>
<file>qml/page/T_OpenGL.qml</file>
<file>qml/page/T_Icons.qml</file>
</qresource> </qresource>
<qresource prefix="/"/>
</RCC> </RCC>

View File

@ -87,22 +87,22 @@
<context> <context>
<name>InitializrHelper</name> <name>InitializrHelper</name>
<message> <message>
<location filename="src/helper/InitializrHelper.cpp" line="69"/> <location filename="src/helper/InitializrHelper.cpp" line="77"/>
<source>The name cannot be empty</source> <source>The name cannot be empty</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="src/helper/InitializrHelper.cpp" line="73"/> <location filename="src/helper/InitializrHelper.cpp" line="81"/>
<source>The creation path cannot be empty</source> <source>The creation path cannot be empty</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="src/helper/InitializrHelper.cpp" line="78"/> <location filename="src/helper/InitializrHelper.cpp" line="86"/>
<source>The path does not exist</source> <source>The path does not exist</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="src/helper/InitializrHelper.cpp" line="84"/> <location filename="src/helper/InitializrHelper.cpp" line="92"/>
<source>%1 folder already exists</source> <source>%1 folder already exists</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -425,7 +425,7 @@
</message> </message>
<message> <message>
<location filename="qml/global/ItemsOriginal.qml" line="367"/> <location filename="qml/global/ItemsOriginal.qml" line="367"/>
<source>Icons</source> <source>Awesome</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
@ -475,44 +475,44 @@
</message> </message>
<message> <message>
<location filename="qml/global/ItemsOriginal.qml" line="430"/> <location filename="qml/global/ItemsOriginal.qml" line="430"/>
<source>OpenGL</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/global/ItemsOriginal.qml" line="436"/>
<source>QRCode</source> <source>QRCode</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/global/ItemsOriginal.qml" line="442"/> <location filename="qml/global/ItemsOriginal.qml" line="436"/>
<source>Tour</source> <source>Tour</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/global/ItemsOriginal.qml" line="448"/> <location filename="qml/global/ItemsOriginal.qml" line="442"/>
<source>Timeline</source> <source>Timeline</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/global/ItemsOriginal.qml" line="454"/> <location filename="qml/global/ItemsOriginal.qml" line="448"/>
<source>Captcha</source> <source>Captcha</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/global/ItemsOriginal.qml" line="460"/> <location filename="qml/global/ItemsOriginal.qml" line="454"/>
<source>Network</source> <source>Network</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/global/ItemsOriginal.qml" line="467"/> <location filename="qml/global/ItemsOriginal.qml" line="461"/>
<source>Remote Loader</source> <source>Remote Loader</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/global/ItemsOriginal.qml" line="481"/> <location filename="qml/global/ItemsOriginal.qml" line="475"/>
<source>Hot Loader</source> <source>Hot Loader</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location filename="qml/global/ItemsOriginal.qml" line="481"/>
<source>3D</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<location filename="qml/global/ItemsOriginal.qml" line="487"/> <location filename="qml/global/ItemsOriginal.qml" line="487"/>
<source>Test Crash</source> <source>Test Crash</source>
@ -545,105 +545,105 @@
</context> </context>
<context> <context>
<name>MainWindow</name> <name>MainWindow</name>
<message>
<location filename="qml/window/MainWindow.qml" line="87"/>
<location filename="qml/window/MainWindow.qml" line="95"/>
<source>Quit</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/window/MainWindow.qml" line="88"/>
<source>Are you sure you want to exit the program?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/window/MainWindow.qml" line="89"/>
<source>Minimize</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/window/MainWindow.qml" line="92"/>
<source>Friendly Reminder</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/window/MainWindow.qml" line="92"/>
<source>FluentUI is hidden from the tray, click on the tray to activate the window again</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/window/MainWindow.qml" line="96"/>
<location filename="qml/window/MainWindow.qml" line="340"/>
<source>Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/window/MainWindow.qml" line="107"/>
<source>Open in Separate Window</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/window/MainWindow.qml" line="204"/>
<source>Click Time</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/window/MainWindow.qml" line="214"/>
<source>Search</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/window/MainWindow.qml" line="305"/>
<source>Finish</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/window/MainWindow.qml" line="306"/>
<source>Next</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="307"/> <location filename="qml/window/MainWindow.qml" line="307"/>
<source>Previous</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/window/MainWindow.qml" line="311"/>
<source>Dark Mode</source> <source>Dark Mode</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="311"/> <location filename="qml/window/MainWindow.qml" line="83"/>
<location filename="qml/window/MainWindow.qml" line="91"/>
<source>Quit</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/window/MainWindow.qml" line="84"/>
<source>Are you sure you want to exit the program?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/window/MainWindow.qml" line="85"/>
<source>Minimize</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/window/MainWindow.qml" line="88"/>
<source>Friendly Reminder</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/window/MainWindow.qml" line="88"/>
<source>FluentUI is hidden from the tray, click on the tray to activate the window again</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/window/MainWindow.qml" line="92"/>
<location filename="qml/window/MainWindow.qml" line="336"/>
<source>Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/window/MainWindow.qml" line="103"/>
<source>Open in Separate Window</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/window/MainWindow.qml" line="200"/>
<source>Click Time</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/window/MainWindow.qml" line="210"/>
<source>Search</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/window/MainWindow.qml" line="301"/>
<source>Finish</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/window/MainWindow.qml" line="302"/>
<source>Next</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/window/MainWindow.qml" line="303"/>
<source>Previous</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/window/MainWindow.qml" line="307"/>
<source>Here you can switch to night mode.</source> <source>Here you can switch to night mode.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="313"/> <location filename="qml/window/MainWindow.qml" line="309"/>
<source>Hide Easter eggs</source> <source>Hide Easter eggs</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="313"/> <location filename="qml/window/MainWindow.qml" line="309"/>
<source>Try a few more clicks!!</source> <source>Try a few more clicks!!</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="337"/> <location filename="qml/window/MainWindow.qml" line="333"/>
<source>Upgrade Tips</source> <source>Upgrade Tips</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="338"/> <location filename="qml/window/MainWindow.qml" line="334"/>
<source>FluentUI is currently up to date </source> <source>FluentUI is currently up to date </source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="338"/> <location filename="qml/window/MainWindow.qml" line="334"/>
<source> -- The current app version</source> <source> -- The current app version</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="338"/> <location filename="qml/window/MainWindow.qml" line="334"/>
<source> <source>
Now go and download the new version Now go and download the new version
@ -652,17 +652,17 @@ Updated content:
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="341"/> <location filename="qml/window/MainWindow.qml" line="337"/>
<source>OK</source> <source>OK</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="368"/> <location filename="qml/window/MainWindow.qml" line="364"/>
<source>The current version is already the latest</source> <source>The current version is already the latest</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="375"/> <location filename="qml/window/MainWindow.qml" line="371"/>
<source>The network is abnormal</source> <source>The network is abnormal</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -769,6 +769,29 @@ Updated content:
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context>
<name>T_Awesome</name>
<message>
<location filename="qml/page/T_Awesome.qml" line="9"/>
<source>Awesome</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_Awesome.qml" line="13"/>
<source>Please enter a keyword</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_Awesome.qml" line="20"/>
<source>Search</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_Awesome.qml" line="55"/>
<source>You Copied </source>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>T_Badge</name> <name>T_Badge</name>
<message> <message>
@ -1084,6 +1107,46 @@ Updated content:
<source>Click to Select a Color - &gt;</source> <source>Click to Select a Color - &gt;</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location filename="qml/page/T_ColorPicker.qml" line="22"/>
<source>Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_ColorPicker.qml" line="23"/>
<source>OK</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_ColorPicker.qml" line="24"/>
<source>Color Picker</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_ColorPicker.qml" line="25"/>
<source>Edit Color</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_ColorPicker.qml" line="26"/>
<source>Red</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_ColorPicker.qml" line="27"/>
<source>Green</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_ColorPicker.qml" line="28"/>
<source>Blue</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_ColorPicker.qml" line="29"/>
<source>Opacity</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>T_ComboBox</name> <name>T_ComboBox</name>
@ -1298,49 +1361,26 @@ My only desire is to be permitted to drive out the traitors and restore the Han.
<context> <context>
<name>T_Home</name> <name>T_Home</name>
<message> <message>
<location filename="qml/page/T_Home.qml" line="19"/> <location filename="qml/page/T_Home.qml" line="23"/>
<source>FluentUI GitHub</source> <source>FluentUI GitHub</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_Home.qml" line="20"/> <location filename="qml/page/T_Home.qml" line="24"/>
<source>The latest FluentUI controls and styles for your applications.</source> <source>The latest FluentUI controls and styles for your applications.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_Home.qml" line="28"/> <location filename="qml/page/T_Home.qml" line="32"/>
<source>FluentUI Initializr</source> <source>FluentUI Initializr</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_Home.qml" line="29"/> <location filename="qml/page/T_Home.qml" line="33"/>
<source>FluentUI Initializr is a Tool that helps you create and customize Fluent UI projects with various options.</source> <source>FluentUI Initializr is a Tool that helps you create and customize Fluent UI projects with various options.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context>
<name>T_Icons</name>
<message>
<location filename="qml/page/T_Icons.qml" line="9"/>
<source>Icons</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_Icons.qml" line="13"/>
<source>Please enter a keyword</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_Icons.qml" line="20"/>
<source>Search</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_Icons.qml" line="60"/>
<source>You Copied </source>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>T_Image</name> <name>T_Image</name>
<message> <message>
@ -1581,14 +1621,6 @@ My only desire is to be permitted to drive out the traitors and restore the Han.
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context>
<name>T_OpenGL</name>
<message>
<location filename="qml/page/T_OpenGL.qml" line="11"/>
<source>OpenGL</source>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>T_Pagination</name> <name>T_Pagination</name>
<message> <message>
@ -1925,6 +1957,26 @@ Some contents...</source>
<source>StatusLayout</source> <source>StatusLayout</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location filename="qml/page/T_StatusLayout.qml" line="63"/>
<source>Loading...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_StatusLayout.qml" line="64"/>
<source>Empty</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_StatusLayout.qml" line="65"/>
<source>The page went wrong...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_StatusLayout.qml" line="66"/>
<source>Reload</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>T_TabView</name> <name>T_TabView</name>
@ -1968,7 +2020,7 @@ Some contents...</source>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="177"/> <location filename="qml/page/T_TableView.qml" line="177"/>
<location filename="qml/page/T_TableView.qml" line="499"/> <location filename="qml/page/T_TableView.qml" line="478"/>
<source>Name</source> <source>Name</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -1988,57 +2040,57 @@ Some contents...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="358"/> <location filename="qml/page/T_TableView.qml" line="337"/>
<source>Age</source> <source>Age</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="433"/> <location filename="qml/page/T_TableView.qml" line="412"/>
<source>Clear All</source> <source>Clear All</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="494"/> <location filename="qml/page/T_TableView.qml" line="473"/>
<source>Avatar</source> <source>Avatar</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="512"/> <location filename="qml/page/T_TableView.qml" line="491"/>
<source>Address</source> <source>Address</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="520"/> <location filename="qml/page/T_TableView.qml" line="498"/>
<source>Nickname</source> <source>Nickname</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="527"/> <location filename="qml/page/T_TableView.qml" line="505"/>
<source>Long String</source> <source>Long String</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="535"/> <location filename="qml/page/T_TableView.qml" line="513"/>
<source>Options</source> <source>Options</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="554"/> <location filename="qml/page/T_TableView.qml" line="532"/>
<source>&lt;Previous</source> <source>&lt;Previous</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="555"/> <location filename="qml/page/T_TableView.qml" line="533"/>
<source>Next&gt;</source> <source>Next&gt;</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="440"/> <location filename="qml/page/T_TableView.qml" line="419"/>
<source>Delete Selection</source> <source>Delete Selection</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="464"/> <location filename="qml/page/T_TableView.qml" line="443"/>
<source>Add a row of Data</source> <source>Add a row of Data</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -2125,11 +2177,6 @@ Some contents...</source>
<source>Open Animation</source> <source>Open Animation</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location filename="qml/page/T_Theme.qml" line="123"/>
<source>Open Blur Window</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>T_TimePicker</name> <name>T_TimePicker</name>
@ -2329,23 +2376,13 @@ Some contents...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TreeView.qml" line="183"/> <location filename="qml/page/T_TreeView.qml" line="44"/>
<source>Title</source> <source>Total %1 data, %2 data currently displayed</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TreeView.qml" line="187"/> <location filename="qml/page/T_TreeView.qml" line="48"/>
<source>Name</source> <source>A total of %1 data items are selected</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_TreeView.qml" line="191"/>
<source>Avatar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_TreeView.qml" line="195"/>
<source>Address</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>

View File

@ -87,22 +87,22 @@
<context> <context>
<name>InitializrHelper</name> <name>InitializrHelper</name>
<message> <message>
<location filename="src/helper/InitializrHelper.cpp" line="69"/> <location filename="src/helper/InitializrHelper.cpp" line="77"/>
<source>The name cannot be empty</source> <source>The name cannot be empty</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="src/helper/InitializrHelper.cpp" line="73"/> <location filename="src/helper/InitializrHelper.cpp" line="81"/>
<source>The creation path cannot be empty</source> <source>The creation path cannot be empty</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="src/helper/InitializrHelper.cpp" line="78"/> <location filename="src/helper/InitializrHelper.cpp" line="86"/>
<source>The path does not exist</source> <source>The path does not exist</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="src/helper/InitializrHelper.cpp" line="84"/> <location filename="src/helper/InitializrHelper.cpp" line="92"/>
<source>%1 folder already exists</source> <source>%1 folder already exists</source>
<translation type="unfinished">%1 </translation> <translation type="unfinished">%1 </translation>
</message> </message>
@ -425,7 +425,7 @@
</message> </message>
<message> <message>
<location filename="qml/global/ItemsOriginal.qml" line="367"/> <location filename="qml/global/ItemsOriginal.qml" line="367"/>
<source>Icons</source> <source>Awesome</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
@ -475,47 +475,43 @@
</message> </message>
<message> <message>
<location filename="qml/global/ItemsOriginal.qml" line="430"/> <location filename="qml/global/ItemsOriginal.qml" line="430"/>
<source>OpenGL</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/global/ItemsOriginal.qml" line="436"/>
<source>QRCode</source> <source>QRCode</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/global/ItemsOriginal.qml" line="442"/> <location filename="qml/global/ItemsOriginal.qml" line="436"/>
<source>Tour</source> <source>Tour</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/global/ItemsOriginal.qml" line="448"/> <location filename="qml/global/ItemsOriginal.qml" line="442"/>
<source>Timeline</source> <source>Timeline</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/global/ItemsOriginal.qml" line="454"/> <location filename="qml/global/ItemsOriginal.qml" line="448"/>
<source>Captcha</source> <source>Captcha</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/global/ItemsOriginal.qml" line="460"/> <location filename="qml/global/ItemsOriginal.qml" line="454"/>
<source>Network</source> <source>Network</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/global/ItemsOriginal.qml" line="467"/> <location filename="qml/global/ItemsOriginal.qml" line="461"/>
<source>Remote Loader</source> <source>Remote Loader</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/global/ItemsOriginal.qml" line="481"/> <location filename="qml/global/ItemsOriginal.qml" line="475"/>
<source>Hot Loader</source> <source>Hot Loader</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/global/ItemsOriginal.qml" line="481"/>
<source>3D</source> <source>3D</source>
<translation type="obsolete">3D</translation> <translation type="unfinished">3D</translation>
</message> </message>
<message> <message>
<location filename="qml/global/ItemsOriginal.qml" line="487"/> <location filename="qml/global/ItemsOriginal.qml" line="487"/>
@ -550,104 +546,104 @@
<context> <context>
<name>MainWindow</name> <name>MainWindow</name>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="311"/> <location filename="qml/window/MainWindow.qml" line="307"/>
<source>Dark Mode</source> <source>Dark Mode</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="87"/> <location filename="qml/window/MainWindow.qml" line="83"/>
<location filename="qml/window/MainWindow.qml" line="95"/> <location filename="qml/window/MainWindow.qml" line="91"/>
<source>Quit</source> <source>Quit</source>
<translation type="unfinished">退</translation> <translation type="unfinished">退</translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="88"/> <location filename="qml/window/MainWindow.qml" line="84"/>
<source>Are you sure you want to exit the program?</source> <source>Are you sure you want to exit the program?</source>
<translation type="unfinished">退</translation> <translation type="unfinished">退</translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="89"/> <location filename="qml/window/MainWindow.qml" line="85"/>
<source>Minimize</source> <source>Minimize</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="92"/> <location filename="qml/window/MainWindow.qml" line="88"/>
<source>Friendly Reminder</source> <source>Friendly Reminder</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="92"/> <location filename="qml/window/MainWindow.qml" line="88"/>
<source>FluentUI is hidden from the tray, click on the tray to activate the window again</source> <source>FluentUI is hidden from the tray, click on the tray to activate the window again</source>
<translation type="unfinished">FluentUI </translation> <translation type="unfinished">FluentUI </translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="96"/> <location filename="qml/window/MainWindow.qml" line="92"/>
<location filename="qml/window/MainWindow.qml" line="340"/> <location filename="qml/window/MainWindow.qml" line="336"/>
<source>Cancel</source> <source>Cancel</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="107"/> <location filename="qml/window/MainWindow.qml" line="103"/>
<source>Open in Separate Window</source> <source>Open in Separate Window</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="204"/> <location filename="qml/window/MainWindow.qml" line="200"/>
<source>Click Time</source> <source>Click Time</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="214"/> <location filename="qml/window/MainWindow.qml" line="210"/>
<source>Search</source> <source>Search</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="305"/> <location filename="qml/window/MainWindow.qml" line="301"/>
<source>Finish</source> <source>Finish</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="306"/> <location filename="qml/window/MainWindow.qml" line="302"/>
<source>Next</source> <source>Next</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="307"/> <location filename="qml/window/MainWindow.qml" line="303"/>
<source>Previous</source> <source>Previous</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="311"/> <location filename="qml/window/MainWindow.qml" line="307"/>
<source>Here you can switch to night mode.</source> <source>Here you can switch to night mode.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="313"/> <location filename="qml/window/MainWindow.qml" line="309"/>
<source>Hide Easter eggs</source> <source>Hide Easter eggs</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="313"/> <location filename="qml/window/MainWindow.qml" line="309"/>
<source>Try a few more clicks!!</source> <source>Try a few more clicks!!</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="337"/> <location filename="qml/window/MainWindow.qml" line="333"/>
<source>Upgrade Tips</source> <source>Upgrade Tips</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="338"/> <location filename="qml/window/MainWindow.qml" line="334"/>
<source>FluentUI is currently up to date </source> <source>FluentUI is currently up to date </source>
<translation type="unfinished">FluentUI </translation> <translation type="unfinished">FluentUI </translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="338"/> <location filename="qml/window/MainWindow.qml" line="334"/>
<source> -- The current app version</source> <source> -- The current app version</source>
<translation type="unfinished"> -- </translation> <translation type="unfinished"> -- </translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="338"/> <location filename="qml/window/MainWindow.qml" line="334"/>
<source> <source>
Now go and download the new version Now go and download the new version
@ -660,17 +656,17 @@ Updated content:
</translation> </translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="341"/> <location filename="qml/window/MainWindow.qml" line="337"/>
<source>OK</source> <source>OK</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="368"/> <location filename="qml/window/MainWindow.qml" line="364"/>
<source>The current version is already the latest</source> <source>The current version is already the latest</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/window/MainWindow.qml" line="375"/> <location filename="qml/window/MainWindow.qml" line="371"/>
<source>The network is abnormal</source> <source>The network is abnormal</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -780,20 +776,24 @@ Updated content:
<context> <context>
<name>T_Awesome</name> <name>T_Awesome</name>
<message> <message>
<location filename="qml/page/T_Awesome.qml" line="9"/>
<source>Awesome</source> <source>Awesome</source>
<translation type="obsolete"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_Awesome.qml" line="13"/>
<source>Please enter a keyword</source> <source>Please enter a keyword</source>
<translation type="obsolete"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_Awesome.qml" line="20"/>
<source>Search</source> <source>Search</source>
<translation type="obsolete"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_Awesome.qml" line="55"/>
<source>You Copied </source> <source>You Copied </source>
<translation type="obsolete"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context> <context>
@ -1112,36 +1112,44 @@ Updated content:
<translation type="unfinished"> - &gt;</translation> <translation type="unfinished"> - &gt;</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_ColorPicker.qml" line="22"/>
<source>Cancel</source> <source>Cancel</source>
<translation type="obsolete"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_ColorPicker.qml" line="23"/>
<source>OK</source> <source>OK</source>
<translation type="obsolete"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_ColorPicker.qml" line="24"/>
<source>Color Picker</source> <source>Color Picker</source>
<translation type="obsolete"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_ColorPicker.qml" line="25"/>
<source>Edit Color</source> <source>Edit Color</source>
<translation type="obsolete"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_ColorPicker.qml" line="26"/>
<source>Red</source> <source>Red</source>
<translation type="obsolete"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_ColorPicker.qml" line="27"/>
<source>Green</source> <source>Green</source>
<translation type="obsolete">绿</translation> <translation type="unfinished">绿</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_ColorPicker.qml" line="28"/>
<source>Blue</source> <source>Blue</source>
<translation type="obsolete"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_ColorPicker.qml" line="29"/>
<source>Opacity</source> <source>Opacity</source>
<translation type="obsolete"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context> <context>
@ -1384,49 +1392,26 @@ My only desire is to be permitted to drive out the traitors and restore the Han.
<context> <context>
<name>T_Home</name> <name>T_Home</name>
<message> <message>
<location filename="qml/page/T_Home.qml" line="19"/> <location filename="qml/page/T_Home.qml" line="23"/>
<source>FluentUI GitHub</source> <source>FluentUI GitHub</source>
<translation type="unfinished">FluentUI GitHub</translation> <translation type="unfinished">FluentUI GitHub</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_Home.qml" line="20"/> <location filename="qml/page/T_Home.qml" line="24"/>
<source>The latest FluentUI controls and styles for your applications.</source> <source>The latest FluentUI controls and styles for your applications.</source>
<translation type="unfinished"> FluentUI </translation> <translation type="unfinished"> FluentUI </translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_Home.qml" line="28"/> <location filename="qml/page/T_Home.qml" line="32"/>
<source>FluentUI Initializr</source> <source>FluentUI Initializr</source>
<translation type="unfinished">FluentUI脚手架</translation> <translation type="unfinished">FluentUI脚手架</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_Home.qml" line="29"/> <location filename="qml/page/T_Home.qml" line="33"/>
<source>FluentUI Initializr is a Tool that helps you create and customize Fluent UI projects with various options.</source> <source>FluentUI Initializr is a Tool that helps you create and customize Fluent UI projects with various options.</source>
<translation type="unfinished">FluentUI Fluent UI </translation> <translation type="unfinished">FluentUI Fluent UI </translation>
</message> </message>
</context> </context>
<context>
<name>T_Icons</name>
<message>
<location filename="qml/page/T_Icons.qml" line="9"/>
<source>Icons</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_Icons.qml" line="13"/>
<source>Please enter a keyword</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_Icons.qml" line="20"/>
<source>Search</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_Icons.qml" line="60"/>
<source>You Copied </source>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>T_Image</name> <name>T_Image</name>
<message> <message>
@ -1675,14 +1660,6 @@ My only desire is to be permitted to drive out the traitors and restore the Han.
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context>
<name>T_OpenGL</name>
<message>
<location filename="qml/page/T_OpenGL.qml" line="11"/>
<source>OpenGL</source>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>T_Pagination</name> <name>T_Pagination</name>
<message> <message>
@ -2052,20 +2029,24 @@ Some contents...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_StatusLayout.qml" line="63"/>
<source>Loading...</source> <source>Loading...</source>
<translation type="obsolete">...</translation> <translation type="unfinished">...</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_StatusLayout.qml" line="64"/>
<source>Empty</source> <source>Empty</source>
<translation type="obsolete"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_StatusLayout.qml" line="65"/>
<source>The page went wrong...</source> <source>The page went wrong...</source>
<translation type="obsolete">...</translation> <translation type="unfinished">...</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_StatusLayout.qml" line="66"/>
<source>Reload</source> <source>Reload</source>
<translation type="obsolete"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context> <context>
@ -2110,7 +2091,7 @@ Some contents...</source>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="177"/> <location filename="qml/page/T_TableView.qml" line="177"/>
<location filename="qml/page/T_TableView.qml" line="499"/> <location filename="qml/page/T_TableView.qml" line="478"/>
<source>Name</source> <source>Name</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -2130,57 +2111,57 @@ Some contents...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="358"/> <location filename="qml/page/T_TableView.qml" line="337"/>
<source>Age</source> <source>Age</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="433"/> <location filename="qml/page/T_TableView.qml" line="412"/>
<source>Clear All</source> <source>Clear All</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="494"/> <location filename="qml/page/T_TableView.qml" line="473"/>
<source>Avatar</source> <source>Avatar</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="512"/> <location filename="qml/page/T_TableView.qml" line="491"/>
<source>Address</source> <source>Address</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="520"/> <location filename="qml/page/T_TableView.qml" line="498"/>
<source>Nickname</source> <source>Nickname</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="527"/> <location filename="qml/page/T_TableView.qml" line="505"/>
<source>Long String</source> <source>Long String</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="535"/> <location filename="qml/page/T_TableView.qml" line="513"/>
<source>Options</source> <source>Options</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="554"/> <location filename="qml/page/T_TableView.qml" line="532"/>
<source>&lt;Previous</source> <source>&lt;Previous</source>
<translation type="unfinished">&lt;</translation> <translation type="unfinished">&lt;</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="555"/> <location filename="qml/page/T_TableView.qml" line="533"/>
<source>Next&gt;</source> <source>Next&gt;</source>
<translation type="unfinished">&gt;</translation> <translation type="unfinished">&gt;</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="440"/> <location filename="qml/page/T_TableView.qml" line="419"/>
<source>Delete Selection</source> <source>Delete Selection</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TableView.qml" line="464"/> <location filename="qml/page/T_TableView.qml" line="443"/>
<source>Add a row of Data</source> <source>Add a row of Data</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -2267,11 +2248,6 @@ Some contents...</source>
<source>Open Animation</source> <source>Open Animation</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location filename="qml/page/T_Theme.qml" line="123"/>
<source>Open Blur Window</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>T_TimePicker</name> <name>T_TimePicker</name>
@ -2483,32 +2459,14 @@ Some contents...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TreeView.qml" line="44"/>
<source>Total %1 data, %2 data currently displayed</source> <source>Total %1 data, %2 data currently displayed</source>
<translation type="obsolete">%1%2</translation> <translation type="unfinished">%1%2</translation>
</message> </message>
<message> <message>
<location filename="qml/page/T_TreeView.qml" line="48"/>
<source>A total of %1 data items are selected</source> <source>A total of %1 data items are selected</source>
<translation type="obsolete">%1</translation> <translation type="unfinished">%1</translation>
</message>
<message>
<location filename="qml/page/T_TreeView.qml" line="183"/>
<source>Title</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_TreeView.qml" line="195"/>
<source>Address</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_TreeView.qml" line="191"/>
<source>Avatar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="qml/page/T_TreeView.qml" line="187"/>
<source>Name</source>
<translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context> <context>

View File

@ -364,9 +364,9 @@ FluObject{
onTap: { navigationView.push(url) } onTap: { navigationView.push(url) }
} }
FluPaneItem{ FluPaneItem{
title: qsTr("Icons") title: qsTr("Awesome")
menuDelegate: paneItemMenu menuDelegate: paneItemMenu
url: "qrc:/example/qml/page/T_Icons.qml" url: "qrc:/example/qml/page/T_Awesome.qml"
onTap: { navigationView.push(url) } onTap: { navigationView.push(url) }
} }
} }
@ -426,12 +426,6 @@ FluObject{
FluPaneItemExpander{ FluPaneItemExpander{
title: qsTr("Other") title: qsTr("Other")
icon: FluentIcons.Shop icon: FluentIcons.Shop
FluPaneItem{
title: qsTr("OpenGL")
menuDelegate: paneItemMenu
url: "qrc:/example/qml/page/T_OpenGL.qml"
onTap: { navigationView.push(url) }
}
FluPaneItem{ FluPaneItem{
title: qsTr("QRCode") title: qsTr("QRCode")
menuDelegate: paneItemMenu menuDelegate: paneItemMenu
@ -483,6 +477,12 @@ FluObject{
FluRouter.navigate("/hotload") FluRouter.navigate("/hotload")
} }
} }
FluPaneItem{
title: qsTr("3D")
menuDelegate: paneItemMenu
url: "qrc:/example/qml/page/T_3D.qml"
onTap: { navigationView.push(url) }
}
FluPaneItem{ FluPaneItem{
title: qsTr("Test Crash") title: qsTr("Test Crash")
onTapListener: function(){ onTapListener: function(){

116
example/qml/page/T_3D.qml Normal file
View File

@ -0,0 +1,116 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15
import QtQuick.Window 2.15
import Qt3D.Core 2.15
import Qt3D.Render 2.15
import Qt3D.Input 2.12
import Qt3D.Extras 2.15
import QtQuick.Scene3D 2.15
import Qt.labs.platform 1.1
import FluentUI 1.0
import "../component"
FluContentPage{
id:root
title:"3D"
Scene3D{
id:scene_3d
anchors.fill: parent
focus: true
aspects: ["input", "logic"]
cameraAspectRatioMode: Scene3D.AutomaticAspectRatio
Entity {
Camera {
id: camera
projectionType: CameraLens.PerspectiveProjection
fieldOfView: 22.5
aspectRatio: scene_3d.width / scene_3d.height
nearPlane: 1
farPlane: 1000.0
viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )
upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
position: Qt.vector3d( 0.0, 0.0, 15.0 )
}
FirstPersonCameraController {
linearSpeed: 100
lookSpeed: 50
camera: camera
}
components: [
RenderSettings{
activeFrameGraph: ForwardRenderer{
clearColor: Qt.rgba(0,0,0,0);
camera: camera
}
},
InputSettings{}
]
Mesh {
id: mesh
source: "https://zhu-zichu.gitee.io/test.obj"
}
PhongMaterial {
id: material
ambient: color_picker.current
}
Transform{
id:transform
scale: 1.0
translation: Qt.vector3d(0, 0, 0)
rotation: fromEulerAngles(0, 0, 0)
property real hAngle:0.0
NumberAnimation on hAngle{
from:0
to:360.0
duration: 5000
loops: Animation.Infinite
}
matrix:{
var m=Qt.matrix4x4();
m.rotate(hAngle,Qt.vector3d(0,1,0));
m.translate(Qt.vector3d(0,0,0));
return m;
}
}
Entity {
id: entity
components: [mesh, material,transform]
}
}
}
ColumnLayout{
RowLayout{
spacing: 10
Layout.topMargin: 20
FluText{
text:"tintColor:"
Layout.alignment: Qt.AlignVCenter
}
FluColorPicker{
id:color_picker
current: "gray"
}
}
FluButton{
text:"选择obj资源"
onClicked: {
file_dialog.open()
}
}
}
FileDialog {
id: file_dialog
nameFilters: ["Obj files (*.obj)"]
folder: StandardPaths.writableLocation(StandardPaths.DocumentsLocation)
onAccepted: {
var fileUrl = file_dialog.currentFile
mesh.source = fileUrl
}
}
}

View File

@ -6,13 +6,13 @@ import FluentUI 1.0
FluContentPage { FluContentPage {
title: qsTr("Icons") title: qsTr("Awesome")
FluTextBox{ FluTextBox{
id: text_box id:text_box
placeholderText: qsTr("Please enter a keyword") placeholderText: qsTr("Please enter a keyword")
anchors{ anchors{
top: parent.top top:parent.top
} }
} }
@ -24,49 +24,47 @@ FluContentPage {
leftMargin: 14 leftMargin: 14
} }
onClicked: { onClicked: {
grid_view.model = FluApp.iconDatas(text_box.text) grid_view.model = FluTheme.awesomeList(text_box.text)
} }
} }
GridView{ GridView{
id: grid_view id:grid_view
cellWidth: 110 cellWidth: 80
cellHeight: 110 cellHeight: 80
clip: true clip: true
boundsBehavior: GridView.StopAtBounds boundsBehavior: GridView.StopAtBounds
model: FluApp.iconDatas() model:FluTheme.awesomeList()
ScrollBar.vertical: FluScrollBar {} ScrollBar.vertical: FluScrollBar {}
anchors{ anchors{
topMargin: 10 topMargin: 10
top: text_box.bottom top:text_box.bottom
left: parent.left left: parent.left
right: parent.right right: parent.right
bottom: parent.bottom bottom: parent.bottom
} }
delegate: Item { delegate: Item {
width: 100 width: 68
height: 100 height: 80
FluIconButton{ FluIconButton{
id:item_icon id:item_icon
iconSource: modelData.icon iconSource:modelData.icon
iconSize: 30 anchors.horizontalCenter: parent.horizontalCenter
padding: 0
verticalPadding: 0
horizontalPadding: 0
bottomPadding: 30
anchors.fill: parent
onClicked: { onClicked: {
var text ="FluentIcons."+modelData.name; var text ="FluentIcons."+modelData.name;
FluTools.clipText(text) FluTools.clipText(text)
showSuccess(qsTr("You Copied ")+text) showSuccess(qsTr("You Copied ")+text)
} }
FluText{ }
width: parent.width FluText {
horizontalAlignment: Qt.AlignHCenter id:item_name
font.pixelSize: 10
font.family: FluTextStyle.family
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: item_icon.bottom
width:parent.width
wrapMode: Text.WrapAnywhere wrapMode: Text.WrapAnywhere
text: modelData.name text: modelData.name
anchors.top: parent.top horizontalAlignment: Text.AlignHCenter
anchors.topMargin: 60
}
} }
} }
} }

View File

@ -18,7 +18,16 @@ FluScrollablePage{
text: qsTr("Click to Select a Color - >") text: qsTr("Click to Select a Color - >")
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
} }
FluColorPicker{} FluColorPicker{
cancelText: qsTr("Cancel")
okText: qsTr("OK")
titleText: qsTr("Color Picker")
editText: qsTr("Edit Color")
redText: qsTr("Red")
greenText: qsTr("Green")
blueText: qsTr("Blue")
opacityText: qsTr("Opacity")
}
} }
} }
CodeExpander{ CodeExpander{

View File

@ -12,6 +12,10 @@ FluScrollablePage{
animationEnabled: false animationEnabled: false
header: Item{} header: Item{}
FluentInitializrWindow{
id:fluent_Initializr
}
ListModel{ ListModel{
id: model_header id: model_header
ListElement{ ListElement{

View File

@ -1,26 +0,0 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import FluentUI 1.0
import example 1.0
import "../component"
FluContentPage{
title: qsTr("OpenGL")
FluFrame{
anchors.fill: parent
OpenGLItem{
anchors.fill: parent
SequentialAnimation on t {
NumberAnimation { to: 1; duration: 2500; easing.type: Easing.InQuad }
NumberAnimation { to: 0; duration: 2500; easing.type: Easing.OutQuad }
loops: Animation.Infinite
running: true
}
}
}
}

View File

@ -60,8 +60,12 @@ FluScrollablePage{
FluStatusLayout{ FluStatusLayout{
id:status_view id:status_view
anchors.fill: parent anchors.fill: parent
loadingText: qsTr("Loading...")
emptyText: qsTr("Empty")
errorText: qsTr("The page went wrong...")
errorButtonText: qsTr("Reload")
onErrorClicked:{ onErrorClicked:{
status_view.statusMode = FluStatusLayoutType.Loading showError("Click Reload")
} }
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent

View File

@ -280,27 +280,6 @@ FluContentPage{
} }
} }
Component{
id:com_auto_suggestbox
FluAutoSuggestBox {
id: textbox
anchors.fill: parent
focus: true
Component.onCompleted: {
var data = ["傲来国界花果山水帘洞","傲来国界坎源山脏水洞","大唐国界黑风山黑风洞","大唐国界黄风岭黄风洞","大唐国界骷髅山白骨洞","宝象国界碗子山波月洞","宝象国界平顶山莲花洞","宝象国界压龙山压龙洞","乌鸡国界号山枯松涧火云洞","乌鸡国界衡阳峪黑水河河神府"]
var result = data.map(function(item) {
return {title: item};
});
items = result
textbox.text= String(display)
}
onCommit: {
editTextChaged(textbox.text)
tableView.closeEditor()
}
}
}
Component{ Component{
id:com_avatar id:com_avatar
Item{ Item{
@ -511,7 +490,6 @@ FluContentPage{
{ {
title: qsTr("Address"), title: qsTr("Address"),
dataIndex: 'address', dataIndex: 'address',
editDelegate: com_auto_suggestbox,
width:200, width:200,
minimumWidth:100, minimumWidth:100,
maximumWidth:250 maximumWidth:250

View File

@ -13,7 +13,7 @@ FluScrollablePage{
FluFrame{ FluFrame{
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: 408 Layout.preferredHeight: 340
padding: 10 padding: 10
ColumnLayout{ ColumnLayout{
@ -119,17 +119,6 @@ FluScrollablePage{
FluTheme.animationEnabled = !FluTheme.animationEnabled FluTheme.animationEnabled = !FluTheme.animationEnabled
} }
} }
FluText{
text: qsTr("Open Blur Window")
Layout.topMargin: 20
}
FluToggleSwitch{
Layout.topMargin: 5
checked: FluTheme.blurBehindWindowEnabled
onClicked: {
FluTheme.blurBehindWindowEnabled = !FluTheme.blurBehindWindowEnabled
}
}
} }
} }
CodeExpander{ CodeExpander{

View File

@ -9,33 +9,14 @@ FluContentPage {
title: qsTr("TreeView") title: qsTr("TreeView")
function treeData(){ function treeData(){
const names = ["孙悟空", "猪八戒", "沙和尚", "唐僧","白骨夫人","金角大王","熊山君","黄风怪","银角大王"] const dig = (path = '0', level = 4) => {
function getRandomName(){
var randomIndex = Math.floor(Math.random() * names.length)
return names[randomIndex]
}
const addresses = ["傲来国界花果山水帘洞","傲来国界坎源山脏水洞","大唐国界黑风山黑风洞","大唐国界黄风岭黄风洞","大唐国界骷髅山白骨洞","宝象国界碗子山波月洞","宝象国界平顶山莲花洞","宝象国界压龙山压龙洞","乌鸡国界号山枯松涧火云洞","乌鸡国界衡阳峪黑水河河神府"]
function getRandomAddresses(){
var randomIndex = Math.floor(Math.random() * addresses.length)
return addresses[randomIndex]
}
const avatars = ["qrc:/example/res/svg/avatar_1.svg", "qrc:/example/res/svg/avatar_2.svg", "qrc:/example/res/svg/avatar_3.svg", "qrc:/example/res/svg/avatar_4.svg","qrc:/example/res/svg/avatar_5.svg","qrc:/example/res/svg/avatar_6.svg","qrc:/example/res/svg/avatar_7.svg","qrc:/example/res/svg/avatar_8.svg","qrc:/example/res/svg/avatar_9.svg","qrc:/example/res/svg/avatar_10.svg","qrc:/example/res/svg/avatar_11.svg","qrc:/example/res/svg/avatar_12.svg"]
function getRandomAvatar(){
var randomIndex = Math.floor(Math.random() * avatars.length);
return avatars[randomIndex];
}
const dig = (path = '0', level = 5) => {
const list = []; const list = [];
for (let i = 0; i < 4; i += 1) { for (let i = 0; i < 6; i += 1) {
const key = `${path}-${i}`; const key = `${path}-${i}`;
const treeNode = { const treeNode = {
title: key, title: key,
_key: key, key,
name: getRandomName(),
avatar:tree_view.customItem(com_avatar,{avatar:getRandomAvatar()}),
address: getRandomAddresses()
}; };
if (level > 0) { if (level > 0) {
treeNode.children = dig(key, level - 1); treeNode.children = dig(key, level - 1);
@ -47,46 +28,26 @@ FluContentPage {
return dig(); return dig();
} }
Component{ Column{
id:com_avatar id: layout_column
Item{
FluClip{
anchors.centerIn: parent
width: height
height: parent.height/3*2
radius: [height/2,height/2,height/2,height/2]
Image{
anchors.fill: parent
source: {
if(options && options.avatar){
return options.avatar
}
return ""
}
sourceSize: Qt.size(80,80)
}
}
}
}
FluFrame{
id:layout_controls
anchors{
left: parent.left
right: parent.right
top: parent.top
topMargin: 10
}
height: 80
clip: true
Row{
spacing: 12 spacing: 12
width: 300
anchors{ anchors{
top:parent.top
left: parent.left left: parent.left
leftMargin: 10 leftMargin: 10
verticalCenter: parent.verticalCenter bottom:parent.bottom
bottomMargin: 20
} }
Column{
anchors.verticalCenter: parent.verticalCenter FluText{
text: qsTr("Total %1 data, %2 data currently displayed").arg(tree_view.count()).arg(tree_view.visibleCount())
}
FluText{
text: qsTr("A total of %1 data items are selected").arg(tree_view.selectionModel().length)
}
RowLayout{ RowLayout{
spacing: 10 spacing: 10
FluText{ FluText{
@ -95,8 +56,8 @@ FluContentPage {
} }
FluSlider{ FluSlider{
id: slider_cell_height id: slider_cell_height
value: 38 value: 30
from: 38 from: 30
to:100 to:100
} }
} }
@ -108,29 +69,26 @@ FluContentPage {
} }
FluSlider{ FluSlider{
id: slider_depth_padding id: slider_depth_padding
value: 15 value: 30
from: 15 from: 30
to:100 to:100
} }
} }
}
Column{
spacing: 8
anchors.verticalCenter: parent.verticalCenter
FluToggleSwitch{ FluToggleSwitch{
id: switch_showline id: switch_showline
text:"showLine" text:"showLine"
checked: false checked: false
} }
FluToggleSwitch{
id: switch_draggable
text:"draggable"
checked: false
}
FluToggleSwitch{ FluToggleSwitch{
id: switch_checkable id: switch_checkable
text:"checkable" text:"checkable"
checked: false checked: false
} }
}
Column{
spacing: 8
anchors.verticalCenter: parent.verticalCenter
FluButton{ FluButton{
text: "all expand" text: "all expand"
onClicked: { onClicked: {
@ -144,62 +102,29 @@ FluContentPage {
} }
} }
} }
FluButton{ FluFrame{
text: "print selection model"
onClicked: {
var printData = []
var data = tree_view.selectionModel();
console.debug(data.length)
for(var i = 0; i <= data.length-1 ; i++){
const newObj = Object.assign({}, data[i].data);
delete newObj["__parent"];
delete newObj["children"];
printData.push(newObj)
}
console.debug(JSON.stringify(printData))
}
}
}
}
FluTreeView{
id:tree_view
anchors{ anchors{
left: parent.left left: layout_column.right
top: layout_controls.bottom top: parent.top
topMargin: 10
bottom: parent.bottom bottom: parent.bottom
right: parent.right right: parent.right
rightMargin: 5
topMargin: 5
bottomMargin: 5
} }
FluShadow{}
FluTreeView{
id:tree_view
anchors.fill: parent
cellHeight: slider_cell_height.value cellHeight: slider_cell_height.value
draggable:switch_draggable.checked
showLine: switch_showline.checked showLine: switch_showline.checked
checkable:switch_checkable.checked checkable:switch_checkable.checked
depthPadding: slider_depth_padding.value depthPadding: slider_depth_padding.value
onCurrentChanged: {
showInfo(current.data.title)
}
columnSource:[
{
title: qsTr("Title"),
dataIndex: 'title',
width: 300
},{
title: qsTr("Name"),
dataIndex: 'name',
width: 100
},{
title: qsTr("Avatar"),
dataIndex: 'avatar',
width: 100
},{
title: qsTr("Address"),
dataIndex: 'address',
width: 200
},
]
Component.onCompleted: { Component.onCompleted: {
var data = treeData() var data = treeData()
dataSource = data dataSource = data
} }
} }
}
} }

View File

@ -20,7 +20,7 @@ FluWindowDialog {
showError(message) showError(message)
} }
function onSuccess(path){ function onSuccess(path){
FluTools.showFileInFolder(path) FluTools.showFileInFolder(path+"/CMakeLists.txt")
window.close() window.close()
} }
} }

View File

@ -15,7 +15,7 @@ FluWindow {
title: "FluentUI" title: "FluentUI"
width: 1000 width: 1000
height: 680 height: 680
minimumWidth: 680 minimumWidth: 520
minimumHeight: 200 minimumHeight: 200
launchMode: FluWindowType.SingleTask launchMode: FluWindowType.SingleTask
fitsAppBarWindows: true fitsAppBarWindows: true
@ -28,10 +28,6 @@ FluWindow {
z:7 z:7
} }
FluentInitializrWindow{
id:fluent_Initializr
}
FluEvent{ FluEvent{
name: "checkUpdate" name: "checkUpdate"
onTriggered: { onTriggered: {

View File

@ -1,15 +1,17 @@
#include "AppInfo.h" #include "AppInfo.h"
#include <QQmlContext> #include <QQmlContext>
#include <QDebug>
#include <QGuiApplication> #include <QGuiApplication>
#include "Version.h" #include "Version.h"
AppInfo::AppInfo(QObject *parent) AppInfo::AppInfo(QObject *parent)
: QObject{parent} { : QObject{parent}
{
version(APPLICATION_VERSION); version(APPLICATION_VERSION);
} }
[[maybe_unused]] void AppInfo::testCrash() { void AppInfo::testCrash(){
auto *crash = reinterpret_cast<volatile int *>(0); auto *crash = reinterpret_cast<volatile int *>(0);
*crash = 0; *crash = 0;
} }

View File

@ -1,18 +1,20 @@
#pragma once #ifndef APPINFO_H
#define APPINFO_H
#include <QObject> #include <QObject>
#include <QQmlApplicationEngine> #include <QQmlApplicationEngine>
#include "stdafx.h" #include "stdafx.h"
#include "singleton.h" #include "singleton.h"
class AppInfo : public QObject { class AppInfo : public QObject
Q_OBJECT {
Q_PROPERTY_AUTO(QString, version) Q_OBJECT
Q_PROPERTY_AUTO(QString,version)
private: private:
explicit AppInfo(QObject *parent = nullptr); explicit AppInfo(QObject *parent = nullptr);
public: public:
SINGLETON(AppInfo) SINGLETON(AppInfo)
Q_INVOKABLE void testCrash();
[[maybe_unused]] Q_INVOKABLE void testCrash();
}; };
#endif // APPINFO_H

View File

@ -1,4 +1,5 @@
#pragma once #ifndef APP_DUMP_H
#define APP_DUMP_H
#include <Windows.h> #include <Windows.h>
#include <DbgHelp.h> #include <DbgHelp.h>
@ -11,22 +12,22 @@
#pragma comment(lib, "Dbghelp.lib") #pragma comment(lib, "Dbghelp.lib")
static void static void miniDumpWriteDump(HANDLE hProcess,DWORD ProcessId,HANDLE hFile,MINIDUMP_TYPE DumpType,CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam){
miniDumpWriteDump(HANDLE hProcess, DWORD ProcessId, HANDLE hFile, CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam) { typedef HRESULT (WINAPI* MiniDumpWriteDumpPtr)(HANDLE hProcess,DWORD ProcessId,HANDLE hFile,MINIDUMP_TYPE DumpType,CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
typedef HRESULT (WINAPI *MiniDumpWriteDumpPtr)(HANDLE hProcess, DWORD ProcessId, HANDLE hFile, MINIDUMP_TYPE DumpType, CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
HMODULE module = LoadLibraryW(L"Dbghelp.dll"); HMODULE module = LoadLibraryW(L"Dbghelp.dll");
if (module) { if (module)
{
MiniDumpWriteDumpPtr mini_dump_write_dump; MiniDumpWriteDumpPtr mini_dump_write_dump;
mini_dump_write_dump = reinterpret_cast<MiniDumpWriteDumpPtr>(GetProcAddress(module, "MiniDumpWriteDump")); mini_dump_write_dump= reinterpret_cast<MiniDumpWriteDumpPtr>(GetProcAddress(module, "MiniDumpWriteDump"));
if (mini_dump_write_dump) { if (mini_dump_write_dump)
mini_dump_write_dump(hProcess, ProcessId, hFile, static_cast<MINIDUMP_TYPE>(80), ExceptionParam, nullptr, CallbackParam); {
mini_dump_write_dump(hProcess,ProcessId,hFile,DumpType,ExceptionParam,UserStreamParam,CallbackParam);
} }
} }
} }
BOOL CALLBACK MyMiniDumpCallback(PVOID, const PMINIDUMP_CALLBACK_INPUT input, PMINIDUMP_CALLBACK_OUTPUT output) { BOOL CALLBACK MyMiniDumpCallback(PVOID, const PMINIDUMP_CALLBACK_INPUT input, PMINIDUMP_CALLBACK_OUTPUT output) {
if (input == nullptr || output == nullptr) if (input == NULL || output == NULL)
return FALSE; return FALSE;
BOOL ret = FALSE; BOOL ret = FALSE;
@ -42,38 +43,40 @@ BOOL CALLBACK MyMiniDumpCallback(PVOID, const PMINIDUMP_CALLBACK_INPUT input, PM
output->ModuleWriteFlags &= ~ModuleWriteModule; output->ModuleWriteFlags &= ~ModuleWriteModule;
} }
ret = TRUE; ret = TRUE;
} } break;
break;
default: default:
break; break;
} }
return ret; return ret;
} }
void WriteDump(EXCEPTION_POINTERS *exp, const std::wstring &path) { void WriteDump(EXCEPTION_POINTERS* exp, const std::wstring& path) {
HANDLE h = ::CreateFileW(path.c_str(), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); HANDLE h = ::CreateFileW(path.c_str(), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
MINIDUMP_EXCEPTION_INFORMATION info; MINIDUMP_EXCEPTION_INFORMATION info;
info.ThreadId = ::GetCurrentThreadId(); info.ThreadId = ::GetCurrentThreadId();
info.ExceptionPointers = exp; info.ExceptionPointers = exp;
info.ClientPointers = FALSE; info.ClientPointers = FALSE;
MINIDUMP_CALLBACK_INFORMATION mci; MINIDUMP_CALLBACK_INFORMATION mci;
mci.CallbackRoutine = (MINIDUMP_CALLBACK_ROUTINE) MyMiniDumpCallback; mci.CallbackRoutine = (MINIDUMP_CALLBACK_ROUTINE)MyMiniDumpCallback;
mci.CallbackParam = nullptr; mci.CallbackParam = 0;
miniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), h, &info, &mci); MINIDUMP_TYPE mdt = (MINIDUMP_TYPE)(MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory);
miniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), h, mdt, &info, NULL, &mci);
::CloseHandle(h); ::CloseHandle(h);
} }
LONG WINAPI MyUnhandledExceptionFilter(EXCEPTION_POINTERS *exp) { LONG WINAPI MyUnhandledExceptionFilter(EXCEPTION_POINTERS* exp) {
const QString dumpFileName = QString("%1_%2.dmp").arg("crash", QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss")); const QString dumpFileName = QString("%1_%2.dmp").arg("crash",QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss"));
const QString dumpDirPath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/dmp"; const QString dumpDirPath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)+"/dmp";
const QDir dumpDir(dumpDirPath); const QDir dumpDir(dumpDirPath);
if (!dumpDir.exists()) { if(!dumpDir.exists()){
dumpDir.mkpath(dumpDirPath); dumpDir.mkpath(dumpDirPath);
} }
QString dumpFilePath = dumpDir.filePath(dumpFileName); QString dumpFilePath = dumpDir.filePath(dumpFileName);
WriteDump(exp, dumpFilePath.toStdWString()); WriteDump(exp, dumpFilePath.toStdWString());
QStringList arguments; QStringList arguments;
arguments << "-crashed=" + dumpFilePath; arguments << "-crashed=" + dumpFilePath;
QProcess::startDetached(QGuiApplication::applicationFilePath(), arguments); QProcess::startDetached(qApp->applicationFilePath(), arguments);
return EXCEPTION_EXECUTE_HANDLER; return EXCEPTION_EXECUTE_HANDLER;
} }
#endif // APP_DUMP_H

View File

@ -3,43 +3,43 @@
#include <QQuickItemGrabResult> #include <QQuickItemGrabResult>
#include <QPainterPath> #include <QPainterPath>
CircularReveal::CircularReveal(QQuickItem *parent) : QQuickPaintedItem(parent) { CircularReveal::CircularReveal(QQuickItem* parent) : QQuickPaintedItem(parent)
_target = nullptr; {
_radius = 0;
_anim = new QPropertyAnimation(this, "radius", this); _anim = new QPropertyAnimation(this, "radius", this);
setVisible(false);
_anim->setDuration(333); _anim->setDuration(333);
_anim->setEasingCurve(QEasingCurve::OutCubic); _anim->setEasingCurve(QEasingCurve::OutCubic);
setVisible(false); connect(_anim, &QPropertyAnimation::finished,this,[=](){
connect(_anim, &QPropertyAnimation::finished, this, [=]() {
update(); update();
setVisible(false); setVisible(false);
Q_EMIT animationFinished(); Q_EMIT animationFinished();
}); });
connect(this, &CircularReveal::radiusChanged, this, [=]() { connect(this,&CircularReveal::radiusChanged,this,[=](){
update(); update();
}); });
} }
void CircularReveal::paint(QPainter *painter) { void CircularReveal::paint(QPainter* painter)
{
painter->save(); painter->save();
painter->drawImage(QRect(0, 0, static_cast<int>(width()), static_cast<int>(height())), _source); painter->drawImage(QRect(0, 0, static_cast<int>(width()), static_cast<int>(height())), _source);
QPainterPath path; QPainterPath path;
path.moveTo(_center.x(), _center.y()); path.moveTo(_center.x(),_center.y());
path.addEllipse(QPointF(_center.x(), _center.y()), _radius, _radius); path.addEllipse(QPointF(_center.x(),_center.y()), _radius, _radius);
painter->setCompositionMode(QPainter::CompositionMode_Clear); painter->setCompositionMode(QPainter::CompositionMode_Clear);
painter->fillPath(path, Qt::black); painter->fillPath(path, Qt::black);
painter->restore(); painter->restore();
} }
[[maybe_unused]] void CircularReveal::start(int w, int h, const QPoint &center, int radius) { void CircularReveal::start(int w,int h,const QPoint& center,int radius){
_anim->setStartValue(0); _anim->setStartValue(0);
_anim->setEndValue(radius); _anim->setEndValue(radius);
_center = center; _center = center;
_grabResult = _target->grabToImage(QSize(w, h)); _grabResult = _target->grabToImage(QSize(w,h));
connect(_grabResult.data(), &QQuickItemGrabResult::ready, this, &CircularReveal::handleGrabResult); connect(_grabResult.data(), &QQuickItemGrabResult::ready, this, &CircularReveal::handleGrabResult);
} }
void CircularReveal::handleGrabResult() { void CircularReveal::handleGrabResult(){
_grabResult.data()->image().swap(_source); _grabResult.data()->image().swap(_source);
update(); update();
setVisible(true); setVisible(true);

View File

@ -1,4 +1,5 @@
#pragma once #ifndef CIRCULARREVEAL_H
#define CIRCULARREVEAL_H
#include <QQuickItem> #include <QQuickItem>
#include <QQuickPaintedItem> #include <QQuickPaintedItem>
@ -6,26 +7,23 @@
#include <QPropertyAnimation> #include <QPropertyAnimation>
#include "src/stdafx.h" #include "src/stdafx.h"
class CircularReveal : public QQuickPaintedItem { class CircularReveal : public QQuickPaintedItem
Q_OBJECT {
Q_PROPERTY_AUTO_P(QQuickItem*, target) Q_OBJECT
Q_PROPERTY_AUTO(int, radius) Q_PROPERTY_AUTO(QQuickItem*,target)
Q_PROPERTY_AUTO(int,radius)
public: public:
explicit CircularReveal(QQuickItem *parent = nullptr); CircularReveal(QQuickItem* parent = nullptr);
void paint(QPainter* painter) override;
void paint(QPainter *painter) override; Q_INVOKABLE void start(int w,int h,const QPoint& center,int radius);
[[maybe_unused]] Q_INVOKABLE void start(int w, int h, const QPoint &center, int radius);
Q_SIGNAL void imageChanged(); Q_SIGNAL void imageChanged();
Q_SIGNAL void animationFinished(); Q_SIGNAL void animationFinished();
Q_SLOT void handleGrabResult(); Q_SLOT void handleGrabResult();
private: private:
QPropertyAnimation *_anim = nullptr; QPropertyAnimation* _anim = nullptr;
QImage _source; QImage _source;
QPoint _center; QPoint _center;
QSharedPointer<QQuickItemGrabResult> _grabResult; QSharedPointer<QQuickItemGrabResult> _grabResult;
}; };
#endif // CIRCULARREVEAL_H

View File

@ -1,23 +1,24 @@
#include "FileWatcher.h" #include "FileWatcher.h"
FileWatcher::FileWatcher(QObject *parent) : QObject{parent} { FileWatcher::FileWatcher(QObject *parent)
connect(&_watcher, &QFileSystemWatcher::fileChanged, this, [=](const QString &path) { : QObject{parent}
{
connect(&_watcher, &QFileSystemWatcher::fileChanged, this, [=](const QString &path){
Q_EMIT fileChanged(); Q_EMIT fileChanged();
clean(); clean();
_watcher.addPath(_path); _watcher.addPath(_path);
}); });
connect(this, &FileWatcher::pathChanged, this, [=]() { connect(this,&FileWatcher::pathChanged,this,[=](){
clean(); clean();
_watcher.addPath(_path.replace("file:///", "")); _watcher.addPath(_path.replace("file:///",""));
}); });
if (!_path.isEmpty()) { if(!_path.isEmpty()){
_watcher.addPath(_path); _watcher.addPath(_path);
} }
} }
void FileWatcher::clean() { void FileWatcher::clean(){
for (int i = 0; i <= _watcher.files().size() - 1; ++i) { foreach (const QString &item, _watcher.files()) {
auto item = _watcher.files().at(i);
_watcher.removePath(item); _watcher.removePath(item);
} }
} }

View File

@ -1,21 +1,22 @@
#pragma once #ifndef FILEWATCHER_H
#define FILEWATCHER_H
#include <QObject> #include <QObject>
#include <QFileSystemWatcher> #include <QFileSystemWatcher>
#include <QtQml/qqml.h> #include <QtQml/qqml.h>
#include "src/stdafx.h" #include "src/stdafx.h"
class FileWatcher : public QObject { class FileWatcher : public QObject
Q_OBJECT {
Q_PROPERTY_AUTO(QString, path); Q_OBJECT
Q_PROPERTY_AUTO(QString,path);
public: public:
explicit FileWatcher(QObject *parent = nullptr); explicit FileWatcher(QObject *parent = nullptr);
Q_SIGNAL void fileChanged(); Q_SIGNAL void fileChanged();
private: private:
void clean(); void clean();
private: private:
QFileSystemWatcher _watcher; QFileSystemWatcher _watcher;
}; };
#endif // FILEWATCHER_H

View File

@ -3,16 +3,16 @@
#include <QTimer> #include <QTimer>
#include <QQuickWindow> #include <QQuickWindow>
FpsItem::FpsItem() { FpsItem::FpsItem()
_fps = 0; {
auto *timer = new QTimer(this); QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, [this] { connect(timer, &QTimer::timeout, this, [this]{
fps(_frameCount); fps(_frameCount);
_frameCount = 0; _frameCount = 0;
}); });
connect(this, &QQuickItem::windowChanged, this, [this] { connect(this, &QQuickItem::windowChanged, this, [this]{
if (window()) { if (window()){
connect(window(), &QQuickWindow::afterRendering, this, [this] { _frameCount++; }, Qt::DirectConnection); connect(window(), &QQuickWindow::afterRendering, this, [this]{ _frameCount++; }, Qt::DirectConnection);
} }
}); });
timer->start(1000); timer->start(1000);

View File

@ -1,11 +1,13 @@
#pragma once #ifndef FPSITEM_H
#define FPSITEM_H
#include <QQuickItem> #include <QQuickItem>
#include "src/stdafx.h" #include "src/stdafx.h"
class FpsItem : public QQuickItem { class FpsItem : public QQuickItem
Q_OBJECT {
Q_PROPERTY_AUTO(int, fps) Q_OBJECT
Q_PROPERTY_AUTO(int,fps)
public: public:
FpsItem(); FpsItem();
@ -13,3 +15,5 @@ private:
int _frameCount = 0; int _frameCount = 0;
}; };
#endif // FPSITEM_H

View File

@ -1,93 +0,0 @@
#include "OpenGLItem.h"
#include <QOpenGLFramebufferObjectFormat>
#include <QOpenGLShaderProgram>
class FBORenderer : public QQuickFramebufferObject::Renderer, protected QOpenGLFunctions {
public:
explicit FBORenderer(const OpenGLItem *item);
void render() override;
QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) override;
QOpenGLShaderProgram program;
const OpenGLItem *item = nullptr;
};
FBORenderer::FBORenderer(const OpenGLItem *item) {
this->item = item;
initializeOpenGLFunctions();
program.addCacheableShaderFromSourceCode(QOpenGLShader::Vertex,
"attribute highp vec4 vertices;"
"varying highp vec2 coords;"
"void main() {"
" gl_Position = vertices;"
" coords = vertices.xy;"
"}");
program.addCacheableShaderFromSourceCode(QOpenGLShader::Fragment,
"uniform lowp float t;"
"varying highp vec2 coords;"
"void main() {"
" lowp float i = 1. - (pow(abs(coords.x), 4.) + pow(abs(coords.y), 4.));"
" i = smoothstep(t - 0.8, t + 0.8, i);"
" i = floor(i * 20.) / 20.;"
" gl_FragColor = vec4(coords * .5 + .5, i, i);"
"}");
program.bindAttributeLocation("vertices", 0);
program.link();
}
QOpenGLFramebufferObject *FBORenderer::createFramebufferObject(const QSize &size) {
QOpenGLFramebufferObjectFormat format;
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
format.setSamples(4);
return new QOpenGLFramebufferObject(size, format);
}
void FBORenderer::render() {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
program.bind();
program.enableAttributeArray(0);
float values[] = {
-1, -1,
1, -1,
-1, 1,
1, 1
};
glBindBuffer(GL_ARRAY_BUFFER, 0);
program.setAttributeArray(0, GL_FLOAT, values, 2);
program.setUniformValue("t", (float) item->t());
glViewport(0, 0, qRound(item->width()), qRound(item->height()));
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
program.disableAttributeArray(0);
program.release();
}
OpenGLItem::OpenGLItem(QQuickItem *parent) : QQuickFramebufferObject(parent) {
setMirrorVertically(true);
startTimer(1);
}
void OpenGLItem::timerEvent(QTimerEvent *) {
update();
}
void OpenGLItem::setT(qreal t) {
if (t == m_t)
return;
m_t = t;
emit tChanged();
}
QQuickFramebufferObject::Renderer *OpenGLItem::createRenderer() const {
return new FBORenderer(this);
}

View File

@ -1,29 +0,0 @@
#pragma once
#include <QtQuick/QQuickItem>
#include <QOpenGLFunctions>
#include <QQuickFramebufferObject>
class FBORenderer;
class OpenGLItem : public QQuickFramebufferObject, protected QOpenGLFunctions {
Q_OBJECT
Q_PROPERTY(qreal t READ t WRITE setT NOTIFY tChanged)
public:
explicit OpenGLItem(QQuickItem *parent = nullptr);
[[nodiscard]] QQuickFramebufferObject::Renderer *createRenderer() const override;
void timerEvent(QTimerEvent *) override;
[[nodiscard]] qreal t() const { return m_t; }
void setT(qreal t);
signals:
void tChanged();
private:
qreal m_t{};
};

View File

@ -3,31 +3,39 @@
#include <QDir> #include <QDir>
#include <QGuiApplication> #include <QGuiApplication>
[[maybe_unused]] InitializrHelper::InitializrHelper(QObject *parent) : QObject(parent) { InitializrHelper::InitializrHelper(QObject *parent) : QObject(parent)
{
} }
InitializrHelper::~InitializrHelper() = default; InitializrHelper::~InitializrHelper() = default;
bool InitializrHelper::copyDir(const QDir &fromDir, const QDir &toDir, bool coverIfFileExists) { bool InitializrHelper::copyDir(const QDir& fromDir, const QDir& toDir, bool coverIfFileExists){
const QDir &_formDir = fromDir; QDir _formDir = fromDir;
QDir _toDir = toDir; QDir _toDir = toDir;
if (!_toDir.exists()) { if(!_toDir.exists())
if (!_toDir.mkdir(toDir.absolutePath())) {
if(!_toDir.mkdir(toDir.absolutePath()))
return false; return false;
} }
QFileInfoList fileInfoList = _formDir.entryInfoList(); QFileInfoList fileInfoList = _formDir.entryInfoList();
foreach(QFileInfo fileInfo, fileInfoList) { foreach(QFileInfo fileInfo, fileInfoList)
if (fileInfo.fileName() == "." || fileInfo.fileName() == "..") {
if(fileInfo.fileName() == "." || fileInfo.fileName() == "..")
continue; continue;
if (fileInfo.isDir()) { if(fileInfo.isDir())
if (!copyDir(fileInfo.filePath(), _toDir.filePath(fileInfo.fileName()), true)) {
if(!copyDir(fileInfo.filePath(), _toDir.filePath(fileInfo.fileName()),true))
return false; return false;
} else { }
if (coverIfFileExists && _toDir.exists(fileInfo.fileName())) { else
{
if(coverIfFileExists && _toDir.exists(fileInfo.fileName()))
{
_toDir.remove(fileInfo.fileName()); _toDir.remove(fileInfo.fileName());
} }
if (!QFile::copy(fileInfo.filePath(), _toDir.filePath(fileInfo.fileName()))) { if(!QFile::copy(fileInfo.filePath(), _toDir.filePath(fileInfo.fileName())))
{
return false; return false;
} }
} }
@ -35,15 +43,15 @@ bool InitializrHelper::copyDir(const QDir &fromDir, const QDir &toDir, bool cove
return true; return true;
} }
template<typename...Args> template <typename...Args>
void InitializrHelper::templateToFile(const QString &source, const QString &dest, Args &&...args) { void InitializrHelper::templateToFile(const QString& source,const QString& dest,Args &&...args){
QFile file(source); QFile file(source);
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream in(&file); QTextStream in(&file);
QString content = in.readAll().arg(std::forward<Args>(args)...); QString content = in.readAll().arg(std::forward<Args>(args)...);
file.close(); file.close();
QDir outputDir = QFileInfo(dest).absoluteDir(); QDir outputDir = QFileInfo(dest).absoluteDir();
if (!outputDir.exists()) { if(!outputDir.exists()){
outputDir.mkpath(outputDir.absolutePath()); outputDir.mkpath(outputDir.absolutePath());
} }
QFile outputFile(dest); QFile outputFile(dest);
@ -59,43 +67,43 @@ void InitializrHelper::templateToFile(const QString &source, const QString &dest
} }
} }
void InitializrHelper::copyFile(const QString &source, const QString &dest) { void InitializrHelper::copyFile(const QString& source,const QString& dest){
QFile::copy(source, dest); QFile::copy(source,dest);
QFile::setPermissions(dest, QFile::WriteOwner | QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther); QFile::setPermissions(dest, QFile::WriteOwner | QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther);
} }
[[maybe_unused]] void InitializrHelper::generate(const QString &name, const QString &path) { void InitializrHelper::generate(const QString& name,const QString& path){
if (name.isEmpty()) { if(name.isEmpty()){
error(tr("The name cannot be empty")); error(tr("The name cannot be empty"));
return; return;
} }
if (path.isEmpty()) { if(path.isEmpty()){
error(tr("The creation path cannot be empty")); error(tr("The creation path cannot be empty"));
return; return;
} }
QDir projectRootDir(path); QDir projectRootDir(path);
if (!projectRootDir.exists()) { if(!projectRootDir.exists()){
error(tr("The path does not exist")); error(tr("The path does not exist"));
return; return;
} }
QString projectPath = projectRootDir.filePath(name); QString projectPath = projectRootDir.filePath(name);
QDir projectDir(projectPath); QDir projectDir(projectPath);
if (projectDir.exists()) { if(projectDir.exists()){
error(tr("%1 folder already exists").arg(name)); error(tr("%1 folder already exists").arg(name));
return; return;
} }
projectDir.mkpath(projectPath); projectDir.mkpath(projectPath);
QDir fluentDir(projectDir.filePath("FluentUI")); QDir fluentDir(projectDir.filePath("FluentUI"));
copyDir(QDir(QGuiApplication::applicationDirPath() + "/source"), fluentDir); copyDir(QDir(QGuiApplication::applicationDirPath()+"/source"),fluentDir);
templateToFile(":/example/res/template/CMakeLists.txt.in", projectDir.filePath("CMakeLists.txt"), name); templateToFile(":/example/res/template/CMakeLists.txt.in",projectDir.filePath("CMakeLists.txt"),name);
templateToFile(":/example/res/template/src/CMakeLists.txt.in", projectDir.filePath("src/CMakeLists.txt"), name); templateToFile(":/example/res/template/src/CMakeLists.txt.in",projectDir.filePath("src/CMakeLists.txt"),name);
templateToFile(":/example/res/template/src/main.cpp.in", projectDir.filePath("src/main.cpp"), name); templateToFile(":/example/res/template/src/main.cpp.in",projectDir.filePath("src/main.cpp"),name);
templateToFile(":/example/res/template/src/main.qml.in", projectDir.filePath("src/main.qml"), name); templateToFile(":/example/res/template/src/main.qml.in",projectDir.filePath("src/main.qml"),name);
templateToFile(":/example/res/template/src/en_US.ts.in", projectDir.filePath("src/" + name + "_en_US.ts"), name); templateToFile(":/example/res/template/src/en_US.ts.in",projectDir.filePath("src/"+name+"_en_US.ts"),name);
templateToFile(":/example/res/template/src/zh_CN.ts.in", projectDir.filePath("src/" + name + "_zh_CN.ts"), name); templateToFile(":/example/res/template/src/zh_CN.ts.in",projectDir.filePath("src/"+name+"_zh_CN.ts"),name);
copyFile(":/example/res/template/src/App.qml.in", projectDir.filePath("src/App.qml")); copyFile(":/example/res/template/src/App.qml.in",projectDir.filePath("src/App.qml"));
copyFile(":/example/res/template/src/qml.qrc.in", projectDir.filePath("src/qml.qrc")); copyFile(":/example/res/template/src/qml.qrc.in",projectDir.filePath("src/qml.qrc"));
copyFile(":/example/res/template/src/logo.ico.in", projectDir.filePath("src/logo.ico")); copyFile(":/example/res/template/src/logo.ico.in",projectDir.filePath("src/logo.ico"));
copyFile(":/example/res/template/src/README.md.in", projectDir.filePath("src/README.md")); copyFile(":/example/res/template/src/README.md.in",projectDir.filePath("src/README.md"));
return this->success(projectPath+"/CMakeLists.txt"); return this->success(projectPath);
} }

View File

@ -1,30 +1,26 @@
#pragma once #ifndef INITIALIZRHELPER_H
#define INITIALIZRHELPER_H
#include <QObject> #include <QObject>
#include <QtQml/qqml.h> #include <QtQml/qqml.h>
#include <QDir> #include <QDir>
#include "src/singleton.h" #include "src/singleton.h"
class InitializrHelper : public QObject { class InitializrHelper : public QObject
Q_OBJECT {
Q_OBJECT
private: private:
[[maybe_unused]] explicit InitializrHelper(QObject *parent = nullptr); explicit InitializrHelper(QObject* parent = nullptr);
bool copyDir(const QDir& fromDir, const QDir& toDir, bool coverIfFileExists = true);
bool copyDir(const QDir &fromDir, const QDir &toDir, bool coverIfFileExists = true); void copyFile(const QString& source,const QString& dest);
template <typename...Args>
static void copyFile(const QString &source, const QString &dest); void templateToFile(const QString& source,const QString& dest,Args &&...args);
template<typename...Args>
void templateToFile(const QString &source, const QString &dest, Args &&...args);
public: public:
SINGLETON(InitializrHelper) SINGLETON(InitializrHelper)
~InitializrHelper() override; ~InitializrHelper() override;
Q_INVOKABLE void generate(const QString& name,const QString& path);
[[maybe_unused]] Q_INVOKABLE void generate(const QString &name, const QString &path); Q_SIGNAL void error(const QString& message);
Q_SIGNAL void success(const QString& path);
Q_SIGNAL void error(const QString &message);
Q_SIGNAL void success(const QString &path);
}; };
#endif // INITIALIZRHELPER_H

View File

@ -11,11 +11,8 @@
#include <QSettings> #include <QSettings>
#include <QRegularExpression> #include <QRegularExpression>
#include "Version.h" #include "Version.h"
#ifdef WIN32 #ifdef WIN32
#include <process.h> #include <process.h>
#else #else
#include <unistd.h> #include <unistd.h>
#endif #endif
@ -29,7 +26,7 @@
#endif #endif
static QString g_app = {}; static QString g_app = {};
static QString g_file_path = {}; static QString g_file_path= {};
static bool g_logError = false; static bool g_logError = false;
static std::unique_ptr<QFile> g_logFile = nullptr; static std::unique_ptr<QFile> g_logFile = nullptr;
@ -38,14 +35,15 @@ static std::unique_ptr<QTextStream> g_logStream = nullptr;
static int g_logLevel = 4; static int g_logLevel = 4;
std::map<QtMsgType, int> logLevelMap = { std::map<QtMsgType, int> logLevelMap = {
{QtFatalMsg, 0}, {QtFatalMsg,0},
{QtCriticalMsg, 1}, {QtCriticalMsg,1},
{QtWarningMsg, 2}, {QtWarningMsg,2},
{QtInfoMsg, 3}, {QtInfoMsg,3},
{QtDebugMsg, 4} {QtDebugMsg,4}
}; };
QString Log::prettyProductInfoWrapper() { QString Log::prettyProductInfoWrapper()
{
auto productName = QSysInfo::prettyProductName(); auto productName = QSysInfo::prettyProductName();
#if QT_VERSION < QT_VERSION_CHECK(6, 5, 0) #if QT_VERSION < QT_VERSION_CHECK(6, 5, 0)
#if defined(Q_OS_MACOS) #if defined(Q_OS_MACOS)
@ -72,17 +70,20 @@ QString Log::prettyProductInfoWrapper() {
#endif #endif
#endif #endif
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
QSettings regKey{QString::fromUtf8(R"(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion)"), QSettings::NativeFormat}; QSettings regKey {QString::fromUtf8("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"), QSettings::NativeFormat};
if (regKey.contains(QString::fromUtf8("CurrentBuildNumber"))) { if (regKey.contains(QString::fromUtf8("CurrentBuildNumber"))) {
auto buildNumber = regKey.value(QString::fromUtf8("CurrentBuildNumber")).toInt(); auto buildNumber = regKey.value(QString::fromUtf8("CurrentBuildNumber")).toInt();
if (buildNumber > 0) { if (buildNumber > 0) {
if (buildNumber < 9200) { if (buildNumber < 9200) {
productName = QString::fromUtf8("Windows 7 build %1").arg(buildNumber); productName = QString::fromUtf8("Windows 7 build %1").arg(buildNumber);
} else if (buildNumber < 10240) { }
else if (buildNumber < 10240) {
productName = QString::fromUtf8("Windows 8 build %1").arg(buildNumber); productName = QString::fromUtf8("Windows 8 build %1").arg(buildNumber);
} else if (buildNumber < 22000) { }
else if (buildNumber < 22000) {
productName = QString::fromUtf8("Windows 10 build %1").arg(buildNumber); productName = QString::fromUtf8("Windows 10 build %1").arg(buildNumber);
} else { }
else {
productName = QString::fromUtf8("Windows 11 build %1").arg(buildNumber); productName = QString::fromUtf8("Windows 11 build %1").arg(buildNumber);
} }
} }
@ -91,11 +92,12 @@ QString Log::prettyProductInfoWrapper() {
return productName; return productName;
} }
static inline void messageHandler(const QtMsgType type, const QMessageLogContext &context, const QString &message) { static inline void messageHandler(const QtMsgType type, const QMessageLogContext &context, const QString &message)
if (message == "Could not get the INetworkConnection instance for the adapter GUID.") { {
if(message == "Could not get the INetworkConnection instance for the adapter GUID."){
return; return;
} }
if (logLevelMap[type] > g_logLevel) { if(logLevelMap[type]>g_logLevel){
return; return;
} }
if (!message.isEmpty()) { if (!message.isEmpty()) {
@ -118,21 +120,21 @@ static inline void messageHandler(const QtMsgType type, const QMessageLogContext
break; break;
} }
QString fileAndLineLogStr; QString fileAndLineLogStr;
if (context.file) { if(context.file){
std::string strFileTmp = context.file; std::string strFileTmp = context.file;
const char *ptr = strrchr(strFileTmp.c_str(), '/'); const char* ptr = strrchr(strFileTmp.c_str(), '/');
if (nullptr != ptr) { if (nullptr != ptr) {
char fn[512] = {0}; char fn[512] = {0};
sprintf(fn, "%s", ptr + 1); sprintf(fn, "%s", ptr + 1);
strFileTmp = fn; strFileTmp = fn;
} }
const char *ptrTmp = strrchr(strFileTmp.c_str(), '\\'); const char* ptrTmp = strrchr(strFileTmp.c_str(), '\\');
if (nullptr != ptrTmp) { if (nullptr != ptrTmp) {
char fn[512] = {0}; char fn[512] = {0};
sprintf(fn, "%s", ptrTmp + 1); sprintf(fn, "%s", ptrTmp + 1);
strFileTmp = fn; strFileTmp = fn;
} }
fileAndLineLogStr = QString::fromStdString("[%1:%2]").arg(QString::fromStdString(strFileTmp), QString::number(context.line)); fileAndLineLogStr = QString::fromStdString("[%1:%2]").arg(QString::fromStdString(strFileTmp),QString::number(context.line));
} }
const QString finalMessage = QString::fromStdString("%1[%2]%3[%4]:%5").arg( const QString finalMessage = QString::fromStdString("%1[%2]%3[%4]:%5").arg(
QDateTime::currentDateTime().toString("yyyy/MM/dd hh:mm:ss.zzz"), QDateTime::currentDateTime().toString("yyyy/MM/dd hh:mm:ss.zzz"),
@ -166,7 +168,8 @@ static inline void messageHandler(const QtMsgType type, const QMessageLogContext
} }
} }
void Log::setup(char *argv[], const QString &app, int level) { void Log::setup(char *argv[],const QString &app,int level)
{
Q_ASSERT(!app.isEmpty()); Q_ASSERT(!app.isEmpty());
if (app.isEmpty()) { if (app.isEmpty()) {
return; return;
@ -179,30 +182,30 @@ void Log::setup(char *argv[], const QString &app, int level) {
QString applicationPath = QString::fromStdString(argv[0]); QString applicationPath = QString::fromStdString(argv[0]);
once = true; once = true;
g_app = app; g_app = app;
const QString logFileName = QString("%1_%2.log").arg(g_app, QDateTime::currentDateTime().toString("yyyyMMdd")); const QString logFileName = QString("%1_%2.log").arg(g_app,QDateTime::currentDateTime().toString("yyyyMMdd"));
const QString logDirPath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/log"; const QString logDirPath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)+"/log";
const QDir logDir(logDirPath); const QDir logDir(logDirPath);
if (!logDir.exists()) { if(!logDir.exists()){
logDir.mkpath(logDirPath); logDir.mkpath(logDirPath);
} }
g_file_path = logDir.filePath(logFileName); g_file_path = logDir.filePath(logFileName);
qInstallMessageHandler(messageHandler); qInstallMessageHandler(messageHandler);
qInfo() << "==================================================="; qInfo()<<"===================================================";
qInfo() << "[AppName]" << g_app; qInfo()<<"[AppName]"<<g_app;
qInfo() << "[AppVersion]" << APPLICATION_VERSION; qInfo()<<"[AppVersion]"<<APPLICATION_VERSION;
qInfo() << "[AppPath]" << applicationPath; qInfo()<<"[AppPath]"<<applicationPath;
qInfo() << "[QtVersion]" << QT_VERSION_STR; qInfo()<<"[QtVersion]"<<QT_VERSION_STR;
#ifdef WIN32 #ifdef WIN32
qInfo() << "[ProcessId]" << QString::number(_getpid()); qInfo()<<"[ProcessId]"<<QString::number(_getpid());
#else #else
qInfo()<<"[ProcessId]"<<QString::number(getpid()); qInfo()<<"[ProcessId]"<<QString::number(getpid());
#endif #endif
qInfo() << "[GitHashCode]" << COMMIT_HASH; qInfo()<<"[GitHashCode]"<<COMMIT_HASH;
qInfo() << "[DeviceInfo]"; qInfo()<<"[DeviceInfo]";
qInfo() << " [DeviceId]" << QSysInfo::machineUniqueId(); qInfo()<<" [DeviceId]"<<QSysInfo::machineUniqueId();
qInfo() << " [Manufacturer]" << prettyProductInfoWrapper(); qInfo()<<" [Manufacturer]"<<prettyProductInfoWrapper();
qInfo() << " [CPU_ABI]" << QSysInfo::currentCpuArchitecture(); qInfo()<<" [CPU_ABI]"<<QSysInfo::currentCpuArchitecture();
qInfo() << "[LOG_LEVEL]" << g_logLevel; qInfo()<<"[LOG_LEVEL]"<<g_logLevel;
qInfo() << "[LOG_PATH]" << g_file_path; qInfo()<<"[LOG_PATH]"<<g_file_path;
qInfo() << "==================================================="; qInfo()<<"===================================================";
} }

View File

@ -1,9 +1,11 @@
#pragma once #ifndef LOG_H
#define LOG_H
#include <QtCore/qstring.h> #include <QtCore/qstring.h>
namespace Log { namespace Log
{
QString prettyProductInfoWrapper(); QString prettyProductInfoWrapper();
void setup(char *argv[], const QString &app,int level = 4);
void setup(char *argv[], const QString &app, int level = 4);
} }
#endif // LOG_H

View File

@ -17,14 +17,12 @@
#include <QCryptographicHash> #include <QCryptographicHash>
#include <QEventLoop> #include <QEventLoop>
#include <QGuiApplication> #include <QGuiApplication>
#include <utility>
NetworkCallable::NetworkCallable(QObject *parent):QObject{parent}{
NetworkCallable::NetworkCallable(QObject *parent) : QObject{parent} {
} }
QString NetworkParams::method2String() const { QString NetworkParams::method2String(){
switch (_method) { switch (_method) {
case METHOD_GET: case METHOD_GET:
return "GET"; return "GET";
@ -43,148 +41,151 @@ QString NetworkParams::method2String() const {
} }
} }
int NetworkParams::getTimeout() const { int NetworkParams::getTimeout(){
if (_timeout != -1) { if(_timeout != -1){
return _timeout; return _timeout;
} }
return Network::getInstance()->timeout(); return Network::getInstance()->timeout();
} }
int NetworkParams::getRetry() const { int NetworkParams::getRetry(){
if (_retry != -1) { if(_retry != -1){
return _retry; return _retry;
} }
return Network::getInstance()->retry(); return Network::getInstance()->retry();
} }
bool NetworkParams::getOpenLog() const { bool NetworkParams::getOpenLog(){
if (!_openLog.isNull()) { if(!_openLog.isNull()){
return _openLog.toBool(); return _openLog.toBool();
} }
return Network::getInstance()->openLog(); return Network::getInstance()->openLog();
} }
FluDownloadParam::FluDownloadParam(QObject *parent) FluDownloadParam::FluDownloadParam(QObject *parent)
: QObject{parent} { : QObject{parent}
{
} }
FluDownloadParam::FluDownloadParam(QString destPath, bool append, QObject *parent) FluDownloadParam::FluDownloadParam(QString destPath,bool append,QObject *parent)
: QObject{parent} { : QObject{parent}
this->_destPath = std::move(destPath); {
this->_destPath = destPath;
this->_append = append; this->_append = append;
} }
NetworkParams::NetworkParams(QObject *parent) : QObject{parent} { NetworkParams::NetworkParams(QObject *parent)
_method = NetworkParams::Method::METHOD_GET; : QObject{parent}
_type = NetworkParams::Type::TYPE_BODY; {
} }
NetworkParams::NetworkParams(QString url, Type type, Method method, QObject *parent) NetworkParams::NetworkParams(QString url,Type type,Method method,QObject *parent)
: QObject{parent} { : QObject{parent}
{
this->_method = method; this->_method = method;
this->_url = std::move(url); this->_url = url;
this->_type = type; this->_type = type;
} }
NetworkParams *NetworkParams::add(const QString &key, const QVariant &val) { NetworkParams* NetworkParams::add(QString key,QVariant val){
_paramMap.insert(key, val); _paramMap.insert(key,val);
return this; return this;
} }
NetworkParams *NetworkParams::addFile(const QString &key, const QVariant &val) { NetworkParams* NetworkParams::addFile(QString key,QVariant val){
_fileMap.insert(key, val); _fileMap.insert(key,val);
return this; return this;
} }
NetworkParams *NetworkParams::addHeader(const QString &key, const QVariant &val) { NetworkParams* NetworkParams::addHeader(QString key,QVariant val){
_headerMap.insert(key, val); _headerMap.insert(key,val);
return this; return this;
} }
NetworkParams *NetworkParams::addQuery(const QString &key, const QVariant &val) { NetworkParams* NetworkParams::addQuery(QString key,QVariant val){
_queryMap.insert(key, val); _queryMap.insert(key,val);
return this; return this;
} }
NetworkParams *NetworkParams::setBody(QString val) { NetworkParams* NetworkParams::setBody(QString val){
_body = std::move(val); _body = val;
return this; return this;
} }
NetworkParams *NetworkParams::setTimeout(int val) { NetworkParams* NetworkParams::setTimeout(int val){
_timeout = val; _timeout = val;
return this; return this;
} }
NetworkParams *NetworkParams::setRetry(int val) { NetworkParams* NetworkParams::setRetry(int val){
_retry = val; _retry = val;
return this; return this;
} }
NetworkParams *NetworkParams::setCacheMode(int val) { NetworkParams* NetworkParams::setCacheMode(int val){
_cacheMode = val; _cacheMode = val;
return this; return this;
} }
NetworkParams *NetworkParams::toDownload(QString destPath, bool append) { NetworkParams* NetworkParams::toDownload(QString destPath,bool append){
_downloadParam = new FluDownloadParam(std::move(destPath), append, this); _downloadParam = new FluDownloadParam(destPath,append,this);
return this; return this;
} }
NetworkParams *NetworkParams::bind(QObject *target) { NetworkParams* NetworkParams::bind(QObject* target){
_target = target; _target = target;
return this; return this;
} }
NetworkParams *NetworkParams::openLog(QVariant val) { NetworkParams* NetworkParams::openLog(QVariant val){
_openLog = std::move(val); _openLog = val;
return this; return this;
} }
QString NetworkParams::buildCacheKey() const { QString NetworkParams::buildCacheKey(){
QJsonObject obj; QJsonObject obj;
obj.insert("url", _url); obj.insert("url",_url);
obj.insert("method", method2String()); obj.insert("method",method2String());
obj.insert("body", _body); obj.insert("body",_body);
obj.insert("query", QJsonDocument::fromVariant(_queryMap).object()); obj.insert("query",QJsonDocument::fromVariant(_queryMap).object());
obj.insert("param", QJsonDocument::fromVariant(_paramMap).object()); obj.insert("param",QJsonDocument::fromVariant(_paramMap).object());
obj.insert("header", QJsonDocument::fromVariant(_headerMap).object()); obj.insert("header",QJsonDocument::fromVariant(_headerMap).object());
obj.insert("file", QJsonDocument::fromVariant(_fileMap).object()); obj.insert("file",QJsonDocument::fromVariant(_fileMap).object());
if (_downloadParam) { if(_downloadParam){
QJsonObject downObj; QJsonObject downObj;
downObj.insert("destPath", _downloadParam->_destPath); downObj.insert("destPath",_downloadParam->_destPath);
downObj.insert("append", _downloadParam->_append); downObj.insert("append",_downloadParam->_append);
obj.insert("download", downObj); obj.insert("download",downObj);
} }
QByteArray data = QJsonDocument(obj).toJson(QJsonDocument::Compact); QByteArray data = QJsonDocument(obj).toJson(QJsonDocument::Compact);
return QCryptographicHash::hash(data, QCryptographicHash::Sha256).toHex(); return QCryptographicHash::hash(data, QCryptographicHash::Sha256).toHex();
} }
void NetworkParams::go(NetworkCallable *callable) { void NetworkParams::go(NetworkCallable* callable){
QJSValueList data; QJSValueList data;
data << qjsEngine(callable)->newQObject(this); data<<qjsEngine(callable)->newQObject(this);
Network::getInstance()->_interceptor.call(data); Network::getInstance()->_interceptor.call(data);
if (_downloadParam) { if(_downloadParam){
Network::getInstance()->handleDownload(this, callable); Network::getInstance()->handleDownload(this,callable);
} else { }else{
Network::getInstance()->handle(this, callable); Network::getInstance()->handle(this,callable);
} }
} }
void Network::handle(NetworkParams *params, NetworkCallable *c) { void Network::handle(NetworkParams* params,NetworkCallable* c){
QPointer<NetworkCallable> callable(c); QPointer<NetworkCallable> callable(c);
QThreadPool::globalInstance()->start([=]() { QThreadPool::globalInstance()->start([=](){
if (!callable.isNull()) { if(!callable.isNull()){
callable->start(); callable->start();
} }
QString cacheKey = params->buildCacheKey(); QString cacheKey = params->buildCacheKey();
if (params->_cacheMode == NetworkType::CacheMode::FirstCacheThenRequest && cacheExists(cacheKey)) { if(params->_cacheMode == NetworkType::CacheMode::FirstCacheThenRequest && cacheExists(cacheKey)){
if (!callable.isNull()) { if(!callable.isNull()){
callable->cache(readCache(cacheKey)); callable->cache(readCache(cacheKey));
} }
} }
if (params->_cacheMode == NetworkType::CacheMode::IfNoneCacheRequest && cacheExists(cacheKey)) { if(params->_cacheMode == NetworkType::CacheMode::IfNoneCacheRequest && cacheExists(cacheKey)){
if (!callable.isNull()) { if(!callable.isNull()){
callable->cache(readCache(cacheKey)); callable->cache(readCache(cacheKey));
callable->finish(); callable->finish();
params->deleteLater(); params->deleteLater();
@ -194,130 +195,131 @@ void Network::handle(NetworkParams *params, NetworkCallable *c) {
QNetworkAccessManager manager; QNetworkAccessManager manager;
manager.setTransferTimeout(params->getTimeout()); manager.setTransferTimeout(params->getTimeout());
QEventLoop loop; QEventLoop loop;
connect(&manager, &QNetworkAccessManager::finished, &manager, [&loop](QNetworkReply *reply) { loop.quit(); }); connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
for (int i = 0; i <= params->getRetry() - 1; ++i) { for (int i = 0; i < params->getRetry(); ++i) {
QUrl url(params->_url); QUrl url(params->_url);
addQueryParam(&url, params->_queryMap); addQueryParam(&url,params->_queryMap);
QNetworkRequest request(url); QNetworkRequest request(url);
addHeaders(&request, params->_headerMap); addHeaders(&request,params->_headerMap);
QNetworkReply *reply; QNetworkReply* reply;
sendRequest(&manager, request, params, reply, i == 0, callable); sendRequest(&manager,request,params,reply,i==0,callable);
if (!QPointer<QCoreApplication>(QGuiApplication::instance())) { if(!QPointer<QGuiApplication>(qApp)){
reply->deleteLater(); reply->deleteLater();
reply = nullptr; reply = nullptr;
return; return;
} }
auto abortCallable = [reply, &i, params] { auto abortCallable = [&loop,reply,&i,params]{
if (reply) { if(reply){
i = params->getRetry(); i = params->getRetry();
reply->abort(); reply->abort();
} }
}; };
QMetaObject::Connection conn_destroyed = {}; QMetaObject::Connection conn_destroyed = {};
QMetaObject::Connection conn_quit = {}; QMetaObject::Connection conn_quit = {};
if (params->_target) { if(params->_target){
conn_destroyed = connect(params->_target, &QObject::destroyed, &manager, abortCallable); conn_destroyed = connect(params->_target,&QObject::destroyed,&manager,abortCallable);
} }
conn_quit = connect(QGuiApplication::instance(), &QGuiApplication::aboutToQuit, &manager, abortCallable); conn_quit = connect(qApp,&QGuiApplication::aboutToQuit,&manager, abortCallable);
loop.exec(); loop.exec();
if (conn_destroyed) { if(conn_destroyed){
disconnect(conn_destroyed); disconnect(conn_destroyed);
} }
if (conn_quit) { if(conn_quit){
disconnect(conn_quit); disconnect(conn_quit);
} }
QString response; QString response;
if (params->_method == NetworkParams::METHOD_HEAD) { if(params->_method == NetworkParams::METHOD_HEAD){
response = headerList2String(reply->rawHeaderPairs()); response = headerList2String(reply->rawHeaderPairs());
} else { }else{
if (reply->isOpen()) { if(reply->isOpen()){
response = QString::fromUtf8(reply->readAll()); response = QString::fromUtf8(reply->readAll());
} }
} }
int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (httpStatus == 200) { if(httpStatus == 200){
if (!callable.isNull()) { if(!callable.isNull()){
if (params->_cacheMode != NetworkType::CacheMode::NoCache) { if(params->_cacheMode != NetworkType::CacheMode::NoCache){
saveResponse(cacheKey, response); saveResponse(cacheKey,response);
} }
callable->success(response); callable->success(response);
} }
printRequestEndLog(request, params, reply, response); printRequestEndLog(request,params,reply,response);
break; break;
} else { }else{
if (i == params->getRetry() - 1) { if(i == params->getRetry()-1){
if (!callable.isNull()) { if(!callable.isNull()){
if (params->_cacheMode == NetworkType::CacheMode::RequestFailedReadCache && cacheExists(cacheKey)) { if(params->_cacheMode == NetworkType::CacheMode::RequestFailedReadCache && cacheExists(cacheKey)){
if (!callable.isNull()) { if(!callable.isNull()){
callable->cache(readCache(cacheKey)); callable->cache(readCache(cacheKey));
} }
} }
callable->error(httpStatus, reply->errorString(), response); callable->error(httpStatus,reply->errorString(),response);
} }
printRequestEndLog(request, params, reply, response); printRequestEndLog(request,params,reply,response);
} }
} }
reply->deleteLater(); reply->deleteLater();
} }
params->deleteLater(); params->deleteLater();
if (!callable.isNull()) { if(!callable.isNull()){
callable->finish(); callable->finish();
} }
}); });
} }
void Network::handleDownload(NetworkParams *params, NetworkCallable *c) { void Network::handleDownload(NetworkParams* params,NetworkCallable* c){
QPointer<NetworkCallable> callable(c); QPointer<NetworkCallable> callable(c);
QThreadPool::globalInstance()->start([=]() { QThreadPool::globalInstance()->start([=](){
if (!callable.isNull()) { if(!callable.isNull()){
callable->start(); callable->start();
} }
QString cacheKey = params->buildCacheKey(); QString cacheKey = params->buildCacheKey();
QUrl url(params->_url); QUrl url(params->_url);
QNetworkAccessManager manager; QNetworkAccessManager manager;
manager.setTransferTimeout(params->getTimeout()); manager.setTransferTimeout(params->getTimeout());
addQueryParam(&url, params->_queryMap); addQueryParam(&url,params->_queryMap);
QNetworkRequest request(url); QNetworkRequest request(url);
addHeaders(&request, params->_headerMap); addHeaders(&request,params->_headerMap);
QString cachePath = getCacheFilePath(cacheKey); QString cachePath = getCacheFilePath(cacheKey);
QString destPath = params->_downloadParam->_destPath; QString destPath = params->_downloadParam->_destPath;
auto *destFile = new QFile(destPath); QFile* destFile = new QFile(destPath);
auto *cacheFile = new QFile(cachePath); QFile* cacheFile = new QFile(cachePath);
bool isOpen; bool isOpen = false;
qint64 seek; qint64 seek = 0;
if (cacheFile->exists() && destFile->exists() && params->_downloadParam->_append) { if(cacheFile->exists() && destFile->exists() && params->_downloadParam->_append){
QJsonObject cacheInfo = QJsonDocument::fromJson(readCache(cacheKey).toUtf8()).object(); QJsonObject cacheInfo = QJsonDocument::fromJson(readCache(cacheKey).toUtf8()).object();
qint64 fileSize = qRound(cacheInfo.value("fileSize").toDouble()); qint64 fileSize = cacheInfo.value("fileSize").toDouble();
qint64 contentLength = qRound(cacheInfo.value("contentLength").toDouble()); qint64 contentLength = cacheInfo.value("contentLength").toDouble();
if (fileSize == contentLength && destFile->size() == contentLength) { if(fileSize == contentLength && destFile->size() == contentLength){
if (!callable.isNull()) { if(!callable.isNull()){
callable->downloadProgress(fileSize, contentLength); callable->downloadProgress(fileSize,contentLength);
callable->success(destPath); callable->success(destPath);
callable->finish(); callable->finish();
} }
return; return;
} }
if (fileSize == destFile->size()) { if(fileSize==destFile->size()){
request.setRawHeader("Range", QString("bytes=%1-").arg(fileSize).toUtf8()); request.setRawHeader("Range", QString("bytes=%1-").arg(fileSize).toUtf8());
seek = fileSize; seek = fileSize;
isOpen = destFile->open(QIODevice::WriteOnly | QIODevice::Append); isOpen = destFile->open(QIODevice::WriteOnly|QIODevice::Append);
} else { }else{
isOpen = destFile->open(QIODevice::WriteOnly | QIODevice::Truncate); isOpen = destFile->open(QIODevice::WriteOnly|QIODevice::Truncate);
} }
} else { }else{
isOpen = destFile->open(QIODevice::WriteOnly | QIODevice::Truncate); isOpen = destFile->open(QIODevice::WriteOnly|QIODevice::Truncate);
} }
if (!isOpen) { if(!isOpen){
if (!callable.isNull()) { if(!callable.isNull()){
callable->error(-1, "device not open", ""); callable->error(-1,"device not open","");
callable->finish(); callable->finish();
} }
return; return;
} }
if (params->_downloadParam->_append) { if(params->_downloadParam->_append){
if (!cacheFile->open(QIODevice::WriteOnly | QIODevice::Truncate)) { if (!cacheFile->open(QIODevice::WriteOnly|QIODevice::Truncate))
if (!callable.isNull()) { {
callable->error(-1, "cache file device not open", ""); if(!callable.isNull()){
callable->error(-1,"cache file device not open","");
callable->finish(); callable->finish();
} }
return; return;
@ -327,72 +329,73 @@ void Network::handleDownload(NetworkParams *params, NetworkCallable *c) {
QNetworkReply *reply = manager.get(request); QNetworkReply *reply = manager.get(request);
destFile->setParent(reply); destFile->setParent(reply);
cacheFile->setParent(reply); cacheFile->setParent(reply);
auto abortCallable = [reply] { auto abortCallable = [&loop,reply,params]{
if (reply) { if(reply){
reply->abort(); reply->abort();
} }
}; };
connect(&manager, &QNetworkAccessManager::finished, &manager, [&loop](QNetworkReply *reply) { loop.quit(); }); connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
connect(QGuiApplication::instance(), &QGuiApplication::aboutToQuit, &manager, [&loop, reply]() { reply->abort(), loop.quit(); }); connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
QMetaObject::Connection conn_destroyed = {}; QMetaObject::Connection conn_destroyed = {};
QMetaObject::Connection conn_quit = {}; QMetaObject::Connection conn_quit = {};
if (params->_target) { if(params->_target){
conn_destroyed = connect(params->_target, &QObject::destroyed, &manager, abortCallable); conn_destroyed = connect(params->_target,&QObject::destroyed,&manager,abortCallable);
} }
conn_quit = connect(QGuiApplication::instance(), &QGuiApplication::aboutToQuit, &manager, abortCallable); conn_quit = connect(qApp,&QGuiApplication::aboutToQuit,&manager, abortCallable);
connect(reply, &QNetworkReply::readyRead, reply, [reply, seek, destFile, cacheFile, callable] { connect(reply,&QNetworkReply::readyRead,reply,[reply,seek,destFile,cacheFile,callable]{
if (!reply || !destFile || reply->error() != QNetworkReply::NoError) { if (!reply || !destFile || reply->error() != QNetworkReply::NoError)
{
return; return;
} }
QMap<QString, QVariant> downInfo; QMap<QString, QVariant> downInfo;
qint64 contentLength = reply->header(QNetworkRequest::ContentLengthHeader).toLongLong() + seek; qint64 contentLength = reply->header(QNetworkRequest::ContentLengthHeader).toLongLong()+seek;
downInfo.insert("contentLength", contentLength); downInfo.insert("contentLength",contentLength);
QString eTag = reply->header(QNetworkRequest::ETagHeader).toString(); QString eTag = reply->header(QNetworkRequest::ETagHeader).toString();
downInfo.insert("eTag", eTag); downInfo.insert("eTag",eTag);
destFile->write(reply->readAll()); destFile->write(reply->readAll());
destFile->flush(); destFile->flush();
downInfo.insert("fileSize", destFile->size()); downInfo.insert("fileSize",destFile->size());
if (cacheFile->isOpen()) { if(cacheFile->isOpen()){
cacheFile->resize(0); cacheFile->resize(0);
cacheFile->write(QJsonDocument::fromVariant(QVariant(downInfo)).toJson().toBase64()); cacheFile->write(QJsonDocument::fromVariant(QVariant(downInfo)).toJson().toBase64());
cacheFile->flush(); cacheFile->flush();
} }
if (!callable.isNull()) { if(!callable.isNull()){
callable->downloadProgress(destFile->size(), contentLength); callable->downloadProgress(destFile->size(),contentLength);
} }
}); });
loop.exec(); loop.exec();
int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (httpStatus == 200) { if(httpStatus == 200){
if (!callable.isNull()) { if(!callable.isNull()){
callable->success(destPath); callable->success(destPath);
} }
printRequestEndLog(request, params, reply, destPath); printRequestEndLog(request,params,reply,destPath);
} else { }else{
if (!callable.isNull()) { if(!callable.isNull()){
callable->error(httpStatus, reply->errorString(), destPath); callable->error(httpStatus,reply->errorString(),destPath);
} }
printRequestEndLog(request, params, reply, destPath); printRequestEndLog(request,params,reply,destPath);
} }
if (conn_destroyed) { if(conn_destroyed){
disconnect(conn_destroyed); disconnect(conn_destroyed);
} }
if (conn_quit) { if(conn_quit){
disconnect(conn_quit); disconnect(conn_quit);
} }
params->deleteLater(); params->deleteLater();
reply->deleteLater(); reply->deleteLater();
if (!callable.isNull()) { if(!callable.isNull()){
callable->finish(); callable->finish();
} }
}); });
} }
QString Network::readCache(const QString &key) { QString Network::readCache(const QString& key){
auto filePath = getCacheFilePath(key); auto filePath = getCacheFilePath(key);
QString result; QString result;
QFile file(filePath); QFile file(filePath);
if (!file.exists()) { if(!file.exists()){
return result; return result;
} }
if (file.open(QIODevice::ReadOnly)) { if (file.open(QIODevice::ReadOnly)) {
@ -402,27 +405,27 @@ QString Network::readCache(const QString &key) {
return result; return result;
} }
bool Network::cacheExists(const QString &key) { bool Network::cacheExists(const QString& key){
return QFile(getCacheFilePath(key)).exists(); return QFile(getCacheFilePath(key)).exists();
} }
QString Network::getCacheFilePath(const QString &key) { QString Network::getCacheFilePath(const QString& key){
QDir cacheDir(_cacheDir); QDir cacheDir(_cacheDir);
if (!cacheDir.exists()) { if(!cacheDir.exists()){
cacheDir.mkpath(_cacheDir); cacheDir.mkpath(_cacheDir);
} }
return cacheDir.absoluteFilePath(key); return cacheDir.absoluteFilePath(key);
} }
QString Network::headerList2String(const QList<QNetworkReply::RawHeaderPair> &data) { QString Network::headerList2String(const QList<QNetworkReply::RawHeaderPair>& data){
QJsonObject object; QJsonObject object;
for (auto it = data.constBegin(); it != data.constEnd(); ++it) { for (auto it = data.constBegin(); it != data.constEnd(); ++it) {
object.insert(QString(it->first), QString(it->second)); object.insert(QString(it->first),QString(it->second));
} }
return QJsonDocument(object).toJson(QJsonDocument::Compact); return QJsonDocument(object).toJson(QJsonDocument::Compact);
} }
QString Network::map2String(const QMap<QString, QVariant> &map) { QString Network::map2String(const QMap<QString, QVariant>& map){
QStringList parameters; QStringList parameters;
for (auto it = map.constBegin(); it != map.constEnd(); ++it) { for (auto it = map.constBegin(); it != map.constEnd(); ++it) {
parameters << QString("%1=%2").arg(it.key(), it.value().toString()); parameters << QString("%1=%2").arg(it.key(), it.value().toString());
@ -430,235 +433,244 @@ QString Network::map2String(const QMap<QString, QVariant> &map) {
return parameters.join(" "); return parameters.join(" ");
} }
void Network::sendRequest(QNetworkAccessManager *manager, QNetworkRequest request, NetworkParams *params, QNetworkReply *&reply, bool isFirst, const QPointer<NetworkCallable> &callable) { void Network::sendRequest(QNetworkAccessManager* manager,QNetworkRequest request,NetworkParams* params,QNetworkReply*& reply,bool isFirst,QPointer<NetworkCallable> callable){
QByteArray verb = params->method2String().toUtf8(); QByteArray verb = params->method2String().toUtf8();
switch (params->_type) { switch (params->_type) {
case NetworkParams::TYPE_FORM: { case NetworkParams::TYPE_FORM:{
bool isFormData = !params->_fileMap.isEmpty(); bool isFormData = !params->_fileMap.isEmpty();
if (isFormData) { if(isFormData){
auto *multiPart = new QHttpMultiPart(); QHttpMultiPart *multiPart = new QHttpMultiPart();
multiPart->setContentType(QHttpMultiPart::FormDataType); multiPart->setContentType(QHttpMultiPart::FormDataType);
for (const auto &each: params->_paramMap.toStdMap()) { for (const auto& each : params->_paramMap.toStdMap())
{
QHttpPart part; QHttpPart part;
part.setHeader(QNetworkRequest::ContentDispositionHeader, QString("form-data; name=\"%1\"").arg(each.first)); part.setHeader(QNetworkRequest::ContentDispositionHeader, QString("form-data; name=\"%1\"").arg(each.first));
part.setBody(each.second.toByteArray()); part.setBody(each.second.toByteArray());
multiPart->append(part); multiPart->append(part);
} }
for (const auto &each: params->_fileMap.toStdMap()) { for (const auto& each : params->_fileMap.toStdMap())
{
QString filePath = each.second.toString(); QString filePath = each.second.toString();
QString name = each.first; QString name = each.first;
auto *file = new QFile(filePath); QFile *file = new QFile(filePath);
QString fileName = QFileInfo(filePath).fileName(); QString fileName = QFileInfo(filePath).fileName();
file->open(QIODevice::ReadOnly); file->open(QIODevice::ReadOnly);
file->setParent(multiPart); file->setParent(multiPart);
QHttpPart part; QHttpPart part;
part.setHeader(QNetworkRequest::ContentDispositionHeader, QString(R"(form-data; name="%1"; filename="%2")").arg(name, fileName)); part.setHeader(QNetworkRequest::ContentDispositionHeader, QString("form-data; name=\"%1\"; filename=\"%2\"").arg(name,fileName));
part.setBodyDevice(file); part.setBodyDevice(file);
multiPart->append(part); multiPart->append(part);
} }
reply = manager->sendCustomRequest(request, verb, multiPart); reply = manager->sendCustomRequest(request,verb,multiPart);
multiPart->setParent(reply); multiPart->setParent(reply);
connect(reply, &QNetworkReply::uploadProgress, reply, [callable](qint64 bytesSent, qint64 bytesTotal) { connect(reply,&QNetworkReply::uploadProgress,reply,[callable](qint64 bytesSent, qint64 bytesTotal){
if (!callable.isNull() && bytesSent != 0 && bytesTotal != 0) { if(!callable.isNull() && bytesSent!=0 && bytesTotal!=0){
Q_EMIT callable->uploadProgress(bytesSent, bytesTotal); Q_EMIT callable->uploadProgress(bytesSent,bytesTotal);
} }
}); });
} else { }else{
request.setHeader(QNetworkRequest::ContentTypeHeader, QString("application/x-www-form-urlencoded")); request.setHeader(QNetworkRequest::ContentTypeHeader, QString("application/x-www-form-urlencoded"));
QString value; QString value;
for (const auto &each: params->_paramMap.toStdMap()) { for (const auto& each : params->_paramMap.toStdMap())
value += QString("%1=%2").arg(each.first, each.second.toString()); {
value += QString("%1=%2").arg(each.first,each.second.toString());
value += "&"; value += "&";
} }
if (!params->_paramMap.isEmpty()) { if(!params->_paramMap.isEmpty()){
value.chop(1); value.chop(1);
} }
QByteArray data = value.toUtf8(); QByteArray data = value.toUtf8();
reply = manager->sendCustomRequest(request, verb, data); reply = manager->sendCustomRequest(request,verb,data);
} }
break; break;
} }
case NetworkParams::TYPE_JSON: { case NetworkParams::TYPE_JSON:{
request.setHeader(QNetworkRequest::ContentTypeHeader, QString("application/json;charset=utf-8")); request.setHeader(QNetworkRequest::ContentTypeHeader, QString("application/json;charset=utf-8"));
QJsonObject json; QJsonObject json;
for (const auto &each: params->_paramMap.toStdMap()) { for (const auto& each : params->_paramMap.toStdMap())
json.insert(each.first, each.second.toJsonValue()); {
json.insert(each.first,each.second.toJsonValue());
} }
QByteArray data = QJsonDocument(json).toJson(QJsonDocument::Compact); QByteArray data = QJsonDocument(json).toJson(QJsonDocument::Compact);
reply = manager->sendCustomRequest(request, verb, data); reply = manager->sendCustomRequest(request,verb,data);
break; break;
} }
case NetworkParams::TYPE_JSONARRAY: { case NetworkParams::TYPE_JSONARRAY:{
request.setHeader(QNetworkRequest::ContentTypeHeader, QString("application/json;charset=utf-8")); request.setHeader(QNetworkRequest::ContentTypeHeader, QString("application/json;charset=utf-8"));
QJsonArray jsonArray; QJsonArray jsonArray;
for (const auto &each: params->_paramMap.toStdMap()) { for (const auto& each : params->_paramMap.toStdMap())
{
QJsonObject json; QJsonObject json;
json.insert(each.first, each.second.toJsonValue()); json.insert(each.first,each.second.toJsonValue());
jsonArray.append(json); jsonArray.append(json);
} }
QByteArray data = QJsonDocument(jsonArray).toJson(QJsonDocument::Compact); QByteArray data = QJsonDocument(jsonArray).toJson(QJsonDocument::Compact);
reply = manager->sendCustomRequest(request, params->method2String().toUtf8(), data); reply = manager->sendCustomRequest(request,params->method2String().toUtf8(),data);
break; break;
} }
case NetworkParams::TYPE_BODY: { case NetworkParams::TYPE_BODY:{
request.setHeader(QNetworkRequest::ContentTypeHeader, QString("text/plain;charset=utf-8")); request.setHeader(QNetworkRequest::ContentTypeHeader, QString("text/plain;charset=utf-8"));
QByteArray data = params->_body.toUtf8(); QByteArray data = params->_body.toUtf8();
reply = manager->sendCustomRequest(request, verb, data); reply = manager->sendCustomRequest(request,verb,data);
break; break;
} }
default: default:
reply = manager->sendCustomRequest(request, verb); reply = manager->sendCustomRequest(request,verb);
break; break;
} }
if (isFirst) { if(isFirst){
printRequestStartLog(request, params); printRequestStartLog(request,params);
} }
} }
void Network::printRequestStartLog(const QNetworkRequest &request, NetworkParams *params) { void Network::printRequestStartLog(QNetworkRequest request,NetworkParams* params){
if (!params->getOpenLog()) { if(!params->getOpenLog()){
return; return;
} }
qDebug() << "<------" << qUtf8Printable(request.header(QNetworkRequest::UserAgentHeader).toString()) << "Request Start ------>"; qDebug()<<"<------"<<qUtf8Printable(request.header(QNetworkRequest::UserAgentHeader).toString())<<"Request Start ------>";
qDebug() << qUtf8Printable(QString::fromStdString("<%1>").arg(params->method2String())) << qUtf8Printable(params->_url); qDebug()<<qUtf8Printable(QString::fromStdString("<%1>").arg(params->method2String()))<<qUtf8Printable(params->_url);
auto contentType = request.header(QNetworkRequest::ContentTypeHeader).toString(); auto contentType = request.header(QNetworkRequest::ContentTypeHeader).toString();
if (!contentType.isEmpty()) { if(!contentType.isEmpty()){
qDebug() << qUtf8Printable(QString::fromStdString("<Header> %1=%2").arg("Content-Type", contentType)); qDebug()<<qUtf8Printable(QString::fromStdString("<Header> %1=%2").arg("Content-Type",contentType));
} }
QList<QByteArray> headers = request.rawHeaderList(); QList<QByteArray> headers = request.rawHeaderList();
for (const QByteArray &header: headers) { for(const QByteArray& header:headers){
qDebug() << qUtf8Printable(QString::fromStdString("<Header> %1=%2").arg(header, request.rawHeader(header))); qDebug()<<qUtf8Printable(QString::fromStdString("<Header> %1=%2").arg(header,request.rawHeader(header)));
} }
if (!params->_queryMap.isEmpty()) { if(!params->_queryMap.isEmpty()){
qDebug() << "<Query>" << qUtf8Printable(map2String(params->_queryMap)); qDebug()<<"<Query>"<<qUtf8Printable(map2String(params->_queryMap));
} }
if (!params->_paramMap.isEmpty()) { if(!params->_paramMap.isEmpty()){
qDebug() << "<Param>" << qUtf8Printable(map2String(params->_paramMap)); qDebug()<<"<Param>"<<qUtf8Printable(map2String(params->_paramMap));
} }
if (!params->_fileMap.isEmpty()) { if(!params->_fileMap.isEmpty()){
qDebug() << "<File>" << qUtf8Printable(map2String(params->_fileMap)); qDebug()<<"<File>"<<qUtf8Printable(map2String(params->_fileMap));
} }
if (!params->_body.isEmpty()) { if(!params->_body.isEmpty()){
qDebug() << "<Body>" << qUtf8Printable(params->_body); qDebug()<<"<Body>"<<qUtf8Printable(params->_body);
} }
} }
void Network::printRequestEndLog(const QNetworkRequest &request, NetworkParams *params, QNetworkReply *&reply, const QString &response) { void Network::printRequestEndLog(QNetworkRequest request,NetworkParams* params,QNetworkReply*& reply,const QString& response){
if (!params->getOpenLog()) { if(!params->getOpenLog()){
return; return;
} }
qDebug() << "<------" << qUtf8Printable(request.header(QNetworkRequest::UserAgentHeader).toString()) << "Request End ------>"; qDebug()<<"<------"<<qUtf8Printable(request.header(QNetworkRequest::UserAgentHeader).toString())<<"Request End ------>";
qDebug() << qUtf8Printable(QString::fromStdString("<%1>").arg(params->method2String())) << qUtf8Printable(params->_url); qDebug()<<qUtf8Printable(QString::fromStdString("<%1>").arg(params->method2String()))<<qUtf8Printable(params->_url);
qDebug() << "<Result>" << qUtf8Printable(response); qDebug()<<"<Result>"<<qUtf8Printable(response);
} }
void Network::saveResponse(const QString &key, const QString &response) { void Network::saveResponse(QString key,QString response){
QSharedPointer<QFile> file(new QFile(getCacheFilePath(key))); QSharedPointer<QFile> file(new QFile(getCacheFilePath(key)));
QIODevice::OpenMode mode = QIODevice::WriteOnly | QIODevice::Truncate; QIODevice::OpenMode mode = QIODevice::WriteOnly|QIODevice::Truncate;
if (!file->open(mode)) { if (!file->open(mode))
{
return; return;
} }
file->write(response.toUtf8().toBase64()); file->write(response.toUtf8().toBase64());
} }
void Network::addHeaders(QNetworkRequest *request, const QMap<QString, QVariant> &headers) { void Network::addHeaders(QNetworkRequest* request,const QMap<QString, QVariant>& headers){
request->setHeader(QNetworkRequest::UserAgentHeader, QString::fromStdString("Mozilla/5.0 %1/%2").arg(QGuiApplication::applicationName(), QGuiApplication::applicationVersion())); request->setHeader(QNetworkRequest::UserAgentHeader,QString::fromStdString("Mozilla/5.0 %1/%2").arg(QGuiApplication::applicationName(),QGuiApplication::applicationVersion()));
QMapIterator<QString, QVariant> iter(headers); QMapIterator<QString, QVariant> iter(headers);
while (iter.hasNext()) { while (iter.hasNext())
{
iter.next(); iter.next();
request->setRawHeader(iter.key().toUtf8(), iter.value().toString().toUtf8()); request->setRawHeader(iter.key().toUtf8(), iter.value().toString().toUtf8());
} }
} }
void Network::addQueryParam(QUrl *url, const QMap<QString, QVariant> &params) { void Network::addQueryParam(QUrl* url,const QMap<QString, QVariant>& params){
QMapIterator<QString, QVariant> iter(params); QMapIterator<QString, QVariant> iter(params);
QUrlQuery urlQuery(*url); QUrlQuery urlQuery(*url);
while (iter.hasNext()) { while (iter.hasNext())
{
iter.next(); iter.next();
urlQuery.addQueryItem(iter.key(), iter.value().toString()); urlQuery.addQueryItem(iter.key(), iter.value().toString());
} }
url->setQuery(urlQuery); url->setQuery(urlQuery);
} }
Network::Network(QObject *parent) : QObject{parent} { Network::Network(QObject *parent): QObject{parent}
_timeout = 5000; {
_retry = 3; timeout(5000);
_openLog = false; retry(3);
_cacheDir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation).append(QDir::separator()).append("network"); openLog(false);
cacheDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation).append(QDir::separator()).append("network"));
} }
NetworkParams *Network::get(const QString &url) { NetworkParams* Network::get(const QString& url){
return new NetworkParams(url, NetworkParams::TYPE_NONE, NetworkParams::METHOD_GET, this); return new NetworkParams(url,NetworkParams::TYPE_NONE,NetworkParams::METHOD_GET,this);
} }
NetworkParams *Network::head(const QString &url) { NetworkParams* Network::head(const QString& url){
return new NetworkParams(url, NetworkParams::TYPE_NONE, NetworkParams::METHOD_HEAD, this); return new NetworkParams(url,NetworkParams::TYPE_NONE,NetworkParams::METHOD_HEAD,this);
} }
NetworkParams *Network::postBody(const QString &url) { NetworkParams* Network::postBody(const QString& url){
return new NetworkParams(url, NetworkParams::TYPE_BODY, NetworkParams::METHOD_POST, this); return new NetworkParams(url,NetworkParams::TYPE_BODY,NetworkParams::METHOD_POST,this);
} }
NetworkParams *Network::putBody(const QString &url) { NetworkParams* Network::putBody(const QString& url){
return new NetworkParams(url, NetworkParams::TYPE_BODY, NetworkParams::METHOD_PUT, this); return new NetworkParams(url,NetworkParams::TYPE_BODY,NetworkParams::METHOD_PUT,this);
} }
NetworkParams *Network::patchBody(const QString &url) { NetworkParams* Network::patchBody(const QString& url){
return new NetworkParams(url, NetworkParams::TYPE_BODY, NetworkParams::METHOD_PATCH, this); return new NetworkParams(url,NetworkParams::TYPE_BODY,NetworkParams::METHOD_PATCH,this);
} }
NetworkParams *Network::deleteBody(const QString &url) { NetworkParams* Network::deleteBody(const QString& url){
return new NetworkParams(url, NetworkParams::TYPE_BODY, NetworkParams::METHOD_DELETE, this); return new NetworkParams(url,NetworkParams::TYPE_BODY,NetworkParams::METHOD_DELETE,this);
} }
NetworkParams *Network::postForm(const QString &url) { NetworkParams* Network::postForm(const QString& url){
return new NetworkParams(url, NetworkParams::TYPE_FORM, NetworkParams::METHOD_POST, this); return new NetworkParams(url,NetworkParams::TYPE_FORM,NetworkParams::METHOD_POST,this);
} }
NetworkParams *Network::putForm(const QString &url) { NetworkParams* Network::putForm(const QString& url){
return new NetworkParams(url, NetworkParams::TYPE_FORM, NetworkParams::METHOD_PUT, this); return new NetworkParams(url,NetworkParams::TYPE_FORM,NetworkParams::METHOD_PUT,this);
} }
NetworkParams *Network::patchForm(const QString &url) { NetworkParams* Network::patchForm(const QString& url){
return new NetworkParams(url, NetworkParams::TYPE_FORM, NetworkParams::METHOD_PATCH, this); return new NetworkParams(url,NetworkParams::TYPE_FORM,NetworkParams::METHOD_PATCH,this);
} }
NetworkParams *Network::deleteForm(const QString &url) { NetworkParams* Network::deleteForm(const QString& url){
return new NetworkParams(url, NetworkParams::TYPE_FORM, NetworkParams::METHOD_DELETE, this); return new NetworkParams(url,NetworkParams::TYPE_FORM,NetworkParams::METHOD_DELETE,this);
} }
NetworkParams *Network::postJson(const QString &url) { NetworkParams* Network::postJson(const QString& url){
return new NetworkParams(url, NetworkParams::TYPE_JSON, NetworkParams::METHOD_POST, this); return new NetworkParams(url,NetworkParams::TYPE_JSON,NetworkParams::METHOD_POST,this);
} }
NetworkParams *Network::putJson(const QString &url) { NetworkParams* Network::putJson(const QString& url){
return new NetworkParams(url, NetworkParams::TYPE_JSON, NetworkParams::METHOD_PUT, this); return new NetworkParams(url,NetworkParams::TYPE_JSON,NetworkParams::METHOD_PUT,this);
} }
NetworkParams *Network::patchJson(const QString &url) { NetworkParams* Network::patchJson(const QString& url){
return new NetworkParams(url, NetworkParams::TYPE_JSON, NetworkParams::METHOD_PATCH, this); return new NetworkParams(url,NetworkParams::TYPE_JSON,NetworkParams::METHOD_PATCH,this);
} }
NetworkParams *Network::deleteJson(const QString &url) { NetworkParams* Network::deleteJson(const QString& url){
return new NetworkParams(url, NetworkParams::TYPE_JSON, NetworkParams::METHOD_DELETE, this); return new NetworkParams(url,NetworkParams::TYPE_JSON,NetworkParams::METHOD_DELETE,this);
} }
NetworkParams *Network::postJsonArray(const QString &url) { NetworkParams* Network::postJsonArray(const QString& url){
return new NetworkParams(url, NetworkParams::TYPE_JSONARRAY, NetworkParams::METHOD_POST, this); return new NetworkParams(url,NetworkParams::TYPE_JSONARRAY,NetworkParams::METHOD_POST,this);
} }
NetworkParams *Network::putJsonArray(const QString &url) { NetworkParams* Network::putJsonArray(const QString& url){
return new NetworkParams(url, NetworkParams::TYPE_JSONARRAY, NetworkParams::METHOD_PUT, this); return new NetworkParams(url,NetworkParams::TYPE_JSONARRAY,NetworkParams::METHOD_PUT,this);
} }
NetworkParams *Network::patchJsonArray(const QString &url) { NetworkParams* Network::patchJsonArray(const QString& url){
return new NetworkParams(url, NetworkParams::TYPE_JSONARRAY, NetworkParams::METHOD_PATCH, this); return new NetworkParams(url,NetworkParams::TYPE_JSONARRAY,NetworkParams::METHOD_PATCH,this);
} }
NetworkParams *Network::deleteJsonArray(const QString &url) { NetworkParams* Network::deleteJsonArray(const QString& url){
return new NetworkParams(url, NetworkParams::TYPE_JSONARRAY, NetworkParams::METHOD_DELETE, this); return new NetworkParams(url,NetworkParams::TYPE_JSONARRAY,NetworkParams::METHOD_DELETE,this);
} }
void Network::setInterceptor(QJSValue interceptor) { void Network::setInterceptor(QJSValue interceptor){
this->_interceptor = std::move(interceptor); this->_interceptor = interceptor;
} }

View File

@ -1,4 +1,5 @@
#pragma once #ifndef NETWORK_H
#define NETWORK_H
#include <QObject> #include <QObject>
#include <QtQml/qqml.h> #include <QtQml/qqml.h>
@ -11,66 +12,56 @@
#include "src/singleton.h" #include "src/singleton.h"
namespace NetworkType { namespace NetworkType {
Q_NAMESPACE Q_NAMESPACE
enum CacheMode { enum CacheMode {
NoCache = 0x0000, NoCache = 0x0000,
RequestFailedReadCache = 0x0001, RequestFailedReadCache = 0x0001,
IfNoneCacheRequest = 0x0002, IfNoneCacheRequest = 0x0002,
FirstCacheThenRequest = 0x0004, FirstCacheThenRequest = 0x0004,
}; };
Q_ENUM_NS(CacheMode)
Q_ENUM_NS(CacheMode) QML_NAMED_ELEMENT(NetworkType)
QML_NAMED_ELEMENT(NetworkType)
} }
/** /**
* @brief The NetworkCallable class * @brief The NetworkCallable class
*/ */
class NetworkCallable : public QObject { class NetworkCallable : public QObject{
Q_OBJECT Q_OBJECT
QML_NAMED_ELEMENT(NetworkCallable) QML_NAMED_ELEMENT(NetworkCallable)
public: public:
explicit NetworkCallable(QObject *parent = nullptr); explicit NetworkCallable(QObject *parent = nullptr);
Q_SIGNAL void start(); Q_SIGNAL void start();
Q_SIGNAL void finish(); Q_SIGNAL void finish();
Q_SIGNAL void error(int status,QString errorString,QString result);
Q_SIGNAL void error(int status, QString errorString, QString result);
Q_SIGNAL void success(QString result); Q_SIGNAL void success(QString result);
Q_SIGNAL void cache(QString result); Q_SIGNAL void cache(QString result);
Q_SIGNAL void uploadProgress(qint64 sent, qint64 total); Q_SIGNAL void uploadProgress(qint64 sent, qint64 total);
Q_SIGNAL void downloadProgress(qint64 recv, qint64 total); Q_SIGNAL void downloadProgress(qint64 recv, qint64 total);
}; };
/** /**
* @brief The FluDownloadParam class * @brief The FluDownloadParam class
*/ */
class FluDownloadParam : public QObject { class FluDownloadParam : public QObject{
Q_OBJECT Q_OBJECT
public: public:
explicit FluDownloadParam(QObject *parent = nullptr); explicit FluDownloadParam(QObject *parent = nullptr);
FluDownloadParam(QString destPath,bool append,QObject *parent = nullptr);
FluDownloadParam(QString destPath, bool append, QObject *parent = nullptr);
public: public:
QString _destPath; QString _destPath;
bool _append{}; bool _append;
}; };
/** /**
* @brief The NetworkParams class * @brief The NetworkParams class
*/ */
class NetworkParams : public QObject { class NetworkParams : public QObject
Q_OBJECT {
Q_OBJECT
QML_NAMED_ELEMENT(NetworkParams) QML_NAMED_ELEMENT(NetworkParams)
public: public:
enum Method { enum Method{
METHOD_GET, METHOD_GET,
METHOD_HEAD, METHOD_HEAD,
METHOD_POST, METHOD_POST,
@ -78,55 +69,35 @@ public:
METHOD_PATCH, METHOD_PATCH,
METHOD_DELETE METHOD_DELETE
}; };
enum Type { enum Type{
TYPE_NONE, TYPE_NONE,
TYPE_FORM, TYPE_FORM,
TYPE_JSON, TYPE_JSON,
TYPE_JSONARRAY, TYPE_JSONARRAY,
TYPE_BODY TYPE_BODY
}; };
explicit NetworkParams(QObject *parent = nullptr); explicit NetworkParams(QObject *parent = nullptr);
NetworkParams(QString url,Type type,Method method,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 *addQuery(const QString &key, const QVariant &val); Q_INVOKABLE NetworkParams* add(QString key,QVariant val);
Q_INVOKABLE NetworkParams* addFile(QString key,QVariant val);
Q_INVOKABLE NetworkParams *addHeader(const QString &key, const QVariant &val); Q_INVOKABLE NetworkParams* setBody(QString val);
Q_INVOKABLE NetworkParams* setTimeout(int val);
Q_INVOKABLE NetworkParams *add(const QString &key, const QVariant &val); Q_INVOKABLE NetworkParams* setRetry(int val);
Q_INVOKABLE NetworkParams* setCacheMode(int val);
Q_INVOKABLE NetworkParams *addFile(const QString &key, const QVariant &val); Q_INVOKABLE NetworkParams* toDownload(QString destPath,bool append = false);
Q_INVOKABLE NetworkParams* bind(QObject* target);
Q_INVOKABLE NetworkParams *setBody(QString val); Q_INVOKABLE NetworkParams* openLog(QVariant val);
Q_INVOKABLE void go(NetworkCallable* result);
Q_INVOKABLE NetworkParams *setTimeout(int val); QString buildCacheKey();
QString method2String();
Q_INVOKABLE NetworkParams *setRetry(int val); int getTimeout();
int getRetry();
Q_INVOKABLE NetworkParams *setCacheMode(int val); bool getOpenLog();
Q_INVOKABLE NetworkParams *toDownload(QString destPath, bool append = false);
Q_INVOKABLE NetworkParams *bind(QObject *target);
Q_INVOKABLE NetworkParams *openLog(QVariant val);
Q_INVOKABLE void go(NetworkCallable *result);
QString buildCacheKey() const;
QString method2String() const;
int getTimeout() const;
int getRetry() const;
bool getOpenLog() const;
public: public:
FluDownloadParam *_downloadParam = nullptr; FluDownloadParam* _downloadParam = nullptr;
QObject *_target = nullptr; QObject* _target = nullptr;
Method _method; Method _method;
Type _type; Type _type;
QString _url; QString _url;
@ -144,88 +115,55 @@ public:
/** /**
* @brief The Network class * @brief The Network class
*/ */
class Network : public QObject { class Network : public QObject
Q_OBJECT {
Q_PROPERTY_AUTO(int, timeout) Q_OBJECT
Q_PROPERTY_AUTO(int, retry) Q_PROPERTY_AUTO(int,timeout)
Q_PROPERTY_AUTO(QString, cacheDir) Q_PROPERTY_AUTO(int,retry)
Q_PROPERTY_AUTO(bool, openLog) Q_PROPERTY_AUTO(QString,cacheDir)
Q_PROPERTY_AUTO(bool,openLog)
QML_NAMED_ELEMENT(Network) QML_NAMED_ELEMENT(Network)
QML_SINGLETON QML_SINGLETON
private: private:
explicit Network(QObject *parent = nullptr); explicit Network(QObject *parent = nullptr);
public: public:
SINGLETON(Network) SINGLETON(Network)
static Network *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return getInstance();}
static Network *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine) { return getInstance(); } Q_INVOKABLE NetworkParams* get(const QString& url);
Q_INVOKABLE NetworkParams* head(const QString& url);
Q_INVOKABLE NetworkParams *get(const QString &url); Q_INVOKABLE NetworkParams* postBody(const QString& url);
Q_INVOKABLE NetworkParams* putBody(const QString& url);
Q_INVOKABLE NetworkParams *head(const QString &url); Q_INVOKABLE NetworkParams* patchBody(const QString& url);
Q_INVOKABLE NetworkParams* deleteBody(const QString& url);
Q_INVOKABLE NetworkParams *postBody(const QString &url); Q_INVOKABLE NetworkParams* postForm(const QString& url);
Q_INVOKABLE NetworkParams* putForm(const QString& url);
Q_INVOKABLE NetworkParams *putBody(const QString &url); Q_INVOKABLE NetworkParams* patchForm(const QString& url);
Q_INVOKABLE NetworkParams* deleteForm(const QString& url);
Q_INVOKABLE NetworkParams *patchBody(const QString &url); Q_INVOKABLE NetworkParams* postJson(const QString& url);
Q_INVOKABLE NetworkParams* putJson(const QString& url);
Q_INVOKABLE NetworkParams *deleteBody(const QString &url); Q_INVOKABLE NetworkParams* patchJson(const QString& url);
Q_INVOKABLE NetworkParams* deleteJson(const QString& url);
Q_INVOKABLE NetworkParams *postForm(const QString &url); Q_INVOKABLE NetworkParams* postJsonArray(const QString& url);
Q_INVOKABLE NetworkParams* putJsonArray(const QString& url);
Q_INVOKABLE NetworkParams *putForm(const QString &url); Q_INVOKABLE NetworkParams* patchJsonArray(const QString& url);
Q_INVOKABLE NetworkParams* deleteJsonArray(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); Q_INVOKABLE void setInterceptor(QJSValue interceptor);
void handle(NetworkParams* params,NetworkCallable* result);
void handle(NetworkParams *params, NetworkCallable *result); void handleDownload(NetworkParams* params,NetworkCallable* result);
void handleDownload(NetworkParams *params, NetworkCallable *result);
private: private:
static void sendRequest(QNetworkAccessManager *manager, QNetworkRequest request, NetworkParams *params, QNetworkReply *&reply, bool isFirst, const QPointer<NetworkCallable> &callable); void sendRequest(QNetworkAccessManager* manager,QNetworkRequest request,NetworkParams* params,QNetworkReply*& reply,bool isFirst,QPointer<NetworkCallable> callable);
void addQueryParam(QUrl* url,const QMap<QString, QVariant>& params);
static void addQueryParam(QUrl *url, const QMap<QString, QVariant> &params); void addHeaders(QNetworkRequest* request,const QMap<QString, QVariant>& headers);
void saveResponse(QString key,QString response);
static void addHeaders(QNetworkRequest *request, const QMap<QString, QVariant> &headers); QString readCache(const QString& key);
bool cacheExists(const QString& key);
void saveResponse(const QString &key, const QString &response); QString getCacheFilePath(const QString& key);
QString map2String(const QMap<QString, QVariant>& map);
QString readCache(const QString &key); QString headerList2String(const QList<QNetworkReply::RawHeaderPair>& data);
void printRequestStartLog(QNetworkRequest request,NetworkParams* params);
bool cacheExists(const QString &key); void printRequestEndLog(QNetworkRequest request,NetworkParams* params,QNetworkReply*& reply,const QString& response);
QString getCacheFilePath(const QString &key);
static QString headerList2String(const QList<QNetworkReply::RawHeaderPair> &data);
static void printRequestStartLog(const QNetworkRequest &request, NetworkParams *params);
static void printRequestEndLog(const QNetworkRequest &request, NetworkParams *params, QNetworkReply *&reply, const QString &response);
static QString map2String(const QMap<QString, QVariant> &map);
public: public:
QJSValue _interceptor; QJSValue _interceptor;
}; };
#endif // Network_H

View File

@ -3,17 +3,19 @@
#include <QDataStream> #include <QDataStream>
#include <QStandardPaths> #include <QStandardPaths>
SettingsHelper::SettingsHelper(QObject *parent) : QObject(parent) { SettingsHelper::SettingsHelper(QObject *parent) : QObject(parent)
{
} }
SettingsHelper::~SettingsHelper() = default; SettingsHelper::~SettingsHelper() = default;
void SettingsHelper::save(const QString &key, QVariant val) { void SettingsHelper::save(const QString& key,QVariant val)
{
m_settings->setValue(key, val); m_settings->setValue(key, val);
} }
QVariant SettingsHelper::get(const QString &key, QVariant def) { QVariant SettingsHelper::get(const QString& key,QVariant def){
QVariant data = m_settings->value(key); QVariant data = m_settings->value(key);
if (!data.isNull() && data.isValid()) { if (!data.isNull() && data.isValid()) {
return data; return data;
@ -21,7 +23,7 @@ QVariant SettingsHelper::get(const QString &key, QVariant def) {
return def; return def;
} }
void SettingsHelper::init(char *argv[]) { void SettingsHelper::init(char *argv[]){
QString applicationPath = QString::fromStdString(argv[0]); QString applicationPath = QString::fromStdString(argv[0]);
const QFileInfo fileInfo(applicationPath); const QFileInfo fileInfo(applicationPath);
const QString iniFileName = fileInfo.completeBaseName() + ".ini"; const QString iniFileName = fileInfo.completeBaseName() + ".ini";

View File

@ -1,4 +1,5 @@
#pragma once #ifndef SETTINGSHELPER_H
#define SETTINGSHELPER_H
#include <QtCore/qobject.h> #include <QtCore/qobject.h>
#include <QtQml/qqml.h> #include <QtQml/qqml.h>
@ -9,35 +10,26 @@
#include <QDir> #include <QDir>
#include "src/singleton.h" #include "src/singleton.h"
class SettingsHelper : public QObject { class SettingsHelper : public QObject
Q_OBJECT {
Q_OBJECT
private: private:
explicit SettingsHelper(QObject *parent = nullptr); explicit SettingsHelper(QObject* parent = nullptr);
public: public:
SINGLETON(SettingsHelper) SINGLETON(SettingsHelper)
~SettingsHelper() override; ~SettingsHelper() override;
void init(char *argv[]); void init(char *argv[]);
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",QVariant(0)).toInt();}
Q_INVOKABLE void saveUseSystemAppBar(bool useSystemAppBar){save("useSystemAppBar",useSystemAppBar);}
Q_INVOKABLE int getDarkMode() { return get("darkMode", QVariant(0)).toInt(); } Q_INVOKABLE bool getUseSystemAppBar(){return get("useSystemAppBar",QVariant(false)).toBool();}
Q_INVOKABLE void saveLanguage(QString language){save("language",language);}
Q_INVOKABLE void saveUseSystemAppBar(bool useSystemAppBar) { save("useSystemAppBar", useSystemAppBar); } Q_INVOKABLE QString getLanguage(){return get("language",QVariant("en_US")).toString();}
Q_INVOKABLE bool getUseSystemAppBar() { return get("useSystemAppBar", QVariant(false)).toBool(); }
Q_INVOKABLE void saveLanguage(const QString &language) { save("language", language); }
Q_INVOKABLE QString getLanguage() { return get("language", QVariant("en_US")).toString(); }
private: private:
void save(const QString &key, QVariant val); void save(const QString& key,QVariant val);
QVariant get(const QString& key,QVariant def={});
QVariant get(const QString &key, QVariant def = {});
private: private:
QScopedPointer<QSettings> m_settings; QScopedPointer<QSettings> m_settings;
}; };
#endif // SETTINGSHELPER_H

View File

@ -5,20 +5,21 @@
#include "SettingsHelper.h" #include "SettingsHelper.h"
[[maybe_unused]] TranslateHelper::TranslateHelper(QObject *parent) : QObject(parent) { TranslateHelper::TranslateHelper(QObject *parent) : QObject(parent)
_languages << "en_US"; {
_languages << "zh_CN"; _languages<<"en_US";
_languages<<"zh_CN";
_current = SettingsHelper::getInstance()->getLanguage(); _current = SettingsHelper::getInstance()->getLanguage();
} }
TranslateHelper::~TranslateHelper() = default; TranslateHelper::~TranslateHelper() = default;
void TranslateHelper::init(QQmlEngine *engine) { void TranslateHelper::init(QQmlEngine* engine){
_engine = engine; _engine = engine;
_translator = new QTranslator(this); _translator = new QTranslator(this);
QGuiApplication::installTranslator(_translator); qApp->installTranslator(_translator);
QString translatorPath = QGuiApplication::applicationDirPath() + "/i18n"; QString translatorPath = QGuiApplication::applicationDirPath()+"/i18n";
if (_translator->load(QString::fromStdString("%1/example_%2.qm").arg(translatorPath, _current))) { if(_translator->load(QString::fromStdString("%1/example_%2.qm").arg(translatorPath,_current))){
_engine->retranslate(); _engine->retranslate();
} }
} }

View File

@ -1,4 +1,5 @@
#pragma once #ifndef TRANSLATEHELPER_H
#define TRANSLATEHELPER_H
#include <QObject> #include <QObject>
#include <QtQml/qqml.h> #include <QtQml/qqml.h>
@ -6,21 +7,20 @@
#include "src/singleton.h" #include "src/singleton.h"
#include "src/stdafx.h" #include "src/stdafx.h"
class TranslateHelper : public QObject { class TranslateHelper : public QObject
Q_OBJECT {
Q_PROPERTY_AUTO(QString, current) Q_OBJECT
Q_PROPERTY_READONLY_AUTO(QStringList, languages) Q_PROPERTY_AUTO(QString,current)
Q_PROPERTY_READONLY_AUTO(QStringList,languages)
private: private:
[[maybe_unused]] explicit TranslateHelper(QObject *parent = nullptr); explicit TranslateHelper(QObject* parent = nullptr);
public: public:
SINGLETON(TranslateHelper) SINGLETON(TranslateHelper)
~TranslateHelper() override; ~TranslateHelper() override;
void init(QQmlEngine* engine);
void init(QQmlEngine *engine);
private: private:
QQmlEngine *_engine = nullptr; QQmlEngine* _engine = nullptr;
QTranslator *_translator = nullptr; QTranslator* _translator = nullptr;
}; };
#endif // TRANSLATEHELPER_H

View File

@ -14,7 +14,6 @@
#include "src/component/CircularReveal.h" #include "src/component/CircularReveal.h"
#include "src/component/FileWatcher.h" #include "src/component/FileWatcher.h"
#include "src/component/FpsItem.h" #include "src/component/FpsItem.h"
#include "src/component/OpenGLItem.h"
#include "src/helper/SettingsHelper.h" #include "src/helper/SettingsHelper.h"
#include "src/helper/InitializrHelper.h" #include "src/helper/InitializrHelper.h"
#include "src/helper/TranslateHelper.h" #include "src/helper/TranslateHelper.h"
@ -54,7 +53,7 @@ int main(int argc, char *argv[])
QGuiApplication::setOrganizationName("ZhuZiChu"); QGuiApplication::setOrganizationName("ZhuZiChu");
QGuiApplication::setOrganizationDomain("https://zhuzichu520.github.io"); QGuiApplication::setOrganizationDomain("https://zhuzichu520.github.io");
QGuiApplication::setApplicationName("FluentUI"); QGuiApplication::setApplicationName("FluentUI");
QGuiApplication::setApplicationDisplayName("FluentUI Example"); QGuiApplication::setApplicationDisplayName("FluentUI Exmaple");
QGuiApplication::setApplicationVersion(APPLICATION_VERSION); QGuiApplication::setApplicationVersion(APPLICATION_VERSION);
QGuiApplication::setQuitOnLastWindowClosed(false); QGuiApplication::setQuitOnLastWindowClosed(false);
SettingsHelper::getInstance()->init(argv); SettingsHelper::getInstance()->init(argv);
@ -76,9 +75,6 @@ int main(int argc, char *argv[])
qmlRegisterType<FpsItem>(uri, major, minor, "FpsItem"); qmlRegisterType<FpsItem>(uri, major, minor, "FpsItem");
qmlRegisterType<NetworkCallable>(uri,major,minor,"NetworkCallable"); qmlRegisterType<NetworkCallable>(uri,major,minor,"NetworkCallable");
qmlRegisterType<NetworkParams>(uri,major,minor,"NetworkParams"); qmlRegisterType<NetworkParams>(uri,major,minor,"NetworkParams");
qmlRegisterType<OpenGLItem>(uri,major,minor,"OpenGLItem");
qmlRegisterUncreatableMetaObject(NetworkType::staticMetaObject, uri, major, minor, "NetworkType", "Access to enums & flags only");
QQmlApplicationEngine engine; QQmlApplicationEngine engine;
TranslateHelper::getInstance()->init(&engine); TranslateHelper::getInstance()->init(&engine);
engine.rootContext()->setContextProperty("AppInfo",AppInfo::getInstance()); engine.rootContext()->setContextProperty("AppInfo",AppInfo::getInstance());

View File

@ -1,17 +1,18 @@
#pragma once #ifndef SINGLETON_H
#define SINGLETON_H
/** /**
* @brief The Singleton class * @brief The Singleton class
*/ */
template<typename T> template <typename T>
class Singleton { class Singleton {
public: public:
static T *getInstance(); static T* getInstance();
}; };
template<typename T> template <typename T>
T *Singleton<T>::getInstance() { T* Singleton<T>::getInstance() {
static T *instance = new T(); static T* instance = new T();
return instance; return instance;
} }
@ -22,3 +23,5 @@ private: \
static Class* getInstance() { \ static Class* getInstance() { \
return Singleton<Class>::getInstance(); \ return Singleton<Class>::getInstance(); \
} }
#endif // SINGLETON_H

View File

@ -1,6 +1,7 @@
#pragma once #ifndef STDAFX_H
#define STDAFX_H
#define Q_PROPERTY_AUTO_P(TYPE, M) \ #define Q_PROPERTY_AUTO(TYPE, M) \
Q_PROPERTY(TYPE M MEMBER _##M NOTIFY M##Changed) \ Q_PROPERTY(TYPE M MEMBER _##M NOTIFY M##Changed) \
public: \ public: \
Q_SIGNAL void M##Changed(); \ Q_SIGNAL void M##Changed(); \
@ -14,30 +15,14 @@ Q_PROPERTY(TYPE M MEMBER _##M NOTIFY M##Changed)
return _##M; \ return _##M; \
} \ } \
private: \ private: \
TYPE _##M; TYPE _##M; \
#define Q_PROPERTY_AUTO(TYPE, M) \
Q_PROPERTY(TYPE M MEMBER _##M NOTIFY M##Changed) \
public: \
Q_SIGNAL void M##Changed(); \
void M(const TYPE& in_##M) \
{ \
_##M = in_##M; \
Q_EMIT M##Changed(); \
} \
TYPE M() \
{ \
return _##M; \
} \
private: \
TYPE _##M;
#define Q_PROPERTY_READONLY_AUTO(TYPE, M) \ #define Q_PROPERTY_READONLY_AUTO(TYPE, M) \
Q_PROPERTY(TYPE M READ M NOTIFY M##Changed FINAL) \ Q_PROPERTY(TYPE M READ M NOTIFY M##Changed FINAL) \
public: \ public: \
Q_SIGNAL void M##Changed(); \ Q_SIGNAL void M##Changed(); \
void M(const TYPE& in_##M) \ void M(TYPE in_##M) \
{ \ { \
_##M = in_##M; \ _##M = in_##M; \
Q_EMIT M##Changed(); \ Q_EMIT M##Changed(); \
@ -47,4 +32,6 @@ Q_PROPERTY(TYPE M READ M NOTIFY M##Changed FINAL)
return _##M; \ return _##M; \
} \ } \
private: \ private: \
TYPE _##M; TYPE _##M; \
#endif // STDAFX_H

View File

@ -2,9 +2,9 @@ cmake_minimum_required(VERSION 3.20)
if (FLUENTUI_BUILD_STATIC_LIB AND (QT_VERSION VERSION_GREATER_EQUAL "6.2")) if (FLUENTUI_BUILD_STATIC_LIB AND (QT_VERSION VERSION_GREATER_EQUAL "6.2"))
project(fluentui VERSION 1.0) project(fluentui VERSION 1.0)
else () else()
project(fluentuiplugin VERSION 1.0) project(fluentuiplugin VERSION 1.0)
endif () endif()
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/.cmake/) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/.cmake/)
@ -13,35 +13,35 @@ set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
# #
add_definitions(-DFLUENTUI_VERSION=1,7,5,0) add_definitions(-DFLUENTUI_VERSION=1,7,4,0)
if (FLUENTUI_BUILD_STATIC_LIB) if (FLUENTUI_BUILD_STATIC_LIB)
add_definitions(-DFLUENTUI_BUILD_STATIC_LIB) add_definitions(-DFLUENTUI_BUILD_STATIC_LIB)
endif () endif()
# #
option(FLUENTUI_BUILD_STATIC_LIB "Build static library." OFF) option(FLUENTUI_BUILD_STATIC_LIB "Build static library." OFF)
#Qt #Qt
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Quick Qml) find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Quick Qml)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Quick) find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Quick Qml)
set(QT_SDK_DIR "${Qt${QT_VERSION_MAJOR}_DIR}/../../..") set(QT_SDK_DIR "${Qt${QT_VERSION_MAJOR}_DIR}/../../..")
cmake_path(SET QT_SDK_DIR NORMALIZE ${QT_SDK_DIR}) cmake_path(SET QT_SDK_DIR NORMALIZE ${QT_SDK_DIR})
#QML<QT_SDK_DIR_PATH>\qml\FluentUI #QML<QT_SDK_DIR_PATH>\qml\FluentUI
set(FLUENTUI_QML_PLUGIN_DIRECTORY "" CACHE PATH "Path to FluentUI plugin") set(FLUENTUI_QML_PLUGIN_DIRECTORY "" CACHE PATH "Path to FluentUI plugin")
if (NOT FLUENTUI_QML_PLUGIN_DIRECTORY) if(NOT FLUENTUI_QML_PLUGIN_DIRECTORY)
set(FLUENTUI_QML_PLUGIN_DIRECTORY ${QT_SDK_DIR}/qml/FluentUI) set(FLUENTUI_QML_PLUGIN_DIRECTORY ${QT_SDK_DIR}/qml/FluentUI)
endif () endif()
if (QT_VERSION VERSION_GREATER_EQUAL "6.3") if(QT_VERSION VERSION_GREATER_EQUAL "6.3")
qt_standard_project_setup() qt_standard_project_setup()
else () else()
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON) set(CMAKE_AUTORCC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_INCLUDE_CURRENT_DIR ON)
endif () endif()
# #
find_program(QT_LUPDATE NAMES lupdate) find_program(QT_LUPDATE NAMES lupdate)
@ -59,76 +59,76 @@ file(GLOB QM_FILE_PATHS ${CMAKE_CURRENT_LIST_DIR}/ *.qm)
file(COPY ${QM_FILE_PATHS} DESTINATION "${CMAKE_CURRENT_SOURCE_DIR}/Qt${QT_VERSION_MAJOR}/imports/FluentUI/i18n") file(COPY ${QM_FILE_PATHS} DESTINATION "${CMAKE_CURRENT_SOURCE_DIR}/Qt${QT_VERSION_MAJOR}/imports/FluentUI/i18n")
#Cpp #Cpp
file(GLOB_RECURSE CPP_FILES *.cpp *.h *.cxx) file(GLOB_RECURSE CPP_FILES *.cpp *.h)
foreach (filepath ${CPP_FILES}) foreach(filepath ${CPP_FILES})
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" filename ${filepath}) string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" filename ${filepath})
list(APPEND sources_files ${filename}) list(APPEND sources_files ${filename})
endforeach (filepath) endforeach(filepath)
if (QT_VERSION VERSION_GREATER_EQUAL "6.2") if(QT_VERSION VERSION_GREATER_EQUAL "6.2")
#fluentuiplugin.cppfluentuiplugin.hQt5使Qt6 #fluentuiplugin.cppfluentuiplugin.hQt5使Qt6
list(REMOVE_ITEM sources_files fluentuiplugin.h fluentuiplugin.cpp) list(REMOVE_ITEM sources_files fluentuiplugin.h fluentuiplugin.cpp)
if (NOT FLUENTUI_BUILD_STATIC_LIB) if (NOT FLUENTUI_BUILD_STATIC_LIB)
list(REMOVE_ITEM sources_files FluentUI.h FluentUI.cpp) list(REMOVE_ITEM sources_files FluentUI.h FluentUI.cpp)
endif () endif()
#qml #qml
file(GLOB_RECURSE QML_PATHS *.qml qmldir) file(GLOB_RECURSE QML_PATHS *.qml qmldir)
foreach (filepath ${QML_PATHS}) foreach(filepath ${QML_PATHS})
if (${filepath} MATCHES "Qt${QT_VERSION_MAJOR}/") if(${filepath} MATCHES "Qt${QT_VERSION_MAJOR}/")
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" filename ${filepath}) string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" filename ${filepath})
if (${filename} MATCHES "qmldir") if(${filename} MATCHES "qmldir")
list(APPEND resource_files ${filename}) list(APPEND resource_files ${filename})
else () else()
list(APPEND qml_files ${filename}) list(APPEND qml_files ${filename})
endif () endif()
endif () endif()
endforeach (filepath) endforeach(filepath)
# #
file(GLOB_RECURSE RES_PATHS *.png *.jpg *.svg *.ico *.ttf *.webp *.js *.qm) file(GLOB_RECURSE RES_PATHS *.png *.jpg *.svg *.ico *.ttf *.webp *.js *.qm)
foreach (filepath ${RES_PATHS}) foreach(filepath ${RES_PATHS})
if (${filepath} MATCHES "Qt${QT_VERSION_MAJOR}/") if(${filepath} MATCHES "Qt${QT_VERSION_MAJOR}/")
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" filename ${filepath}) string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" filename ${filepath})
list(APPEND resource_files ${filename}) list(APPEND resource_files ${filename})
endif () endif()
endforeach (filepath) endforeach(filepath)
# #
foreach (filepath IN LISTS qml_files resource_files) foreach(filepath IN LISTS qml_files resource_files)
string(REPLACE "Qt${QT_VERSION_MAJOR}/imports/FluentUI/" "" filename ${filepath}) string(REPLACE "Qt${QT_VERSION_MAJOR}/imports/FluentUI/" "" filename ${filepath})
set_source_files_properties(${filepath} PROPERTIES QT_RESOURCE_ALIAS ${filename}) set_source_files_properties(${filepath} PROPERTIES QT_RESOURCE_ALIAS ${filename})
endforeach () endforeach()
endif () endif()
if (FLUENTUI_BUILD_STATIC_LIB) if (FLUENTUI_BUILD_STATIC_LIB)
set(LIB_TYPE "STATIC") set(LIB_TYPE "STATIC")
else () else()
set(LIB_TYPE "SHARED") set(LIB_TYPE "SHARED")
endif () endif()
if (FLUENTUI_BUILD_STATIC_LIB) if (FLUENTUI_BUILD_STATIC_LIB)
set(PLUGIN_TARGET_NAME "") set(PLUGIN_TARGET_NAME "")
else () else()
#使 QML #使 QML
set(PLUGIN_TARGET_NAME ${PROJECT_NAME}) set(PLUGIN_TARGET_NAME ${PROJECT_NAME})
endif () endif()
#Windowsrc #Windowsrc
set(FLUENTUI_VERSION_RC_PATH "") set(FLUENTUI_VERSION_RC_PATH "")
if (WIN32) if(WIN32)
set(FLUENTUI_VERSION_RC_PATH ${CMAKE_CURRENT_BINARY_DIR}/version_${PROJECT_NAME}.rc) set(FLUENTUI_VERSION_RC_PATH ${CMAKE_CURRENT_BINARY_DIR}/version_${PROJECT_NAME}.rc)
configure_file( configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/.cmake/version_dll.rc.in ${CMAKE_CURRENT_SOURCE_DIR}/.cmake/version_dll.rc.in
${FLUENTUI_VERSION_RC_PATH} ${FLUENTUI_VERSION_RC_PATH}
) )
endif () endif()
if (QT_VERSION VERSION_GREATER_EQUAL "6.2") if(QT_VERSION VERSION_GREATER_EQUAL "6.2")
#Qt6.2使qt_add_libraryqt_add_qml_module #Qt6.2使qt_add_libraryqt_add_qml_module
if (FLUENTUI_BUILD_STATIC_LIB) if(FLUENTUI_BUILD_STATIC_LIB)
set(FLUENTUI_QML_PLUGIN_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/FluentUI) set(FLUENTUI_QML_PLUGIN_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/FluentUI)
endif () endif()
qt_add_library(${PROJECT_NAME} ${LIB_TYPE}) qt_add_library(${PROJECT_NAME} ${LIB_TYPE})
qt_add_qml_module(${PROJECT_NAME} qt_add_qml_module(${PROJECT_NAME}
PLUGIN_TARGET ${PLUGIN_TARGET_NAME} PLUGIN_TARGET ${PLUGIN_TARGET_NAME}
@ -142,8 +142,12 @@ if (QT_VERSION VERSION_GREATER_EQUAL "6.2")
RESOURCES ${resource_files} RESOURCES ${resource_files}
RESOURCE_PREFIX "/qt/qml" RESOURCE_PREFIX "/qt/qml"
) )
else () else()
qt_add_resources(QRC_RESOURCES Qt5/imports/fluentui.qrc) #qrc
set(QRC_FILE Qt5/imports/fluentui.qrc)
qt_add_big_resources(QRC_RESOURCES ${QRC_FILE})
list(APPEND QRC_RESOURCES ${QRC_FILE})
set_property(SOURCE ${QRC_FILE} PROPERTY SKIP_AUTORCC ON)
#Qt6.2使add_qmlplugin.cmake/QmlPlugin.cmake #Qt6.2使add_qmlplugin.cmake/QmlPlugin.cmake
include(QmlPlugin) include(QmlPlugin)
add_qmlplugin(${PROJECT_NAME} add_qmlplugin(${PROJECT_NAME}
@ -155,7 +159,7 @@ else ()
BINARY_DIR ${FLUENTUI_QML_PLUGIN_DIRECTORY} BINARY_DIR ${FLUENTUI_QML_PLUGIN_DIRECTORY}
LIBTYPE ${LIB_TYPE} LIBTYPE ${LIB_TYPE}
) )
endif () endif()
target_compile_definitions(${PROJECT_NAME} target_compile_definitions(${PROJECT_NAME}
PRIVATE PRIVATE
@ -164,14 +168,14 @@ target_compile_definitions(${PROJECT_NAME}
) )
#mingwlibxxxlib module "FluentUI" plugin "fluentuiplugin" not found #mingwlibxxxlib module "FluentUI" plugin "fluentuiplugin" not found
if (MINGW) if(MINGW)
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "") set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")
endif () endif()
#MSVC Debug dQt #MSVC Debug dQt
if (MSVC) if(MSVC)
set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX "d") set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX "d")
endif () endif()
# #
target_link_libraries(${PROJECT_NAME} PUBLIC target_link_libraries(${PROJECT_NAME} PUBLIC

1
src/Def.cpp Normal file
View File

@ -0,0 +1 @@
#include "Def.h"

1576
src/Def.h

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -1,4 +1,5 @@
#pragma once #ifndef FLUACCENTCOLOR_H
#define FLUACCENTCOLOR_H
#include <QObject> #include <QObject>
#include <QtQml/qqml.h> #include <QtQml/qqml.h>
@ -8,17 +9,19 @@
/** /**
* @brief The FluAccentColor class * @brief The FluAccentColor class
*/ */
class FluAccentColor : public QObject { class FluAccentColor : public QObject
Q_OBJECT {
Q_OBJECT
Q_PROPERTY_AUTO(QColor, darkest) Q_PROPERTY_AUTO(QColor,darkest)
Q_PROPERTY_AUTO(QColor, darker) Q_PROPERTY_AUTO(QColor,darker)
Q_PROPERTY_AUTO(QColor, dark) Q_PROPERTY_AUTO(QColor,dark)
Q_PROPERTY_AUTO(QColor, normal) Q_PROPERTY_AUTO(QColor,normal)
Q_PROPERTY_AUTO(QColor, light) Q_PROPERTY_AUTO(QColor,light)
Q_PROPERTY_AUTO(QColor, lighter) Q_PROPERTY_AUTO(QColor,lighter)
Q_PROPERTY_AUTO(QColor, lightest) Q_PROPERTY_AUTO(QColor,lightest)
QML_NAMED_ELEMENT(FluAccentColor) QML_NAMED_ELEMENT(FluAccentColor)
public: public:
explicit FluAccentColor(QObject *parent = nullptr); explicit FluAccentColor(QObject *parent = nullptr);
}; };
#endif // FLUACCENTCOLOR_H

View File

@ -2,48 +2,32 @@
#include <QQmlEngine> #include <QQmlEngine>
#include <QGuiApplication> #include <QGuiApplication>
#include <QQmlContext>
#include <QQuickItem> #include <QQuickItem>
#include <QTimer> #include <QTimer>
#include <QUuid> #include <QUuid>
#include <QFontDatabase> #include <QFontDatabase>
#include <QClipboard> #include <QClipboard>
#include <QTranslator> #include <QTranslator>
#include <utility>
#include "FluentIconDef.h"
FluApp::FluApp(QObject *parent) : QObject{parent} { FluApp::FluApp(QObject *parent):QObject{parent}{
_useSystemAppBar = false; useSystemAppBar(false);
} }
FluApp::~FluApp() = default; FluApp::~FluApp(){
}
void FluApp::init(QObject *target, QLocale locale) { void FluApp::init(QObject *target,QLocale locale){
_locale = std::move(locale); _locale = locale;
_engine = qmlEngine(target); _engine = qmlEngine(target);
_translator = new QTranslator(this); _translator = new QTranslator(this);
QGuiApplication::installTranslator(_translator); qApp->installTranslator(_translator);
const QStringList uiLanguages = _locale.uiLanguages(); const QStringList uiLanguages = _locale.uiLanguages();
for (const QString &name: uiLanguages) { for (const QString &name : uiLanguages) {
const QString baseName = "fluentui_" + QLocale(name).name(); const QString baseName = "fluentui_" + QLocale(name).name();
if (_translator->load(":/qt/qml/FluentUI/i18n/" + baseName)) { if (_translator->load(":/qt/qml/FluentUI/i18n/"+ baseName)) {
_engine->retranslate(); _engine->retranslate();
break; break;
} }
} }
} }
[[maybe_unused]] QJsonArray FluApp::iconDatas(const QString &keyword) {
QJsonArray arr;
QMetaEnum enumType = Fluent_Icons::staticMetaObject.enumerator(Fluent_Icons::staticMetaObject.indexOfEnumerator("Fluent_IconType"));
for (int i = 0; i <= enumType.keyCount() - 1; ++i) {
QString name = enumType.key(i);
int icon = enumType.value(i);
if (keyword.isEmpty() || name.contains(keyword)) {
QJsonObject obj;
obj.insert("name", name);
obj.insert("icon", icon);
arr.append(obj);
}
}
return arr;
}

View File

@ -1,4 +1,5 @@
#pragma once #ifndef FLUAPP_H
#define FLUAPP_H
#include <QObject> #include <QObject>
#include <QWindow> #include <QWindow>
@ -8,37 +9,30 @@
#include <QQmlEngine> #include <QQmlEngine>
#include <QTranslator> #include <QTranslator>
#include <QQuickWindow> #include <QQuickWindow>
#include <QJsonArray>
#include "stdafx.h" #include "stdafx.h"
#include "singleton.h" #include "singleton.h"
/** /**
* @brief The FluApp class * @brief The FluApp class
*/ */
class FluApp : public QObject { class FluApp : public QObject
Q_OBJECT {
Q_OBJECT
Q_PROPERTY_AUTO(bool, useSystemAppBar) Q_PROPERTY_AUTO(bool,useSystemAppBar);
Q_PROPERTY_AUTO(QString, windowIcon) Q_PROPERTY_AUTO(QString,windowIcon);
Q_PROPERTY_AUTO(QLocale, locale) Q_PROPERTY_AUTO(QLocale,locale);
QML_NAMED_ELEMENT(FluApp) QML_NAMED_ELEMENT(FluApp)
QML_SINGLETON QML_SINGLETON
private: private:
explicit FluApp(QObject *parent = nullptr); explicit FluApp(QObject *parent = nullptr);
~FluApp();
~FluApp() override;
public: public:
SINGLETON(FluApp) SINGLETON(FluApp)
static FluApp *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return getInstance();}
static FluApp *create(QQmlEngine *, QJSEngine *) { return getInstance(); } Q_INVOKABLE void init(QObject *target,QLocale locale = QLocale::system());
Q_INVOKABLE void init(QObject *target, QLocale locale = QLocale::system());
[[maybe_unused]] Q_INVOKABLE static QJsonArray iconDatas(const QString &keyword = "");
private: private:
QQmlEngine *_engine{}; QQmlEngine *_engine;
QTranslator *_translator = nullptr; QTranslator* _translator = nullptr;
}; };
#endif // FLUAPP_H

View File

@ -3,67 +3,74 @@
#include <QChar> #include <QChar>
#include <QPainter> #include <QPainter>
#include <QRandomGenerator> #include <QRandomGenerator>
#include <qmath.h>
int generaNumber(int number) { FluCaptcha::FluCaptcha(QQuickItem *parent):QQuickPaintedItem(parent){
return QRandomGenerator::global()->bounded(0, number); ignoreCase(true);
} QFont fontStype;
fontStype.setPixelSize(28);
FluCaptcha::FluCaptcha(QQuickItem *parent) : QQuickPaintedItem(parent) { fontStype.setBold(true);
_ignoreCase = false; font(fontStype);
QFont fontStyle;
#ifdef Q_OS_WIN
fontStyle.setFamily("微软雅黑");
#endif
fontStyle.setPixelSize(28);
fontStyle.setBold(true);
font(fontStyle);
setWidth(180); setWidth(180);
setHeight(80); setHeight(80);
refresh(); refresh();
} }
void FluCaptcha::paint(QPainter *painter) { void FluCaptcha::paint(QPainter* painter){
painter->save(); painter->save();
painter->fillRect(boundingRect().toRect(), QColor(255, 255, 255, 255)); painter->fillRect(boundingRect().toRect(),QColor(255,255,255,255));
QPen pen; QPen pen;
painter->setFont(_font); painter->setFont(_font);
for (int i = 0; i < 100; i++) { for(int i=0;i<100;i++)
pen = QPen(QColor(generaNumber(256), generaNumber(256), generaNumber(256))); {
pen = QPen(QColor(_generaNumber(256),_generaNumber(256),_generaNumber(256)));
painter->setPen(pen); painter->setPen(pen);
painter->drawPoint(generaNumber(180), generaNumber(80)); painter->drawPoint(_generaNumber(180),_generaNumber(80));
} }
for (int i = 0; i < 5; i++) { for(int i=0;i<5;i++)
pen = QPen(QColor(generaNumber(256), generaNumber(256), generaNumber(256))); {
pen = QPen(QColor(_generaNumber(256),_generaNumber(256),_generaNumber(256)));
painter->setPen(pen); painter->setPen(pen);
painter->drawLine(generaNumber(180), generaNumber(80), generaNumber(180), generaNumber(80)); painter->drawLine(_generaNumber(180),_generaNumber(80),_generaNumber(180),_generaNumber(80));
} }
for (int i = 0; i < 4; i++) { for(int i=0;i<4;i++)
pen = QPen(QColor(generaNumber(255), generaNumber(255), generaNumber(255))); {
pen = QPen(QColor(_generaNumber(255),_generaNumber(255),_generaNumber(255)));
painter->setPen(pen); painter->setPen(pen);
painter->drawText(15 + 35 * i, 10 + generaNumber(15), 30, 40, Qt::AlignCenter, QString(_code[i])); painter->drawText(15+35*i,10+_generaNumber(15),30,40,Qt::AlignCenter, QString(_code[i]));
} }
painter->restore(); painter->restore();
} }
void FluCaptcha::refresh() { int FluCaptcha::_generaNumber(int number){
return QRandomGenerator::global()->bounded(0,number);
}
void FluCaptcha::refresh(){
this->_code.clear(); this->_code.clear();
for (int i = 0; i < 4; ++i) { for(int i = 0;i < 4;++i)
int num = generaNumber(3); {
if (num == 0) { int num = _generaNumber(3);
this->_code += QString::number(generaNumber(10)); if(num == 0)
} else if (num == 1) { {
this->_code += QString::number(_generaNumber(10));
}
else if(num == 1)
{
int temp = 'A'; int temp = 'A';
this->_code += static_cast<QChar>(temp + generaNumber(26)); this->_code += static_cast<QChar>(temp + _generaNumber(26));
} else if (num == 2) { }
else if(num == 2)
{
int temp = 'a'; int temp = 'a';
this->_code += static_cast<QChar>(temp + generaNumber(26)); this->_code += static_cast<QChar>(temp + _generaNumber(26));
} }
} }
update(); update();
} }
[[maybe_unused]] bool FluCaptcha::verify(const QString &code) { bool FluCaptcha::verify(const QString& code){
if (_ignoreCase) { if(_ignoreCase){
return this->_code.toUpper() == code.toUpper(); return this->_code.toUpper() == code.toUpper();
} }
return this->_code == code; return this->_code == code;

View File

@ -1,4 +1,5 @@
#pragma once #ifndef FLUCAPTCHA_H
#define FLUCAPTCHA_H
#include <QQuickItem> #include <QQuickItem>
#include <QQuickPaintedItem> #include <QQuickPaintedItem>
@ -8,22 +9,21 @@
/** /**
* @brief The FluCaptcha class * @brief The FluCaptcha class
*/ */
class FluCaptcha : public QQuickPaintedItem { class FluCaptcha : public QQuickPaintedItem
Q_OBJECT {
Q_OBJECT
Q_PROPERTY_AUTO(QFont, font); Q_PROPERTY_AUTO(QFont,font);
Q_PROPERTY_AUTO(bool, ignoreCase); Q_PROPERTY_AUTO(bool,ignoreCase);
QML_NAMED_ELEMENT(FluCaptcha) QML_NAMED_ELEMENT(FluCaptcha)
private:
int _generaNumber(int number);
public: public:
explicit FluCaptcha(QQuickItem *parent = nullptr); explicit FluCaptcha(QQuickItem *parent = nullptr);
void paint(QPainter* painter) override;
void paint(QPainter *painter) override;
Q_INVOKABLE void refresh(); Q_INVOKABLE void refresh();
Q_INVOKABLE bool verify(const QString& code);
[[maybe_unused]] Q_INVOKABLE bool verify(const QString &code);
private: private:
QString _code; QString _code;
}; };
#endif // FLUCAPTCHA_H

View File

@ -1,34 +1,35 @@
#include "FluColors.h" #include "FluColors.h"
#include "FluTools.h" #include "FluTools.h"
FluColors::FluColors(QObject *parent) : QObject{parent} { FluColors::FluColors(QObject *parent):QObject{parent}{
_Transparent = QColor(0, 0, 0, 0); Transparent(QColor(0, 0, 0, 0));
_Black = QColor(0, 0, 0); Black(QColor(0, 0, 0));
_White = QColor(255, 255, 255); White(QColor(255, 255, 255));
_Grey10 = QColor(250, 249, 248); Grey10(QColor(250, 249, 248));
_Grey20 = QColor(243, 242, 241); Grey20(QColor(243, 242, 241));
_Grey30 = QColor(237, 235, 233); Grey30(QColor(237, 235, 233));
_Grey40 = QColor(225, 223, 221); Grey40(QColor(225, 223, 221));
_Grey50 = QColor(210, 208, 206); Grey50(QColor(210, 208, 206));
_Grey60 = QColor(200, 198, 196); Grey60(QColor(200, 198, 196));
_Grey70 = QColor(190, 185, 184); Grey70(QColor(190, 185, 184));
_Grey80 = QColor(179, 176, 173); Grey80(QColor(179, 176, 173));
_Grey90 = QColor(161, 159, 157); Grey90(QColor(161, 159, 157));
_Grey100 = QColor(151, 149, 146); Grey100(QColor(151, 149, 146));
_Grey110 = QColor(138, 136, 134); Grey110(QColor(138, 136, 134));
_Grey120 = QColor(121, 119, 117); Grey120(QColor(121, 119, 117));
_Grey130 = QColor(96, 94, 92); Grey130(QColor(96, 94, 92));
_Grey140 = QColor(72, 70, 68); Grey140(QColor(72, 70, 68));
_Grey150 = QColor(59, 58, 57); Grey150(QColor(59, 58, 57));
_Grey160 = QColor(50, 49, 48); Grey160(QColor(50, 49, 48));
_Grey170 = QColor(41, 40, 39); Grey170(QColor(41, 40, 39));
_Grey180 = QColor(37, 36, 35); Grey180(QColor(37, 36, 35));
_Grey190 = QColor(32, 31, 30); Grey190(QColor(32, 31, 30));
_Grey200 = QColor(27, 26, 25); Grey200(QColor(27, 26, 25));
_Grey210 = QColor(22, 21, 20); Grey210(QColor(22, 21, 20));
_Grey220 = QColor(17, 16, 15); Grey220(QColor(17, 16, 15));
auto yellow = new FluAccentColor(this);
FluAccentColor *yellow = new FluAccentColor(this);
yellow->darkest(QColor(249, 168, 37)); yellow->darkest(QColor(249, 168, 37));
yellow->darker(QColor(251, 192, 45)); yellow->darker(QColor(251, 192, 45));
yellow->dark(QColor(253, 212, 53)); yellow->dark(QColor(253, 212, 53));
@ -36,9 +37,9 @@ FluColors::FluColors(QObject *parent) : QObject{parent} {
yellow->light(QColor(255, 238, 88)); yellow->light(QColor(255, 238, 88));
yellow->lighter(QColor(255, 241, 118)); yellow->lighter(QColor(255, 241, 118));
yellow->lightest(QColor(255, 245, 155)); yellow->lightest(QColor(255, 245, 155));
_Yellow = yellow; Yellow(yellow);
auto orange = new FluAccentColor(this); FluAccentColor *orange = new FluAccentColor(this);
orange->darkest(QColor(153, 61, 7)); orange->darkest(QColor(153, 61, 7));
orange->darker(QColor(172, 68, 8)); orange->darker(QColor(172, 68, 8));
orange->dark(QColor(209, 88, 10)); orange->dark(QColor(209, 88, 10));
@ -46,9 +47,9 @@ FluColors::FluColors(QObject *parent) : QObject{parent} {
orange->light(QColor(248, 122, 48)); orange->light(QColor(248, 122, 48));
orange->lighter(QColor(249, 145, 84)); orange->lighter(QColor(249, 145, 84));
orange->lightest(QColor(250, 192, 106)); orange->lightest(QColor(250, 192, 106));
_Orange = orange; Orange(orange);
auto red = new FluAccentColor(this); FluAccentColor *red = new FluAccentColor(this);
red->darkest(QColor(143, 10, 21)); red->darkest(QColor(143, 10, 21));
red->darker(QColor(162, 11, 24)); red->darker(QColor(162, 11, 24));
red->dark(QColor(185, 13, 28)); red->dark(QColor(185, 13, 28));
@ -56,9 +57,9 @@ FluColors::FluColors(QObject *parent) : QObject{parent} {
red->light(QColor(236, 64, 79)); red->light(QColor(236, 64, 79));
red->lighter(QColor(238, 88, 101)); red->lighter(QColor(238, 88, 101));
red->lightest(QColor(240, 107, 118)); red->lightest(QColor(240, 107, 118));
_Red = red; Red(red);
auto magenta = new FluAccentColor(this); FluAccentColor *magenta = new FluAccentColor(this);
magenta->darkest(QColor(111, 0, 79)); magenta->darkest(QColor(111, 0, 79));
magenta->darker(QColor(160, 7, 108)); magenta->darker(QColor(160, 7, 108));
magenta->dark(QColor(181, 13, 125)); magenta->dark(QColor(181, 13, 125));
@ -66,9 +67,9 @@ FluColors::FluColors(QObject *parent) : QObject{parent} {
magenta->light(QColor(234, 77, 168)); magenta->light(QColor(234, 77, 168));
magenta->lighter(QColor(238, 110, 193)); magenta->lighter(QColor(238, 110, 193));
magenta->lightest(QColor(241, 140, 213)); magenta->lightest(QColor(241, 140, 213));
_Magenta = magenta; Magenta(magenta);
auto purple = new FluAccentColor(this); FluAccentColor *purple = new FluAccentColor(this);
purple->darkest(QColor(44, 15, 118)); purple->darkest(QColor(44, 15, 118));
purple->darker(QColor(61, 15, 153)); purple->darker(QColor(61, 15, 153));
purple->dark(QColor(78, 17, 174)); purple->dark(QColor(78, 17, 174));
@ -76,9 +77,9 @@ FluColors::FluColors(QObject *parent) : QObject{parent} {
purple->light(QColor(123, 76, 157)); purple->light(QColor(123, 76, 157));
purple->lighter(QColor(141, 110, 189)); purple->lighter(QColor(141, 110, 189));
purple->lightest(QColor(158, 142, 217)); purple->lightest(QColor(158, 142, 217));
_Purple = purple; Purple(purple);
auto blue = new FluAccentColor(this); FluAccentColor *blue = new FluAccentColor(this);
blue->darkest(QColor(0, 74, 131)); blue->darkest(QColor(0, 74, 131));
blue->darker(QColor(0, 84, 148)); blue->darker(QColor(0, 84, 148));
blue->dark(QColor(0, 102, 180)); blue->dark(QColor(0, 102, 180));
@ -86,9 +87,9 @@ FluColors::FluColors(QObject *parent) : QObject{parent} {
blue->light(QColor(38, 140, 220)); blue->light(QColor(38, 140, 220));
blue->lighter(QColor(76, 160, 224)); blue->lighter(QColor(76, 160, 224));
blue->lightest(QColor(96, 171, 228)); blue->lightest(QColor(96, 171, 228));
_Blue = blue; Blue(blue);
auto teal = new FluAccentColor(this); FluAccentColor *teal = new FluAccentColor(this);
teal->darkest(QColor(0, 110, 91)); teal->darkest(QColor(0, 110, 91));
teal->darker(QColor(0, 124, 103)); teal->darker(QColor(0, 124, 103));
teal->dark(QColor(0, 151, 125)); teal->dark(QColor(0, 151, 125));
@ -96,9 +97,9 @@ FluColors::FluColors(QObject *parent) : QObject{parent} {
teal->light(QColor(38, 189, 164)); teal->light(QColor(38, 189, 164));
teal->lighter(QColor(77, 201, 180)); teal->lighter(QColor(77, 201, 180));
teal->lightest(QColor(96, 207, 188)); teal->lightest(QColor(96, 207, 188));
_Teal = teal; Teal(teal);
auto green = new FluAccentColor(this); FluAccentColor *green = new FluAccentColor(this);
green->darkest(QColor(9, 76, 9)); green->darkest(QColor(9, 76, 9));
green->darker(QColor(12, 93, 12)); green->darker(QColor(12, 93, 12));
green->dark(QColor(14, 111, 14)); green->dark(QColor(14, 111, 14));
@ -106,17 +107,17 @@ FluColors::FluColors(QObject *parent) : QObject{parent} {
green->light(QColor(39, 137, 57)); green->light(QColor(39, 137, 57));
green->lighter(QColor(76, 156, 76)); green->lighter(QColor(76, 156, 76));
green->lightest(QColor(106, 173, 106)); green->lightest(QColor(106, 173, 106));
_Green = green; Green(green);
} }
[[maybe_unused]] FluAccentColor *FluColors::createAccentColor(const QColor &primaryColor) { FluAccentColor* FluColors::createAccentColor(QColor primaryColor){
auto accentColor = new FluAccentColor(this); FluAccentColor *accentColor = new FluAccentColor(this);
accentColor->darkest(FluTools::getInstance()->withOpacity(primaryColor,0.7));
accentColor->darker(FluTools::getInstance()->withOpacity(primaryColor,0.8));
accentColor->dark(FluTools::getInstance()->withOpacity(primaryColor,0.9));
accentColor->normal(primaryColor); accentColor->normal(primaryColor);
accentColor->dark(FluTools::getInstance()->withOpacity(primaryColor, 0.9)); accentColor->light(FluTools::getInstance()->withOpacity(primaryColor,0.9));
accentColor->light(FluTools::getInstance()->withOpacity(primaryColor, 0.9)); accentColor->lighter(FluTools::getInstance()->withOpacity(primaryColor,0.8));
accentColor->darker(FluTools::getInstance()->withOpacity(accentColor->dark(), 0.8)); accentColor->lightest(FluTools::getInstance()->withOpacity(primaryColor,0.7));
accentColor->lighter(FluTools::getInstance()->withOpacity(accentColor->light(), 0.8));
accentColor->darkest(FluTools::getInstance()->withOpacity(accentColor->darker(), 0.7));
accentColor->lightest(FluTools::getInstance()->withOpacity(accentColor->lighter(), 0.7));
return accentColor; return accentColor;
} }

View File

@ -1,4 +1,5 @@
#pragma once #ifndef FLUCOLORS_H
#define FLUCOLORS_H
#include <QObject> #include <QObject>
#include <QtQml/qqml.h> #include <QtQml/qqml.h>
@ -10,52 +11,50 @@
/** /**
* @brief The FluColors class * @brief The FluColors class
*/ */
class FluColors : public QObject { class FluColors : public QObject
Q_OBJECT {
Q_OBJECT
Q_PROPERTY_AUTO(QColor, Transparent); Q_PROPERTY_AUTO(QColor,Transparent);
Q_PROPERTY_AUTO(QColor, Black); Q_PROPERTY_AUTO(QColor,Black);
Q_PROPERTY_AUTO(QColor, White); Q_PROPERTY_AUTO(QColor,White);
Q_PROPERTY_AUTO(QColor, Grey10); Q_PROPERTY_AUTO(QColor,Grey10);
Q_PROPERTY_AUTO(QColor, Grey20); Q_PROPERTY_AUTO(QColor,Grey20);
Q_PROPERTY_AUTO(QColor, Grey30); Q_PROPERTY_AUTO(QColor,Grey30);
Q_PROPERTY_AUTO(QColor, Grey40); Q_PROPERTY_AUTO(QColor,Grey40);
Q_PROPERTY_AUTO(QColor, Grey50); Q_PROPERTY_AUTO(QColor,Grey50);
Q_PROPERTY_AUTO(QColor, Grey60); Q_PROPERTY_AUTO(QColor,Grey60);
Q_PROPERTY_AUTO(QColor, Grey70); Q_PROPERTY_AUTO(QColor,Grey70);
Q_PROPERTY_AUTO(QColor, Grey80); Q_PROPERTY_AUTO(QColor,Grey80);
Q_PROPERTY_AUTO(QColor, Grey90); Q_PROPERTY_AUTO(QColor,Grey90);
Q_PROPERTY_AUTO(QColor, Grey100); Q_PROPERTY_AUTO(QColor,Grey100);
Q_PROPERTY_AUTO(QColor, Grey110); Q_PROPERTY_AUTO(QColor,Grey110);
Q_PROPERTY_AUTO(QColor, Grey120); Q_PROPERTY_AUTO(QColor,Grey120);
Q_PROPERTY_AUTO(QColor, Grey130); Q_PROPERTY_AUTO(QColor,Grey130);
Q_PROPERTY_AUTO(QColor, Grey140); Q_PROPERTY_AUTO(QColor,Grey140);
Q_PROPERTY_AUTO(QColor, Grey150); Q_PROPERTY_AUTO(QColor,Grey150);
Q_PROPERTY_AUTO(QColor, Grey160); Q_PROPERTY_AUTO(QColor,Grey160);
Q_PROPERTY_AUTO(QColor, Grey170); Q_PROPERTY_AUTO(QColor,Grey170);
Q_PROPERTY_AUTO(QColor, Grey180); Q_PROPERTY_AUTO(QColor,Grey180);
Q_PROPERTY_AUTO(QColor, Grey190); Q_PROPERTY_AUTO(QColor,Grey190);
Q_PROPERTY_AUTO(QColor, Grey200); Q_PROPERTY_AUTO(QColor,Grey200);
Q_PROPERTY_AUTO(QColor, Grey210); Q_PROPERTY_AUTO(QColor,Grey210);
Q_PROPERTY_AUTO(QColor, Grey220); Q_PROPERTY_AUTO(QColor,Grey220);
Q_PROPERTY_AUTO_P(FluAccentColor*, Yellow); Q_PROPERTY_AUTO(FluAccentColor*,Yellow);
Q_PROPERTY_AUTO_P(FluAccentColor*, Orange); Q_PROPERTY_AUTO(FluAccentColor*,Orange);
Q_PROPERTY_AUTO_P(FluAccentColor*, Red); Q_PROPERTY_AUTO(FluAccentColor*,Red);
Q_PROPERTY_AUTO_P(FluAccentColor*, Magenta); Q_PROPERTY_AUTO(FluAccentColor*,Magenta);
Q_PROPERTY_AUTO_P(FluAccentColor*, Purple); Q_PROPERTY_AUTO(FluAccentColor*,Purple);
Q_PROPERTY_AUTO_P(FluAccentColor*, Blue); Q_PROPERTY_AUTO(FluAccentColor*,Blue);
Q_PROPERTY_AUTO_P(FluAccentColor*, Teal); Q_PROPERTY_AUTO(FluAccentColor*,Teal);
Q_PROPERTY_AUTO_P(FluAccentColor*, Green); Q_PROPERTY_AUTO(FluAccentColor*,Green);
QML_NAMED_ELEMENT(FluColors) QML_NAMED_ELEMENT(FluColors)
QML_SINGLETON QML_SINGLETON
private: private:
explicit FluColors(QObject *parent = nullptr); explicit FluColors(QObject *parent = nullptr);
public: public:
SINGLETON(FluColors) SINGLETON(FluColors)
Q_INVOKABLE FluAccentColor* createAccentColor(QColor primaryColor);
[[maybe_unused]] Q_INVOKABLE FluAccentColor *createAccentColor(const QColor &primaryColor); static FluColors *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return getInstance();}
static FluColors *create(QQmlEngine *, QJSEngine *) { return getInstance(); }
}; };
#endif // FLUCOLORS_H

View File

@ -4,152 +4,132 @@
#include <QGuiApplication> #include <QGuiApplication>
#include <QScreen> #include <QScreen>
#include <QDateTime> #include <QDateTime>
#include "FluTools.h"
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#pragma comment (lib, "user32.lib") #pragma comment (lib,"user32.lib")
#pragma comment (lib, "dwmapi.lib") #pragma comment (lib,"dwmapi.lib")
#include <windows.h> #include <windows.h>
#include <windowsx.h> #include <windowsx.h>
#include <dwmapi.h> #include <dwmapi.h>
static inline QByteArray qtNativeEventType()
{
static inline QByteArray qtNativeEventType() {
static const auto result = "windows_generic_MSG"; static const auto result = "windows_generic_MSG";
return result; return result;
} }
static inline bool isCompositionEnabled(){
static inline bool isCompositionEnabled() { typedef HRESULT (WINAPI* DwmIsCompositionEnabledPtr)(BOOL *pfEnabled);
typedef HRESULT (WINAPI *DwmIsCompositionEnabledPtr)(BOOL *pfEnabled);
HMODULE module = ::LoadLibraryW(L"dwmapi.dll"); HMODULE module = ::LoadLibraryW(L"dwmapi.dll");
if (module) { if (module)
{
BOOL composition_enabled = false; BOOL composition_enabled = false;
DwmIsCompositionEnabledPtr dwm_is_composition_enabled; DwmIsCompositionEnabledPtr dwm_is_composition_enabled;
dwm_is_composition_enabled = reinterpret_cast<DwmIsCompositionEnabledPtr>(::GetProcAddress(module, "DwmIsCompositionEnabled")); dwm_is_composition_enabled= reinterpret_cast<DwmIsCompositionEnabledPtr>(::GetProcAddress(module, "DwmIsCompositionEnabled"));
if (dwm_is_composition_enabled) { if (dwm_is_composition_enabled)
{
dwm_is_composition_enabled(&composition_enabled); dwm_is_composition_enabled(&composition_enabled);
} }
return composition_enabled; return composition_enabled;
} }
return false; return false;
} }
#endif #endif
bool containsCursorToItem(QQuickItem *item) { FluFrameless::FluFrameless(QQuickItem *parent)
if (!item || !item->isVisible()) { : QQuickItem{parent}
return false; {
} appbar(nullptr);
auto point = QCursor::pos(); maximizeButton(nullptr);
auto rect = QRectF(item->mapToGlobal(QPoint(0, 0)), item->size()); minimizedButton(nullptr);
if (point.x() > rect.x() && point.x() < (rect.x() + rect.width()) && point.y() > rect.y() && point.y() < (rect.y() + rect.height())) { closeButton(nullptr);
return true; topmost(false);
} disabled(false);
return false;
} }
FluFrameless::FluFrameless(QQuickItem *parent) : QQuickItem{parent} { FluFrameless::~FluFrameless(){
_fixSize = false;
_appbar = nullptr;
_maximizeButton = nullptr;
_minimizedButton = nullptr;
_closeButton = nullptr;
_topmost = false;
_disabled = false;
_isWindows11OrGreater = FluTools::getInstance()->isWindows11OrGreater();
} }
FluFrameless::~FluFrameless() = default; void FluFrameless::onDestruction(){
qApp->removeNativeEventFilter(this);
[[maybe_unused]] void FluFrameless::onDestruction() {
QGuiApplication::instance()->removeNativeEventFilter(this);
} }
void FluFrameless::componentComplete() { void FluFrameless::componentComplete(){
if (_disabled) { if(_disabled){
return; return;
} }
int w = window()->width();
int h = window()->height();
_current = window()->winId(); _current = window()->winId();
window()->setFlags((window()->flags()) | Qt::CustomizeWindowHint | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint | Qt::FramelessWindowHint); window()->setFlags(( window()->flags()) | Qt::CustomizeWindowHint | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint | Qt::FramelessWindowHint);
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
if (QQuickWindow::sceneGraphBackend() == "software") { if(QQuickWindow::sceneGraphBackend() == "software"){
window()->setFlag(Qt::FramelessWindowHint, false); window()->setFlag(Qt::FramelessWindowHint,false);
} }
#endif #endif
if (!_fixSize) { if(!_fixSize){
window()->setFlag(Qt::WindowMaximizeButtonHint); window()->setFlag(Qt::WindowMaximizeButtonHint);
} }
window()->installEventFilter(this); window()->installEventFilter(this);
QGuiApplication::instance()->installNativeEventFilter(this); qApp->installNativeEventFilter(this);
if (_maximizeButton) { if(_maximizeButton){
setHitTestVisible(_maximizeButton); setHitTestVisible(_maximizeButton);
} }
if (_minimizedButton) { if(_minimizedButton){
setHitTestVisible(_minimizedButton); setHitTestVisible(_minimizedButton);
} }
if (_closeButton) { if(_closeButton){
setHitTestVisible(_closeButton); setHitTestVisible(_closeButton);
} }
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
HWND hwnd = reinterpret_cast<HWND>(window()->winId()); HWND hwnd = reinterpret_cast<HWND>(window()->winId());
DWORD style = ::GetWindowLongPtr(hwnd, GWL_STYLE); DWORD style = ::GetWindowLongPtr(hwnd, GWL_STYLE);
if (_fixSize) { if(_fixSize){
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_THICKFRAME); ::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_THICKFRAME);
for (int i = 0; i <= QGuiApplication::screens().count() - 1; ++i) { for (int i = 0; i < qApp->screens().count(); ++i) {
connect(QGuiApplication::screens().at(i), &QScreen::logicalDotsPerInchChanged, this, [=] { connect( qApp->screens().at(i),&QScreen::logicalDotsPerInchChanged,this,[=]{
SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_FRAMECHANGED); SetWindowPos(hwnd,nullptr,0,0,0,0,SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_FRAMECHANGED);
}); });
} }
} else { }else{
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_MAXIMIZEBOX | WS_THICKFRAME); ::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_MAXIMIZEBOX | WS_THICKFRAME);
} }
SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); SetWindowPos(hwnd,nullptr,0,0,0,0,SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
connect(window(), &QQuickWindow::screenChanged, this, [hwnd] { connect(window(),&QQuickWindow::screenChanged,this,[hwnd]{
::SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOOWNERZORDER); ::SetWindowPos(hwnd,0,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOOWNERZORDER);
::RedrawWindow(hwnd, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW); ::RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
}); });
#endif #endif
h = qRound(h + _appbar->height()); connect(this,&FluFrameless::topmostChanged,this,[this]{
if (_fixSize) {
window()->setMaximumSize(QSize(w, h));
window()->setMinimumSize(QSize(w, h));
}
window()->resize(QSize(w, h));
connect(this, &FluFrameless::topmostChanged, this, [this] {
_setWindowTopmost(topmost()); _setWindowTopmost(topmost());
}); });
_setWindowTopmost(topmost()); _setWindowTopmost(topmost());
} }
[[maybe_unused]] bool FluFrameless::nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result) { bool FluFrameless::nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result){
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
if ((eventType != qtNativeEventType()) || !message) { if ((eventType != qtNativeEventType()) || !message) {
return false; return false;
} }
const auto msg = static_cast<const MSG *>(message); const auto msg = static_cast<const MSG *>(message);
auto hwnd = msg->hwnd; const HWND hwnd = msg->hwnd;
if (!hwnd) { if (!hwnd || !msg) {
return false; return false;
} }
const quint64 wid = reinterpret_cast<qint64>(hwnd); const qint64 wid = reinterpret_cast<qint64>(hwnd);
if (wid != _current) { if(wid != _current){
return false; return false;
} }
const auto uMsg = msg->message; const UINT uMsg = msg->message;
const auto wParam = msg->wParam; const WPARAM wParam = msg->wParam;
const auto lParam = msg->lParam; const LPARAM lParam = msg->lParam;
if (uMsg == WM_WINDOWPOSCHANGING) { static QPoint offsetXY;
auto *wp = reinterpret_cast<WINDOWPOS *>(lParam); if(uMsg == WM_WINDOWPOSCHANGING){
if (wp != nullptr && (wp->flags & SWP_NOSIZE) == 0) { WINDOWPOS* wp = reinterpret_cast<WINDOWPOS*>(lParam);
if (wp != nullptr && (wp->flags & SWP_NOSIZE) == 0)
{
wp->flags |= SWP_NOCOPYBITS; wp->flags |= SWP_NOCOPYBITS;
*result = static_cast<QT_NATIVE_EVENT_RESULT_TYPE>(::DefWindowProcW(hwnd, uMsg, wParam, lParam)); *result = ::DefWindowProcW(hwnd, uMsg, wParam, lParam);
return true; return true;
} }
return false; return false;
} else if (uMsg == WM_NCCALCSIZE) { }else if(uMsg == WM_NCCALCSIZE){
const auto clientRect = ((wParam == FALSE) ? reinterpret_cast<LPRECT>(lParam) : &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(lParam))->rgrc[0]); const auto clientRect = ((wParam == FALSE) ? reinterpret_cast<LPRECT>(lParam) : &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(lParam))->rgrc[0]);
const LONG originalTop = clientRect->top; const LONG originalTop = clientRect->top;
const LONG originalLeft = clientRect->left; const LONG originalLeft = clientRect->left;
@ -157,29 +137,31 @@ void FluFrameless::componentComplete() {
const LONG originalBottom = clientRect->bottom; const LONG originalBottom = clientRect->bottom;
const LRESULT hitTestResult = ::DefWindowProcW(hwnd, WM_NCCALCSIZE, wParam, lParam); const LRESULT hitTestResult = ::DefWindowProcW(hwnd, WM_NCCALCSIZE, wParam, lParam);
if ((hitTestResult != HTERROR) && (hitTestResult != HTNOWHERE)) { if ((hitTestResult != HTERROR) && (hitTestResult != HTNOWHERE)) {
*result = static_cast<QT_NATIVE_EVENT_RESULT_TYPE>(hitTestResult); *result = hitTestResult;
return true; return true;
} }
int offsetSize; int offsetSize = 0;
bool isMaximum = ::IsZoomed(hwnd); bool isMaximum = ::IsZoomed(hwnd);
if (isMaximum || _isFullScreen()) { offsetXY = QPoint(abs(clientRect->left - originalLeft),abs(clientRect->top - originalTop));
if(isMaximum || _isFullScreen()){
offsetSize = 0; offsetSize = 0;
} else { }else{
offsetSize = 1; offsetSize = 1;
} }
if (!isCompositionEnabled()) { if(!isCompositionEnabled()){
offsetSize = 0; offsetSize = 0;
} }
if (!isMaximum || QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) {
clientRect->top = originalTop + offsetSize; clientRect->top = originalTop + offsetSize;
clientRect->bottom = originalBottom - offsetSize; clientRect->bottom = originalBottom - offsetSize;
clientRect->left = originalLeft + offsetSize; clientRect->left = originalLeft + offsetSize;
clientRect->right = originalRight - offsetSize; clientRect->right = originalRight - offsetSize;
}
_setMaximizeHovered(false); _setMaximizeHovered(false);
*result = WVR_REDRAW; *result = WVR_REDRAW;
return true; return true;
} else if (uMsg == WM_NCHITTEST) { }else if(uMsg == WM_NCHITTEST){
if (_isWindows11OrGreater) { if(_hitMaximizeButton()){
if (_hitMaximizeButton()) {
if (*result == HTNOWHERE) { if (*result == HTNOWHERE) {
*result = HTZOOM; *result = HTZOOM;
} }
@ -188,15 +170,14 @@ void FluFrameless::componentComplete() {
} }
_setMaximizeHovered(false); _setMaximizeHovered(false);
_setMaximizePressed(false); _setMaximizePressed(false);
}
*result = 0; *result = 0;
POINT nativeGlobalPos{GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)}; POINT nativeGlobalPos{GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
POINT nativeLocalPos = nativeGlobalPos; POINT nativeLocalPos = nativeGlobalPos;
::ScreenToClient(hwnd, &nativeLocalPos); ::ScreenToClient(hwnd, &nativeLocalPos);
RECT clientRect{0, 0, 0, 0}; RECT clientRect{0, 0, 0, 0};
::GetClientRect(hwnd, &clientRect); ::GetClientRect(hwnd, &clientRect);
auto clientWidth = clientRect.right - clientRect.left; auto clientWidth = clientRect.right-clientRect.left;
auto clientHeight = clientRect.bottom - clientRect.top; auto clientHeight = clientRect.bottom-clientRect.top;
bool left = nativeLocalPos.x < _margins; bool left = nativeLocalPos.x < _margins;
bool right = nativeLocalPos.x > clientWidth - _margins; bool right = nativeLocalPos.x > clientWidth - _margins;
bool top = nativeLocalPos.y < _margins; bool top = nativeLocalPos.y < _margins;
@ -224,139 +205,146 @@ void FluFrameless::componentComplete() {
if (0 != *result) { if (0 != *result) {
return true; return true;
} }
if (_hitAppBar()) { if(_hitAppBar()){
*result = HTCAPTION; *result = HTCAPTION;
return true; return true;
} }
*result = HTCLIENT; *result = HTCLIENT;
return true; return true;
} else if (_isWindows11OrGreater && (uMsg == WM_NCLBUTTONDBLCLK || uMsg == WM_NCLBUTTONDOWN)) { }else if(uMsg == WM_NCLBUTTONDBLCLK || uMsg == WM_NCLBUTTONDOWN){
if (_hitMaximizeButton()) { if(_hitMaximizeButton()){
QMouseEvent event = QMouseEvent(QEvent::MouseButtonPress, QPoint(), QPoint(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); QMouseEvent event = QMouseEvent(QEvent::MouseButtonPress, QPoint(), QPoint(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QGuiApplication::sendEvent(_maximizeButton, &event); QGuiApplication::sendEvent(_maximizeButton,&event);
_setMaximizePressed(true); _setMaximizePressed(true);
return true; return true;
} }
} else if (_isWindows11OrGreater && (uMsg == WM_NCLBUTTONUP || uMsg == WM_NCRBUTTONUP)) { }else if(uMsg == WM_NCLBUTTONUP || uMsg == WM_NCRBUTTONUP){
if (_hitMaximizeButton()) { if(_hitMaximizeButton()){
QMouseEvent event = QMouseEvent(QEvent::MouseButtonRelease, QPoint(), QPoint(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); QMouseEvent event = QMouseEvent(QEvent::MouseButtonRelease, QPoint(), QPoint(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QGuiApplication::sendEvent(_maximizeButton, &event); QGuiApplication::sendEvent(_maximizeButton,&event);
_setMaximizePressed(false); _setMaximizePressed(false);
return true; return true;
} }
} else if (uMsg == WM_NCPAINT) { }else if(uMsg == WM_NCPAINT){
*result = FALSE; *result = FALSE;
return true; return true;
} else if (uMsg == WM_NCACTIVATE) { }else if(uMsg == WM_NCACTIVATE){
*result = static_cast<QT_NATIVE_EVENT_RESULT_TYPE>(::DefWindowProcW(hwnd, WM_NCACTIVATE, wParam, -1)); *result = ::DefWindowProcW(hwnd, WM_NCACTIVATE, wParam, -1);
return true; return true;
} else if (uMsg == WM_GETMINMAXINFO) { }else if(uMsg == WM_GETMINMAXINFO){
auto *minmaxInfo = reinterpret_cast<MINMAXINFO *>(lParam); MINMAXINFO* minmaxInfo = reinterpret_cast<MINMAXINFO *>(lParam);
auto pixelRatio = window()->devicePixelRatio(); auto pixelRatio = window()->devicePixelRatio();
auto geometry = window()->screen()->availableGeometry(); auto geometry = window()->screen()->availableGeometry();
RECT rect; RECT rect;
SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0); SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0);
minmaxInfo->ptMaxPosition.x = rect.left; minmaxInfo->ptMaxPosition.x = rect.left - offsetXY.x();
minmaxInfo->ptMaxPosition.y = rect.top; minmaxInfo->ptMaxPosition.y = rect.top - offsetXY.x();
minmaxInfo->ptMaxSize.x = qRound(geometry.width() * pixelRatio); minmaxInfo->ptMaxSize.x = geometry.width()*pixelRatio + offsetXY.x() * 2;
minmaxInfo->ptMaxSize.y = qRound(geometry.height() * pixelRatio); minmaxInfo->ptMaxSize.y = geometry.height()*pixelRatio + offsetXY.y() * 2;
return false; return false;
} else if (uMsg == WM_NCRBUTTONDOWN) { }else if(uMsg == WM_NCRBUTTONDOWN){
if (wParam == HTCAPTION) { if (wParam == HTCAPTION) {
_showSystemMenu(QCursor::pos()); _showSystemMenu(QCursor::pos());
} }
} else if (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN) { }else if(uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN){
const bool altPressed = ((wParam == VK_MENU) || (::GetKeyState(VK_MENU) < 0)); const bool altPressed = ((wParam == VK_MENU) || (::GetKeyState(VK_MENU) < 0));
const bool spacePressed = ((wParam == VK_SPACE) || (::GetKeyState(VK_SPACE) < 0)); const bool spacePressed = ((wParam == VK_SPACE) || (::GetKeyState(VK_SPACE) < 0));
if (altPressed && spacePressed) { if (altPressed && spacePressed) {
auto pos = window()->position(); auto pos = window()->position();
_showSystemMenu(QPoint(pos.x(), qRound(pos.y() + _appbar->height()))); _showSystemMenu(QPoint(pos.x(),pos.y()+_appbar->height()));
} }
} else if (uMsg == WM_SYSCOMMAND) { }else if(uMsg == WM_SYSCOMMAND){
if (wParam == SC_MINIMIZE) { if(wParam == SC_MINIMIZE){
if (window()->transientParent()) { if(window()->transientParent()){
auto _hwnd = reinterpret_cast<HWND>(window()->transientParent()->winId()); window()->transientParent()->showMinimized();
::ShowWindow(_hwnd, 2); }else{
} else { window()->showMinimized();
auto _hwnd = reinterpret_cast<HWND>(window()->winId());
::ShowWindow(_hwnd, 2);
} }
return true; return true;
} }
return false; return false;
} }
return false; return false;
#else
return false;
#endif #endif
return false;
} }
bool FluFrameless::_isMaximized() { bool FluFrameless::_isMaximized(){
return window()->visibility() == QWindow::Maximized; return window()->visibility() == QWindow::Maximized;
} }
bool FluFrameless::_isFullScreen() { bool FluFrameless::_isFullScreen(){
return window()->visibility() == QWindow::FullScreen; return window()->visibility() == QWindow::FullScreen;
} }
void FluFrameless::_showSystemMenu(QPoint point) { void FluFrameless::_showSystemMenu(QPoint point){
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
HWND hwnd = reinterpret_cast<HWND>(window()->winId()); HWND hwnd = reinterpret_cast<HWND>(window()->winId());
DWORD style = ::GetWindowLongPtr(hwnd, GWL_STYLE); DWORD style = ::GetWindowLongPtr(hwnd,GWL_STYLE);
::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_SYSMENU); ::SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_SYSMENU);
auto hMenu = ::GetSystemMenu(hwnd, FALSE); const HMENU hMenu = ::GetSystemMenu(hwnd, FALSE);
if (_isMaximized() || _isFullScreen()) { if(_isMaximized() || _isFullScreen()){
::EnableMenuItem(hMenu, SC_MOVE, MFS_DISABLED); ::EnableMenuItem(hMenu,SC_MOVE,MFS_DISABLED);
::EnableMenuItem(hMenu, SC_RESTORE, MFS_ENABLED); ::EnableMenuItem(hMenu,SC_RESTORE,MFS_ENABLED);
} else { }else{
::EnableMenuItem(hMenu, SC_MOVE, MFS_ENABLED); ::EnableMenuItem(hMenu,SC_MOVE,MFS_ENABLED);
::EnableMenuItem(hMenu, SC_RESTORE, MFS_DISABLED); ::EnableMenuItem(hMenu,SC_RESTORE,MFS_DISABLED);
} }
if (!_fixSize && !_isMaximized() && !_isFullScreen()) { if(!_fixSize && !_isMaximized() && !_isFullScreen()){
::EnableMenuItem(hMenu, SC_SIZE, MFS_ENABLED); ::EnableMenuItem(hMenu,SC_SIZE,MFS_ENABLED);
::EnableMenuItem(hMenu, SC_MAXIMIZE, MFS_ENABLED); ::EnableMenuItem(hMenu,SC_MAXIMIZE,MFS_ENABLED);
} else { }else{
::EnableMenuItem(hMenu, SC_SIZE, MFS_DISABLED); ::EnableMenuItem(hMenu,SC_SIZE,MFS_DISABLED);
::EnableMenuItem(hMenu, SC_MAXIMIZE, MFS_DISABLED); ::EnableMenuItem(hMenu,SC_MAXIMIZE,MFS_DISABLED);
} }
const int result = ::TrackPopupMenu(hMenu, (TPM_RETURNCMD | (QGuiApplication::isRightToLeft() ? TPM_RIGHTALIGN : TPM_LEFTALIGN)), qRound(point.x() * window()->devicePixelRatio()), const int result = ::TrackPopupMenu(hMenu, (TPM_RETURNCMD | (QGuiApplication::isRightToLeft() ? TPM_RIGHTALIGN : TPM_LEFTALIGN)), point.x()*window()->devicePixelRatio(), point.y()*window()->devicePixelRatio(), 0, hwnd, nullptr);
qRound(point.y() * window()->devicePixelRatio()), 0, hwnd, nullptr);
if (result != FALSE) { if (result != FALSE) {
::PostMessageW(hwnd, WM_SYSCOMMAND, result, 0); ::PostMessageW(hwnd, WM_SYSCOMMAND, result, 0);
} }
::SetWindowLongPtr(hwnd, GWL_STYLE, style & ~WS_SYSMENU); ::SetWindowLongPtr(hwnd, GWL_STYLE, style &~ WS_SYSMENU);
#endif #endif
} }
bool FluFrameless::_hitAppBar() { bool FluFrameless::_containsCursorToItem(QQuickItem* item){
for (int i = 0; i <= _hitTestList.size() - 1; ++i) { if(!item || !item->isVisible()){
auto item = _hitTestList.at(i);
if (containsCursorToItem(item)) {
return false; return false;
} }
} auto point = QCursor::pos();
if (containsCursorToItem(_appbar)) { auto rect = QRectF(item->mapToGlobal(QPoint(0,0)),item->size());
if(point.x()>rect.x() && point.x()<(rect.x()+rect.width()) && point.y()>rect.y() && point.y()<(rect.y()+rect.height())){
return true; return true;
} }
return false; return false;
} }
bool FluFrameless::_hitMaximizeButton() { bool FluFrameless::_hitAppBar(){
if (containsCursorToItem(_maximizeButton)) { foreach (auto item, _hitTestList) {
if(_containsCursorToItem(item)){
return false;
}
}
if(_containsCursorToItem(_appbar)){
return true; return true;
} }
return false; return false;
} }
void FluFrameless::_setMaximizePressed(bool val) { bool FluFrameless::_hitMaximizeButton(){
_maximizeButton->setProperty("down", val); if(_containsCursorToItem(_maximizeButton)){
return true;
}
return false;
} }
void FluFrameless::_setMaximizeHovered(bool val) { void FluFrameless::_setMaximizePressed(bool val){
_maximizeButton->setProperty("hover", val); _maximizeButton->setProperty("down",val);
} }
void FluFrameless::_updateCursor(int edges) { void FluFrameless::_setMaximizeHovered(bool val){
_maximizeButton->setProperty("hover",val);
}
void FluFrameless::_updateCursor(int edges){
switch (edges) { switch (edges) {
case 0: case 0:
window()->setCursor(Qt::ArrowCursor); window()->setCursor(Qt::ArrowCursor);
@ -377,49 +365,43 @@ void FluFrameless::_updateCursor(int edges) {
case Qt::LeftEdge | Qt::BottomEdge: case Qt::LeftEdge | Qt::BottomEdge:
window()->setCursor(Qt::SizeBDiagCursor); window()->setCursor(Qt::SizeBDiagCursor);
break; break;
default:
break;
} }
} }
[[maybe_unused]] void FluFrameless::showFullScreen() { void FluFrameless::showFullScreen(){
window()->showFullScreen(); window()->showFullScreen();
} }
void FluFrameless::showMaximized() { void FluFrameless::showMaximized(){
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
HWND hwnd = reinterpret_cast<HWND>(window()->winId()); HWND hwnd = reinterpret_cast<HWND>(window()->winId());
::ShowWindow(hwnd, 3); ::ShowWindow(hwnd,3);
#else #else
window()->setVisibility(QQuickWindow::Maximized); window()->showMaximized();
#endif #endif
} }
[[maybe_unused]] void FluFrameless::showMinimized() { void FluFrameless::showMinimized(){
#ifdef Q_OS_WIN window()->showMinimized();
HWND hwnd = reinterpret_cast<HWND>(window()->winId());
::ShowWindow(hwnd, 2);
#else
window()->setVisibility(QQuickWindow::Minimized);
#endif
} }
void FluFrameless::showNormal() { void FluFrameless::showNormal(){
window()->setVisibility(QQuickWindow::Windowed); window()->showNormal();
} }
void FluFrameless::setHitTestVisible(QQuickItem *val) { void FluFrameless::setHitTestVisible(QQuickItem* val){
if (!_hitTestList.contains(val)) { if(!_hitTestList.contains(val)){
_hitTestList.append(val); _hitTestList.append(val);
} }
} }
void FluFrameless::_setWindowTopmost(bool topmost) {
void FluFrameless::_setWindowTopmost(bool topmost){
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
HWND hwnd = reinterpret_cast<HWND>(window()->winId()); HWND hwnd = reinterpret_cast<HWND>(window()->winId());
if (topmost) { if(topmost){
::SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); ::SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
} else { }else{
::SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); ::SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
} }
#else #else
@ -427,7 +409,7 @@ void FluFrameless::_setWindowTopmost(bool topmost) {
#endif #endif
} }
bool FluFrameless::eventFilter(QObject *obj, QEvent *ev) { bool FluFrameless::eventFilter(QObject *obj, QEvent *ev){
#ifndef Q_OS_WIN #ifndef Q_OS_WIN
switch (ev->type()) { switch (ev->type()) {
case QEvent::MouseButtonPress: case QEvent::MouseButtonPress:

View File

@ -1,9 +1,9 @@
#pragma once #ifndef FLUFRAMELESS_H
#define FLUFRAMELESS_H
#include <QObject> #include <QObject>
#include <QQuickItem> #include <QQuickItem>
#include <QAbstractNativeEventFilter> #include <QAbstractNativeEventFilter>
#include <QQmlProperty>
#include "stdafx.h" #include "stdafx.h"
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
@ -15,64 +15,47 @@ using QT_ENTER_EVENT_TYPE = QEvent;
#endif #endif
class FluFrameless : public QQuickItem, QAbstractNativeEventFilter { class FluFrameless : public QQuickItem,QAbstractNativeEventFilter
Q_OBJECT {
Q_PROPERTY_AUTO_P(QQuickItem*, appbar) Q_OBJECT
Q_PROPERTY_AUTO_P(QQuickItem*, maximizeButton) Q_PROPERTY_AUTO(QQuickItem*,appbar)
Q_PROPERTY_AUTO_P(QQuickItem*, minimizedButton) Q_PROPERTY_AUTO(bool,topmost)
Q_PROPERTY_AUTO_P(QQuickItem*, closeButton) Q_PROPERTY_AUTO(QQuickItem*,maximizeButton)
Q_PROPERTY_AUTO(bool, topmost) Q_PROPERTY_AUTO(QQuickItem*,minimizedButton)
Q_PROPERTY_AUTO(bool, disabled) Q_PROPERTY_AUTO(QQuickItem*,closeButton)
Q_PROPERTY_AUTO(bool, fixSize) Q_PROPERTY_AUTO(bool,disabled)
Q_PROPERTY_AUTO(bool,fixSize)
QML_NAMED_ELEMENT(FluFrameless) QML_NAMED_ELEMENT(FluFrameless)
public: public:
explicit FluFrameless(QQuickItem *parent = nullptr); explicit FluFrameless(QQuickItem* parent = nullptr);
~FluFrameless();
~FluFrameless() override;
void componentComplete() override; void componentComplete() override;
bool nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result) override;
[[maybe_unused]] bool nativeEventFilter(const QByteArray &eventType, void *message, QT_NATIVE_EVENT_RESULT_TYPE *result) override; Q_INVOKABLE void showFullScreen();
[[maybe_unused]] Q_INVOKABLE void showFullScreen();
Q_INVOKABLE void showMaximized(); Q_INVOKABLE void showMaximized();
Q_INVOKABLE void showMinimized();
[[maybe_unused]] Q_INVOKABLE void showMinimized();
Q_INVOKABLE void showNormal(); Q_INVOKABLE void showNormal();
Q_INVOKABLE void setHitTestVisible(QQuickItem*);
Q_INVOKABLE void setHitTestVisible(QQuickItem *); Q_INVOKABLE void onDestruction();
[[maybe_unused]] Q_INVOKABLE void onDestruction();
protected: protected:
bool eventFilter(QObject *obj, QEvent *event) override; bool eventFilter(QObject *obj, QEvent *event) override;
private: private:
bool _isFullScreen(); bool _isFullScreen();
bool _isMaximized(); bool _isMaximized();
void _updateCursor(int edges); void _updateCursor(int edges);
void _setWindowTopmost(bool topmost); void _setWindowTopmost(bool topmost);
void _showSystemMenu(QPoint point); void _showSystemMenu(QPoint point);
bool _containsCursorToItem(QQuickItem* item);
bool _hitAppBar(); bool _hitAppBar();
bool _hitMaximizeButton(); bool _hitMaximizeButton();
void _setMaximizePressed(bool val); void _setMaximizePressed(bool val);
void _setMaximizeHovered(bool val); void _setMaximizeHovered(bool val);
private: private:
quint64 _current = 0; qint64 _current;
int _edges = 0; int _edges = 0;
int _margins = 8; int _margins = 8;
quint64 _clickTimer = 0; qint64 _clickTimer = 0;
bool _isWindows11OrGreater = false;
QList<QPointer<QQuickItem>> _hitTestList; QList<QPointer<QQuickItem>> _hitTestList;
}; };
#endif // FLUFRAMELESS_H

View File

@ -2,47 +2,51 @@
#include "qrcode/qrencode.h" #include "qrcode/qrencode.h"
FluQrCodeItem::FluQrCodeItem(QQuickItem *parent) : QQuickPaintedItem(parent) { FluQrCodeItem::FluQrCodeItem(QQuickItem* parent):QQuickPaintedItem(parent){
_color = QColor(0, 0, 0, 255); color(QColor(0,0,0,255));
_bgColor = QColor(255, 255, 255, 255); bgColor(QColor(255,255,255,255));
_size = 100; size(100);
setWidth(_size); setWidth(_size);
setHeight(_size); setHeight(_size);
connect(this, &FluQrCodeItem::textChanged, this, [=] { update(); }); connect(this,&FluQrCodeItem::textChanged,this,[=]{update();});
connect(this, &FluQrCodeItem::colorChanged, this, [=] { update(); }); connect(this,&FluQrCodeItem::colorChanged,this,[=]{update();});
connect(this, &FluQrCodeItem::bgColorChanged, this, [=] { update(); }); connect(this,&FluQrCodeItem::bgColorChanged,this,[=]{update();});
connect(this, &FluQrCodeItem::sizeChanged, this, [=] { connect(this,&FluQrCodeItem::sizeChanged,this,[=]{
setWidth(_size); setWidth(_size);
setHeight(_size); setHeight(_size);
update(); update();
}); });
} }
void FluQrCodeItem::paint(QPainter *painter) {
if (_text.isEmpty()) { void FluQrCodeItem::paint(QPainter* painter){
if(_text.isEmpty()){
return; return;
} }
if (_text.length() > 1024) { if(_text.length()>1024){
return; return;
} }
painter->save(); painter->save();
QRcode *qrcode = QRcode_encodeString(_text.toUtf8().constData(), 2, QR_ECLEVEL_Q, QR_MODE_8, 1); QRcode *qrcode = QRcode_encodeString(_text.toUtf8().constData(), 2, QR_ECLEVEL_Q, QR_MODE_8, 1);
auto w = qint32(width()); qint32 w = width();
auto h = qint32(height()); qint32 h = height();
qint32 qrcodeW = qrcode->width > 0 ? qrcode->width : 1; qint32 qrcodeW = qrcode->width > 0 ? qrcode->width : 1;
double scaleX = (double) w / (double) qrcodeW; double scaleX = (double)w / (double)qrcodeW;
double scaleY = (double) h / (double) qrcodeW; double scaleY = (double)h / (double)qrcodeW;
QImage image = QImage(w, h, QImage::Format_ARGB32); QImage image = QImage(w, h, QImage::Format_ARGB32);
QPainter p(&image); QPainter p(&image);
p.setBrush(_bgColor); p.setBrush(_bgColor);
p.setPen(Qt::NoPen); p.setPen(Qt::NoPen);
p.drawRect(0, 0, w, h); p.drawRect(0, 0, w, h);
p.setBrush(_color); p.setBrush(_color);
for (qint32 y = 0; y < qrcodeW; y++) { for (qint32 y = 0; y < qrcodeW; y++)
for (qint32 x = 0; x < qrcodeW; x++) { {
unsigned char b = qrcode->data[y * qrcodeW + x]; for (qint32 x = 0; x < qrcodeW; x++)
if (b & 0x01) { {
QRectF r(x * scaleX, y * scaleY, scaleX, scaleY); unsigned char b = qrcode->data[y*qrcodeW + x];
if (b & 0x01)
{
QRectF r(x * scaleX,y * scaleY, scaleX, scaleY);
p.drawRects(&r, 1); p.drawRects(&r, 1);
} }
} }

View File

@ -1,4 +1,5 @@
#pragma once #ifndef FLUQRCODEITEM_H
#define FLUQRCODEITEM_H
#include <QQuickItem> #include <QQuickItem>
#include <QQuickPaintedItem> #include <QQuickPaintedItem>
@ -8,16 +9,17 @@
/** /**
* @brief The FluQrCodeItem class * @brief The FluQrCodeItem class
*/ */
class FluQrCodeItem : public QQuickPaintedItem { class FluQrCodeItem : public QQuickPaintedItem
Q_OBJECT {
Q_OBJECT
Q_PROPERTY_AUTO(QString, text) Q_PROPERTY_AUTO(QString,text)
Q_PROPERTY_AUTO(QColor, color) Q_PROPERTY_AUTO(QColor,color)
Q_PROPERTY_AUTO(QColor, bgColor) Q_PROPERTY_AUTO(QColor,bgColor)
Q_PROPERTY_AUTO(int, size); Q_PROPERTY_AUTO(int,size);
QML_NAMED_ELEMENT(FluQrCodeItem) QML_NAMED_ELEMENT(FluQrCodeItem)
public: public:
explicit FluQrCodeItem(QQuickItem *parent = nullptr); explicit FluQrCodeItem(QQuickItem *parent = nullptr);
void paint(QPainter* painter) override;
void paint(QPainter *painter) override;
}; };
#endif // FLUQRCODEITEM_H

View File

@ -1,14 +1,14 @@
#include "FluRectangle.h" #include "FluRectangle.h"
#include <QPainterPath> #include <QPainterPath>
FluRectangle::FluRectangle(QQuickItem *parent) : QQuickPaintedItem(parent) { FluRectangle::FluRectangle(QQuickItem* parent) : QQuickPaintedItem(parent){
color(QColor(255, 255, 255, 255)); color(QColor(255,255,255,255));
radius({0, 0, 0, 0}); radius({0,0,0,0});
connect(this, &FluRectangle::colorChanged, this, [=] { update(); }); connect(this,&FluRectangle::colorChanged,this,[=]{update();});
connect(this, &FluRectangle::radiusChanged, this, [=] { update(); }); connect(this,&FluRectangle::radiusChanged,this,[=]{update();});
} }
void FluRectangle::paint(QPainter *painter) { void FluRectangle::paint(QPainter* painter){
painter->save(); painter->save();
painter->setRenderHint(QPainter::Antialiasing); painter->setRenderHint(QPainter::Antialiasing);
QPainterPath path; QPainterPath path;
@ -22,6 +22,6 @@ void FluRectangle::paint(QPainter *painter) {
path.arcTo(QRectF(QPointF(rect.bottomLeft() - QPointF(0, _radius[3] * 2)), QSize(_radius[3] * 2, _radius[3] * 2)), 180, 90); path.arcTo(QRectF(QPointF(rect.bottomLeft() - QPointF(0, _radius[3] * 2)), QSize(_radius[3] * 2, _radius[3] * 2)), 180, 90);
path.lineTo(rect.bottomRight() - QPointF(_radius[2], 0)); path.lineTo(rect.bottomRight() - QPointF(_radius[2], 0));
path.arcTo(QRectF(QPointF(rect.bottomRight() - QPointF(_radius[2] * 2, _radius[2] * 2)), QSize(_radius[2] * 2, _radius[2] * 2)), 270, 90); path.arcTo(QRectF(QPointF(rect.bottomRight() - QPointF(_radius[2] * 2, _radius[2] * 2)), QSize(_radius[2] * 2, _radius[2] * 2)), 270, 90);
painter->fillPath(path, _color); painter->fillPath(path,_color);
painter->restore(); painter->restore();
} }

View File

@ -1,4 +1,5 @@
#pragma once #ifndef FLURECTANGLE_H
#define FLURECTANGLE_H
#include <QQuickItem> #include <QQuickItem>
#include <QQuickPaintedItem> #include <QQuickPaintedItem>
@ -8,13 +9,15 @@
/** /**
* @brief The FluRectangle class * @brief The FluRectangle class
*/ */
class FluRectangle : public QQuickPaintedItem { class FluRectangle : public QQuickPaintedItem
Q_OBJECT {
Q_PROPERTY_AUTO(QColor, color) Q_OBJECT
Q_PROPERTY_AUTO(QList<int>, radius) Q_PROPERTY_AUTO(QColor,color)
Q_PROPERTY_AUTO(QList<int>,radius)
QML_NAMED_ELEMENT(FluRectangle) QML_NAMED_ELEMENT(FluRectangle)
public: public:
explicit FluRectangle(QQuickItem *parent = nullptr); explicit FluRectangle(QQuickItem *parent = nullptr);
void paint(QPainter* painter) override;
void paint(QPainter *painter) override;
}; };
#endif // FLURECTANGLE_H

View File

@ -2,72 +2,74 @@
#include <QJSValueList> #include <QJSValueList>
FluTableSortProxyModel::FluTableSortProxyModel(QSortFilterProxyModel *parent) : QSortFilterProxyModel{parent} { FluTableSortProxyModel::FluTableSortProxyModel(QSortFilterProxyModel *parent)
: QSortFilterProxyModel {parent}
{
_model = nullptr; _model = nullptr;
connect(this, &FluTableSortProxyModel::modelChanged, this, [=] { connect(this,&FluTableSortProxyModel::modelChanged,this,[=]{
setSourceModel(this->model()); setSourceModel(this->model());
}); });
} }
bool FluTableSortProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { bool FluTableSortProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const{
QJSValue filter = _filter; QJSValue filter = _filter;
if (filter.isUndefined()) { if(filter.isUndefined()){
return true; return true;
} }
QJSValueList data; QJSValueList data;
data << source_row; data<<source_row;
return filter.call(data).toBool(); return filter.call(data).toBool();
} }
bool FluTableSortProxyModel::filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const { bool FluTableSortProxyModel::filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const{
return true; return true;
} }
bool FluTableSortProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const { bool FluTableSortProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const{
QJSValue comparator = _comparator; QJSValue comparator = _comparator;
if (comparator.isUndefined()) { if(comparator.isUndefined()){
return true; return true;
} }
QJSValueList data; QJSValueList data;
data << source_left.row(); data<<source_left.row();
data << source_right.row(); data<<source_right.row();
bool flag = comparator.call(data).toBool(); bool flag = comparator.call(data).toBool();
if (sortOrder() == Qt::AscendingOrder) { if(sortOrder()==Qt::AscendingOrder){
return !flag; return !flag;
} else { }else{
return flag; return flag;
} }
} }
[[maybe_unused]] void FluTableSortProxyModel::setComparator(const QJSValue &comparator) { void FluTableSortProxyModel::setComparator(QJSValue comparator){
int column = 0; int column = 0;
if (comparator.isUndefined()) { if(comparator.isUndefined()){
column = -1; column = -1;
} }
this->_comparator = comparator; this->_comparator = comparator;
if (sortOrder() == Qt::AscendingOrder) { if(sortOrder()==Qt::AscendingOrder){
sort(column, Qt::DescendingOrder); sort(column,Qt::DescendingOrder);
} else { }else{
sort(column, Qt::AscendingOrder); sort(column,Qt::AscendingOrder);
} }
} }
[[maybe_unused]] void FluTableSortProxyModel::setFilter(const QJSValue &filter) { void FluTableSortProxyModel::setFilter(QJSValue filter){
this->_filter = filter; this->_filter = filter;
invalidateFilter(); invalidateFilter();
} }
[[maybe_unused]] QVariant FluTableSortProxyModel::getRow(int rowIndex) { QVariant FluTableSortProxyModel::getRow(int rowIndex){
QVariant result; QVariant result;
QMetaObject::invokeMethod(_model, "getRow", Q_RETURN_ARG(QVariant, result), Q_ARG(int, mapToSource(index(rowIndex, 0)).row())); QMetaObject::invokeMethod(_model, "getRow",Q_RETURN_ARG(QVariant, result),Q_ARG(int, mapToSource(index(rowIndex,0)).row()));
return result; return result;
} }
[[maybe_unused]] void FluTableSortProxyModel::setRow(int rowIndex, const QVariant &val) { void FluTableSortProxyModel::setRow(int rowIndex,QVariant val){
QMetaObject::invokeMethod(_model, "setRow", Q_ARG(int, mapToSource(index(rowIndex, 0)).row()), Q_ARG(QVariant, val)); QMetaObject::invokeMethod(_model, "setRow",Q_ARG(int, mapToSource(index(rowIndex,0)).row()),Q_ARG(QVariant,val));
} }
[[maybe_unused]] void FluTableSortProxyModel::removeRow(int rowIndex, int rows) { void FluTableSortProxyModel::removeRow(int rowIndex,int rows){
QMetaObject::invokeMethod(_model, "removeRow", Q_ARG(int, mapToSource(index(rowIndex, 0)).row()), Q_ARG(int, rows)); QMetaObject::invokeMethod(_model, "removeRow",Q_ARG(int, mapToSource(index(rowIndex,0)).row()),Q_ARG(int,rows));
} }

View File

@ -1,4 +1,5 @@
#pragma once #ifndef FLUTABLESORTPROXYMODEL_H
#define FLUTABLESORTPROXYMODEL_H
#include <QSortFilterProxyModel> #include <QSortFilterProxyModel>
#include <QAbstractTableModel> #include <QAbstractTableModel>
@ -6,30 +7,24 @@
#include <QJSValue> #include <QJSValue>
#include "stdafx.h" #include "stdafx.h"
class FluTableSortProxyModel : public QSortFilterProxyModel { class FluTableSortProxyModel : public QSortFilterProxyModel
Q_OBJECT {
Q_PROPERTY_AUTO_P(QAbstractTableModel*, model) Q_OBJECT
Q_PROPERTY_AUTO(QAbstractTableModel*,model)
QML_NAMED_ELEMENT(FluTableSortProxyModel) QML_NAMED_ELEMENT(FluTableSortProxyModel)
public: public:
explicit FluTableSortProxyModel(QSortFilterProxyModel *parent = nullptr); explicit FluTableSortProxyModel(QSortFilterProxyModel *parent = nullptr);
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
bool filterAcceptsColumn(int sourceColumn, const QModelIndex &sourceParent) const override; bool filterAcceptsColumn(int sourceColumn, const QModelIndex &sourceParent) const override;
bool lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const override; bool lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const override;
Q_INVOKABLE QVariant getRow(int rowIndex);
[[maybe_unused]] Q_INVOKABLE QVariant getRow(int rowIndex); Q_INVOKABLE void setRow(int rowIndex,QVariant val);
Q_INVOKABLE void removeRow(int rowIndex,int rows);
[[maybe_unused]] Q_INVOKABLE void setRow(int rowIndex, const QVariant &val); Q_INVOKABLE void setComparator(QJSValue comparator);
Q_INVOKABLE void setFilter(QJSValue filter);
[[maybe_unused]] Q_INVOKABLE void removeRow(int rowIndex, int rows);
[[maybe_unused]] Q_INVOKABLE void setComparator(const QJSValue &comparator);
[[maybe_unused]] Q_INVOKABLE void setFilter(const QJSValue &filter);
private: private:
QJSValue _filter; QJSValue _filter;
QJSValue _comparator; QJSValue _comparator;
}; };
#endif // FLUTABLESORTPROXYMODEL_H

View File

@ -1,6 +1,6 @@
#include "FluTextStyle.h" #include "FluTextStyle.h"
FluTextStyle::FluTextStyle(QObject *parent) : QObject{parent} { FluTextStyle::FluTextStyle(QObject *parent):QObject{parent}{
_family = QFont().defaultFamily(); _family = QFont().defaultFamily();
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
_family = "微软雅黑"; _family = "微软雅黑";

View File

@ -1,4 +1,5 @@
#pragma once #ifndef FLUTEXTSTYLE_H
#define FLUTEXTSTYLE_H
#include <QObject> #include <QObject>
#include <QtQml/qqml.h> #include <QtQml/qqml.h>
@ -9,25 +10,25 @@
/** /**
* @brief The FluTextStyle class * @brief The FluTextStyle class
*/ */
class FluTextStyle : public QObject { class FluTextStyle : public QObject
Q_OBJECT {
Q_OBJECT
public: public:
Q_PROPERTY_AUTO(QString, family) Q_PROPERTY_AUTO(QString,family)
Q_PROPERTY_AUTO(QFont, Caption); Q_PROPERTY_AUTO(QFont,Caption);
Q_PROPERTY_AUTO(QFont, Body); Q_PROPERTY_AUTO(QFont,Body);
Q_PROPERTY_AUTO(QFont, BodyStrong); Q_PROPERTY_AUTO(QFont,BodyStrong);
Q_PROPERTY_AUTO(QFont, Subtitle); Q_PROPERTY_AUTO(QFont,Subtitle);
Q_PROPERTY_AUTO(QFont, Title); Q_PROPERTY_AUTO(QFont,Title);
Q_PROPERTY_AUTO(QFont, TitleLarge); Q_PROPERTY_AUTO(QFont,TitleLarge);
Q_PROPERTY_AUTO(QFont, Display); Q_PROPERTY_AUTO(QFont,Display);
QML_NAMED_ELEMENT(FluTextStyle) QML_NAMED_ELEMENT(FluTextStyle)
QML_SINGLETON QML_SINGLETON
private: private:
explicit FluTextStyle(QObject *parent = nullptr); explicit FluTextStyle(QObject *parent = nullptr);
public: public:
SINGLETON(FluTextStyle) SINGLETON(FluTextStyle)
static FluTextStyle *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return getInstance();}
static FluTextStyle *create(QQmlEngine *, QJSEngine *) { return getInstance(); }
}; };
#endif // FLUTEXTSTYLE_H

View File

@ -2,60 +2,43 @@
#include <QGuiApplication> #include <QGuiApplication>
#include <QPalette> #include <QPalette>
#include <QImage>
#include <QThreadPool>
#include "Def.h" #include "Def.h"
#include "FluColors.h" #include "FluColors.h"
#include "FluTools.h"
bool systemDark() { FluTheme::FluTheme(QObject *parent):QObject{parent}{
QPalette palette = QGuiApplication::palette(); connect(this,&FluTheme::darkModeChanged,this,[=]{
QColor color = palette.color(QPalette::Window).rgb();
return color.red() * 0.2126 + color.green() * 0.7152 + color.blue() * 0.0722 <= 255.0f / 2;
}
FluTheme::FluTheme(QObject *parent) : QObject{parent} {
_accentColor = FluColors::getInstance()->Blue();
_darkMode = FluThemeType::DarkMode::Light;
_nativeText = false;
_animationEnabled = true;
_systemDark = systemDark();
_desktopImagePath = "";
_blurBehindWindowEnabled = false;
QGuiApplication::instance()->installEventFilter(this);
refreshColors();
connect(this, &FluTheme::darkModeChanged, this, [=] {
Q_EMIT darkChanged(); Q_EMIT darkChanged();
}); });
connect(this, &FluTheme::darkChanged, this, [=] { refreshColors(); }); connect(this,&FluTheme::darkChanged,this,[=]{refreshColors();});
connect(this, &FluTheme::accentColorChanged, this, [=] { refreshColors(); }); connect(this,&FluTheme::accentColorChanged,this,[=]{refreshColors();});
connect(&_watcher, &QFileSystemWatcher::fileChanged, this, [=](const QString &path) { accentColor(FluColors::getInstance()->Blue());
Q_EMIT desktopImagePathChanged(); darkMode(FluThemeType::DarkMode::Light);
}); nativeText(false);
connect(this, &FluTheme::blurBehindWindowEnabledChanged, this, [=] { checkUpdateDesktopImage(); }); animationEnabled(true);
startTimer(1000); _systemDark = systemDark();
qApp->installEventFilter(this);
} }
void FluTheme::refreshColors() { void FluTheme::refreshColors(){
auto isDark = dark(); auto isDark = dark();
primaryColor(isDark ? _accentColor->lighter() : _accentColor->dark()); primaryColor(isDark ? _accentColor->lighter() : _accentColor->dark());
backgroundColor(isDark ? QColor(0, 0, 0, 255) : QColor(255, 255, 255, 255)); backgroundColor(isDark ? QColor(0,0,0,255) : QColor(255,255,255,255));
dividerColor(isDark ? QColor(80, 80, 80, 255) : QColor(210, 210, 210, 255)); dividerColor(isDark ? QColor(80,80,80,255) : QColor(210,210,210,255));
windowBackgroundColor(isDark ? QColor(32, 32, 32, 255) : QColor(237, 237, 237, 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)); windowActiveBackgroundColor(isDark ? QColor(26,26,26,255) : QColor(243,243,243,255));
fontPrimaryColor(isDark ? QColor(248, 248, 248, 255) : QColor(7, 7, 7, 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)); fontSecondaryColor(isDark ? QColor(222,222,222,255) : QColor(102,102,102,255));
fontTertiaryColor(isDark ? QColor(200, 200, 200, 255) : QColor(153, 153, 153, 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)); itemNormalColor(isDark ? QColor(255,255,255,0) : QColor(0,0,0,0));
frameColor(isDark ? QColor(56, 56, 56, qRound(255 * 0.8)) : QColor(243, 243, 243, qRound(255 * 0.8))); itemHoverColor(isDark ? QColor(255,255,255,255*0.06) : QColor(0,0,0,255*0.03));
frameActiveColor(isDark ? QColor(48, 48, 48, qRound(255 * 0.8)) : QColor(255, 255, 255, qRound(255 * 0.8))); itemPressColor(isDark ? QColor(255,255,255,255*0.09) : QColor(0,0,0,255*0.06));
itemHoverColor(isDark ? QColor(255, 255, 255, qRound(255 * 0.06)) : QColor(0, 0, 0, qRound(255 * 0.03))); itemCheckColor(isDark ? QColor(255,255,255,255*0.12) : QColor(0,0,0,255*0.09));
itemPressColor(isDark ? QColor(255, 255, 255, qRound(255 * 0.09)) : QColor(0, 0, 0, qRound(255 * 0.06)));
itemCheckColor(isDark ? QColor(255, 255, 255, qRound(255 * 0.12)) : QColor(0, 0, 0, qRound(255 * 0.09)));
} }
bool FluTheme::eventFilter(QObject *, QEvent *event) { bool FluTheme::eventFilter(QObject *obj, QEvent *event){
if (event->type() == QEvent::ApplicationPaletteChange || event->type() == QEvent::ThemeChange) { Q_UNUSED(obj);
if (event->type() == QEvent::ApplicationPaletteChange || event->type() == QEvent::ThemeChange)
{
_systemDark = systemDark(); _systemDark = systemDark();
Q_EMIT darkChanged(); Q_EMIT darkChanged();
event->accept(); event->accept();
@ -64,34 +47,36 @@ bool FluTheme::eventFilter(QObject *, QEvent *event) {
return false; return false;
} }
bool FluTheme::dark() const { QJsonArray FluTheme::awesomeList(const QString& keyword){
if (_darkMode == FluThemeType::DarkMode::Dark) { QJsonArray arr;
QMetaEnum enumType = Fluent_Awesome::staticMetaObject.enumerator(Fluent_Awesome::staticMetaObject.indexOfEnumerator("Fluent_AwesomeType"));
for(int i=0; i < enumType.keyCount(); ++i){
QString name = enumType.key(i);
int icon = enumType.value(i);
if(keyword.isEmpty() || name.contains(keyword)){
QJsonObject obj;
obj.insert("name",name);
obj.insert("icon",icon);
arr.append(obj);
}
}
return arr;
}
bool FluTheme::systemDark(){
QPalette palette = qApp->palette();
QColor color = palette.color(QPalette::Window).rgb();
return !(color.red() * 0.2126 + color.green() * 0.7152 + color.blue() * 0.0722 > 255 / 2);
}
bool FluTheme::dark(){
if(_darkMode == FluThemeType::DarkMode::Dark){
return true; return true;
} else if (_darkMode == FluThemeType::DarkMode::System) { }else if(_darkMode == FluThemeType::DarkMode::Light){
return false;
}else if(_darkMode == FluThemeType::DarkMode::System){
return _systemDark; return _systemDark;
} else { }else{
return false; return false;
} }
} }
void FluTheme::checkUpdateDesktopImage() {
if (!_blurBehindWindowEnabled) {
return;
}
QThreadPool::globalInstance()->start([=]() {
_mutex.lock();
auto path = FluTools::getInstance()->getWallpaperFilePath();
if (_desktopImagePath != path) {
if (!_desktopImagePath.isEmpty()) {
_watcher.removePath(_desktopImagePath);
}
desktopImagePath(path);
_watcher.addPath(path);
}
_mutex.unlock();
});
}
void FluTheme::timerEvent(QTimerEvent *event) {
checkUpdateDesktopImage();
}

View File

@ -1,13 +1,11 @@
#pragma once #ifndef FLUTHEME_H
#define FLUTHEME_H
#include <QObject> #include <QObject>
#include <QtQml/qqml.h> #include <QtQml/qqml.h>
#include <QJsonArray> #include <QJsonArray>
#include <QJsonObject> #include <QJsonObject>
#include <QColor> #include <QColor>
#include <QTimer>
#include <QFileSystemWatcher>
#include <QMutex>
#include "FluAccentColor.h" #include "FluAccentColor.h"
#include "stdafx.h" #include "stdafx.h"
#include "singleton.h" #include "singleton.h"
@ -15,56 +13,41 @@
/** /**
* @brief The FluTheme class * @brief The FluTheme class
*/ */
class FluTheme : public QObject { 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_P(FluAccentColor*, accentColor); Q_PROPERTY_AUTO(FluAccentColor*,accentColor);
Q_PROPERTY_AUTO(QColor, primaryColor); Q_PROPERTY_AUTO(QColor,primaryColor);
Q_PROPERTY_AUTO(QColor, backgroundColor); Q_PROPERTY_AUTO(QColor,backgroundColor);
Q_PROPERTY_AUTO(QColor, dividerColor); Q_PROPERTY_AUTO(QColor,dividerColor);
Q_PROPERTY_AUTO(QColor, windowBackgroundColor); Q_PROPERTY_AUTO(QColor,windowBackgroundColor);
Q_PROPERTY_AUTO(QColor, windowActiveBackgroundColor); Q_PROPERTY_AUTO(QColor,windowActiveBackgroundColor);
Q_PROPERTY_AUTO(QColor, fontPrimaryColor); Q_PROPERTY_AUTO(QColor,fontPrimaryColor);
Q_PROPERTY_AUTO(QColor, fontSecondaryColor); Q_PROPERTY_AUTO(QColor,fontSecondaryColor);
Q_PROPERTY_AUTO(QColor, fontTertiaryColor); Q_PROPERTY_AUTO(QColor,fontTertiaryColor);
Q_PROPERTY_AUTO(QColor, itemNormalColor); Q_PROPERTY_AUTO(QColor,itemNormalColor);
Q_PROPERTY_AUTO(QColor, frameColor); Q_PROPERTY_AUTO(QColor,itemHoverColor);
Q_PROPERTY_AUTO(QColor, frameActiveColor); Q_PROPERTY_AUTO(QColor,itemPressColor);
Q_PROPERTY_AUTO(QColor, itemHoverColor); Q_PROPERTY_AUTO(QColor,itemCheckColor);
Q_PROPERTY_AUTO(QColor, itemPressColor); Q_PROPERTY_AUTO(int,darkMode);
Q_PROPERTY_AUTO(QColor, itemCheckColor); Q_PROPERTY_AUTO(bool,nativeText);
Q_PROPERTY_AUTO(QString, desktopImagePath); Q_PROPERTY_AUTO(bool,animationEnabled);
Q_PROPERTY_AUTO(int, darkMode);
Q_PROPERTY_AUTO(bool, nativeText);
Q_PROPERTY_AUTO(bool, animationEnabled);
Q_PROPERTY_AUTO(bool, blurBehindWindowEnabled);
QML_NAMED_ELEMENT(FluTheme) QML_NAMED_ELEMENT(FluTheme)
QML_SINGLETON QML_SINGLETON
private: private:
explicit FluTheme(QObject *parent = nullptr); explicit FluTheme(QObject *parent = nullptr);
bool eventFilter(QObject *obj, QEvent *event);
bool eventFilter(QObject *obj, QEvent *event) override; bool systemDark();
void refreshColors(); void refreshColors();
protected:
void timerEvent(QTimerEvent *event) override;
void checkUpdateDesktopImage();
public: public:
SINGLETON(FluTheme) SINGLETON(FluTheme)
Q_INVOKABLE QJsonArray awesomeList(const QString& keyword = "");
Q_SIGNAL void darkChanged(); Q_SIGNAL void darkChanged();
static FluTheme *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return getInstance();}
static FluTheme *create(QQmlEngine *, QJSEngine *) { return getInstance(); } bool dark();
bool dark() const;
private: private:
bool _systemDark; bool _systemDark;
QFileSystemWatcher _watcher;
QMutex _mutex;
}; };
#endif // FLUTHEME_H

View File

@ -16,27 +16,19 @@
#include <QDateTime> #include <QDateTime>
#include <QSettings> #include <QSettings>
#ifdef Q_OS_WIN FluTools::FluTools(QObject *parent):QObject{parent}{
#pragma comment (lib, "user32.lib")
#include <windows.h>
#include <windowsx.h>
#endif
FluTools::FluTools(QObject *parent) : QObject{parent} {
} }
void FluTools::clipText(const QString &text) { void FluTools::clipText(const QString& text){
QGuiApplication::clipboard()->setText(text); QGuiApplication::clipboard()->setText(text);
} }
QString FluTools::uuid() { QString FluTools::uuid(){
return QUuid::createUuid().toString().remove('-').remove('{').remove('}'); return QUuid::createUuid().toString().remove('-').remove('{').remove('}');
} }
QString FluTools::readFile(const QString &fileName) { QString FluTools::readFile(const QString &fileName){
QString content; QString content;
QFile file(fileName); QFile file(fileName);
if (file.open(QIODevice::ReadOnly)) { if (file.open(QIODevice::ReadOnly)) {
@ -46,7 +38,7 @@ QString FluTools::readFile(const QString &fileName) {
return content; return content;
} }
bool FluTools::isMacos() { bool FluTools::isMacos(){
#if defined(Q_OS_MACOS) #if defined(Q_OS_MACOS)
return true; return true;
#else #else
@ -54,7 +46,7 @@ bool FluTools::isMacos() {
#endif #endif
} }
bool FluTools::isLinux() { bool FluTools::isLinux(){
#if defined(Q_OS_LINUX) #if defined(Q_OS_LINUX)
return true; return true;
#else #else
@ -62,7 +54,7 @@ bool FluTools::isLinux() {
#endif #endif
} }
bool FluTools::isWin() { bool FluTools::isWin(){
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
return true; return true;
#else #else
@ -70,94 +62,95 @@ bool FluTools::isWin() {
#endif #endif
} }
int FluTools::qtMajor() { int FluTools::qtMajor(){
const QString qtVersion = QString::fromLatin1(qVersion()); const QString qtVersion = QString::fromLatin1(qVersion());
const QStringList versionParts = qtVersion.split('.'); const QStringList versionParts = qtVersion.split('.');
return versionParts[0].toInt(); return versionParts[0].toInt();
} }
int FluTools::qtMinor() { int FluTools::qtMinor(){
const QString qtVersion = QString::fromLatin1(qVersion()); const QString qtVersion = QString::fromLatin1(qVersion());
const QStringList versionParts = qtVersion.split('.'); const QStringList versionParts = qtVersion.split('.');
return versionParts[1].toInt(); return versionParts[1].toInt();
} }
void FluTools::setQuitOnLastWindowClosed(bool val) { void FluTools::setQuitOnLastWindowClosed(bool val){
QGuiApplication::setQuitOnLastWindowClosed(val); qApp->setQuitOnLastWindowClosed(val);
} }
void FluTools::setOverrideCursor(Qt::CursorShape shape) { void FluTools::setOverrideCursor(Qt::CursorShape shape){
QGuiApplication::setOverrideCursor(QCursor(shape)); qApp->setOverrideCursor(QCursor(shape));
} }
void FluTools::restoreOverrideCursor() { void FluTools::restoreOverrideCursor(){
QGuiApplication::restoreOverrideCursor(); qApp->restoreOverrideCursor();
} }
void FluTools::deleteLater(QObject *p) { void FluTools::deleteLater(QObject *p){
if (p) { if(p){
p->deleteLater(); p->deleteLater();
p = nullptr;
} }
} }
QString FluTools::toLocalPath(const QUrl &url) { QString FluTools::toLocalPath(const QUrl& url){
return url.toLocalFile(); return url.toLocalFile();
} }
QString FluTools::getFileNameByUrl(const QUrl &url) { QString FluTools::getFileNameByUrl(const QUrl& url){
return QFileInfo(url.toLocalFile()).fileName(); return QFileInfo(url.toLocalFile()).fileName();
} }
QString FluTools::html2PlantText(const QString &html) { QString FluTools::html2PlantText(const QString& html){
QTextDocument textDocument; QTextDocument textDocument;
textDocument.setHtml(html); textDocument.setHtml(html);
return textDocument.toPlainText(); return textDocument.toPlainText();
} }
QRect FluTools::getVirtualGeometry() { QRect FluTools::getVirtualGeometry(){
return QGuiApplication::primaryScreen()->virtualGeometry(); return qApp->primaryScreen()->virtualGeometry();
} }
QString FluTools::getApplicationDirPath() { QString FluTools::getApplicationDirPath(){
return QGuiApplication::applicationDirPath(); return qApp->applicationDirPath();
} }
QUrl FluTools::getUrlByFilePath(const QString &path) { QUrl FluTools::getUrlByFilePath(const QString& path){
return QUrl::fromLocalFile(path); return QUrl::fromLocalFile(path);
} }
QColor FluTools::withOpacity(const QColor &color, qreal opacity) { QColor FluTools::withOpacity(const QColor& color,qreal opacity){
int alpha = qRound(opacity * 255) & 0xff; int alpha = qRound(opacity * 255) & 0xff;
return QColor::fromRgba((alpha << 24) | (color.rgba() & 0xffffff)); return QColor::fromRgba((alpha << 24) | (color.rgba() & 0xffffff));
} }
QString FluTools::md5(const QString &text) { QString FluTools::md5(QString text){
return QCryptographicHash::hash(text.toUtf8(), QCryptographicHash::Md5).toHex(); return QCryptographicHash::hash(text.toUtf8(), QCryptographicHash::Md5).toHex();
} }
QString FluTools::toBase64(const QString &text) { QString FluTools::toBase64(QString text){
return text.toUtf8().toBase64(); return text.toUtf8().toBase64();
} }
QString FluTools::fromBase64(const QString &text) { QString FluTools::fromBase64(QString text){
return QByteArray::fromBase64(text.toUtf8()); return QByteArray::fromBase64(text.toUtf8());
} }
bool FluTools::removeDir(const QString &dirPath) { bool FluTools::removeDir(QString dirPath){
QDir qDir(dirPath); QDir qDir(dirPath);
return qDir.removeRecursively(); return qDir.removeRecursively();
} }
bool FluTools::removeFile(const QString &filePath) { bool FluTools::removeFile(QString filePath){
QFile file(filePath); QFile file(filePath);
return file.remove(); return file.remove();
} }
QString FluTools::sha256(const QString &text) { QString FluTools::sha256(QString text){
return QCryptographicHash::hash(text.toUtf8(), QCryptographicHash::Sha256).toHex(); return QCryptographicHash::hash(text.toUtf8(), QCryptographicHash::Sha256).toHex();
} }
void FluTools::showFileInFolder(const QString &path) { void FluTools::showFileInFolder(QString path){
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
QProcess::startDetached("explorer.exe", {"/select,", QDir::toNativeSeparators(path)}); QProcess::startDetached("explorer.exe", {"/select,", QDir::toNativeSeparators(path)});
#endif #endif
@ -173,29 +166,29 @@ void FluTools::showFileInFolder(const QString &path) {
#endif #endif
} }
bool FluTools::isSoftware() { bool FluTools::isSoftware(){
return QQuickWindow::sceneGraphBackend() == "software"; return QQuickWindow::sceneGraphBackend() == "software";
} }
QPoint FluTools::cursorPos() { QPoint FluTools::cursorPos(){
return QCursor::pos(); return QCursor::pos();
} }
qint64 FluTools::currentTimestamp() { qint64 FluTools::currentTimestamp(){
return QDateTime::currentMSecsSinceEpoch(); return QDateTime::currentMSecsSinceEpoch();
} }
QIcon FluTools::windowIcon() { QIcon FluTools::windowIcon(){
return QGuiApplication::windowIcon(); return QGuiApplication::windowIcon();
} }
int FluTools::cursorScreenIndex() { int FluTools::cursorScreenIndex(){
int screenIndex = 0; int screenIndex = 0;
int screenCount = QGuiApplication::screens().count(); int screenCount = qApp->screens().count();
if (screenCount > 1) { if (screenCount > 1) {
QPoint pos = QCursor::pos(); QPoint pos = QCursor::pos();
for (int i = 0; i <= screenCount - 1; ++i) { for (int i = 0; i < screenCount; ++i) {
if (QGuiApplication::screens().at(i)->geometry().contains(pos)) { if (qApp->screens().at(i)->geometry().contains(pos)) {
screenIndex = i; screenIndex = i;
break; break;
} }
@ -204,9 +197,9 @@ int FluTools::cursorScreenIndex() {
return screenIndex; return screenIndex;
} }
int FluTools::windowBuildNumber() { int FluTools::windowBuildNumber(){
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
QSettings regKey{QString::fromUtf8(R"(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion)"), QSettings::NativeFormat}; QSettings regKey {QString::fromUtf8("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"), QSettings::NativeFormat};
if (regKey.contains(QString::fromUtf8("CurrentBuildNumber"))) { if (regKey.contains(QString::fromUtf8("CurrentBuildNumber"))) {
auto buildNumber = regKey.value(QString::fromUtf8("CurrentBuildNumber")).toInt(); auto buildNumber = regKey.value(QString::fromUtf8("CurrentBuildNumber")).toInt();
return buildNumber; return buildNumber;
@ -215,103 +208,40 @@ int FluTools::windowBuildNumber() {
return -1; return -1;
} }
bool FluTools::isWindows11OrGreater() { bool FluTools::isWindows11OrGreater(){
static QVariant var; static QVariant var;
if (var.isNull()) { if(var.isNull()){
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
auto buildNumber = windowBuildNumber(); auto buildNumber = windowBuildNumber();
if (buildNumber >= 22000) { if(buildNumber>=22000){
var = QVariant::fromValue(true); var = QVariant::fromValue(true);
return true; return true;
} }
#endif #endif
var = QVariant::fromValue(false); var = QVariant::fromValue(false);
return false; return false;
} else { }else{
return var.toBool(); return var.toBool();
} }
} }
bool FluTools::isWindows10OrGreater() { bool FluTools::isWindows10OrGreater(){
static QVariant var; static QVariant var;
if (var.isNull()) { if(var.isNull()){
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
auto buildNumber = windowBuildNumber(); auto buildNumber = windowBuildNumber();
if (buildNumber >= 10240) { if(buildNumber>=10240){
var = QVariant::fromValue(true); var = QVariant::fromValue(true);
return true; return true;
} }
#endif #endif
var = QVariant::fromValue(false); var = QVariant::fromValue(false);
return false; return false;
} else { }else{
return var.toBool(); return var.toBool();
} }
} }
QRect FluTools::desktopAvailableGeometry(QQuickWindow *window) { QRect FluTools::desktopAvailableGeometry(QQuickWindow* window){
return window->screen()->availableGeometry(); return window->screen()->availableGeometry();
} }
QString FluTools::getWallpaperFilePath() {
#if defined(Q_OS_WIN)
wchar_t path[MAX_PATH] = {};
if (::SystemParametersInfoW(SPI_GETDESKWALLPAPER, MAX_PATH, path, FALSE) == FALSE) {
return {};
}
return QString::fromWCharArray(path);
#elif defined(Q_OS_LINUX)
auto type = QSysInfo::productType();
if (type == "uos") {
QProcess process;
QStringList args;
args << "--session";
args << "--type=method_call";
args << "--print-reply";
args << "--dest=com.deepin.wm";
args << "/com/deepin/wm";
args << "com.deepin.wm.GetCurrentWorkspaceBackgroundForMonitor";
args << QString("string:'%1'").arg(currentTimestamp());
process.start("dbus-send", args);
process.waitForFinished();
QByteArray result = process.readAllStandardOutput().trimmed();
int startIndex = result.indexOf("file:///");
if (startIndex != -1) {
auto path = result.mid(startIndex + 7, result.length() - startIndex - 8);
return path;
}
}
#elif defined(Q_OS_MACOS)
QProcess process;
QStringList args;
args << "-e";
args << R"(tell application "Finder" to get POSIX path of (desktop picture as alias))";
process.start("osascript", args);
process.waitForFinished();
QByteArray result = process.readAllStandardOutput().trimmed();
if(result.isEmpty()){
return "/System/Library/CoreServices/DefaultDesktop.heic";
}
return result;
#else
return {};
#endif
}
QColor FluTools::imageMainColor(const QImage &image, double bright) {
int step = 20;
int t = 0;
int r = 0, g = 0, b = 0;
for (int i = 0; i < image.width(); i += step) {
for (int j = 0; j < image.height(); j += step) {
if (image.valid(i, j)) {
t++;
QColor c = image.pixel(i, j);
r += c.red();
b += c.blue();
g += c.green();
}
}
}
return QColor(int(bright * r / t) > 255 ? 255 : int(bright * r / t), int(bright * g / t) > 255 ? 255 : int(bright * g / t), int(bright * b / t) > 255 ? 255 : int(bright * b / t));
}

View File

@ -1,4 +1,5 @@
#pragma once #ifndef FLUTOOLS_H
#define FLUTOOLS_H
#include <QObject> #include <QObject>
#include <QFile> #include <QFile>
@ -10,90 +11,51 @@
/** /**
* @brief The FluTools class * @brief The FluTools class
*/ */
class FluTools : public QObject { class FluTools : public QObject
Q_OBJECT {
Q_OBJECT
QML_NAMED_ELEMENT(FluTools) QML_NAMED_ELEMENT(FluTools)
QML_SINGLETON QML_SINGLETON
private: private:
explicit FluTools(QObject *parent = nullptr); explicit FluTools(QObject *parent = nullptr);
public: public:
SINGLETON(FluTools) SINGLETON(FluTools)
static FluTools *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine){return getInstance();}
static FluTools *create(QQmlEngine *, QJSEngine *) { return getInstance(); }
Q_INVOKABLE int qtMajor(); Q_INVOKABLE int qtMajor();
Q_INVOKABLE int qtMinor(); Q_INVOKABLE int qtMinor();
Q_INVOKABLE bool isMacos(); Q_INVOKABLE bool isMacos();
Q_INVOKABLE bool isLinux(); Q_INVOKABLE bool isLinux();
Q_INVOKABLE bool isWin(); Q_INVOKABLE bool isWin();
Q_INVOKABLE void clipText(const QString& text);
Q_INVOKABLE void clipText(const QString &text);
Q_INVOKABLE QString uuid(); Q_INVOKABLE QString uuid();
Q_INVOKABLE QString readFile(const QString& fileName);
Q_INVOKABLE QString readFile(const QString &fileName);
Q_INVOKABLE void setQuitOnLastWindowClosed(bool val); Q_INVOKABLE void setQuitOnLastWindowClosed(bool val);
Q_INVOKABLE void setOverrideCursor(Qt::CursorShape shape); Q_INVOKABLE void setOverrideCursor(Qt::CursorShape shape);
Q_INVOKABLE void restoreOverrideCursor(); Q_INVOKABLE void restoreOverrideCursor();
Q_INVOKABLE QString html2PlantText(const QString& html);
Q_INVOKABLE QString html2PlantText(const QString &html); Q_INVOKABLE QString toLocalPath(const QUrl& url);
Q_INVOKABLE QString toLocalPath(const QUrl &url);
Q_INVOKABLE void deleteLater(QObject *p); Q_INVOKABLE void deleteLater(QObject *p);
Q_INVOKABLE QString getFileNameByUrl(const QUrl& url);
Q_INVOKABLE QString getFileNameByUrl(const QUrl &url);
Q_INVOKABLE QRect getVirtualGeometry(); Q_INVOKABLE QRect getVirtualGeometry();
Q_INVOKABLE QString getApplicationDirPath(); Q_INVOKABLE QString getApplicationDirPath();
Q_INVOKABLE QUrl getUrlByFilePath(const QString& path);
Q_INVOKABLE QUrl getUrlByFilePath(const QString &path); Q_INVOKABLE QColor withOpacity(const QColor&,qreal alpha);
Q_INVOKABLE QString md5(QString text);
Q_INVOKABLE QColor withOpacity(const QColor &, qreal alpha); Q_INVOKABLE QString sha256(QString text);
Q_INVOKABLE QString toBase64(QString text);
Q_INVOKABLE QString md5(const QString &text); Q_INVOKABLE QString fromBase64(QString text);
Q_INVOKABLE bool removeDir(QString dirPath);
Q_INVOKABLE QString sha256(const QString &text); Q_INVOKABLE bool removeFile(QString filePath);
Q_INVOKABLE void showFileInFolder(QString path);
Q_INVOKABLE QString toBase64(const QString &text);
Q_INVOKABLE QString fromBase64(const QString &text);
Q_INVOKABLE bool removeDir(const QString &dirPath);
Q_INVOKABLE bool removeFile(const QString &filePath);
Q_INVOKABLE void showFileInFolder(const QString &path);
Q_INVOKABLE bool isSoftware(); Q_INVOKABLE bool isSoftware();
Q_INVOKABLE qint64 currentTimestamp(); Q_INVOKABLE qint64 currentTimestamp();
Q_INVOKABLE QPoint cursorPos(); Q_INVOKABLE QPoint cursorPos();
Q_INVOKABLE QIcon windowIcon(); Q_INVOKABLE QIcon windowIcon();
Q_INVOKABLE int cursorScreenIndex(); Q_INVOKABLE int cursorScreenIndex();
Q_INVOKABLE int windowBuildNumber(); Q_INVOKABLE int windowBuildNumber();
Q_INVOKABLE bool isWindows11OrGreater(); Q_INVOKABLE bool isWindows11OrGreater();
Q_INVOKABLE bool isWindows10OrGreater(); Q_INVOKABLE bool isWindows10OrGreater();
Q_INVOKABLE QRect desktopAvailableGeometry(QQuickWindow* window);
Q_INVOKABLE QRect desktopAvailableGeometry(QQuickWindow *window);
Q_INVOKABLE QString getWallpaperFilePath();
Q_INVOKABLE QColor imageMainColor(const QImage& image, double bright = 1);
}; };
#endif // FLUTOOLS_H

View File

@ -1,76 +1,70 @@
#include "FluTreeModel.h" #include "FluTreeModel.h"
#include <QMetaEnum> #include <QMetaEnum>
#include <utility>
FluTreeNode::FluTreeNode(QObject *parent) : QObject{parent} { FluTreeNode::FluTreeNode(QObject *parent): QObject{parent}{
} }
FluTreeModel::FluTreeModel(QObject *parent) : QAbstractItemModel{parent} { FluTreeModel::FluTreeModel(QObject *parent): QAbstractItemModel{parent}{
_dataSourceSize = 0; dataSourceSize(0);
} }
QModelIndex FluTreeModel::parent(const QModelIndex &child) const { QModelIndex FluTreeModel::parent(const QModelIndex &child) const{
return {}; return QModelIndex();
} }
QModelIndex FluTreeModel::index(int row, int column, const QModelIndex &parent) const { QModelIndex FluTreeModel::index(int row, int column,const QModelIndex &parent) const{
if (!hasIndex(row, column, parent) || parent.isValid()) if (!hasIndex(row, column, parent) || parent.isValid())
return {}; return QModelIndex();
return createIndex(row, column, _rows.at(row)); return createIndex(row, column, _rows.at(row));
} }
int FluTreeModel::rowCount(const QModelIndex &parent) const { int FluTreeModel::rowCount(const QModelIndex &parent) const {
return _rows.count(); return _rows.count();
} };
int FluTreeModel::columnCount(const QModelIndex &parent) const { int FluTreeModel::columnCount(const QModelIndex &parent) const {
return this->_columnSource.size(); return 1;;
} };
QVariant FluTreeModel::data(const QModelIndex &index, int role) const { QVariant FluTreeModel::data(const QModelIndex &index, int role) const {
switch (role) { switch (role) {
case TreeModelRoles::RowModel: case Qt::DisplayRole:
return QVariant::fromValue(_rows.at(index.row())); return QVariant::fromValue(_rows.at(index.row()));
case TreeModelRoles::ColumnModel:
return QVariant::fromValue(_columnSource.at(index.column()));
default: default:
break; break;
} }
return {}; return QVariant();
} };
QHash<int, QByteArray> FluTreeModel::roleNames() const { QHash<int, QByteArray> FluTreeModel::roleNames() const {
return { return { {Qt::DisplayRole, "dataModel"} };
{TreeModelRoles::RowModel, "rowModel"}, };
{TreeModelRoles::ColumnModel, "columnModel"}
};
}
void FluTreeModel::setData(QList<FluTreeNode *> data) { void FluTreeModel::setData(QList<FluTreeNode*> data){
beginResetModel(); beginResetModel();
_rows = std::move(data); _rows = data;
endResetModel(); endResetModel();
} }
void FluTreeModel::removeRows(int row, int count) { void FluTreeModel::removeRows(int row,int count){
if (row < 0 || row + count > _rows.size() || count == 0) if (row < 0 || row + count > _rows.size() || count==0)
return; return;
beginRemoveRows(QModelIndex(), row, row + count - 1); beginRemoveRows(QModelIndex(),row, row + count - 1);
QList<FluTreeNode *> firstPart = _rows.mid(0, row); QList<FluTreeNode*> firstPart = _rows.mid(0,row);
QList<FluTreeNode *> secondPart = _rows.mid(row + count); QList<FluTreeNode*> secondPart = _rows.mid(row + count);
_rows.clear(); _rows.clear();
_rows.append(firstPart); _rows.append(firstPart);
_rows.append(secondPart); _rows.append(secondPart);
endRemoveRows(); endRemoveRows();
} }
void FluTreeModel::insertRows(int row, const QList<FluTreeNode *> &data) { void FluTreeModel::insertRows(int row,QList<FluTreeNode*> data){
if (row < 0 || row > _rows.size() || data.empty()) if (row < 0 || row > _rows.size() || data.size() == 0)
return; return;;
beginInsertRows(QModelIndex(), row, row + data.size() - 1); beginInsertRows(QModelIndex(), row, row + data.size() - 1);
QList<FluTreeNode *> firstPart = _rows.mid(0, row); QList<FluTreeNode*> firstPart = _rows.mid(0, row);
QList<FluTreeNode *> secondPart = _rows.mid(row); QList<FluTreeNode*> secondPart = _rows.mid(row);
_rows.clear(); _rows.clear();
_rows.append(firstPart); _rows.append(firstPart);
_rows.append(data); _rows.append(data);
@ -78,75 +72,79 @@ void FluTreeModel::insertRows(int row, const QList<FluTreeNode *> &data) {
endInsertRows(); endInsertRows();
} }
QObject *FluTreeModel::getRow(int row) { QObject* FluTreeModel::getRow(int row){
return _rows.at(row); return _rows.at(row);
} }
void FluTreeModel::setRow(int row, QVariantMap data) { void FluTreeModel::checkRow(int row,bool checked){
_rows.at(row)->_data = std::move(data);
Q_EMIT dataChanged(index(row, 0), index(row, columnCount() - 1));
}
void FluTreeModel::checkRow(int row, bool checked) {
auto itemData = _rows.at(row); auto itemData = _rows.at(row);
if (itemData->hasChildren()) { if(itemData->hasChildren()){
QList<FluTreeNode *> stack = itemData->_children; QList<FluTreeNode*> stack = itemData->_children;
std::reverse(stack.begin(), stack.end()); std::reverse(stack.begin(), stack.end());
while (stack.count() > 0) { while (stack.count() > 0) {
auto item = stack.at(stack.count() - 1); auto item = stack.at(stack.count()-1);
stack.pop_back(); stack.pop_back();
if (!item->hasChildren()) { if(!item->hasChildren()){
item->_checked = checked; item->_checked = checked;
} }
QList<FluTreeNode *> children = item->_children; QList<FluTreeNode*> children = item->_children;
if (!children.isEmpty()) { if(!children.isEmpty()){
std::reverse(children.begin(), children.end()); std::reverse(children.begin(), children.end());
foreach (auto c, children) { foreach (auto c, children) {
stack.append(c); stack.append(c);
} }
} }
} }
} else { }else{
if (itemData->_checked == checked) { if(itemData->_checked == checked){
return; return;
} }
itemData->_checked = checked; itemData->_checked = checked;
} }
Q_EMIT dataChanged(index(0, 0), index(rowCount() - 1, 0)); Q_EMIT dataChanged(index(0,0),index(rowCount()-1,0));
QList<FluTreeNode*> data;
foreach (auto item, _dataSource) {
if(!item->hasChildren()){
if(item->_checked){
data.append(item);
}
}
}
selectionModel(data);
} }
void FluTreeModel::setDataSource(QList<QMap<QString, QVariant>> data) { void FluTreeModel::setDataSource(QList<QMap<QString,QVariant>> data){
_dataSource.clear(); _dataSource.clear();
if (_root) { if(_root){
delete _root; delete _root;
_root = nullptr; _root = nullptr;
} }
_root = new FluTreeNode(this); _root = new FluTreeNode(this);
std::reverse(data.begin(), data.end()); std::reverse(data.begin(), data.end());
while (data.count() > 0) { while (data.count() > 0) {
auto item = data.at(data.count() - 1); auto item = data.at(data.count()-1);
data.pop_back(); data.pop_back();
auto *node = new FluTreeNode(this); FluTreeNode* node = new FluTreeNode(this);
node->_title = item.value("title").toString();
node->_key = item.value("key").toString();
node->_depth = item.value("__depth").toInt(); node->_depth = item.value("__depth").toInt();
node->_parent = item.value("__parent").value<FluTreeNode *>(); node->_parent = item.value("__parent").value<FluTreeNode*>();
node->_data = item;
node->_isExpanded = true; node->_isExpanded = true;
if (node->_parent) { if(node->_parent){
node->_parent->_children.append(node); node->_parent->_children.append(node);
} else { }else{
node->_parent = _root; node->_parent = _root;
_root->_children.append(node); _root->_children.append(node);
} }
_dataSource.append(node); _dataSource.append(node);
if (item.contains("children")) { if (item.contains("children")) {
QList<QVariant> children = item.value("children").toList(); QList<QVariant> children = item.value("children").toList();
if (!children.isEmpty()) { if(!children.isEmpty()){
std::reverse(children.begin(), children.end()); std::reverse(children.begin(), children.end());
for (int i = 0; i <= children.count() - 1; ++i) { for (int i = 0; i < children.count(); ++i) {
auto child = children.at(i).toMap(); auto child = children.at(i).toMap();
child.insert("__depth", item.value("__depth").toInt(nullptr) + 1); child.insert("__depth",item.value("__depth").toInt(0)+1);
child.insert("__parent", QVariant::fromValue(node)); child.insert("__parent",QVariant::fromValue(node));
data.append(child); data.append(child);
} }
} }
@ -158,81 +156,185 @@ void FluTreeModel::setDataSource(QList<QMap<QString, QVariant>> data) {
dataSourceSize(_dataSource.size()); dataSourceSize(_dataSource.size());
} }
void FluTreeModel::collapse(int row) { void FluTreeModel::collapse(int row){
if (!_rows.at(row)->_isExpanded) { if(!_rows.at(row)->_isExpanded){
return; return;
} }
_rows.at(row)->_isExpanded = false; _rows.at(row)->_isExpanded = false;
Q_EMIT dataChanged(index(row, 0), index(row, 0)); Q_EMIT dataChanged(index(row,0),index(row,0));
auto modelData = _rows.at(row); auto modelData = _rows.at(row);
int removeCount = 0; int removeCount = 0;
for (int i = row + 1; i < _rows.count(); i++) { for(int i=row+1;i<_rows.count();i++){
auto obj = _rows[i]; auto obj = _rows[i];
if (obj->_depth <= modelData->_depth) { if(obj->_depth<=modelData->_depth){
break; break;
} }
removeCount = removeCount + 1; removeCount = removeCount + 1;
} }
removeRows(row + 1, removeCount); removeRows(row+1,removeCount);
} }
void FluTreeModel::expand(int row) { void FluTreeModel::expand(int row){
if (_rows.at(row)->_isExpanded) { if(_rows.at(row)->_isExpanded){
return; return;
} }
_rows.at(row)->_isExpanded = true; _rows.at(row)->_isExpanded = true;
Q_EMIT dataChanged(index(row, 0), index(row, 0)); Q_EMIT dataChanged(index(row,0),index(row,0));
auto modelData = _rows.at(row); auto modelData = _rows.at(row);
QList<FluTreeNode *> insertData; QList<FluTreeNode*> insertData;
QList<FluTreeNode *> stack = modelData->_children; QList<FluTreeNode*> stack = modelData->_children;
std::reverse(stack.begin(), stack.end()); std::reverse(stack.begin(), stack.end());
while (stack.count() > 0) { while (stack.count() > 0) {
auto item = stack.at(stack.count() - 1); auto item = stack.at(stack.count()-1);
stack.pop_back(); stack.pop_back();
if (item->isShown()) { if(item->isShown()){
insertData.append(item); insertData.append(item);
} }
QList<FluTreeNode *> children = item->_children; QList<FluTreeNode*> children = item->_children;
if (!children.isEmpty()) { if(!children.isEmpty()){
std::reverse(children.begin(), children.end()); std::reverse(children.begin(), children.end());
foreach (auto c, children) { foreach (auto c, children) {
stack.append(c); stack.append(c);
} }
} }
} }
insertRows(row + 1, insertData); insertRows(row+1,insertData);
} }
bool FluTreeModel::hitHasChildrenExpanded(int row) { void FluTreeModel::dragAndDrop(int dragIndex,int dropIndex,bool isDropTopArea){
if(dropIndex>_rows.count() || dropIndex<0){
return;
}
auto dragItem = _rows[dragIndex];
auto dropItem = _rows[dropIndex];
int targetIndex;
if(dropIndex > dragIndex){
if(isDropTopArea){
targetIndex = dropIndex;
}else{
targetIndex = dropIndex+1;
}
}else{
if(isDropTopArea){
targetIndex = dropIndex;
}else{
targetIndex = dropIndex+1;
}
}
if (!beginMoveRows(QModelIndex(), dragIndex, dragIndex, QModelIndex(), targetIndex)) {
return;
}
if(dropIndex > dragIndex){
if(isDropTopArea){
targetIndex = dropIndex-1;
}else{
targetIndex = dropIndex;
}
}else{
if(isDropTopArea){
targetIndex = dropIndex;
}else{
targetIndex = dropIndex+1;
}
}
_rows.move(dragIndex,targetIndex);
endMoveRows();
Q_EMIT layoutAboutToBeChanged();
if(dragItem->_parent == dropItem->_parent){
QList<FluTreeNode*>* children = &(dragItem->_parent->_children);
int srcIndex = children->indexOf(dragItem);
int destIndex = children->indexOf(dropItem);
if(dropIndex > dragIndex){
if(isDropTopArea){
targetIndex = destIndex-1;
}else{
targetIndex = destIndex;
}
}else{
if(isDropTopArea){
targetIndex = destIndex;
}else{
targetIndex = destIndex+1;
}
}
children->move(srcIndex,targetIndex);
}else{
QList<FluTreeNode*>* srcChildren = &(dragItem->_parent->_children);
QList<FluTreeNode*>* destChildren = &(dropItem->_parent->_children);
int srcIndex = srcChildren->indexOf(dragItem);
int destIndex = destChildren->indexOf(dropItem);
dragItem->_depth = dropItem->_depth;
dragItem->_parent = dropItem->_parent;
if(dragItem->hasChildren()){
QList<FluTreeNode*> stack = dragItem->_children;
foreach (auto node, stack) {
node->_depth = dragItem->_depth+1;
}
std::reverse(stack.begin(), stack.end());
while (stack.count() > 0) {
auto item = stack.at(stack.count()-1);
stack.pop_back();
QList<FluTreeNode*> children = item->_children;
if(!children.isEmpty()){
std::reverse(children.begin(), children.end());
foreach (auto c, children) {
c->_depth = item->_depth+1;
stack.append(c);
}
}
}
}
srcChildren->removeAt(srcIndex);
if(dropIndex > dragIndex){
if(isDropTopArea){
targetIndex = destIndex;
}else{
targetIndex = destIndex + 1;
}
}else{
if(isDropTopArea){
targetIndex = destIndex;
}else{
targetIndex = destIndex + 1;
}
}
destChildren->insert(targetIndex,dragItem);
}
changePersistentIndex(index(qMin(dragIndex,dropIndex),0),index(qMax(dragIndex,dropIndex),0));
Q_EMIT dataChanged(index(0,0),index(rowCount()-1,0));
}
bool FluTreeModel::hitHasChildrenExpanded(int row){
auto itemData = _rows.at(row); auto itemData = _rows.at(row);
if (itemData->hasChildren() && itemData->_isExpanded) { if(itemData->hasChildren() && itemData->_isExpanded){
return true; return true;
} }
return false; return false;
} }
void FluTreeModel::refreshNode(int row) { void FluTreeModel::refreshNode(int row){
Q_EMIT dataChanged(index(row, 0), index(row, 0)); Q_EMIT dataChanged(index(row,0),index(row,0));
} };
FluTreeNode *FluTreeModel::getNode(int row) { FluTreeNode* FluTreeModel::getNode(int row){
return _rows.at(row); return _rows.at(row);
} }
void FluTreeModel::allExpand() { void FluTreeModel::allExpand(){
beginResetModel(); beginResetModel();
QList<FluTreeNode *> data; QList<FluTreeNode*> data;
QList<FluTreeNode *> stack = _root->_children; QList<FluTreeNode*> stack = _root->_children;
std::reverse(stack.begin(), stack.end()); std::reverse(stack.begin(), stack.end());
while (stack.count() > 0) { while (stack.count() > 0) {
auto item = stack.at(stack.count() - 1); auto item = stack.at(stack.count()-1);
stack.pop_back(); stack.pop_back();
if (item->hasChildren()) { if(item->hasChildren()){
item->_isExpanded = true; item->_isExpanded = true;
} }
data.append(item); data.append(item);
QList<FluTreeNode *> children = item->_children; QList<FluTreeNode*> children = item->_children;
if (!children.isEmpty()) { if(!children.isEmpty()){
std::reverse(children.begin(), children.end()); std::reverse(children.begin(), children.end());
foreach (auto c, children) { foreach (auto c, children) {
stack.append(c); stack.append(c);
@ -242,19 +344,18 @@ void FluTreeModel::allExpand() {
_rows = data; _rows = data;
endResetModel(); endResetModel();
} }
void FluTreeModel::allCollapse(){
void FluTreeModel::allCollapse() {
beginResetModel(); beginResetModel();
QList<FluTreeNode *> stack = _root->_children; QList<FluTreeNode*> stack = _root->_children;
std::reverse(stack.begin(), stack.end()); std::reverse(stack.begin(), stack.end());
while (stack.count() > 0) { while (stack.count() > 0) {
auto item = stack.at(stack.count() - 1); auto item = stack.at(stack.count()-1);
stack.pop_back(); stack.pop_back();
if (item->hasChildren()) { if(item->hasChildren()){
item->_isExpanded = false; item->_isExpanded = false;
} }
QList<FluTreeNode *> children = item->_children; QList<FluTreeNode*> children = item->_children;
if (!children.isEmpty()) { if(!children.isEmpty()){
std::reverse(children.begin(), children.end()); std::reverse(children.begin(), children.end());
foreach (auto c, children) { foreach (auto c, children) {
stack.append(c); stack.append(c);
@ -264,13 +365,3 @@ void FluTreeModel::allCollapse() {
_rows = _root->_children; _rows = _root->_children;
endResetModel(); endResetModel();
} }
QVariant FluTreeModel::selectionModel(){
QList<FluTreeNode *> data;
foreach (auto item, _dataSource) {
if (item->checked()) {
data.append(item);
}
}
return QVariant::fromValue(data);
}

View File

@ -1,149 +1,118 @@
#pragma once #ifndef FLUTREEMODEL_H
#define FLUTREEMODEL_H
#include <QObject> #include <QObject>
#include <QAbstractTableModel> #include <QAbstractTableModel>
#include <QJsonArray> #include <QJsonArray>
#include <QVariant>
#include <QtQml/qqml.h> #include <QtQml/qqml.h>
#include "stdafx.h" #include "stdafx.h"
/** /**
* @brief The FluTreeNode class * @brief The FluTreeNode class
*/ */
class FluTreeNode : public QObject { class FluTreeNode : public QObject{
Q_OBJECT Q_OBJECT
Q_PROPERTY(QVariantMap data READ data CONSTANT) Q_PROPERTY(QString key READ key CONSTANT)
Q_PROPERTY(QString title READ title CONSTANT)
Q_PROPERTY(int depth READ depth CONSTANT) Q_PROPERTY(int depth READ depth CONSTANT)
Q_PROPERTY(bool isExpanded READ isExpanded CONSTANT) Q_PROPERTY(bool isExpanded READ isExpanded CONSTANT)
Q_PROPERTY(bool checked READ checked CONSTANT) Q_PROPERTY(bool checked READ checked CONSTANT)
public: public:
explicit FluTreeNode(QObject *parent = nullptr); explicit FluTreeNode(QObject *parent = nullptr);
Q_INVOKABLE QString key(){return _key;};
[[nodiscard]] Q_INVOKABLE int depth() const { return _depth; }; Q_INVOKABLE QString title(){return _title;};
Q_INVOKABLE int depth(){return _depth;};
[[nodiscard]] Q_INVOKABLE bool isExpanded() const { return _isExpanded; }; Q_INVOKABLE bool isExpanded(){return _isExpanded;};
Q_INVOKABLE bool hasChildren(){ return !_children.isEmpty();};
[[nodiscard]] Q_INVOKABLE QVariantMap data() const { return _data; }; Q_INVOKABLE bool hasNextNodeByIndex(int index){
FluTreeNode* p = this;
[[nodiscard]] Q_INVOKABLE bool hasChildren() const { return !_children.isEmpty(); }; for(int i=0;i<(_depth - index -1);i++){
Q_INVOKABLE bool hasNextNodeByIndex(int index) {
FluTreeNode *p = this;
for (int i = 0; i <= _depth - index - 1; i++) {
p = p->_parent; p = p->_parent;
} }
if (p->_parent->_children.indexOf(p) == p->_parent->_children.count() - 1) { if(p->_parent->_children.indexOf(p) == p->_parent->_children.count()-1){
return false; return false;
} }
return true; return true;
} }
Q_INVOKABLE bool checked(){
[[nodiscard]] Q_INVOKABLE bool checked() const { if(!hasChildren()){
if (!hasChildren()) {
return _checked; return _checked;
} }
for (int i = 0; i <= _children.size() - 1; ++i) { foreach (auto item, _children) {
auto item = _children.at(i); if(!item->checked()){
if (!item->checked()) {
return false; return false;
} }
} }
return true; return true;
}; };
Q_INVOKABLE bool hideLineFooter(){
Q_INVOKABLE bool hideLineFooter() { if(_parent){
if (_parent) {
auto childIndex = _parent->_children.indexOf(this); auto childIndex = _parent->_children.indexOf(this);
if (childIndex == _parent->_children.count() - 1) { if(childIndex==_parent->_children.count()-1){
return true; return true;
} }
if (_parent->_children.at(childIndex + 1)->hasChildren()) { if(_parent->_children.at(childIndex+1)->hasChildren()){
return true; return true;
} }
return false; return false;
} }
return false; return false;
}; };
bool isShown(){
[[nodiscard]] bool isShown() const {
auto p = _parent; auto p = _parent;
while (p) { while (p) {
if (!p->_isExpanded) { if(!p->_isExpanded){
return false; return false;
} }
p = p->_parent; p = p->_parent;
} }
return true; return true;
} }
public: public:
QString _title = ""; QString _key="";
int _depth = 0; QString _title="";
int _depth=0;
bool _checked = false; bool _checked = false;
bool _isExpanded = true; bool _isExpanded=true;
QVariantMap _data; QList<FluTreeNode*> _children;
QList<FluTreeNode *> _children; FluTreeNode* _parent = nullptr;
FluTreeNode *_parent = nullptr;
}; };
class FluTreeModel : public QAbstractItemModel { class FluTreeModel : public QAbstractItemModel
Q_OBJECT {
Q_PROPERTY_AUTO(int, dataSourceSize) Q_OBJECT
Q_PROPERTY_AUTO(QList<QVariantMap>, columnSource) Q_PROPERTY_AUTO(int,dataSourceSize)
Q_PROPERTY_AUTO(QList<FluTreeNode*>,selectionModel)
QML_NAMED_ELEMENT(FluTreeModel) QML_NAMED_ELEMENT(FluTreeModel)
QML_ADDED_IN_MINOR_VERSION(1) QML_ADDED_IN_MINOR_VERSION(1)
public: public:
enum TreeModelRoles {
RowModel = 0x0101,
ColumnModel = 0x0102
};
explicit FluTreeModel(QObject *parent = nullptr); explicit FluTreeModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QHash<int, QByteArray> roleNames() const override;
QModelIndex parent(const QModelIndex &child) const override;
QModelIndex index(int row, int column,const QModelIndex &parent = QModelIndex()) const override;
[[nodiscard]] int rowCount(const QModelIndex &parent = {}) const override; Q_INVOKABLE void removeRows(int row,int count);
Q_INVOKABLE void insertRows(int row,QList<FluTreeNode*> data);
[[nodiscard]] int columnCount(const QModelIndex &parent = {}) const override; Q_INVOKABLE QObject* getRow(int row);
Q_INVOKABLE void setData(QList<FluTreeNode*> data);
[[nodiscard]] QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; Q_INVOKABLE void setDataSource(QList<QMap<QString,QVariant>> data);
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
[[nodiscard]] QModelIndex parent(const QModelIndex &child) const override;
[[nodiscard]] QModelIndex index(int row, int column, const QModelIndex &parent = {}) const override;
Q_INVOKABLE void removeRows(int row, int count);
Q_INVOKABLE void insertRows(int row, const QList<FluTreeNode *> &data);
Q_INVOKABLE QObject *getRow(int row);
Q_INVOKABLE void setRow(int row, QVariantMap data);
Q_INVOKABLE void setData(QList<FluTreeNode *> data);
Q_INVOKABLE void setDataSource(QList<QMap<QString, QVariant>> data);
Q_INVOKABLE void collapse(int row); Q_INVOKABLE void collapse(int row);
Q_INVOKABLE void expand(int row); Q_INVOKABLE void expand(int row);
Q_INVOKABLE void dragAndDrop(int dragIndex,int dropIndex,bool isDropTopArea);
Q_INVOKABLE FluTreeNode *getNode(int row); Q_INVOKABLE FluTreeNode* getNode(int row);
Q_INVOKABLE void refreshNode(int row); Q_INVOKABLE void refreshNode(int row);
Q_INVOKABLE void checkRow(int row,bool checked);
Q_INVOKABLE void checkRow(int row, bool checked);
Q_INVOKABLE bool hitHasChildrenExpanded(int row); Q_INVOKABLE bool hitHasChildrenExpanded(int row);
Q_INVOKABLE void allExpand(); Q_INVOKABLE void allExpand();
Q_INVOKABLE void allCollapse(); Q_INVOKABLE void allCollapse();
Q_INVOKABLE QVariant selectionModel();
private: private:
QList<FluTreeNode *> _rows; QList<FluTreeNode*> _rows;
QList<FluTreeNode *> _dataSource; QList<FluTreeNode*> _dataSource;
FluTreeNode *_root = nullptr; FluTreeNode* _root = nullptr;
}; };
#endif // FLUTREEMODEL_H

View File

@ -1,37 +1,36 @@
#include "FluWatermark.h" #include "FluWatermark.h"
#include "FluTextStyle.h" FluWatermark::FluWatermark(QQuickItem* parent) : QQuickPaintedItem(parent){
gap(QPoint(100,100));
FluWatermark::FluWatermark(QQuickItem *parent) : QQuickPaintedItem(parent) { offset(QPoint(_gap.x()/2,_gap.y()/2));
_gap = QPoint(100, 100); rotate(22);
_offset = QPoint(_gap.x() / 2, _gap.y() / 2);
_rotate = 22;
_textColor = QColor(222, 222, 222, 222);
_textSize = 16;
setZ(9999); setZ(9999);
connect(this, &FluWatermark::textColorChanged, this, [=] { update(); }); textColor(QColor(222,222,222,222));
connect(this, &FluWatermark::gapChanged, this, [=] { update(); }); textSize(16);
connect(this, &FluWatermark::offsetChanged, this, [=] { update(); }); connect(this,&FluWatermark::textColorChanged,this,[=]{update();});
connect(this, &FluWatermark::textChanged, this, [=] { update(); }); connect(this,&FluWatermark::gapChanged,this,[=]{update();});
connect(this, &FluWatermark::rotateChanged, this, [=] { update(); }); connect(this,&FluWatermark::offsetChanged,this,[=]{update();});
connect(this, &FluWatermark::textSizeChanged, this, [=] { update(); }); connect(this,&FluWatermark::textChanged,this,[=]{update();});
connect(this,&FluWatermark::rotateChanged,this,[=]{update();});
connect(this,&FluWatermark::textSizeChanged,this,[=]{update();});
} }
void FluWatermark::paint(QPainter *painter) { void FluWatermark::paint(QPainter* painter){
QFont font; QFont font;
font.setFamily(FluTextStyle::getInstance()->family());
font.setPixelSize(_textSize); font.setPixelSize(_textSize);
painter->setFont(font); painter->setFont(font);
painter->setPen(_textColor); painter->setPen(_textColor);
QFontMetricsF fontMetrics(font); QFontMetricsF fontMetrics(font);
qreal fontWidth = fontMetrics.horizontalAdvance(_text); qreal fontWidth = fontMetrics.horizontalAdvance(_text);
qreal fontHeight = fontMetrics.height(); qreal fontHeight = fontMetrics.height();
int stepX = qRound(fontWidth + _gap.x()); int stepX = fontWidth + _gap.x();
int stepY = qRound(fontHeight + _gap.y()); int stepY = fontHeight + _gap.y();
int rowCount = qRound(width() / stepX + 1); int rowCount = width() / stepX+1;
int colCount = qRound(height() / stepY + 1); int colCount = height() / stepY+1;
for (int r = 0; r < rowCount; r++) { for (int r = 0; r < rowCount; r++)
for (int c = 0; c < colCount; c++) { {
for (int c = 0; c < colCount; c++)
{
qreal centerX = stepX * r + _offset.x() + fontWidth / 2.0; qreal centerX = stepX * r + _offset.x() + fontWidth / 2.0;
qreal centerY = stepY * c + _offset.y() + fontHeight / 2.0; qreal centerY = stepY * c + _offset.y() + fontHeight / 2.0;
painter->save(); painter->save();

View File

@ -1,4 +1,5 @@
#pragma once #ifndef FLUWATERMARK_H
#define FLUWATERMARK_H
#include <QQuickItem> #include <QQuickItem>
#include <QQuickPaintedItem> #include <QQuickPaintedItem>
@ -8,17 +9,19 @@
/** /**
* @brief The FluWatermark class * @brief The FluWatermark class
*/ */
class FluWatermark : public QQuickPaintedItem { class FluWatermark : public QQuickPaintedItem
Q_OBJECT {
Q_PROPERTY_AUTO(QString, text) Q_OBJECT
Q_PROPERTY_AUTO(QPoint, gap) Q_PROPERTY_AUTO(QString,text)
Q_PROPERTY_AUTO(QPoint, offset); Q_PROPERTY_AUTO(QPoint,gap)
Q_PROPERTY_AUTO(QColor, textColor); Q_PROPERTY_AUTO(QPoint,offset);
Q_PROPERTY_AUTO(int, rotate); Q_PROPERTY_AUTO(QColor,textColor);
Q_PROPERTY_AUTO(int, textSize); Q_PROPERTY_AUTO(int,rotate);
Q_PROPERTY_AUTO(int,textSize);
QML_NAMED_ELEMENT(FluWatermark) QML_NAMED_ELEMENT(FluWatermark)
public: public:
explicit FluWatermark(QQuickItem *parent = nullptr); explicit FluWatermark(QQuickItem *parent = nullptr);
void paint(QPainter* painter) override;
void paint(QPainter *painter) override;
}; };
#endif // FLUWATERMARK_H

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,6 @@
#include <QGuiApplication> #include <QGuiApplication>
#include "Def.h" #include "Def.h"
#include "FluentIconDef.h"
#include "FluApp.h" #include "FluApp.h"
#include "FluColors.h" #include "FluColors.h"
#include "FluTheme.h" #include "FluTheme.h"
@ -16,144 +15,143 @@
#include "FluTableSortProxyModel.h" #include "FluTableSortProxyModel.h"
#include "FluFrameless.h" #include "FluFrameless.h"
void FluentUI::registerTypes(QQmlEngine *engine) { void FluentUI::registerTypes(QQmlEngine *engine){
initializeEngine(engine, _uri); initializeEngine(engine,uri);
registerTypes(_uri); registerTypes(uri);
} }
void FluentUI::registerTypes(const char *uri) const { void FluentUI::registerTypes(const char *uri){
#if (QT_VERSION < QT_VERSION_CHECK(6, 2, 0)) #if (QT_VERSION < QT_VERSION_CHECK(6, 2, 0))
Q_INIT_RESOURCE(fluentui); Q_INIT_RESOURCE(fluentui);
int major = _major;
int minor = _minor;
//@uri FluentUI //@uri FluentUI
qmlRegisterType<FluQrCodeItem>(uri, major, minor, "FluQrCodeItem"); qmlRegisterType<FluQrCodeItem>(uri,major,minor,"FluQrCodeItem");
qmlRegisterType<FluCaptcha>(uri, major, minor, "FluCaptcha"); qmlRegisterType<FluCaptcha>(uri,major,minor,"FluCaptcha");
qmlRegisterType<FluWatermark>(uri, major, minor, "FluWatermark"); qmlRegisterType<FluWatermark>(uri,major,minor,"FluWatermark");
qmlRegisterType<FluAccentColor>(uri, major, minor, "FluAccentColor"); qmlRegisterType<FluAccentColor>(uri,major,minor,"FluAccentColor");
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<FluFrameless>(uri, major, minor, "FluFrameless"); qmlRegisterType<FluFrameless>(uri,major,minor,"FluFrameless");
qmlRegisterType<FluTableSortProxyModel>(uri, major, minor, "FluTableSortProxyModel"); qmlRegisterType<FluTableSortProxyModel>(uri,major,minor,"FluTableSortProxyModel");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluAcrylic.qml"), uri, major, minor, "FluAcrylic"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluAcrylic.qml"),uri,major,minor,"FluAcrylic");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluAppBar.qml"), uri, major, minor, "FluAppBar"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluAppBar.qml"),uri,major,minor,"FluAppBar");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluFrame.qml"), uri, major, minor, "FluFrame"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluFrame.qml"),uri,major,minor,"FluFrame");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluAutoSuggestBox.qml"), uri, major, minor, "FluAutoSuggestBox"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluAutoSuggestBox.qml"),uri,major,minor,"FluAutoSuggestBox");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluBadge.qml"), uri, major, minor, "FluBadge"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluBadge.qml"),uri,major,minor,"FluBadge");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluBreadcrumbBar.qml"), uri, major, minor, "FluBreadcrumbBar"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluBreadcrumbBar.qml"),uri,major,minor,"FluBreadcrumbBar");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluButton.qml"), uri, major, minor, "FluButton"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluButton.qml"),uri,major,minor,"FluButton");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluCalendarPicker.qml"), uri, major, minor, "FluCalendarPicker"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluCalendarPicker.qml"),uri,major,minor,"FluCalendarPicker");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluCarousel.qml"), uri, major, minor, "FluCarousel"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluCarousel.qml"),uri,major,minor,"FluCarousel");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluChart.qml"), uri, major, minor, "FluChart"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluChart.qml"),uri,major,minor,"FluChart");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluCheckBox.qml"), uri, major, minor, "FluCheckBox"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluCheckBox.qml"),uri,major,minor,"FluCheckBox");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluColorPicker.qml"), uri, major, minor, "FluColorPicker"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluColorPicker.qml"),uri,major,minor,"FluColorPicker");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluComboBox.qml"), uri, major, minor, "FluComboBox"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluComboBox.qml"),uri,major,minor,"FluComboBox");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluContentDialog.qml"), uri, major, minor, "FluContentDialog"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluContentDialog.qml"),uri,major,minor,"FluContentDialog");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluContentPage.qml"), uri, major, minor, "FluContentPage"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluContentPage.qml"),uri,major,minor,"FluContentPage");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluControl.qml"), uri, major, minor, "FluControl"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluControl.qml"),uri,major,minor,"FluControl");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluCopyableText.qml"), uri, major, minor, "FluCopyableText"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluCopyableText.qml"),uri,major,minor,"FluCopyableText");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluDatePicker.qml"), uri, major, minor, "FluDatePicker"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluDatePicker.qml"),uri,major,minor,"FluDatePicker");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluDivider.qml"), uri, major, minor, "FluDivider"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluDivider.qml"),uri,major,minor,"FluDivider");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluDropDownButton.qml"), uri, major, minor, "FluDropDownButton"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluDropDownButton.qml"),uri,major,minor,"FluDropDownButton");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluExpander.qml"), uri, major, minor, "FluExpander"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluExpander.qml"),uri,major,minor,"FluExpander");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluFilledButton.qml"), uri, major, minor, "FluFilledButton"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluFilledButton.qml"),uri,major,minor,"FluFilledButton");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluFlipView.qml"), uri, major, minor, "FluFlipView"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluFlipView.qml"),uri,major,minor,"FluFlipView");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluFocusRectangle.qml"), uri, major, minor, "FluFocusRectangle"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluFocusRectangle.qml"),uri,major,minor,"FluFocusRectangle");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluIcon.qml"), uri, major, minor, "FluIcon"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluIcon.qml"),uri,major,minor,"FluIcon");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluIconButton.qml"), uri, major, minor, "FluIconButton"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluIconButton.qml"),uri,major,minor,"FluIconButton");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluImage.qml"), uri, major, minor, "FluImage"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluImage.qml"),uri,major,minor,"FluImage");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluImageButton.qml"), uri, major, minor, "FluImageButton"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluImageButton.qml"),uri,major,minor,"FluImageButton");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluInfoBar.qml"), uri, major, minor, "FluInfoBar"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluInfoBar.qml"),uri,major,minor,"FluInfoBar");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluItemDelegate.qml"), uri, major, minor, "FluItemDelegate"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluItemDelegate.qml"),uri,major,minor,"FluItemDelegate");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluMenu.qml"), uri, major, minor, "FluMenu"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluMenu.qml"),uri,major,minor,"FluMenu");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluMenuBar.qml"), uri, major, minor, "FluMenuBar"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluMenuBar.qml"),uri,major,minor,"FluMenuBar");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluMenuBarItem.qml"), uri, major, minor, "FluMenuBarItem"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluMenuBarItem.qml"),uri,major,minor,"FluMenuBarItem");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluMenuItem.qml"), uri, major, minor, "FluMenuItem"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluMenuItem.qml"),uri,major,minor,"FluMenuItem");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluMenuSeparator.qml"), uri, major, minor, "FluMenuSeparator"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluMenuSeparator.qml"),uri,major,minor,"FluMenuSeparator");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluMultilineTextBox.qml"), uri, major, minor, "FluMultilineTextBox"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluMultilineTextBox.qml"),uri,major,minor,"FluMultilineTextBox");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluNavigationView.qml"), uri, major, minor, "FluNavigationView"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluNavigationView.qml"),uri,major,minor,"FluNavigationView");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluObject.qml"), uri, major, minor, "FluObject"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluObject.qml"),uri,major,minor,"FluObject");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluPage.qml"), uri, major, minor, "FluPage"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluPage.qml"),uri,major,minor,"FluPage");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluPagination.qml"), uri, major, minor, "FluPagination"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluPagination.qml"),uri,major,minor,"FluPagination");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluPaneItem.qml"), uri, major, minor, "FluPaneItem"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluPaneItem.qml"),uri,major,minor,"FluPaneItem");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluPaneItemEmpty.qml"), uri, major, minor, "FluPaneItemEmpty"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluPaneItemEmpty.qml"),uri,major,minor,"FluPaneItemEmpty");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluPaneItemExpander.qml"), uri, major, minor, "FluPaneItemExpander"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluPaneItemExpander.qml"),uri,major,minor,"FluPaneItemExpander");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluPaneItemHeader.qml"), uri, major, minor, "FluPaneItemHeader"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluPaneItemHeader.qml"),uri,major,minor,"FluPaneItemHeader");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluPaneItemSeparator.qml"), uri, major, minor, "FluPaneItemSeparator"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluPaneItemSeparator.qml"),uri,major,minor,"FluPaneItemSeparator");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluPasswordBox.qml"), uri, major, minor, "FluPasswordBox"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluPasswordBox.qml"),uri,major,minor,"FluPasswordBox");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluPivot.qml"), uri, major, minor, "FluPivot"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluPivot.qml"),uri,major,minor,"FluPivot");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluPivotItem.qml"), uri, major, minor, "FluPivotItem"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluPivotItem.qml"),uri,major,minor,"FluPivotItem");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluPopup.qml"), uri, major, minor, "FluPopup"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluPopup.qml"),uri,major,minor,"FluPopup");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluProgressBar.qml"), uri, major, minor, "FluProgressBar"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluProgressBar.qml"),uri,major,minor,"FluProgressBar");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluProgressRing.qml"), uri, major, minor, "FluProgressRing"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluProgressRing.qml"),uri,major,minor,"FluProgressRing");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluQRCode.qml"), uri, major, minor, "FluQRCode"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluQRCode.qml"),uri,major,minor,"FluQRCode");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluRadioButton.qml"), uri, major, minor, "FluRadioButton"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluRadioButton.qml"),uri,major,minor,"FluRadioButton");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluRadioButtons.qml"), uri, major, minor, "FluRadioButtons"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluRadioButtons.qml"),uri,major,minor,"FluRadioButtons");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluRatingControl.qml"), uri, major, minor, "FluRatingControl"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluRatingControl.qml"),uri,major,minor,"FluRatingControl");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluRemoteLoader.qml"), uri, major, minor, "FluRemoteLoader"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluRemoteLoader.qml"),uri,major,minor,"FluRemoteLoader");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluScrollBar.qml"), uri, major, minor, "FluScrollBar"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluScrollBar.qml"),uri,major,minor,"FluScrollBar");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluScrollIndicator.qml"), uri, major, minor, "FluScrollIndicator"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluScrollIndicator.qml"),uri,major,minor,"FluScrollIndicator");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluScrollablePage.qml"), uri, major, minor, "FluScrollablePage"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluScrollablePage.qml"),uri,major,minor,"FluScrollablePage");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluShadow.qml"), uri, major, minor, "FluShadow"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluShadow.qml"),uri,major,minor,"FluShadow");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluSlider.qml"), uri, major, minor, "FluSlider"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluSlider.qml"),uri,major,minor,"FluSlider");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluSpinBox.qml"), uri, major, minor, "FluSpinBox"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluSpinBox.qml"),uri,major,minor,"FluSpinBox");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluStatusLayout.qml"), uri, major, minor, "FluStatusLayout"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluStatusLayout.qml"),uri,major,minor,"FluStatusLayout");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluTabView.qml"), uri, major, minor, "FluTabView"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluTabView.qml"),uri,major,minor,"FluTabView");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluTableView.qml"), uri, major, minor, "FluTableView"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluTableView.qml"),uri,major,minor,"FluTableView");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluText.qml"), uri, major, minor, "FluText"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluText.qml"),uri,major,minor,"FluText");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluTextBox.qml"), uri, major, minor, "FluTextBox"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluTextBox.qml"),uri,major,minor,"FluTextBox");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluTextBoxBackground.qml"), uri, major, minor, "FluTextBoxBackground"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluTextBoxBackground.qml"),uri,major,minor,"FluTextBoxBackground");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluTextBoxMenu.qml"), uri, major, minor, "FluTextBoxMenu"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluTextBoxMenu.qml"),uri,major,minor,"FluTextBoxMenu");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluTextButton.qml"), uri, major, minor, "FluTextButton"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluTextButton.qml"),uri,major,minor,"FluTextButton");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluTimePicker.qml"), uri, major, minor, "FluTimePicker"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluTimePicker.qml"),uri,major,minor,"FluTimePicker");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluTimeline.qml"), uri, major, minor, "FluTimeline"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluTimeline.qml"),uri,major,minor,"FluTimeline");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluToggleButton.qml"), uri, major, minor, "FluToggleButton"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluToggleButton.qml"),uri,major,minor,"FluToggleButton");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluToggleSwitch.qml"), uri, major, minor, "FluToggleSwitch"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluToggleSwitch.qml"),uri,major,minor,"FluToggleSwitch");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluTooltip.qml"), uri, major, minor, "FluTooltip"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluTooltip.qml"),uri,major,minor,"FluTooltip");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluTour.qml"), uri, major, minor, "FluTour"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluTour.qml"),uri,major,minor,"FluTour");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluTreeView.qml"), uri, major, minor, "FluTreeView"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluTreeView.qml"),uri,major,minor,"FluTreeView");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluWindow.qml"), uri, major, minor, "FluWindow"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluWindow.qml"),uri,major,minor,"FluWindow");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluWindowDialog.qml"), uri, major, minor, "FluWindowDialog"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluWindowDialog.qml"),uri,major,minor,"FluWindowDialog");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluRangeSlider.qml"), uri, major, minor, "FluRangeSlider"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluRangeSlider.qml"),uri,major,minor,"FluRangeSlider");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluStaggeredLayout.qml"), uri, major, minor, "FluStaggeredLayout"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluStaggeredLayout.qml"),uri,major,minor,"FluStaggeredLayout");
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"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluLoader.qml"),uri,major,minor,"FluLoader");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluShortcutPicker.qml"), uri, major, minor, "FluShortcutPicker"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluShortcutPicker.qml"),uri,major,minor,"FluShortcutPicker");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluSplitLayout.qml"), uri, major, minor, "FluSplitLayout"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluSplitLayout.qml"),uri,major,minor,"FluSplitLayout");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluWindowResultLauncher.qml"), uri, major, minor, "FluWindowResultLauncher"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluWindowResultLauncher.qml"),uri,major,minor,"FluWindowResultLauncher");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluLauncher.qml"), uri, major, minor, "FluLauncher"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluLauncher.qml"),uri,major,minor,"FluLauncher");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluEvent.qml"), uri, major, minor, "FluEvent"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluEvent.qml"),uri,major,minor,"FluEvent");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluSheet.qml"), uri, major, minor, "FluSheet"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluSheet.qml"),uri,major,minor,"FluSheet");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluGroupBox.qml"), uri, major, minor, "FluGroupBox"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluGroupBox.qml"),uri,major,minor,"FluGroupBox");
qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluControlBackground.qml"), uri, major, minor, "FluControlBackground"); qmlRegisterType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluControlBackground.qml"),uri,major,minor,"FluControlBackground");
qmlRegisterSingletonType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluRouter.qml"), uri, major, minor, "FluRouter"); qmlRegisterSingletonType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluRouter.qml"),uri,major,minor,"FluRouter");
qmlRegisterSingletonType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluEventBus.qml"), uri, major, minor, "FluEventBus"); qmlRegisterSingletonType(QUrl("qrc:/qt/qml/FluentUI/Controls/FluEventBus.qml"),uri,major,minor,"FluEventBus");
qmlRegisterUncreatableMetaObject(Fluent_Icons::staticMetaObject, uri, major, minor, "FluentIcons", "Access to enums & flags only"); qmlRegisterUncreatableMetaObject(Fluent_Awesome::staticMetaObject, uri,major,minor,"FluentIcons", "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");
qmlRegisterUncreatableMetaObject(FluTreeViewType::staticMetaObject, uri, major, minor, "FluTreeViewType", "Access to enums & flags only"); qmlRegisterUncreatableMetaObject(FluTreeViewType::staticMetaObject, uri,major,minor,"FluTreeViewType", "Access to enums & flags only");
qmlRegisterUncreatableMetaObject(FluStatusLayoutType::staticMetaObject, uri, major, minor, "FluStatusLayoutType", "Access to enums & flags only"); qmlRegisterUncreatableMetaObject(FluStatusLayoutType::staticMetaObject, uri,major,minor,"FluStatusLayoutType", "Access to enums & flags only");
qmlRegisterUncreatableMetaObject(FluContentDialogType::staticMetaObject, uri, major, minor, "FluContentDialogType", "Access to enums & flags only"); qmlRegisterUncreatableMetaObject(FluContentDialogType::staticMetaObject, uri,major,minor,"FluContentDialogType", "Access to enums & flags only");
qmlRegisterUncreatableMetaObject(FluTimePickerType::staticMetaObject, uri, major, minor, "FluTimePickerType", "Access to enums & flags only"); qmlRegisterUncreatableMetaObject(FluTimePickerType::staticMetaObject, uri,major,minor,"FluTimePickerType", "Access to enums & flags only");
qmlRegisterUncreatableMetaObject(FluCalendarViewType::staticMetaObject, uri, major, minor, "FluCalendarViewType", "Access to enums & flags only"); qmlRegisterUncreatableMetaObject(FluCalendarViewType::staticMetaObject, uri,major,minor,"FluCalendarViewType", "Access to enums & flags only");
qmlRegisterUncreatableMetaObject(FluTabViewType::staticMetaObject, uri, major, minor, "FluTabViewType", "Access to enums & flags only"); qmlRegisterUncreatableMetaObject(FluTabViewType::staticMetaObject, uri,major,minor,"FluTabViewType", "Access to enums & flags only");
qmlRegisterUncreatableMetaObject(FluNavigationViewType::staticMetaObject, uri, major, minor, "FluNavigationViewType", "Access to enums & flags only"); qmlRegisterUncreatableMetaObject(FluNavigationViewType::staticMetaObject, uri,major,minor,"FluNavigationViewType", "Access to enums & flags only");
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(FluSheetType::staticMetaObject, uri, major, minor, "FluSheetType", "Access to enums & flags only"); qmlRegisterUncreatableMetaObject(FluSheetType::staticMetaObject, uri,major,minor,"FluSheetType", "Access to enums & flags only");
qmlRegisterModule(uri, major, minor); qmlRegisterModule(uri,major,minor);
#endif #endif
} }
void FluentUI::initializeEngine(QQmlEngine *engine, [[maybe_unused]] const char *uri) { void FluentUI::initializeEngine(QQmlEngine *engine, const char *uri){
engine->rootContext()->setContextProperty("FluApp", FluApp::getInstance()); engine->rootContext()->setContextProperty("FluApp",FluApp::getInstance());
engine->rootContext()->setContextProperty("FluColors", FluColors::getInstance()); engine->rootContext()->setContextProperty("FluColors",FluColors::getInstance());
engine->rootContext()->setContextProperty("FluTheme", FluTheme::getInstance()); engine->rootContext()->setContextProperty("FluTheme",FluTheme::getInstance());
engine->rootContext()->setContextProperty("FluTools", FluTools::getInstance()); engine->rootContext()->setContextProperty("FluTools",FluTools::getInstance());
engine->rootContext()->setContextProperty("FluTextStyle", FluTextStyle::getInstance()); engine->rootContext()->setContextProperty("FluTextStyle",FluTextStyle::getInstance());
} }

View File

@ -1,4 +1,5 @@
#pragma once #ifndef FLUENTUI_H
#define FLUENTUI_H
#include <QObject> #include <QObject>
#include <QQmlEngine> #include <QQmlEngine>
@ -7,20 +8,18 @@
/** /**
* @brief The FluentUI class * @brief The FluentUI class
*/ */
class FluentUI : public QObject { class FluentUI : public QObject
Q_OBJECT {
Q_OBJECT
public: public:
SINGLETON(FluentUI) SINGLETON(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) const; void initializeEngine(QQmlEngine *engine, const char *uri);
void initializeEngine(QQmlEngine *engine, [[maybe_unused]] const char *uri);
private: private:
const int _major = 1; const int major = 1;
const int _minor = 0; const int minor = 0;
const char *_uri = "FluentUI"; const char *uri = "FluentUI";
}; };
#endif // FLUENTUI_H

View File

@ -8,9 +8,10 @@ Item {
property real tintOpacity: 0.65 property real tintOpacity: 0.65
property real luminosity: 0.01 property real luminosity: 0.01
property real noiseOpacity: 0.02 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
@ -33,7 +34,7 @@ Item {
} }
Image { Image {
anchors.fill: parent anchors.fill: parent
source: "qrc:/qt/qml/FluentUI/Image/noise.png" source: "../Image/noise.png"
fillMode: Image.Tile fillMode: Image.Tile
opacity: control.noiseOpacity opacity: control.noiseOpacity
} }

View File

@ -14,7 +14,7 @@ Rectangle{
property string closeText : qsTr("Close") property string closeText : qsTr("Close")
property string stayTopText : qsTr("Sticky on Top") property string stayTopText : qsTr("Sticky on Top")
property string stayTopCancelText : qsTr("Sticky on Top cancelled") property string stayTopCancelText : qsTr("Sticky on Top cancelled")
property color textColor: FluTheme.fontPrimaryColor property color textColor: FluTheme.dark ? "#FFFFFF" : "#000000"
property color minimizeNormalColor: FluTheme.itemNormalColor property color minimizeNormalColor: FluTheme.itemNormalColor
property color minimizeHoverColor: FluTheme.itemHoverColor property color minimizeHoverColor: FluTheme.itemHoverColor
property color minimizePressColor: FluTheme.itemPressColor property color minimizePressColor: FluTheme.itemPressColor

View File

@ -7,7 +7,6 @@ FluTextBox{
property var items:[] property var items:[]
property string emptyText: qsTr("No results found") property string emptyText: qsTr("No results found")
property int autoSuggestBoxReplacement: FluentIcons.Search property int autoSuggestBoxReplacement: FluentIcons.Search
property string textRole: "title"
property var filter: function(item){ property var filter: function(item){
if(item.title.indexOf(control.text)!==-1){ if(item.title.indexOf(control.text)!==-1){
return true return true
@ -26,7 +25,7 @@ FluTextBox{
function handleClick(modelData){ function handleClick(modelData){
control_popup.visible = false control_popup.visible = false
control.itemClicked(modelData) control.itemClicked(modelData)
control.updateText(modelData[textRole]) control.updateText(modelData.title)
} }
function loadData(){ function loadData(){
var result = [] var result = []
@ -49,6 +48,7 @@ FluTextBox{
} }
Popup{ Popup{
id:control_popup id:control_popup
y:control.height
focus: false focus: false
padding: 0 padding: 0
enter: Transition { enter: Transition {
@ -59,10 +59,14 @@ FluTextBox{
duration: FluTheme.animationEnabled ? 83 : 0 duration: FluTheme.animationEnabled ? 83 : 0
} }
} }
contentItem: FluClip{ contentItem: FluRectangle{
radius: [5,5,5,5] radius: [4,4,4,4]
FluShadow{
radius: 4
}
color: FluTheme.dark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(248/255,250/255,253/255,1)
ListView{ ListView{
id: list_view id:list_view
anchors.fill: parent anchors.fill: parent
clip: true clip: true
boundsBehavior: ListView.StopAtBounds boundsBehavior: ListView.StopAtBounds
@ -72,7 +76,7 @@ FluTextBox{
height: visible ? 38 : 0 height: visible ? 38 : 0
visible: list_view.count === 0 visible: list_view.count === 0
FluText{ FluText{
text: emptyText text:emptyText
anchors{ anchors{
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
left: parent.left left: parent.left
@ -81,10 +85,10 @@ FluTextBox{
} }
} }
delegate:FluControl{ delegate:FluControl{
id: item_control id:item_control
height: 38 height: 38
width: control.width width: control.width
onClicked: { onClicked:{
d.handleClick(modelData) d.handleClick(modelData)
} }
background: Rectangle{ background: Rectangle{
@ -93,17 +97,14 @@ FluTextBox{
radius:4 radius:4
} }
color: { color: {
if(pressed){
return FluTheme.itemPressColor
}
if(hovered){ if(hovered){
return FluTheme.itemHoverColor return FluTheme.dark ? Qt.rgba(63/255,60/255,61/255,1) : Qt.rgba(237/255,237/255,242/255,1)
} }
return FluTheme.itemNormalColor return FluTheme.dark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(0,0,0,0)
} }
} }
contentItem: FluText{ contentItem: FluText{
text: modelData[textRole] text:modelData.title
leftPadding: 10 leftPadding: 10
rightPadding: 10 rightPadding: 10
verticalAlignment : Qt.AlignVCenter verticalAlignment : Qt.AlignVCenter
@ -111,28 +112,22 @@ FluTextBox{
} }
} }
} }
background:Rectangle{ background: Item{
id: rect_background id:container
implicitWidth: control.width implicitWidth: control.width
implicitHeight: 38*Math.min(Math.max(list_view.count,1),8) implicitHeight: 38*Math.min(Math.max(list_view.count,1),8)
radius: 5
color: FluTheme.dark ? Qt.rgba(43/255,43/255,43/255,1) : Qt.rgba(1,1,1,1)
border.color: FluTheme.dark ? Qt.rgba(26/255,26/255,26/255,1) : Qt.rgba(191/255,191/255,191/255,1)
FluShadow{
radius: 5
}
} }
} }
onTextChanged: { onTextChanged: {
d.loadData() d.loadData()
if(d.flagVisible){ if(d.flagVisible){
var pos = control.mapToItem(null, 0, 0) var pos = control.mapToItem(null, 0, 0)
if(d.window.height>pos.y+control.height+rect_background.implicitHeight){ if(d.window.height>pos.y+control.height+container.implicitHeight){
control_popup.y = Qt.binding(function(){return control.height}) control_popup.y = control.height
} else if(pos.y>rect_background.implicitHeight){ } else if(pos.y>container.implicitHeight){
control_popup.y = -rect_background.implicitHeight control_popup.y = -container.implicitHeight
} else { } else {
control_popup.y = d.window.height-(pos.y+rect_background.implicitHeight) - 1 control_popup.y = d.window.height-(pos.y+container.implicitHeight)
} }
control_popup.visible = true control_popup.visible = true
} }

View File

@ -57,12 +57,12 @@ Item {
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
color: { color: {
if(item_mouse.pressed){ if(item_mouse.pressed){
return FluTheme.dark ? Qt.rgba(150/255,150/255,150/255,1) : Qt.rgba(134/255,134/255,134/255,1) return FluTheme.dark ? Qt.rgba(150/255,150/255,150/235,1) : Qt.rgba(134/255,134/255,134/235,1)
} }
if(item_mouse.containsMouse){ if(item_mouse.containsMouse){
return FluTheme.dark ? Qt.rgba(204/255,204/255,204/255,1) : Qt.rgba(92/255,92/255,92/255,1) return FluTheme.dark ? Qt.rgba(204/255,204/255,204/235,1) : Qt.rgba(92/255,92/255,92/235,1)
} }
return FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(26/255,26/255,26/255,1) return FluTheme.dark ? Qt.rgba(255/255,255/255,255/235,1) : Qt.rgba(26/255,26/255,26/235,1)
} }
MouseArea{ MouseArea{
id:item_mouse id:item_mouse

View File

@ -53,6 +53,8 @@ FluButton {
} }
Menu{ Menu{
id:popup id:popup
height: container.height
width: container.width
modal: true modal: true
Overlay.modal: Item {} Overlay.modal: Item {}
enter: Transition { enter: Transition {
@ -73,9 +75,11 @@ FluButton {
} }
} }
contentItem: Item{ contentItem: Item{
clip: true
FluFrame{
id:container id:container
implicitWidth: 300 width: 300
implicitHeight: 360 height: 360
ColumnLayout { ColumnLayout {
anchors.fill: parent anchors.fill: parent
spacing: 0 spacing: 0
@ -605,10 +609,8 @@ FluButton {
} }
} }
} }
background:Rectangle{ }
radius: 5 background: Item{
color: FluTheme.dark ? Qt.rgba(43/255,43/255,43/255,1) : Qt.rgba(1,1,1,1)
border.color: FluTheme.dark ? Qt.rgba(26/255,26/255,26/255,1) : Qt.rgba(191/255,191/255,191/255,1)
FluShadow{ FluShadow{
radius: 5 radius: 5
} }
@ -616,12 +618,13 @@ FluButton {
function showPopup() { function showPopup() {
var pos = control.mapToItem(null, 0, 0) var pos = control.mapToItem(null, 0, 0)
if(d.window.height>pos.y+control.height+container.height){ if(d.window.height>pos.y+control.height+container.height){
popup.y = control.height - 1 popup.y = control.height
} else if(pos.y>container.height){ } else if(pos.y>container.height){
popup.y = -container.height popup.y = -container.height
} else { } else {
popup.y = d.window.height-(pos.y+container.height) popup.y = d.window.height-(pos.y+container.height)
} }
popup.x = -(popup.width-control.width)/2
popup.open() popup.open()
} }
} }

View File

@ -13,15 +13,16 @@ Button{
property color current : Qt.rgba(1,1,1,1) property color current : Qt.rgba(1,1,1,1)
signal accepted() signal accepted()
property int colorHandleRadius: 8 property int colorHandleRadius: 8
property string cancelText: qsTr("Cancel") property string cancelText: "取消"
property string okText: qsTr("OK") property string okText: "确定"
property string titleText: qsTr("Color Picker") property string titleText: "颜色选择器"
property string editText: qsTr("Edit Color") property string editText: "编辑颜色"
property string redText: qsTr("Red") property string redText: "红色"
property string greenText: qsTr("Green") property string greenText: "绿色"
property string blueText: qsTr("Blue") property string blueText: "蓝色"
property string opacityText: qsTr("Opacity") property string opacityText: "透明度"
background: Rectangle{ background:
Rectangle{
id:layout_color id:layout_color
radius: 5 radius: 5
color:"#00000000" color:"#00000000"

View File

@ -134,9 +134,10 @@ T.ComboBox {
} }
} }
background:Rectangle{ background:Rectangle{
color:FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(249/255,249/255,249/255,1)
border.color: FluTheme.dark ? Window.active ? Qt.rgba(55/255,55/255,55/255,1):Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,229/255,234/255,1)
border.width: 1
radius: 5 radius: 5
color: FluTheme.dark ? Qt.rgba(43/255,43/255,43/255,1) : Qt.rgba(1,1,1,1)
border.color: FluTheme.dark ? Qt.rgba(26/255,26/255,26/255,1) : Qt.rgba(191/255,191/255,191/255,1)
FluShadow{ FluShadow{
radius: 5 radius: 5
} }

View File

@ -4,6 +4,7 @@ import QtQuick.Layouts 1.15
import QtQuick.Window 2.15 import QtQuick.Window 2.15
import FluentUI 1.0 import FluentUI 1.0
FluButton { FluButton {
property bool showYear: true property bool showYear: true
property var current property var current
@ -95,6 +96,8 @@ FluButton {
Menu{ Menu{
id:popup id:popup
modal: true modal: true
width: container.width
height: container.height
Overlay.modal: Item {} Overlay.modal: Item {}
enter: Transition { enter: Transition {
reversible: true reversible: true
@ -113,31 +116,35 @@ FluButton {
duration: FluTheme.animationEnabled ? 83 : 0 duration: FluTheme.animationEnabled ? 83 : 0
} }
} }
background:Rectangle{ background:Item{
radius: 5
color: FluTheme.dark ? Qt.rgba(43/255,43/255,43/255,1) : Qt.rgba(1,1,1,1)
border.color: FluTheme.dark ? Qt.rgba(26/255,26/255,26/255,1) : Qt.rgba(191/255,191/255,191/255,1)
FluShadow{ FluShadow{
radius: 5 radius: 4
} }
} }
contentItem: Item{ contentItem: Item{
clip: true
Rectangle{
id:container id:container
implicitHeight: 340 radius: 4
implicitWidth: 300 width: 300
height: 340
color: FluTheme.dark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(248/255,250/255,253/255,1)
MouseArea{ MouseArea{
anchors.fill: parent anchors.fill: parent
} }
FluShadow{
radius: 4
}
RowLayout{ RowLayout{
id:layout_content id:layout_content
spacing: 0 spacing: 0
width: parent.width width: parent.width
height: 280 height: 300
Component{ Component{
id:list_delegate id:list_delegate
Item{ Item{
height: 38 height:38
width: getListView().width width:getListView().width
function getListView(){ function getListView(){
if(type === 0) if(type === 0)
return list_view_1 return list_view_1
@ -159,7 +166,7 @@ FluButton {
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)
} }
return Qt.rgba(0,0,0,0) return FluTheme.dark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(0,0,0,0)
} }
radius: 3 radius: 3
MouseArea{ MouseArea{
@ -207,9 +214,8 @@ FluButton {
} }
ListView{ ListView{
id:list_view_1 id:list_view_1
Layout.preferredWidth: 100 width: 100
Layout.preferredHeight: parent.height - 2 height: parent.height
Layout.alignment: Qt.AlignVCenter
boundsBehavior:Flickable.StopAtBounds boundsBehavior:Flickable.StopAtBounds
ScrollBar.vertical: FluScrollBar {} ScrollBar.vertical: FluScrollBar {}
model: generateYearArray(1924,2048) model: generateYearArray(1924,2048)
@ -226,16 +232,14 @@ FluButton {
} }
} }
Rectangle{ Rectangle{
Layout.preferredWidth: 1 width: 1
Layout.preferredHeight: parent.height height: parent.height
color: control.dividerColor color: control.dividerColor
visible: showYear
} }
ListView{ ListView{
id:list_view_2 id:list_view_2
Layout.preferredWidth: showYear ? 99 : 150 width: showYear ? 100 : 150
Layout.preferredHeight: parent.height - 2 height: parent.height
Layout.alignment: Qt.AlignVCenter
clip: true clip: true
ScrollBar.vertical: FluScrollBar {} ScrollBar.vertical: FluScrollBar {}
preferredHighlightBegin: 0 preferredHighlightBegin: 0
@ -250,20 +254,20 @@ FluButton {
} }
} }
Rectangle{ Rectangle{
Layout.preferredWidth: 1 width: 1
Layout.preferredHeight: parent.height height: parent.height
color: control.dividerColor color: control.dividerColor
} }
ListView{ ListView{
id:list_view_3 id:list_view_3
Layout.preferredWidth: showYear ? 99 : 150 width: showYear ? 100 : 150
Layout.preferredHeight: parent.height - 2 height: parent.height
Layout.alignment: Qt.AlignVCenter
clip: true clip: true
preferredHighlightBegin: 0 preferredHighlightBegin: 0
preferredHighlightEnd: 0 preferredHighlightEnd: 0
highlightMoveDuration: 0 highlightMoveDuration: 0
ScrollBar.vertical: FluScrollBar {} ScrollBar.vertical: FluScrollBar {}
Layout.alignment: Qt.AlignVCenter
boundsBehavior:Flickable.StopAtBounds boundsBehavior:Flickable.StopAtBounds
delegate: FluLoader{ delegate: FluLoader{
property var model: modelData property var model: modelData
@ -273,12 +277,17 @@ FluButton {
} }
} }
} }
Rectangle{
width: parent.width
height: 1
anchors.top: layout_content.bottom
color: control.dividerColor
}
Rectangle{ Rectangle{
id:layout_actions id:layout_actions
height: 60 height: 40
color: FluTheme.dark ? Qt.rgba(32/255,32/255,32/255,1) : Qt.rgba(243/255,243/255,243/255,1)
border.color: FluTheme.dark ? Qt.rgba(26/255,26/255,26/255,1) : Qt.rgba(191/255,191/255,191/255,1)
radius: 5 radius: 5
color: FluTheme.dark ? Qt.rgba(32/255,32/255,32/255,1) : Qt.rgba(243/255,243/255,243/255,1)
anchors{ anchors{
bottom:parent.bottom bottom:parent.bottom
left: parent.left left: parent.left
@ -331,6 +340,7 @@ FluButton {
} }
} }
} }
}
y:35 y:35
function showPopup() { function showPopup() {
d.changeFlag = true d.changeFlag = true
@ -351,7 +361,7 @@ FluButton {
text_day.text = day text_day.text = day
var pos = control.mapToItem(null, 0, 0) var pos = control.mapToItem(null, 0, 0)
if(d.window.height>pos.y+control.height+container.height){ if(d.window.height>pos.y+control.height+container.height){
popup.y = control.height-1 popup.y = control.height
} else if(pos.y>container.height){ } else if(pos.y>container.height){
popup.y = -container.height popup.y = -container.height
} else { } else {

View File

@ -19,20 +19,16 @@ FluButton {
} }
iconColor:control.textColor iconColor:control.textColor
} }
Item{
id: d
property var window: Window.window
}
onClicked: { onClicked: {
if(menu.count !==0){ if(menu.count !==0){
var pos = control.mapToItem(null, 0, 0) var pos = control.mapToItem(null, 0, 0)
var containerHeight = menu.count*36 var containerHeight = menu.count*36
if(d.window.height>pos.y+control.height+containerHeight){ if(window.height>pos.y+control.height+containerHeight){
menu.y = control.height menu.y = control.height
}else if(pos.y>containerHeight){ }else if(pos.y>containerHeight){
menu.y = -containerHeight menu.y = -containerHeight
}else{ }else{
menu.y = d.window.height-(pos.y+containerHeight) menu.y = window.height-(pos.y+containerHeight)
} }
menu.open() menu.open()
} }

View File

@ -27,12 +27,7 @@ Item {
height: 45 height: 45
radius: 4 radius: 4
border.color: FluTheme.dividerColor border.color: FluTheme.dividerColor
color: { color: FluTheme.dark ? Window.active ? Qt.rgba(39/255,39/255,39/255,1) : Qt.rgba(39/255,39/255,39/255,1) : Qt.rgba(251/255,251/255,253/255,1)
if(Window.active){
return FluTheme.frameActiveColor
}
return FluTheme.frameColor
}
MouseArea{ MouseArea{
id:control_mouse id:control_mouse
anchors.fill: parent anchors.fill: parent
@ -89,18 +84,12 @@ Item {
height: contentHeight+container.anchors.topMargin height: contentHeight+container.anchors.topMargin
width: parent.width width: parent.width
z:-999 z:-999
clip: true
Rectangle{ Rectangle{
id:container id:container
anchors.fill: parent anchors.fill: parent
radius: 4 radius: 4
clip: true clip: true
color: { color: FluTheme.dark ? Qt.rgba(39/255,39/255,39/255,1) : Qt.rgba(251/255,251/255,253/255,1)
if(Window.active){
return FluTheme.frameActiveColor
}
return FluTheme.frameColor
}
border.color: FluTheme.dividerColor border.color: FluTheme.dividerColor
anchors.topMargin: -contentHeight anchors.topMargin: -contentHeight
states: [ states: [

View File

@ -19,11 +19,6 @@ T.Frame {
id:d id:d
radius: 4 radius: 4
border.color: FluTheme.dividerColor border.color: FluTheme.dividerColor
color: { color: FluTheme.dark ? Window.active ? Qt.rgba(39/255,39/255,39/255,1) : Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(251/255,251/255,253/255,1)
if(Window.active){
return FluTheme.frameActiveColor
}
return FluTheme.frameColor
}
} }
} }

View File

@ -8,13 +8,8 @@ import FluentUI 1.0
T.GroupBox { T.GroupBox {
id: control id: control
property int borderWidth : 1 property int borderWidth : 1
property color borderColor : FluTheme.dividerColor property color borderColor : FluTheme.dark ? Window.active ? Qt.rgba(55/255,55/255,55/255,1):Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,229/255,234/255,1)
property color color: { property color color: FluTheme.dark ? Window.active ? Qt.rgba(38/255,44/255,54/255,1) : Qt.rgba(39/255,39/255,39/255,1) : Qt.rgba(251/255,251/255,253/255,1)
if(Window.active){
return FluTheme.frameActiveColor
}
return FluTheme.frameColor
}
property int radius: 4 property int radius: 4
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
contentWidth + leftPadding + rightPadding, contentWidth + leftPadding + rightPadding,

View File

@ -7,15 +7,13 @@ Text {
property int iconSize: 20 property int iconSize: 20
property color iconColor: FluTheme.dark ? "#FFFFFF" : "#000000" property color iconColor: FluTheme.dark ? "#FFFFFF" : "#000000"
id:control id:control
font.family: font_loader.name font.family: "Segoe Fluent Icons"
font.pixelSize: iconSize font.pixelSize: iconSize
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
color: iconColor color: iconColor
text: (String.fromCharCode(iconSource).toString(16)) text: (String.fromCharCode(iconSource).toString(16))
opacity: iconSource>0
FontLoader{ FontLoader{
id: font_loader source: "../Font/Segoe_Fluent_Icons.ttf"
source: "qrc:/qt/qml/FluentUI/Font/FluentIcons.ttf"
} }
} }

View File

@ -44,8 +44,8 @@ T.Menu {
background: Rectangle { background: Rectangle {
implicitWidth: 150 implicitWidth: 150
implicitHeight: 36 implicitHeight: 36
color:FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(252/255,252/255,252/255,1) color:FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(240/255,240/255,240/255,1)
border.color: FluTheme.dark ? Qt.rgba(26/255,26/255,26/255,1) : Qt.rgba(191/255,191/255,191/255,1) border.color: FluTheme.dark ? Window.active ? Qt.rgba(55/255,55/255,55/255,1):Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,229/255,234/255,1)
border.width: 1 border.width: 1
radius: 5 radius: 5
FluShadow{} FluShadow{}

View File

@ -21,7 +21,6 @@ T.SpinBox {
bottom: Math.min(control.from, control.to) bottom: Math.min(control.from, control.to)
top: Math.max(control.from, control.to) top: Math.max(control.from, control.to)
} }
font: FluTextStyle.Body
contentItem: TextInput { contentItem: TextInput {
property color normalColor: FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1) property color normalColor: FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1)

View File

@ -8,11 +8,11 @@ Item{
id:control id:control
default property alias content: container.data default property alias content: container.data
property int statusMode: FluStatusLayoutType.Loading property int statusMode: FluStatusLayoutType.Loading
property string loadingText: qsTr("Loading...") property string loadingText:"正在加载..."
property string emptyText: qsTr("Empty") property string emptyText: "空空如也"
property string errorText: qsTr("Error") property string errorText: "页面出错了.."
property string errorButtonText: qsTr("Reload") property string errorButtonText: "重新加载"
property color color: Qt.rgba(0,0,0,0) property color color: FluTheme.dark ? Window.active ? Qt.rgba(38/255,44/255,54/255,1) : Qt.rgba(39/255,39/255,39/255,1) : Qt.rgba(251/255,251/255,253/255,1)
signal errorClicked signal errorClicked
property Component loadingItem : com_loading property Component loadingItem : com_loading
property Component emptyItem : com_empty property Component emptyItem : com_empty

View File

@ -1,5 +1,4 @@
import QtQuick 2.15 import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15 import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import Qt.labs.qmlmodels 1.0 import Qt.labs.qmlmodels 1.0
@ -18,12 +17,7 @@ Rectangle {
property color selectedBorderColor: FluTheme.primaryColor property color selectedBorderColor: FluTheme.primaryColor
property color selectedColor: FluTools.withOpacity(FluTheme.primaryColor,0.3) property color selectedColor: FluTools.withOpacity(FluTheme.primaryColor,0.3)
id:control id:control
color: { color: FluTheme.dark ? Qt.rgba(39/255,39/255,39/255,1) : Qt.rgba(251/255,251/255,253/255,1)
if(Window.active){
return FluTheme.frameActiveColor
}
return FluTheme.frameColor
}
onColumnSourceChanged: { onColumnSourceChanged: {
if(columnSource.length!==0){ if(columnSource.length!==0){
var columns= [] var columns= []
@ -96,7 +90,7 @@ Rectangle {
if(!readOnly){ if(!readOnly){
editTextChaged(text_box.text) editTextChaged(text_box.text)
} }
control.closeEditor() tableView.closeEditor()
} }
} }
} }
@ -125,7 +119,7 @@ Rectangle {
if(!readOnly){ if(!readOnly){
editTextChaged(text_box.text) editTextChaged(text_box.text)
} }
control.closeEditor() tableView.closeEditor()
} }
} }
} }
@ -196,11 +190,6 @@ Rectangle {
id:com_table_delegate id:com_table_delegate
MouseArea{ MouseArea{
id:item_table_mouse id:item_table_mouse
TableView.onPooled: {
if(d.editPosition && d.editPosition.row === row && d.editPosition.column === column){
control.closeEditor()
}
}
property var rowObject : control.getRow(row) property var rowObject : control.getRow(row)
property var itemModel: model property var itemModel: model
property bool editVisible: { property bool editVisible: {
@ -269,7 +258,7 @@ Rectangle {
anchors.fill: parent anchors.fill: parent
acceptedButtons: Qt.LeftButton acceptedButtons: Qt.LeftButton
onPressed:{ onPressed:{
control.closeEditor() closeEditor()
} }
onCanceled: { onCanceled: {
} }
@ -279,14 +268,14 @@ Rectangle {
if(typeof(display) == "object"){ if(typeof(display) == "object"){
return return
} }
loader_edit.display = display
d.editDelegate = d.getEditDelegate(column) d.editDelegate = d.getEditDelegate(column)
updateEditPosition() updateEditPosition()
loader_edit.display = display
} }
onClicked: onClicked:
(event)=>{ (event)=>{
d.current = rowObject d.current = rowObject
control.closeEditor() closeEditor()
event.accepted = true event.accepted = true
} }
} }
@ -392,7 +381,6 @@ Rectangle {
clip: true clip: true
onRowsChanged: { onRowsChanged: {
control.closeEditor() control.closeEditor()
table_view.flick(0,1)
} }
delegate: com_table_delegate delegate: com_table_delegate
FluLoader{ FluLoader{
@ -783,9 +771,9 @@ Rectangle {
timer_vertical_force_layout.restart() timer_vertical_force_layout.restart()
} }
Connections{ Connections{
target: table_view target: table_model
function onRowsChanged(){ function onRowCountChanged(){
header_row_model.rows = Array.from({length: table_view.rows}, (_, i) => ({rowIndex:i+1})) header_row_model.rows = Array.from({length: table_model.rows.length}, (_, i) => ({rowIndex:i+1}))
} }
} }
Timer{ Timer{

View File

@ -23,27 +23,16 @@ FluControlBackground{
GradientStop { position: 1 - d.offsetSize/control.height; color: d.startColor } GradientStop { position: 1 - d.offsetSize/control.height; color: d.startColor }
GradientStop { position: 1.0; color: d.endColor } GradientStop { position: 1.0; color: d.endColor }
} }
bottomMargin: 1 bottomMargin: inputItem && inputItem.activeFocus ? 2 : 1
QtObject{ QtObject{
id:d id:d
property int offsetSize : 3 property int offsetSize : inputItem && inputItem.activeFocus ? 2 : 3
property color startColor : FluTheme.dark ? Qt.rgba(66/255,66/255,66/255,1) : Qt.rgba(232/255,232/255,232/255,1) property color startColor: FluTheme.dark ? Qt.rgba(66/255,66/255,66/255,1) : Qt.rgba(232/255,232/255,232/255,1)
property color endColor: { property color endColor: {
if(!control.enabled){ if(!control.enabled){
return d.startColor return d.startColor
} }
return FluTheme.dark ? Qt.rgba(123/255,123/255,123/255,1) : Qt.rgba(132/255,132/255,132/255,1) return inputItem && inputItem.activeFocus ? FluTheme.primaryColor : FluTheme.dark ? Qt.rgba(123/255,123/255,123/255,1) : Qt.rgba(132/255,132/255,132/255,1)
}
}
FluClip{
anchors.fill: parent
radius: [control.radius,control.radius,control.radius,control.radius]
visible: inputItem && inputItem.activeFocus
Rectangle{
width: parent.width
height: 2
anchors.bottom: parent.bottom
color: FluTheme.primaryColor
} }
} }
} }

View File

@ -111,6 +111,8 @@ FluButton {
} }
Menu{ Menu{
id:popup id:popup
width: container.width
height: container.height
modal: true modal: true
Overlay.modal: Item {} Overlay.modal: Item {}
enter: Transition { enter: Transition {
@ -130,18 +132,19 @@ FluButton {
duration: FluTheme.animationEnabled ? 83 : 0 duration: FluTheme.animationEnabled ? 83 : 0
} }
} }
background:Rectangle{ background:Item{
radius: 5
color: FluTheme.dark ? Qt.rgba(43/255,43/255,43/255,1) : Qt.rgba(1,1,1,1)
border.color: FluTheme.dark ? Qt.rgba(26/255,26/255,26/255,1) : Qt.rgba(191/255,191/255,191/255,1)
FluShadow{ FluShadow{
radius: 5 radius: 4
} }
} }
contentItem: Item{ contentItem: Item{
clip: true
Rectangle{
id:container id:container
implicitHeight: 340 height: 340
implicitWidth: 300 width: 300
radius: 4
color: FluTheme.dark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(248/255,250/255,253/255,1)
MouseArea{ MouseArea{
anchors.fill: parent anchors.fill: parent
} }
@ -149,7 +152,7 @@ FluButton {
id:layout_content id:layout_content
spacing: 0 spacing: 0
width: parent.width width: parent.width
height: 280 height: 300
Component{ Component{
id:list_delegate id:list_delegate
Item{ Item{
@ -176,7 +179,7 @@ FluButton {
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)
} }
return Qt.rgba(0,0,0,0) return FluTheme.dark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(0,0,0,0)
} }
radius: 3 radius: 3
MouseArea{ MouseArea{
@ -216,9 +219,8 @@ FluButton {
} }
ListView{ ListView{
id:list_view_1 id:list_view_1
Layout.preferredWidth: isH ? 100 : 150 width: isH ? 100 : 150
Layout.preferredHeight: parent.height-2 height: parent.height
Layout.alignment: Qt.AlignVCenter
boundsBehavior:Flickable.StopAtBounds boundsBehavior:Flickable.StopAtBounds
ScrollBar.vertical: FluScrollBar {} ScrollBar.vertical: FluScrollBar {}
preferredHighlightBegin: 0 preferredHighlightBegin: 0
@ -234,15 +236,14 @@ FluButton {
} }
} }
Rectangle{ Rectangle{
Layout.preferredWidth: 1 width: 1
Layout.preferredHeight: parent.height height: parent.height
color: control.dividerColor color: control.dividerColor
} }
ListView{ ListView{
id:list_view_2 id:list_view_2
Layout.preferredWidth: isH ? 99 : 150 width: isH ? 100 : 150
Layout.preferredHeight: parent.height-2 height: parent.height
Layout.alignment: Qt.AlignVCenter
model: generateArray(0,59) model: generateArray(0,59)
clip: true clip: true
preferredHighlightBegin: 0 preferredHighlightBegin: 0
@ -265,8 +266,8 @@ FluButton {
} }
ListView{ ListView{
id:list_view_3 id:list_view_3
Layout.preferredWidth: 100 width: 100
Layout.preferredHeight: 76 height: 76
model: [control.amText,control.pmText] model: [control.amText,control.pmText]
clip: true clip: true
visible: isH visible: isH
@ -284,12 +285,17 @@ FluButton {
} }
} }
} }
Rectangle{
width: parent.width
height: 1
anchors.top: layout_content.bottom
color: control.dividerColor
}
Rectangle{ Rectangle{
id:layout_actions id:layout_actions
height: 60 height: 40
color: FluTheme.dark ? Qt.rgba(32/255,32/255,32/255,1) : Qt.rgba(243/255,243/255,243/255,1)
border.color: FluTheme.dark ? Qt.rgba(26/255,26/255,26/255,1) : Qt.rgba(191/255,191/255,191/255,1)
radius: 5 radius: 5
color: FluTheme.dark ? Qt.rgba(32/255,32/255,32/255,1) : Qt.rgba(243/255,243/255,243/255,1)
anchors{ anchors{
bottom:parent.bottom bottom:parent.bottom
left: parent.left left: parent.left
@ -347,6 +353,7 @@ FluButton {
} }
} }
} }
}
y:35 y:35
function showPopup() { function showPopup() {
d.changeFlag = true d.changeFlag = true
@ -380,7 +387,7 @@ FluButton {
} }
var pos = control.mapToItem(null, 0, 0) var pos = control.mapToItem(null, 0, 0)
if(d.window.height>pos.y+control.height+container.height){ if(d.window.height>pos.y+control.height+container.height){
popup.y = control.height-1 popup.y = control.height
} else if(pos.y>container.height){ } else if(pos.y>container.height){
popup.y = -container.height popup.y = -container.height
} else { } else {

File diff suppressed because it is too large Load Diff

View File

@ -109,56 +109,9 @@ Window {
} }
Component{ Component{
id:com_background id:com_background
Item{
Rectangle{ Rectangle{
anchors.fill: parent
color: window.backgroundColor color: window.backgroundColor
} }
Image{
id:img_back
visible: false
cache: false
fillMode: Image.PreserveAspectCrop
asynchronous: true
Component.onCompleted: {
var geometry = FluTools.desktopAvailableGeometry(window)
width = geometry.width
height = geometry.height
sourceSize = Qt.size(width,height)
source = FluTools.getUrlByFilePath(FluTheme.desktopImagePath)
}
Connections{
target: FluTheme
function onDesktopImagePathChanged(){
timer_update_image.restart()
}
function onBlurBehindWindowEnabledChanged(){
if(FluTheme.blurBehindWindowEnabled){
img_back.source = FluTools.getUrlByFilePath(FluTheme.desktopImagePath)
}else{
img_back.source = ""
}
}
}
Timer{
id:timer_update_image
interval: 500
onTriggered: {
img_back.source = ""
img_back.source = FluTools.getUrlByFilePath(FluTheme.desktopImagePath)
}
}
}
FluAcrylic{
anchors.fill: parent
target: img_back
tintOpacity: FluTheme.dark ? 0.80 : 0.75
blurRadius: 64
visible: window.active && FluTheme.blurBehindWindowEnabled
tintColor: FluTheme.dark ? Qt.rgba(0, 0, 0, 1) : Qt.rgba(1, 1, 1, 1)
targetRect: Qt.rect(window.x,window.y,window.width,window.height)
}
}
} }
Component{ Component{
id:com_app_bar id:com_app_bar
@ -330,12 +283,6 @@ Window {
function showMaximized(){ function showMaximized(){
frameless.showMaximized() frameless.showMaximized()
} }
function showMinimized(){
frameless.showMinimized()
}
function showNormal(){
frameless.showNormal()
}
function showLoading(text = "",cancel = true){ function showLoading(text = "",cancel = true){
if(text===""){ if(text===""){
text = qsTr("Loading...") text = qsTr("Loading...")

View File

@ -32,9 +32,9 @@ FluWindow {
} }
} }
} }
function showDialog(offsetX=0,offsetY=0){ function showDialog(){
var x = transientParent.x + (transientParent.width - width)/2 + offsetX var x = transientParent.x + (transientParent.width - width)/2
var y = transientParent.y + (transientParent.height - height)/2 + offsetY var y = transientParent.y + (transientParent.height - height)/2
control.stayTop = Qt.binding(function(){return transientParent.stayTop}) control.stayTop = Qt.binding(function(){return transientParent.stayTop})
control.setGeometry(x,y,width,height) control.setGeometry(x,y,width,height)
control.visibility = Window.Windowed control.visibility = Window.Windowed

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