This commit is contained in:
zhuzichu 2023-07-18 18:24:06 +08:00
parent 4b3548563b
commit 98e0aafb44
40 changed files with 269 additions and 568 deletions

View File

@ -9,7 +9,7 @@ Window {
flags: Qt.SplashScreen flags: Qt.SplashScreen
Component.onCompleted: { Component.onCompleted: {
FluApp.init(app) FluApp.init(app)
FluTheme.darkMode = FluDarkMode.System FluTheme.darkMode = FluThemeType.System
FluTheme.enableAnimation = true FluTheme.enableAnimation = true
FluApp.routes = { FluApp.routes = {
"/":"qrc:/example/qml/window/MainWindow.qml", "/":"qrc:/example/qml/window/MainWindow.qml",

View File

@ -5,5 +5,5 @@ import QtQuick.Controls
import FluentUI import FluentUI
QtObject { QtObject {
property int displayMode : FluNavigationView.Auto property int displayMode : FluNavigationViewType.Auto
} }

View File

@ -31,7 +31,7 @@ FluScrollablePage{
title:"友情提示" title:"友情提示"
message:"确定要退出程序么?" message:"确定要退出程序么?"
negativeText:"取消" negativeText:"取消"
buttonFlags: FluContentDialog.NegativeButton | FluContentDialog.PositiveButton buttonFlags: FluContentDialogType.NegativeButton | FluContentDialogType.PositiveButton
onNegativeClicked:{ onNegativeClicked:{
showSuccess("点击取消按钮") showSuccess("点击取消按钮")
} }
@ -47,7 +47,7 @@ FluScrollablePage{
id:double_btn_dialog id:double_btn_dialog
title:"友情提示" title:"友情提示"
message:"确定要退出程序么?" message:"确定要退出程序么?"
buttonFlags: FluContentDialog.NegativeButton | FluContentDialog.PositiveButton buttonFlags: FluContentDialogType.NegativeButton | FluContentDialogType.PositiveButton
negativeText:"取消" negativeText:"取消"
onNegativeClicked:{ onNegativeClicked:{
showSuccess("点击取消按钮") showSuccess("点击取消按钮")
@ -80,7 +80,7 @@ FluScrollablePage{
title:"友情提示" title:"友情提示"
message:"确定要退出程序么?" message:"确定要退出程序么?"
negativeText:"取消" negativeText:"取消"
buttonFlags: FluContentDialog.NeutralButton | FluContentDialog.NegativeButton | FluContentDialog.PositiveButton buttonFlags: FluContentDialogType.NeutralButton | FluContentDialogType.NegativeButton | FluContentDialogType.PositiveButton
negativeText:"取消" negativeText:"取消"
onNegativeClicked:{ onNegativeClicked:{
showSuccess("点击取消按钮") showSuccess("点击取消按钮")
@ -101,7 +101,7 @@ FluScrollablePage{
id:triple_btn_dialog id:triple_btn_dialog
title:"友情提示" title:"友情提示"
message:"确定要退出程序么?" message:"确定要退出程序么?"
buttonFlags: FluContentDialog.NeutralButton | FluContentDialog.NegativeButton | FluContentDialog.PositiveButton buttonFlags: FluContentDialogType.NeutralButton | FluContentDialogType.NegativeButton | FluContentDialogType.PositiveButton
negativeText:"取消" negativeText:"取消"
onNegativeClicked:{ onNegativeClicked:{
showSuccess("点击取消按钮") showSuccess("点击取消按钮")

View File

@ -7,7 +7,7 @@ import FluentUI
FluScrollablePage{ FluScrollablePage{
launchMode: FluPage.SingleTask launchMode: FluPageType.SingleTask
animDisabled: true animDisabled: true
ListModel{ ListModel{

View File

@ -93,9 +93,9 @@ FluScrollablePage{
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: -1 Layout.topMargin: -1
code:'FluWindow{ code:'FluWindow{
//launchMode: FluWindow.Standard //launchMode: FluWindowType.Standard
//launchMode: FluWindow.SingleTask //launchMode: FluWindowType.SingleTask
launchMode: FluWindow.SingleInstance launchMode: FluWindowType.SingleInstance
} }
' '
} }

View File

@ -6,7 +6,7 @@ import FluentUI
import "qrc:///example/qml/component" import "qrc:///example/qml/component"
FluPage{ FluPage{
launchMode: FluPage.SingleTop launchMode: FluPageType.SingleTop
FluRemoteLoader{ FluRemoteLoader{
anchors.fill: parent anchors.fill: parent
source: "https://zhu-zichu.gitee.io/T_RemoteLoader.qml" source: "https://zhu-zichu.gitee.io/T_RemoteLoader.qml"

View File

@ -28,7 +28,7 @@ FluScrollablePage{
Layout.bottomMargin: 4 Layout.bottomMargin: 4
} }
Repeater{ Repeater{
model: [{title:"System",mode:FluDarkMode.System},{title:"Light",mode:FluDarkMode.Light},{title:"Dark",mode:FluDarkMode.Dark}] model: [{title:"System",mode:FluThemeType.System},{title:"Light",mode:FluThemeType.Light},{title:"Dark",mode:FluThemeType.Dark}]
delegate: FluRadioButton{ delegate: FluRadioButton{
checked : FluTheme.darkMode === modelData.mode checked : FluTheme.darkMode === modelData.mode
text:modelData.title text:modelData.title
@ -58,7 +58,7 @@ FluScrollablePage{
Layout.bottomMargin: 4 Layout.bottomMargin: 4
} }
Repeater{ Repeater{
model: [{title:"Open",mode:FluNavigationView.Open},{title:"Compact",mode:FluNavigationView.Compact},{title:"Minimal",mode:FluNavigationView.Minimal},{title:"Auto",mode:FluNavigationView.Auto}] model: [{title:"Open",mode:FluNavigationViewType.Open},{title:"Compact",mode:FluNavigationViewType.Compact},{title:"Minimal",mode:FluNavigationViewType.Minimal},{title:"Auto",mode:FluNavigationViewType.Auto}]
delegate: FluRadioButton{ delegate: FluRadioButton{
checked : MainEvent.displayMode===modelData.mode checked : MainEvent.displayMode===modelData.mode
text:modelData.title text:modelData.title

View File

@ -25,28 +25,28 @@ FluScrollablePage{
text:"Loading" text:"Loading"
onClicked: { onClicked: {
btn_status_mode.text = text btn_status_mode.text = text
status_view.statusMode = FluStatusView.Loading status_view.statusMode = FluStatusViewType.Loading
} }
} }
FluMenuItem{ FluMenuItem{
text:"Empty" text:"Empty"
onClicked: { onClicked: {
btn_status_mode.text = text btn_status_mode.text = text
status_view.statusMode = FluStatusView.Empty status_view.statusMode = FluStatusViewType.Empty
} }
} }
FluMenuItem{ FluMenuItem{
text:"Error" text:"Error"
onClicked: { onClicked: {
btn_status_mode.text = text btn_status_mode.text = text
status_view.statusMode = FluStatusView.Error status_view.statusMode = FluStatusViewType.Error
} }
} }
FluMenuItem{ FluMenuItem{
text:"Success" text:"Success"
onClicked: { onClicked: {
btn_status_mode.text = text btn_status_mode.text = text
status_view.statusMode = FluStatusView.Success status_view.statusMode = FluStatusViewType.Success
} }
} }
} }
@ -75,7 +75,7 @@ FluScrollablePage{
Layout.topMargin: -1 Layout.topMargin: -1
code:'FluStatusView{ code:'FluStatusView{
anchors.fill: parent anchors.fill: parent
statusMode: FluStatusView.Loading statusMode: FluStatusViewType.Loading
Rectangle{ Rectangle{
anchors.fill: parent anchors.fill: parent
color:FluTheme.primaryColor.dark color:FluTheme.primaryColor.dark

View File

@ -44,21 +44,21 @@ FluScrollablePage{
text:"Equal" text:"Equal"
onClicked: { onClicked: {
btn_tab_width_behavior.text = text btn_tab_width_behavior.text = text
tab_view.tabWidthBehavior = FluTabView.Equal tab_view.tabWidthBehavior = FluTabViewType.Equal
} }
} }
FluMenuItem{ FluMenuItem{
text:"SizeToContent" text:"SizeToContent"
onClicked: { onClicked: {
btn_tab_width_behavior.text = text btn_tab_width_behavior.text = text
tab_view.tabWidthBehavior = FluTabView.SizeToContent tab_view.tabWidthBehavior = FluTabViewType.SizeToContent
} }
} }
FluMenuItem{ FluMenuItem{
text:"Compact" text:"Compact"
onClicked: { onClicked: {
btn_tab_width_behavior.text = text btn_tab_width_behavior.text = text
tab_view.tabWidthBehavior = FluTabView.Compact tab_view.tabWidthBehavior = FluTabViewType.Compact
} }
} }
} }
@ -70,21 +70,21 @@ FluScrollablePage{
text:"Nerver" text:"Nerver"
onClicked: { onClicked: {
btn_close_button_visibility.text = text btn_close_button_visibility.text = text
tab_view.closeButtonVisibility = FluTabView.Nerver tab_view.closeButtonVisibility = FluTabViewType.Nerver
} }
} }
FluMenuItem{ FluMenuItem{
text:"Always" text:"Always"
onClicked: { onClicked: {
btn_close_button_visibility.text = text btn_close_button_visibility.text = text
tab_view.closeButtonVisibility = FluTabView.Always tab_view.closeButtonVisibility = FluTabViewType.Always
} }
} }
FluMenuItem{ FluMenuItem{
text:"OnHover" text:"OnHover"
onClicked: { onClicked: {
btn_close_button_visibility.text = text btn_close_button_visibility.text = text
tab_view.closeButtonVisibility = FluTabView.OnHover tab_view.closeButtonVisibility = FluTabViewType.OnHover
} }
} }
} }

View File

@ -7,7 +7,7 @@ import "qrc:///example/qml/component"
FluScrollablePage{ FluScrollablePage{
launchMode: FluPage.SingleInstance launchMode: FluPageType.SingleInstance
title:"TextBox" title:"TextBox"
FluArea{ FluArea{

View File

@ -55,9 +55,9 @@ FluScrollablePage{
checked: FluTheme.dark checked: FluTheme.dark
onClicked: { onClicked: {
if(FluTheme.dark){ if(FluTheme.dark){
FluTheme.darkMode = FluDarkMode.Light FluTheme.darkMode = FluThemeType.Light
}else{ }else{
FluTheme.darkMode = FluDarkMode.Dark FluTheme.darkMode = FluThemeType.Dark
} }
} }
} }

View File

@ -8,7 +8,7 @@ import "qrc:///example/qml/component"
FluScrollablePage{ FluScrollablePage{
title:"TimePicker" title:"TimePicker"
launchMode: FluPage.SingleInstance launchMode: FluPageType.SingleInstance
FluArea{ FluArea{
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 20 Layout.topMargin: 20
@ -23,7 +23,7 @@ FluScrollablePage{
} }
FluText{ FluText{
text:"hourFormat=FluTimePicker.H" text:"hourFormat=FluTimePickerType.H"
} }
FluTimePicker{ FluTimePicker{
@ -56,11 +56,11 @@ FluScrollablePage{
} }
FluText{ FluText{
text:"hourFormat=FluTimePicker.HH" text:"hourFormat=FluTimePickerType.HH"
} }
FluTimePicker{ FluTimePicker{
hourFormat:FluTimePicker.HH hourFormat:FluTimePickerType.HH
onCurrentChanged: { onCurrentChanged: {
showSuccess(current.toLocaleTimeString(Qt.locale("de_DE"))) showSuccess(current.toLocaleTimeString(Qt.locale("de_DE")))
} }
@ -72,7 +72,7 @@ FluScrollablePage{
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: -1 Layout.topMargin: -1
code:'FluTimePicker{ code:'FluTimePicker{
hourFormat:FluTimePicker.HH hourFormat:FluTimePickerType.HH
}' }'
} }

View File

@ -64,38 +64,38 @@ FluScrollablePage {
text:"None" text:"None"
onClicked: { onClicked: {
btn_selection_model.text = text btn_selection_model.text = text
tree_view.selectionMode = FluTabView.Equal tree_view.selectionMode = FluTabViewType.Equal
} }
} }
FluMenuItem{ FluMenuItem{
text:"Single" text:"Single"
onClicked: { onClicked: {
btn_selection_model.text = text btn_selection_model.text = text
tree_view.selectionMode = FluTabView.SizeToContent tree_view.selectionMode = FluTabViewType.SizeToContent
} }
} }
FluMenuItem{ FluMenuItem{
text:"Muiltple" text:"Muiltple"
onClicked: { onClicked: {
btn_selection_model.text = text btn_selection_model.text = text
tree_view.selectionMode = FluTabView.Compact tree_view.selectionMode = FluTabViewType.Compact
} }
} }
} }
FluFilledButton{ FluFilledButton{
text:"获取选中的数据" text:"获取选中的数据"
onClicked: { onClicked: {
if(tree_view.selectionMode === FluTreeView.None){ if(tree_view.selectionMode === FluTreeViewType.None){
showError("当前非选择模式,没有选中的数据") showError("当前非选择模式,没有选中的数据")
} }
if(tree_view.selectionMode === FluTreeView.Single){ if(tree_view.selectionMode === FluTreeViewType.Single){
if(!tree_view.signleData()){ if(!tree_view.signleData()){
showError("没有选中数据") showError("没有选中数据")
return return
} }
showSuccess(tree_view.signleData().text) showSuccess(tree_view.signleData().text)
} }
if(tree_view.selectionMode === FluTreeView.Multiple){ if(tree_view.selectionMode === FluTreeViewType.Multiple){
if(tree_view.multipData().length===0){ if(tree_view.multipData().length===0){
showError("没有选中数据") showError("没有选中数据")
return return

View File

@ -11,7 +11,7 @@ CustomWindow {
width: 600 width: 600
height: 600 height: 600
fixSize: true fixSize: true
launchMode: FluWindow.SingleTask launchMode: FluWindowType.SingleTask
ColumnLayout{ ColumnLayout{
anchors{ anchors{

View File

@ -13,7 +13,7 @@ CustomWindow {
height: 600 height: 600
minimumWidth: 520 minimumWidth: 520
minimumHeight: 200 minimumHeight: 200
launchMode: FluWindow.SingleTask launchMode: FluWindowType.SingleTask
FileWatcher{ FileWatcher{
id:watcher id:watcher
onFileChanged: { onFileChanged: {
@ -25,7 +25,7 @@ CustomWindow {
FluRemoteLoader{ FluRemoteLoader{
id:loader id:loader
anchors.fill: parent anchors.fill: parent
statusMode: FluStatusView.Success statusMode: FluStatusViewType.Success
lazy: true lazy: true
errorItem: Item{ errorItem: Item{
FluText{ FluText{
@ -43,7 +43,7 @@ CustomWindow {
text:"拖入qml文件" text:"拖入qml文件"
font.pixelSize: 26 font.pixelSize: 26
anchors.centerIn: parent anchors.centerIn: parent
visible: !loader.itemLodaer().item && loader.statusMode === FluStatusView.Success visible: !loader.itemLodaer().item && loader.statusMode === FluStatusViewType.Success
} }
Rectangle{ Rectangle{
radius: 4 radius: 4

View File

@ -18,7 +18,7 @@ CustomWindow {
minimumWidth: 520 minimumWidth: 520
minimumHeight: 200 minimumHeight: 200
appBarVisible: false appBarVisible: false
launchMode: FluWindow.SingleTask launchMode: FluWindowType.SingleTask
closeFunc:function(event){ closeFunc:function(event){
dialog_close.open() dialog_close.open()
@ -29,15 +29,6 @@ CustomWindow {
FluTools.setQuitOnLastWindowClosed(false) FluTools.setQuitOnLastWindowClosed(false)
} }
Connections{
target: appInfo
function onActiveWindow(){
window.show()
window.raise()
window.requestActivate()
}
}
SystemTrayIcon { SystemTrayIcon {
id:system_tray id:system_tray
visible: true visible: true
@ -67,7 +58,7 @@ CustomWindow {
title:"退出" title:"退出"
message:"确定要退出程序吗?" message:"确定要退出程序吗?"
negativeText:"最小化" negativeText:"最小化"
buttonFlags: FluContentDialog.NeutralButton | FluContentDialog.NegativeButton | FluContentDialog.PositiveButton buttonFlags: FluContentDialogType.NegativeButton | FluContentDialogType.NeutralButton | FluContentDialogType.PositiveButton
onNegativeClicked:{ onNegativeClicked:{
window.hide() window.hide()
system_tray.showMessage("友情提示","FluentUI已隐藏至托盘,点击托盘可再次激活窗口"); system_tray.showMessage("友情提示","FluentUI已隐藏至托盘,点击托盘可再次激活窗口");
@ -173,9 +164,9 @@ CustomWindow {
height: parent.height height: parent.height
z:999 z:999
//StackpopFluPagelaunchMode //StackpopFluPagelaunchMode
// pageMode: FluNavigationView.Stack // pageMode: FluNavigationViewType.Stack
//NoStack //NoStack
// pageMode: FluNavigationView.NoStack // pageMode: FluNavigationViewType.NoStack
items: ItemsOriginal items: ItemsOriginal
footerItems:ItemsFooter footerItems:ItemsFooter
topPadding:FluTools.isMacos() ? 20 : 5 topPadding:FluTools.isMacos() ? 20 : 5
@ -238,9 +229,9 @@ CustomWindow {
function changeDark(){ function changeDark(){
if(FluTheme.dark){ if(FluTheme.dark){
FluTheme.darkMode = FluDarkMode.Light FluTheme.darkMode = FluThemeType.Light
}else{ }else{
FluTheme.darkMode = FluDarkMode.Dark FluTheme.darkMode = FluThemeType.Dark
} }
} }

View File

@ -11,7 +11,7 @@ CustomWindow {
width: 500 width: 500
height: 600 height: 600
fixSize: true fixSize: true
launchMode: FluWindow.SingleInstance launchMode: FluWindowType.SingleInstance
FluTextBox{ FluTextBox{
anchors{ anchors{

View File

@ -11,7 +11,7 @@ CustomWindow {
width: 500 width: 500
height: 600 height: 600
fixSize: true fixSize: true
launchMode: FluWindow.SingleTask launchMode: FluWindowType.SingleTask
FluText{ FluText{
anchors.centerIn: parent anchors.centerIn: parent

View File

@ -11,7 +11,7 @@ CustomWindow {
width: 500 width: 500
height: 600 height: 600
fixSize: true fixSize: true
launchMode: FluWindow.Standard launchMode: FluWindowType.Standard
FluMenuBar { FluMenuBar {
FluMenu { FluMenu {

View File

@ -39,18 +39,3 @@ void AppInfo::changeLang(const QString& locale){
lang(new En()); lang(new En());
} }
} }
bool AppInfo::isOwnerProcess(IPC *ipc){
QString activeWindowEvent = "activeWindow";
if(!ipc->isCurrentOwner()){
ipc->postEvent(activeWindowEvent,QString().toUtf8(),0);
return false;
}
if(ipc->isAttached()){
ipc->registerEventHandler(activeWindowEvent,[=](const QByteArray&){
Q_EMIT this->activeWindow();
return true;
});
}
return true;
}

View File

@ -3,7 +3,6 @@
#include <QObject> #include <QObject>
#include <QQmlApplicationEngine> #include <QQmlApplicationEngine>
#include "tool/IPC.h"
#include "lang/Lang.h" #include "lang/Lang.h"
#include "stdafx.h" #include "stdafx.h"
@ -15,9 +14,7 @@ class AppInfo : public QObject
public: public:
explicit AppInfo(QObject *parent = nullptr); explicit AppInfo(QObject *parent = nullptr);
void init(QQmlApplicationEngine *engine); void init(QQmlApplicationEngine *engine);
bool isOwnerProcess(IPC *ipc);
Q_INVOKABLE void changeLang(const QString& locale); Q_INVOKABLE void changeLang(const QString& locale);
Q_SIGNAL void activeWindow();
}; };
#endif // APPINFO_H #endif // APPINFO_H

View File

@ -12,7 +12,7 @@
FRAMELESSHELPER_USE_NAMESPACE FRAMELESSHELPER_USE_NAMESPACE
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
//将样式设置为Basic不然会导致组件显示异常 //将样式设置为Basic不然会导致组件显示异常
qputenv("QT_QUICK_CONTROLS_STYLE","Basic"); qputenv("QT_QUICK_CONTROLS_STYLE","Basic");
@ -32,10 +32,6 @@ FRAMELESSHELPER_USE_NAMESPACE
FramelessConfig::instance()->set(Global::Option::ForceNonNativeBackgroundBlur,false); FramelessConfig::instance()->set(Global::Option::ForceNonNativeBackgroundBlur,false);
#endif #endif
AppInfo* appInfo = new AppInfo(); AppInfo* appInfo = new AppInfo();
IPC ipc(0);
if(!appInfo->isOwnerProcess(&ipc)){
return 0;
}
QQmlApplicationEngine engine; QQmlApplicationEngine engine;
FramelessHelper::Quick::registerTypes(&engine); FramelessHelper::Quick::registerTypes(&engine);
#ifdef FLUENTUI_BUILD_STATIC_LIB #ifdef FLUENTUI_BUILD_STATIC_LIB

View File

@ -1,250 +0,0 @@
#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());
}

View File

@ -1,75 +0,0 @@
#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

126
src/Def.h
View File

@ -4,15 +4,127 @@
#include <QObject> #include <QObject>
#include <QtQml/qqml.h> #include <QtQml/qqml.h>
namespace Fluent_DarkMode { namespace FluThemeType {
Q_NAMESPACE Q_NAMESPACE
enum Fluent_DarkModeType { enum DarkMode {
System = 0x0, System = 0x0000,
Light = 0x1, Light = 0x0001,
Dark = 0x2, Dark = 0x0002,
}; };
Q_ENUM_NS(Fluent_DarkModeType) Q_ENUM_NS(DarkMode)
QML_NAMED_ELEMENT(FluDarkMode) QML_NAMED_ELEMENT(FluThemeType)
}
namespace FluPageType {
Q_NAMESPACE
enum LaunchMode {
Standard = 0x0000,
SingleTask = 0x0001,
SingleTop = 0x0002,
SingleInstance = 0x0004
};
Q_ENUM_NS(LaunchMode)
QML_NAMED_ELEMENT(FluPageType)
}
namespace FluWindowType {
Q_NAMESPACE
enum LaunchMode {
Standard = 0x0000,
SingleTask = 0x0001,
SingleInstance = 0x0002
};
Q_ENUM_NS(LaunchMode)
QML_NAMED_ELEMENT(FluWindowType)
}
namespace FluTreeViewType {
Q_NAMESPACE
enum SelectionMode {
None = 0x0000,
Single = 0x0001,
Multiple = 0x0002
};
Q_ENUM_NS(SelectionMode)
QML_NAMED_ELEMENT(FluTreeViewType)
}
namespace FluStatusViewType {
Q_NAMESPACE
enum StatusMode {
Loading = 0x0000,
Empty = 0x0001,
Error = 0x0002,
Success = 0x0004
};
Q_ENUM_NS(StatusMode)
QML_NAMED_ELEMENT(FluStatusViewType)
}
namespace FluContentDialogType {
Q_NAMESPACE
enum ButtonFlag {
NeutralButton = 0x0001,
NegativeButton = 0x0002,
PositiveButton = 0x0004
};
Q_ENUM_NS(ButtonFlag)
QML_NAMED_ELEMENT(FluContentDialogType)
}
namespace FluTimePickerType {
Q_NAMESPACE
enum HourFormat {
H = 0x0000,
HH = 0x0001
};
Q_ENUM_NS(HourFormat)
QML_NAMED_ELEMENT(FluTimePickerType)
}
namespace FluCalendarViewType {
Q_NAMESPACE
enum DisplayMode {
Month = 0x0000,
Year = 0x0001,
Decade = 0x0002
};
Q_ENUM_NS(DisplayMode)
QML_NAMED_ELEMENT(FluCalendarViewType)
}
namespace FluTabViewType {
Q_NAMESPACE
enum TabWidthBehavior {
Equal = 0x0000,
SizeToContent = 0x0001,
Compact = 0x0002
};
Q_ENUM_NS(TabWidthBehavior)
enum CloseButtonVisibility {
Nerver = 0x0000,
Always = 0x0001,
OnHover = 0x0002
};
Q_ENUM_NS(CloseButtonVisibility)
QML_NAMED_ELEMENT(FluTabViewType)
}
namespace FluNavigationViewType {
Q_NAMESPACE
enum DisplayMode {
Open = 0x0000,
Compact = 0x0001,
Minimal = 0x0002,
Auto = 0x0004
};
Q_ENUM_NS(DisplayMode)
enum PageMode {
Stack = 0x0000,
NoStack = 0x0001
};
Q_ENUM_NS(PageMode)
QML_NAMED_ELEMENT(FluNavigationViewType)
} }
namespace Fluent_Awesome { namespace Fluent_Awesome {

View File

@ -30,6 +30,7 @@ FluApp::~FluApp(){
void FluApp::init(QQuickWindow *window){ void FluApp::init(QQuickWindow *window){
this->appWindow = window; this->appWindow = window;
FluContentDialogType::ButtonFlag::NegativeButton;
} }
void FluApp::run(){ void FluApp::run(){

View File

@ -32,7 +32,7 @@ FluTheme::FluTheme(QObject *parent)
primaryColor(FluColors::getInstance()->Blue()); primaryColor(FluColors::getInstance()->Blue());
nativeText(false); nativeText(false);
enableAnimation(false); enableAnimation(false);
darkMode(Fluent_DarkMode::Fluent_DarkModeType::Light); darkMode(FluThemeType::DarkMode::Light);
_systemDark = systemDark(); _systemDark = systemDark();
qApp->installEventFilter(this); qApp->installEventFilter(this);
} }
@ -67,11 +67,11 @@ bool FluTheme::systemDark()
} }
bool FluTheme::dark(){ bool FluTheme::dark(){
if(_darkMode == Fluent_DarkMode::Fluent_DarkModeType::Dark){ if(_darkMode == FluThemeType::DarkMode::Dark){
return true; return true;
}else if(_darkMode == Fluent_DarkMode::Fluent_DarkModeType::Light){ }else if(_darkMode == FluThemeType::DarkMode::Light){
return false; return false;
}else if(_darkMode == Fluent_DarkMode::Fluent_DarkModeType::System){ }else if(_darkMode == FluThemeType::DarkMode::System){
return _systemDark; return _systemDark;
}else{ }else{
return false; return false;

View File

@ -39,9 +39,9 @@ Rectangle{
} }
property var darkClickListener: function(){ property var darkClickListener: function(){
if(FluTheme.dark){ if(FluTheme.dark){
FluTheme.darkMode = FluDarkMode.Light FluTheme.darkMode = FluThemeType.Light
}else{ }else{
FluTheme.darkMode = FluDarkMode.Dark FluTheme.darkMode = FluThemeType.Dark
} }
} }
id:root id:root

View File

@ -3,12 +3,7 @@ import QtQuick.Controls
import FluentUI import FluentUI
Item { Item {
enum DisplayMode { property int displayMode: FluCalendarViewType.Month
Month,
Year,
Decade
}
property int displayMode: FluCalendarView.Month
property var date: new Date() property var date: new Date()
property var currentDate : new Date() property var currentDate : new Date()
property var toDay: new Date() property var toDay: new Date()
@ -39,7 +34,7 @@ Item {
width: 70 width: 70
onClicked:{ onClicked:{
control.date = date control.date = date
displayMode = FluCalendarView.Year displayMode = FluCalendarViewType.Year
updateYear(date) updateYear(date)
} }
background: Item{ background: Item{
@ -98,7 +93,7 @@ Item {
width: 70 width: 70
onClicked:{ onClicked:{
control.date = date control.date = date
displayMode = FluCalendarView.Month displayMode = FluCalendarViewType.Month
updateMouth(date) updateMouth(date)
} }
background: Item{ background: Item{
@ -248,13 +243,13 @@ Item {
left: parent.left left: parent.left
leftMargin: 14 leftMargin: 14
} }
disabled: displayMode === FluCalendarView.Decade disabled: displayMode === FluCalendarViewType.Decade
onClicked:{ onClicked:{
if(displayMode === FluCalendarView.Month){ if(displayMode === FluCalendarViewType.Month){
displayMode = FluCalendarView.Year displayMode = FluCalendarViewType.Year
updateYear(date) updateYear(date)
}else if(displayMode === FluCalendarView.Year){ }else if(displayMode === FluCalendarViewType.Year){
displayMode = FluCalendarView.Decade displayMode = FluCalendarViewType.Decade
updateDecade(date) updateDecade(date)
} }
} }
@ -271,7 +266,7 @@ Item {
onClicked: { onClicked: {
var year = date.getFullYear() var year = date.getFullYear()
var month = date.getMonth() var month = date.getMonth()
if(displayMode === FluCalendarView.Month){ if(displayMode === FluCalendarViewType.Month){
var lastMonthYear = year; var lastMonthYear = year;
var lastMonthMonth = month - 1 var lastMonthMonth = month - 1
if (month === 0) { if (month === 0) {
@ -280,10 +275,10 @@ Item {
} }
date = new Date(lastMonthYear,lastMonthMonth,1) date = new Date(lastMonthYear,lastMonthMonth,1)
updateMouth(date) updateMouth(date)
}else if(displayMode === FluCalendarView.Year){ }else if(displayMode === FluCalendarViewType.Year){
date = new Date(year-1,month,1) date = new Date(year-1,month,1)
updateYear(date) updateYear(date)
}else if(displayMode === FluCalendarView.Decade){ }else if(displayMode === FluCalendarViewType.Decade){
date = new Date(Math.floor(year / 10) * 10-10,month,1) date = new Date(Math.floor(year / 10) * 10-10,month,1)
updateDecade(date) updateDecade(date)
} }
@ -301,7 +296,7 @@ Item {
onClicked: { onClicked: {
var year = date.getFullYear() var year = date.getFullYear()
var month = date.getMonth() var month = date.getMonth()
if(displayMode === FluCalendarView.Month){ if(displayMode === FluCalendarViewType.Month){
var nextMonthYear = year var nextMonthYear = year
var nextMonth = month + 1 var nextMonth = month + 1
if (month === 11) { if (month === 11) {
@ -310,10 +305,10 @@ Item {
} }
date = new Date(nextMonthYear,nextMonth,1) date = new Date(nextMonthYear,nextMonth,1)
updateMouth(date) updateMouth(date)
}else if(displayMode === FluCalendarView.Year){ }else if(displayMode === FluCalendarViewType.Year){
date = new Date(year+1,month,1) date = new Date(year+1,month,1)
updateYear(date) updateYear(date)
}else if(displayMode === FluCalendarView.Decade){ }else if(displayMode === FluCalendarViewType.Decade){
date = new Date(Math.floor(year / 10) * 10+10,month,1) date = new Date(Math.floor(year / 10) * 10+10,month,1)
updateDecade(date) updateDecade(date)
} }
@ -334,8 +329,8 @@ Item {
GridView{ GridView{
model: list_model model: list_model
anchors.fill: parent anchors.fill: parent
cellHeight: displayMode === FluCalendarView.Month ? 40 : 70 cellHeight: displayMode === FluCalendarViewType.Month ? 40 : 70
cellWidth: displayMode === FluCalendarView.Month ? 40 : 70 cellWidth: displayMode === FluCalendarViewType.Month ? 40 : 70
clip: true clip: true
boundsBehavior:Flickable.StopAtBounds boundsBehavior:Flickable.StopAtBounds
delegate: Loader{ delegate: Loader{

View File

@ -15,12 +15,7 @@ FluPopup {
signal neutralClicked signal neutralClicked
signal negativeClicked signal negativeClicked
signal positiveClicked signal positiveClicked
enum ButtonFlag{ property int buttonFlags: FluContentDialogType.NegativeButton | FluContentDialogType.PositiveButton
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
@ -85,11 +80,11 @@ FluPopup {
id:neutral_btn id:neutral_btn
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
visible: popup.buttonFlags&FluContentDialog.NeutralButton visible: popup.buttonFlags&FluContentDialogType.NeutralButton
text: neutralText text: neutralText
onClicked: { onClicked: {
popup.close() popup.close()
timer_delay.targetFlags = FluContentDialog.NeutralButton timer_delay.targetFlags = FluContentDialogType.NeutralButton
timer_delay.restart() timer_delay.restart()
} }
} }
@ -97,11 +92,11 @@ FluPopup {
id:negative_btn id:negative_btn
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
visible: popup.buttonFlags&FluContentDialog.NegativeButton visible: popup.buttonFlags&FluContentDialogType.NegativeButton
text: negativeText text: negativeText
onClicked: { onClicked: {
popup.close() popup.close()
timer_delay.targetFlags = FluContentDialog.NegativeButton timer_delay.targetFlags = FluContentDialogType.NegativeButton
timer_delay.restart() timer_delay.restart()
} }
} }
@ -109,11 +104,11 @@ FluPopup {
id:positive_btn id:positive_btn
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
visible: popup.buttonFlags&FluContentDialog.PositiveButton visible: popup.buttonFlags&FluContentDialogType.PositiveButton
text: positiveText text: positiveText
onClicked: { onClicked: {
popup.close() popup.close()
timer_delay.targetFlags = FluContentDialog.PositiveButton timer_delay.targetFlags = FluContentDialogType.PositiveButton
timer_delay.restart() timer_delay.restart()
} }
} }
@ -125,13 +120,13 @@ FluPopup {
id:timer_delay id:timer_delay
interval: popup.delayTime interval: popup.delayTime
onTriggered: { onTriggered: {
if(targetFlags === FluContentDialog.NegativeButton){ if(targetFlags === FluContentDialogType.NegativeButton){
negativeClicked() negativeClicked()
} }
if(targetFlags === FluContentDialog.NeutralButton){ if(targetFlags === FluContentDialogType.NeutralButton){
neutralClicked() neutralClicked()
} }
if(targetFlags === FluContentDialog.PositiveButton){ if(targetFlags === FluContentDialogType.PositiveButton){
positiveClicked() positiveClicked()
} }
} }

View File

@ -40,7 +40,7 @@ FluPage {
FluStatusView{ FluStatusView{
id:status_view id:status_view
color: "#00000000" color: "#00000000"
statusMode: FluStatusView.Success statusMode: FluStatusViewType.Success
onErrorClicked: control.errorClicked() onErrorClicked: control.errorClicked()
anchors{ anchors{
left: parent.left left: parent.left

View File

@ -6,26 +6,16 @@ import QtQuick.Layouts
import FluentUI import FluentUI
Item { Item {
enum DisplayMode {
Open = 0,
Compact = 1,
Minimal = 2,
Auto = 3
}
enum PageMode {
Stack = 0,
NoStack = 1
}
property url logo property url logo
property string title: "" property string title: ""
property FluObject items property FluObject items
property FluObject footerItems property FluObject footerItems
property int displayMode: FluNavigationView.Auto property int displayMode: FluNavigationViewType.Auto
property Component autoSuggestBox property Component autoSuggestBox
property Component actionItem property Component actionItem
property int topPadding: 0 property int topPadding: 0
property int navWidth: 300 property int navWidth: 300
property int pageMode: FluNavigationView.Stack property int pageMode: FluNavigationViewType.Stack
signal logoClicked signal logoClicked
id:control id:control
QtObject{ QtObject{
@ -34,11 +24,11 @@ Item {
property var stackItems: [] property var stackItems: []
property int displayMode: control.displayMode property int displayMode: control.displayMode
property bool enableNavigationPanel: false property bool enableNavigationPanel: false
property bool isCompact: d.displayMode === FluNavigationView.Compact property bool isCompact: d.displayMode === FluNavigationViewType.Compact
property bool isMinimal: d.displayMode === FluNavigationView.Minimal property bool isMinimal: d.displayMode === FluNavigationViewType.Minimal
property bool isCompactAndPanel: d.displayMode === FluNavigationView.Compact && d.enableNavigationPanel property bool isCompactAndPanel: d.displayMode === FluNavigationViewType.Compact && d.enableNavigationPanel
property bool isCompactAndNotPanel:d.displayMode === FluNavigationView.Compact && !d.enableNavigationPanel property bool isCompactAndNotPanel:d.displayMode === FluNavigationViewType.Compact && !d.enableNavigationPanel
property bool isMinimalAndPanel: d.displayMode === FluNavigationView.Minimal && d.enableNavigationPanel property bool isMinimalAndPanel: d.displayMode === FluNavigationViewType.Minimal && d.enableNavigationPanel
onIsCompactAndNotPanelChanged: { onIsCompactAndNotPanelChanged: {
collapseAll() collapseAll()
} }
@ -79,15 +69,15 @@ Item {
} }
Component.onCompleted: { Component.onCompleted: {
d.displayMode = Qt.binding(function(){ d.displayMode = Qt.binding(function(){
if(control.displayMode !==FluNavigationView.Auto){ if(control.displayMode !==FluNavigationViewType.Auto){
return control.displayMode return control.displayMode
} }
if(control.width<=700){ if(control.width<=700){
return FluNavigationView.Minimal return FluNavigationViewType.Minimal
}else if(control.width<=900){ }else if(control.width<=900){
return FluNavigationView.Compact return FluNavigationViewType.Compact
}else{ }else{
return FluNavigationView.Open return FluNavigationViewType.Open
} }
}) })
timer_anim_delay.restart() timer_anim_delay.restart()
@ -102,10 +92,10 @@ Item {
Connections{ Connections{
target: d target: d
function onDisplayModeChanged(){ function onDisplayModeChanged(){
if(d.displayMode === FluNavigationView.Compact){ if(d.displayMode === FluNavigationViewType.Compact){
collapseAll() collapseAll()
} }
if(d.displayMode === FluNavigationView.Minimal){ if(d.displayMode === FluNavigationViewType.Minimal){
d.enableNavigationPanel = false d.enableNavigationPanel = false
} }
} }
@ -533,11 +523,11 @@ Item {
layout_footer.currentIndex = item._idx-(nav_list.count-layout_footer.count) layout_footer.currentIndex = item._idx-(nav_list.count-layout_footer.count)
} }
nav_list.currentIndex = item._idx nav_list.currentIndex = item._idx
if(pageMode === FluNavigationView.Stack){ if(pageMode === FluNavigationViewType.Stack){
var nav_stack = loader_content.item.navStack() var nav_stack = loader_content.item.navStack()
var nav_stack2 = loader_content.item.navStack2() var nav_stack2 = loader_content.item.navStack2()
nav_stack.pop() nav_stack.pop()
if(nav_stack.currentItem.launchMode === FluPage.SingleInstance){ if(nav_stack.currentItem.launchMode === FluPageType.SingleInstance){
var url = nav_stack.currentItem.url var url = nav_stack.currentItem.url
var pageIndex = -1 var pageIndex = -1
for(var i=0;i<nav_stack2.children.length;i++){ for(var i=0;i<nav_stack2.children.length;i++){
@ -551,7 +541,7 @@ Item {
nav_stack2.currentIndex = pageIndex nav_stack2.currentIndex = pageIndex
} }
} }
}else if(pageMode === FluNavigationView.NoStack){ }else if(pageMode === FluNavigationViewType.NoStack){
loader_content.setSource(item._ext.url,item._ext.argument) loader_content.setSource(item._ext.url,item._ext.argument)
} }
} }
@ -646,7 +636,7 @@ Item {
id:nav_stack2 id:nav_stack2
anchors.fill: nav_stack anchors.fill: nav_stack
clip: true clip: true
visible: nav_stack.currentItem?.launchMode === FluPage.SingleInstance visible: nav_stack.currentItem?.launchMode === FluPageType.SingleInstance
} }
function navStack(){ function navStack(){
return nav_stack return nav_stack
@ -728,7 +718,7 @@ Item {
} }
} }
visible: { visible: {
if(d.displayMode !== FluNavigationView.Minimal) if(d.displayMode !== FluNavigationViewType.Minimal)
return true return true
return d.isMinimalAndPanel ? true : false return d.isMinimalAndPanel ? true : false
} }
@ -1005,7 +995,7 @@ Item {
Component{ Component{
id:com_placeholder id:com_placeholder
Item{ Item{
property int launchMode: FluPage.SingleInstance property int launchMode: FluPageType.SingleInstance
property string url property string url
} }
} }
@ -1031,12 +1021,12 @@ Item {
return nav_list.currentIndex return nav_list.currentIndex
} }
function getCurrentUrl(){ function getCurrentUrl(){
if(pageMode === FluNavigationView.Stack){ if(pageMode === FluNavigationViewType.Stack){
var nav_stack = loader_content.item.navStack() var nav_stack = loader_content.item.navStack()
if(nav_stack.currentItem){ if(nav_stack.currentItem){
return nav_stack.currentItem.url return nav_stack.currentItem.url
} }
}else if(pageMode === FluNavigationView.NoStack){ }else if(pageMode === FluNavigationViewType.NoStack){
return loader_content.source.toString() return loader_content.source.toString()
} }
return undefined return undefined
@ -1051,19 +1041,19 @@ Item {
if(page){ if(page){
switch(page.launchMode) switch(page.launchMode)
{ {
case FluPage.SingleTask: case FluPageType.SingleTask:
while(nav_stack.currentItem !== page) while(nav_stack.currentItem !== page)
{ {
nav_stack.pop() nav_stack.pop()
d.stackItems = d.stackItems.slice(0, -1) d.stackItems = d.stackItems.slice(0, -1)
} }
return return
case FluPage.SingleTop: case FluPageType.SingleTop:
if (nav_stack.currentItem.url === url){ if (nav_stack.currentItem.url === url){
return return
} }
break break
case FluPage.Standard: case FluPageType.Standard:
default: default:
} }
} }
@ -1083,7 +1073,7 @@ Item {
var comp = Qt.createComponent(url) var comp = Qt.createComponent(url)
if (comp.status === Component.Ready) { if (comp.status === Component.Ready) {
var obj = comp.createObject(nav_stack,options) var obj = comp.createObject(nav_stack,options)
if(obj.launchMode === FluPage.SingleInstance){ if(obj.launchMode === FluPageType.SingleInstance){
nav_stack.push(com_placeholder,options) nav_stack.push(com_placeholder,options)
nav_stack2.children.push(obj) nav_stack2.children.push(obj)
nav_stack2.currentIndex = nav_stack2.count - 1 nav_stack2.currentIndex = nav_stack2.count - 1
@ -1105,9 +1095,9 @@ Item {
obj._ext = {url:url,argument:argument} obj._ext = {url:url,argument:argument}
d.stackItems = d.stackItems.concat(obj) d.stackItems = d.stackItems.concat(obj)
} }
if(pageMode === FluNavigationView.Stack){ if(pageMode === FluNavigationViewType.Stack){
stackPush() stackPush()
}else if(pageMode === FluNavigationView.NoStack){ }else if(pageMode === FluNavigationViewType.NoStack){
noStackPush() noStackPush()
} }
} }

View File

@ -5,13 +5,7 @@ import QtQuick.Window
import FluentUI import FluentUI
Item { Item {
enum LaunchMode{ property int launchMode: FluPageType.SingleTop
Standard = 0,
SingleTask = 1,
SingleTop = 2,
SingleInstance = 3
}
property int launchMode: FluPage.SingleTop
property bool animDisabled: false property bool animDisabled: false
property string url : "" property string url : ""
id: control id: control

View File

@ -21,11 +21,11 @@ FluStatusView {
asynchronous: true asynchronous: true
onStatusChanged: { onStatusChanged: {
if(status === Loader.Error){ if(status === Loader.Error){
control.statusMode = FluStatusView.Error control.statusMode = FluStatusViewType.Error
}else if(status === Loader.Loading){ }else if(status === Loader.Loading){
control.statusMode = FluStatusView.Loading control.statusMode = FluStatusViewType.Loading
}else{ }else{
control.statusMode = FluStatusView.Success control.statusMode = FluStatusViewType.Success
} }
} }
} }

View File

@ -41,7 +41,7 @@ FluPage {
FluStatusView{ FluStatusView{
id:status_view id:status_view
color: "#00000000" color: "#00000000"
statusMode: FluStatusView.Success statusMode: FluStatusViewType.Success
onErrorClicked: control.errorClicked() onErrorClicked: control.errorClicked()
anchors{ anchors{
left: parent.left left: parent.left

View File

@ -5,14 +5,8 @@ import FluentUI
Item{ Item{
id:control id:control
enum StatusMode {
Loading,
Empty,
Error,
Success
}
default property alias content: container.data default property alias content: container.data
property int statusMode: FluStatusView.Loading property int statusMode: FluStatusViewType.Loading
property string loadingText:"正在加载..." property string loadingText:"正在加载..."
property string emptyText: "空空如也" property string emptyText: "空空如也"
property string errorText: "页面出错了.." property string errorText: "页面出错了.."
@ -26,20 +20,20 @@ Item{
Item{ Item{
id:container id:container
anchors.fill: parent anchors.fill: parent
visible: statusMode===FluStatusView.Success visible: statusMode===FluStatusViewType.Success
} }
Loader{ Loader{
id:loader id:loader
anchors.fill: parent anchors.fill: parent
visible: statusMode!==FluStatusView.Success visible: statusMode!==FluStatusViewType.Success
sourceComponent: { sourceComponent: {
if(statusMode === FluStatusView.Loading){ if(statusMode === FluStatusViewType.Loading){
return loadingItem return loadingItem
} }
if(statusMode === FluStatusView.Empty){ if(statusMode === FluStatusViewType.Empty){
return emptyItem return emptyItem
} }
if(statusMode === FluStatusView.Error){ if(statusMode === FluStatusViewType.Error){
return errorItem return errorItem
} }
return undefined return undefined
@ -108,15 +102,15 @@ Item{
} }
} }
function showSuccessView(){ function showSuccessView(){
statusMode = FluStatusView.Success statusMode = FluStatusViewType.Success
} }
function showLoadingView(){ function showLoadingView(){
statusMode = FluStatusView.Loading statusMode = FluStatusViewType.Loading
} }
function showEmptyView(){ function showEmptyView(){
statusMode = FluStatusView.Empty statusMode = FluStatusViewType.Empty
} }
function showErrorView(){ function showErrorView(){
statusMode = FluStatusView.Error statusMode = FluStatusViewType.Error
} }
} }

View File

@ -4,18 +4,8 @@ import QtQuick.Layouts
import FluentUI import FluentUI
Item { Item {
enum TabWidthBehavior { property int tabWidthBehavior : FluTabViewType.Equal
Equal, property int closeButtonVisibility : FluTabViewType.Always
SizeToContent,
Compact
}
enum CloseButtonVisibility{
Nerver,
Always,
OnHover
}
property int tabWidthBehavior : FluTabView.Equal
property int closeButtonVisibility : FluTabView.Always
property int itemWidth: 146 property int itemWidth: 146
property bool addButtonVisibility: true property bool addButtonVisibility: true
signal newPressed signal newPressed
@ -91,13 +81,13 @@ Item {
property real timestamp: new Date().getTime() property real timestamp: new Date().getTime()
height: tab_nav.height height: tab_nav.height
width: { width: {
if(tabWidthBehavior === FluTabView.Equal){ if(tabWidthBehavior === FluTabViewType.Equal){
return Math.max(Math.min(d.maxEqualWidth,tab_nav.width/tab_nav.count),41 + item_btn_close.width) return Math.max(Math.min(d.maxEqualWidth,tab_nav.width/tab_nav.count),41 + item_btn_close.width)
} }
if(tabWidthBehavior === FluTabView.SizeToContent){ if(tabWidthBehavior === FluTabViewType.SizeToContent){
return itemWidth return itemWidth
} }
if(tabWidthBehavior === FluTabView.Compact){ if(tabWidthBehavior === FluTabViewType.Compact){
return item_mouse_hove.containsMouse || item_btn_close.hovered || tab_nav.currentIndex === index ? itemWidth : 41 + item_btn_close.width return item_mouse_hove.containsMouse || item_btn_close.hovered || tab_nav.currentIndex === index ? itemWidth : 41 + item_btn_close.width
} }
return Math.max(Math.min(d.maxEqualWidth,tab_nav.width/tab_nav.count),41 + item_btn_close.width) return Math.max(Math.min(d.maxEqualWidth,tab_nav.width/tab_nav.count),41 + item_btn_close.width)
@ -233,13 +223,13 @@ Item {
text: model.text text: model.text
Layout.leftMargin: 10 Layout.leftMargin: 10
visible: { visible: {
if(tabWidthBehavior === FluTabView.Equal){ if(tabWidthBehavior === FluTabViewType.Equal){
return true return true
} }
if(tabWidthBehavior === FluTabView.SizeToContent){ if(tabWidthBehavior === FluTabViewType.SizeToContent){
return true return true
} }
if(tabWidthBehavior === FluTabView.Compact){ if(tabWidthBehavior === FluTabViewType.Compact){
return item_mouse_hove.containsMouse || item_btn_close.hovered || tab_nav.currentIndex === index return item_mouse_hove.containsMouse || item_btn_close.hovered || tab_nav.currentIndex === index
} }
return false return false
@ -256,9 +246,9 @@ Item {
width: visible ? 24 : 0 width: visible ? 24 : 0
height: 24 height: 24
visible: { visible: {
if(closeButtonVisibility === FluTabView.Nerver) if(closeButtonVisibility === FluTabViewType.Nerver)
return false return false
if(closeButtonVisibility === FluTabView.OnHover) if(closeButtonVisibility === FluTabViewType.OnHover)
return item_mouse_hove.containsMouse || item_btn_close.hovered return item_mouse_hove.containsMouse || item_btn_close.hovered
return true return true
} }

View File

@ -5,15 +5,11 @@ import QtQuick.Window
import FluentUI import FluentUI
Rectangle { Rectangle {
enum HourFormat {
H,
HH
}
property color dividerColor: FluTheme.dark ? Qt.rgba(77/255,77/255,77/255,1) : Qt.rgba(239/255,239/255,239/255,1) property color dividerColor: FluTheme.dark ? Qt.rgba(77/255,77/255,77/255,1) : Qt.rgba(239/255,239/255,239/255,1)
property color hoverColor: FluTheme.dark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(251/255,251/255,251/255,1) property color hoverColor: FluTheme.dark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(251/255,251/255,251/255,1)
property color normalColor: FluTheme.dark ? Qt.rgba(61/255,61/255,61/255,1) : Qt.rgba(254/255,254/255,254/255,1) property color normalColor: FluTheme.dark ? Qt.rgba(61/255,61/255,61/255,1) : Qt.rgba(254/255,254/255,254/255,1)
property int hourFormat: FluTimePicker.H property int hourFormat: FluTimePickerType.H
property int isH: hourFormat === FluTimePicker.H property int isH: hourFormat === FluTimePickerType.H
property var current property var current
id:control id:control
color: { color: {
@ -326,7 +322,7 @@ Rectangle {
const period = text_ampm.text const period = text_ampm.text
const date = new Date() const date = new Date()
var hours24 = parseInt(hours); var hours24 = parseInt(hours);
if(control.hourFormat === FluTimePicker.H){ if(control.hourFormat === FluTimePickerType.H){
if (hours === "12") { if (hours === "12") {
hours24 = (period === "上午") ? 0 : 12; hours24 = (period === "上午") ? 0 : 12;
} else { } else {

View File

@ -5,12 +5,7 @@ import QtQuick.Controls
import FluentUI import FluentUI
Item { Item {
enum TreeViewSelectionMode { property int selectionMode: FluTreeViewType.None
None,
Single,
Multiple
}
property int selectionMode: FluTreeView.None
property var currentElement property var currentElement
property var currentParentElement property var currentParentElement
property var rootModel: tree_model.get(0).items property var rootModel: tree_model.get(0).items
@ -83,12 +78,12 @@ Item {
anchors.margins: 2 anchors.margins: 2
color:{ color:{
if(FluTheme.dark){ if(FluTheme.dark){
if(item_layout.singleSelected && selectionMode === FluTreeView.Single){ if(item_layout.singleSelected && selectionMode === FluTreeViewType.Single){
return Qt.rgba(62/255,62/255,62/255,1) return Qt.rgba(62/255,62/255,62/255,1)
} }
return (item_layout_mouse.containsMouse || item_layout_expanded.hovered || item_layout_checkbox.hovered)?Qt.rgba(62/255,62/255,62/255,1):Qt.rgba(0,0,0,0) return (item_layout_mouse.containsMouse || item_layout_expanded.hovered || item_layout_checkbox.hovered)?Qt.rgba(62/255,62/255,62/255,1):Qt.rgba(0,0,0,0)
}else{ }else{
if(item_layout.singleSelected && selectionMode === FluTreeView.Single){ if(item_layout.singleSelected && selectionMode === FluTreeViewType.Single){
return Qt.rgba(0,0,0,0.06) return Qt.rgba(0,0,0,0.06)
} }
return (item_layout_mouse.containsMouse || item_layout_expanded.hovered || item_layout_checkbox.hovered)?Qt.rgba(0,0,0,0.03):Qt.rgba(0,0,0,0) return (item_layout_mouse.containsMouse || item_layout_expanded.hovered || item_layout_checkbox.hovered)?Qt.rgba(0,0,0,0.03):Qt.rgba(0,0,0,0)
@ -97,7 +92,7 @@ Item {
Rectangle{ Rectangle{
width: 3 width: 3
color:FluTheme.primaryColor.dark color:FluTheme.primaryColor.dark
visible: item_layout.singleSelected && (selectionMode === FluTreeView.Single) visible: item_layout.singleSelected && (selectionMode === FluTreeViewType.Single)
radius: 3 radius: 3
height: 20 height: 20
anchors{ anchors{
@ -115,10 +110,10 @@ Item {
} }
} }
function onClickItem(){ function onClickItem(){
if(selectionMode === FluTreeView.None){ if(selectionMode === FluTreeViewType.None){
itemClicked(model) itemClicked(model)
} }
if(selectionMode === FluTreeView.Single){ if(selectionMode === FluTreeViewType.Single){
currentElement = model currentElement = model
if(item_layout.parent.parent.parent.itemModel){ if(item_layout.parent.parent.parent.itemModel){
currentParentElement = item_layout.parent.parent.parent.itemModel currentParentElement = item_layout.parent.parent.parent.itemModel
@ -129,7 +124,7 @@ Item {
} }
itemClicked(model) itemClicked(model)
} }
if(selectionMode === FluTreeView.Multiple){ if(selectionMode === FluTreeViewType.Multiple){
} }
} }
@ -144,7 +139,7 @@ Item {
id:item_layout_checkbox id:item_layout_checkbox
text:"" text:""
checked: itemModel.multipSelected checked: itemModel.multipSelected
visible: selectionMode === FluTreeView.Multiple visible: selectionMode === FluTreeViewType.Multiple
Layout.leftMargin: 5 Layout.leftMargin: 5
function refreshCheckBox(){ function refreshCheckBox(){
const stack = [tree_model.get(0)]; const stack = [tree_model.get(0)];

View File

@ -5,14 +5,9 @@ import QtQuick.Layouts
import FluentUI import FluentUI
Window { Window {
enum LaunchMode {
Standard,
SingleTask,
SingleInstance
}
default property alias content: container.data default property alias content: container.data
property bool closeDestory: true property bool closeDestory: true
property int launchMode: FluWindow.Standard property int launchMode: FluWindowType.Standard
property string route property string route
property var argument:({}) property var argument:({})
property var pageRegister property var pageRegister