Compare commits

..

72 Commits
1.2.5 ... 1.2.9

Author SHA1 Message Date
eaad0dc565 update 2023-05-06 00:08:04 +08:00
9a494e938c update 2023-05-05 23:54:10 +08:00
ad35ac2588 update 2023-05-05 23:05:07 +08:00
c81910a41f update 2023-05-05 22:46:54 +08:00
cff6aaf6f4 update 2023-05-05 22:45:02 +08:00
a1c8672a5a update 2023-05-05 21:58:39 +08:00
df5e657ad1 update 2023-05-05 21:42:16 +08:00
fb4ed03530 update 2023-05-05 18:51:40 +08:00
7ceb4f27a3 Merge pull request #83 from mentalfl0w/dev
Make the library compile as Universal Library in macOS.
2023-05-04 08:23:58 +08:00
292e96cdfd Make the library compile as Universal Library in macOS. 2023-05-04 00:22:20 +08:00
c925ab79c6 Merge pull request #81 from mentalfl0w/dev
Allow the table to set the maximum height of each row based on the content.
2023-04-30 14:52:01 +08:00
f51d9f960b Allow the table to set the maximum height of each row based on the content. 2023-04-30 13:50:51 +08:00
86fa76edee update 2023-04-28 23:44:32 +08:00
4222597ef0 Merge pull request #76 from mentalfl0w/dev
Added ToolTip for FluTabView's tab.
2023-04-27 18:18:24 +08:00
a3adedf164 Added ToolTip for FluTabView's tab. 2023-04-27 18:06:01 +08:00
a70ddf7087 update 2023-04-27 17:29:39 +08:00
afeb6daea5 update 2023-04-27 15:43:45 +08:00
a258d429c2 Merge branch 'main' of https://github.com/zhuzichu520/FluentUI 2023-04-27 14:30:46 +08:00
7a25a48fdb update 2023-04-27 14:30:10 +08:00
0e434a36e7 Update README.md 2023-04-27 10:25:40 +08:00
36561fd75a Update README.md 2023-04-27 10:24:09 +08:00
430fac2f77 update 2023-04-27 10:12:53 +08:00
c15470f723 update 2023-04-27 09:38:57 +08:00
2aef114969 Merge pull request #74 from mentalfl0w/dev
Improve SingleInstance.
2023-04-26 00:18:46 +08:00
c0e470d78e Improve SingleInstance. 2023-04-25 23:58:25 +08:00
c8f2d7c926 Update README.md 2023-04-25 12:56:20 +08:00
b032e0306f Update README.md 2023-04-25 12:53:21 +08:00
36ac017e3d update 2023-04-24 21:14:08 +08:00
981445630b update 2023-04-24 21:05:39 +08:00
9494ec4ac6 update 2023-04-24 17:48:12 +08:00
d71441e7c5 update 2023-04-24 17:02:26 +08:00
9f0b8c5ec5 Merge branch 'main' of https://github.com/zhuzichu520/FluentUI 2023-04-23 18:08:50 +08:00
94c0356c25 update 2023-04-23 18:08:20 +08:00
9e73f33877 Merge pull request #70 from LiangLiang723/main
🐛 修复宏定义错误导致无法编译
2023-04-23 15:53:58 +08:00
adc8040604 🐛 修复宏定义错误导致无法编译 2023-04-23 10:26:06 +08:00
82d1edc43c update 2023-04-22 19:25:10 +08:00
da17b31be7 update 2023-04-22 18:45:10 +08:00
67518fb4e6 update 2023-04-22 18:29:43 +08:00
2bd03ad9d8 update 2023-04-22 18:26:10 +08:00
e16a8d6b09 update 2023-04-22 18:18:13 +08:00
9e0050be63 update 2023-04-22 18:08:11 +08:00
a4398d1a2f update 2023-04-22 18:01:52 +08:00
a27e5db032 update 2023-04-22 16:02:52 +08:00
f7c17a27b6 update 2023-04-22 00:29:47 +08:00
020a75ac93 update 2023-04-21 09:37:10 +08:00
1b0cdd6152 update 2023-04-20 23:37:51 +08:00
1a9cca4300 Merge pull request #67 from mentalfl0w/dev
Add addButtonVisibility into FluTabView.
2023-04-20 23:16:51 +08:00
d939546f31 Add addButtonVisibility into FluTabView. 2023-04-20 22:57:56 +08:00
9f9d9da601 update 2023-04-20 20:22:56 +08:00
6d24cbf37c update 2023-04-20 20:13:31 +08:00
d2929ad701 update 2023-04-20 19:15:38 +08:00
689843fbef Merge pull request #65 from mentalfl0w/dev
Imporve FluContentDialog and add relative example.
2023-04-20 18:49:53 +08:00
c6db001b74 Imporve FluContentDialog and add relative example. 2023-04-20 18:10:45 +08:00
3ec0841b44 add FluPasswordBox 2023-04-20 14:56:09 +08:00
b3d1568de4 Merge pull request #62 from mentalfl0w/dev
Fix crash in macOS.
2023-04-20 11:24:54 +08:00
2511c5dba8 Fix crash in macOS. 2023-04-20 11:08:13 +08:00
3049be128f update 2023-04-20 11:06:24 +08:00
3291b3a882 update 2023-04-20 09:34:57 +08:00
d5744a39bd update 2023-04-20 09:15:28 +08:00
882606b2f6 update 2023-04-20 09:01:58 +08:00
aba33c4d1f update 2023-04-20 00:15:13 +08:00
51aef3f3ec update 2023-04-19 23:53:00 +08:00
221afeea58 Merge branch 'main' of https://github.com/zhuzichu520/FluentUI 2023-04-19 23:05:02 +08:00
c19f5d4c48 update 2023-04-19 23:04:56 +08:00
d2eb72cc5b Merge pull request #60 from mentalfl0w/dev
Add sync with system toggle switch and remove the deprecated warning.
2023-04-19 22:58:33 +08:00
420a9b2bbb Add sync with system toggle switch and remove the deprecated warning. 2023-04-19 22:27:27 +08:00
59dacd8fae update 2023-04-19 18:24:08 +08:00
7489a4bcbe update 2023-04-19 18:04:14 +08:00
6dd859dd1d update 2023-04-19 17:25:46 +08:00
98363542d3 update 2023-04-19 16:58:54 +08:00
5b836a4d82 update 2023-04-19 14:13:46 +08:00
7dcb65f7b6 update 2023-04-19 11:22:44 +08:00
203 changed files with 2588 additions and 1893 deletions

View File

@ -2,14 +2,19 @@ name: MacOS
on:
push:
paths:
- '*.pro'
- '*.txt'
- 'example/**'
- 'src/**'
- 'scripts/**'
- '.github/workflows/macos.yml'
pull_request:
paths:
- '*.pro'
- '*.txt'
- 'example/**'
- 'src/**'
- 'scripts/**'
- '.github/workflows/macos.yml'
jobs:
build:
name: Build
@ -22,12 +27,11 @@ jobs:
env:
targetName: example
steps:
- name: '⚙️ Cache Qt'
id: cache-qt
uses: actions/cache@v3
- name: Check out repository
uses: actions/checkout@v3
with:
path: ${{ runner.workspace }}/Qt
key: ${{runner.os}}-qtcachedir-${{ matrix.qt_ver }}
submodules: recursive
- name: Install Qt
uses: jurplel/install-qt-action@v3
with:
@ -35,24 +39,30 @@ jobs:
cache: ${{steps.cache-qt.outputs.cache-hit}}
arch: ${{ matrix.qt_arch }}
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
- uses: actions/checkout@v2
- name: Set up Ninja
uses: seanmiddleditch/gha-setup-ninja@v3
with:
fetch-depth: 1
version: 1.10.2
- name: build macos
run: |
qmake
make
# 打包
cmake --version
mkdir build
cd build
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=/Users/runner/work/FluentUI/Qt/6.4.3/macos -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -GNinja ..
cmake --build . --target all --config Release --parallel
- name: package
run: |
# 拷贝依赖
macdeployqt bin/release/${targetName}.app -qmldir=. -verbose=1 -dmg
# 上传artifacts
macdeployqt bin/release/${targetName}.app -qmldir=. -verbose=1 -dmg
- uses: actions/upload-artifact@v2
with:
name: ${{ env.targetName }}_${{ matrix.os }}_${{matrix.qt_ver}}.zip
path: bin/release/${{ env.targetName }}.app
# tag 上传Release
- name: uploadRelease
if: startsWith(github.event.ref, 'refs/tags/')
uses: svenstaro/upload-release-action@v2

View File

@ -1,17 +1,21 @@
name: Ubuntu
# Qt官方没有linux平台的x86包
on:
workflow_dispatch:
push:
paths:
- '*.pro'
- '*.txt'
- 'src/**'
- 'example/**'
- 'scripts/**'
- '.github/workflows/ubuntu.yml'
pull_request:
paths:
- '*.pro'
- '*.txt'
- 'src/**'
- '.github/workflows/ubuntu.yml'
- 'example/**'
- 'scripts/**'
- '.github/workflows/ubuntu.yml'
jobs:
build:
name: Build
@ -24,12 +28,11 @@ jobs:
env:
targetName: example
steps:
- name: '⚙️ Cache Qt'
id: cache-qt
uses: actions/cache@v3
- name: Check out repository
uses: actions/checkout@v3
with:
path: ${{ runner.workspace }}/Qt
key: ${{runner.os}}-qtcachedir-${{ matrix.qt_ver }}
submodules: recursive
- name: Install Qt
uses: jurplel/install-qt-action@v3
with:
@ -37,35 +40,45 @@ jobs:
cache: ${{steps.cache-qt.outputs.cache-hit}}
arch: ${{ matrix.qt_arch }}
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
- name: Set up Ninja
uses: seanmiddleditch/gha-setup-ninja@v3
with:
version: 1.10.2
- name: ubuntu install GL library
run: sudo apt-get install -y libxkbcommon-x11-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-xfixes0-dev libxcb-xinerama0-dev libxcb-sync-dev libxcb-render-util0-dev libxcb-shm0-dev
- uses: actions/checkout@v2
with:
fetch-depth: 1
- name: build ubuntu
run: |
qmake
make
ninja --version
cmake --version
mkdir build
cd build
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=/home/runner/work/FluentUI/Qt/6.4.3/gcc_64 -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Release -GNinja ..
cmake --build . --target all --config Release --parallel
- name: install QT linux deploy
uses: miurahr/install-linuxdeploy-action@v1
with:
plugins: qt appimage
- name: Check if svg file exists
run: if [ ! -f "${targetName}.svg" ]; then echo "File not found, creating..."; touch ${targetName}.svg; fi
# 打包
- name: package
run: |
# make sure Qt plugin finds QML sources so it can deploy the imported files
export QML_SOURCES_PATHS=src
export QML_SOURCES_PATHS=./
# 拷贝依赖
linuxdeploy-x86_64.AppImage --plugin=qt --output=appimage --create-desktop-file --icon-file=${targetName}.svg --executable=bin/release/${targetName} --appdir bin/release/
mv ${{ env.targetName }}-*.AppImage ${{ env.targetName }}.AppImage
# 上传artifacts
- uses: actions/upload-artifact@v2
with:
name: ${{ env.targetName }}_${{ matrix.os }}_${{matrix.qt_ver}}
path: ${{ env.targetName }}.AppImage
# tag 上传Release
- name: uploadRelease
if: startsWith(github.event.ref, 'refs/tags/')
uses: svenstaro/upload-release-action@v2

View File

@ -2,14 +2,19 @@ name: Windows MinGW
on:
push:
paths:
- '*.pro'
- '*.txt'
- 'src/**'
- 'example/**'
- 'scripts/**'
- '.github/workflows/windows-mingw.yml'
pull_request:
paths:
- '*.pro'
- '*.txt'
- 'example/**'
- 'src/**'
- '.github/workflows/windows-mingw.yml'
- 'scripts/**'
- '.github/workflows/windows-mingw.yml'
jobs:
build:
name: Build
@ -25,6 +30,11 @@ jobs:
targetName: example.exe
fileName: example
steps:
- name: Check out repository
uses: actions/checkout@v3
with:
submodules: recursive
- name: Install Qt
uses: jurplel/install-qt-action@v3
with:
@ -32,26 +42,29 @@ jobs:
arch: ${{ matrix.qt_arch }}
cache: ${{steps.cache-qt.outputs.cache-hit}}
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
- uses: actions/checkout@v2
with:
fetch-depth: 1
- name: Qt6 environment configuration
if: ${{ startsWith( matrix.qt_ver, 6 ) }}
shell: pwsh
run: |
Write-Output "${{ env.Qt6_DIR }}/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
Write-Output "${{ env.Qt6_DIR }}/../../Tools/${{ matrix.qt_tools_mingw_install }}/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: where is qmake & where is mingw32-make
- name: where is cmake & where is mingw32-make
shell: pwsh
run: |
Get-Command -Name 'qmake' | Format-List
Get-Command -Name 'cmake' | Format-List
Get-Command -Name 'mingw32-make' | Format-List
- name: mingw-build
id: build
shell: cmd
run: |
qmake
mingw32-make
mkdir build
cd build
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=D:\a\FluentUI\Qt\6.4.3\mingw_64 -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Release -GNinja ..
cmake --build . --target all --config Release --parallel
- name: package
id: package
env:
@ -61,10 +74,12 @@ jobs:
& scripts\windows-mingw-publish.ps1 ${env:archiveName} ${env:targetName}
$name = ${env:archiveName}
echo "::set-output name=packageName::$name"
- uses: actions/upload-artifact@v2
with:
name: ${{ steps.package.outputs.packageName }}
path: ${{ steps.package.outputs.packageName }}
- name: uploadRelease
if: startsWith(github.event.ref, 'refs/tags/')
uses: svenstaro/upload-release-action@v2

View File

@ -1,24 +1,25 @@
name: Windows
on:
# push代码时触发workflow
push:
paths:
- '*.pro'
- '*.txt'
- 'src/**'
- 'example/**'
- 'scripts/**'
- '.github/workflows/windows.yml'
pull_request:
paths:
- '*.pro'
- '*.txt'
- 'example/**'
- 'src/**'
- '.github/workflows/windows.yml'
- 'scripts/**'
- '.github/workflows/windows.yml'
jobs:
build:
name: Build
# 运行平台, windows-latest目前是windows server 2019
# 参考文档 https://github.com/actions/virtual-environments/blob/main/images/win/Windows2019-Readme.md
runs-on: ${{ matrix.os }}
strategy:
# 矩阵配置
matrix:
os: [windows-2019]
include:
@ -29,40 +30,34 @@ jobs:
env:
targetName: example.exe
fileName: example
# 步骤
steps:
- name: '⚙️ Cache Qt'
id: cache-qt
uses: actions/cache@v3
- name: Check out repository
uses: actions/checkout@v3
with:
path: ${{ runner.workspace }}\Qt
key: ${{runner.os}}-qtcachedir-${{ matrix.qt_ver }}
# 安装Qt
submodules: recursive
- name: Install Qt
# 使用外部action。这个action专门用来安装Qt
uses: jurplel/install-qt-action@v3
with:
version: ${{ matrix.qt_ver }}
arch: ${{ matrix.qt_arch }}
cache: ${{steps.cache-qt.outputs.cache-hit}}
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
# 拉取代码
- uses: actions/checkout@v2
with:
fetch-depth: 1
# msvc编译
- name: msvc-build
id: build
shell: cmd
run: |
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.msvc_arch }}
qmake
nmake
mkdir build
cd build
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=D:\a\FluentUI\Qt\6.4.3\msvc2019_64 -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl -DCMAKE_BUILD_TYPE=Release -GNinja ..
cmake --build . --target all --config Release --parallel
echo winSdkDir=%WindowsSdkDir% >> %GITHUB_ENV%
echo winSdkVer=%WindowsSdkVersion% >> %GITHUB_ENV%
echo vcToolsInstallDir=%VCToolsInstallDir% >> %GITHUB_ENV%
echo vcToolsRedistDir=%VCToolsRedistDir% >> %GITHUB_ENV%
# 打包
- name: package
id: package
env:
@ -73,14 +68,13 @@ jobs:
& scripts\windows-publish.ps1 ${env:archiveName} ${env:targetName}
# 记录packageName给后续step
$name = ${env:archiveName}
echo "::set-output name=packageName::$name"
# tag 查询github-Release
# 上传artifacts
echo "::set-output name=packageName::$name"
- uses: actions/upload-artifact@v2
with:
name: ${{ steps.package.outputs.packageName }}
path: ${{ steps.package.outputs.packageName }}
# tag 上传Release
- name: uploadRelease
if: startsWith(github.event.ref, 'refs/tags/')
uses: svenstaro/upload-release-action@v2

5
.gitignore vendored
View File

@ -33,4 +33,7 @@ CMakeLists.txt.user*
src/build-preset/plugins.qmltypes
bin
.DS_Store
.DS_Store
build
cmake-build-*
.idea

View File

@ -1,4 +1,5 @@
cmake_minimum_required(VERSION 3.16)
project(FluentUI VERSION 0.1 LANGUAGES CXX)
add_subdirectory(src)

View File

@ -1,6 +0,0 @@
TEMPLATE = subdirs
SUBDIRS += \
src/FluentUI.pro \
example
example.depends = src/FluentUI.pro

View File

@ -2,7 +2,7 @@
## 简介
这是一个漂亮的Fluent组件库使用QML插件开发的。main分支是Qt6.4.3如果需要qt5的请切换至qt5分支
这是一个漂亮的Fluent组件库使用QML插件开发的。main分支是Qt6.4.3<a href="https://github.com/zhuzichu520/FluentUI/wiki/%E6%96%B0%E6%89%8B%E5%85%A5%E9%97%A8" target="_blank">如何使用?</a>。如果需要qt5的请切换至qt5分支<a href="https://github.com/zhuzichu520/FluentUI/wiki/%E6%96%B0%E6%89%8B%E5%85%A5%E9%97%A8%EF%BC%881.2.7%E4%BB%A5%E5%8F%8A%E4%B9%8B%E5%89%8D%E7%89%88%E6%9C%AC%EF%BC%89" target="_blank">如何使用?</a>
## 编译状态
| [Windows][win-link]| [Ubuntu][ubuntu-link]|[MacOS][macos-link]|

View File

@ -1,26 +0,0 @@
import QtQuick
import QtQuick.Window
import QtQuick.Controls
import QtQuick.Layouts
import FluentUI
Window {
id:app
Component.onCompleted: {
FluApp.init(app)
FluTheme.frameless = ("windows" === Qt.platform.os)
FluTheme.dark = false
FluApp.routes = {
"/":"qrc:/page/MainPage.qml",
"/about":"qrc:/page/AboutPage.qml",
"/login":"qrc:/page/LoginPage.qml",
"/chat":"qrc:/page/ChatPage.qml",
"/media":"qrc:/page/MediaPage.qml",
"/singleTaskWindow":"qrc:/page/SingleTaskWindow.qml",
"/standardWindow":"qrc:/page/StandardWindow.qml",
"/singleInstanceWindow":"qrc:/page/SingleInstanceWindow.qml"
}
FluApp.initialRoute = "/"
FluApp.run()
}
}

View File

@ -1,56 +1,68 @@
cmake_minimum_required(VERSION 3.16)
project(example)
project(example VERSION 0.1 LANGUAGES CXX)
#配置通用编译
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(APPLE)
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
endif()
set(CMAKE_CXX_STANDARD 17)
#设置可执行文件输出目录
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/debug)
else()
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/release)
endif()
#获取文件路径分隔符(解决执行命令的时候有些平台会报错)
file(TO_CMAKE_PATH "/" PATH_SEPARATOR)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(platform 64)
else()
set(platform 32)
endif()
#设置版本号
add_definitions(-DVERSION=1,2,9,0)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../bin/debug)
else()
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../bin/release)
endif()
find_package(Qt6 REQUIRED COMPONENTS Quick REQUIRED)
find_package(Qt6 COMPONENTS Core Quick QuickControls2 Concurrent Network Multimedia REQUIRED)
#遍历所有Cpp文件
file(GLOB_RECURSE CPP_FILES *.cpp *.h)
foreach(filepath ${CPP_FILES})
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" filename ${filepath})
list(APPEND sources_files ${filename})
endforeach(filepath)
set(SOURCES
ChatController.cpp
AppInfo.cpp
main.cpp
)
#遍历所有qml文件
file(GLOB_RECURSE QML_PATHS *.qml)
foreach(filepath ${QML_PATHS})
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" filename ${filepath})
list(APPEND qml_files ${filename})
endforeach(filepath)
set(HEADERS
ChatController.h
AppInfo.h
)
#遍历所有资源文件
file(GLOB_RECURSE RES_PATHS *.png *.jpg *.svg *.ico *.ttf *.webp qmldir)
foreach(filepath ${RES_PATHS})
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" filename ${filepath})
list(APPEND resource_files ${filename})
endforeach(filepath)
set(RESOURCES
qml.qrc
)
set(RC_ICONS
favicon.ico
)
qt_add_resources(QT_RESOURCES ${RESOURCES})
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${QT_RESOURCES} ${RC_ICONS})
#添加可执行文件
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
qt_add_executable(example
${sources_files}
example.rc
)
else ()
qt_add_executable(example
${sources_files}
)
endif ()
#复制动态库到可执行文件同级目录下
if(WIN32)
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
set(DLLPATH ${CMAKE_CURRENT_SOURCE_DIR}/../third/msvc/*.dll)
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(DLLPATH ${CMAKE_SOURCE_DIR}/3rdparty/msvc/*.dll)
else()
set(DLLPATH ${CMAKE_CURRENT_SOURCE_DIR}/../third/mingw/*.dll)
set(DLLPATH ${CMAKE_SOURCE_DIR}/3rdparty/mingw/*.dll)
endif()
string(REPLACE "/" ${PATH_SEPARATOR} DLLPATH "${DLLPATH}")
file(GLOB DLL_FILES ${DLLPATH})
@ -61,27 +73,30 @@ if(WIN32)
)
endif()
target_compile_definitions(${PROJECT_NAME} PRIVATE
QT_DEPRECATED_WARNINGS
QT_NO_WARNING_OUTPUT
#添加qml模块
qt_add_qml_module(example
URI example
VERSION 1.0
QML_FILES ${qml_files}
RESOURCES ${resource_files}
)
target_link_libraries(${PROJECT_NAME} PRIVATE
Qt6::Core
#设置属性
set_target_properties(example PROPERTIES
MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)
#链接库
target_link_libraries(example PRIVATE
Qt6::Quick
Qt6::QuickControls2
Qt6::Concurrent
Qt6::Network
Qt6::Multimedia
fluentui
)
if(WIN32)
target_compile_definitions(${PROJECT_NAME} PRIVATE UNICODE WIN32 _WINDOWS)
target_link_libraries(${PROJECT_NAME} PRIVATE dwmapi user32)
endif()
if(APPLE)
set_target_properties(${PROJECT_NAME} PROPERTIES
MACOSX_BUNDLE_INFO_PLIST Info.plist
)
endif()
#安装
install(TARGETS example
BUNDLE DESTINATION .
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})

View File

@ -1,29 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>CFBundleExecutable</key>
<string>example</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>com.zhuzichu.example</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>LSMinimumSystemVersion</key>
<string>10.13</string>
<key>NOTE</key>
<string>This file was generated by Qt/QMake.</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
</dict>
</plist>

View File

@ -1,64 +0,0 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import FluentUI
import "./component"
FluScrollablePage{
title:"Dialog"
leftPadding:10
rightPadding:10
bottomPadding:20
spacing: 0
FluArea{
Layout.fillWidth: true
height: 68
paddings: 10
Layout.topMargin: 20
FluButton{
anchors.verticalCenter: parent.verticalCenter
Layout.topMargin: 20
text:"Show Dialog"
onClicked: {
dialog.open()
}
}
}
CodeExpander{
Layout.fillWidth: true
code:'FluContentDialog{
id:dialog
title:"友情提示"
message:"确定要退出程序么?"
negativeText:"取消"
onNegativeClicked:{
showSuccess("点击取消按钮")
}
positiveText:"确定"
onPositiveClicked:{
showSuccess("点击确定按钮")
}
}
dialog.open()
'
}
FluContentDialog{
id:dialog
title:"友情提示"
message:"确定要退出程序么?"
negativeText:"取消"
onNegativeClicked:{
showSuccess("点击取消按钮")
}
positiveText:"确定"
onPositiveClicked:{
showSuccess("点击确定按钮")
}
}
}

View File

@ -1,52 +0,0 @@
QT += quick quickcontrols2 concurrent network multimedia
CONFIG += c++17
DEFINES += QT_DEPRECATED_WARNINGS QT_NO_WARNING_OUTPUT
HEADERS += \
lang/En.h \
lang/Lang.h \
lang/Zh.h \
stdafx.h \
ChatController.h \
AppInfo.h
SOURCES += \
ChatController.cpp \
AppInfo.cpp \
lang/En.cpp \
lang/Lang.cpp \
lang/Zh.cpp \
main.cpp
RESOURCES += qml.qrc
RC_ICONS = favicon.ico
QML_IMPORT_PATH =
QML_DESIGNER_IMPORT_PATH =
CONFIG(debug,debug|release) {
DESTDIR = $$absolute_path($${_PRO_FILE_PWD_}/../bin/debug)
} else {
DESTDIR = $$absolute_path($${_PRO_FILE_PWD_}/../bin/release)
}
win32 {
contains(QMAKE_CC, cl) {
COPYDLL = $$absolute_path($${_PRO_FILE_PWD_}/../third/msvc/*.dll) $$DESTDIR
QMAKE_PRE_LINK += $$QMAKE_COPY $$replace(COPYDLL, /, $$QMAKE_DIR_SEP)
} else {
COPYDLL = $$absolute_path($${_PRO_FILE_PWD_}/../third/mingw/*.dll) $$DESTDIR
QMAKE_PRE_LINK += $$QMAKE_COPY $$replace(COPYDLL, /, $$QMAKE_DIR_SEP)
}
}
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
mac: {
QMAKE_INFO_PLIST = Info.plist
}

42
example/example.rc Normal file
View File

@ -0,0 +1,42 @@
#include <windows.h>
IDI_ICON1 ICON "favicon.ico"
#define STR(x) #x
#define VER_JOIN(a,b,c,d) STR(a.b.c.d)
#define VER_JOIN_(x) VER_JOIN x
#define VER_STR VER_JOIN_((VERSION))
VS_VERSION_INFO VERSIONINFO
FILEVERSION VERSION
PRODUCTVERSION VERSION
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS VS_FF_DEBUG
#else
FILEFLAGS 0x0L
#endif
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_APP
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "Built by the FluentUI."
VALUE "CompanyName", "zhuzichu"
VALUE "FileDescription", "example"
VALUE "FileVersion", VER_STR
VALUE "InternalName", ""
VALUE "LegalCopyright", "Copyright (C) 2023"
VALUE "OriginalFilename", ""
VALUE "ProductName", "example"
VALUE "ProductVersion", VER_STR
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

View File

@ -1,38 +0,0 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QDir>
#include <QQuickWindow>
#include <QQuickStyle>
#include <QProcess>
#include "lang/Lang.h"
#include "AppInfo.h"
#include "ChatController.h"
int main(int argc, char *argv[])
{
QCoreApplication::setOrganizationName("ZhuZiChu");
QCoreApplication::setOrganizationDomain("https://zhuzichu520.github.io");
QCoreApplication::setApplicationName("FluentUI");
QQuickStyle::setStyle("Basic");
QGuiApplication app(argc, argv);
app.setQuitOnLastWindowClosed(false);
QQmlApplicationEngine engine;
qmlRegisterType<ChatController>("Controller",1,0,"ChatController");
AppInfo* appInfo = new AppInfo();
QQmlContext * context = engine.rootContext();
Lang* lang = appInfo->lang();
context->setContextProperty("lang",lang);
QObject::connect(appInfo,&AppInfo::langChanged,&app,[context,appInfo]{
context->setContextProperty("lang",appInfo->lang());
});
context->setContextProperty("appInfo",appInfo);
const QUrl url(QStringLiteral("qrc:/App.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}

View File

@ -1,172 +0,0 @@
<RCC>
<qresource prefix="/">
<file>App.qml</file>
<file>res/image/image_huoyin.webp</file>
<file>res/svg/avatar_1.svg</file>
<file>res/svg/avatar_2.svg</file>
<file>res/svg/avatar_3.svg</file>
<file>res/svg/avatar_4.svg</file>
<file>res/svg/avatar_5.svg</file>
<file>res/svg/avatar_6.svg</file>
<file>res/svg/avatar_7.svg</file>
<file>res/svg/avatar_8.svg</file>
<file>res/svg/avatar_9.svg</file>
<file>res/svg/avatar_10.svg</file>
<file>res/svg/avatar_11.svg</file>
<file>res/svg/avatar_12.svg</file>
<file>page/AboutPage.qml</file>
<file>page/MainPage.qml</file>
<file>page/LoginPage.qml</file>
<file>T_ToggleSwitch.qml</file>
<file>T_Typography.qml</file>
<file>T_Awesome.qml</file>
<file>T_Buttons.qml</file>
<file>T_Rectangle.qml</file>
<file>T_InfoBar.qml</file>
<file>T_Progress.qml</file>
<file>T_Slider.qml</file>
<file>T_TextBox.qml</file>
<file>T_Theme.qml</file>
<file>T_Dialog.qml</file>
<file>T_TreeView.qml</file>
<file>T_Expander.qml</file>
<file>T_TimePicker.qml</file>
<file>T_DatePicker.qml</file>
<file>T_MultiWindow.qml</file>
<file>T_Menu.qml</file>
<file>res/image/banner_1.jpg</file>
<file>res/image/banner_2.jpg</file>
<file>res/image/banner_3.jpg</file>
<file>res/image/logo_openai.png</file>
<file>page/ChatPage.qml</file>
<file>T_Tooltip.qml</file>
<file>T_Badge.qml</file>
<file>T_CalendarPicker.qml</file>
<file>T_ColorPicker.qml</file>
<file>T_Carousel.qml</file>
<file>T_MediaPlayer.qml</file>
<file>T_TabView.qml</file>
<file>res/image/favicon.ico</file>
<file>T_Home.qml</file>
<file>res/image/bg_home_header.png</file>
<file>res/image/ic_home_github.png</file>
<file>res/image/control/Acrylic.png</file>
<file>res/image/control/AnimatedIcon.png</file>
<file>res/image/control/AnimatedVisualPlayer.png</file>
<file>res/image/control/AnimationInterop.png</file>
<file>res/image/control/AppBarButton.png</file>
<file>res/image/control/AppBarSeparator.png</file>
<file>res/image/control/AppBarToggleButton.png</file>
<file>res/image/control/AutomationProperties.png</file>
<file>res/image/control/AutoSuggestBox.png</file>
<file>res/image/control/Border.png</file>
<file>res/image/control/BreadcrumbBar.png</file>
<file>res/image/control/Button.png</file>
<file>res/image/control/CalendarDatePicker.png</file>
<file>res/image/control/CalendarView.png</file>
<file>res/image/control/Canvas.png</file>
<file>res/image/control/Checkbox.png</file>
<file>res/image/control/Clipboard.png</file>
<file>res/image/control/ColorPaletteResources.png</file>
<file>res/image/control/ColorPicker.png</file>
<file>res/image/control/ComboBox.png</file>
<file>res/image/control/CommandBar.png</file>
<file>res/image/control/CommandBarFlyout.png</file>
<file>res/image/control/CompactSizing.png</file>
<file>res/image/control/ConnectedAnimation.png</file>
<file>res/image/control/ContentDialog.png</file>
<file>res/image/control/CreateMultipleWindows.png</file>
<file>res/image/control/DataGrid.png</file>
<file>res/image/control/DatePicker.png</file>
<file>res/image/control/DropDownButton.png</file>
<file>res/image/control/EasingFunction.png</file>
<file>res/image/control/Expander.png</file>
<file>res/image/control/FilePicker.png</file>
<file>res/image/control/FlipView.png</file>
<file>res/image/control/Flyout.png</file>
<file>res/image/control/Grid.png</file>
<file>res/image/control/GridView.png</file>
<file>res/image/control/HyperlinkButton.png</file>
<file>res/image/control/IconElement.png</file>
<file>res/image/control/Image.png</file>
<file>res/image/control/ImplicitTransition.png</file>
<file>res/image/control/InfoBadge.png</file>
<file>res/image/control/InfoBar.png</file>
<file>res/image/control/InkCanvas.png</file>
<file>res/image/control/InkToolbar.png</file>
<file>res/image/control/InputValidation.png</file>
<file>res/image/control/ItemsRepeater.png</file>
<file>res/image/control/Line.png</file>
<file>res/image/control/ListBox.png</file>
<file>res/image/control/ListView.png</file>
<file>res/image/control/MediaPlayerElement.png</file>
<file>res/image/control/MenuBar.png</file>
<file>res/image/control/MenuFlyout.png</file>
<file>res/image/control/NavigationView.png</file>
<file>res/image/control/NumberBox.png</file>
<file>res/image/control/PageTransition.png</file>
<file>res/image/control/ParallaxView.png</file>
<file>res/image/control/PasswordBox.png</file>
<file>res/image/control/PersonPicture.png</file>
<file>res/image/control/PipsPager.png</file>
<file>res/image/control/Pivot.png</file>
<file>res/image/control/ProgressBar.png</file>
<file>res/image/control/ProgressRing.png</file>
<file>res/image/control/PullToRefresh.png</file>
<file>res/image/control/RadialGradientBrush.png</file>
<file>res/image/control/RadioButton.png</file>
<file>res/image/control/RadioButtons.png</file>
<file>res/image/control/RatingControl.png</file>
<file>res/image/control/RelativePanel.png</file>
<file>res/image/control/RepeatButton.png</file>
<file>res/image/control/RevealFocus.png</file>
<file>res/image/control/RichEditBox.png</file>
<file>res/image/control/RichTextBlock.png</file>
<file>res/image/control/ScrollViewer.png</file>
<file>res/image/control/SemanticZoom.png</file>
<file>res/image/control/Shape.png</file>
<file>res/image/control/Slider.png</file>
<file>res/image/control/Sound.png</file>
<file>res/image/control/SplitButton.png</file>
<file>res/image/control/SplitView.png</file>
<file>res/image/control/StackPanel.png</file>
<file>res/image/control/StandardUICommand.png</file>
<file>res/image/control/SwipeControl.png</file>
<file>res/image/control/TabView.png</file>
<file>res/image/control/TeachingTip.png</file>
<file>res/image/control/TextBlock.png</file>
<file>res/image/control/TextBox.png</file>
<file>res/image/control/ThemeTransition.png</file>
<file>res/image/control/TimePicker.png</file>
<file>res/image/control/TitleBar.png</file>
<file>res/image/control/ToggleButton.png</file>
<file>res/image/control/ToggleSplitButton.png</file>
<file>res/image/control/ToggleSwitch.png</file>
<file>res/image/control/ToolTip.png</file>
<file>res/image/control/TreeView.png</file>
<file>res/image/control/VariableSizedWrapGrid.png</file>
<file>res/image/control/Viewbox.png</file>
<file>res/image/control/WebView.png</file>
<file>res/image/control/XamlUICommand.png</file>
<file>T_CheckBox.qml</file>
<file>global/ItemsOriginal.qml</file>
<file>global/qmldir</file>
<file>global/ItemsFooter.qml</file>
<file>page/MediaPage.qml</file>
<file>T_FlipView.qml</file>
<file>T_Pivot.qml</file>
<file>component/CodeExpander.qml</file>
<file>T_TableView.qml</file>
<file>T_StatusView.qml</file>
<file>T_Settings.qml</file>
<file>global/MainEvent.qml</file>
<file>res/svg/home.svg</file>
<file>res/svg/home_dark.svg</file>
<file>page/StandardWindow.qml</file>
<file>page/SingleTaskWindow.qml</file>
<file>page/SingleInstanceWindow.qml</file>
<file>T_RatingControl.qml</file>
<file>res/image/qrcode_wx.jpg</file>
<file>res/image/qrcode_zfb.jpg</file>
</qresource>
</RCC>

26
example/qml/App.qml Normal file
View File

@ -0,0 +1,26 @@
import QtQuick
import QtQuick.Window
import QtQuick.Controls
import QtQuick.Layouts
import FluentUI
Window {
id:app
Component.onCompleted: {
FluApp.init(app)
FluTheme.frameless = ("windows" === Qt.platform.os)
FluTheme.darkMode = FluDarkMode.System
FluApp.routes = {
"/":"qrc:/example/qml/window/MainWindow.qml",
"/about":"qrc:/example/qml/window/AboutWindow.qml",
"/login":"qrc:/example/qml/window/LoginWindow.qml",
"/chat":"qrc:/example/qml/window/ChatWindow.qml",
"/media":"qrc:/example/qml/window/MediaWindow.qml",
"/singleTaskWindow":"qrc:/example/qml/window/SingleTaskWindow.qml",
"/standardWindow":"qrc:/example/qml/window/StandardWindow.qml",
"/singleInstanceWindow":"qrc:/example/qml/window/SingleInstanceWindow.qml"
}
FluApp.initialRoute = "/"
FluApp.run()
}
}

View File

@ -36,7 +36,7 @@ FluExpander{
topMargin: 5
}
onClicked:{
FluApp.clipText(content.text)
FluTools.clipText(content.text)
showSuccess("复制成功")
}
}
@ -68,7 +68,6 @@ FluExpander{
"FluComboBox",
"FluContentDialog",
"FluContentPage",
"FluControl",
"FluDatePicker",
"FluDivider",
"FluDropDownButton",
@ -119,7 +118,9 @@ FluExpander{
"FluColors",
"FluTheme",
"FluStatusView",
"FluRatingControl"
"FluRatingControl",
"FluPasswordBox",
"FluBreadcrumbBar"
];
code = code.replace(/\n/g, "<br>");
code = code.replace(/ /g, "&nbsp;");

View File

@ -20,7 +20,7 @@ FluObject{
title:lang.settings
icon:FluentIcons.Settings
onTap:{
navigationView.push("qrc:/T_Settings.qml")
navigationView.push("qrc:/example/qml/page/T_Settings.qml")
}
}
}

View File

@ -12,13 +12,13 @@ FluObject{
// icon:FluentIcons.Home
cusIcon: Image{
anchors.centerIn: parent
source: FluTheme.dark ? "qrc:/res/svg/home_dark.svg" : "qrc:/res/svg/home.svg"
source: FluTheme.dark ? "qrc:/example/res/svg/home_dark.svg" : "qrc:/example/res/svg/home.svg"
sourceSize: Qt.size(30,30)
width: 18
height: 18
}
onTap:{
navigationView.push("qrc:/T_Home.qml")
navigationView.push("qrc:/example/qml/page/T_Home.qml")
}
}
@ -27,35 +27,35 @@ FluObject{
icon:FluentIcons.CheckboxComposite
FluPaneItem{
title:"Buttons"
image:"qrc:/res/image/control/Button.png"
image:"qrc:/example/res/image/control/Button.png"
recentlyUpdated:true
desc:"A control that responds to user input and raisesa Click event."
onTap:{
navigationView.push("qrc:/T_Buttons.qml")
navigationView.push("qrc:/example/qml/page/T_Buttons.qml")
}
}
FluPaneItem{
title:"Slider"
image:"qrc:/res/image/control/Slider.png"
image:"qrc:/example/res/image/control/Slider.png"
recentlyUpdated:true
desc:"A control that lets the user select from a rangeof values by moving a Thumb control along atrack."
onTap:{
navigationView.push("qrc:/T_Slider.qml")
navigationView.push("qrc:/example/qml/page/T_Slider.qml")
}
}
FluPaneItem{
title:"CheckBox"
image:"qrc:/res/image/control/Checkbox.png"
image:"qrc:/example/res/image/control/Checkbox.png"
recentlyUpdated:true
desc:"A control that a user can select or clear."
onTap:{
navigationView.push("qrc:/T_CheckBox.qml")
navigationView.push("qrc:/example/qml/page/T_CheckBox.qml")
}
}
FluPaneItem{
title:"ToggleSwitch"
onTap:{
navigationView.push("qrc:/T_ToggleSwitch.qml")
navigationView.push("qrc:/example/qml/page/T_ToggleSwitch.qml")
}
}
}
@ -66,31 +66,31 @@ FluObject{
FluPaneItem{
title:"TextBox"
onTap:{
navigationView.push("qrc:/T_TextBox.qml")
navigationView.push("qrc:/example/qml/page/T_TextBox.qml")
}
}
FluPaneItem{
title:"TimePicker"
onTap:{
navigationView.push("qrc:/T_TimePicker.qml")
navigationView.push("qrc:/example/qml/page/T_TimePicker.qml")
}
}
FluPaneItem{
title:"DatePicker"
onTap:{
navigationView.push("qrc:/T_DatePicker.qml")
navigationView.push("qrc:/example/qml/page/T_DatePicker.qml")
}
}
FluPaneItem{
title:"CalendarPicker"
onTap:{
navigationView.push("qrc:/T_CalendarPicker.qml")
navigationView.push("qrc:/example/qml/page/T_CalendarPicker.qml")
}
}
FluPaneItem{
title:"ColorPicker"
onTap:{
navigationView.push("qrc:/T_ColorPicker.qml")
navigationView.push("qrc:/example/qml/page/T_ColorPicker.qml")
}
}
}
@ -100,53 +100,53 @@ FluObject{
icon:FluentIcons.SurfaceHub
FluPaneItem{
title:"InfoBar"
image:"qrc:/res/image/control/InfoBar.png"
image:"qrc:/example/res/image/control/InfoBar.png"
recentlyUpdated:true
desc:"An inline message to display app-wide statuschange information."
onTap:{
navigationView.push("qrc:/T_InfoBar.qml")
navigationView.push("qrc:/example/qml/page/T_InfoBar.qml")
}
}
FluPaneItem{
title:"Progress"
onTap:{
navigationView.push("qrc:/T_Progress.qml")
navigationView.push("qrc:/example/qml/page/T_Progress.qml")
}
}
FluPaneItem{
title:"RatingControl"
onTap:{
navigationView.push("qrc:/T_RatingControl.qml")
navigationView.push("qrc:/example/qml/page/T_RatingControl.qml")
}
}
FluPaneItem{
title:"Badge"
onTap:{
navigationView.push("qrc:/T_Badge.qml")
navigationView.push("qrc:/example/qml/page/T_Badge.qml")
}
}
FluPaneItem{
title:"Rectangle"
onTap:{
navigationView.push("qrc:/T_Rectangle.qml")
navigationView.push("qrc:/example/qml/page/T_Rectangle.qml")
}
}
FluPaneItem{
title:"StatusView"
onTap:{
navigationView.push("qrc:/T_StatusView.qml")
navigationView.push("qrc:/example/qml/page/T_StatusView.qml")
}
}
FluPaneItem{
title:"Carousel"
onTap:{
navigationView.push("qrc:/T_Carousel.qml")
navigationView.push("qrc:/example/qml/page/T_Carousel.qml")
}
}
FluPaneItem{
title:"Expander"
onTap:{
navigationView.push("qrc:/T_Expander.qml")
navigationView.push("qrc:/example/qml/page/T_Expander.qml")
}
}
}
@ -157,19 +157,19 @@ FluObject{
FluPaneItem{
title:"Dialog"
onTap:{
navigationView.push("qrc:/T_Dialog.qml")
navigationView.push("qrc:/example/qml/page/T_Dialog.qml")
}
}
FluPaneItem{
title:"Tooltip"
onTap:{
navigationView.push("qrc:/T_Tooltip.qml")
navigationView.push("qrc:/example/qml/page/T_Tooltip.qml")
}
}
FluPaneItem{
title:"Menu"
onTap:{
navigationView.push("qrc:/T_Menu.qml")
navigationView.push("qrc:/example/qml/page/T_Menu.qml")
}
}
}
@ -179,54 +179,60 @@ FluObject{
icon:FluentIcons.AllApps
FluPaneItem{
title:"Pivot"
image:"qrc:/res/image/control/Pivot.png"
image:"qrc:/example/res/image/control/Pivot.png"
recentlyAdded:true
order:3
desc:"Presents information from different sources in atabbed view."
onTap:{
navigationView.push("qrc:/T_Pivot.qml")
navigationView.push("qrc:/example/qml/page/T_Pivot.qml")
}
}
FluPaneItem{
title:"BreadcrumbBar"
onTap:{
navigationView.push("qrc:/example/qml/page/T_BreadcrumbBar.qml")
}
}
FluPaneItem{
title:"TabView"
image:"qrc:/res/image/control/TabView.png"
image:"qrc:/example/res/image/control/TabView.png"
recentlyAdded:true
order:1
desc:"A control that displays a collection of tabs thatcan be used to display several documents."
onTap:{
navigationView.push("qrc:/T_TabView.qml")
navigationView.push("qrc:/example/qml/page/T_TabView.qml")
}
}
FluPaneItem{
title:"TreeView"
onTap:{
navigationView.push("qrc:/T_TreeView.qml")
navigationView.push("qrc:/example/qml/page/T_TreeView.qml")
}
}
FluPaneItem{
title:"TableView"
image:"qrc:/res/image/control/DataGrid.png"
image:"qrc:/example/res/image/control/DataGrid.png"
recentlyAdded:true
order:4
desc:"The TableView control provides a flexible way to display a collection of data in rows and columns"
onTap:{
navigationView.push("qrc:/T_TableView.qml")
navigationView.push("qrc:/example/qml/page/T_TableView.qml")
}
}
FluPaneItem{
title:"MultiWindow"
onTap:{
navigationView.push("qrc:/T_MultiWindow.qml")
navigationView.push("qrc:/example/qml/page/T_MultiWindow.qml")
}
}
FluPaneItem{
title:"FlipView"
image:"qrc:/res/image/control/FlipView.png"
image:"qrc:/example/res/image/control/FlipView.png"
recentlyAdded:true
order:2
desc:"Presents a collection of items that the user canflip through, one item at a time."
onTap:{
navigationView.push("qrc:/T_FlipView.qml")
navigationView.push("qrc:/example/qml/page/T_FlipView.qml")
}
}
}
@ -237,19 +243,19 @@ FluObject{
FluPaneItem{
title:"Theme"
onTap:{
navigationView.push("qrc:/T_Theme.qml")
navigationView.push("qrc:/example/qml/page/T_Theme.qml")
}
}
FluPaneItem{
title:"Typography"
onTap:{
navigationView.push("qrc:/T_Typography.qml")
navigationView.push("qrc:/example/qml/page/T_Typography.qml")
}
}
FluPaneItem{
title:"Awesome"
onTap:{
navigationView.push("qrc:/T_Awesome.qml")
navigationView.push("qrc:/example/qml/page/T_Awesome.qml")
}
}
}
@ -259,12 +265,12 @@ FluObject{
icon:FluentIcons.Media
FluPaneItem{
title:"MediaPlayer"
image:"qrc:/res/image/control/MediaPlayerElement.png"
image:"qrc:/example/res/image/control/MediaPlayerElement.png"
recentlyAdded:true
order:0
desc:"A control to display video and image content."
onTap:{
navigationView.push("qrc:/T_MediaPlayer.qml")
navigationView.push("qrc:/example/qml/page/T_MediaPlayer.qml")
}
}
}

View File

@ -55,7 +55,7 @@ FluContentPage {
anchors.horizontalCenter: parent.horizontalCenter
onClicked: {
var text ="FluentIcons."+modelData.name;
FluApp.clipText(text)
FluTools.clipText(text)
showSuccess("您复制了 "+text)
}
}

View File

@ -3,7 +3,7 @@ import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -103,6 +103,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'Rectangle{
width: 40
height: 40

View File

@ -0,0 +1,98 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Window
import FluentUI
import "../component"
FluScrollablePage{
title:"BreadcurmbBar"
leftPadding:10
rightPadding:10
bottomPadding:20
spacing: 0
Component.onCompleted: {
var items = []
for(var i=0;i<10;i++){
items.push({title:"Item_"+(i+1)})
}
breadcrumb_1.items = items
breadcrumb_2.items = items
}
FluArea{
Layout.fillWidth: true
height: 68
paddings: 10
Layout.topMargin: 20
FluBreadcrumbBar{
id:breadcrumb_1
width:parent.width
anchors.verticalCenter: parent.verticalCenter
onClickItem:
(model)=>{
showSuccess(model.title)
}
}
}
FluArea{
Layout.fillWidth: true
height: 100
paddings: 10
Layout.topMargin: 20
ColumnLayout{
anchors.verticalCenter: parent.verticalCenter
width:parent.width
spacing: 10
FluFilledButton{
text:"Reset sample"
onClicked:{
var items = []
for(var i=0;i<10;i++){
items.push({title:"Item_"+(i+1)})
}
breadcrumb_2.items = items
}
}
FluBreadcrumbBar{
id:breadcrumb_2
separator:">"
spacing:8
textSize:18
Layout.fillWidth: true
onClickItem:
(model)=>{
//不是点击最后一个item元素
if(model.index+1!==count()){
breadcrumb_2.remove(model.index+1,count()-model.index-1)
}
showSuccess(model.title)
}
}
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluBreadcrumbBar{
width:parent.width
separator:">"
spacing:8
textSize:18
onClickItem: (model)=>{
}
}'
}
}

View File

@ -2,8 +2,9 @@
import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import QtQuick.Controls.Basic
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
title:"Buttons"
@ -51,6 +52,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluTextButton{
text:"Text Button"
onClicked: {
@ -92,6 +94,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluButton{
text:"Standard Button"
onClicked: {
@ -133,6 +136,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluFilledButton{
text:"Filled Button"
onClicked: {
@ -174,6 +178,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluToggleButton{
text:"Toggle Button"
onClicked: {
@ -216,6 +221,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluIconButton{
iconSource:FluentIcons.ChromeCloseContrast
onClicked: {
@ -266,6 +272,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluDropDownButton{
text:"DropDownButton"
items:[
@ -327,6 +334,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluRadioButton{
selected:true
text:"Text Button"
@ -365,6 +373,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluCheckBox{
text:"Check Box"
}'

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Window
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -23,6 +23,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluCalendarView{
}'
@ -44,6 +45,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluCalendarPicker{
}'

View File

@ -3,7 +3,7 @@ import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -32,18 +32,19 @@ FluScrollablePage{
Layout.topMargin: 20
Layout.leftMargin: 5
Component.onCompleted: {
carousel.setData([{url:"qrc:/res/image/banner_1.jpg"},{url:"qrc:/res/image/banner_2.jpg"},{url:"qrc:/res/image/banner_3.jpg"}])
carousel.setData([{url:"qrc:/example/res/image/banner_1.jpg"},{url:"qrc:/example/res/image/banner_2.jpg"},{url:"qrc:/example/res/image/banner_3.jpg"}])
}
}
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluCarousel{
width: 400
height: 300
Component.onCompleted: {
setData([{url:"qrc:/res/image/banner_1.jpg"},{url:"qrc:/res/image/banner_2.jpg"},{url:"qrc:/res/image/banner_3.jpg"}])
setData([{url:"qrc:/example/res/image/banner_1.jpg"},{url:"qrc:/example/res/image/banner_2.jpg"},{url:"qrc:/example/res/image/banner_3.jpg"}])
}
}'
}

View File

@ -3,7 +3,7 @@ import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -30,6 +30,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluCheckBox{
text:"Text"
}'

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Window
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -41,6 +41,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluColorView{
}'
@ -64,6 +65,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluColorPicker{
}'

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Window
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -32,6 +32,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluDatePicker{
}'
@ -59,6 +60,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluDatePicker{
showYear:false
}'

View File

@ -0,0 +1,122 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import FluentUI
import "../component"
FluScrollablePage{
title:"Dialog"
leftPadding:10
rightPadding:10
bottomPadding:20
spacing: 0
FluArea{
Layout.fillWidth: true
height: 68
paddings: 10
Layout.topMargin: 20
FluButton{
anchors.verticalCenter: parent.verticalCenter
Layout.topMargin: 20
text:"Show Double Button Dialog"
onClicked: {
double_btn_dialog.open()
}
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluContentDialog{
id:dialog
title:"友情提示"
message:"确定要退出程序么?"
negativeText:"取消"
buttonFlags: FluContentDialog.NegativeButton | FluContentDialog.PositiveButton
onNegativeClicked:{
showSuccess("点击取消按钮")
}
positiveText:"确定"
onPositiveClicked:{
showSuccess("点击确定按钮")
}
}
dialog.open()'
}
FluContentDialog{
id:double_btn_dialog
title:"友情提示"
message:"确定要退出程序么?"
buttonFlags: FluContentDialog.NegativeButton | FluContentDialog.PositiveButton
negativeText:"取消"
onNegativeClicked:{
showSuccess("点击取消按钮")
}
positiveText:"确定"
onPositiveClicked:{
showSuccess("点击确定按钮")
}
}
FluArea{
Layout.fillWidth: true
height: 68
paddings: 10
Layout.topMargin: 20
FluButton{
anchors.verticalCenter: parent.verticalCenter
Layout.topMargin: 20
text:"Show Triple Button Dialog"
onClicked: {
triple_btn_dialog.open()
}
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluContentDialog{
id:dialog
title:"友情提示"
message:"确定要退出程序么?"
negativeText:"取消"
buttonFlags: FluContentDialog.NeutralButton | FluContentDialog.NegativeButton | FluContentDialog.PositiveButton
negativeText:"取消"
onNegativeClicked:{
showSuccess("点击取消按钮")
}
positiveText:"确定"
onPositiveClicked:{
showSuccess("点击确定按钮")
}
neutralText:"最小化"
onNeutralClicked:{
showSuccess("点击最小化按钮")
}
}
dialog.open()'
}
FluContentDialog{
id:triple_btn_dialog
title:"友情提示"
message:"确定要退出程序么?"
buttonFlags: FluContentDialog.NeutralButton | FluContentDialog.NegativeButton | FluContentDialog.PositiveButton
negativeText:"取消"
onNegativeClicked:{
showSuccess("点击取消按钮")
}
positiveText:"确定"
onPositiveClicked:{
showSuccess("点击确定按钮")
}
neutralText:"最小化"
onNeutralClicked:{
showSuccess("点击最小化按钮")
}
}
}

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Window
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -15,14 +15,14 @@ FluScrollablePage{
FluArea{
Layout.fillWidth: true
height: layout_column.height+40
height: layout_column.height+20
paddings: 10
Layout.topMargin: 20
Column{
id:layout_column
spacing: 15
anchors{
verticalCenter: parent.verticalCenter
top:parent.top
left:parent.left
}
@ -77,12 +77,12 @@ FluScrollablePage{
}
}
}
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluExpander{
headerText:"打开一个单选框"
Item{

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Window
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -25,17 +25,17 @@ FluScrollablePage{
}
FluFlipView{
Image{
source: "qrc:/res/image/banner_1.jpg"
source: "qrc:/example/res/image/banner_1.jpg"
asynchronous: true
fillMode:Image.PreserveAspectCrop
}
Image{
source: "qrc:/res/image/banner_2.jpg"
source: "qrc:/example/res/image/banner_2.jpg"
asynchronous: true
fillMode:Image.PreserveAspectCrop
}
Image{
source: "qrc:/res/image/banner_3.jpg"
source: "qrc:/example/res/image/banner_3.jpg"
asynchronous: true
fillMode:Image.PreserveAspectCrop
}
@ -44,19 +44,20 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluFlipView{
Image{
source: "qrc:/res/image/banner_1.jpg"
source: "qrc:/example/res/image/banner_1.jpg"
asynchronous: true
fillMode:Image.PreserveAspectCrop
}
Image{
source: "qrc:/res/image/banner_1.jpg"
source: "qrc:/example/res/image/banner_1.jpg"
asynchronous: true
fillMode:Image.PreserveAspectCrop
}
Image{
source: "qrc:/res/image/banner_1.jpg"
source: "qrc:/example/res/image/banner_1.jpg"
asynchronous: true
fillMode:Image.PreserveAspectCrop
}
@ -77,18 +78,18 @@ FluScrollablePage{
FluFlipView{
vertical:true
Image{
source: "qrc:/res/image/banner_1.jpg"
source: "qrc:/example/res/image/banner_1.jpg"
asynchronous: true
sourceSize: Qt.size(400,300)
fillMode:Image.PreserveAspectCrop
}
Image{
source: "qrc:/res/image/banner_2.jpg"
source: "qrc:/example/res/image/banner_2.jpg"
asynchronous: true
fillMode:Image.PreserveAspectCrop
}
Image{
source: "qrc:/res/image/banner_3.jpg"
source: "qrc:/example/res/image/banner_3.jpg"
asynchronous: true
fillMode:Image.PreserveAspectCrop
}
@ -97,20 +98,21 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluFlipView{
vertical:true
Image{
source: "qrc:/res/image/banner_1.jpg"
source: "qrc:/example/res/image/banner_1.jpg"
asynchronous: true
fillMode:Image.PreserveAspectCrop
}
Image{
source: "qrc:/res/image/banner_1.jpg"
source: "qrc:/example/res/image/banner_1.jpg"
asynchronous: true
fillMode:Image.PreserveAspectCrop
}
Image{
source: "qrc:/res/image/banner_1.jpg"
source: "qrc:/example/res/image/banner_1.jpg"
asynchronous: true
fillMode:Image.PreserveAspectCrop
}

View File

@ -2,7 +2,7 @@
import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import "qrc:///global/"
import "qrc:///example/qml/global/"
import FluentUI
FluScrollablePage{
@ -15,7 +15,7 @@ FluScrollablePage{
ListModel{
id:model_header
ListElement{
icon:"qrc:/res/image/ic_home_github.png"
icon:"qrc:/example/res/image/ic_home_github.png"
title:"FluentUI GitHub"
desc:"The latest FluentUI controls and styles for your applications."
url:"https://github.com/zhuzichu520/FluentUI"
@ -30,7 +30,7 @@ FluScrollablePage{
fillMode:Image.PreserveAspectCrop
anchors.fill: parent
verticalAlignment: Qt.AlignTop
source: "qrc:/res/image/bg_home_header.png"
source: "qrc:/example/res/image/bg_home_header.png"
}
Rectangle{
anchors.fill: parent

View File

@ -3,7 +3,7 @@ import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -52,6 +52,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'showInfo("这是一个Info样式的InfoBar")
showWarning("这是一个Warning样式的InfoBar")

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Window
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -38,6 +38,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluMediaPlayer{
id:player
source:"http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"

View File

@ -3,7 +3,7 @@ import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -53,6 +53,7 @@ FluScrollablePage{
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluMenu{
id:menu
FluMenuItem:{

View File

@ -3,12 +3,12 @@ import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
property string password: ""
property var loginPageRegister: registerForPageResult("/login")
property var loginPageRegister: registerForWindowResult("/login")
title:"MultiWindow"
leftPadding:10
@ -95,6 +95,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluWindow{
//launchMode: FluWindow.Standard
//launchMode: FluWindow.SingleTask
@ -128,6 +129,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluButton{
text:"点击跳转"
onClicked: {
@ -165,7 +167,8 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
code:'property var loginPageRegister: registerForPageResult("/login")
Layout.topMargin: -1
code:'property var loginPageRegister: registerForWindowResult("/login")
Connections{
target: loginPageRegister

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Window
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -50,6 +50,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluPivot{
anchors.fill: parent
FluPivotItem:{

View File

@ -3,7 +3,7 @@ import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -47,6 +47,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluProgressBar{
}

View File

@ -3,7 +3,7 @@ import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -34,6 +34,7 @@ FluScrollablePage{
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluRatingControl{
}'

View File

@ -3,7 +3,7 @@ import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Window
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -79,7 +79,7 @@ FluScrollablePage{
Image {
asynchronous: true
anchors.fill: parent
source: "qrc:/res/svg/avatar_1.svg"
source: "qrc:/example/res/svg/avatar_1.svg"
sourceSize: Qt.size(width,height)
}
}
@ -91,7 +91,7 @@ FluScrollablePage{
asynchronous: true
anchors.fill: parent
sourceSize: Qt.size(width,height)
source: "qrc:/res/svg/avatar_2.svg"
source: "qrc:/example/res/svg/avatar_2.svg"
}
}
FluRectangle{
@ -102,7 +102,7 @@ FluScrollablePage{
asynchronous: true
anchors.fill: parent
sourceSize: Qt.size(width,height)
source: "qrc:/res/svg/avatar_3.svg"
source: "qrc:/example/res/svg/avatar_3.svg"
}
}
FluRectangle{
@ -113,7 +113,7 @@ FluScrollablePage{
asynchronous: true
anchors.fill: parent
sourceSize: Qt.size(width,height)
source: "qrc:/res/svg/avatar_4.svg"
source: "qrc:/example/res/svg/avatar_4.svg"
}
}
}
@ -123,7 +123,7 @@ FluScrollablePage{
radius:[25,25,25,25]
Image {
asynchronous: true
source: "qrc:/res/image/image_huoyin.webp"
source: "qrc:/example/res/image/image_huoyin.webp"
anchors.fill: parent
sourceSize: Qt.size(width,height)
}
@ -134,6 +134,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluRectangle{
radius: [25,25,25,25]
width: 50
@ -141,7 +142,7 @@ FluScrollablePage{
Image{
asynchronous: true
anchors.fill: parent
source: "qrc:/res/svg/avatar_4.svg"
source: "qrc:/example/res/svg/avatar_4.svg"
sourceSize: Qt.size(width,height)
}
}'

View File

@ -3,8 +3,8 @@ import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import FluentUI
import "qrc:///global/"
import "./component"
import "qrc:///example/qml/global/"
import "../component"
FluScrollablePage{
@ -14,6 +14,39 @@ FluScrollablePage{
bottomPadding:20
spacing: 0
FluArea{
Layout.fillWidth: true
Layout.topMargin: 20
height: 136
paddings: 10
ColumnLayout{
spacing: 10
anchors{
top: parent.top
left: parent.left
}
FluText{
text:lang.dark_mode
fontStyle: FluText.BodyStrong
Layout.bottomMargin: 4
}
Repeater{
model: [{title:"System",mode:FluDarkMode.System},{title:"Light",mode:FluDarkMode.Light},{title:"Dark",mode:FluDarkMode.Dark}]
delegate: FluRadioButton{
selected : FluTheme.darkMode === modelData.mode
text:modelData.title
onClicked:{
FluTheme.darkMode = modelData.mode
}
}
}
}
}
FluArea{
Layout.fillWidth: true
Layout.topMargin: 20
@ -32,9 +65,7 @@ FluScrollablePage{
fontStyle: FluText.BodyStrong
Layout.bottomMargin: 4
}
Repeater{
id:repeater
model: [{title:"Open",mode:FluNavigationView.Open},{title:"Compact",mode:FluNavigationView.Compact},{title:"Minimal",mode:FluNavigationView.Minimal},{title:"Auto",mode:FluNavigationView.Auto}]
delegate: FluRadioButton{
selected : MainEvent.displayMode===modelData.mode
@ -45,13 +76,12 @@ FluScrollablePage{
}
}
}
}
FluArea{
Layout.fillWidth: true
Layout.topMargin: 20
height: 168
height: 80
paddings: 10
ColumnLayout{
@ -82,7 +112,6 @@ FluScrollablePage{
}
}
}
}
}

View File

@ -2,7 +2,7 @@
import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import "./component"
import "../component"
import FluentUI
FluScrollablePage{
@ -25,6 +25,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluSlider{
value:50
}'
@ -46,6 +47,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluSlider{
vertical:true
value:50

View File

@ -3,7 +3,7 @@ import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Window
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -78,6 +78,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluStatusView{
anchors.fill: parent
statusMode: FluStatusView.Loading

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Window
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -24,7 +24,7 @@ FluScrollablePage{
}
function newTab(){
tab_view.appendTab("qrc:/res/image/favicon.ico","Document "+tab_view.count(),com_page,colors[Math.floor(Math.random() * 8)].dark)
tab_view.appendTab("qrc:/example/res/image/favicon.ico","Document "+tab_view.count(),com_page,colors[Math.floor(Math.random() * 8)].dark)
}
Component.onCompleted: {
@ -113,6 +113,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluTabView{
anchors.fill: parent
Component.onCompleted: {
@ -128,7 +129,7 @@ FluScrollablePage{
}
}
function newTab(){
tab_view.appendTab("qrc:/res/image/favicon.ico","Document 1",com_page,argument)
tab_view.appendTab("qrc:/example/res/image/favicon.ico","Document 1",com_page,argument)
}
}
'

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Window
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -68,8 +68,8 @@ FluScrollablePage{
text:"编辑"
topPadding:3
bottomPadding:3
leftPadding:3
rightPadding:3
leftPadding:6
rightPadding:6
onClicked:{
console.debug(dataModel.index)
showSuccess(JSON.stringify(dataObject))
@ -79,8 +79,8 @@ FluScrollablePage{
text:"删除"
topPadding:3
bottomPadding:3
leftPadding:3
rightPadding:3
leftPadding:6
rightPadding:6
onClicked:{
showError(JSON.stringify(dataObject))
}
@ -110,7 +110,6 @@ FluScrollablePage{
id:table_view
Layout.fillWidth: true
Layout.topMargin: 20
width:parent.width
pageCurrent:1
pageCount:10
itemCount: 1000
@ -141,15 +140,15 @@ FluScrollablePage{
width:100
}
];
table_view.columns = columns
table_view.columns = columns
const dataSource = [
{
name: ",
age: 500,
address:"钟灵毓秀的花果山,如神仙仙境的水帘洞",
{
name: ",
age: 500,
address:"钟灵毓秀的花果山,如神仙仙境的水帘洞",
nickname:"齐天大圣"
}
];
}
];
table_view.dataSource = columns
}
}'

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Window
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -45,19 +45,59 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluTextBox{
placeholderText:"单行输入框"
}'
}
FluArea{
Layout.fillWidth: true
height: 68
paddings: 10
Layout.topMargin: 20
FluPasswordBox{
Layout.topMargin: 20
placeholderText: "请输入密码"
Layout.preferredWidth: 300
disabled:password_box_switch.selected
anchors{
verticalCenter: parent.verticalCenter
left: parent.left
}
}
Row{
spacing: 5
anchors{
verticalCenter: parent.verticalCenter
right: parent.right
}
FluToggleSwitch{
id:password_box_switch
Layout.alignment: Qt.AlignRight
text:"Disabled"
}
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluPasswordBox{
placeholderText:"请输入密码"
}'
}
FluArea{
Layout.fillWidth: true
height: 36+multiine_textbox.height
paddings: 10
Layout.topMargin: 20
FluMultilineTextBox{
id:multiine_textbox
Layout.topMargin: 20
placeholderText: "多行输入框"
Layout.preferredWidth: 300
@ -83,6 +123,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluMultilineTextBox{
placeholderText:"多行输入框"
}'
@ -122,6 +163,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluAutoSuggestBox{
placeholderText:"AutoSuggestBox"
}'

View File

@ -3,7 +3,7 @@ import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -58,7 +58,11 @@ FluScrollablePage{
Layout.topMargin: 5
selected: FluTheme.dark
clickFunc:function(){
FluTheme.dark = !FluTheme.dark
if(FluTheme.dark){
FluTheme.darkMode = FluDarkMode.Light
}else{
FluTheme.darkMode = FluDarkMode.Dark
}
}
}
FluText{
@ -76,12 +80,12 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluTheme.primaryColor = FluColors.Orange
FluTheme.dark = true
FluTheme.nativeText = true
'
FluTheme.nativeText = true'
}

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Window
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -37,6 +37,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluTimePicker{
}'
@ -67,6 +68,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluTimePicker{
hourFormat:FluTimePicker.HH
}'

View File

@ -3,7 +3,7 @@ import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -30,6 +30,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluToggleSwitch{
text:"Text"
}'

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Window
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -45,6 +45,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluIconButton{
iconSource:FluentIcons.ChromeCloseContrast
iconSize: 15
@ -87,6 +88,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluButton{
id:button_1
text:"删除"
@ -98,8 +100,7 @@ FluScrollablePage{
onClicked:{
showSuccess("点击一个Button")
}
}
'
}'
}

View File

@ -3,7 +3,7 @@ import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import FluentUI
import "./component"
import "../component"
FluScrollablePage {
@ -142,6 +142,7 @@ FluScrollablePage {
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluTreeView{
id:tree_view
width:240

View File

@ -83,12 +83,5 @@ FluContentPage {
textSize = value/100*6+FluTheme.textSize
}
}
}
}

View File

@ -6,7 +6,7 @@ import FluentUI
FluWindow {
id:window
title:"关于"
width: 600
height: 600
minimumWidth: 600
@ -15,8 +15,6 @@ FluWindow {
maximumHeight: 600
launchMode: FluWindow.SingleTask
title:"关于"
FluAppBar{
id:appbar
title:"关于"
@ -66,6 +64,8 @@ FluWindow {
}
FluTextButton{
id:text_hublink
topPadding:0
bottomPadding:0
text:"https://github.com/zhuzichu520/FluentUI"
Layout.alignment: Qt.AlignBottom
onClicked: {
@ -81,6 +81,8 @@ FluWindow {
text:"B站"
}
FluTextButton{
topPadding:0
bottomPadding:0
text:"https://www.bilibili.com/video/BV1mg4y1M71w/"
Layout.alignment: Qt.AlignBottom
onClicked: {
@ -126,12 +128,12 @@ FluWindow {
Image{
width: 164.55
height: 224.25
source: "qrc:/res/image/qrcode_wx.jpg"
source: "qrc:/example/res/image/qrcode_wx.jpg"
}
Image{
width: 162
height: 252
source: "qrc:/res/image/qrcode_zfb.jpg"
source: "qrc:/example/res/image/qrcode_zfb.jpg"
}
}
}

View File

@ -7,13 +7,12 @@ import QtQuick.Dialogs
FluWindow {
title:"ChatGPT"
width: 680
height: 600
minimumWidth: 500
minimumHeight: 600
title:"ChatGPT"
onInitArgument:
(argument)=>{
scrollview.focus = true
@ -121,7 +120,7 @@ FluWindow {
asynchronous: true
anchors.fill: parent
sourceSize: Qt.size(100,100)
source: isMy ? "qrc:/res/svg/avatar_2.svg" : "qrc:/res/image/logo_openai.png"
source: isMy ? "qrc:/example/res/svg/avatar_2.svg" : "qrc:/example/res/image/logo_openai.png"
}
}

View File

@ -6,13 +6,13 @@ import FluentUI
FluWindow {
id:window
title:"登录"
width: 400
height: 400
minimumWidth: 400
minimumHeight: 400
maximumWidth: 400
maximumHeight: 400
title:"登录"
onInitArgument:
(argument)=>{

View File

@ -4,17 +4,32 @@ import QtQuick.Controls
import QtQuick.Layouts
import Qt.labs.platform
import FluentUI
import "qrc:///global/"
import "qrc:///example/qml/global/"
FluWindow {
id:window
title: "FluentUI"
width: 1000
height: 640
title: "FluentUI"
closeDestory:false
minimumWidth: 520
minimumHeight: 460
closeFunc:function(event){
close_app.open()
event.accepted = false
}
Connections{
target: appInfo
function onActiveWindow(){
window.show()
window.raise()
window.requestActivate()
}
}
FluAppBar{
id:appbar
z:9
@ -24,8 +39,9 @@ FluWindow {
}
SystemTrayIcon {
id:system_tray
visible: true
icon.source: "qrc:/res/image/favicon.ico"
icon.source: "qrc:/example/res/image/favicon.ico"
tooltip: "FluentUI"
menu: Menu {
MenuItem {
@ -46,6 +62,24 @@ FluWindow {
}
}
FluContentDialog{
id:close_app
title:"退出"
message:"确定要退出程序吗?"
negativeText:"最小化"
buttonFlags: FluContentDialog.NeutralButton | FluContentDialog.NegativeButton | FluContentDialog.PositiveButton
onNegativeClicked:{
system_tray.showMessage("友情提示","FluentUI已隐藏至托盘,点击托盘可再次激活窗口");
window.hide()
}
positiveText:"退出"
neutralText:"取消"
onPositiveClicked:{
window.destoryWindow()
FluApp.closeApp()
}
}
FluNavigationView{
id:nav_view
@ -54,7 +88,7 @@ FluWindow {
footerItems:ItemsFooter
z:11
displayMode:MainEvent.displayMode
logo: "qrc:/res/image/favicon.ico"
logo: "qrc:/example/res/image/favicon.ico"
title:"FluentUI"
autoSuggestBox:FluAutoSuggestBox{
width: 280

View File

@ -5,13 +5,12 @@ import FluentUI
FluWindow {
title:"视频播放器"
width: 640
height: 480
minimumWidth: 640
minimumHeight: 480
title:"视频播放器"
onInitArgument:
(argument)=>{
player.source = argument.source
@ -23,7 +22,6 @@ FluWindow {
width:parent.width
}
FluMediaPlayer{
id:player
anchors{

View File

@ -6,7 +6,7 @@ import FluentUI
FluWindow {
id:window
title:"SingleInstance"
width: 500
height: 600
minimumWidth: 500
@ -15,8 +15,6 @@ FluWindow {
maximumHeight: 600
launchMode: FluWindow.SingleInstance
title:"SingleInstance"
FluAppBar{
id:appbar
title:"SingleInstance"

View File

@ -6,7 +6,7 @@ import FluentUI
FluWindow {
id:window
title:"SingleTask"
width: 500
height: 600
minimumWidth: 500
@ -15,8 +15,6 @@ FluWindow {
maximumHeight: 600
launchMode: FluWindow.SingleTask
title:"SingleTask"
FluAppBar{
id:appbar
title:"SingleTask"

View File

@ -6,7 +6,7 @@ import FluentUI
FluWindow {
id:window
title:"Standard"
width: 500
height: 600
minimumWidth: 500
@ -15,8 +15,6 @@ FluWindow {
maximumHeight: 600
launchMode: FluWindow.Standard
title:"Standard"
FluAppBar{
id:appbar
title:"Standard"

View File

@ -1,12 +1,17 @@
#include "AppInfo.h"
#include "lang/En.h"
#include "lang/Zh.h"
#include <QDebug>
#define STR(x) #x
#define VER_JOIN(a,b,c,d) STR(a.b.c.d)
#define VER_JOIN_(x) VER_JOIN x
#define VER_STR VER_JOIN_((VERSION))
AppInfo::AppInfo(QObject *parent)
: QObject{parent}
{
version("1.2.5");
version(VER_STR);
lang(new En());
}

View File

@ -13,6 +13,7 @@ class AppInfo : public QObject
public:
explicit AppInfo(QObject *parent = nullptr);
Q_INVOKABLE void changeLang(const QString& locale);
Q_SIGNAL void activeWindow();
};
#endif // APPINFO_H

View File

@ -11,7 +11,7 @@
#include <QClipboard>
#include <QByteArray>
#include <QFile>
#include "stdafx.h"
#include "../stdafx.h"
class ChatController : public QObject
{

View File

@ -13,6 +13,7 @@ En::En(QObject *parent)
theming("Theming");
media("Media");
dark_mode("Dark Mode");
sys_dark_mode("Sync with system");
search("Search");
about("About");
settings("Settings");

View File

@ -2,7 +2,7 @@
#define LANG_H
#include <QObject>
#include "stdafx.h"
#include "../stdafx.h"
class Lang : public QObject
{
@ -16,6 +16,7 @@ class Lang : public QObject
Q_PROPERTY_AUTO(QString,theming);
Q_PROPERTY_AUTO(QString,media);
Q_PROPERTY_AUTO(QString,dark_mode);
Q_PROPERTY_AUTO(QString,sys_dark_mode);
Q_PROPERTY_AUTO(QString,search);
Q_PROPERTY_AUTO(QString,about);
Q_PROPERTY_AUTO(QString,settings);

View File

@ -13,6 +13,7 @@ Zh::Zh(QObject *parent)
theming("主题");
media("媒体");
dark_mode("夜间模式");
sys_dark_mode("跟随系统");
search("查找");
about("关于");
settings("设置");

63
example/src/main.cpp Normal file
View File

@ -0,0 +1,63 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QDir>
#include <QQuickWindow>
#include <QProcess>
#include "lang/Lang.h"
#include "AppInfo.h"
#include "controller/ChatController.h"
#include "tool/IPC.h"
#if defined(STATICLIB)
#include <FluentUI.h>
#endif
int main(int argc, char *argv[])
{
//将样式设置为Basic不然会导致组件显示异常
qputenv("QT_QUICK_CONTROLS_STYLE","Basic");
//6.4及以下监听系统深色模式变化
#ifdef Q_OS_WIN
qputenv("QT_QPA_PLATFORM","windows:darkmode=2");
#endif
QGuiApplication::setOrganizationName("ZhuZiChu");
QGuiApplication::setOrganizationDomain("https://zhuzichu520.github.io");
QGuiApplication::setApplicationName("FluentUI");
// QQuickWindow::setGraphicsApi(QSGRendererInterface::Software);
QGuiApplication app(argc, argv);
AppInfo* appInfo = new AppInfo();
IPC ipc(0);
QString activeWindowEvent = "activeWindow";
if(!ipc.isCurrentOwner()){
ipc.postEvent(activeWindowEvent,QString().toUtf8(),0);
delete appInfo;
return 0;
}
if(ipc.isAttached()){
ipc.registerEventHandler(activeWindowEvent,[&appInfo](const QByteArray&){
Q_EMIT appInfo->activeWindow();
return true;
});
}
app.setQuitOnLastWindowClosed(false);
QQmlApplicationEngine engine;
#if defined(STATICLIB)
FluentUI::initialize(&engine);
#endif
qmlRegisterType<ChatController>("Controller",1,0,"ChatController");
QQmlContext * context = engine.rootContext();
Lang* lang = appInfo->lang();
context->setContextProperty("lang",lang);
QObject::connect(appInfo,&AppInfo::langChanged,&app,[context,appInfo]{
context->setContextProperty("lang",appInfo->lang());
});
context->setContextProperty("appInfo",appInfo);
const QUrl url(QStringLiteral("qrc:/example/qml/App.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}

250
example/src/tool/IPC.cpp Normal file
View File

@ -0,0 +1,250 @@
#include "IPC.h"
#include <QCoreApplication>
#include <QDebug>
#include <QThread>
#include <ctime>
#include <random>
IPC::IPC(uint32_t profileId)
: profileId{profileId}
, globalMemory{"ipc-" IPC_PROTOCOL_VERSION}
{
qRegisterMetaType<IPCEventHandler>("IPCEventHandler");
timer.setInterval(EVENT_TIMER_MS);
timer.setSingleShot(true);
connect(&timer, &QTimer::timeout, this, &IPC::processEvents);
std::default_random_engine randEngine((std::random_device())());
std::uniform_int_distribution<uint64_t> distribution;
globalId = distribution(randEngine);
qDebug() << "Our global IPC ID is " << globalId;
if (globalMemory.create(sizeof(IPCMemory))) {
if (globalMemory.lock()) {
IPCMemory* mem = global();
memset(mem, 0, sizeof(IPCMemory));
mem->globalId = globalId;
mem->lastProcessed = time(nullptr);
globalMemory.unlock();
} else {
qWarning() << "Couldn't lock to take ownership";
}
} else if (globalMemory.attach()) {
qDebug() << "Attaching to the global shared memory";
} else {
qDebug() << "Failed to attach to the global shared memory, giving up. Error:"
<< globalMemory.error();
return;
}
processEvents();
}
IPC::~IPC()
{
if (!globalMemory.lock()) {
qWarning() << "Failed to lock in ~IPC";
return;
}
if (isCurrentOwnerNoLock()) {
global()->globalId = 0;
}
globalMemory.unlock();
}
time_t IPC::postEvent(const QString& name, const QByteArray& data, uint32_t dest)
{
QByteArray binName = name.toUtf8();
if (binName.length() > (int32_t)sizeof(IPCEvent::name)) {
return 0;
}
if (data.length() > (int32_t)sizeof(IPCEvent::data)) {
return 0;
}
if (!globalMemory.lock()) {
qDebug() << "Failed to lock in postEvent()";
return 0;
}
IPCEvent* evt = nullptr;
IPCMemory* mem = global();
time_t result = 0;
for (uint32_t i = 0; !evt && i < EVENT_QUEUE_SIZE; ++i) {
if (mem->events[i].posted == 0) {
evt = &mem->events[i];
}
}
if (evt) {
memset(evt, 0, sizeof(IPCEvent));
memcpy(evt->name, binName.constData(), binName.length());
memcpy(evt->data, data.constData(), data.length());
mem->lastEvent = evt->posted = result = qMax(mem->lastEvent + 1, time(nullptr));
evt->dest = dest;
evt->sender = qApp->applicationPid();
qDebug() << "postEvent " << name << "to" << dest;
}
globalMemory.unlock();
return result;
}
bool IPC::isCurrentOwner()
{
if (globalMemory.lock()) {
const bool isOwner = isCurrentOwnerNoLock();
globalMemory.unlock();
return isOwner;
} else {
qWarning() << "isCurrentOwner failed to lock, returning false";
return false;
}
}
void IPC::registerEventHandler(const QString& name, IPCEventHandler handler)
{
eventHandlers[name] = handler;
}
bool IPC::isEventAccepted(time_t time)
{
bool result = false;
if (!globalMemory.lock()) {
return result;
}
if (difftime(global()->lastProcessed, time) > 0) {
IPCMemory* mem = global();
for (uint32_t i = 0; i < EVENT_QUEUE_SIZE; ++i) {
if (mem->events[i].posted == time && mem->events[i].processed) {
result = mem->events[i].accepted;
break;
}
}
}
globalMemory.unlock();
return result;
}
bool IPC::waitUntilAccepted(time_t postTime, int32_t timeout /*=-1*/)
{
bool result = false;
time_t start = time(nullptr);
forever
{
result = isEventAccepted(postTime);
if (result || (timeout > 0 && difftime(time(nullptr), start) >= timeout)) {
break;
}
qApp->processEvents();
QThread::msleep(0);
}
return result;
}
bool IPC::isAttached() const
{
return globalMemory.isAttached();
}
void IPC::setProfileId(uint32_t profileId)
{
this->profileId = profileId;
}
IPC::IPCEvent* IPC::fetchEvent()
{
IPCMemory* mem = global();
for (uint32_t i = 0; i < EVENT_QUEUE_SIZE; ++i) {
IPCEvent* evt = &mem->events[i];
if ((evt->processed && difftime(time(nullptr), evt->processed) > EVENT_GC_TIMEOUT)
|| (!evt->processed && difftime(time(nullptr), evt->posted) > EVENT_GC_TIMEOUT)) {
memset(evt, 0, sizeof(IPCEvent));
}
if (evt->posted && !evt->processed && evt->sender != qApp->applicationPid()
&& (evt->dest == profileId || (evt->dest == 0 && isCurrentOwnerNoLock()))) {
return evt;
}
}
return nullptr;
}
bool IPC::runEventHandler(IPCEventHandler handler, const QByteArray& arg)
{
bool result = false;
if (QThread::currentThread() == qApp->thread()) {
result = handler(arg);
} else {
QMetaObject::invokeMethod(this, "runEventHandler", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(bool, result), Q_ARG(IPCEventHandler, handler),
Q_ARG(const QByteArray&, arg));
}
return result;
}
void IPC::processEvents()
{
if (!globalMemory.lock()) {
timer.start();
return;
}
IPCMemory* mem = global();
if (mem->globalId == globalId) {
mem->lastProcessed = time(nullptr);
} else {
if (difftime(time(nullptr), mem->lastProcessed) >= OWNERSHIP_TIMEOUT_S) {
qDebug() << "Previous owner timed out, taking ownership" << mem->globalId << "->"
<< globalId;
memset(mem, 0, sizeof(IPCMemory));
mem->globalId = globalId;
mem->lastProcessed = time(nullptr);
}
}
while (IPCEvent* evt = fetchEvent()) {
QString name = QString::fromUtf8(evt->name);
auto it = eventHandlers.find(name);
if (it != eventHandlers.end()) {
evt->accepted = runEventHandler(it.value(), evt->data);
qDebug() << "Processed event:" << name << "posted:" << evt->posted
<< "accepted:" << evt->accepted;
if (evt->dest == 0) {
if (evt->accepted) {
evt->processed = time(nullptr);
}
} else {
evt->processed = time(nullptr);
}
} else {
qDebug() << "Received event:" << name << "without handler";
qDebug() << "Available handlers:" << eventHandlers.keys();
}
}
globalMemory.unlock();
timer.start();
}
bool IPC::isCurrentOwnerNoLock()
{
const void* const data = globalMemory.data();
if (!data) {
qWarning() << "isCurrentOwnerNoLock failed to access the memory, returning false";
return false;
}
return (*static_cast<const uint64_t*>(data) == globalId);
}
IPC::IPCMemory* IPC::global()
{
return static_cast<IPCMemory*>(globalMemory.data());
}

75
example/src/tool/IPC.h Normal file
View File

@ -0,0 +1,75 @@
#ifndef IPC_H
#define IPC_H
#include <QMap>
#include <QObject>
#include <QSharedMemory>
#include <QTimer>
#include <ctime>
#include <functional>
using IPCEventHandler = std::function<bool(const QByteArray&)>;
#define IPC_PROTOCOL_VERSION "1"
class IPC : public QObject
{
Q_OBJECT
protected:
static const int EVENT_TIMER_MS = 1000;
static const int EVENT_GC_TIMEOUT = 5;
static const int EVENT_QUEUE_SIZE = 32;
static const int OWNERSHIP_TIMEOUT_S = 5;
public:
IPC(uint32_t profileId);
~IPC();
struct IPCEvent
{
uint32_t dest;
int32_t sender;
char name[16];
char data[128];
time_t posted;
time_t processed;
uint32_t flags;
bool accepted;
bool global;
};
struct IPCMemory
{
uint64_t globalId;
time_t lastEvent;
time_t lastProcessed;
IPCEvent events[IPC::EVENT_QUEUE_SIZE];
};
time_t postEvent(const QString& name, const QByteArray& data = QByteArray(), uint32_t dest = 0);
bool isCurrentOwner();
void registerEventHandler(const QString& name, IPCEventHandler handler);
bool isEventAccepted(time_t time);
bool waitUntilAccepted(time_t time, int32_t timeout = -1);
bool isAttached() const;
public slots:
void setProfileId(uint32_t profileId);
private:
IPCMemory* global();
bool runEventHandler(IPCEventHandler handler, const QByteArray& arg);
IPCEvent* fetchEvent();
void processEvents();
bool isCurrentOwnerNoLock();
private:
QTimer timer;
uint64_t globalId;
uint32_t profileId;
QSharedMemory globalMemory;
QMap<QString, IPCEventHandler> eventHandlers;
};
#endif // IPC_H

View File

@ -17,7 +17,7 @@ function Main() {
New-Item -ItemType Directory $archiveName
# 拷贝exe
Copy-Item bin\release\* $archiveName\
Copy-Item bin\release\* $archiveName\ -Force -Recurse | Out-Null
# 拷贝依赖
windeployqt --qmldir . --plugindir $archiveName\plugins --no-translations --compiler-runtime $archiveName\$targetName
# 删除不必要的文件

View File

@ -27,7 +27,7 @@ function Main() {
New-Item -ItemType Directory $archiveName
# 拷贝exe
Copy-Item bin\release\* $archiveName\
Copy-Item bin\release\* $archiveName\ -Force -Recurse | Out-Null
# 拷贝依赖
windeployqt --qmldir . --plugindir $archiveName\plugins --no-translations --compiler-runtime $archiveName\$targetName
# 删除不必要的文件

View File

@ -1,67 +1,71 @@
cmake_minimum_required(VERSION 3.16)
project(FluentUI)
project(fluentui LANGUAGES CXX)
#配置通用编译
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
find_package(Qt6 COMPONENTS Core Quick Svg REQUIRED)
set(QT_INSTALL_QML ${Qt6Core_DIR}/../../../qml)
set(TARGET_TYPE SHARED)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/FluentUI)
if(WIN32)
set(CMAKE_SHARED_LIBRARY_PREFIX "")
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(APPLE)
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
endif()
set(TARGET_RESOURCES res.qrc)
set(TARGET_SOURCES
Def.cpp
FluApp.cpp
FluColorSet.cpp
FluColors.cpp
FluRegister.cpp
FluTheme.cpp
Fluent.cpp
FluentUI.cpp
NativeEventFilter.cpp
WindowHelper.cpp
qml_plugin.cpp
#设置可执行文件输出目录
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/debug)
else()
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/release)
endif()
#设置版本号
add_definitions(-DVERSION=1,2,9,0)
find_package(Qt6 REQUIRED COMPONENTS Core Quick Qml)
#遍历所有Cpp文件
file(GLOB_RECURSE CPP_FILES *.cpp *.h)
foreach(filepath ${CPP_FILES})
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" filename ${filepath})
list(APPEND sources_files ${filename})
endforeach(filepath)
#遍历所有qml文件
file(GLOB_RECURSE QML_PATHS *.qml)
foreach(filepath ${QML_PATHS})
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" filename ${filepath})
list(APPEND qml_files ${filename})
endforeach(filepath)
#遍历所有资源文件
file(GLOB_RECURSE RES_PATHS *.png *.jpg *.svg *.ico *.ttf *.webp)
foreach(filepath ${RES_PATHS})
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" filename ${filepath})
list(APPEND resource_files ${filename})
endforeach(filepath)
#修改资源文件导出路径
foreach(filepath IN LISTS qml_files resource_files)
string(REPLACE "imports/FluentUI/" "" filename ${filepath})
set_source_files_properties(${filepath} PROPERTIES QT_RESOURCE_ALIAS ${filename})
endforeach()
#添加qml模块
qt_add_qml_module(fluentui
OUTPUT_DIRECTORY ${CMAKE_PREFIX_PATH}/qml/FluentUI
VERSION 1.0
URI "FluentUI"
SOURCES ${sources_files} fluentui.rc
QML_FILES ${qml_files}
RESOURCES ${resource_files}
)
set(TARGET_HEADERS
Def.h
FluApp.h
FluColorSet.h
FluColors.h
FluRegister.h
FluTheme.h
Fluent.h
FluentUI.h
NativeEventFilter.h
WindowHelper.h
qml_plugin.h
stdafx.h
#链接库
target_link_libraries(fluentui PUBLIC
Qt::Core
Qt::Quick
Qt::Qml
)
add_definitions(-DVERSION_IN="1.0.0")
add_definitions(-DVURI_STR="FluentUI")
add_library(${PROJECT_NAME} ${TARGET_TYPE} ${TARGET_SOURCES} ${TARGET_HEADERS} ${TARGET_RESOURCES})
set_target_properties(${PROJECT_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/FluentUI)
#链接库 win32库 不然mingw会编译错误
if(WIN32)
target_link_libraries(${PROJECT_NAME} PRIVATE dwmapi user32)
else()
endif()
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Core Qt6::Quick Qt6::Svg)
if(WIN32)
include(build_windows.cmake)
else()
include(build_macos.cmake)
target_link_libraries(fluentui PRIVATE dwmapi user32)
endif()

View File

@ -2,6 +2,18 @@
#define DEF_H
#include <QObject>
#include <QtQml/qqml.h>
namespace Fluent_DarkMode {
Q_NAMESPACE
enum Fluent_DarkModeType {
System = 0x0,
Light = 0x1,
Dark = 0x2,
};
QML_NAMED_ELEMENT(FluDarkMode)
Q_ENUMS(Fluent_DarkModeType);
}
namespace Fluent_Awesome {
Q_NAMESPACE
@ -1410,6 +1422,7 @@ enum class Fluent_AwesomeType {
SpeechSolidBold=0xf8b2,
ClickedOutLoudSolidBold=0xf8b3,
};
QML_NAMED_ELEMENT(FluentIcons)
Q_ENUMS(Fluent_AwesomeType)
}

View File

@ -6,11 +6,12 @@
#include <QQuickItem>
#include <QTimer>
#include <QUuid>
#include <QFontDatabase>
#include <QClipboard>
#include "FluTheme.h"
#include "Def.h"
#ifdef Q_OS_WIN
#pragma comment(lib, "Dwmapi.lib")
#pragma comment(lib, "User32.lib")
#include <dwmapi.h>
#include <Windows.h>
#include <windowsx.h>
@ -22,29 +23,56 @@ static bool isCompositionEnabled()
}
#endif
FluApp* FluApp::m_instance = nullptr;
FluApp* FluApp::fluApp = nullptr;
FluApp *FluApp::getInstance()
{
if(FluApp::m_instance == nullptr){
FluApp::m_instance = new FluApp;
}
return FluApp::m_instance;
}
FluTheme* FluApp::fluTheme = nullptr;
FluColors* FluApp::fluColors = nullptr;
FluTools* FluApp::fluTools = nullptr;
FluApp::FluApp(QObject *parent)
: QObject{parent}
{
QFontDatabase::addApplicationFont(":/FluentUI/Font/Segoe_Fluent_Icons.ttf");
}
FluApp::~FluApp(){
if (nativeEvent != Q_NULLPTR) {
delete nativeEvent;
nativeEvent = Q_NULLPTR;
}
}
void FluApp::setFluApp(FluApp* val){
FluApp::fluApp = val;
}
void FluApp::setFluTheme(FluTheme* val){
FluApp::fluTheme = val;
}
void FluApp::setFluColors(FluColors* val){
FluApp::fluColors = val;
}
void FluApp::setFluTools(FluTools* val){
FluApp::fluTools = val;
}
void FluApp::init(QQuickWindow *window){
this->appWindow = window;
QQmlEngine *engine = qmlEngine(appWindow);
QQmlComponent component(engine, ":/FluentUI/Controls/FluSingleton.qml");
component.create();
nativeEvent = new NativeEventFilter();
qApp->installNativeEventFilter(nativeEvent);
}
void FluApp::run(){
#ifdef Q_OS_WIN
if(!isCompositionEnabled()){
FluTheme::getInstance()->frameless(false);
fluTheme->frameless(false);
}
#endif
navigate(initialRoute());
@ -64,12 +92,13 @@ void FluApp::navigate(const QString& route,const QJsonObject& argument,FluRegist
}
properties.insert("argument",argument);
QQuickWindow *view = qobject_cast<QQuickWindow*>(component.createWithInitialProperties(properties));
int launchMode = view->property("launchMode").toInt();
if(launchMode==1){
for (auto& pair : wnds) {
QString r = pair->property("route").toString();
if(r == route){
pair->setProperty("argument",argument);
pair->raise();
pair->requestActivate();
view->deleteLater();
return;
@ -84,8 +113,7 @@ void FluApp::navigate(const QString& route,const QJsonObject& argument,FluRegist
}
}
}
if(FluTheme::getInstance()->frameless()){
if(fluTheme->frameless()){
view->setFlag(Qt::FramelessWindowHint,true);
}
wnds.insert(view->winId(),view);
@ -120,14 +148,6 @@ QJsonArray FluApp::awesomelist(const QString& keyword)
return arr;
}
void FluApp::clipText(const QString& text){
QGuiApplication::clipboard()->setText(text);
}
QString FluApp::uuid(){
return QUuid::createUuid().toString();
}
void FluApp::closeApp(){
qApp->exit(0);
}

View File

@ -3,43 +3,131 @@
#include <QObject>
#include <QWindow>
#include <QtQml/qqml.h>
#include <QJsonArray>
#include <QQmlContext>
#include <QJsonObject>
#include <QQmlEngine>
#include "FluTheme.h"
#include "FluTools.h"
#include "FluColors.h"
#include "NativeEventFilter.h"
#include "FluRegister.h"
#include "stdafx.h"
/**
* @brief The FluApp class
*/
class FluApp : public QObject
{
Q_OBJECT
/**
* @brief initialRoute 初始路由
*/
Q_PROPERTY_AUTO(QString,initialRoute);
/**
* @brief routes 路由表
*/
Q_PROPERTY_AUTO(QJsonObject,routes);
QML_NAMED_ELEMENT(FluApp)
QML_SINGLETON
public:
static FluApp *getInstance();
explicit FluApp(QObject *parent = nullptr);
~FluApp();
/**
* @brief run
*/
Q_INVOKABLE void run();
/**
* @brief navigate
* @param route
* @param argument
* @param fluRegister
*/
Q_INVOKABLE void navigate(const QString& route,const QJsonObject& argument = {},FluRegister* fluRegister = nullptr);
/**
* @brief init
* @param window
*/
Q_INVOKABLE void init(QQuickWindow *window);
/**
* @brief awesomelist
* @param keyword
* @return
*/
Q_INVOKABLE QJsonArray awesomelist(const QString& keyword = "");
Q_INVOKABLE void clipText(const QString& text);
Q_INVOKABLE QString uuid();
/**
* @brief closeApp
*/
Q_INVOKABLE void closeApp();
/**
* @brief setFluApp 在FluSingleton.qml调用拿到QML中FluApp的单例
* @param val
*/
Q_INVOKABLE void setFluApp(FluApp* val);
/**
* @brief setFluTheme 在FluSingleton.qml调用拿到QML中FluTheme的单例
* @param val
*/
Q_INVOKABLE void setFluTheme(FluTheme* val);
/**
* @brief setFluColors 在FluSingleton.qml调用拿到QML中FluColors的单例
* @param val
*/
Q_INVOKABLE void setFluColors(FluColors* val);
/**
* @brief setFluColors 在FluSingleton.qml调用拿到QML中FluTools的单例
* @param val
*/
Q_INVOKABLE void setFluTools(FluTools* val);
public:
/**
* @brief wnds
*/
QMap<quint64, QQuickWindow*> wnds;
/**
* @brief fluApp
*/
static FluApp* fluApp;
/**
* @brief fluTheme
*/
static FluTheme* fluTheme;
/**
* @brief fluColors
*/
static FluColors* fluColors;
/**
* @brief fluTools
*/
static FluTools* fluTools;
private:
static FluApp* m_instance;
/**
* @brief nativeEvent
*/
NativeEventFilter *nativeEvent = Q_NULLPTR;
/**
* @brief appWindow
*/
QWindow *appWindow;
};

View File

@ -4,9 +4,11 @@
#include <QObject>
#include "stdafx.h"
/**
* @brief The FluColorSet class
*/
class FluColorSet : public QObject
{
Q_OBJECT
Q_PROPERTY_AUTO(QString,darkest)
Q_PROPERTY_AUTO(QString,darker)

View File

@ -1,15 +1,5 @@
#include "FluColors.h"
FluColors* FluColors::m_instance = nullptr;
FluColors *FluColors::getInstance()
{
if(FluColors::m_instance == nullptr){
FluColors::m_instance = new FluColors;
}
return FluColors::m_instance;
}
FluColors::FluColors(QObject *parent)
: QObject{parent}
{

View File

@ -2,9 +2,13 @@
#define FLUCOLORS_H
#include <QObject>
#include <QtQml/qqml.h>
#include "FluColorSet.h"
#include "stdafx.h"
/**
* @brief The FluColors class
*/
class FluColors : public QObject
{
Q_OBJECT
@ -32,7 +36,6 @@ class FluColors : public QObject
Q_PROPERTY_AUTO(QString,Grey200);
Q_PROPERTY_AUTO(QString,Grey210);
Q_PROPERTY_AUTO(QString,Grey220);
Q_PROPERTY_AUTO(FluColorSet*,Yellow);
Q_PROPERTY_AUTO(FluColorSet*,Orange);
Q_PROPERTY_AUTO(FluColorSet*,Red);
@ -41,13 +44,10 @@ class FluColors : public QObject
Q_PROPERTY_AUTO(FluColorSet*,Blue);
Q_PROPERTY_AUTO(FluColorSet*,Teal);
Q_PROPERTY_AUTO(FluColorSet*,Green);
QML_NAMED_ELEMENT(FluColors)
QML_SINGLETON
public:
explicit FluColors(QObject *parent = nullptr);
static FluColors *getInstance();
private:
static FluColors* m_instance;
};
#endif // FLUCOLORS_H

View File

@ -12,7 +12,7 @@ FluRegister::FluRegister(QObject *parent)
}
void FluRegister::launch(const QJsonObject& argument){
FluApp::getInstance()->navigate(path(),argument,this);
FluApp::fluApp->navigate(path(),argument,this);
}
void FluRegister::onResult(const QJsonObject& data){

View File

@ -6,6 +6,9 @@
#include <QJsonObject>
#include "stdafx.h"
/**
* @brief The FluRegister class
*/
class FluRegister : public QObject
{
Q_OBJECT
@ -15,8 +18,22 @@ class FluRegister : public QObject
public:
explicit FluRegister(QObject *parent = nullptr);
/**
* @brief launch 窗口跳转
* @param argument 跳转携带参数
*/
Q_INVOKABLE void launch(const QJsonObject& argument = {});
/**
* @brief onResult 将结果数据回传到上一个窗口
* @param data 结果数据
*/
Q_INVOKABLE void onResult(const QJsonObject& data = {});
/**
* @brief result 收到结果数据的信号
* @param data 结果数据
*/
Q_SIGNAL void result(const QJsonObject& data);
};

View File

@ -1,33 +1,51 @@
#include "FluTheme.h"
#include "FluColors.h"
#include "Def.h"
#include <QPalette>
#include "FluApp.h"
#include <QGuiApplication>
FluTheme* FluTheme::m_instance = nullptr;
FluTheme *FluTheme::getInstance()
{
if(FluTheme::m_instance == nullptr){
FluTheme::m_instance = new FluTheme;
}
return FluTheme::m_instance;
}
FluTheme::FluTheme(QObject *parent)
: QObject{parent}
{
primaryColor(FluColors::getInstance()->Blue());
textSize(13);
nativeText(true);
frameless(true);
std::function<bool()> isDark = [](){
QPalette palette = (qobject_cast<QGuiApplication *>(QCoreApplication::instance()))->palette();
QColor color = palette.color(QPalette::Window).rgb();
return !(color.red() * 0.2126 + color.green() * 0.7152 + color.blue() * 0.0722 > 255 / 2);
};
dark(isDark());
connect(qobject_cast<QGuiApplication *>(QCoreApplication::instance()), &QGuiApplication::paletteChanged, this, [=] (const QPalette &) {
dark(isDark());
connect(this,&FluTheme::darkModeChanged,this,[=]{
Q_EMIT darkChanged();
});
primaryColor(FluApp::fluColors->Blue());
textSize(13);
nativeText(false);
frameless(true);
darkMode(Fluent_DarkMode::Fluent_DarkModeType::Light);
qApp->installEventFilter(this);
}
bool FluTheme::eventFilter(QObject *obj, QEvent *event)
{
Q_UNUSED(obj);
if (event->type() == QEvent::ApplicationPaletteChange)
{
Q_EMIT darkChanged();
event->accept();
return true;
}
return false;
}
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 == Fluent_DarkMode::Fluent_DarkModeType::Dark){
return true;
}else if(_darkMode == Fluent_DarkMode::Fluent_DarkModeType::Light){
return false;
}else if(_darkMode == Fluent_DarkMode::Fluent_DarkModeType::System){
return systemDark();
}else{
return false;
}
}

View File

@ -2,23 +2,56 @@
#define FLUTHEME_H
#include <QObject>
#include <QtQml/qqml.h>
#include "FluColorSet.h"
#include "stdafx.h"
/**
* @brief The FluTheme class
*/
class FluTheme : public QObject
{
Q_OBJECT
/**
* @brief dark 改变窗口夜间样式只读属性可以通过darkMode切换
*/
Q_PROPERTY(bool dark READ dark NOTIFY darkChanged)
/**
* @brief primaryColor 主题颜色
*/
Q_PROPERTY_AUTO(FluColorSet*,primaryColor)
/**
* @brief frameless 是否是无边框窗口只支持windows部分电脑
*/
Q_PROPERTY_AUTO(bool,frameless);
Q_PROPERTY_AUTO(bool,dark);
/**
* @brief darkMode 夜间模式支持System=0、Light=1、Dark=2
*/
Q_PROPERTY_AUTO(int,darkMode);
/**
* @brief nativeText 本地渲染文本
*/
Q_PROPERTY_AUTO(bool,nativeText);
/**
* @brief textSize 文字大小
*/
Q_PROPERTY_AUTO(int,textSize);
QML_NAMED_ELEMENT(FluTheme)
QML_SINGLETON
public:
explicit FluTheme(QObject *parent = nullptr);
static FluTheme *getInstance();
bool dark();
Q_SIGNAL void darkChanged();
private:
static FluTheme* m_instance;
bool _dark;
bool eventFilter(QObject *obj, QEvent *event);
bool systemDark();
};
#endif // FLUTHEME_H

18
src/FluTools.cpp Normal file
View File

@ -0,0 +1,18 @@
#include "FluTools.h"
#include <QGuiApplication>
#include <QClipboard>
#include <QUuid>
FluTools::FluTools(QObject *parent)
: QObject{parent}
{
}
void FluTools::clipText(const QString& text){
QGuiApplication::clipboard()->setText(text);
}
QString FluTools::uuid(){
return QUuid::createUuid().toString();
}

34
src/FluTools.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef FLUTOOLS_H
#define FLUTOOLS_H
#include <QObject>
#include <QtQml/qqml.h>
/**
* @brief The FluTools class
*/
class FluTools : public QObject
{
Q_OBJECT
QML_NAMED_ELEMENT(FluTools)
QML_SINGLETON
public:
explicit FluTools(QObject *parent = nullptr);
/**
* @brief clipText 将字符串添加到剪切板
* @param text
*/
Q_INVOKABLE void clipText(const QString& text);
/**
* @brief uuid 获取uuid
* @return
*/
Q_INVOKABLE QString uuid();
};
#endif // FLUTOOLS_H

View File

@ -1,117 +0,0 @@
#include "Fluent.h"
#include <QFontDatabase>
#include <QQmlContext>
#include <QGuiApplication>
#include <QQuickWindow>
#include "FluColors.h"
#include "NativeEventFilter.h"
#include "FluTheme.h"
#include "WindowHelper.h"
#include "FluApp.h"
#include "Def.h"
Fluent* Fluent::m_instance = nullptr;
Fluent *Fluent::getInstance()
{
if(Fluent::m_instance == nullptr){
Fluent::m_instance = new Fluent;
}
return Fluent::m_instance;
}
QString Fluent::version() const
{
return QStringLiteral(VERSION_IN);
}
void Fluent::registerTypes(const char *uri){
Q_INIT_RESOURCE(res);
int major = 1;
int minor = 0;
qmlRegisterType<WindowHelper>(uri,major,minor,"WindowHelper");
qmlRegisterType<FluColorSet>(uri,major,minor,"FluColorSet");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluRatingControl.qml"),uri,major,minor,"FluRatingControl");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluStatusView.qml"),uri,major,minor,"FluStatusView");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluPagination.qml"),uri,major,minor,"FluPagination");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluToggleButton.qml"),uri,major,minor,"FluToggleButton");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTableView.qml"),uri,major,minor,"FluTableView");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluPivotItem.qml"),uri,major,minor,"FluPivotItem");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluPivot.qml"),uri,major,minor,"FluPivot");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluFlipView.qml"),uri,major,minor,"FluFlipView");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluPaneItemExpander.qml"),uri,major,minor,"FluPaneItemExpander");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTabView.qml"),uri,major,minor,"FluTabView");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluArea.qml"),uri,major,minor,"FluArea");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluBadge.qml"),uri,major,minor,"FluBadge");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluMediaPlayer.qml"),uri,major,minor,"FluMediaPlayer");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluContentPage.qml"),uri,major,minor,"FluContentPage");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluScrollablePage.qml"),uri,major,minor,"FluScrollablePage");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluPaneItemHeader.qml"),uri,major,minor,"FluPaneItemHeader");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluPaneItem.qml"),uri,major,minor,"FluPaneItem");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluPaneItemSeparator.qml"),uri,major,minor,"FluPaneItemSeparator");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluNavigationView.qml"),uri,major,minor,"FluNavigationView");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluCalendarPicker.qml"),uri,major,minor,"FluCalendarPicker");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluCalendarView.qml"),uri,major,minor,"FluCalendarView");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluDatePicker.qml"),uri,major,minor,"FluDatePicker");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTimePicker.qml"),uri,major,minor,"FluTimePicker");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluColorView.qml"),uri,major,minor,"FluColorView");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluColorPicker.qml"),uri,major,minor,"FluColorPicker");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluCarousel.qml"),uri,major,minor,"FluCarousel");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluAutoSuggestBox.qml"),uri,major,minor,"FluAutoSuggestBox");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluExpander.qml"),uri,major,minor,"FluExpander");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTreeView.qml"),uri,major,minor,"FluTreeView");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluContentDialog.qml"),uri,major,minor,"FluContentDialog");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluMenuItem.qml"),uri,major,minor,"FluMenuItem");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluMenu.qml"),uri,major,minor,"FluMenu");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluScrollBar.qml"),uri,major,minor,"FluScrollBar");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTextButton.qml"),uri,major,minor,"FluTextButton");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluMultilineTextBox.qml"),uri,major,minor,"FluMultilineTextBox");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTooltip.qml"),uri,major,minor,"FluTooltip");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluDivider.qml"),uri,major,minor,"FluDivider");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluIcon.qml"),uri,major,minor,"FluIcon");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluObject.qml"),uri,major,minor,"FluObject");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluInfoBar.qml"),uri,major,minor,"FluInfoBar");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluWindow.qml"),uri,major,minor,"FluWindow");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluRectangle.qml"),uri,major,minor,"FluRectangle");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluAppBar.qml"),uri,major,minor,"FluAppBar");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluButton.qml"),uri,major,minor,"FluButton");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluCheckBox.qml"),uri,major,minor,"FluCheckBox");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluComboBox.qml"),uri,major,minor,"FluComboBox");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluDropDownButton.qml"),uri,major,minor,"FluDropDownButton");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluFilledButton.qml"),uri,major,minor,"FluFilledButton");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluIconButton.qml"),uri,major,minor,"FluIconButton");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluProgressBar.qml"),uri,major,minor,"FluProgressBar");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluProgressRing.qml"),uri,major,minor,"FluProgressRing");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluRadioButton.qml"),uri,major,minor,"FluRadioButton");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluSlider.qml"),uri,major,minor,"FluSlider");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTextBox.qml"),uri,major,minor,"FluTextBox");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluText.qml"),uri,major,minor,"FluText");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluFilledButton.qml"),uri,major,minor,"FluFilledButton");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluToggleSwitch.qml"),uri,major,minor,"FluToggleSwitch");
qmlRegisterUncreatableMetaObject(Fluent_Awesome::staticMetaObject, uri,major,minor,"FluentIcons", "Access to enums & flags only");
}
void Fluent::initializeEngine(QQmlEngine *engine, const char *uri)
{
nativeEvent = new NativeEventFilter();
qApp->installNativeEventFilter(nativeEvent);
Q_UNUSED(engine)
Q_UNUSED(uri)
#ifdef Q_OS_WIN
QFont font;
font.setFamily("Microsoft YaHei");
QGuiApplication::setFont(font);
// QQuickWindow::setTextRenderType(QQuickWindow::NativeTextRendering);
#endif
QFontDatabase::addApplicationFont(":/com.zhuzichu/res/font/Segoe_Fluent_Icons.ttf");
FluApp* app = FluApp::getInstance();
engine->rootContext()->setContextProperty("FluApp",app);
FluColors* colors = FluColors::getInstance();
engine->rootContext()->setContextProperty("FluColors",colors);
FluTheme* theme = FluTheme::getInstance();
engine->rootContext()->setContextProperty("FluTheme",theme);
}

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