main
zhuzihcu 2023-03-03 18:19:48 +08:00
parent 5ee8729353
commit 891270e6d1
32 changed files with 462 additions and 221 deletions

View File

@ -3,5 +3,4 @@ TEMPLATE = subdirs
SUBDIRS += \ SUBDIRS += \
src/FluentUI.pro \ src/FluentUI.pro \
example example
example.depends = src/FluentUI.pro example.depends = src/FluentUI.pro

BIN
README.md

Binary file not shown.

View File

@ -1,4 +1,5 @@
import QtQuick 2.15 import QtQuick 2.15
import QtQuick.Layouts 1.15
import FluentUI 1.0 import FluentUI 1.0
FluWindow { FluWindow {
@ -12,18 +13,60 @@ FluWindow {
title:"关于" title:"关于"
} }
ColumnLayout{
anchors{
top: appbar.bottom
left: parent.left
right: parent.right
}
RowLayout{
Layout.topMargin: 20
Layout.leftMargin: 15
spacing: 14
FluText{ FluText{
text:"关于" text:"FluentUI"
fontStyle: FluText.Display fontStyle: FluText.Title
anchors.centerIn: parent }
FluText{
text:"v1.0.0.0"
fontStyle: FluText.Body
Layout.alignment: Qt.AlignBottom
}
}
MouseArea{ RowLayout{
anchors.fill: parent spacing: 14
Layout.topMargin: 20
Layout.leftMargin: 15
FluText{
text:"作者:"
}
FluText{
text:"朱子楚"
Layout.alignment: Qt.AlignBottom
}
}
RowLayout{
spacing: 14
Layout.topMargin: 20
Layout.leftMargin: 15
FluText{
text:"GitHub"
}
FluTextButton{
id:text_hublink
text:"https://github.com/zhuzichu520/FluentUI"
Layout.alignment: Qt.AlignBottom
onClicked: { onClicked: {
Qt.openUrlExternally(text_hublink.text)
}
} }
} }
} }
} }

View File

@ -9,16 +9,23 @@ Window {
id:app id:app
color: "#00000000" color: "#00000000"
Component.onCompleted: { Component.onCompleted: {
FluApp.isFps = true
FluApp.setContextProperty("installHelper",installHelper)
FluApp.isDark = false FluApp.isDark = false
FluApp.setAppWindow(app) FluApp.setAppWindow(app)
FluApp.routes = { FluApp.routes = {
"/":"qrc:/MainPage.qml", "/":"qrc:/MainPage.qml",
"/Setting":"qrc:/SettingPage.qml", "/Setting":"qrc:/SettingPage.qml",
"/About":"qrc:/AboutPage.qml", "/About":"qrc:/AboutPage.qml",
"/Installer":"qrc:/Installer.qml" "/Installer":"qrc:/Installer.qml",
"/Uninstall":"qrc:/Uninstall.qml"
} }
if(installHelper.isNavigateUninstall()){
FluApp.initialRoute = "/Uninstall"
}else{
FluApp.initialRoute = "/Installer" FluApp.initialRoute = "/Installer"
}
FluApp.run() FluApp.run()
} }

View File

@ -1,5 +1,105 @@
#include "InstallHelper.h" #include "InstallHelper.h"
#include <QDir>
#include <QCoreApplication>
#include <QtConcurrent>
#include <windows.h>
#include <shobjidl.h>
#include <shlguid.h>
#pragma comment(lib, "User32.lib")
#pragma comment(lib, "Ole32.lib")
using CopyProgressCallback = std::function<void(int currentFile, int totalFiles)>;
static void copyDir(const QString& srcPath, const QString& dstPath, CopyProgressCallback callback)
{
QDir srcDir(srcPath);
QDir dstDir(dstPath);
if (!dstDir.exists()) {
dstDir.mkdir(dstPath);
}
QFileInfoList fileInfos = srcDir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
int totalFiles = fileInfos.count();
int currentFile = 0;
foreach (QFileInfo fileInfo, fileInfos) {
currentFile++;
QString srcFilePath = fileInfo.filePath();
QString dstFilePath = dstPath + QDir::separator() + fileInfo.fileName();
if (fileInfo.isDir()) {
copyDir(srcFilePath, dstFilePath, callback);
} else {
QFile dstFile(dstFilePath);
if(dstFile.exists()){
dstFile.remove();
}
QFile::copy(srcFilePath, dstFilePath);
}
if (callback != nullptr) {
callback(currentFile, totalFiles);
}
}
}
static void createHome(const QString& exePath,const QString& linkName){
//创建桌面快捷方式
QFile::link(exePath, QStandardPaths::writableLocation(QStandardPaths::DesktopLocation).append("/").append(linkName));
}
static void createUninstallLink(QString exePath, QString path, QString uninstallLinkName){
#ifdef Q_OS_WIN
QString dst = path.append("\\").append(uninstallLinkName);
IShellLink *pShellLink;
QString args = "--uninstall";
HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
IID_IShellLink, (LPVOID *)&pShellLink);
if (SUCCEEDED(hres))
{
// 设置快捷方式的目标路径和参数
pShellLink->SetPath(exePath.toStdWString().c_str());
pShellLink->SetArguments(args.toStdWString().c_str());
// 设置快捷方式的描述
pShellLink->SetDescription(L"Fluent Uninstall");
// 获取IPersistFile接口
IPersistFile *pPersistFile;
hres = pShellLink->QueryInterface(IID_IPersistFile, (LPVOID *)&pPersistFile);
if (SUCCEEDED(hres))
{
// 保存快捷方式到文件
hres = pPersistFile->Save(dst.toStdWString().c_str(), TRUE);
pPersistFile->Release();
}
pShellLink->Release();
}
CoUninitialize();
// std::string dst = path.append("\\").append(uninstallLinkName).toStdString();
// QFile::link(exePath,QString::fromStdString(dst + " --uninstall"));
#endif
}
static void createStartMenu(const QString& exePath,const QString& fileName,const QString& linkName){
//创建开始菜单快捷方式
QString startMenuPath=QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation).append("/").append(fileName);
QDir dir(startMenuPath);
if(!dir.exists())
{
dir.mkdir(startMenuPath);
}
if(dir.exists())
{
QFile::link(exePath, startMenuPath.append("/").append(linkName));
}
}
InstallHelper::InstallHelper(QObject *parent) InstallHelper::InstallHelper(QObject *parent)
: QObject{parent} : QObject{parent}
{ {
@ -7,6 +107,32 @@ InstallHelper::InstallHelper(QObject *parent)
} }
void InstallHelper::install(const QString& path,bool isHome,bool isStartMenu){ void InstallHelper::install(const QString& path,bool isHome,bool isStartMenu){
QtConcurrent::run([=](){
installing(true); installing(true);
qDebug()<<path; QFuture<void> future = QtConcurrent::run(copyDir,QCoreApplication::applicationDirPath(),path,[=](int currentFile, int totalFiles){
if(currentFile==totalFiles){
QString exePath = path+"\\"+"example.exe";
QString fileName = "FluentUI";
QString linkName = "FluentUI.lnk";
QString uninstallLinkName = "Uninstall FluentUI.lnk";
if(isHome){
createHome(exePath,linkName);
}
if(isStartMenu){
createStartMenu(exePath,fileName,linkName);
}
createUninstallLink(exePath,path,uninstallLinkName);
}
});
future.waitForFinished();
qDebug()<<QCoreApplication::applicationDirPath();
qDebug()<<path;
installing(false);
});
}
void InstallHelper::uninstall(){
QString currentDir = QCoreApplication::applicationDirPath();
QDir dir(currentDir);
dir.removeRecursively();
} }

View File

@ -2,18 +2,32 @@
#define INSTALLHELPER_H #define INSTALLHELPER_H
#include <QObject> #include <QObject>
#include <QGuiApplication>
#include <QDebug> #include <QDebug>
#include "stdafx.h" #include "stdafx.h"
class InstallHelper : public QObject class InstallHelper : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO(bool,installing) Q_PROPERTY_AUTO(bool,installing)
public: public:
explicit InstallHelper(QObject *parent = nullptr); explicit InstallHelper(QObject *parent = nullptr);
Q_INVOKABLE void install(const QString& path,bool isHome,bool isStartMenu); Q_INVOKABLE void install(const QString& path,bool isHome,bool isStartMenu);
signals:
Q_INVOKABLE QString applicationFilePath(){
return QGuiApplication::arguments().join(" ");
}
Q_INVOKABLE bool isNavigateUninstall(){
return true;
// return QGuiApplication::arguments().contains("--uninstall");
}
Q_INVOKABLE void uninstall();
}; };

View File

@ -2,7 +2,6 @@
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import QtQuick.Dialogs 1.3 as Dialogs import QtQuick.Dialogs 1.3 as Dialogs
import Qt.labs.platform 1.1 import Qt.labs.platform 1.1
import UI 1.0
import FluentUI 1.0 import FluentUI 1.0
FluWindow { FluWindow {
@ -27,9 +26,6 @@ FluWindow {
Item{ Item{
id:data id:data
InstallHelper{
id:helper
}
Dialogs.FileDialog { Dialogs.FileDialog {
id: fileDialog id: fileDialog
selectFolder: true selectFolder: true
@ -72,7 +68,8 @@ FluWindow {
text:"更改路径" text:"更改路径"
Layout.rightMargin: 30 Layout.rightMargin: 30
onClicked: { onClicked: {
fileDialog.open() showInfo(installHelper.applicationFilePath())
// fileDialog.open()
} }
} }
} }
@ -122,7 +119,7 @@ FluWindow {
FluFilledButton{ FluFilledButton{
text:"同意并安装" text:"同意并安装"
onClicked: { onClicked: {
helper.install(textbox_path.text,checkbox_home.checked,checkbox_startmenu.checked) installHelper.install(textbox_path.text,checkbox_home.checked,checkbox_startmenu.checked)
} }
} }
FluButton{ FluButton{
@ -139,7 +136,7 @@ FluWindow {
Rectangle{ Rectangle{
anchors.fill: parent anchors.fill: parent
visible: helper.installing visible: installHelper.installing
color: "#80000000" color: "#80000000"
MouseArea{ MouseArea{

View File

@ -17,6 +17,8 @@ FluWindow {
FluAppBar{ FluAppBar{
id:appbar id:appbar
title: "FluentUI" title: "FluentUI"
showDark: true
showFps: true
} }
Item{ Item{
@ -75,18 +77,24 @@ FluWindow {
id:menu id:menu
x:40 x:40
margins:4 margins:4
FluMenuItem{
text:"意见反馈"
onClicked:{
showInfo("正在建设中...")
}
}
FluMenuItem{ FluMenuItem{
text:"关于" text:"关于"
onClicked:{ onClicked:{
FluApp.navigate("/About") FluApp.navigate("/About")
} }
} }
FluMenuItem{ // FluMenuItem{
text:"设置" // text:""
onClicked:{ // onClicked:{
FluApp.navigate("/Setting") // FluApp.navigate("/Setting")
} // }
} // }
} }
onClicked:{ onClicked:{
menu.open() menu.open()

View File

@ -79,9 +79,6 @@ Item {
source: "qrc:/res/svg/avatar_1.svg" source: "qrc:/res/svg/avatar_1.svg"
sourceSize: Qt.size(width,height) sourceSize: Qt.size(width,height)
} }
layer.enabled: true
layer.effect: FluDropShadow {}
} }
FluRectangle{ FluRectangle{
width: 50 width: 50
@ -93,8 +90,6 @@ Item {
sourceSize: Qt.size(width,height) sourceSize: Qt.size(width,height)
source: "qrc:/res/svg/avatar_2.svg" source: "qrc:/res/svg/avatar_2.svg"
} }
layer.enabled: true
layer.effect: FluDropShadow {}
} }
FluRectangle{ FluRectangle{
width: 50 width: 50
@ -106,12 +101,6 @@ Item {
sourceSize: Qt.size(width,height) sourceSize: Qt.size(width,height)
source: "qrc:/res/svg/avatar_3.svg" source: "qrc:/res/svg/avatar_3.svg"
} }
layer.enabled: true
layer.effect: DropShadow {
radius: 5
samples: 4
color: "#80000000"
}
} }
FluRectangle{ FluRectangle{
width: 50 width: 50
@ -123,8 +112,6 @@ Item {
sourceSize: Qt.size(width,height) sourceSize: Qt.size(width,height)
source: "qrc:/res/svg/avatar_4.svg" source: "qrc:/res/svg/avatar_4.svg"
} }
layer.enabled: true
layer.effect: FluDropShadow {}
} }
} }
@ -139,12 +126,6 @@ Item {
sourceSize: Qt.size(width,height) sourceSize: Qt.size(width,height)
} }
Layout.topMargin: 10 Layout.topMargin: 10
layer.enabled: true }
layer.effect: FluDropShadow {}
}
} }
} }

68
example/Uninstall.qml Normal file
View File

@ -0,0 +1,68 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Dialogs 1.3 as Dialogs
import Qt.labs.platform 1.1
import FluentUI 1.0
FluWindow {
id:window
width: 800
height: 400
minimumWidth:800
maximumWidth:800
minimumHeight:400
maximumHeight:400
title:"卸载向导"
FluAppBar{
id:appbar
title: "卸载向导"
}
ColumnLayout{
width: parent.width
anchors{
top: appbar.bottom
bottom: parent.bottom
topMargin: 20
}
Item{
width: 1
Layout.fillHeight: true
}
Rectangle{
Layout.fillWidth: true
border.width: 1
border.color: FluApp.isDark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(238/255,238/255,238/255,1)
height: 60
color: FluApp.isDark ? "#323232" : "#FFFFFF"
RowLayout{
anchors{
right: parent.right
rightMargin: 30
verticalCenter: parent.verticalCenter
}
spacing: 14
FluButton{
text:"取消"
onClicked: {
window.close()
}
}
FluButton{
text:"确定要卸载"
onClicked: {
installHelper.uninstall()
}
}
}
}
}
}

View File

@ -1,4 +1,4 @@
QT += quick QT += quick concurrent
CONFIG += c++11 CONFIG += c++11
DEFINES += QT_DEPRECATED_WARNINGS QT_NO_WARNING_OUTPUT DEFINES += QT_DEPRECATED_WARNINGS QT_NO_WARNING_OUTPUT
@ -13,37 +13,6 @@ qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target !isEmpty(target.path): INSTALLS += target
#### 如果你正在使用静态库.a 那么你还需要将下面的配置注释取消掉
#### 其它项目使用方法也是如此
# DEFINES += STATICLIB
# LIBNAME = FluentUI
# CONFIG(debug, debug|release) {
# contains(QMAKE_HOST.os,Windows) {
# LIBNAME = FluentUId
# }else{
# LIBNAME = FluentUI_debug
# }
# }
# # Additional import path used to resolve QML modules in Qt Creator's code model
# QML_IMPORT_PATH = $$OUT_PWD/../bin/
# # Additional import path used to resolve QML modules just for Qt Quick Designer
# QML_DESIGNER_IMPORT_PATH = $$OUT_PWD/../bin/
# INCLUDEPATH += $$OUT_PWD/../bin/FluentUI/
# DEPENDPATH += $$OUT_PWD/../bin/FluentUI/
# LIBS += -L$$OUT_PWD/../bin/FluentUI/ -l$${LIBNAME}
# PRE_TARGETDEPS += $$OUT_PWD/../bin/FluentUI/lib$${LIBNAME}.a
### 注意:静态库 .so .dylib .dll 是自动安装的Qt qml plugin目录中不需要此步配置
HEADERS += \ HEADERS += \
InstallHelper.h \ InstallHelper.h \
stdafx.h stdafx.h

View File

@ -1,35 +1,18 @@
#include <QGuiApplication> #include <QGuiApplication>
#include <QQmlApplicationEngine> #include <QQmlApplicationEngine>
#include <QQmlContext>
#include "InstallHelper.h" #include "InstallHelper.h"
#if defined(STATICLIB)
#include <FluentUI.h>
#endif
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QCoreApplication::setOrganizationName("ZhuZiChu"); QCoreApplication::setOrganizationName("ZhuZiChu");
QCoreApplication::setOrganizationDomain("https://zhuzichu520.github.io"); QCoreApplication::setOrganizationDomain("https://zhuzichu520.github.io");
QCoreApplication::setApplicationName("FluentUI"); QCoreApplication::setApplicationName("FluentUI");
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
qputenv("QSG_RENDER_LOOP","basic");
QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Round);
#endif
// QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv); QGuiApplication app(argc, argv);
QQmlApplicationEngine engine; QQmlApplicationEngine engine;
qDebug()<<"setContextProperty------->1";
qmlRegisterType<InstallHelper>("UI",1,0,"InstallHelper"); engine.rootContext()->setContextProperty("installHelper",new InstallHelper());
#if defined(STATICLIB)
FluentUI::create(&engine);
#endif
const QUrl url(QStringLiteral("qrc:/App.qml")); const QUrl url(QStringLiteral("qrc:/App.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) { &app, [url](QObject *obj, const QUrl &objUrl) {

View File

@ -27,5 +27,6 @@
<file>Installer.qml</file> <file>Installer.qml</file>
<file>T_Awesome.qml</file> <file>T_Awesome.qml</file>
<file>T_TextBox.qml</file> <file>T_TextBox.qml</file>
<file>Uninstall.qml</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -22,8 +22,7 @@ FluApp *FluApp::getInstance()
FluApp::FluApp(QObject *parent) FluApp::FluApp(QObject *parent)
: QObject{parent} : QObject{parent}
{ {
isDark(true); isDark(false);
isFps(true);
} }
void FluApp::setAppWindow(QWindow *window){ void FluApp::setAppWindow(QWindow *window){

View File

@ -4,7 +4,9 @@
#include <QObject> #include <QObject>
#include <QWindow> #include <QWindow>
#include <QJsonArray> #include <QJsonArray>
#include <QQmlContext>
#include <QJsonObject> #include <QJsonObject>
#include <QQmlEngine>
#include "FramelessView.h" #include "FramelessView.h"
#include "stdafx.h" #include "stdafx.h"
@ -13,7 +15,6 @@ class FluApp : public QObject
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO(QString,initialRoute); Q_PROPERTY_AUTO(QString,initialRoute);
Q_PROPERTY_AUTO(bool,isDark); Q_PROPERTY_AUTO(bool,isDark);
Q_PROPERTY_AUTO(bool,isFps);
Q_PROPERTY_AUTO(QJsonObject,routes); Q_PROPERTY_AUTO(QJsonObject,routes);
public: public:
@ -36,10 +37,20 @@ public:
Q_INVOKABLE void clipText(const QString& text); Q_INVOKABLE void clipText(const QString& text);
Q_INVOKABLE void setContextProperty(const QString &name, QObject *data){
if(engine){
engine->rootContext()->setContextProperty(name,data);
}
}
void setEngine(QQmlEngine *engine){
this->engine = engine;
}
private: private:
static FluApp* m_instance; static FluApp* m_instance;
QQmlEngine *engine;
QWindow *appWindow; QWindow *appWindow;
}; };

View File

@ -32,10 +32,9 @@ void Fluent::registerTypes(const char *uri){
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluMenu.qml"),uri,major,minor,"FluMenu"); qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluMenu.qml"),uri,major,minor,"FluMenu");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluMenuItem.qml"),uri,major,minor,"FluMenuItem"); qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluMenuItem.qml"),uri,major,minor,"FluMenuItem");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluScrollBar.qml"),uri,major,minor,"FluScrollBar"); qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluScrollBar.qml"),uri,major,minor,"FluScrollBar");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTextButton.qml"),uri,major,minor,"FluTextButton");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluMultiLineTextBox.qml"),uri,major,minor,"FluMultiLineTextBox"); qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluMultiLineTextBox.qml"),uri,major,minor,"FluMultiLineTextBox");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluDropShadow.qml"),uri,major,minor,"FluDropShadow");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTooltip.qml"),uri,major,minor,"FluTooltip"); qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTooltip.qml"),uri,major,minor,"FluTooltip");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluDivider.qml"),uri,major,minor,"FluDivider"); qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluDivider.qml"),uri,major,minor,"FluDivider");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluIcon.qml"),uri,major,minor,"FluIcon"); qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluIcon.qml"),uri,major,minor,"FluIcon");
@ -72,5 +71,7 @@ void Fluent::initializeEngine(QQmlEngine *engine, const char *uri)
font.setFamily("Microsoft YaHei"); font.setFamily("Microsoft YaHei");
QGuiApplication::setFont(font); QGuiApplication::setFont(font);
QFontDatabase::addApplicationFont(":/com.zhuzichu/res/font/fontawesome-webfont.ttf"); QFontDatabase::addApplicationFont(":/com.zhuzichu/res/font/fontawesome-webfont.ttf");
engine->rootContext()->setContextProperty("FluApp",FluApp::getInstance()); FluApp* app = FluApp::getInstance();
app->setEngine(engine);
engine->rootContext()->setContextProperty("FluApp",app);
} }

View File

@ -2,14 +2,10 @@
#include "Fluent.h" #include "Fluent.h"
void FluentUI::create(QQmlEngine *engine)
{
engine->addImportPath("/");
Fluent::getInstance()->initializeEngine(engine,URI_STR);
Fluent::getInstance()->registerTypes(URI_STR);
}
QString FluentUI::version() void FluentUI::registerTypes(const char *uri){
{ Fluent::getInstance()->registerTypes(uri);
return Fluent::getInstance()->version(); }
void FluentUI::initializeEngine(QQmlEngine *engine, const char *uri){
Fluent::getInstance()->initializeEngine(engine,uri);
} }

View File

@ -7,8 +7,8 @@ class FluentUI
{ {
public: public:
static void create(QQmlEngine* engine); static void registerTypes(const char *uri) ;
static QString version(); static void initializeEngine(QQmlEngine *engine, const char *uri);
}; };
#endif // FLUENTUI_H #endif // FLUENTUI_H

View File

@ -5,24 +5,11 @@ TARGET = FluentUI
TARGET = $$qtLibraryTarget($$TARGET) TARGET = $$qtLibraryTarget($$TARGET)
uri = FluentUI uri = FluentUI
##########################################
CONFIG += sharedlib # staticlib or sharedlib CONFIG += sharedlib # staticlib or sharedlib
#** 多次切换编译构建模式,建议先清理缓存项目右键->清理
#*[staticlib] 构建静态库.a
#需要修改example.pro请打开后按说明操作
#*[sharedlib] 构建动态库 .dll .so .dylib
#会自动安装到Qt qmlplugin目录中
#无需其它配置即可运行demo以及其它项目中使用
#发布目标平台前必须每个平台都要构建一次
##########################################
RESOURCES += \ RESOURCES += \
res.qrc res.qrc
# Input
HEADERS += \ HEADERS += \
Def.h \ Def.h \
FluApp.h \ FluApp.h \
@ -33,7 +20,6 @@ HEADERS += \
qml_plugin.h \ qml_plugin.h \
stdafx.h stdafx.h
SOURCES += \ SOURCES += \
Def.cpp \ Def.cpp \
FluApp.cpp \ FluApp.cpp \
@ -50,7 +36,6 @@ win32 {
FramelessView_unix.cpp FramelessView_unix.cpp
} }
DEFINES += VERSION_IN=\\\"1.0.0\\\" DEFINES += VERSION_IN=\\\"1.0.0\\\"
DEFINES += URI_STR=\\\"$$uri\\\" DEFINES += URI_STR=\\\"$$uri\\\"

View File

@ -15,6 +15,9 @@ Rectangle{
property string title: "标题" property string title: "标题"
property bool showDark: false
property bool showFps: false
property bool resizable: { property bool resizable: {
if(Window.window == null){ if(Window.window == null){
return false return false
@ -63,12 +66,13 @@ Rectangle{
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
Layout.rightMargin: 12 Layout.rightMargin: 12
Layout.topMargin: 5 Layout.topMargin: 5
visible: FluApp.isFps visible: showFps
} }
RowLayout{ RowLayout{
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
spacing: 5 spacing: 5
visible: showDark
FluText{ FluText{
text:"夜间模式" text:"夜间模式"
fontStyle: FluText.Body fontStyle: FluText.Body
@ -112,7 +116,6 @@ Rectangle{
icon : FluentIcons.FA_close icon : FluentIcons.FA_close
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
text:"关闭" text:"关闭"
iconSize: 15
onClicked: { onClicked: {
Window.window.close() Window.window.close()
} }

View File

@ -1,8 +0,0 @@
import QtQuick 2.15
import QtGraphicalEffects 1.15
DropShadow {
radius: 5
samples: 4
color: FluApp.isDark ? "#80FFFFFF" : "#40000000"
}

View File

@ -6,13 +6,14 @@ Popup {
id: popup id: popup
default property alias content: container.children default property alias content: container.children
background: FluRectangle { background: Rectangle {
implicitWidth: 140 implicitWidth: 140
implicitHeight: container.height implicitHeight: container.height
color:FluApp.isDark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(237/255,237/255,237/255,1) color:FluApp.isDark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(237/255,237/255,237/255,1)
radius: [5,5,5,5] radius: 5
layer.effect: FluDropShadow{} FluShadow{
layer.enabled: true radius: 5
}
Column{ Column{
spacing: 5 spacing: 5
topPadding: 5 topPadding: 5

View File

@ -8,6 +8,7 @@ Item{
property color color : "#FFFFFF" property color color : "#FFFFFF"
property color borderColor:"red" property color borderColor:"red"
property int borderWidth: 1 property int borderWidth: 1
property bool shadow: true
default property alias contentItem: container.children default property alias contentItem: container.children
Rectangle{ Rectangle{
@ -18,6 +19,17 @@ Item{
color:root.color color:root.color
} }
FluShadow{
anchors.fill: container
radius: root.radius[0]
visible: {
if(root.radius[0] === root.radius[1] && root.radius[0] === root.radius[2] && root.radius[0] === root.radius[3] && root.shadow){
return true
}
return false
}
}
Canvas { Canvas {
id: canvas id: canvas
anchors.fill: parent anchors.fill: parent

View File

@ -0,0 +1,65 @@
import QtQuick 2.15
Item {
id:root
anchors.fill: parent
anchors.margins: -4
property color color: FluApp.isDark ? "#FFFFFF" : "#000000"
property var radius: 4
Rectangle{
width: root.width
height: root.height
anchors.centerIn: parent
color: "#00000000"
opacity: 0.02
border.width: 1
radius: root.radius
border.color: root.color
}
Rectangle{
width: root.width - 2
height: root.height - 2
anchors.centerIn: parent
color: "#00000000"
opacity: 0.04
border.width: 1
radius: root.radius
border.color: root.color
}
Rectangle{
width: root.width - 4
height: root.height - 4
anchors.centerIn: parent
color: "#00000000"
opacity: 0.06
border.width: 1
radius: root.radius
border.color: root.color
}
Rectangle{
width: root.width - 6
height: root.height - 6
anchors.centerIn: parent
color: "#00000000"
opacity: 0.08
border.width: 1
radius: root.radius
border.color: root.color
}
Rectangle{
width: root.width - 8
height: root.height - 8
anchors.centerIn: parent
opacity: 0.1
radius: root.radius
color: "#00000000"
border.width: 1
border.color: root.color
}
}

View File

@ -40,11 +40,12 @@ Item{
id:dot id:dot
width: dotSize width: dotSize
height: dotSize height: dotSize
FluShadow{
radius: 15
}
radius: 15 radius: 15
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
layer.enabled: true
color:FluApp.isDark ? Qt.rgba(69/255,69/255,69/255,1) :Qt.rgba(1,1,1,1) color:FluApp.isDark ? Qt.rgba(69/255,69/255,69/255,1) :Qt.rgba(1,1,1,1)
layer.effect: FluDropShadow {}
Rectangle{ Rectangle{
width: dotSize/2 width: dotSize/2
height: dotSize/2 height: dotSize/2

View File

@ -0,0 +1,22 @@
import QtQuick 2.15
import FluentUI 1.0
FluText {
id:root
color: {
if(FluApp.isDark){
return mouse_area.containsMouse?Qt.rgba(73/255,148/255,206/255,1):Qt.rgba(76/255,160/255,224/255,1)
}
return mouse_area.containsMouse?Qt.rgba(24/255,116/255,186/255,1):Qt.rgba(0/255,102/255,180/255,1)
}
signal clicked
MouseArea{
id:mouse_area
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
root.clicked()
}
}
}

View File

@ -18,7 +18,6 @@ ToolTip {
anchors.fill: parent anchors.fill: parent
color: FluApp.isDark ? Qt.rgba(50/255,49/255,48/255,1) : Qt.rgba(1,1,1,1) color: FluApp.isDark ? Qt.rgba(50/255,49/255,48/255,1) : Qt.rgba(1,1,1,1)
radius: 5 radius: 5
layer.enabled: true FluShadow{}
layer.effect: FluDropShadow {}
} }
} }

View File

@ -32,25 +32,22 @@ Item {
FluWindowResize{} FluWindowResize{}
Behavior on opacity{ Behavior on opacity{
NumberAnimation{ NumberAnimation{
duration: 100 duration: 100
} }
} }
FluShadow{
anchors.fill: container
}
Rectangle{ Rectangle{
id:container id:container
color:root.color color:root.color
anchors.fill: parent anchors.fill: parent
anchors.margins: borderless anchors.margins: borderless
layer.enabled: true
layer.effect: DropShadow {
radius: 5
samples: 5
horizontalOffset: 0
verticalOffset: 0
color: "#40000000"
}
} }
Component.onCompleted: { Component.onCompleted: {

View File

@ -31,68 +31,50 @@ MouseArea {
return; return;
} }
var rc = Qt.rect(0, 0, 0, 0);
let e = 0; let e = 0;
if (ptInRect(0,0,border,border, mouse.x, mouse.y)) {
//top-left
rc = Qt.rect(0, 0, border, border);
if (ptInRect(rc, mouse.x, mouse.y)) {
e = Qt.TopEdge | Qt.LeftEdge; e = Qt.TopEdge | Qt.LeftEdge;
window.startSystemResize(e); window.startSystemResize(e);
return; return;
} }
//top if (ptInRect(border,0,window.width-border*2,border, mouse.x, mouse.y)) {
rc = Qt.rect(border, 0, window.width-border*2, border);
if (ptInRect(rc, mouse.x, mouse.y)) {
e = Qt.TopEdge; e = Qt.TopEdge;
window.startSystemResize(e); window.startSystemResize(e);
return; return;
} }
//top-right if (ptInRect(window.width-border,0,border,border, mouse.x, mouse.y)) {
rc = Qt.rect(window.width-border, 0, border, border);
if (ptInRect(rc, mouse.x, mouse.y)) {
e = Qt.TopEdge | Qt.RightEdge; e = Qt.TopEdge | Qt.RightEdge;
window.startSystemResize(e); window.startSystemResize(e);
return; return;
} }
//right if (ptInRect(window.width-border,border,border,window.height-border*2, mouse.x, mouse.y)) {
rc = Qt.rect(window.width-border, border, border, window.height-border*2);
if (ptInRect(rc, mouse.x, mouse.y)) {
e = Qt.RightEdge; e = Qt.RightEdge;
window.startSystemResize(e); window.startSystemResize(e);
return; return;
} }
//bottom-right if (ptInRect(window.width-border,window.height-border,border,border, mouse.x, mouse.y)) {
rc = Qt.rect(window.width-border, window.height-border, border, border);
if (ptInRect(rc, mouse.x, mouse.y)) {
e = Qt.BottomEdge | Qt.RightEdge; e = Qt.BottomEdge | Qt.RightEdge;
window.startSystemResize(e); window.startSystemResize(e);
return; return;
} }
//bottom if (ptInRect(border,window.height-border,window.width-border*2,border, mouse.x, mouse.y)) {
rc = Qt.rect(border, window.height-border, window.width-border*2, border);
if (ptInRect(rc, mouse.x, mouse.y)) {
e = Qt.BottomEdge; e = Qt.BottomEdge;
window.startSystemResize(e); window.startSystemResize(e);
return; return;
} }
//bottom_left if (ptInRect(0,window.height-border,border,border, mouse.x, mouse.y)) {
rc = Qt.rect(0, window.height-border,border, border);
if (ptInRect(rc, mouse.x, mouse.y)) {
e = Qt.BottomEdge | Qt.LeftEdge; e = Qt.BottomEdge | Qt.LeftEdge;
window.startSystemResize(e); window.startSystemResize(e);
return; return;
} }
//left if (ptInRect(0,border,border , window.height-border*2, mouse.x, mouse.y)) {
rc = Qt.rect(0, border,border, window.height-border*2);
if (ptInRect(rc, mouse.x, mouse.y)) {
e = Qt.LeftEdge; e = Qt.LeftEdge;
window.startSystemResize(e); window.startSystemResize(e);
return; return;
@ -105,66 +87,46 @@ MouseArea {
cursorShape = Qt.ArrowCursor; cursorShape = Qt.ArrowCursor;
return; return;
} }
if (ptInRect(0,0,border,border, mouse.x, mouse.y)) {
var rc = Qt.rect(0, 0, 0, 0);
//top-left
rc = Qt.rect(0, 0, border, border);
if (ptInRect(rc, mouse.x, mouse.y)) {
cursorShape = Qt.SizeFDiagCursor; cursorShape = Qt.SizeFDiagCursor;
return; return;
} }
//top if (ptInRect(border,0,window.width-border*2,border, mouse.x, mouse.y)) {
rc = Qt.rect(border, 0, window.width-border*2, border);
if (ptInRect(rc, mouse.x, mouse.y)) {
cursorShape = Qt.SizeVerCursor; cursorShape = Qt.SizeVerCursor;
return; return;
} }
//top-right if (ptInRect(window.width-border,0,border,border, mouse.x, mouse.y)) {
rc = Qt.rect(window.width-border, 0, border, border);
if (ptInRect(rc, mouse.x, mouse.y)) {
cursorShape = Qt.SizeBDiagCursor; cursorShape = Qt.SizeBDiagCursor;
return; return;
} }
//right if (ptInRect(window.width-border,border,border,window.height-border*2, mouse.x, mouse.y)) {
rc = Qt.rect(window.width-border, border, border, window.height-border*2);
if (ptInRect(rc, mouse.x, mouse.y)) {
cursorShape = Qt.SizeHorCursor; cursorShape = Qt.SizeHorCursor;
return; return;
} }
//bottom-right if (ptInRect(window.width-border,window.height-border,border,border, mouse.x, mouse.y)) {
rc = Qt.rect(window.width-border, window.height-border, border, border);
if (ptInRect(rc, mouse.x, mouse.y)) {
cursorShape = Qt.SizeFDiagCursor; cursorShape = Qt.SizeFDiagCursor;
return; return;
} }
//bottom if (ptInRect(border,window.height-border,window.width-border*2,border, mouse.x, mouse.y)) {
rc = Qt.rect(border, window.height-border, window.width-border*2, border);
if (ptInRect(rc, mouse.x, mouse.y)) {
cursorShape = Qt.SizeVerCursor; cursorShape = Qt.SizeVerCursor;
return; return;
} }
//bottom_left if (ptInRect(0,window.height-border,border,border, mouse.x, mouse.y)) {
rc = Qt.rect(0, window.height-border,border, border);
if (ptInRect(rc, mouse.x, mouse.y)) {
cursorShape = Qt.SizeBDiagCursor; cursorShape = Qt.SizeBDiagCursor;
return; return;
} }
//left if (ptInRect(0,border,border, window.height-border*2, mouse.x, mouse.y)) {
rc = Qt.rect(0, border,border, window.height-border*2);
if (ptInRect(rc, mouse.x, mouse.y)) {
cursorShape = Qt.SizeHorCursor; cursorShape = Qt.SizeHorCursor;
return; return;
} }
//default
cursorShape = Qt.ArrowCursor; cursorShape = Qt.ArrowCursor;
} }
@ -172,13 +134,12 @@ MouseArea {
cursorShape = Qt.ArrowCursor; cursorShape = Qt.ArrowCursor;
} }
function ptInRect(rc, x, y) function ptInRect(rcx,rcy,rcwidth,rcheight, x, y)
{ {
if ((rc.x <= x && x <= (rc.x + rc.width)) && if ((rcx <= x && x <= (rcx + rcwidth)) &&
(rc.y <= y && y <= (rc.y + rc.height))) { (rcy <= y && y <= (rcy + rcheight))) {
return true; return true;
} }
return false; return false;
} }

View File

@ -1,14 +1,12 @@
#include "qml_plugin.h" #include "qml_plugin.h"
#include "Fluent.h"
void FluentUIQmlPlugin::registerTypes(const char *uri) void FluentUIQmlPlugin::registerTypes(const char *uri)
{ {
Fluent::getInstance()->registerTypes(uri); FluentUI::registerTypes(uri);
} }
void FluentUIQmlPlugin::initializeEngine(QQmlEngine *engine, const char *uri) void FluentUIQmlPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
{ {
Fluent::getInstance()->initializeEngine(engine,uri); FluentUI::initializeEngine(engine,uri);
} }

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <QQmlExtensionPlugin> #include <QQmlExtensionPlugin>
#include <FluentUI.h>
class FluentUIQmlPlugin : public QQmlExtensionPlugin class FluentUIQmlPlugin : public QQmlExtensionPlugin
{ {

View File

@ -23,7 +23,6 @@
<file>controls/FluIcon.qml</file> <file>controls/FluIcon.qml</file>
<file>controls/FluDivider.qml</file> <file>controls/FluDivider.qml</file>
<file>controls/FluTooltip.qml</file> <file>controls/FluTooltip.qml</file>
<file>controls/FluDropShadow.qml</file>
<file>controls/TFpsMonitor.qml</file> <file>controls/TFpsMonitor.qml</file>
<file>controls/FluTextBoxBackground.qml</file> <file>controls/FluTextBoxBackground.qml</file>
<file>controls/FluMultiLineTextBox.qml</file> <file>controls/FluMultiLineTextBox.qml</file>
@ -31,5 +30,7 @@
<file>controls/FluScrollBar.qml</file> <file>controls/FluScrollBar.qml</file>
<file>controls/FluMenu.qml</file> <file>controls/FluMenu.qml</file>
<file>controls/FluMenuItem.qml</file> <file>controls/FluMenuItem.qml</file>
<file>controls/FluShadow.qml</file>
<file>controls/FluTextButton.qml</file>
</qresource> </qresource>
</RCC> </RCC>