Compare commits

..

94 Commits
1.2.1 ... 1.2.7

Author SHA1 Message Date
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
60c2ebee56 update 2023-04-19 10:14:35 +08:00
88fed82260 update 2023-04-19 09:41:08 +08:00
cb94db8a97 Merge pull request #53 from mentalfl0w/dev
Add automatic dark color mode switching function.
2023-04-16 02:30:08 +08:00
88008e16be update 2023-04-16 02:28:58 +08:00
f2db544be0 Add automatic dark color mode switching function. 2023-04-16 01:18:17 +08:00
6db8c4d4ac update 2023-04-15 21:20:00 +08:00
4ab78bbaba 修改registerForPageResult崩溃问题 2023-04-15 09:45:54 +08:00
11b2b04cb9 update 2023-04-14 17:43:19 +08:00
9f2e066a9f update 2023-04-14 17:36:33 +08:00
5b8312dcb9 update 2023-04-14 17:10:36 +08:00
b28f15c23b update 2023-04-14 17:07:54 +08:00
935f515a49 Merge branch 'main' of https://github.com/zhuzichu520/FluentUI 2023-04-14 15:18:32 +08:00
70585c007e 新增FluRatingControl组件 2023-04-14 15:18:08 +08:00
bdde046a4d Update README.md 2023-04-14 12:35:16 +08:00
ad420366f1 Update README.md 2023-04-14 12:34:51 +08:00
727a0220b4 update 2023-04-13 18:10:38 +08:00
ab0fcf5d9c FluWindowd新增launchMode枚举值,支持Standard、SingleTask、SingleInstance 2023-04-13 17:41:34 +08:00
f43bfec992 Merge pull request #43 from LiangLiang723/main
🔧 重构 FluWindow 后 CMakeLists 做对应修改
2023-04-13 16:36:12 +08:00
6bf38b5e5e 🔧 重构 FluWindow 后 CMakeLists 做对应修改 2023-04-13 15:01:04 +08:00
73ff2b45b9 update 2023-04-12 22:02:05 +08:00
7303e7d900 update 2023-04-12 13:42:45 +08:00
5ca1b715f3 update 2023-04-12 11:55:39 +08:00
cd984fddf5 update 2023-04-12 00:15:38 +08:00
2acb3c34bd update 2023-04-11 23:43:20 +08:00
1df3b4ba96 update 2023-04-11 23:39:20 +08:00
5ea3cb1054 Merge pull request #39 from zhuzichu520/dev1.2.4
update
2023-04-11 23:17:51 +08:00
5afd2ec518 update 2023-04-11 23:12:31 +08:00
59527fc954 Merge pull request #38 from zhuzichu520/dev1.2.4
update
2023-04-11 18:06:06 +08:00
c26fdfaee3 update 2023-04-11 18:05:07 +08:00
878dbd668b Merge pull request #36 from zhuzichu520/dev1.2.4
update
2023-04-11 16:31:35 +08:00
b10a0752fb update 2023-04-11 16:30:54 +08:00
51e73e7f8e fix bug 2023-04-11 16:30:07 +08:00
3a46fd11c6 update 2023-04-10 22:07:30 +08:00
70f048f629 update 2023-04-10 22:05:20 +08:00
1f2d0d9b9f update 2023-04-10 18:17:22 +08:00
09e87e0fb8 update 2023-04-09 19:29:50 +08:00
0603a7603d update 2023-04-09 18:08:37 +08:00
d9a4f01e20 update 2023-04-09 17:59:00 +08:00
93709cd1dd update 2023-04-08 21:23:03 +08:00
0000e557a7 update 2023-04-08 20:44:27 +08:00
d2183e350e update 2023-04-08 20:26:49 +08:00
47caf4bb52 update 2023-04-08 20:20:44 +08:00
6fb9ee41fb update 2023-04-08 20:12:28 +08:00
b349c22434 update 2023-04-08 20:08:26 +08:00
12fa3487bb Merge pull request #29 from LiangLiang723/win32_cmake_fix
🐛 修复 windows 下生成 dll 库带 linux 前缀导致查找不到控件
2023-04-08 19:57:14 +08:00
a76806645a 🐛 修复 windows 下生成 dll 库带 linux 前缀导致查找不到控件 2023-04-08 19:45:39 +08:00
738db25c2c Merge pull request #28 from LiangLiang723/win32_cmake_fix
🐛 修复 windows 下生成 dll 库带 linux 前缀导致查找不到控件
2023-04-08 19:43:35 +08:00
9f8a5f5646 🐛 修复 windows 下生成 dll 库带 linux 前缀导致查找不到控件 2023-04-08 19:32:35 +08:00
c59c07e756 update 2023-04-07 20:48:04 +08:00
160 changed files with 3931 additions and 2033 deletions

View File

@ -38,7 +38,7 @@ jobs:
arch: ${{ matrix.qt_arch }}
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
- name: ubuntu install GL library
run: sudo apt-get install -y libglew-dev libglfw3-dev qml-module-qtquick-controls qml-module-qtquick-controls2
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
@ -56,7 +56,7 @@ jobs:
- 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

View File

@ -2,7 +2,7 @@
## 简介
这是一个漂亮的Fluent组件库使用QML插件开发的
这是一个漂亮的Fluent组件库使用QML插件开发的。main分支是Qt6.4.3如果需要qt5的请切换至qt5分支
## 编译状态
| [Windows][win-link]| [Ubuntu][ubuntu-link]|[MacOS][macos-link]|
@ -62,6 +62,12 @@
|FluDatePicker|日期选择器||
|FluMenu|菜单Popup||
|FluNavigationView|响应式导航布局||
|FluScrollbar|滚动条||
|FluToggleButton|开关按钮||
|FluPagination|分页组件||
|FluTableView|表格组件||
|FluMediaPlayer|播放器||
|FluFlipView|FlipView||
# 部分效果预览
@ -77,6 +83,10 @@
![](doc/preview/theme.png)
## TableView表格组件
![](doc/preview/tableview.png)
## FluTreeView树组件
![](doc/preview/treeview.png)
@ -85,13 +95,5 @@
![](doc/preview/carousel.png)
## InfoBar提示框组件
![](doc/preview/infobar.png)
## 多窗口路由跳转
![](doc/preview/multiwindow.png)
### ⚡ Visitor count
![](https://profile-counter.glitch.me/zhuzichu520-FluentUI/count.svg)
![](https://profile-counter.glitch.me/zhuzichu520-FluentUI/count.svg)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 383 KiB

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 382 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 204 KiB

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

BIN
doc/preview/tableview.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 49 KiB

View File

@ -1,28 +0,0 @@
import QtQuick
import QtQuick.Window
import QtQuick.Controls
import QtQuick.Layouts
import QtMultimedia
import FluentUI
Window {
id:app
color: "#00000000"
//初始化一个MediaPlayer解决macos切换到T_MediaPalyer页面崩溃问题
MediaPlayer{}
Component.onCompleted: {
FluApp.init(app,properties)
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",
}
FluApp.initialRoute = "/"
FluApp.run()
}
}

View File

@ -7,6 +7,8 @@ set(CMAKE_AUTOUIC ON)
set(CMAKE_CXX_STANDARD 17)
file(TO_CMAKE_PATH "/" PATH_SEPARATOR)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(platform 64)
else()
@ -22,12 +24,23 @@ endif()
find_package(Qt6 COMPONENTS Core Quick QuickControls2 Concurrent Network Multimedia REQUIRED)
set(SOURCES
ChatController.cpp
main.cpp
src/controller/ChatController.cpp
src/AppInfo.cpp
src/main.cpp
src/lang/Lang.cpp
src/lang/Zh.cpp
src/lang/En.cpp
src/tool/IPC.cpp
)
set(HEADERS
ChatController.h
src/controller/ChatController.h
src/AppInfo.h
src/stdafx.h
src/lang/Lang.h
src/lang/Zh.h
src/lang/En.h
src/tool/IPC.h
)
set(RESOURCES
@ -44,20 +57,17 @@ add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${QT_RESOURCES} ${RC_ICONS}
if(WIN32)
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
file(GLOB DLL_FILES ${CMAKE_CURRENT_SOURCE_DIR}/../third/msvc/*.dll)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${DLL_FILES}
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)
set(DLLPATH ${CMAKE_CURRENT_SOURCE_DIR}/../third/msvc/*.dll)
else()
file(GLOB DLL_FILES ${CMAKE_CURRENT_SOURCE_DIR}/../third/mingw/*.dll)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${DLL_FILES}
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)
set(DLLPATH ${CMAKE_CURRENT_SOURCE_DIR}/../third/mingw/*.dll)
endif()
string(REPLACE "/" ${PATH_SEPARATOR} DLLPATH "${DLLPATH}")
file(GLOB DLL_FILES ${DLLPATH})
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${DLL_FILES}
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)
endif()
target_compile_definitions(${PROJECT_NAME} PRIVATE

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,107 +0,0 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import FluentUI
import "./component"
FluScrollablePage{
property string password: ""
property var loginPageRegister: registerForPageResult("/login")
title:"MultiWindow"
leftPadding:10
rightPadding:10
bottomPadding:20
spacing: 0
Connections{
target: loginPageRegister
function onResult(data)
{
password = data.password
}
}
FluArea{
Layout.fillWidth: true
height: 100
paddings: 10
Layout.topMargin: 20
Column{
spacing: 15
anchors{
verticalCenter: parent.verticalCenter
left: parent.left
}
FluText{
text:"页面跳转,不携带任何参数"
}
FluButton{
text:"点击跳转"
onClicked: {
FluApp.navigate("/about")
}
}
}
}
CodeExpander{
Layout.fillWidth: true
code:'FluButton{
text:"点击跳转"
onClicked: {
FluApp.navigate("/about")
}
}
'
}
FluArea{
Layout.fillWidth: true
height: 130
paddings: 10
Layout.topMargin: 20
Column{
spacing: 15
anchors{
verticalCenter: parent.verticalCenter
left: parent.left
}
FluText{
text:"页面跳转并携带参数用户名zhuzichu"
}
FluButton{
text:"点击跳转到登录"
onClicked: {
loginPageRegister.launch({username:"zhuzichu"})
}
}
FluText{
text:"登录窗口返回过来的密码->"+password
}
}
}
CodeExpander{
Layout.fillWidth: true
code:'property var loginPageRegister: registerForPageResult("/login")
Connections{
target: loginPageRegister
function onResult(data)
{
password = data.password
}
}
FluButton{
text:"点击跳转"
onClicked: {
loginPageRegister.launch({username:"zhuzichu"})
}
}
'
}
}

View File

@ -1,13 +1,24 @@
QT += quick quickcontrols2 concurrent network multimedia
QT += quick concurrent network multimedia
CONFIG += c++17
DEFINES += QT_DEPRECATED_WARNINGS QT_NO_WARNING_OUTPUT
HEADERS += \
ChatController.h
src/lang/En.h \
src/lang/Lang.h \
src/lang/Zh.h \
src/stdafx.h \
src/controller/ChatController.h \
src/AppInfo.h \
src/tool/IPC.h
SOURCES += \
ChatController.cpp \
main.cpp
src/controller/ChatController.cpp \
src/AppInfo.cpp \
src/lang/En.cpp \
src/lang/Lang.cpp \
src/lang/Zh.cpp \
src/main.cpp \
src/tool/IPC.cpp
RESOURCES += qml.qrc
@ -41,3 +52,8 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin
mac: {
QMAKE_INFO_PLIST = Info.plist
}
#### 如果你正在使用静态库,请将将下面的配置注释取消掉。
#DEFINES += STATICLIB
#INCLUDEPATH += $$OUT_PWD/../bin/FluentUI/
#LIBS += -L$$OUT_PWD/../bin/FluentUI/ -lFluentUI

View File

@ -1,21 +0,0 @@
pragma Singleton
import QtQuick
import FluentUI
FluObject{
id:footer_items
FluPaneItemSeparator{}
FluPaneItem{
title:"意见反馈"
onTap:{
Qt.openUrlExternally("https://github.com/zhuzichu520/FluentUI/issues/new")
}
}
FluPaneItem{
title:"关于"
onTap:{
FluApp.navigate("/about")
}
}
}

View File

@ -1,43 +0,0 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QDir>
#include <QQuickWindow>
#include <QQuickStyle>
#include <QProcess>
#include "ChatController.h"
QMap<QString, QVariant> properties(){
QMap<QString, QVariant> map;
// map["installHelper"] = QVariant::fromValue(QVariant::fromValue(InstallHelper::getInstance()));
return map;
}
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);
QQmlApplicationEngine engine;
qmlRegisterType<ChatController>("Controller",1,0,"ChatController");
QMapIterator<QString, QVariant> iterator(properties());
while (iterator.hasNext()) {
iterator.next();
QString key = iterator.key();
QVariant value = iterator.value();
engine.rootContext()->setContextProperty(key,value);
}
engine.rootContext()->setContextProperty("properties",properties());
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,49 +0,0 @@
import QtQuick
import QtQuick.Window
import QtQuick.Controls
import QtQuick.Layouts
import "qrc:///global/"
import FluentUI
FluWindow {
id:rootwindow
width: 1000
height: 640
title: "FluentUI"
minimumWidth: 520
minimumHeight: 460
FluAppBar{
id:appbar
z:10
showDark: true
width:parent.width
}
FluNavigationView{
id:nav_view
anchors.fill: parent
items: ItemsOriginal
footerItems:ItemsFooter
logo: "qrc:/res/image/favicon.ico"
z: 11
title:"FluentUI"
autoSuggestBox:FluAutoSuggestBox{
width: 280
anchors.centerIn: parent
iconSource: FluentIcons.Zoom
items: ItemsOriginal.getSearchData()
placeholderText: "查找"
onItemClicked:
(data)=>{
ItemsOriginal.startPageByItem(data)
}
}
Component.onCompleted: {
ItemsOriginal.navigationView = nav_view
nav_view.setCurrentIndex(0)
nav_view.push("qrc:/T_Home.qml")
}
}
}

View File

@ -1,6 +1,5 @@
<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>
@ -14,40 +13,11 @@
<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>
@ -148,14 +118,56 @@
<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>res/svg/home.svg</file>
<file>res/svg/home_dark.svg</file>
<file>res/image/qrcode_wx.jpg</file>
<file>res/image/qrcode_zfb.jpg</file>
<file>qml/component/CodeExpander.qml</file>
<file>qml/global/ItemsFooter.qml</file>
<file>qml/global/ItemsOriginal.qml</file>
<file>qml/global/MainEvent.qml</file>
<file>qml/global/qmldir</file>
<file>qml/App.qml</file>
<file>qml/window/AboutWindow.qml</file>
<file>qml/window/ChatWindow.qml</file>
<file>qml/window/LoginWindow.qml</file>
<file>qml/window/MainWindow.qml</file>
<file>qml/window/MediaWindow.qml</file>
<file>qml/window/SingleInstanceWindow.qml</file>
<file>qml/window/SingleTaskWindow.qml</file>
<file>qml/window/StandardWindow.qml</file>
<file>qml/page/T_Awesome.qml</file>
<file>qml/page/T_Badge.qml</file>
<file>qml/page/T_Buttons.qml</file>
<file>qml/page/T_CalendarPicker.qml</file>
<file>qml/page/T_Carousel.qml</file>
<file>qml/page/T_CheckBox.qml</file>
<file>qml/page/T_ColorPicker.qml</file>
<file>qml/page/T_DatePicker.qml</file>
<file>qml/page/T_Dialog.qml</file>
<file>qml/page/T_Expander.qml</file>
<file>qml/page/T_FlipView.qml</file>
<file>qml/page/T_Home.qml</file>
<file>qml/page/T_InfoBar.qml</file>
<file>qml/page/T_MediaPlayer.qml</file>
<file>qml/page/T_Menu.qml</file>
<file>qml/page/T_MultiWindow.qml</file>
<file>qml/page/T_Pivot.qml</file>
<file>qml/page/T_Progress.qml</file>
<file>qml/page/T_RatingControl.qml</file>
<file>qml/page/T_Rectangle.qml</file>
<file>qml/page/T_Settings.qml</file>
<file>qml/page/T_Slider.qml</file>
<file>qml/page/T_StatusView.qml</file>
<file>qml/page/T_TableView.qml</file>
<file>qml/page/T_TabView.qml</file>
<file>qml/page/T_TextBox.qml</file>
<file>qml/page/T_Theme.qml</file>
<file>qml/page/T_TimePicker.qml</file>
<file>qml/page/T_ToggleSwitch.qml</file>
<file>qml/page/T_Tooltip.qml</file>
<file>qml/page/T_TreeView.qml</file>
<file>qml/page/T_Typography.qml</file>
<file>qml/page/T_BreadcrumbBar.qml</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:/qml/window/MainWindow.qml",
"/about":"qrc:/qml/window/AboutWindow.qml",
"/login":"qrc:/qml/window/LoginWindow.qml",
"/chat":"qrc:/qml/window/ChatWindow.qml",
"/media":"qrc:/qml/window/MediaWindow.qml",
"/singleTaskWindow":"qrc:/qml/window/SingleTaskWindow.qml",
"/standardWindow":"qrc:/qml/window/StandardWindow.qml",
"/singleInstanceWindow":"qrc:/qml/window/SingleInstanceWindow.qml"
}
FluApp.initialRoute = "/"
FluApp.run()
}
}

View File

@ -68,7 +68,6 @@ FluExpander{
"FluComboBox",
"FluContentDialog",
"FluContentPage",
"FluControl",
"FluDatePicker",
"FluDivider",
"FluDropDownButton",
@ -113,7 +112,15 @@ FluExpander{
"FluTooltip",
"FluTreeView",
"FluWindow",
"FluWindowResize"
"FluWindowResize",
"FluToggleButton",
"FluTableView",
"FluColors",
"FluTheme",
"FluStatusView",
"FluRatingControl",
"FluPasswordBox",
"FluBreadcrumbBar"
];
code = code.replace(/\n/g, "<br>");
code = code.replace(/ /g, "&nbsp;");

View File

@ -0,0 +1,26 @@
pragma Singleton
import QtQuick
import FluentUI
FluObject{
id:footer_items
property var navigationView
FluPaneItemSeparator{}
FluPaneItem{
title:lang.about
icon:FluentIcons.Contact
tapFunc:function(){
FluApp.navigate("/about")
}
}
FluPaneItem{
title:lang.settings
icon:FluentIcons.Settings
onTap:{
navigationView.push("qrc:/qml/page/T_Settings.qml")
}
}
}

View File

@ -8,15 +8,22 @@ FluObject{
property var navigationView
FluPaneItem{
title:"Home"
icon:FluentIcons.Home
title:lang.home
// icon:FluentIcons.Home
cusIcon: Image{
anchors.centerIn: parent
source: FluTheme.dark ? "qrc:/res/svg/home_dark.svg" : "qrc:/res/svg/home.svg"
sourceSize: Qt.size(30,30)
width: 18
height: 18
}
onTap:{
navigationView.push("qrc:/T_Home.qml")
navigationView.push("qrc:/qml/page/T_Home.qml")
}
}
FluPaneItemExpander{
title:"Basic input"
title:lang.basic_input
icon:FluentIcons.CheckboxComposite
FluPaneItem{
title:"Buttons"
@ -24,7 +31,7 @@ FluObject{
recentlyUpdated:true
desc:"A control that responds to user input and raisesa Click event."
onTap:{
navigationView.push("qrc:/T_Buttons.qml")
navigationView.push("qrc:/qml/page/T_Buttons.qml")
}
}
FluPaneItem{
@ -33,7 +40,7 @@ FluObject{
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:/qml/page/T_Slider.qml")
}
}
FluPaneItem{
@ -42,54 +49,54 @@ FluObject{
recentlyUpdated:true
desc:"A control that a user can select or clear."
onTap:{
navigationView.push("qrc:/T_CheckBox.qml")
navigationView.push("qrc:/qml/page/T_CheckBox.qml")
}
}
FluPaneItem{
title:"ToggleSwitch"
onTap:{
navigationView.push("qrc:/T_ToggleSwitch.qml")
navigationView.push("qrc:/qml/page/T_ToggleSwitch.qml")
}
}
}
FluPaneItemExpander{
title:"Form"
title:lang.form
icon:FluentIcons.GridView
FluPaneItem{
title:"TextBox"
onTap:{
navigationView.push("qrc:/T_TextBox.qml")
navigationView.push("qrc:/qml/page/T_TextBox.qml")
}
}
FluPaneItem{
title:"TimePicker"
onTap:{
navigationView.push("qrc:/T_TimePicker.qml")
navigationView.push("qrc:/qml/page/T_TimePicker.qml")
}
}
FluPaneItem{
title:"DatePicker"
onTap:{
navigationView.push("qrc:/T_DatePicker.qml")
navigationView.push("qrc:/qml/page/T_DatePicker.qml")
}
}
FluPaneItem{
title:"CalendarPicker"
onTap:{
navigationView.push("qrc:/T_CalendarPicker.qml")
navigationView.push("qrc:/qml/page/T_CalendarPicker.qml")
}
}
FluPaneItem{
title:"ColorPicker"
onTap:{
navigationView.push("qrc:/T_ColorPicker.qml")
navigationView.push("qrc:/qml/page/T_ColorPicker.qml")
}
}
}
FluPaneItemExpander{
title:"Surface"
title:lang.surface
icon:FluentIcons.SurfaceHub
FluPaneItem{
title:"InfoBar"
@ -97,66 +104,78 @@ FluObject{
recentlyUpdated:true
desc:"An inline message to display app-wide statuschange information."
onTap:{
navigationView.push("qrc:/T_InfoBar.qml")
navigationView.push("qrc:/qml/page/T_InfoBar.qml")
}
}
FluPaneItem{
title:"Progress"
onTap:{
navigationView.push("qrc:/T_Progress.qml")
navigationView.push("qrc:/qml/page/T_Progress.qml")
}
}
FluPaneItem{
title:"RatingControl"
onTap:{
navigationView.push("qrc:/qml/page/T_RatingControl.qml")
}
}
FluPaneItem{
title:"Badge"
onTap:{
navigationView.push("qrc:/T_Badge.qml")
navigationView.push("qrc:/qml/page/T_Badge.qml")
}
}
FluPaneItem{
title:"Rectangle"
onTap:{
navigationView.push("qrc:/T_Rectangle.qml")
navigationView.push("qrc:/qml/page/T_Rectangle.qml")
}
}
FluPaneItem{
title:"StatusView"
onTap:{
navigationView.push("qrc:/qml/page/T_StatusView.qml")
}
}
FluPaneItem{
title:"Carousel"
onTap:{
navigationView.push("qrc:/T_Carousel.qml")
navigationView.push("qrc:/qml/page/T_Carousel.qml")
}
}
FluPaneItem{
title:"Expander"
onTap:{
navigationView.push("qrc:/T_Expander.qml")
navigationView.push("qrc:/qml/page/T_Expander.qml")
}
}
}
FluPaneItemExpander{
title:"Popus"
title:lang.popus
icon:FluentIcons.ButtonMenu
FluPaneItem{
title:"Dialog"
onTap:{
navigationView.push("qrc:/T_Dialog.qml")
navigationView.push("qrc:/qml/page/T_Dialog.qml")
}
}
FluPaneItem{
title:"Tooltip"
onTap:{
navigationView.push("qrc:/T_Tooltip.qml")
navigationView.push("qrc:/qml/page/T_Tooltip.qml")
}
}
FluPaneItem{
title:"Menu"
onTap:{
navigationView.push("qrc:/T_Menu.qml")
navigationView.push("qrc:/qml/page/T_Menu.qml")
}
}
}
FluPaneItemExpander{
title:"Navigation"
title:lang.navigation
icon:FluentIcons.AllApps
FluPaneItem{
title:"Pivot"
@ -165,7 +184,13 @@ FluObject{
order:3
desc:"Presents information from different sources in atabbed view."
onTap:{
navigationView.push("qrc:/T_Pivot.qml")
navigationView.push("qrc:/qml/page/T_Pivot.qml")
}
}
FluPaneItem{
title:"BreadcrumbBar"
onTap:{
navigationView.push("qrc:/qml/page/T_BreadcrumbBar.qml")
}
}
FluPaneItem{
@ -175,13 +200,13 @@ FluObject{
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:/qml/page/T_TabView.qml")
}
}
FluPaneItem{
title:"TreeView"
onTap:{
navigationView.push("qrc:/T_TreeView.qml")
navigationView.push("qrc:/qml/page/T_TreeView.qml")
}
}
FluPaneItem{
@ -191,13 +216,13 @@ FluObject{
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:/qml/page/T_TableView.qml")
}
}
FluPaneItem{
title:"MultiWindow"
onTap:{
navigationView.push("qrc:/T_MultiWindow.qml")
navigationView.push("qrc:/qml/page/T_MultiWindow.qml")
}
}
FluPaneItem{
@ -207,36 +232,36 @@ FluObject{
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:/qml/page/T_FlipView.qml")
}
}
}
FluPaneItemExpander{
title:"Theming"
title:lang.theming
icon:FluentIcons.Brightness
FluPaneItem{
title:"Theme"
onTap:{
navigationView.push("qrc:/T_Theme.qml")
navigationView.push("qrc:/qml/page/T_Theme.qml")
}
}
FluPaneItem{
title:"Typography"
onTap:{
navigationView.push("qrc:/T_Typography.qml")
navigationView.push("qrc:/qml/page/T_Typography.qml")
}
}
FluPaneItem{
title:"Awesome"
onTap:{
navigationView.push("qrc:/T_Awesome.qml")
navigationView.push("qrc:/qml/page/T_Awesome.qml")
}
}
}
FluPaneItemExpander{
title:"Media"
title:lang.media
icon:FluentIcons.Media
FluPaneItem{
title:"MediaPlayer"
@ -245,7 +270,7 @@ FluObject{
order:0
desc:"A control to display video and image content."
onTap:{
navigationView.push("qrc:/T_MediaPlayer.qml")
navigationView.push("qrc:/qml/page/T_MediaPlayer.qml")
}
}
}
@ -295,21 +320,7 @@ FluObject{
}
function startPageByItem(data){
var items = navigationView.getItems();
for(var i=0;i<items.length;i++){
var item = items[i]
if(item.key === data.key){
if(navigationView.getCurrentIndex() === i){
return
}
item.tap()
navigationView.setCurrentIndex(i)
if(item.parent){
item.parent.isExpand = true
}
return
}
}
navigationView.startPageByItem(data)
}
}

View File

@ -0,0 +1,9 @@
pragma Singleton
import QtQuick
import QtQuick.Controls
import FluentUI
QtObject {
property int displayMode : FluNavigationView.Auto
}

View File

@ -1,2 +1,3 @@
singleton ItemsOriginal 1.0 ItemsOriginal.qml
singleton ItemsFooter 1.0 ItemsFooter.qml
singleton MainEvent 1.0 MainEvent.qml

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{
@ -39,6 +39,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluCarousel{
width: 400
height: 300

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{
@ -44,6 +44,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluFlipView{
Image{
source: "qrc:/res/image/banner_1.jpg"
@ -97,6 +98,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluFlipView{
vertical:true
Image{

View File

@ -2,7 +2,7 @@
import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import "qrc:///global/"
import "qrc:///qml/global/"
import FluentUI
FluScrollablePage{

View File

@ -3,7 +3,7 @@ import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -52,12 +52,13 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
code:' showInfo("这是一个Info样式的InfoBar")
Layout.topMargin: -1
code:'showInfo("这是一个Info样式的InfoBar")
showWarning("这是一个Warning样式的InfoBar")
showWarning("这是一个Warning样式的InfoBar")
showError("这是一个Error样式的InfoBar")
showError("这是一个Error样式的InfoBar")
showSuccess("这是一个Success样式的InfoBar这是一个Success样式的InfoBar")'
showSuccess("这是一个Success样式的InfoBar这是一个Success样式的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

@ -0,0 +1,190 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import FluentUI
import "../component"
FluScrollablePage{
property string password: ""
property var loginPageRegister: registerForWindowResult("/login")
title:"MultiWindow"
leftPadding:10
rightPadding:10
bottomPadding:20
spacing: 0
Connections{
target: loginPageRegister
function onResult(data)
{
password = data.password
}
}
FluArea{
Layout.fillWidth: true
height: 86
paddings: 10
Layout.topMargin: 20
Column{
spacing: 15
anchors{
verticalCenter: parent.verticalCenter
left: parent.left
}
FluText{
text:"<font color='red'>Standard</font>模式窗口,每次都会创建新窗口"
}
FluButton{
text:"点击创建窗口"
onClicked: {
FluApp.navigate("/standardWindow")
}
}
}
}
FluArea{
Layout.fillWidth: true
height: 86
paddings: 10
Layout.topMargin: 10
Column{
spacing: 15
anchors{
verticalCenter: parent.verticalCenter
left: parent.left
}
FluText{
text:"<font color='red'>SingleTask</font>模式窗口,如果窗口存在,这激活该窗口"
textFormat: Text.RichText
}
FluButton{
text:"点击创建窗口"
onClicked: {
FluApp.navigate("/singleTaskWindow")
}
}
}
}
FluArea{
Layout.fillWidth: true
height: 86
paddings: 10
Layout.topMargin: 10
Column{
spacing: 15
anchors{
verticalCenter: parent.verticalCenter
left: parent.left
}
FluText{
text:"<font color='red'>SingleInstance</font>模式窗口,如果窗口存在,则销毁窗口,然后新建窗口"
}
FluButton{
text:"点击创建窗口"
onClicked: {
FluApp.navigate("/singleInstanceWindow")
}
}
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluWindow{
//launchMode: FluWindow.Standard
//launchMode: FluWindow.SingleTask
launchMode: FluWindow.SingleInstance
}
'
}
FluArea{
Layout.fillWidth: true
height: 100
paddings: 10
Layout.topMargin: 20
Column{
spacing: 15
anchors{
verticalCenter: parent.verticalCenter
left: parent.left
}
FluText{
text:"页面跳转,不携带任何参数"
}
FluButton{
text:"点击跳转"
onClicked: {
FluApp.navigate("/about")
}
}
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluButton{
text:"点击跳转"
onClicked: {
FluApp.navigate("/about")
}
}
'
}
FluArea{
Layout.fillWidth: true
height: 130
paddings: 10
Layout.topMargin: 20
Column{
spacing: 15
anchors{
verticalCenter: parent.verticalCenter
left: parent.left
}
FluText{
text:"页面跳转并携带参数用户名zhuzichu"
}
FluButton{
text:"点击跳转到登录"
onClicked: {
loginPageRegister.launch({username:"zhuzichu"})
}
}
FluText{
text:"登录窗口返回过来的密码->"+password
}
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'property var loginPageRegister: registerForWindowResult("/login")
Connections{
target: loginPageRegister
function onResult(data)
{
password = data.password
}
}
FluButton{
text:"点击跳转"
onClicked: {
loginPageRegister.launch({username:"zhuzichu"})
}
}
'
}
}

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Window
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -21,6 +21,7 @@ FluScrollablePage{
FluPivot{
anchors.fill: parent
currentIndex: 2
FluPivotItem{
title:"All"
contentItem:FluText{
@ -49,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

@ -0,0 +1,44 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import FluentUI
import "../component"
FluScrollablePage{
title:"RatingControl"
leftPadding:10
rightPadding:10
bottomPadding:20
spacing: 0
FluArea{
Layout.fillWidth: true
height: 100
paddings: 10
Layout.topMargin: 20
Column{
spacing: 10
anchors.verticalCenter: parent.verticalCenter
FluRatingControl{
}
FluRatingControl{
number:10
}
}
}
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{
@ -134,6 +134,7 @@ FluScrollablePage{
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluRectangle{
radius: [25,25,25,25]
width: 50

View File

@ -0,0 +1,117 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import FluentUI
import "qrc:///qml/global/"
import "../component"
FluScrollablePage{
title:"Settings"
leftPadding:10
rightPadding:10
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
height: 168
paddings: 10
ColumnLayout{
spacing: 10
anchors{
top: parent.top
left: parent.left
}
FluText{
text:lang.navigation_view_display_mode
fontStyle: FluText.BodyStrong
Layout.bottomMargin: 4
}
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
text:modelData.title
onClicked:{
MainEvent.displayMode = modelData.mode
}
}
}
}
}
FluArea{
Layout.fillWidth: true
Layout.topMargin: 20
height: 80
paddings: 10
ColumnLayout{
spacing: 10
anchors{
top: parent.top
left: parent.left
}
FluText{
text:lang.locale
fontStyle: FluText.BodyStrong
Layout.bottomMargin: 4
}
Flow{
spacing: 5
Repeater{
model: ["Zh","En"]
delegate: FluRadioButton{
selected : appInfo.lang.objectName === modelData
text:modelData
onClicked:{
console.debug(modelData)
appInfo.changeLang(modelData)
}
}
}
}
}
}
}

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

@ -0,0 +1,92 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Window
import FluentUI
import "../component"
FluScrollablePage{
title:"StatusView"
leftPadding:10
rightPadding:10
bottomPadding:20
spacing: 0
FluArea{
id:layout_actions
Layout.fillWidth: true
Layout.topMargin: 20
height: 50
paddings: 10
RowLayout{
spacing: 14
FluDropDownButton{
id:btn_status_mode
Layout.preferredWidth: 140
text:"Loading"
items:[
FluMenuItem{
text:"Loading"
onClicked: {
btn_status_mode.text = text
status_view.statusMode = FluStatusView.Loading
}
},
FluMenuItem{
text:"Empty"
onClicked: {
btn_status_mode.text = text
status_view.statusMode = FluStatusView.Empty
}
},
FluMenuItem{
text:"Error"
onClicked: {
btn_status_mode.text = text
status_view.statusMode = FluStatusView.Error
}
},
FluMenuItem{
text:"Success"
onClicked: {
btn_status_mode.text = text
status_view.statusMode = FluStatusView.Success
}
}
]
}
}
}
FluArea{
Layout.fillWidth: true
Layout.topMargin: 10
height: 380
paddings: 10
FluStatusView{
id:status_view
anchors.fill: parent
onErrorClicked:{
showError("点击重新加载")
}
Rectangle {
anchors.fill: parent
color:FluTheme.primaryColor.dark
}
}
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluStatusView{
anchors.fill: parent
statusMode: FluStatusView.Loading
Rectangle{
anchors.fill: parent
color:FluTheme.primaryColor.dark
}
}'
}
}

View File

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

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Window
import FluentUI
import "./component"
import "../component"
FluScrollablePage{
@ -45,12 +45,10 @@ FluScrollablePage{
loadData(1,10)
}
FluTableView{
id:table_view
Layout.fillWidth: true
Layout.topMargin: 20
width:parent.width
pageCurrent:1
pageCount:10
itemCount: 1000
@ -70,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))
@ -81,8 +79,8 @@ FluScrollablePage{
text:"删除"
topPadding:3
bottomPadding:3
leftPadding:3
rightPadding:3
leftPadding:6
rightPadding:6
onClicked:{
showError(JSON.stringify(dataObject))
}
@ -102,9 +100,60 @@ FluScrollablePage{
action:com_action
})
}
table_view.dataSource = dataSource
}
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: 10
code:'FluTableView{
id:table_view
Layout.fillWidth: true
Layout.topMargin: 20
pageCurrent:1
pageCount:10
itemCount: 1000
onRequestPage:
(page,count)=> {
loadData(page,count)
}
Component.onCompleted: {
const columns = [
{
title: "姓名",
dataIndex: "name",
width:100
},
{
title: "年龄",
dataIndex: "age",
width:100
},
{
title: "住址",
dataIndex: "address",
width:200
},
{
title: "别名",
dataIndex: "nickname",
width:100
}
];
table_view.columns = columns
const dataSource = [
{
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

@ -5,14 +5,15 @@ import FluentUI
FluWindow {
width: 500
height: 600
minimumWidth: 500
minimumHeight: 600
maximumWidth: 500
maximumHeight: 600
id:window
title:"关于"
width: 600
height: 600
minimumWidth: 600
minimumHeight: 600
maximumWidth: 600
maximumHeight: 600
launchMode: FluWindow.SingleTask
FluAppBar{
id:appbar
@ -36,7 +37,7 @@ FluWindow {
fontStyle: FluText.Title
}
FluText{
text:"v1.2.1"
text:"v%1".arg(appInfo.version)
fontStyle: FluText.Body
Layout.alignment: Qt.AlignBottom
}
@ -57,13 +58,14 @@ FluWindow {
RowLayout{
spacing: 14
Layout.topMargin: 20
Layout.leftMargin: 15
FluText{
text:"GitHub"
}
FluTextButton{
id:text_hublink
topPadding:0
bottomPadding:0
text:"https://github.com/zhuzichu520/FluentUI"
Layout.alignment: Qt.AlignBottom
onClicked: {
@ -71,13 +73,30 @@ FluWindow {
}
}
}
RowLayout{
spacing: 14
Layout.leftMargin: 15
FluText{
text:"B站"
}
FluTextButton{
topPadding:0
bottomPadding:0
text:"https://www.bilibili.com/video/BV1mg4y1M71w/"
Layout.alignment: Qt.AlignBottom
onClicked: {
Qt.openUrlExternally(text)
}
}
}
RowLayout{
spacing: 14
Layout.topMargin: 20
Layout.leftMargin: 15
FluText{
id:text_info
text:"如果该项目对你有作用就请点击上方链接给一个免费的star"
text:"如果该项目对你有作用就请点击上方链接给一个免费的star,或者一键三连,谢谢"
ColorAnimation {
id: animation
target: text_info
@ -91,5 +110,43 @@ FluWindow {
}
}
}
RowLayout{
spacing: 14
Layout.leftMargin: 15
FluText{
text:"捐赠:"
}
}
Item{
Layout.preferredWidth: parent.width
Layout.preferredHeight: 252
Row{
anchors.horizontalCenter: parent.horizontalCenter
spacing: 60
Image{
width: 164.55
height: 224.25
source: "qrc:/res/image/qrcode_wx.jpg"
}
Image{
width: 162
height: 252
source: "qrc:/res/image/qrcode_zfb.jpg"
}
}
}
RowLayout{
spacing: 14
Layout.leftMargin: 15
FluText{
id:text_desc
text:"个人开发,维护不易,你们的捐赠就是我继续更新的动力!\n有什么问题提Issues只要时间充足我就会解决的"
}
}
}
}

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

View File

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

View File

@ -0,0 +1,111 @@
import QtQuick
import QtQuick.Window
import QtQuick.Controls
import QtQuick.Layouts
import Qt.labs.platform
import FluentUI
import "qrc:///qml/global/"
FluWindow {
id:window
title: "FluentUI"
width: 1000
height: 640
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
showDark: true
width:parent.width
darkText: lang.dark_mode
}
SystemTrayIcon {
id:system_tray
visible: true
icon.source: "qrc:/res/image/favicon.ico"
tooltip: "FluentUI"
menu: Menu {
MenuItem {
text: "退出"
onTriggered: {
window.destoryWindow()
FluApp.closeApp()
}
}
}
onActivated:
(reason)=>{
if(reason === SystemTrayIcon.Trigger){
window.show()
window.raise()
window.requestActivate()
}
}
}
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
anchors.fill: parent
items: ItemsOriginal
footerItems:ItemsFooter
z:11
displayMode:MainEvent.displayMode
logo: "qrc:/res/image/favicon.ico"
title:"FluentUI"
autoSuggestBox:FluAutoSuggestBox{
width: 280
anchors.centerIn: parent
iconSource: FluentIcons.Search
items: ItemsOriginal.getSearchData()
placeholderText: lang.search
onItemClicked:
(data)=>{
ItemsOriginal.startPageByItem(data)
}
}
Component.onCompleted: {
ItemsOriginal.navigationView = nav_view
ItemsFooter.navigationView = nav_view
nav_view.setCurrentIndex(0)
}
}
}

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

@ -0,0 +1,44 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import FluentUI
FluWindow {
id:window
title:"SingleInstance"
width: 500
height: 600
minimumWidth: 500
minimumHeight: 600
maximumWidth: 500
maximumHeight: 600
launchMode: FluWindow.SingleInstance
FluAppBar{
id:appbar
title:"SingleInstance"
width:parent.width
}
FluTextBox{
anchors{
top:parent.top
topMargin:60
horizontalCenter: parent.horizontalCenter
}
}
FluText{
wrapMode: Text.WrapAnywhere
anchors{
left: parent.left
right: parent.right
leftMargin: 20
rightMargin: 20
verticalCenter: parent.verticalCenter
}
text:"我是一个SingleInstance模式的窗口如果我存在我会销毁之前的窗口并创建一个新窗口"
}
}

View File

@ -0,0 +1,29 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import FluentUI
FluWindow {
id:window
title:"SingleTask"
width: 500
height: 600
minimumWidth: 500
minimumHeight: 600
maximumWidth: 500
maximumHeight: 600
launchMode: FluWindow.SingleTask
FluAppBar{
id:appbar
title:"SingleTask"
width:parent.width
}
FluText{
anchors.centerIn: parent
text:"我是一个SingleTask模式的窗口如果我存在我就激活窗口"
}
}

View File

@ -0,0 +1,29 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import FluentUI
FluWindow {
id:window
title:"Standard"
width: 500
height: 600
minimumWidth: 500
minimumHeight: 600
maximumWidth: 500
maximumHeight: 600
launchMode: FluWindow.Standard
FluAppBar{
id:appbar
title:"Standard"
width:parent.width
}
FluText{
anchors.centerIn: parent
text:"我是一个Standard模式的窗口每次我都会创建一个新的窗口"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

1
example/res/svg/home.svg Normal file
View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1681271578882" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3664" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M923.733333 394.666667c-85.333333-70.4-206.933333-174.933333-362.666666-309.333334C533.333333 61.866667 490.666667 61.866667 462.933333 85.333333c-155.733333 134.4-277.333333 238.933333-362.666666 309.333334-14.933333 14.933333-25.6 34.133333-25.6 53.333333 0 38.4 32 70.4 70.4 70.4H192v358.4c0 29.866667 23.466667 53.333333 53.333333 53.333333H405.333333c29.866667 0 53.333333-23.466667 53.333334-53.333333v-206.933333h106.666666v206.933333c0 29.866667 23.466667 53.333333 53.333334 53.333333h160c29.866667 0 53.333333-23.466667 53.333333-53.333333V518.4h46.933333c38.4 0 70.4-32 70.4-70.4 0-21.333333-10.666667-40.533333-25.6-53.333333z m-44.8 59.733333h-57.6c-29.866667 0-53.333333 23.466667-53.333333 53.333333v358.4h-138.666667V661.333333c0-29.866667-23.466667-53.333333-53.333333-53.333333h-128c-29.866667 0-53.333333 23.466667-53.333333 53.333333v206.933334H256V507.733333c0-29.866667-23.466667-53.333333-53.333333-53.333333H145.066667c-4.266667 0-6.4-2.133333-6.4-6.4 0-2.133333 2.133333-4.266667 2.133333-6.4 85.333333-70.4 206.933333-174.933333 362.666667-309.333333 4.266667-4.266667 10.666667-4.266667 14.933333 0 155.733333 134.4 277.333333 238.933333 362.666667 309.333333 2.133333 2.133333 2.133333 2.133333 2.133333 4.266667 2.133333 6.4-2.133333 8.533333-4.266667 8.533333z" fill="#2c2c2c" p-id="3665"></path></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1681277986581" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3875" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M923.733333 394.666667c-85.333333-70.4-206.933333-174.933333-362.666666-309.333334C533.333333 61.866667 490.666667 61.866667 462.933333 85.333333c-155.733333 134.4-277.333333 238.933333-362.666666 309.333334-14.933333 14.933333-25.6 34.133333-25.6 53.333333 0 38.4 32 70.4 70.4 70.4H192v358.4c0 29.866667 23.466667 53.333333 53.333333 53.333333H405.333333c29.866667 0 53.333333-23.466667 53.333334-53.333333v-206.933333h106.666666v206.933333c0 29.866667 23.466667 53.333333 53.333334 53.333333h160c29.866667 0 53.333333-23.466667 53.333333-53.333333V518.4h46.933333c38.4 0 70.4-32 70.4-70.4 0-21.333333-10.666667-40.533333-25.6-53.333333z m-44.8 59.733333h-57.6c-29.866667 0-53.333333 23.466667-53.333333 53.333333v358.4h-138.666667V661.333333c0-29.866667-23.466667-53.333333-53.333333-53.333333h-128c-29.866667 0-53.333333 23.466667-53.333333 53.333333v206.933334H256V507.733333c0-29.866667-23.466667-53.333333-53.333333-53.333333H145.066667c-4.266667 0-6.4-2.133333-6.4-6.4 0-2.133333 2.133333-4.266667 2.133333-6.4 85.333333-70.4 206.933333-174.933333 362.666667-309.333333 4.266667-4.266667 10.666667-4.266667 14.933333 0 155.733333 134.4 277.333333 238.933333 362.666667 309.333333 2.133333 2.133333 2.133333 2.133333 2.133333 4.266667 2.133333 6.4-2.133333 8.533333-4.266667 8.533333z" fill="#ffffff" p-id="3876"></path></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

24
example/src/AppInfo.cpp Normal file
View File

@ -0,0 +1,24 @@
#include "AppInfo.h"
#include "lang/En.h"
#include "lang/Zh.h"
AppInfo::AppInfo(QObject *parent)
: QObject{parent}
{
version("1.2.7");
lang(new En());
}
void AppInfo::changeLang(const QString& locale){
if(_lang){
_lang->deleteLater();
}
if(locale=="Zh"){
lang(new Zh());
}else if(locale=="En"){
lang(new En());
}else {
lang(new En());
}
}

19
example/src/AppInfo.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef APPINFO_H
#define APPINFO_H
#include <QObject>
#include "lang/Lang.h"
#include "stdafx.h"
class AppInfo : public QObject
{
Q_OBJECT
Q_PROPERTY_AUTO(QString,version)
Q_PROPERTY_AUTO(Lang*,lang)
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
{

22
example/src/lang/En.cpp Normal file
View File

@ -0,0 +1,22 @@
#include "En.h"
En::En(QObject *parent)
: Lang{parent}
{
setObjectName("En");
home("Home");
basic_input("Basic Input");
form("Form");
surface("Surfaces");
popus("Popus");
navigation("Navigation");
theming("Theming");
media("Media");
dark_mode("Dark Mode");
sys_dark_mode("Sync with system");
search("Search");
about("About");
settings("Settings");
locale("Locale");
navigation_view_display_mode("NavigationView Display Mode");
}

17
example/src/lang/En.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef EN_H
#define EN_H
#include <QObject>
#include "Lang.h"
class En : public Lang
{
Q_OBJECT
public:
explicit En(QObject *parent = nullptr);
signals:
};
#endif // EN_H

View File

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

30
example/src/lang/Lang.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef LANG_H
#define LANG_H
#include <QObject>
#include "../stdafx.h"
class Lang : public QObject
{
Q_OBJECT
Q_PROPERTY_AUTO(QString,home);
Q_PROPERTY_AUTO(QString,basic_input);
Q_PROPERTY_AUTO(QString,form);
Q_PROPERTY_AUTO(QString,surface);
Q_PROPERTY_AUTO(QString,popus);
Q_PROPERTY_AUTO(QString,navigation);
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);
Q_PROPERTY_AUTO(QString,navigation_view_display_mode);
Q_PROPERTY_AUTO(QString,locale);
public:
explicit Lang(QObject *parent = nullptr);
};
#endif // LANG_H

22
example/src/lang/Zh.cpp Normal file
View File

@ -0,0 +1,22 @@
#include "Zh.h"
Zh::Zh(QObject *parent)
: Lang{parent}
{
setObjectName("Zh");
home("首页");
basic_input("基本输入");
form("表单");
surface("表面");
popus("弹窗");
navigation("导航");
theming("主题");
media("媒体");
dark_mode("夜间模式");
sys_dark_mode("跟随系统");
search("查找");
about("关于");
settings("设置");
locale("语言环境");
navigation_view_display_mode("导航视图显示模式");
}

17
example/src/lang/Zh.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef ZH_H
#define ZH_H
#include <QObject>
#include "Lang.h"
class Zh : public Lang
{
Q_OBJECT
public:
explicit Zh(QObject *parent = nullptr);
signals:
};
#endif // ZH_H

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:/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

@ -10,6 +10,10 @@ 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 "")
endif()
set(TARGET_RESOURCES res.qrc)
set(TARGET_SOURCES
Def.cpp
@ -20,6 +24,7 @@ set(TARGET_SOURCES
FluTheme.cpp
Fluent.cpp
FluentUI.cpp
NativeEventFilter.cpp
WindowHelper.cpp
qml_plugin.cpp
)
@ -33,20 +38,14 @@ set(TARGET_HEADERS
FluTheme.h
Fluent.h
FluentUI.h
FramelessView.h
NativeEventFilter.h
WindowHelper.h
qml_plugin.h
stdafx.h
)
if(WIN32)
set(TARGET_SOURCES ${TARGET_SOURCES} FramelessView_win.cpp)
else()
set(TARGET_SOURCES ${TARGET_SOURCES} FramelessView_unix.cpp)
endif()
add_definitions(-DVERSION_IN="1.0.0")
add_definitions(-DVURI_STR="FluentUI")
add_definitions(-DURI_STR="FluentUI")
add_library(${PROJECT_NAME} ${TARGET_TYPE} ${TARGET_SOURCES} ${TARGET_HEADERS} ${TARGET_RESOURCES})

View File

@ -3,6 +3,16 @@
#include <QObject>
namespace Fluent_DarkMode {
Q_NAMESPACE
enum Fluent_DarkModeType {
System = 0x0,
Light = 0x1,
Dark = 0x2,
};
Q_ENUMS(Fluent_DarkModeType);
}
namespace Fluent_Awesome {
Q_NAMESPACE
enum class Fluent_AwesomeType {

View File

@ -7,8 +7,22 @@
#include <QTimer>
#include <QUuid>
#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>
static bool isCompositionEnabled()
{
BOOL composition_enabled = FALSE;
bool success = ::DwmIsCompositionEnabled(&composition_enabled) == S_OK;
return composition_enabled && success;
}
#endif
FluApp* FluApp::m_instance = nullptr;
@ -25,12 +39,16 @@ FluApp::FluApp(QObject *parent)
{
}
void FluApp::init(QWindow *window,QMap<QString, QVariant> properties){
void FluApp::init(QQuickWindow *window){
this->appWindow = window;
this->properties = properties;
}
void FluApp::run(){
#ifdef Q_OS_WIN
if(!isCompositionEnabled()){
FluTheme::getInstance()->frameless(false);
}
#endif
navigate(initialRoute());
}
@ -39,38 +57,45 @@ void FluApp::navigate(const QString& route,const QJsonObject& argument,FluRegist
qErrnoWarning("没有找到当前路由");
return;
}
bool isAppWindow = route == initialRoute();
FramelessView *view = new FramelessView();
QQmlEngine *engine = qmlEngine(appWindow);
QQmlComponent component(engine, routes().value(route).toString());
QVariantMap properties;
properties.insert("route",route);
if(fluRegister){
properties.insert("pageRegister",QVariant::fromValue(fluRegister));
}
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->requestActivate();
view->deleteLater();
return;
}
}
}else if(launchMode==2){
for (auto& pair : wnds) {
QString r = pair->property("route").toString();
if(r == route){
pair->close();
break;
}
}
}
if(FluTheme::getInstance()->frameless()){
view->setFlag(Qt::FramelessWindowHint,true);
}
wnds.insert(view->winId(),view);
if(fluRegister){
fluRegister->to(view);
view->setProperty("pageRegister",QVariant::fromValue(fluRegister));
}
view->setProperty("argument",argument);
QMapIterator<QString, QVariant> iterator(properties);
while (iterator.hasNext()) {
iterator.next();
QString key = iterator.key();
QVariant value = iterator.value();
view->engine()->rootContext()->setContextProperty(key,value);
}
view->setColor(QColor(Qt::transparent));
QObject::connect(view, &QQuickView::statusChanged, view, [&](QQuickView::Status status) {
if (status == QQuickView::Status::Ready) {
Q_EMIT windowReady(view);
view->moveToScreenCenter();
view->show();
}
});
view->setSource((routes().value(route).toString()));
if(isAppWindow){
QObject::connect(view->engine(), &QQmlEngine::quit, qApp, &QCoreApplication::quit);
}else{
view->closeDeleteLater();
}
}
bool FluApp::equalsWindow(FramelessView *view,QWindow *window){
return view->winId() == window->winId();
view->show();
}
QJsonArray FluApp::awesomelist(const QString& keyword)
@ -104,3 +129,7 @@ void FluApp::clipText(const QString& text){
QString FluApp::uuid(){
return QUuid::createUuid().toString();
}
void FluApp::closeApp(){
qApp->exit(0);
}

View File

@ -8,7 +8,6 @@
#include <QJsonObject>
#include <QQmlEngine>
#include "FluRegister.h"
#include "FramelessView.h"
#include "stdafx.h"
class FluApp : public QObject
@ -27,11 +26,7 @@ public:
Q_INVOKABLE void navigate(const QString& route,const QJsonObject& argument = {},FluRegister* fluRegister = nullptr);
Q_INVOKABLE void init(QWindow *window,QMap<QString, QVariant> properties);
Q_SIGNAL void windowReady(FramelessView *view);
Q_INVOKABLE bool equalsWindow(FramelessView *view,QWindow *window);
Q_INVOKABLE void init(QQuickWindow *window);
Q_INVOKABLE QJsonArray awesomelist(const QString& keyword = "");
@ -39,11 +34,13 @@ public:
Q_INVOKABLE QString uuid();
Q_INVOKABLE void closeApp();
public:
QMap<quint64, QQuickWindow*> wnds;
private:
QMap<QString, QVariant> properties;
static FluApp* m_instance;
QWindow *appWindow;
};
#endif // FLUAPP_H

View File

@ -2,15 +2,15 @@
#define FLUREGISTER_H
#include <QObject>
#include <FramelessView.h>
#include <QQuickWindow>
#include <QJsonObject>
#include "stdafx.h"
class FluRegister : public QObject
{
Q_OBJECT
Q_PROPERTY_AUTO(FramelessView*,from)
Q_PROPERTY_AUTO(FramelessView*,to)
Q_PROPERTY_AUTO(QQuickWindow*,from)
Q_PROPERTY_AUTO(QQuickWindow*,to)
Q_PROPERTY_AUTO(QString,path);
public:
explicit FluRegister(QObject *parent = nullptr);

View File

@ -1,6 +1,9 @@
#include "FluTheme.h"
#include "FluColors.h"
#include "Def.h"
#include <QPalette>
#include <QGuiApplication>
FluTheme* FluTheme::m_instance = nullptr;
@ -15,9 +18,44 @@ FluTheme *FluTheme::getInstance()
FluTheme::FluTheme(QObject *parent)
: QObject{parent}
{
connect(this,&FluTheme::darkModeChanged,this,[=]{
Q_EMIT darkChanged();
});
primaryColor(FluColors::getInstance()->Blue());
textSize(13);
nativeText(true);
nativeText(false);
frameless(true);
dark(false);
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

@ -8,17 +8,22 @@
class FluTheme : public QObject
{
Q_OBJECT
Q_PROPERTY(bool dark READ dark NOTIFY darkChanged)
Q_PROPERTY_AUTO(FluColorSet*,primaryColor)
Q_PROPERTY_AUTO(bool,frameless);
Q_PROPERTY_AUTO(bool,dark);
Q_PROPERTY_AUTO(int,darkMode);
Q_PROPERTY_AUTO(bool,nativeText);
Q_PROPERTY_AUTO(int,textSize);
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

View File

@ -5,6 +5,7 @@
#include <QGuiApplication>
#include <QQuickWindow>
#include "FluColors.h"
#include "NativeEventFilter.h"
#include "FluTheme.h"
#include "WindowHelper.h"
#include "FluApp.h"
@ -33,6 +34,10 @@ void Fluent::registerTypes(const char *uri){
qmlRegisterType<WindowHelper>(uri,major,minor,"WindowHelper");
qmlRegisterType<FluColorSet>(uri,major,minor,"FluColorSet");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluBreadcrumbBar.qml"),uri,major,minor,"FluBreadcrumbBar");
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");
@ -84,15 +89,20 @@ void Fluent::registerTypes(const char *uri){
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/FluPasswordBox.qml"),uri,major,minor,"FluPasswordBox");
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");
qmlRegisterUncreatableMetaObject(Fluent_DarkMode::staticMetaObject, uri,major,minor,"FluDarkMode", "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

View File

@ -3,17 +3,25 @@
#include <QObject>
#include <QQmlEngine>
#include "NativeEventFilter.h"
class Fluent: public QObject
{
Q_OBJECT
public:
Q_INVOKABLE QString version() const;
~Fluent(){
if (nativeEvent != Q_NULLPTR) {
delete nativeEvent;
nativeEvent = Q_NULLPTR;
}
}
void registerTypes(const char *uri);
void initializeEngine(QQmlEngine *engine, const char *uri);
static Fluent *getInstance();
private:
static Fluent* m_instance;
NativeEventFilter *nativeEvent = Q_NULLPTR;
};
#endif // FLUENT_H

View File

@ -8,3 +8,8 @@ void FluentUI::registerTypes(const char *uri){
void FluentUI::initializeEngine(QQmlEngine *engine, const char *uri){
Fluent::getInstance()->initializeEngine(engine,uri);
}
void FluentUI::initialize(QQmlEngine *engine){
Fluent::getInstance()->registerTypes(URI_STR);
Fluent::getInstance()->initializeEngine(engine,URI_STR);
}

View File

@ -3,12 +3,13 @@
#include <QQmlEngine>
class FluentUI
class Q_DECL_EXPORT FluentUI
{
public:
static void registerTypes(const char *uri) ;
static void initializeEngine(QQmlEngine *engine, const char *uri);
static void initialize(QQmlEngine *engine);
};
#endif // FLUENTUI_H

View File

@ -19,7 +19,7 @@ HEADERS += \
FluTheme.h \
Fluent.h \
FluentUI.h \
FramelessView.h \
NativeEventFilter.h \
WindowHelper.h \
qml_plugin.h \
stdafx.h
@ -33,16 +33,12 @@ SOURCES += \
FluTheme.cpp \
Fluent.cpp \
FluentUI.cpp \
NativeEventFilter.cpp \
WindowHelper.cpp \
qml_plugin.cpp \
win32 {
LIBS += -ldwmapi -luser32
SOURCES += \
FramelessView_win.cpp
} else {
SOURCES += \
FramelessView_unix.cpp
}
DEFINES += VERSION_IN=\\\"1.0.0\\\"

View File

@ -1,56 +0,0 @@
#pragma once
#include <QMouseEvent>
#include <QQuickView>
#include <QRegion>
class FramelessViewPrivate;
class FramelessView : public QQuickView
{
Q_OBJECT
using Super = QQuickView;
Q_PROPERTY(bool isMax READ isMax NOTIFY isMaxChanged)
Q_PROPERTY(bool isFull READ isFull NOTIFY isFullChanged)
public:
explicit FramelessView(QWindow *parent = nullptr);
~FramelessView();
void moveToScreenCenter();
void closeDeleteLater();
bool isMax() const;
bool isFull() const;
QQuickItem *titleItem() const;
static QMap<WId,FramelessView*> *windowCache;
static QRect calcCenterGeo(const QRect &screenGeo, const QSize &normalSize);
public slots:
void setIsMax(bool isMax);
void setIsFull(bool isFull);
void setTitleItem(QQuickItem* item);
signals:
void isMaxChanged(bool isMax);
void isFullChanged(bool isFull);
void mousePressed(int xPos, int yPos, int button);
protected:
void showEvent(QShowEvent *e) override;
void resizeEvent(QResizeEvent *e) override;
bool event(QEvent *ev) override;
# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
bool nativeEvent(const QByteArray &eventType, void *message, qintptr *result) override;
# else
bool nativeEvent(const QByteArray &eventType, void *message, long *result) override;
# endif
void mousePressEvent(QMouseEvent* event) override
{
# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
emit mousePressed(event->position().x(), event->position().y(), event->button());
#else
emit mousePressed(event->x(), event->y(), event->button());
#endif
Super::mousePressEvent(event);
}
private:
FramelessViewPrivate *d;
};

View File

@ -1,138 +0,0 @@
#include "FramelessView.h"
#include <QGuiApplication>
#include <QQuickItem>
#include <QScreen>
#include <QWindow>
#include <FluTheme.h>
class FramelessViewPrivate
{
public:
bool m_isMax = false;
bool m_isFull = false;
bool m_deleteLater = false;
QQuickItem *m_titleItem = nullptr;
};
FramelessView::FramelessView(QWindow *parent) : Super(parent), d(new FramelessViewPrivate)
{
if(FluTheme::getInstance()->frameless()){
setFlags( Qt::Window | Qt::FramelessWindowHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
}
setResizeMode(SizeRootObjectToView);
setIsMax(windowState() == Qt::WindowMaximized);
setIsFull(windowState() == Qt::WindowFullScreen);
connect(this, &QWindow::windowStateChanged, this, [&](Qt::WindowState state) {
(void)state;
setIsMax(windowState() == Qt::WindowMaximized);
setIsFull(windowState() == Qt::WindowFullScreen);
});
connect(FluTheme::getInstance(),&FluTheme::framelessChanged,this,[=](){
setFlag(Qt::Window,false);
setFlag(Qt::Window,true);
});
}
FramelessView::~FramelessView()
{
delete d;
}
void FramelessView::showEvent(QShowEvent *e)
{
Super::showEvent(e);
}
QRect FramelessView::calcCenterGeo(const QRect &screenGeo, const QSize &normalSize)
{
int w = normalSize.width();
int h = normalSize.height();
int x = screenGeo.x() + (screenGeo.width() - w) / 2;
int y = screenGeo.y() + (screenGeo.height() - h) / 2;
if (screenGeo.width() < w) {
x = screenGeo.x();
w = screenGeo.width();
}
if (screenGeo.height() < h) {
y = screenGeo.y();
h = screenGeo.height();
}
return { x, y, w, h };
}
void FramelessView::moveToScreenCenter()
{
auto geo = calcCenterGeo(screen()->availableGeometry(), size());
if (minimumWidth() > geo.width() || minimumHeight() > geo.height()) {
setMinimumSize(geo.size());
}
setGeometry(geo);
update();
}
void FramelessView::closeDeleteLater(){
d->m_deleteLater = true;
}
bool FramelessView::isMax() const
{
return d->m_isMax;
}
bool FramelessView::isFull() const
{
return d->m_isFull;
}
QQuickItem *FramelessView::titleItem() const
{
return d->m_titleItem;
}
void FramelessView::setIsMax(bool isMax)
{
if (d->m_isMax == isMax)
return;
d->m_isMax = isMax;
emit isMaxChanged(d->m_isMax);
}
void FramelessView::setIsFull(bool isFull)
{
if(d->m_isFull == isFull)
return;
d->m_isFull = isFull;
emit isFullChanged(d->m_isFull);
}
void FramelessView::setTitleItem(QQuickItem *item)
{
d->m_titleItem = item;
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
bool FramelessView::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
#else
bool FramelessView::nativeEvent(const QByteArray &eventType, void *message, long *result)
#endif
{
return Super::nativeEvent(eventType, message, result);
}
void FramelessView::resizeEvent(QResizeEvent *e)
{
Super::resizeEvent(e);
}
bool FramelessView::event(QEvent *ev)
{
if (ev->type() == QEvent::Close) {
if(d->m_deleteLater){
deleteLater();
ev->setAccepted(false);
}
}
return QQuickWindow::event(ev);
}

View File

@ -1,268 +0,0 @@
#include "FramelessView.h"
#include <QGuiApplication>
#include <QQuickItem>
#include <QScreen>
#include <QWindow>
#include <FluTheme.h>
#include <QTimer>
#include <dwmapi.h>
#include <windowsx.h>
#pragma comment(lib, "Dwmapi.lib")
#pragma comment(lib, "User32.lib")
static bool isCompositionEnabled()
{
BOOL composition_enabled = FALSE;
bool success = ::DwmIsCompositionEnabled(&composition_enabled) == S_OK;
return composition_enabled && success;
}
static bool isMaxWin(QWindow* win)
{
return win->windowState() == Qt::WindowMaximized;
}
static bool isFullWin(QQuickView* win)
{
return win->windowState() == Qt::WindowFullScreen;
}
static bool isFixWin(QQuickView* win)
{
return win->minimumWidth() == win->maximumWidth() && win->minimumHeight() == win->maximumHeight();
}
static long hitTest(RECT winrect, long x, long y, int borderWidth)
{
if ((x >= winrect.left) && (x < winrect.left + borderWidth) && (y >= winrect.top) && (y < winrect.top + borderWidth))
{
return HTTOPLEFT;
}
else if (x < winrect.right && x >= winrect.right - borderWidth && y >= winrect.top && y < winrect.top + borderWidth)
{
return HTTOPRIGHT;
}
else if (x >= winrect.left && x < winrect.left + borderWidth && y < winrect.bottom && y >= winrect.bottom - borderWidth)
{
return HTBOTTOMLEFT;
}
else if (x < winrect.right && x >= winrect.right - borderWidth && y < winrect.bottom && y >= winrect.bottom - borderWidth)
{
return HTBOTTOMRIGHT;
}
else if (x >= winrect.left && x < winrect.left + borderWidth)
{
return HTLEFT;
}
else if (x < winrect.right && x >= winrect.right - borderWidth)
{
return HTRIGHT;
}
else if (y >= winrect.top && y < winrect.top + borderWidth)
{
return HTTOP;
}
else if (y < winrect.bottom && y >= winrect.bottom - borderWidth)
{
return HTBOTTOM;
}
else
{
return 0;
}
}
class FramelessViewPrivate
{
public:
bool m_isMax = false;
bool m_isFull = false;
bool m_deleteLater = false;
bool m_isFirst = true;
QQuickItem *m_titleItem = nullptr;
};
FramelessView::FramelessView(QWindow *parent) : Super(parent), d(new FramelessViewPrivate)
{
if(!isCompositionEnabled()){
FluTheme::getInstance()->frameless(false);
}
if(FluTheme::getInstance()->frameless()){
setFlag(Qt::FramelessWindowHint,true);
}
setResizeMode(SizeRootObjectToView);
setIsMax(windowState() == Qt::WindowMaximized);
setIsFull(windowState() == Qt::WindowFullScreen);
connect(this, &QWindow::windowStateChanged, this, [=](Qt::WindowState state) {
(void)state;
setIsMax(windowState() == Qt::WindowMaximized);
setIsFull(windowState() == Qt::WindowFullScreen);
});
connect(FluTheme::getInstance(),&FluTheme::framelessChanged,this,[=](){
setFlag(Qt::Window,false);
setFlag(Qt::Window,true);
});
}
FramelessView::~FramelessView()
{
delete d;
}
void FramelessView::showEvent(QShowEvent *e)
{
static const MARGINS shadow_state[2] { { 0, 0, 0, 0 }, { 1, 1, 1, 1 } };
::DwmExtendFrameIntoClientArea((HWND)(winId()), &shadow_state[true]);
if(FluTheme::getInstance()->frameless()){
setFlag(Qt::FramelessWindowHint,false);
}
Super::showEvent(e);
}
QRect FramelessView::calcCenterGeo(const QRect &screenGeo, const QSize &normalSize)
{
int w = normalSize.width();
int h = normalSize.height();
int x = screenGeo.x() + (screenGeo.width() - w) / 2;
int y = screenGeo.y() + (screenGeo.height() - h) / 2;
if (screenGeo.width() < w) {
x = screenGeo.x();
w = screenGeo.width();
}
if (screenGeo.height() < h) {
y = screenGeo.y();
h = screenGeo.height();
}
return { x, y, w, h };
}
void FramelessView::moveToScreenCenter()
{
auto geo = calcCenterGeo(screen()->availableGeometry(), size());
if (minimumWidth() > geo.width() || minimumHeight() > geo.height()) {
setMinimumSize(geo.size());
}
setGeometry(geo);
update();
}
void FramelessView::closeDeleteLater(){
d->m_deleteLater = true;
}
bool FramelessView::isMax() const
{
return d->m_isMax;
}
bool FramelessView::isFull() const
{
return d->m_isFull;
}
QQuickItem *FramelessView::titleItem() const
{
return d->m_titleItem;
}
void FramelessView::setIsMax(bool isMax)
{
if (d->m_isMax == isMax)
return;
d->m_isMax = isMax;
emit isMaxChanged(d->m_isMax);
}
void FramelessView::setIsFull(bool isFull)
{
if(d->m_isFull == isFull)
return;
d->m_isFull = isFull;
emit isFullChanged(d->m_isFull);
}
int count = 1;
void FramelessView::setTitleItem(QQuickItem *item)
{
d->m_titleItem = item;
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
bool FramelessView::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
#else
bool FramelessView::nativeEvent(const QByteArray &eventType, void *message, long *result)
#endif
{
MSG* msg = static_cast<MSG*>(message);
if (!msg || !msg->hwnd)
{
return false;
}
if (msg->message == WM_NCHITTEST && FluTheme::getInstance()->frameless())
{
RECT winrect;
GetWindowRect(HWND(winId()), &winrect);
long x = GET_X_LPARAM(msg->lParam);
long y = GET_Y_LPARAM(msg->lParam);
*result = 0;
if (!isMaxWin(this) && !isFullWin(this) && !isFixWin(this))
{
*result = hitTest(winrect, x, y, 4);
if (0 != *result)
{
return true;
}
}
}else if (msg->message == WM_NCCALCSIZE && FluTheme::getInstance()->frameless())
{
const auto mode = static_cast<BOOL>(msg->wParam);
const auto clientRect = mode ? &(reinterpret_cast<LPNCCALCSIZE_PARAMS>(msg->lParam)->rgrc[0]) : reinterpret_cast<LPRECT>(msg->lParam);
if (mode == TRUE)
{
*result = WVR_REDRAW;
if (!isMaxWin(this) && !isFullWin(this))
{
if (clientRect->top != 0)
{
clientRect->top -= 0.1;
}
}
else
{
if (clientRect->top != 0)
{
clientRect->top += 0.1;
}
}
return true;
}
}else if (msg->message == WM_WINDOWPOSCHANGING)
{
WINDOWPOS* wp = reinterpret_cast<WINDOWPOS*>(msg->lParam);
if (wp != nullptr && (wp->flags & SWP_NOSIZE) == 0)
{
wp->flags |= SWP_NOCOPYBITS;
*result = 0;
return true;
}
}
return Super::nativeEvent(eventType, message, result);
}
void FramelessView::resizeEvent(QResizeEvent *e)
{
Super::resizeEvent(e);
}
bool FramelessView::event(QEvent *ev)
{
if (ev->type() == QEvent::Close) {
if(d->m_deleteLater){
deleteLater();
ev->setAccepted(false);
}
}
return QQuickWindow::event(ev);
}

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