Compare commits

..

68 Commits
1.2.4 ... 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
142 changed files with 3053 additions and 1340 deletions

View File

@ -56,7 +56,7 @@ jobs:
- name: package - name: package
run: | run: |
# make sure Qt plugin finds QML sources so it can deploy the imported files # 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/ 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 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]| | [Windows][win-link]| [Ubuntu][ubuntu-link]|[MacOS][macos-link]|
@ -96,4 +96,4 @@
![](doc/preview/carousel.png) ![](doc/preview/carousel.png)
### ⚡ Visitor count ### ⚡ Visitor count
![](https://profile-counter.glitch.me/zhuzichu520-FluentUI/count.svg) ![](https://profile-counter.glitch.me/zhuzichu520-FluentUI/count.svg)

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)
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

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

View File

@ -24,12 +24,23 @@ endif()
find_package(Qt6 COMPONENTS Core Quick QuickControls2 Concurrent Network Multimedia REQUIRED) find_package(Qt6 COMPONENTS Core Quick QuickControls2 Concurrent Network Multimedia REQUIRED)
set(SOURCES set(SOURCES
ChatController.cpp src/controller/ChatController.cpp
main.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 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 set(RESOURCES

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,50 +0,0 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Window
import QtQuick.Controls
import FluentUI
import "qrc:///global/"
import "./component"
FluScrollablePage{
title:"Settings"
leftPadding:10
rightPadding:10
bottomPadding:20
spacing: 0
FluArea{
Layout.fillWidth: true
Layout.topMargin: 20
height: 168
paddings: 10
ColumnLayout{
spacing: 10
anchors{
verticalCenter: parent.verticalCenter
left: parent.left
}
FluText{
text:"NavigationView Display Mode"
fontStyle: FluText.BodyStrong
Layout.bottomMargin: 4
}
Repeater{
id:repeater
model: [{title:"Open",mode:FluNavigationView.Open},{title:"Compact",mode:FluNavigationView.Compact},{title:"Minimal",mode:FluNavigationView.Minimal},{title:"Auto",mode:FluNavigationView.Auto}]
delegate: FluRadioButton{
selected : MainEvent.displayMode===modelData.mode
text:modelData.title
onClicked:{
MainEvent.displayMode = modelData.mode
}
}
}
}
}
}

View File

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

View File

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

View File

@ -1,51 +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:9
showDark: true
width:parent.width
darkText: "Dark Mode"
}
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: "Search"
onItemClicked:
(data)=>{
ItemsOriginal.startPageByItem(data)
}
}
Component.onCompleted: {
ItemsOriginal.navigationView = nav_view
ItemsFooter.navigationView = nav_view
nav_view.setCurrentIndex(0)
}
}
}

View File

@ -1,6 +1,5 @@
<RCC> <RCC>
<qresource prefix="/"> <qresource prefix="/">
<file>App.qml</file>
<file>res/image/image_huoyin.webp</file> <file>res/image/image_huoyin.webp</file>
<file>res/svg/avatar_1.svg</file> <file>res/svg/avatar_1.svg</file>
<file>res/svg/avatar_2.svg</file> <file>res/svg/avatar_2.svg</file>
@ -14,40 +13,11 @@
<file>res/svg/avatar_10.svg</file> <file>res/svg/avatar_10.svg</file>
<file>res/svg/avatar_11.svg</file> <file>res/svg/avatar_11.svg</file>
<file>res/svg/avatar_12.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_1.jpg</file>
<file>res/image/banner_2.jpg</file> <file>res/image/banner_2.jpg</file>
<file>res/image/banner_3.jpg</file> <file>res/image/banner_3.jpg</file>
<file>res/image/logo_openai.png</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>res/image/favicon.ico</file>
<file>T_Home.qml</file>
<file>res/image/bg_home_header.png</file> <file>res/image/bg_home_header.png</file>
<file>res/image/ic_home_github.png</file> <file>res/image/ic_home_github.png</file>
<file>res/image/control/Acrylic.png</file> <file>res/image/control/Acrylic.png</file>
@ -148,17 +118,56 @@
<file>res/image/control/Viewbox.png</file> <file>res/image/control/Viewbox.png</file>
<file>res/image/control/WebView.png</file> <file>res/image/control/WebView.png</file>
<file>res/image/control/XamlUICommand.png</file> <file>res/image/control/XamlUICommand.png</file>
<file>T_CheckBox.qml</file> <file>res/svg/home.svg</file>
<file>global/ItemsOriginal.qml</file> <file>res/svg/home_dark.svg</file>
<file>global/qmldir</file> <file>res/image/qrcode_wx.jpg</file>
<file>global/ItemsFooter.qml</file> <file>res/image/qrcode_zfb.jpg</file>
<file>page/MediaPage.qml</file> <file>qml/component/CodeExpander.qml</file>
<file>T_FlipView.qml</file> <file>qml/global/ItemsFooter.qml</file>
<file>T_Pivot.qml</file> <file>qml/global/ItemsOriginal.qml</file>
<file>component/CodeExpander.qml</file> <file>qml/global/MainEvent.qml</file>
<file>T_TableView.qml</file> <file>qml/global/qmldir</file>
<file>T_StatusView.qml</file> <file>qml/App.qml</file>
<file>T_Settings.qml</file> <file>qml/window/AboutWindow.qml</file>
<file>global/MainEvent.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> </qresource>
</RCC> </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", "FluComboBox",
"FluContentDialog", "FluContentDialog",
"FluContentPage", "FluContentPage",
"FluControl",
"FluDatePicker", "FluDatePicker",
"FluDivider", "FluDivider",
"FluDropDownButton", "FluDropDownButton",
@ -118,7 +117,10 @@ FluExpander{
"FluTableView", "FluTableView",
"FluColors", "FluColors",
"FluTheme", "FluTheme",
"FluStatusView" "FluStatusView",
"FluRatingControl",
"FluPasswordBox",
"FluBreadcrumbBar"
]; ];
code = code.replace(/\n/g, "<br>"); code = code.replace(/\n/g, "<br>");
code = code.replace(/ /g, "&nbsp;"); code = code.replace(/ /g, "&nbsp;");

View File

@ -10,17 +10,17 @@ FluObject{
FluPaneItemSeparator{} FluPaneItemSeparator{}
FluPaneItem{ FluPaneItem{
title:"About" title:lang.about
icon:FluentIcons.Contact icon:FluentIcons.Contact
tapFunc:function(){ tapFunc:function(){
FluApp.navigate("/about") FluApp.navigate("/about")
} }
} }
FluPaneItem{ FluPaneItem{
title:"Settings" title:lang.settings
icon:FluentIcons.Settings icon:FluentIcons.Settings
onTap:{ onTap:{
navigationView.push("qrc:/T_Settings.qml") navigationView.push("qrc:/qml/page/T_Settings.qml")
} }
} }
} }

View File

@ -8,15 +8,22 @@ FluObject{
property var navigationView property var navigationView
FluPaneItem{ FluPaneItem{
title:"Home" title:lang.home
icon:FluentIcons.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:{ onTap:{
navigationView.push("qrc:/T_Home.qml") navigationView.push("qrc:/qml/page/T_Home.qml")
} }
} }
FluPaneItemExpander{ FluPaneItemExpander{
title:"Basic input" title:lang.basic_input
icon:FluentIcons.CheckboxComposite icon:FluentIcons.CheckboxComposite
FluPaneItem{ FluPaneItem{
title:"Buttons" title:"Buttons"
@ -24,7 +31,7 @@ FluObject{
recentlyUpdated:true recentlyUpdated:true
desc:"A control that responds to user input and raisesa Click event." desc:"A control that responds to user input and raisesa Click event."
onTap:{ onTap:{
navigationView.push("qrc:/T_Buttons.qml") navigationView.push("qrc:/qml/page/T_Buttons.qml")
} }
} }
FluPaneItem{ FluPaneItem{
@ -33,7 +40,7 @@ FluObject{
recentlyUpdated:true recentlyUpdated:true
desc:"A control that lets the user select from a rangeof values by moving a Thumb control along atrack." desc:"A control that lets the user select from a rangeof values by moving a Thumb control along atrack."
onTap:{ onTap:{
navigationView.push("qrc:/T_Slider.qml") navigationView.push("qrc:/qml/page/T_Slider.qml")
} }
} }
FluPaneItem{ FluPaneItem{
@ -42,54 +49,54 @@ FluObject{
recentlyUpdated:true recentlyUpdated:true
desc:"A control that a user can select or clear." desc:"A control that a user can select or clear."
onTap:{ onTap:{
navigationView.push("qrc:/T_CheckBox.qml") navigationView.push("qrc:/qml/page/T_CheckBox.qml")
} }
} }
FluPaneItem{ FluPaneItem{
title:"ToggleSwitch" title:"ToggleSwitch"
onTap:{ onTap:{
navigationView.push("qrc:/T_ToggleSwitch.qml") navigationView.push("qrc:/qml/page/T_ToggleSwitch.qml")
} }
} }
} }
FluPaneItemExpander{ FluPaneItemExpander{
title:"Form" title:lang.form
icon:FluentIcons.GridView icon:FluentIcons.GridView
FluPaneItem{ FluPaneItem{
title:"TextBox" title:"TextBox"
onTap:{ onTap:{
navigationView.push("qrc:/T_TextBox.qml") navigationView.push("qrc:/qml/page/T_TextBox.qml")
} }
} }
FluPaneItem{ FluPaneItem{
title:"TimePicker" title:"TimePicker"
onTap:{ onTap:{
navigationView.push("qrc:/T_TimePicker.qml") navigationView.push("qrc:/qml/page/T_TimePicker.qml")
} }
} }
FluPaneItem{ FluPaneItem{
title:"DatePicker" title:"DatePicker"
onTap:{ onTap:{
navigationView.push("qrc:/T_DatePicker.qml") navigationView.push("qrc:/qml/page/T_DatePicker.qml")
} }
} }
FluPaneItem{ FluPaneItem{
title:"CalendarPicker" title:"CalendarPicker"
onTap:{ onTap:{
navigationView.push("qrc:/T_CalendarPicker.qml") navigationView.push("qrc:/qml/page/T_CalendarPicker.qml")
} }
} }
FluPaneItem{ FluPaneItem{
title:"ColorPicker" title:"ColorPicker"
onTap:{ onTap:{
navigationView.push("qrc:/T_ColorPicker.qml") navigationView.push("qrc:/qml/page/T_ColorPicker.qml")
} }
} }
} }
FluPaneItemExpander{ FluPaneItemExpander{
title:"Surface" title:lang.surface
icon:FluentIcons.SurfaceHub icon:FluentIcons.SurfaceHub
FluPaneItem{ FluPaneItem{
title:"InfoBar" title:"InfoBar"
@ -97,72 +104,78 @@ FluObject{
recentlyUpdated:true recentlyUpdated:true
desc:"An inline message to display app-wide statuschange information." desc:"An inline message to display app-wide statuschange information."
onTap:{ onTap:{
navigationView.push("qrc:/T_InfoBar.qml") navigationView.push("qrc:/qml/page/T_InfoBar.qml")
} }
} }
FluPaneItem{ FluPaneItem{
title:"Progress" title:"Progress"
onTap:{ 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{ FluPaneItem{
title:"Badge" title:"Badge"
onTap:{ onTap:{
navigationView.push("qrc:/T_Badge.qml") navigationView.push("qrc:/qml/page/T_Badge.qml")
} }
} }
FluPaneItem{ FluPaneItem{
title:"Rectangle" title:"Rectangle"
onTap:{ onTap:{
navigationView.push("qrc:/T_Rectangle.qml") navigationView.push("qrc:/qml/page/T_Rectangle.qml")
} }
} }
FluPaneItem{ FluPaneItem{
title:"StatusView" title:"StatusView"
onTap:{ onTap:{
navigationView.push("qrc:/T_StatusView.qml") navigationView.push("qrc:/qml/page/T_StatusView.qml")
} }
} }
FluPaneItem{ FluPaneItem{
title:"Carousel" title:"Carousel"
onTap:{ onTap:{
navigationView.push("qrc:/T_Carousel.qml") navigationView.push("qrc:/qml/page/T_Carousel.qml")
} }
} }
FluPaneItem{ FluPaneItem{
title:"Expander" title:"Expander"
onTap:{ onTap:{
navigationView.push("qrc:/T_Expander.qml") navigationView.push("qrc:/qml/page/T_Expander.qml")
} }
} }
} }
FluPaneItemExpander{ FluPaneItemExpander{
title:"Popus" title:lang.popus
icon:FluentIcons.ButtonMenu icon:FluentIcons.ButtonMenu
FluPaneItem{ FluPaneItem{
title:"Dialog" title:"Dialog"
onTap:{ onTap:{
navigationView.push("qrc:/T_Dialog.qml") navigationView.push("qrc:/qml/page/T_Dialog.qml")
} }
} }
FluPaneItem{ FluPaneItem{
title:"Tooltip" title:"Tooltip"
onTap:{ onTap:{
navigationView.push("qrc:/T_Tooltip.qml") navigationView.push("qrc:/qml/page/T_Tooltip.qml")
} }
} }
FluPaneItem{ FluPaneItem{
title:"Menu" title:"Menu"
onTap:{ onTap:{
navigationView.push("qrc:/T_Menu.qml") navigationView.push("qrc:/qml/page/T_Menu.qml")
} }
} }
} }
FluPaneItemExpander{ FluPaneItemExpander{
title:"Navigation" title:lang.navigation
icon:FluentIcons.AllApps icon:FluentIcons.AllApps
FluPaneItem{ FluPaneItem{
title:"Pivot" title:"Pivot"
@ -171,7 +184,13 @@ FluObject{
order:3 order:3
desc:"Presents information from different sources in atabbed view." desc:"Presents information from different sources in atabbed view."
onTap:{ 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{ FluPaneItem{
@ -181,13 +200,13 @@ FluObject{
order:1 order:1
desc:"A control that displays a collection of tabs thatcan be used to display several documents." desc:"A control that displays a collection of tabs thatcan be used to display several documents."
onTap:{ onTap:{
navigationView.push("qrc:/T_TabView.qml") navigationView.push("qrc:/qml/page/T_TabView.qml")
} }
} }
FluPaneItem{ FluPaneItem{
title:"TreeView" title:"TreeView"
onTap:{ onTap:{
navigationView.push("qrc:/T_TreeView.qml") navigationView.push("qrc:/qml/page/T_TreeView.qml")
} }
} }
FluPaneItem{ FluPaneItem{
@ -197,13 +216,13 @@ FluObject{
order:4 order:4
desc:"The TableView control provides a flexible way to display a collection of data in rows and columns" desc:"The TableView control provides a flexible way to display a collection of data in rows and columns"
onTap:{ onTap:{
navigationView.push("qrc:/T_TableView.qml") navigationView.push("qrc:/qml/page/T_TableView.qml")
} }
} }
FluPaneItem{ FluPaneItem{
title:"MultiWindow" title:"MultiWindow"
onTap:{ onTap:{
navigationView.push("qrc:/T_MultiWindow.qml") navigationView.push("qrc:/qml/page/T_MultiWindow.qml")
} }
} }
FluPaneItem{ FluPaneItem{
@ -213,36 +232,36 @@ FluObject{
order:2 order:2
desc:"Presents a collection of items that the user canflip through, one item at a time." desc:"Presents a collection of items that the user canflip through, one item at a time."
onTap:{ onTap:{
navigationView.push("qrc:/T_FlipView.qml") navigationView.push("qrc:/qml/page/T_FlipView.qml")
} }
} }
} }
FluPaneItemExpander{ FluPaneItemExpander{
title:"Theming" title:lang.theming
icon:FluentIcons.Brightness icon:FluentIcons.Brightness
FluPaneItem{ FluPaneItem{
title:"Theme" title:"Theme"
onTap:{ onTap:{
navigationView.push("qrc:/T_Theme.qml") navigationView.push("qrc:/qml/page/T_Theme.qml")
} }
} }
FluPaneItem{ FluPaneItem{
title:"Typography" title:"Typography"
onTap:{ onTap:{
navigationView.push("qrc:/T_Typography.qml") navigationView.push("qrc:/qml/page/T_Typography.qml")
} }
} }
FluPaneItem{ FluPaneItem{
title:"Awesome" title:"Awesome"
onTap:{ onTap:{
navigationView.push("qrc:/T_Awesome.qml") navigationView.push("qrc:/qml/page/T_Awesome.qml")
} }
} }
} }
FluPaneItemExpander{ FluPaneItemExpander{
title:"Media" title:lang.media
icon:FluentIcons.Media icon:FluentIcons.Media
FluPaneItem{ FluPaneItem{
title:"MediaPlayer" title:"MediaPlayer"
@ -251,7 +270,7 @@ FluObject{
order:0 order:0
desc:"A control to display video and image content." desc:"A control to display video and image content."
onTap:{ onTap:{
navigationView.push("qrc:/T_MediaPlayer.qml") navigationView.push("qrc:/qml/page/T_MediaPlayer.qml")
} }
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Window import QtQuick.Window
import FluentUI import FluentUI
import "./component" import "../component"
FluScrollablePage{ FluScrollablePage{
@ -44,6 +44,7 @@ FluScrollablePage{
} }
CodeExpander{ CodeExpander{
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: -1
code:'FluFlipView{ code:'FluFlipView{
Image{ Image{
source: "qrc:/res/image/banner_1.jpg" source: "qrc:/res/image/banner_1.jpg"
@ -97,6 +98,7 @@ FluScrollablePage{
} }
CodeExpander{ CodeExpander{
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: -1
code:'FluFlipView{ code:'FluFlipView{
vertical:true vertical:true
Image{ Image{

View File

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

View File

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

View File

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

View File

@ -3,7 +3,7 @@ import QtQuick.Layouts
import QtQuick.Window import QtQuick.Window
import QtQuick.Controls import QtQuick.Controls
import FluentUI import FluentUI
import "./component" import "../component"
FluScrollablePage{ FluScrollablePage{
@ -53,6 +53,7 @@ FluScrollablePage{
CodeExpander{ CodeExpander{
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: -1
code:'FluMenu{ code:'FluMenu{
id:menu id:menu
FluMenuItem:{ 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.Layouts
import QtQuick.Window import QtQuick.Window
import FluentUI import FluentUI
import "./component" import "../component"
FluScrollablePage{ FluScrollablePage{
@ -21,6 +21,7 @@ FluScrollablePage{
FluPivot{ FluPivot{
anchors.fill: parent anchors.fill: parent
currentIndex: 2
FluPivotItem{ FluPivotItem{
title:"All" title:"All"
contentItem:FluText{ contentItem:FluText{
@ -49,6 +50,7 @@ FluScrollablePage{
} }
CodeExpander{ CodeExpander{
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: -1
code:'FluPivot{ code:'FluPivot{
anchors.fill: parent anchors.fill: parent
FluPivotItem:{ FluPivotItem:{

View File

@ -3,7 +3,7 @@ import QtQuick.Layouts
import QtQuick.Window import QtQuick.Window
import QtQuick.Controls import QtQuick.Controls
import FluentUI import FluentUI
import "./component" import "../component"
FluScrollablePage{ FluScrollablePage{
@ -47,6 +47,7 @@ FluScrollablePage{
} }
CodeExpander{ CodeExpander{
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: -1
code:'FluProgressBar{ 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.Controls
import QtQuick.Window import QtQuick.Window
import FluentUI import FluentUI
import "./component" import "../component"
FluScrollablePage{ FluScrollablePage{
@ -134,6 +134,7 @@ FluScrollablePage{
} }
CodeExpander{ CodeExpander{
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: -1
code:'FluRectangle{ code:'FluRectangle{
radius: [25,25,25,25] radius: [25,25,25,25]
width: 50 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.Layouts
import QtQuick.Window import QtQuick.Window
import QtQuick.Controls import QtQuick.Controls
import "./component" import "../component"
import FluentUI import FluentUI
FluScrollablePage{ FluScrollablePage{
@ -25,6 +25,7 @@ FluScrollablePage{
} }
CodeExpander{ CodeExpander{
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: -1
code:'FluSlider{ code:'FluSlider{
value:50 value:50
}' }'
@ -46,6 +47,7 @@ FluScrollablePage{
} }
CodeExpander{ CodeExpander{
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: -1
code:'FluSlider{ code:'FluSlider{
vertical:true vertical:true
value:50 value:50

View File

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

View File

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

View File

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

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Window import QtQuick.Window
import FluentUI import FluentUI
import "./component" import "../component"
FluScrollablePage{ FluScrollablePage{
@ -45,19 +45,59 @@ FluScrollablePage{
} }
CodeExpander{ CodeExpander{
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: -1
code:'FluTextBox{ code:'FluTextBox{
placeholderText:"单行输入框" placeholderText:"单行输入框"
}' }'
} }
FluArea{ FluArea{
Layout.fillWidth: true Layout.fillWidth: true
height: 68 height: 68
paddings: 10 paddings: 10
Layout.topMargin: 20 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{ FluMultilineTextBox{
id:multiine_textbox
Layout.topMargin: 20 Layout.topMargin: 20
placeholderText: "多行输入框" placeholderText: "多行输入框"
Layout.preferredWidth: 300 Layout.preferredWidth: 300
@ -83,6 +123,7 @@ FluScrollablePage{
} }
CodeExpander{ CodeExpander{
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: -1
code:'FluMultilineTextBox{ code:'FluMultilineTextBox{
placeholderText:"多行输入框" placeholderText:"多行输入框"
}' }'
@ -122,6 +163,7 @@ FluScrollablePage{
} }
CodeExpander{ CodeExpander{
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: -1
code:'FluAutoSuggestBox{ code:'FluAutoSuggestBox{
placeholderText:"AutoSuggestBox" placeholderText:"AutoSuggestBox"
}' }'

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -6,15 +6,14 @@ import FluentUI
FluWindow { FluWindow {
id:window id:window
width: 500
height: 600
minimumWidth: 500
minimumHeight: 600
maximumWidth: 500
maximumHeight: 600
title:"关于" title:"关于"
width: 600
height: 600
minimumWidth: 600
minimumHeight: 600
maximumWidth: 600
maximumHeight: 600
launchMode: FluWindow.SingleTask
FluAppBar{ FluAppBar{
id:appbar id:appbar
@ -59,13 +58,14 @@ FluWindow {
RowLayout{ RowLayout{
spacing: 14 spacing: 14
Layout.topMargin: 20
Layout.leftMargin: 15 Layout.leftMargin: 15
FluText{ FluText{
text:"GitHub" text:"GitHub"
} }
FluTextButton{ FluTextButton{
id:text_hublink id:text_hublink
topPadding:0
bottomPadding:0
text:"https://github.com/zhuzichu520/FluentUI" text:"https://github.com/zhuzichu520/FluentUI"
Layout.alignment: Qt.AlignBottom Layout.alignment: Qt.AlignBottom
onClicked: { onClicked: {
@ -73,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{ RowLayout{
spacing: 14 spacing: 14
Layout.topMargin: 20
Layout.leftMargin: 15 Layout.leftMargin: 15
FluText{ FluText{
id:text_info id:text_info
text:"如果该项目对你有作用就请点击上方链接给一个免费的star" text:"如果该项目对你有作用就请点击上方链接给一个免费的star,或者一键三连,谢谢"
ColorAnimation { ColorAnimation {
id: animation id: animation
target: text_info target: text_info
@ -93,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 { FluWindow {
title:"ChatGPT"
width: 680 width: 680
height: 600 height: 600
minimumWidth: 500 minimumWidth: 500
minimumHeight: 600 minimumHeight: 600
title:"ChatGPT"
onInitArgument: onInitArgument:
(argument)=>{ (argument)=>{
scrollview.focus = true scrollview.focus = true

View File

@ -6,13 +6,13 @@ import FluentUI
FluWindow { FluWindow {
id:window id:window
title:"登录"
width: 400 width: 400
height: 400 height: 400
minimumWidth: 400 minimumWidth: 400
minimumHeight: 400 minimumHeight: 400
maximumWidth: 400 maximumWidth: 400
maximumHeight: 400 maximumHeight: 400
title:"登录"
onInitArgument: onInitArgument:
(argument)=>{ (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 { FluWindow {
title:"视频播放器"
width: 640 width: 640
height: 480 height: 480
minimumWidth: 640 minimumWidth: 640
minimumHeight: 480 minimumHeight: 480
title:"视频播放器"
onInitArgument: onInitArgument:
(argument)=>{ (argument)=>{
player.source = argument.source player.source = argument.source
@ -23,7 +22,6 @@ FluWindow {
width:parent.width width:parent.width
} }
FluMediaPlayer{ FluMediaPlayer{
id:player id:player
anchors{ 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());
}
}

View File

@ -2,14 +2,18 @@
#define APPINFO_H #define APPINFO_H
#include <QObject> #include <QObject>
#include "lang/Lang.h"
#include "stdafx.h" #include "stdafx.h"
class AppInfo : public QObject class AppInfo : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO(QString,version) Q_PROPERTY_AUTO(QString,version)
Q_PROPERTY_AUTO(Lang*,lang)
public: public:
explicit AppInfo(QObject *parent = nullptr); explicit AppInfo(QObject *parent = nullptr);
Q_INVOKABLE void changeLang(const QString& locale);
Q_SIGNAL void activeWindow();
}; };
#endif // APPINFO_H #endif // APPINFO_H

View File

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

@ -24,6 +24,7 @@ set(TARGET_SOURCES
FluTheme.cpp FluTheme.cpp
Fluent.cpp Fluent.cpp
FluentUI.cpp FluentUI.cpp
NativeEventFilter.cpp
WindowHelper.cpp WindowHelper.cpp
qml_plugin.cpp qml_plugin.cpp
) )
@ -37,20 +38,14 @@ set(TARGET_HEADERS
FluTheme.h FluTheme.h
Fluent.h Fluent.h
FluentUI.h FluentUI.h
FramelessView.h NativeEventFilter.h
WindowHelper.h WindowHelper.h
qml_plugin.h qml_plugin.h
stdafx.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(-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}) add_library(${PROJECT_NAME} ${TARGET_TYPE} ${TARGET_SOURCES} ${TARGET_HEADERS} ${TARGET_RESOURCES})

View File

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

View File

@ -11,6 +11,8 @@
#include "Def.h" #include "Def.h"
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#pragma comment(lib, "Dwmapi.lib")
#pragma comment(lib, "User32.lib")
#include <dwmapi.h> #include <dwmapi.h>
#include <Windows.h> #include <Windows.h>
#include <windowsx.h> #include <windowsx.h>
@ -44,8 +46,8 @@ void FluApp::init(QQuickWindow *window){
void FluApp::run(){ void FluApp::run(){
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
if(!isCompositionEnabled()){ if(!isCompositionEnabled()){
FluTheme::getInstance()->frameless(false); FluTheme::getInstance()->frameless(false);
} }
#endif #endif
navigate(initialRoute()); navigate(initialRoute());
} }
@ -58,19 +60,41 @@ void FluApp::navigate(const QString& route,const QJsonObject& argument,FluRegist
QQmlEngine *engine = qmlEngine(appWindow); QQmlEngine *engine = qmlEngine(appWindow);
QQmlComponent component(engine, routes().value(route).toString()); QQmlComponent component(engine, routes().value(route).toString());
QVariantMap properties; QVariantMap properties;
properties.insert("route",route);
if(fluRegister){ if(fluRegister){
properties.insert("pageRegister",QVariant::fromValue(fluRegister)); properties.insert("pageRegister",QVariant::fromValue(fluRegister));
} }
properties.insert("argument",argument); properties.insert("argument",argument);
QQuickWindow *view = qobject_cast<QQuickWindow*>(component.createWithInitialProperties(properties)); 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); wnds.insert(view->winId(),view);
if(fluRegister){ if(fluRegister){
fluRegister->to(view); fluRegister->to(view);
} }
view->setColor(QColor(Qt::transparent)); view->setColor(QColor(Qt::transparent));
if(view->maximumWidth()==view->minimumWidth()&&view->maximumHeight()==view->minimumHeight()){
view->resize(view->minimumSize());
}
view->show(); view->show();
} }
@ -105,3 +129,7 @@ void FluApp::clipText(const QString& text){
QString FluApp::uuid(){ QString FluApp::uuid(){
return QUuid::createUuid().toString(); return QUuid::createUuid().toString();
} }
void FluApp::closeApp(){
qApp->exit(0);
}

View File

@ -34,6 +34,8 @@ public:
Q_INVOKABLE QString uuid(); Q_INVOKABLE QString uuid();
Q_INVOKABLE void closeApp();
public: public:
QMap<quint64, QQuickWindow*> wnds; QMap<quint64, QQuickWindow*> wnds;
private: private:

View File

@ -1,6 +1,9 @@
#include "FluTheme.h" #include "FluTheme.h"
#include "FluColors.h" #include "FluColors.h"
#include "Def.h"
#include <QPalette>
#include <QGuiApplication>
FluTheme* FluTheme::m_instance = nullptr; FluTheme* FluTheme::m_instance = nullptr;
@ -15,9 +18,44 @@ FluTheme *FluTheme::getInstance()
FluTheme::FluTheme(QObject *parent) FluTheme::FluTheme(QObject *parent)
: QObject{parent} : QObject{parent}
{ {
connect(this,&FluTheme::darkModeChanged,this,[=]{
Q_EMIT darkChanged();
});
primaryColor(FluColors::getInstance()->Blue()); primaryColor(FluColors::getInstance()->Blue());
textSize(13); textSize(13);
nativeText(true); nativeText(false);
frameless(true); 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 class FluTheme : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool dark READ dark NOTIFY darkChanged)
Q_PROPERTY_AUTO(FluColorSet*,primaryColor) Q_PROPERTY_AUTO(FluColorSet*,primaryColor)
Q_PROPERTY_AUTO(bool,frameless); Q_PROPERTY_AUTO(bool,frameless);
Q_PROPERTY_AUTO(bool,dark); Q_PROPERTY_AUTO(int,darkMode);
Q_PROPERTY_AUTO(bool,nativeText); Q_PROPERTY_AUTO(bool,nativeText);
Q_PROPERTY_AUTO(int,textSize); Q_PROPERTY_AUTO(int,textSize);
public: public:
explicit FluTheme(QObject *parent = nullptr); explicit FluTheme(QObject *parent = nullptr);
static FluTheme *getInstance(); static FluTheme *getInstance();
bool dark();
Q_SIGNAL void darkChanged();
private: private:
static FluTheme* m_instance; static FluTheme* m_instance;
bool _dark;
bool eventFilter(QObject *obj, QEvent *event);
bool systemDark();
}; };
#endif // FLUTHEME_H #endif // FLUTHEME_H

View File

@ -34,6 +34,8 @@ void Fluent::registerTypes(const char *uri){
qmlRegisterType<WindowHelper>(uri,major,minor,"WindowHelper"); qmlRegisterType<WindowHelper>(uri,major,minor,"WindowHelper");
qmlRegisterType<FluColorSet>(uri,major,minor,"FluColorSet"); 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/FluStatusView.qml"),uri,major,minor,"FluStatusView");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluPagination.qml"),uri,major,minor,"FluPagination"); 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/FluToggleButton.qml"),uri,major,minor,"FluToggleButton");
@ -87,11 +89,14 @@ void Fluent::registerTypes(const char *uri){
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluRadioButton.qml"),uri,major,minor,"FluRadioButton"); 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/FluSlider.qml"),uri,major,minor,"FluSlider");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTextBox.qml"),uri,major,minor,"FluTextBox"); 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/FluText.qml"),uri,major,minor,"FluText");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluFilledButton.qml"),uri,major,minor,"FluFilledButton"); qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluFilledButton.qml"),uri,major,minor,"FluFilledButton");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluToggleSwitch.qml"),uri,major,minor,"FluToggleSwitch"); 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_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) void Fluent::initializeEngine(QQmlEngine *engine, const char *uri)

View File

@ -8,3 +8,8 @@ void FluentUI::registerTypes(const char *uri){
void FluentUI::initializeEngine(QQmlEngine *engine, const char *uri){ void FluentUI::initializeEngine(QQmlEngine *engine, const char *uri){
Fluent::getInstance()->initializeEngine(engine,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> #include <QQmlEngine>
class FluentUI class Q_DECL_EXPORT FluentUI
{ {
public: public:
static void registerTypes(const char *uri) ; static void registerTypes(const char *uri) ;
static void initializeEngine(QQmlEngine *engine, const char *uri); static void initializeEngine(QQmlEngine *engine, const char *uri);
static void initialize(QQmlEngine *engine);
}; };
#endif // FLUENTUI_H #endif // FLUENTUI_H

View File

@ -2,6 +2,8 @@
#include "FluTheme.h" #include "FluTheme.h"
#include "FluApp.h" #include "FluApp.h"
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#pragma comment(lib, "Dwmapi.lib")
#pragma comment(lib, "User32.lib")
#include <Windows.h> #include <Windows.h>
#include <windowsx.h> #include <windowsx.h>
#endif #endif
@ -10,72 +12,70 @@ bool NativeEventFilter::nativeEventFilter(const QByteArray &eventType, void *mes
{ {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
if (eventType == "windows_generic_MSG" && FluTheme::getInstance()->frameless()) { if (eventType == "windows_generic_MSG" && FluTheme::getInstance()->frameless()) {
MSG* msg = static_cast<MSG *>(message); MSG* msg = static_cast<MSG *>(message);
if (msg == Q_NULLPTR) if (msg == Q_NULLPTR)
return false; return false;
switch(msg->message) { if(!FluApp::getInstance()->wnds.contains((WId)msg->hwnd)){
case WM_COMMAND: { return false;
SendMessage(msg->hwnd, WM_SYSCOMMAND, msg->wParam, msg->lParam); }
*result = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam); switch(msg->message) {
return true; case WM_NCCALCSIZE:{
} NCCALCSIZE_PARAMS& params = *reinterpret_cast<NCCALCSIZE_PARAMS*>(msg->lParam);
case WM_NCCALCSIZE:{ if (params.rgrc[0].top != 0)
NCCALCSIZE_PARAMS& params = *reinterpret_cast<NCCALCSIZE_PARAMS*>(msg->lParam); params.rgrc[0].top -= 1;
if (params.rgrc[0].top != 0) *result = WVR_REDRAW;
params.rgrc[0].top -= 1; return true;
*result = WVR_REDRAW; }
case WM_NCHITTEST: {
auto view = FluApp::getInstance()->wnds[(WId)msg->hwnd];
bool isResize = !(view->maximumWidth()==view->minimumWidth()&&view->maximumHeight()==view->minimumHeight());
const LONG borderWidth = 8;
RECT winrect;
GetWindowRect(msg->hwnd, &winrect);
long x = GET_X_LPARAM(msg->lParam);
long y = GET_Y_LPARAM(msg->lParam);
if (x >= winrect.left && x < winrect.left + borderWidth &&
y < winrect.bottom && y >= winrect.bottom - borderWidth && isResize) {
*result = HTBOTTOMLEFT;
return true; return true;
} }
case WM_NCHITTEST: { if (x < winrect.right && x >= winrect.right - borderWidth &&
auto view = FluApp::getInstance()->wnds[(WId)msg->hwnd];
bool isResize = !(view->maximumWidth()==view->minimumWidth()&&view->maximumHeight()==view->minimumHeight());
const LONG borderWidth = 8;
RECT winrect;
GetWindowRect(msg->hwnd, &winrect);
long x = GET_X_LPARAM(msg->lParam);
long y = GET_Y_LPARAM(msg->lParam);
if (x >= winrect.left && x < winrect.left + borderWidth &&
y < winrect.bottom && y >= winrect.bottom - borderWidth && isResize) { y < winrect.bottom && y >= winrect.bottom - borderWidth && isResize) {
*result = HTBOTTOMLEFT; *result = HTBOTTOMRIGHT;
return true; return true;
}
if (x < winrect.right && x >= winrect.right - borderWidth &&
y < winrect.bottom && y >= winrect.bottom - borderWidth && isResize) {
*result = HTBOTTOMRIGHT;
return true;
}
if (x >= winrect.left && x < winrect.left + borderWidth &&
y >= winrect.top && y < winrect.top + borderWidth && isResize) {
*result = HTTOPLEFT;
return true;
}
if (x < winrect.right && x >= winrect.right - borderWidth &&
y >= winrect.top && y < winrect.top + borderWidth && isResize) {
*result = HTTOPRIGHT;
return true;
}
if (x >= winrect.left && x < winrect.left + borderWidth && isResize) {
*result = HTLEFT;
return true;
}
if (x < winrect.right && x >= winrect.right - borderWidth && isResize) {
*result = HTRIGHT;
return true;
}
if (y < winrect.bottom && y >= winrect.bottom - borderWidth && isResize) {
*result = HTBOTTOM;
return true;
}
if (y >= winrect.top && y < winrect.top + borderWidth && isResize) {
*result = HTTOP;
return true;
}
return false;
} }
default: if (x >= winrect.left && x < winrect.left + borderWidth &&
break; y >= winrect.top && y < winrect.top + borderWidth && isResize) {
*result = HTTOPLEFT;
return true;
} }
if (x < winrect.right && x >= winrect.right - borderWidth &&
y >= winrect.top && y < winrect.top + borderWidth && isResize) {
*result = HTTOPRIGHT;
return true;
}
if (x >= winrect.left && x < winrect.left + borderWidth && isResize) {
*result = HTLEFT;
return true;
}
if (x < winrect.right && x >= winrect.right - borderWidth && isResize) {
*result = HTRIGHT;
return true;
}
if (y < winrect.bottom && y >= winrect.bottom - borderWidth && isResize) {
*result = HTBOTTOM;
return true;
}
if (y >= winrect.top && y < winrect.top + borderWidth && isResize) {
*result = HTTOP;
return true;
}
return false;
} }
default:
break;
}
}
#endif #endif
return false; return false;
} }

View File

@ -5,6 +5,8 @@
#include "FluTheme.h" #include "FluTheme.h"
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#pragma comment(lib, "Dwmapi.lib")
#pragma comment(lib, "User32.lib")
#include <dwmapi.h> #include <dwmapi.h>
#include <Windows.h> #include <Windows.h>
#include <windowsx.h> #include <windowsx.h>
@ -23,21 +25,29 @@ WindowHelper::WindowHelper(QObject *parent)
void WindowHelper::initWindow(QQuickWindow* window){ void WindowHelper::initWindow(QQuickWindow* window){
this->window = window; this->window = window;
#ifdef Q_OS_WIN
if(FluTheme::getInstance()->frameless()){
HWND wnd = (HWND)window->winId();
SetWindowLongPtr(wnd, GWL_STYLE, static_cast<LONG>(Style::aero_borderless));
const MARGINS shadow_on = { 1, 1, 1, 1 };
DwmExtendFrameIntoClientArea(wnd, &shadow_on);
SetWindowPos(wnd, Q_NULLPTR, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE);
ShowWindow(wnd, SW_SHOW);
}
#endif
} }
QVariant WindowHelper::createRegister(const QString& path){ void WindowHelper::firstUpdate(){
FluRegister *p = new FluRegister(this->window); if(isFisrt){
p->from(this->window); #ifdef Q_OS_WIN
if(FluTheme::getInstance()->frameless()){
HWND wnd = (HWND)window->winId();
SetWindowLongPtr(wnd, GWL_STYLE, static_cast<LONG>(Style::aero_borderless));
const MARGINS shadow_on = { 1, 1, 1, 1 };
DwmExtendFrameIntoClientArea(wnd, &shadow_on);
SetWindowPos(wnd, Q_NULLPTR, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE);
ShowWindow(wnd, SW_SHOW);
window->setFlag(Qt::FramelessWindowHint,false);
}
#endif
isFisrt = false;
}
}
QVariant WindowHelper::createRegister(QQuickWindow* window,const QString& path){
FluRegister *p = new FluRegister(window);
p->from(window);
p->path(path); p->path(path);
return QVariant::fromValue(p); return QVariant::fromValue(p);
} }

View File

@ -16,10 +16,13 @@ public:
Q_INVOKABLE void initWindow(QQuickWindow* window); Q_INVOKABLE void initWindow(QQuickWindow* window);
Q_INVOKABLE void destoryWindow(); Q_INVOKABLE void destoryWindow();
Q_INVOKABLE QVariant createRegister(const QString& path); Q_INVOKABLE QVariant createRegister(QQuickWindow* window,const QString& path);
Q_INVOKABLE void firstUpdate();
private: private:
QQuickWindow* window; QQuickWindow* window;
bool isFisrt=true;
}; };
#endif // WINDOWHELPER_H #endif // WINDOWHELPER_H

View File

@ -24,6 +24,7 @@ Item {
y: -Math.round(cursorHeight/2) y: -Math.round(cursorHeight/2)
height: parent.height+cursorHeight height: parent.height+cursorHeight
anchors.left: parent.left anchors.left: parent.left
preventStealing: true
anchors.right: parent.right anchors.right: parent.right
function handleMouse(mouse) { function handleMouse(mouse) {
if (mouse.buttons & Qt.LeftButton) { if (mouse.buttons & Qt.LeftButton) {

View File

@ -19,8 +19,6 @@ Rectangle{
property color maximizeHoverColor: FluTheme.dark ? Qt.rgba(1,1,1,0.1) : Qt.rgba(0,0,0,0.06) property color maximizeHoverColor: FluTheme.dark ? Qt.rgba(1,1,1,0.1) : Qt.rgba(0,0,0,0.06)
property color closeNormalColor: Qt.rgba(0,0,0,0) property color closeNormalColor: Qt.rgba(0,0,0,0)
property color closeHoverColor: Qt.rgba(251/255,115/255,115/255,1) property color closeHoverColor: Qt.rgba(251/255,115/255,115/255,1)
property bool showDark: false property bool showDark: false
property color borerlessColor : FluTheme.dark ? FluTheme.primaryColor.lighter : FluTheme.primaryColor.dark property color borerlessColor : FluTheme.dark ? FluTheme.primaryColor.lighter : FluTheme.primaryColor.dark
@ -67,7 +65,6 @@ Rectangle{
height: root.height height: root.height
spacing: 0 spacing: 0
RowLayout{ RowLayout{
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
Layout.rightMargin: 5 Layout.rightMargin: 5
@ -80,7 +77,11 @@ Rectangle{
FluToggleSwitch{ FluToggleSwitch{
selected: FluTheme.dark selected: FluTheme.dark
clickFunc:function(){ clickFunc:function(){
FluTheme.dark = !FluTheme.dark if(FluTheme.dark){
FluTheme.darkMode = FluDarkMode.Light
}else{
FluTheme.darkMode = FluDarkMode.Dark
}
} }
} }
} }

View File

@ -1,4 +1,6 @@
import QtQuick import QtQuick
import QtQuick.Controls
import QtQuick.Window
import FluentUI import FluentUI
Rectangle { Rectangle {
@ -11,12 +13,24 @@ Rectangle {
property int bottomPadding : 0 property int bottomPadding : 0
radius: 4 radius: 4
color: FluTheme.dark ? Qt.rgba(39/255,39/255,39/255,1) : Qt.rgba(251/255,251/255,253/255,1) color: FluTheme.dark ? Window.active ? Qt.rgba(38/255,44/255,54/255,1) : Qt.rgba(39/255,39/255,39/255,1) : Qt.rgba(251/255,251/255,253/255,1)
border.color: FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,229/255,234/255,1) border.color: FluTheme.dark ? Window.active ? Qt.rgba(55/255,55/255,55/255,1):Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,229/255,234/255,1)
border.width: 1 border.width: 1
implicitHeight: height implicitHeight: height
implicitWidth: width implicitWidth: width
Behavior on color{
ColorAnimation {
duration: 300
}
}
Behavior on border.color{
ColorAnimation {
duration: 300
}
}
Item { Item {
id: container id: container
anchors.fill: parent anchors.fill: parent

View File

@ -3,20 +3,25 @@ import QtQuick.Controls
import FluentUI import FluentUI
FluTextBox{ FluTextBox{
property var items:[] property var items:[]
property string emptyText: "没有找到结果" property string emptyText: "没有找到结果"
property int autoSuggestBoxReplacement: FluentIcons.Search property int autoSuggestBoxReplacement: FluentIcons.Search
signal itemClicked(var data) signal itemClicked(var data)
signal handleClicked signal handleClicked
id:control
width: 300
Component.onCompleted: {
loadData()
}
QtObject{ QtObject{
id:d id:d
property bool flagVisible: true property bool flagVisible: true
} }
id:control
width: 300
Component.onCompleted: {
loadData()
}
Popup{ Popup{
id:control_popup id:control_popup
y:control.height y:control.height
@ -121,14 +126,6 @@ FluTextBox{
control_popup.visible = true control_popup.visible = true
} }
} }
TapHandler {
acceptedButtons: Qt.RightButton
onTapped: control.echoMode !== TextInput.Password && menu.popup()
}
FluTextBoxMenu{
id:menu
inputItem: control
}
function handleClick(modelData){ function handleClick(modelData){
control_popup.visible = false control_popup.visible = false

View File

@ -0,0 +1,100 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import FluentUI
Item {
property int textSize: 15
property string separator: "/"
property var items: []
property int spacing: 5
signal clickItem(var model)
id:control
implicitWidth: 300
height: 30
onItemsChanged: {
list_model.clear()
list_model.append(items)
}
ListModel{
id:list_model
}
ListView{
id:list_view
width: parent.width
height: 30
orientation: ListView.Horizontal
model: list_model
clip: true
spacing : control.spacing
boundsBehavior: ListView.StopAtBounds
remove: Transition {
NumberAnimation {
properties: "opacity"
from: 1
to: 0
duration: 83
}
}
add: Transition {
NumberAnimation {
properties: "opacity"
from: 0
to: 1
duration: 83
}
}
delegate: Item{
height: item_layout.height
width: item_layout.width
RowLayout{
id:item_layout
spacing: list_view.spacing
height: list_view.height
FluText{
text:model.title
Layout.alignment: Qt.AlignVCenter
color: {
if(item_mouse.pressed){
return FluTheme.dark ? Qt.rgba(150/255,150/255,150/235,1) : Qt.rgba(134/255,134/255,134/235,1)
}
if(item_mouse.containsMouse){
return FluTheme.dark ? Qt.rgba(204/255,204/255,204/235,1) : Qt.rgba(92/255,92/255,92/235,1)
}
return FluTheme.dark ? Qt.rgba(255/255,255/255,255/235,1) : Qt.rgba(26/255,26/255,26/235,1)
}
MouseArea{
id:item_mouse
anchors.fill: parent
hoverEnabled: true
onClicked: {
control.clickItem(model)
}
}
}
FluText{
text:control.separator
font.pixelSize: control.textSize
visible: list_view.count-1 !== index
Layout.alignment: Qt.AlignVCenter
}
}
}
}
function remove(index,count){
list_model.remove(index,count)
}
function count(){
return list_model.count
}
}

View File

@ -1,8 +1,9 @@
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Controls.Basic
import FluentUI import FluentUI
FluControl { Button {
property bool disabled: false property bool disabled: false
property color normalColor: FluTheme.dark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(254/255,254/255,254/255,1) property color normalColor: FluTheme.dark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(254/255,254/255,254/255,1)
@ -16,7 +17,6 @@ FluControl {
rightPadding:15 rightPadding:15
enabled: !disabled enabled: !disabled
focusPolicy:Qt.TabFocus focusPolicy:Qt.TabFocus
Keys.onSpacePressed: control.visualFocus&&clicked() Keys.onSpacePressed: control.visualFocus&&clicked()
background: Rectangle{ background: Rectangle{

View File

@ -67,21 +67,26 @@ Rectangle {
modal: true modal: true
dim:false dim:false
enter: Transition { enter: Transition {
NumberAnimation { reversible: true
property: "y"
from:0
to:popup.y
duration: 150
}
NumberAnimation { NumberAnimation {
property: "opacity" property: "opacity"
from:0 from:0
to:1 to:1
duration: 150 duration: 83
} }
} }
exit:Transition {
NumberAnimation {
property: "opacity"
from:1
to:0
duration: 83
}
}
contentItem: Item{ contentItem: Item{
anchors.fill: parent clip: true
FluCalendarView{ FluCalendarView{
id:container id:container
onDateClicked: onDateClicked:
@ -94,15 +99,19 @@ Rectangle {
} }
} }
} }
background: Item{} background: Item{
FluShadow{
radius: 5
}
}
function showPopup() { function showPopup() {
var pos = control.mapToItem(null, 0, 0) var pos = control.mapToItem(null, 0, 0)
if(window.height>pos.y+control.height+popup.height){ if(window.height>pos.y+control.height+container.height){
popup.y = control.height popup.y = control.height
} else if(pos.y>popup.height){ } else if(pos.y>container.height){
popup.y = -popup.height popup.y = -container.height
} else { } else {
popup.y = window.height-(pos.y+popup.height) popup.y = window.height-(pos.y+container.height)
} }
popup.x = -(popup.width-control.width)/2 popup.x = -(popup.width-control.width)/2
popup.open() popup.open()

View File

@ -12,9 +12,11 @@ Item {
id:control id:control
width: 400 width: 400
height: 300 height: 300
ListModel{ ListModel{
id:content_model id:content_model
} }
FluRectangle{ FluRectangle{
anchors.fill: parent anchors.fill: parent
radius: [control.radius,control.radius,control.radius,control.radius] radius: [control.radius,control.radius,control.radius,control.radius]
@ -105,9 +107,6 @@ Item {
return false return false
return true return true
} }
layer.samples: 4
layer.enabled: true
layer.smooth: true
border.width: 1 border.width: 1
border.color: FluColors.Grey100 border.color: FluColors.Grey100
color: list_view.currentIndex === index ? FluTheme.primaryColor.dark : Qt.rgba(1,1,1,0.5) color: list_view.currentIndex === index ? FluTheme.primaryColor.dark : Qt.rgba(1,1,1,0.5)

View File

@ -1,9 +1,10 @@
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Controls.Basic
import QtQuick.Layouts import QtQuick.Layouts
import FluentUI import FluentUI
FluControl { Button {
property bool selected: false property bool selected: false
property var clickFunc property var clickFunc

View File

@ -1,10 +1,11 @@
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Controls.Basic
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Window import QtQuick.Window
import FluentUI import FluentUI
FluControl{ Button{
id:control id:control
width: 36 width: 36
height: 36 height: 36
@ -33,34 +34,42 @@ FluControl{
height: container.height height: container.height
width: container.width width: container.width
contentItem: Item{ contentItem: Item{
anchors.fill: parent clip: true
FluColorView{ FluColorView{
id:container id:container
} }
} }
background:Item{} background:Item{
enter: Transition { FluShadow{
NumberAnimation { radius: 5
property: "y"
from:0
to:popup.y
duration: 150
} }
}
enter: Transition {
reversible: true
NumberAnimation { NumberAnimation {
property: "opacity" property: "opacity"
from:0 from:0
to:1 to:1
duration: 150 duration: 83
}
}
exit:Transition {
NumberAnimation {
property: "opacity"
from:1
to:0
duration: 83
} }
} }
function showPopup() { function showPopup() {
var pos = control.mapToItem(null, 0, 0) var pos = control.mapToItem(null, 0, 0)
if(window.height>pos.y+control.height+popup.height){ if(window.height>pos.y+control.height+container.height){
popup.y = control.height popup.y = control.height
} else if(pos.y>popup.height){ } else if(pos.y>container.height){
popup.y = -popup.height popup.y = -container.height
} else { } else {
popup.y = window.height-(pos.y+popup.height) popup.y = window.height-(pos.y+container.height)
} }
popup.x = -(popup.width-control.width)/2 popup.x = -(popup.width-control.width)/2
popup.open() popup.open()

View File

@ -7,11 +7,19 @@ Popup {
id: popup id: popup
property string title: "Title" property string title: "Title"
property string message: "Messaeg" property string message: "Message"
property string neutralText: "Neutral"
property string negativeText: "Negative" property string negativeText: "Negative"
property string positiveText: "Positive" property string positiveText: "Positive"
signal neutralClicked
signal negativeClicked signal negativeClicked
signal positiveClicked signal positiveClicked
enum ButtonFlag{
NegativeButton=1
,NeutralButton=2
,PositiveButton=4
}
property int buttonFlags: FluContentDialog.NegativeButton | FluContentDialog.PositiveButton
property var minWidth: { property var minWidth: {
if(Window.window==null) if(Window.window==null)
return 400 return 400
@ -21,6 +29,28 @@ Popup {
anchors.centerIn: Overlay.overlay anchors.centerIn: Overlay.overlay
closePolicy: Popup.CloseOnEscape closePolicy: Popup.CloseOnEscape
background:Item{} background:Item{}
enter: Transition {
reversible: true
NumberAnimation {
properties: "opacity,scale"
from:0
to:1
duration: 167
easing.type: Easing.BezierSpline
easing.bezierCurve: [ 0, 0, 0, 1 ]
}
}
exit:Transition {
NumberAnimation {
properties: "opacity,scale"
from:1
to:0
duration: 167
easing.type: Easing.BezierSpline
easing.bezierCurve: [ 1, 0, 0, 0 ]
}
}
contentItem: Rectangle { contentItem: Rectangle {
id:layout_content id:layout_content
implicitWidth:minWidth implicitWidth:minWidth
@ -74,40 +104,48 @@ Popup {
right: parent.right right: parent.right
} }
Item { RowLayout{
id:divider anchors
width: 1 {
height: parent.height centerIn: parent
anchors.centerIn: parent margins: spacing
} fill: parent
}
spacing: 15
FluButton{
id:neutral_btn
Layout.fillWidth: true
Layout.fillHeight: true
visible: popup.buttonFlags&FluContentDialog.NeutralButton
text: neutralText
onClicked: {
popup.close()
neutralClicked()
}
}
FluButton{ FluButton{
anchors{ id:negative_btn
left: parent.left Layout.fillWidth: true
leftMargin: 20 Layout.fillHeight: true
rightMargin: 10 visible: popup.buttonFlags&FluContentDialog.NegativeButton
right: divider.left text: negativeText
verticalCenter: parent.verticalCenter onClicked: {
popup.close()
negativeClicked()
}
} }
text: negativeText
onClicked: {
popup.close()
negativeClicked()
}
}
FluFilledButton{ FluFilledButton{
anchors{ id:positive_btn
right: parent.right Layout.fillWidth: true
left: divider.right Layout.fillHeight: true
rightMargin: 20 visible: popup.buttonFlags&FluContentDialog.PositiveButton
leftMargin: 10 text: positiveText
verticalCenter: parent.verticalCenter onClicked: {
} popup.close()
text: positiveText positiveClicked()
onClicked: { }
popup.close()
positiveClicked()
} }
} }
} }

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