diff --git a/example/qml/component/CodeExpander.qml b/example/qml/component/CodeExpander.qml index 95fdda6..50dfaa1 100644 --- a/example/qml/component/CodeExpander.qml +++ b/example/qml/component/CodeExpander.qml @@ -36,7 +36,7 @@ FluExpander{ topMargin: 5 } onClicked:{ - FluApp.clipText(content.text) + FluTools.clipText(content.text) showSuccess("复制成功") } } diff --git a/example/qml/page/T_Awesome.qml b/example/qml/page/T_Awesome.qml index af40f9f..c3b8784 100644 --- a/example/qml/page/T_Awesome.qml +++ b/example/qml/page/T_Awesome.qml @@ -55,7 +55,7 @@ FluContentPage { anchors.horizontalCenter: parent.horizontalCenter onClicked: { var text ="FluentIcons."+modelData.name; - FluApp.clipText(text) + FluTools.clipText(text) showSuccess("您复制了 "+text) } } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9d175e4..4cd0e66 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,6 +7,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) #设置版本号 add_definitions(-DVERSION=1,2,9,0) +#设置插件输出目录 if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/debug) else() @@ -15,29 +16,34 @@ endif() find_package(Qt6 REQUIRED COMPONENTS Core Quick Qml) +#遍历所有Cpp文件 file(GLOB_RECURSE CPP_FILES *.cpp *.h) foreach(filepath ${CPP_FILES}) string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" filename ${filepath}) list(APPEND sources_files ${filename}) endforeach(filepath) +#遍历所有qml文件 file(GLOB_RECURSE QML_PATHS *.qml) foreach(filepath ${QML_PATHS}) string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" filename ${filepath}) list(APPEND qml_files ${filename}) endforeach(filepath) +#遍历所有资源文件 file(GLOB_RECURSE RES_PATHS *.png *.jpg *.svg *.ico *.ttf *.webp) foreach(filepath ${RES_PATHS}) string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" filename ${filepath}) list(APPEND resource_files ${filename}) endforeach(filepath) +#修改资源文件导出路径 foreach(filepath IN LISTS qml_files resource_files) string(REPLACE "imports/FluentUI/" "" filename ${filepath}) set_source_files_properties(${filepath} PROPERTIES QT_RESOURCE_ALIAS ${filename}) endforeach() +#添加qml模块 qt_add_qml_module(fluentui OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/FluentUI VERSION 1.0 @@ -47,17 +53,20 @@ qt_add_qml_module(fluentui RESOURCES ${resource_files} ) +#设置属性 set_target_properties(fluentui PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE ) +#链接库 target_link_libraries(fluentui PUBLIC Qt::Core Qt::Quick Qt::Qml ) +#链接库 win32库 不然mingw会编译错误 if(WIN32) target_link_libraries(fluentui PRIVATE dwmapi user32) endif() diff --git a/src/FluApp.cpp b/src/FluApp.cpp index 334c835..3556873 100644 --- a/src/FluApp.cpp +++ b/src/FluApp.cpp @@ -8,9 +8,7 @@ #include #include #include -#include "FluTheme.h" #include "Def.h" - #ifdef Q_OS_WIN #pragma comment(lib, "Dwmapi.lib") #pragma comment(lib, "User32.lib") @@ -26,18 +24,12 @@ static bool isCompositionEnabled() #endif FluApp* FluApp::fluApp = nullptr; -FluTheme* FluApp::fluTheme = nullptr; -FluColors* FluApp::flutColors = nullptr; -void FluApp::setFluApp(FluApp* val){ - FluApp::fluApp = val; -} -void FluApp::setFluTheme(FluTheme* val){ - FluApp::fluTheme = val; -} -void FluApp::setFluColors(FluColors* val){ - FluApp::flutColors = val; -} +FluTheme* FluApp::fluTheme = nullptr; + +FluColors* FluApp::fluColors = nullptr; + +FluTools* FluApp::fluTools = nullptr; FluApp::FluApp(QObject *parent) : QObject{parent} @@ -45,6 +37,29 @@ FluApp::FluApp(QObject *parent) QFontDatabase::addApplicationFont(":/FluentUI/Font/Segoe_Fluent_Icons.ttf"); } +FluApp::~FluApp(){ + if (nativeEvent != Q_NULLPTR) { + delete nativeEvent; + nativeEvent = Q_NULLPTR; + } +} + +void FluApp::setFluApp(FluApp* val){ + FluApp::fluApp = val; +} + +void FluApp::setFluTheme(FluTheme* val){ + FluApp::fluTheme = val; +} + +void FluApp::setFluColors(FluColors* val){ + FluApp::fluColors = val; +} + +void FluApp::setFluTools(FluTools* val){ + FluApp::fluTools = val; +} + void FluApp::init(QQuickWindow *window){ this->appWindow = window; QQmlEngine *engine = qmlEngine(appWindow); @@ -133,14 +148,6 @@ QJsonArray FluApp::awesomelist(const QString& keyword) return arr; } -void FluApp::clipText(const QString& text){ - QGuiApplication::clipboard()->setText(text); -} - -QString FluApp::uuid(){ - return QUuid::createUuid().toString(); -} - void FluApp::closeApp(){ qApp->exit(0); } diff --git a/src/FluApp.h b/src/FluApp.h index 5b173d6..289cae0 100644 --- a/src/FluApp.h +++ b/src/FluApp.h @@ -9,44 +9,125 @@ #include #include #include "FluTheme.h" +#include "FluTools.h" #include "FluColors.h" #include "NativeEventFilter.h" #include "FluRegister.h" #include "stdafx.h" +/** + * @brief The FluApp class + */ class FluApp : public QObject { Q_OBJECT + /** + * @brief initialRoute 初始路由 + */ Q_PROPERTY_AUTO(QString,initialRoute); + + /** + * @brief routes 路由表 + */ Q_PROPERTY_AUTO(QJsonObject,routes); + QML_NAMED_ELEMENT(FluApp) QML_SINGLETON + public: - static FluApp *getInstance(); explicit FluApp(QObject *parent = nullptr); - ~FluApp(){ - if (nativeEvent != Q_NULLPTR) { - delete nativeEvent; - nativeEvent = Q_NULLPTR; - } - } + ~FluApp(); + + /** + * @brief run + */ Q_INVOKABLE void run(); + + /** + * @brief navigate + * @param route + * @param argument + * @param fluRegister + */ Q_INVOKABLE void navigate(const QString& route,const QJsonObject& argument = {},FluRegister* fluRegister = nullptr); + + /** + * @brief init + * @param window + */ Q_INVOKABLE void init(QQuickWindow *window); + + /** + * @brief awesomelist + * @param keyword + * @return + */ Q_INVOKABLE QJsonArray awesomelist(const QString& keyword = ""); - Q_INVOKABLE void clipText(const QString& text); - Q_INVOKABLE QString uuid(); + + /** + * @brief closeApp + */ Q_INVOKABLE void closeApp(); + + /** + * @brief setFluApp 在FluSingleton.qml调用,拿到QML中FluApp的单例 + * @param val + */ Q_INVOKABLE void setFluApp(FluApp* val); + + /** + * @brief setFluTheme 在FluSingleton.qml调用,拿到QML中FluTheme的单例 + * @param val + */ Q_INVOKABLE void setFluTheme(FluTheme* val); + + /** + * @brief setFluColors 在FluSingleton.qml调用,拿到QML中FluColors的单例 + * @param val + */ Q_INVOKABLE void setFluColors(FluColors* val); + + /** + * @brief setFluColors 在FluSingleton.qml调用,拿到QML中FluTools的单例 + * @param val + */ + Q_INVOKABLE void setFluTools(FluTools* val); + public: + /** + * @brief wnds + */ QMap wnds; + + /** + * @brief fluApp + */ static FluApp* fluApp; + + /** + * @brief fluTheme + */ static FluTheme* fluTheme; - static FluColors* flutColors; + + /** + * @brief fluColors + */ + static FluColors* fluColors; + + /** + * @brief fluTools + */ + static FluTools* fluTools; + private: + /** + * @brief nativeEvent + */ NativeEventFilter *nativeEvent = Q_NULLPTR; + + /** + * @brief appWindow + */ QWindow *appWindow; }; diff --git a/src/FluColorSet.h b/src/FluColorSet.h index 2b2c764..bb1edbc 100644 --- a/src/FluColorSet.h +++ b/src/FluColorSet.h @@ -4,9 +4,11 @@ #include #include "stdafx.h" +/** + * @brief The FluColorSet class + */ class FluColorSet : public QObject { - Q_OBJECT Q_PROPERTY_AUTO(QString,darkest) Q_PROPERTY_AUTO(QString,darker) diff --git a/src/FluColors.h b/src/FluColors.h index 0186b36..34b6e56 100644 --- a/src/FluColors.h +++ b/src/FluColors.h @@ -6,6 +6,9 @@ #include "FluColorSet.h" #include "stdafx.h" +/** + * @brief The FluColors class + */ class FluColors : public QObject { Q_OBJECT @@ -33,7 +36,6 @@ class FluColors : public QObject Q_PROPERTY_AUTO(QString,Grey200); Q_PROPERTY_AUTO(QString,Grey210); Q_PROPERTY_AUTO(QString,Grey220); - Q_PROPERTY_AUTO(FluColorSet*,Yellow); Q_PROPERTY_AUTO(FluColorSet*,Orange); Q_PROPERTY_AUTO(FluColorSet*,Red); diff --git a/src/FluRegister.h b/src/FluRegister.h index 19abbd0..7bf6852 100644 --- a/src/FluRegister.h +++ b/src/FluRegister.h @@ -6,6 +6,9 @@ #include #include "stdafx.h" +/** + * @brief The FluRegister class + */ class FluRegister : public QObject { Q_OBJECT @@ -15,8 +18,22 @@ class FluRegister : public QObject public: explicit FluRegister(QObject *parent = nullptr); + /** + * @brief launch 窗口跳转 + * @param argument 跳转携带参数 + */ Q_INVOKABLE void launch(const QJsonObject& argument = {}); + + /** + * @brief onResult 将结果数据回传到上一个窗口 + * @param data 结果数据 + */ Q_INVOKABLE void onResult(const QJsonObject& data = {}); + + /** + * @brief result 收到结果数据的信号 + * @param data 结果数据 + */ Q_SIGNAL void result(const QJsonObject& data); }; diff --git a/src/FluTheme.cpp b/src/FluTheme.cpp index fdd1ca1..13497b8 100644 --- a/src/FluTheme.cpp +++ b/src/FluTheme.cpp @@ -11,7 +11,7 @@ FluTheme::FluTheme(QObject *parent) connect(this,&FluTheme::darkModeChanged,this,[=]{ Q_EMIT darkChanged(); }); - primaryColor(FluApp::flutColors->Blue()); + primaryColor(FluApp::fluColors->Blue()); textSize(13); nativeText(false); frameless(true); diff --git a/src/FluTheme.h b/src/FluTheme.h index d4efa36..78e03fe 100644 --- a/src/FluTheme.h +++ b/src/FluTheme.h @@ -6,15 +6,42 @@ #include "FluColorSet.h" #include "stdafx.h" +/** + * @brief The FluTheme class + */ class FluTheme : public QObject { Q_OBJECT + /** + * @brief dark 改变窗口夜间样式,只读属性,可以通过darkMode切换 + */ Q_PROPERTY(bool dark READ dark NOTIFY darkChanged) + + /** + * @brief primaryColor 主题颜色 + */ Q_PROPERTY_AUTO(FluColorSet*,primaryColor) + + /** + * @brief frameless 是否是无边框窗口,只支持windows部分电脑 + */ Q_PROPERTY_AUTO(bool,frameless); + + /** + * @brief darkMode 夜间模式,支持System=0、Light=1、Dark=2 + */ Q_PROPERTY_AUTO(int,darkMode); + + /** + * @brief nativeText 本地渲染文本 + */ Q_PROPERTY_AUTO(bool,nativeText); + + /** + * @brief textSize 文字大小 + */ Q_PROPERTY_AUTO(int,textSize); + QML_NAMED_ELEMENT(FluTheme) QML_SINGLETON public: diff --git a/src/FluTools.cpp b/src/FluTools.cpp new file mode 100644 index 0000000..16b24df --- /dev/null +++ b/src/FluTools.cpp @@ -0,0 +1,18 @@ +#include "FluTools.h" +#include +#include +#include + +FluTools::FluTools(QObject *parent) + : QObject{parent} +{ + +} + +void FluTools::clipText(const QString& text){ + QGuiApplication::clipboard()->setText(text); +} + +QString FluTools::uuid(){ + return QUuid::createUuid().toString(); +} diff --git a/src/FluTools.h b/src/FluTools.h new file mode 100644 index 0000000..01a634f --- /dev/null +++ b/src/FluTools.h @@ -0,0 +1,34 @@ +#ifndef FLUTOOLS_H +#define FLUTOOLS_H + +#include +#include + +/** + * @brief The FluTools class + */ +class FluTools : public QObject +{ + Q_OBJECT + + QML_NAMED_ELEMENT(FluTools) + QML_SINGLETON + +public: + explicit FluTools(QObject *parent = nullptr); + + /** + * @brief clipText 将字符串添加到剪切板 + * @param text + */ + Q_INVOKABLE void clipText(const QString& text); + + /** + * @brief uuid 获取uuid + * @return + */ + Q_INVOKABLE QString uuid(); + +}; + +#endif // FLUTOOLS_H diff --git a/src/NativeEventFilter.h b/src/NativeEventFilter.h index c767796..3b60455 100644 --- a/src/NativeEventFilter.h +++ b/src/NativeEventFilter.h @@ -4,6 +4,9 @@ #include #include +/** + * @brief The NativeEventFilter class + */ class NativeEventFilter : public QAbstractNativeEventFilter { diff --git a/src/WindowHelper.cpp b/src/WindowHelper.cpp index 1fd1b64..e72cf59 100644 --- a/src/WindowHelper.cpp +++ b/src/WindowHelper.cpp @@ -28,21 +28,17 @@ void WindowHelper::initWindow(QQuickWindow* window){ } void WindowHelper::firstUpdate(){ - if(isFisrt){ #ifdef Q_OS_WIN - if(FluApp::fluTheme->frameless()){ - HWND wnd = (HWND)window->winId(); - SetWindowLongPtr(wnd, GWL_STYLE, static_cast(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; + if(FluApp::fluTheme->frameless()){ + HWND wnd = (HWND)window->winId(); + SetWindowLongPtr(wnd, GWL_STYLE, static_cast(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 } QVariant WindowHelper::createRegister(QQuickWindow* window,const QString& path){ diff --git a/src/WindowHelper.h b/src/WindowHelper.h index 0b2a3f1..0e60c51 100644 --- a/src/WindowHelper.h +++ b/src/WindowHelper.h @@ -8,6 +8,9 @@ #include #include +/** + * @brief The WindowHelper class + */ class WindowHelper : public QObject { Q_OBJECT @@ -15,14 +18,32 @@ class WindowHelper : public QObject public: explicit WindowHelper(QObject *parent = nullptr); + /** + * @brief initWindow FluWindow中初始化调用 + * @param window + */ Q_INVOKABLE void initWindow(QQuickWindow* window); + + /** + * @brief destoryWindow 销毁窗口,释放资源,QML中的Window close并不会销毁窗口,只是把窗口隐藏了 + */ Q_INVOKABLE void destoryWindow(); + + /** + * @brief createRegister 创建一个FluRegsiter对象,在FluWindow中registerForWindowResult方法调用 + * @param window + * @param path + * @return + */ Q_INVOKABLE QVariant createRegister(QQuickWindow* window,const QString& path); + + /** + * @brief firstUpdate 窗口创建成功后调用,只调用一次 + */ Q_INVOKABLE void firstUpdate(); private: QQuickWindow* window; - bool isFisrt=true; }; #endif // WINDOWHELPER_H diff --git a/src/imports/FluentUI/Controls/FluPaneItem.qml b/src/imports/FluentUI/Controls/FluPaneItem.qml index d932ae6..3eb3555 100644 --- a/src/imports/FluentUI/Controls/FluPaneItem.qml +++ b/src/imports/FluentUI/Controls/FluPaneItem.qml @@ -3,7 +3,7 @@ import QtQuick.Controls import FluentUI QtObject { - readonly property string key : FluApp.uuid() + readonly property string key : FluTools.uuid() readonly property int flag : 0 property string title property int order : 0 diff --git a/src/imports/FluentUI/Controls/FluPaneItemEmpty.qml b/src/imports/FluentUI/Controls/FluPaneItemEmpty.qml index c0a4b8c..7fa9a09 100644 --- a/src/imports/FluentUI/Controls/FluPaneItemEmpty.qml +++ b/src/imports/FluentUI/Controls/FluPaneItemEmpty.qml @@ -3,7 +3,7 @@ import QtQuick.Controls import FluentUI QtObject { - readonly property string key : FluApp.uuid() + readonly property string key : FluTools.uuid() property var parent property int idx } diff --git a/src/imports/FluentUI/Controls/FluPaneItemExpander.qml b/src/imports/FluentUI/Controls/FluPaneItemExpander.qml index d354d0b..1d616cd 100644 --- a/src/imports/FluentUI/Controls/FluPaneItemExpander.qml +++ b/src/imports/FluentUI/Controls/FluPaneItemExpander.qml @@ -3,7 +3,7 @@ import QtQuick.Controls import FluentUI FluObject { - readonly property string key : FluApp.uuid() + readonly property string key : FluTools.uuid() property string title property var icon property Component cusIcon diff --git a/src/imports/FluentUI/Controls/FluPaneItemHeader.qml b/src/imports/FluentUI/Controls/FluPaneItemHeader.qml index c00d6e7..aa7aec6 100644 --- a/src/imports/FluentUI/Controls/FluPaneItemHeader.qml +++ b/src/imports/FluentUI/Controls/FluPaneItemHeader.qml @@ -3,7 +3,7 @@ import QtQuick.Controls import FluentUI QtObject { - readonly property string key : FluApp.uuid() + readonly property string key : FluTools.uuid() property string title property var parent property int idx diff --git a/src/imports/FluentUI/Controls/FluPaneItemSeparator.qml b/src/imports/FluentUI/Controls/FluPaneItemSeparator.qml index c0a4b8c..7fa9a09 100644 --- a/src/imports/FluentUI/Controls/FluPaneItemSeparator.qml +++ b/src/imports/FluentUI/Controls/FluPaneItemSeparator.qml @@ -3,7 +3,7 @@ import QtQuick.Controls import FluentUI QtObject { - readonly property string key : FluApp.uuid() + readonly property string key : FluTools.uuid() property var parent property int idx } diff --git a/src/imports/FluentUI/Controls/FluSingleton.qml b/src/imports/FluentUI/Controls/FluSingleton.qml index 28e0b8a..bee9dd9 100644 --- a/src/imports/FluentUI/Controls/FluSingleton.qml +++ b/src/imports/FluentUI/Controls/FluSingleton.qml @@ -10,6 +10,7 @@ QtObject { FluApp.setFluApp(FluApp) FluApp.setFluColors(FluColors) FluApp.setFluTheme(FluTheme) + FluApp.setFluTools(FluTools) } } diff --git a/src/imports/FluentUI/Controls/FluWindow.qml b/src/imports/FluentUI/Controls/FluWindow.qml index b649949..ce7f0e1 100644 --- a/src/imports/FluentUI/Controls/FluWindow.qml +++ b/src/imports/FluentUI/Controls/FluWindow.qml @@ -28,6 +28,11 @@ ApplicationWindow { } signal initArgument(var argument) + QtObject{ + id:d + property bool firstFlag: true + } + id:window background: Rectangle{ color: { @@ -51,8 +56,9 @@ ApplicationWindow { } onActiveChanged: { - if(active){ + if(d.firstFlag){ helper.firstUpdate() + d.firstFlag = false } }