mirror of
https://github.com/zhuzichu520/FluentUI.git
synced 2024-11-30 07:03:46 +08:00
update
This commit is contained in:
parent
4b3548563b
commit
98e0aafb44
@ -9,7 +9,7 @@ Window {
|
||||
flags: Qt.SplashScreen
|
||||
Component.onCompleted: {
|
||||
FluApp.init(app)
|
||||
FluTheme.darkMode = FluDarkMode.System
|
||||
FluTheme.darkMode = FluThemeType.System
|
||||
FluTheme.enableAnimation = true
|
||||
FluApp.routes = {
|
||||
"/":"qrc:/example/qml/window/MainWindow.qml",
|
||||
|
@ -5,5 +5,5 @@ import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
QtObject {
|
||||
property int displayMode : FluNavigationView.Auto
|
||||
property int displayMode : FluNavigationViewType.Auto
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ FluScrollablePage{
|
||||
title:"友情提示"
|
||||
message:"确定要退出程序么?"
|
||||
negativeText:"取消"
|
||||
buttonFlags: FluContentDialog.NegativeButton | FluContentDialog.PositiveButton
|
||||
buttonFlags: FluContentDialogType.NegativeButton | FluContentDialogType.PositiveButton
|
||||
onNegativeClicked:{
|
||||
showSuccess("点击取消按钮")
|
||||
}
|
||||
@ -47,7 +47,7 @@ FluScrollablePage{
|
||||
id:double_btn_dialog
|
||||
title:"友情提示"
|
||||
message:"确定要退出程序么?"
|
||||
buttonFlags: FluContentDialog.NegativeButton | FluContentDialog.PositiveButton
|
||||
buttonFlags: FluContentDialogType.NegativeButton | FluContentDialogType.PositiveButton
|
||||
negativeText:"取消"
|
||||
onNegativeClicked:{
|
||||
showSuccess("点击取消按钮")
|
||||
@ -80,7 +80,7 @@ FluScrollablePage{
|
||||
title:"友情提示"
|
||||
message:"确定要退出程序么?"
|
||||
negativeText:"取消"
|
||||
buttonFlags: FluContentDialog.NeutralButton | FluContentDialog.NegativeButton | FluContentDialog.PositiveButton
|
||||
buttonFlags: FluContentDialogType.NeutralButton | FluContentDialogType.NegativeButton | FluContentDialogType.PositiveButton
|
||||
negativeText:"取消"
|
||||
onNegativeClicked:{
|
||||
showSuccess("点击取消按钮")
|
||||
@ -101,7 +101,7 @@ FluScrollablePage{
|
||||
id:triple_btn_dialog
|
||||
title:"友情提示"
|
||||
message:"确定要退出程序么?"
|
||||
buttonFlags: FluContentDialog.NeutralButton | FluContentDialog.NegativeButton | FluContentDialog.PositiveButton
|
||||
buttonFlags: FluContentDialogType.NeutralButton | FluContentDialogType.NegativeButton | FluContentDialogType.PositiveButton
|
||||
negativeText:"取消"
|
||||
onNegativeClicked:{
|
||||
showSuccess("点击取消按钮")
|
||||
|
@ -7,7 +7,7 @@ import FluentUI
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
launchMode: FluPage.SingleTask
|
||||
launchMode: FluPageType.SingleTask
|
||||
animDisabled: true
|
||||
|
||||
ListModel{
|
||||
|
@ -93,9 +93,9 @@ FluScrollablePage{
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: -1
|
||||
code:'FluWindow{
|
||||
//launchMode: FluWindow.Standard
|
||||
//launchMode: FluWindow.SingleTask
|
||||
launchMode: FluWindow.SingleInstance
|
||||
//launchMode: FluWindowType.Standard
|
||||
//launchMode: FluWindowType.SingleTask
|
||||
launchMode: FluWindowType.SingleInstance
|
||||
}
|
||||
'
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import FluentUI
|
||||
import "qrc:///example/qml/component"
|
||||
|
||||
FluPage{
|
||||
launchMode: FluPage.SingleTop
|
||||
launchMode: FluPageType.SingleTop
|
||||
FluRemoteLoader{
|
||||
anchors.fill: parent
|
||||
source: "https://zhu-zichu.gitee.io/T_RemoteLoader.qml"
|
||||
|
@ -28,7 +28,7 @@ FluScrollablePage{
|
||||
Layout.bottomMargin: 4
|
||||
}
|
||||
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{
|
||||
checked : FluTheme.darkMode === modelData.mode
|
||||
text:modelData.title
|
||||
@ -58,7 +58,7 @@ FluScrollablePage{
|
||||
Layout.bottomMargin: 4
|
||||
}
|
||||
Repeater{
|
||||
model: [{title:"Open",mode:FluNavigationView.Open},{title:"Compact",mode:FluNavigationView.Compact},{title:"Minimal",mode:FluNavigationView.Minimal},{title:"Auto",mode:FluNavigationView.Auto}]
|
||||
model: [{title:"Open",mode:FluNavigationViewType.Open},{title:"Compact",mode:FluNavigationViewType.Compact},{title:"Minimal",mode:FluNavigationViewType.Minimal},{title:"Auto",mode:FluNavigationViewType.Auto}]
|
||||
delegate: FluRadioButton{
|
||||
checked : MainEvent.displayMode===modelData.mode
|
||||
text:modelData.title
|
||||
|
@ -25,28 +25,28 @@ FluScrollablePage{
|
||||
text:"Loading"
|
||||
onClicked: {
|
||||
btn_status_mode.text = text
|
||||
status_view.statusMode = FluStatusView.Loading
|
||||
status_view.statusMode = FluStatusViewType.Loading
|
||||
}
|
||||
}
|
||||
FluMenuItem{
|
||||
text:"Empty"
|
||||
onClicked: {
|
||||
btn_status_mode.text = text
|
||||
status_view.statusMode = FluStatusView.Empty
|
||||
status_view.statusMode = FluStatusViewType.Empty
|
||||
}
|
||||
}
|
||||
FluMenuItem{
|
||||
text:"Error"
|
||||
onClicked: {
|
||||
btn_status_mode.text = text
|
||||
status_view.statusMode = FluStatusView.Error
|
||||
status_view.statusMode = FluStatusViewType.Error
|
||||
}
|
||||
}
|
||||
FluMenuItem{
|
||||
text:"Success"
|
||||
onClicked: {
|
||||
btn_status_mode.text = text
|
||||
status_view.statusMode = FluStatusView.Success
|
||||
status_view.statusMode = FluStatusViewType.Success
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -75,7 +75,7 @@ FluScrollablePage{
|
||||
Layout.topMargin: -1
|
||||
code:'FluStatusView{
|
||||
anchors.fill: parent
|
||||
statusMode: FluStatusView.Loading
|
||||
statusMode: FluStatusViewType.Loading
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
color:FluTheme.primaryColor.dark
|
||||
|
@ -44,21 +44,21 @@ FluScrollablePage{
|
||||
text:"Equal"
|
||||
onClicked: {
|
||||
btn_tab_width_behavior.text = text
|
||||
tab_view.tabWidthBehavior = FluTabView.Equal
|
||||
tab_view.tabWidthBehavior = FluTabViewType.Equal
|
||||
}
|
||||
}
|
||||
FluMenuItem{
|
||||
text:"SizeToContent"
|
||||
onClicked: {
|
||||
btn_tab_width_behavior.text = text
|
||||
tab_view.tabWidthBehavior = FluTabView.SizeToContent
|
||||
tab_view.tabWidthBehavior = FluTabViewType.SizeToContent
|
||||
}
|
||||
}
|
||||
FluMenuItem{
|
||||
text:"Compact"
|
||||
onClicked: {
|
||||
btn_tab_width_behavior.text = text
|
||||
tab_view.tabWidthBehavior = FluTabView.Compact
|
||||
tab_view.tabWidthBehavior = FluTabViewType.Compact
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -70,21 +70,21 @@ FluScrollablePage{
|
||||
text:"Nerver"
|
||||
onClicked: {
|
||||
btn_close_button_visibility.text = text
|
||||
tab_view.closeButtonVisibility = FluTabView.Nerver
|
||||
tab_view.closeButtonVisibility = FluTabViewType.Nerver
|
||||
}
|
||||
}
|
||||
FluMenuItem{
|
||||
text:"Always"
|
||||
onClicked: {
|
||||
btn_close_button_visibility.text = text
|
||||
tab_view.closeButtonVisibility = FluTabView.Always
|
||||
tab_view.closeButtonVisibility = FluTabViewType.Always
|
||||
}
|
||||
}
|
||||
FluMenuItem{
|
||||
text:"OnHover"
|
||||
onClicked: {
|
||||
btn_close_button_visibility.text = text
|
||||
tab_view.closeButtonVisibility = FluTabView.OnHover
|
||||
tab_view.closeButtonVisibility = FluTabViewType.OnHover
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import "qrc:///example/qml/component"
|
||||
|
||||
FluScrollablePage{
|
||||
|
||||
launchMode: FluPage.SingleInstance
|
||||
launchMode: FluPageType.SingleInstance
|
||||
|
||||
title:"TextBox"
|
||||
FluArea{
|
||||
|
@ -55,9 +55,9 @@ FluScrollablePage{
|
||||
checked: FluTheme.dark
|
||||
onClicked: {
|
||||
if(FluTheme.dark){
|
||||
FluTheme.darkMode = FluDarkMode.Light
|
||||
FluTheme.darkMode = FluThemeType.Light
|
||||
}else{
|
||||
FluTheme.darkMode = FluDarkMode.Dark
|
||||
FluTheme.darkMode = FluThemeType.Dark
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import "qrc:///example/qml/component"
|
||||
FluScrollablePage{
|
||||
|
||||
title:"TimePicker"
|
||||
launchMode: FluPage.SingleInstance
|
||||
launchMode: FluPageType.SingleInstance
|
||||
FluArea{
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
@ -23,7 +23,7 @@ FluScrollablePage{
|
||||
}
|
||||
|
||||
FluText{
|
||||
text:"hourFormat=FluTimePicker.H"
|
||||
text:"hourFormat=FluTimePickerType.H"
|
||||
}
|
||||
|
||||
FluTimePicker{
|
||||
@ -56,11 +56,11 @@ FluScrollablePage{
|
||||
}
|
||||
|
||||
FluText{
|
||||
text:"hourFormat=FluTimePicker.HH"
|
||||
text:"hourFormat=FluTimePickerType.HH"
|
||||
}
|
||||
|
||||
FluTimePicker{
|
||||
hourFormat:FluTimePicker.HH
|
||||
hourFormat:FluTimePickerType.HH
|
||||
onCurrentChanged: {
|
||||
showSuccess(current.toLocaleTimeString(Qt.locale("de_DE")))
|
||||
}
|
||||
@ -72,7 +72,7 @@ FluScrollablePage{
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: -1
|
||||
code:'FluTimePicker{
|
||||
hourFormat:FluTimePicker.HH
|
||||
hourFormat:FluTimePickerType.HH
|
||||
}'
|
||||
}
|
||||
|
||||
|
@ -64,38 +64,38 @@ FluScrollablePage {
|
||||
text:"None"
|
||||
onClicked: {
|
||||
btn_selection_model.text = text
|
||||
tree_view.selectionMode = FluTabView.Equal
|
||||
tree_view.selectionMode = FluTabViewType.Equal
|
||||
}
|
||||
}
|
||||
FluMenuItem{
|
||||
text:"Single"
|
||||
onClicked: {
|
||||
btn_selection_model.text = text
|
||||
tree_view.selectionMode = FluTabView.SizeToContent
|
||||
tree_view.selectionMode = FluTabViewType.SizeToContent
|
||||
}
|
||||
}
|
||||
FluMenuItem{
|
||||
text:"Muiltple"
|
||||
onClicked: {
|
||||
btn_selection_model.text = text
|
||||
tree_view.selectionMode = FluTabView.Compact
|
||||
tree_view.selectionMode = FluTabViewType.Compact
|
||||
}
|
||||
}
|
||||
}
|
||||
FluFilledButton{
|
||||
text:"获取选中的数据"
|
||||
onClicked: {
|
||||
if(tree_view.selectionMode === FluTreeView.None){
|
||||
if(tree_view.selectionMode === FluTreeViewType.None){
|
||||
showError("当前非选择模式,没有选中的数据")
|
||||
}
|
||||
if(tree_view.selectionMode === FluTreeView.Single){
|
||||
if(tree_view.selectionMode === FluTreeViewType.Single){
|
||||
if(!tree_view.signleData()){
|
||||
showError("没有选中数据")
|
||||
return
|
||||
}
|
||||
showSuccess(tree_view.signleData().text)
|
||||
}
|
||||
if(tree_view.selectionMode === FluTreeView.Multiple){
|
||||
if(tree_view.selectionMode === FluTreeViewType.Multiple){
|
||||
if(tree_view.multipData().length===0){
|
||||
showError("没有选中数据")
|
||||
return
|
||||
|
@ -11,7 +11,7 @@ CustomWindow {
|
||||
width: 600
|
||||
height: 600
|
||||
fixSize: true
|
||||
launchMode: FluWindow.SingleTask
|
||||
launchMode: FluWindowType.SingleTask
|
||||
|
||||
ColumnLayout{
|
||||
anchors{
|
||||
|
@ -13,7 +13,7 @@ CustomWindow {
|
||||
height: 600
|
||||
minimumWidth: 520
|
||||
minimumHeight: 200
|
||||
launchMode: FluWindow.SingleTask
|
||||
launchMode: FluWindowType.SingleTask
|
||||
FileWatcher{
|
||||
id:watcher
|
||||
onFileChanged: {
|
||||
@ -25,7 +25,7 @@ CustomWindow {
|
||||
FluRemoteLoader{
|
||||
id:loader
|
||||
anchors.fill: parent
|
||||
statusMode: FluStatusView.Success
|
||||
statusMode: FluStatusViewType.Success
|
||||
lazy: true
|
||||
errorItem: Item{
|
||||
FluText{
|
||||
@ -43,7 +43,7 @@ CustomWindow {
|
||||
text:"拖入qml文件"
|
||||
font.pixelSize: 26
|
||||
anchors.centerIn: parent
|
||||
visible: !loader.itemLodaer().item && loader.statusMode === FluStatusView.Success
|
||||
visible: !loader.itemLodaer().item && loader.statusMode === FluStatusViewType.Success
|
||||
}
|
||||
Rectangle{
|
||||
radius: 4
|
||||
|
@ -18,7 +18,7 @@ CustomWindow {
|
||||
minimumWidth: 520
|
||||
minimumHeight: 200
|
||||
appBarVisible: false
|
||||
launchMode: FluWindow.SingleTask
|
||||
launchMode: FluWindowType.SingleTask
|
||||
|
||||
closeFunc:function(event){
|
||||
dialog_close.open()
|
||||
@ -29,15 +29,6 @@ CustomWindow {
|
||||
FluTools.setQuitOnLastWindowClosed(false)
|
||||
}
|
||||
|
||||
Connections{
|
||||
target: appInfo
|
||||
function onActiveWindow(){
|
||||
window.show()
|
||||
window.raise()
|
||||
window.requestActivate()
|
||||
}
|
||||
}
|
||||
|
||||
SystemTrayIcon {
|
||||
id:system_tray
|
||||
visible: true
|
||||
@ -67,7 +58,7 @@ CustomWindow {
|
||||
title:"退出"
|
||||
message:"确定要退出程序吗?"
|
||||
negativeText:"最小化"
|
||||
buttonFlags: FluContentDialog.NeutralButton | FluContentDialog.NegativeButton | FluContentDialog.PositiveButton
|
||||
buttonFlags: FluContentDialogType.NegativeButton | FluContentDialogType.NeutralButton | FluContentDialogType.PositiveButton
|
||||
onNegativeClicked:{
|
||||
window.hide()
|
||||
system_tray.showMessage("友情提示","FluentUI已隐藏至托盘,点击托盘可再次激活窗口");
|
||||
@ -173,9 +164,9 @@ CustomWindow {
|
||||
height: parent.height
|
||||
z:999
|
||||
//Stack模式,每次切换都会将页面压入栈中,随着栈的页面增多,消耗的内存也越多,内存消耗多就会卡顿,这时候就需要按返回将页面pop掉,释放内存。该模式可以配合FluPage中的launchMode属性,设置页面的启动模式
|
||||
// pageMode: FluNavigationView.Stack
|
||||
// pageMode: FluNavigationViewType.Stack
|
||||
//NoStack模式,每次切换都会销毁之前的页面然后创建一个新的页面,只需消耗少量内存(推荐)
|
||||
// pageMode: FluNavigationView.NoStack
|
||||
// pageMode: FluNavigationViewType.NoStack
|
||||
items: ItemsOriginal
|
||||
footerItems:ItemsFooter
|
||||
topPadding:FluTools.isMacos() ? 20 : 5
|
||||
@ -238,9 +229,9 @@ CustomWindow {
|
||||
|
||||
function changeDark(){
|
||||
if(FluTheme.dark){
|
||||
FluTheme.darkMode = FluDarkMode.Light
|
||||
FluTheme.darkMode = FluThemeType.Light
|
||||
}else{
|
||||
FluTheme.darkMode = FluDarkMode.Dark
|
||||
FluTheme.darkMode = FluThemeType.Dark
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ CustomWindow {
|
||||
width: 500
|
||||
height: 600
|
||||
fixSize: true
|
||||
launchMode: FluWindow.SingleInstance
|
||||
launchMode: FluWindowType.SingleInstance
|
||||
|
||||
FluTextBox{
|
||||
anchors{
|
||||
|
@ -11,7 +11,7 @@ CustomWindow {
|
||||
width: 500
|
||||
height: 600
|
||||
fixSize: true
|
||||
launchMode: FluWindow.SingleTask
|
||||
launchMode: FluWindowType.SingleTask
|
||||
|
||||
FluText{
|
||||
anchors.centerIn: parent
|
||||
|
@ -11,7 +11,7 @@ CustomWindow {
|
||||
width: 500
|
||||
height: 600
|
||||
fixSize: true
|
||||
launchMode: FluWindow.Standard
|
||||
launchMode: FluWindowType.Standard
|
||||
|
||||
FluMenuBar {
|
||||
FluMenu {
|
||||
|
@ -39,18 +39,3 @@ void AppInfo::changeLang(const QString& locale){
|
||||
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;
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
#include <QObject>
|
||||
#include <QQmlApplicationEngine>
|
||||
#include "tool/IPC.h"
|
||||
#include "lang/Lang.h"
|
||||
#include "stdafx.h"
|
||||
|
||||
@ -15,9 +14,7 @@ class AppInfo : public QObject
|
||||
public:
|
||||
explicit AppInfo(QObject *parent = nullptr);
|
||||
void init(QQmlApplicationEngine *engine);
|
||||
bool isOwnerProcess(IPC *ipc);
|
||||
Q_INVOKABLE void changeLang(const QString& locale);
|
||||
Q_SIGNAL void activeWindow();
|
||||
};
|
||||
|
||||
#endif // APPINFO_H
|
||||
|
@ -32,10 +32,6 @@ FRAMELESSHELPER_USE_NAMESPACE
|
||||
FramelessConfig::instance()->set(Global::Option::ForceNonNativeBackgroundBlur,false);
|
||||
#endif
|
||||
AppInfo* appInfo = new AppInfo();
|
||||
IPC ipc(0);
|
||||
if(!appInfo->isOwnerProcess(&ipc)){
|
||||
return 0;
|
||||
}
|
||||
QQmlApplicationEngine engine;
|
||||
FramelessHelper::Quick::registerTypes(&engine);
|
||||
#ifdef FLUENTUI_BUILD_STATIC_LIB
|
||||
|
@ -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());
|
||||
}
|
@ -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
126
src/Def.h
@ -4,15 +4,127 @@
|
||||
#include <QObject>
|
||||
#include <QtQml/qqml.h>
|
||||
|
||||
namespace Fluent_DarkMode {
|
||||
namespace FluThemeType {
|
||||
Q_NAMESPACE
|
||||
enum Fluent_DarkModeType {
|
||||
System = 0x0,
|
||||
Light = 0x1,
|
||||
Dark = 0x2,
|
||||
enum DarkMode {
|
||||
System = 0x0000,
|
||||
Light = 0x0001,
|
||||
Dark = 0x0002,
|
||||
};
|
||||
Q_ENUM_NS(Fluent_DarkModeType)
|
||||
QML_NAMED_ELEMENT(FluDarkMode)
|
||||
Q_ENUM_NS(DarkMode)
|
||||
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 {
|
||||
|
@ -30,6 +30,7 @@ FluApp::~FluApp(){
|
||||
|
||||
void FluApp::init(QQuickWindow *window){
|
||||
this->appWindow = window;
|
||||
FluContentDialogType::ButtonFlag::NegativeButton;
|
||||
}
|
||||
|
||||
void FluApp::run(){
|
||||
|
@ -32,7 +32,7 @@ FluTheme::FluTheme(QObject *parent)
|
||||
primaryColor(FluColors::getInstance()->Blue());
|
||||
nativeText(false);
|
||||
enableAnimation(false);
|
||||
darkMode(Fluent_DarkMode::Fluent_DarkModeType::Light);
|
||||
darkMode(FluThemeType::DarkMode::Light);
|
||||
_systemDark = systemDark();
|
||||
qApp->installEventFilter(this);
|
||||
}
|
||||
@ -67,11 +67,11 @@ bool FluTheme::systemDark()
|
||||
}
|
||||
|
||||
bool FluTheme::dark(){
|
||||
if(_darkMode == Fluent_DarkMode::Fluent_DarkModeType::Dark){
|
||||
if(_darkMode == FluThemeType::DarkMode::Dark){
|
||||
return true;
|
||||
}else if(_darkMode == Fluent_DarkMode::Fluent_DarkModeType::Light){
|
||||
}else if(_darkMode == FluThemeType::DarkMode::Light){
|
||||
return false;
|
||||
}else if(_darkMode == Fluent_DarkMode::Fluent_DarkModeType::System){
|
||||
}else if(_darkMode == FluThemeType::DarkMode::System){
|
||||
return _systemDark;
|
||||
}else{
|
||||
return false;
|
||||
|
@ -39,9 +39,9 @@ Rectangle{
|
||||
}
|
||||
property var darkClickListener: function(){
|
||||
if(FluTheme.dark){
|
||||
FluTheme.darkMode = FluDarkMode.Light
|
||||
FluTheme.darkMode = FluThemeType.Light
|
||||
}else{
|
||||
FluTheme.darkMode = FluDarkMode.Dark
|
||||
FluTheme.darkMode = FluThemeType.Dark
|
||||
}
|
||||
}
|
||||
id:root
|
||||
|
@ -3,12 +3,7 @@ import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
enum DisplayMode {
|
||||
Month,
|
||||
Year,
|
||||
Decade
|
||||
}
|
||||
property int displayMode: FluCalendarView.Month
|
||||
property int displayMode: FluCalendarViewType.Month
|
||||
property var date: new Date()
|
||||
property var currentDate : new Date()
|
||||
property var toDay: new Date()
|
||||
@ -39,7 +34,7 @@ Item {
|
||||
width: 70
|
||||
onClicked:{
|
||||
control.date = date
|
||||
displayMode = FluCalendarView.Year
|
||||
displayMode = FluCalendarViewType.Year
|
||||
updateYear(date)
|
||||
}
|
||||
background: Item{
|
||||
@ -98,7 +93,7 @@ Item {
|
||||
width: 70
|
||||
onClicked:{
|
||||
control.date = date
|
||||
displayMode = FluCalendarView.Month
|
||||
displayMode = FluCalendarViewType.Month
|
||||
updateMouth(date)
|
||||
}
|
||||
background: Item{
|
||||
@ -248,13 +243,13 @@ Item {
|
||||
left: parent.left
|
||||
leftMargin: 14
|
||||
}
|
||||
disabled: displayMode === FluCalendarView.Decade
|
||||
disabled: displayMode === FluCalendarViewType.Decade
|
||||
onClicked:{
|
||||
if(displayMode === FluCalendarView.Month){
|
||||
displayMode = FluCalendarView.Year
|
||||
if(displayMode === FluCalendarViewType.Month){
|
||||
displayMode = FluCalendarViewType.Year
|
||||
updateYear(date)
|
||||
}else if(displayMode === FluCalendarView.Year){
|
||||
displayMode = FluCalendarView.Decade
|
||||
}else if(displayMode === FluCalendarViewType.Year){
|
||||
displayMode = FluCalendarViewType.Decade
|
||||
updateDecade(date)
|
||||
}
|
||||
}
|
||||
@ -271,7 +266,7 @@ Item {
|
||||
onClicked: {
|
||||
var year = date.getFullYear()
|
||||
var month = date.getMonth()
|
||||
if(displayMode === FluCalendarView.Month){
|
||||
if(displayMode === FluCalendarViewType.Month){
|
||||
var lastMonthYear = year;
|
||||
var lastMonthMonth = month - 1
|
||||
if (month === 0) {
|
||||
@ -280,10 +275,10 @@ Item {
|
||||
}
|
||||
date = new Date(lastMonthYear,lastMonthMonth,1)
|
||||
updateMouth(date)
|
||||
}else if(displayMode === FluCalendarView.Year){
|
||||
}else if(displayMode === FluCalendarViewType.Year){
|
||||
date = new Date(year-1,month,1)
|
||||
updateYear(date)
|
||||
}else if(displayMode === FluCalendarView.Decade){
|
||||
}else if(displayMode === FluCalendarViewType.Decade){
|
||||
date = new Date(Math.floor(year / 10) * 10-10,month,1)
|
||||
updateDecade(date)
|
||||
}
|
||||
@ -301,7 +296,7 @@ Item {
|
||||
onClicked: {
|
||||
var year = date.getFullYear()
|
||||
var month = date.getMonth()
|
||||
if(displayMode === FluCalendarView.Month){
|
||||
if(displayMode === FluCalendarViewType.Month){
|
||||
var nextMonthYear = year
|
||||
var nextMonth = month + 1
|
||||
if (month === 11) {
|
||||
@ -310,10 +305,10 @@ Item {
|
||||
}
|
||||
date = new Date(nextMonthYear,nextMonth,1)
|
||||
updateMouth(date)
|
||||
}else if(displayMode === FluCalendarView.Year){
|
||||
}else if(displayMode === FluCalendarViewType.Year){
|
||||
date = new Date(year+1,month,1)
|
||||
updateYear(date)
|
||||
}else if(displayMode === FluCalendarView.Decade){
|
||||
}else if(displayMode === FluCalendarViewType.Decade){
|
||||
date = new Date(Math.floor(year / 10) * 10+10,month,1)
|
||||
updateDecade(date)
|
||||
}
|
||||
@ -334,8 +329,8 @@ Item {
|
||||
GridView{
|
||||
model: list_model
|
||||
anchors.fill: parent
|
||||
cellHeight: displayMode === FluCalendarView.Month ? 40 : 70
|
||||
cellWidth: displayMode === FluCalendarView.Month ? 40 : 70
|
||||
cellHeight: displayMode === FluCalendarViewType.Month ? 40 : 70
|
||||
cellWidth: displayMode === FluCalendarViewType.Month ? 40 : 70
|
||||
clip: true
|
||||
boundsBehavior:Flickable.StopAtBounds
|
||||
delegate: Loader{
|
||||
|
@ -15,12 +15,7 @@ FluPopup {
|
||||
signal neutralClicked
|
||||
signal negativeClicked
|
||||
signal positiveClicked
|
||||
enum ButtonFlag{
|
||||
NegativeButton=1
|
||||
,NeutralButton=2
|
||||
,PositiveButton=4
|
||||
}
|
||||
property int buttonFlags: FluContentDialog.NegativeButton | FluContentDialog.PositiveButton
|
||||
property int buttonFlags: FluContentDialogType.NegativeButton | FluContentDialogType.PositiveButton
|
||||
property var minWidth: {
|
||||
if(Window.window==null)
|
||||
return 400
|
||||
@ -85,11 +80,11 @@ FluPopup {
|
||||
id:neutral_btn
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
visible: popup.buttonFlags&FluContentDialog.NeutralButton
|
||||
visible: popup.buttonFlags&FluContentDialogType.NeutralButton
|
||||
text: neutralText
|
||||
onClicked: {
|
||||
popup.close()
|
||||
timer_delay.targetFlags = FluContentDialog.NeutralButton
|
||||
timer_delay.targetFlags = FluContentDialogType.NeutralButton
|
||||
timer_delay.restart()
|
||||
}
|
||||
}
|
||||
@ -97,11 +92,11 @@ FluPopup {
|
||||
id:negative_btn
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
visible: popup.buttonFlags&FluContentDialog.NegativeButton
|
||||
visible: popup.buttonFlags&FluContentDialogType.NegativeButton
|
||||
text: negativeText
|
||||
onClicked: {
|
||||
popup.close()
|
||||
timer_delay.targetFlags = FluContentDialog.NegativeButton
|
||||
timer_delay.targetFlags = FluContentDialogType.NegativeButton
|
||||
timer_delay.restart()
|
||||
}
|
||||
}
|
||||
@ -109,11 +104,11 @@ FluPopup {
|
||||
id:positive_btn
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
visible: popup.buttonFlags&FluContentDialog.PositiveButton
|
||||
visible: popup.buttonFlags&FluContentDialogType.PositiveButton
|
||||
text: positiveText
|
||||
onClicked: {
|
||||
popup.close()
|
||||
timer_delay.targetFlags = FluContentDialog.PositiveButton
|
||||
timer_delay.targetFlags = FluContentDialogType.PositiveButton
|
||||
timer_delay.restart()
|
||||
}
|
||||
}
|
||||
@ -125,13 +120,13 @@ FluPopup {
|
||||
id:timer_delay
|
||||
interval: popup.delayTime
|
||||
onTriggered: {
|
||||
if(targetFlags === FluContentDialog.NegativeButton){
|
||||
if(targetFlags === FluContentDialogType.NegativeButton){
|
||||
negativeClicked()
|
||||
}
|
||||
if(targetFlags === FluContentDialog.NeutralButton){
|
||||
if(targetFlags === FluContentDialogType.NeutralButton){
|
||||
neutralClicked()
|
||||
}
|
||||
if(targetFlags === FluContentDialog.PositiveButton){
|
||||
if(targetFlags === FluContentDialogType.PositiveButton){
|
||||
positiveClicked()
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ FluPage {
|
||||
FluStatusView{
|
||||
id:status_view
|
||||
color: "#00000000"
|
||||
statusMode: FluStatusView.Success
|
||||
statusMode: FluStatusViewType.Success
|
||||
onErrorClicked: control.errorClicked()
|
||||
anchors{
|
||||
left: parent.left
|
||||
|
@ -6,26 +6,16 @@ import QtQuick.Layouts
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
enum DisplayMode {
|
||||
Open = 0,
|
||||
Compact = 1,
|
||||
Minimal = 2,
|
||||
Auto = 3
|
||||
}
|
||||
enum PageMode {
|
||||
Stack = 0,
|
||||
NoStack = 1
|
||||
}
|
||||
property url logo
|
||||
property string title: ""
|
||||
property FluObject items
|
||||
property FluObject footerItems
|
||||
property int displayMode: FluNavigationView.Auto
|
||||
property int displayMode: FluNavigationViewType.Auto
|
||||
property Component autoSuggestBox
|
||||
property Component actionItem
|
||||
property int topPadding: 0
|
||||
property int navWidth: 300
|
||||
property int pageMode: FluNavigationView.Stack
|
||||
property int pageMode: FluNavigationViewType.Stack
|
||||
signal logoClicked
|
||||
id:control
|
||||
QtObject{
|
||||
@ -34,11 +24,11 @@ Item {
|
||||
property var stackItems: []
|
||||
property int displayMode: control.displayMode
|
||||
property bool enableNavigationPanel: false
|
||||
property bool isCompact: d.displayMode === FluNavigationView.Compact
|
||||
property bool isMinimal: d.displayMode === FluNavigationView.Minimal
|
||||
property bool isCompactAndPanel: d.displayMode === FluNavigationView.Compact && d.enableNavigationPanel
|
||||
property bool isCompactAndNotPanel:d.displayMode === FluNavigationView.Compact && !d.enableNavigationPanel
|
||||
property bool isMinimalAndPanel: d.displayMode === FluNavigationView.Minimal && d.enableNavigationPanel
|
||||
property bool isCompact: d.displayMode === FluNavigationViewType.Compact
|
||||
property bool isMinimal: d.displayMode === FluNavigationViewType.Minimal
|
||||
property bool isCompactAndPanel: d.displayMode === FluNavigationViewType.Compact && d.enableNavigationPanel
|
||||
property bool isCompactAndNotPanel:d.displayMode === FluNavigationViewType.Compact && !d.enableNavigationPanel
|
||||
property bool isMinimalAndPanel: d.displayMode === FluNavigationViewType.Minimal && d.enableNavigationPanel
|
||||
onIsCompactAndNotPanelChanged: {
|
||||
collapseAll()
|
||||
}
|
||||
@ -79,15 +69,15 @@ Item {
|
||||
}
|
||||
Component.onCompleted: {
|
||||
d.displayMode = Qt.binding(function(){
|
||||
if(control.displayMode !==FluNavigationView.Auto){
|
||||
if(control.displayMode !==FluNavigationViewType.Auto){
|
||||
return control.displayMode
|
||||
}
|
||||
if(control.width<=700){
|
||||
return FluNavigationView.Minimal
|
||||
return FluNavigationViewType.Minimal
|
||||
}else if(control.width<=900){
|
||||
return FluNavigationView.Compact
|
||||
return FluNavigationViewType.Compact
|
||||
}else{
|
||||
return FluNavigationView.Open
|
||||
return FluNavigationViewType.Open
|
||||
}
|
||||
})
|
||||
timer_anim_delay.restart()
|
||||
@ -102,10 +92,10 @@ Item {
|
||||
Connections{
|
||||
target: d
|
||||
function onDisplayModeChanged(){
|
||||
if(d.displayMode === FluNavigationView.Compact){
|
||||
if(d.displayMode === FluNavigationViewType.Compact){
|
||||
collapseAll()
|
||||
}
|
||||
if(d.displayMode === FluNavigationView.Minimal){
|
||||
if(d.displayMode === FluNavigationViewType.Minimal){
|
||||
d.enableNavigationPanel = false
|
||||
}
|
||||
}
|
||||
@ -533,11 +523,11 @@ Item {
|
||||
layout_footer.currentIndex = item._idx-(nav_list.count-layout_footer.count)
|
||||
}
|
||||
nav_list.currentIndex = item._idx
|
||||
if(pageMode === FluNavigationView.Stack){
|
||||
if(pageMode === FluNavigationViewType.Stack){
|
||||
var nav_stack = loader_content.item.navStack()
|
||||
var nav_stack2 = loader_content.item.navStack2()
|
||||
nav_stack.pop()
|
||||
if(nav_stack.currentItem.launchMode === FluPage.SingleInstance){
|
||||
if(nav_stack.currentItem.launchMode === FluPageType.SingleInstance){
|
||||
var url = nav_stack.currentItem.url
|
||||
var pageIndex = -1
|
||||
for(var i=0;i<nav_stack2.children.length;i++){
|
||||
@ -551,7 +541,7 @@ Item {
|
||||
nav_stack2.currentIndex = pageIndex
|
||||
}
|
||||
}
|
||||
}else if(pageMode === FluNavigationView.NoStack){
|
||||
}else if(pageMode === FluNavigationViewType.NoStack){
|
||||
loader_content.setSource(item._ext.url,item._ext.argument)
|
||||
}
|
||||
}
|
||||
@ -646,7 +636,7 @@ Item {
|
||||
id:nav_stack2
|
||||
anchors.fill: nav_stack
|
||||
clip: true
|
||||
visible: nav_stack.currentItem?.launchMode === FluPage.SingleInstance
|
||||
visible: nav_stack.currentItem?.launchMode === FluPageType.SingleInstance
|
||||
}
|
||||
function navStack(){
|
||||
return nav_stack
|
||||
@ -728,7 +718,7 @@ Item {
|
||||
}
|
||||
}
|
||||
visible: {
|
||||
if(d.displayMode !== FluNavigationView.Minimal)
|
||||
if(d.displayMode !== FluNavigationViewType.Minimal)
|
||||
return true
|
||||
return d.isMinimalAndPanel ? true : false
|
||||
}
|
||||
@ -1005,7 +995,7 @@ Item {
|
||||
Component{
|
||||
id:com_placeholder
|
||||
Item{
|
||||
property int launchMode: FluPage.SingleInstance
|
||||
property int launchMode: FluPageType.SingleInstance
|
||||
property string url
|
||||
}
|
||||
}
|
||||
@ -1031,12 +1021,12 @@ Item {
|
||||
return nav_list.currentIndex
|
||||
}
|
||||
function getCurrentUrl(){
|
||||
if(pageMode === FluNavigationView.Stack){
|
||||
if(pageMode === FluNavigationViewType.Stack){
|
||||
var nav_stack = loader_content.item.navStack()
|
||||
if(nav_stack.currentItem){
|
||||
return nav_stack.currentItem.url
|
||||
}
|
||||
}else if(pageMode === FluNavigationView.NoStack){
|
||||
}else if(pageMode === FluNavigationViewType.NoStack){
|
||||
return loader_content.source.toString()
|
||||
}
|
||||
return undefined
|
||||
@ -1051,19 +1041,19 @@ Item {
|
||||
if(page){
|
||||
switch(page.launchMode)
|
||||
{
|
||||
case FluPage.SingleTask:
|
||||
case FluPageType.SingleTask:
|
||||
while(nav_stack.currentItem !== page)
|
||||
{
|
||||
nav_stack.pop()
|
||||
d.stackItems = d.stackItems.slice(0, -1)
|
||||
}
|
||||
return
|
||||
case FluPage.SingleTop:
|
||||
case FluPageType.SingleTop:
|
||||
if (nav_stack.currentItem.url === url){
|
||||
return
|
||||
}
|
||||
break
|
||||
case FluPage.Standard:
|
||||
case FluPageType.Standard:
|
||||
default:
|
||||
}
|
||||
}
|
||||
@ -1083,7 +1073,7 @@ Item {
|
||||
var comp = Qt.createComponent(url)
|
||||
if (comp.status === Component.Ready) {
|
||||
var obj = comp.createObject(nav_stack,options)
|
||||
if(obj.launchMode === FluPage.SingleInstance){
|
||||
if(obj.launchMode === FluPageType.SingleInstance){
|
||||
nav_stack.push(com_placeholder,options)
|
||||
nav_stack2.children.push(obj)
|
||||
nav_stack2.currentIndex = nav_stack2.count - 1
|
||||
@ -1105,9 +1095,9 @@ Item {
|
||||
obj._ext = {url:url,argument:argument}
|
||||
d.stackItems = d.stackItems.concat(obj)
|
||||
}
|
||||
if(pageMode === FluNavigationView.Stack){
|
||||
if(pageMode === FluNavigationViewType.Stack){
|
||||
stackPush()
|
||||
}else if(pageMode === FluNavigationView.NoStack){
|
||||
}else if(pageMode === FluNavigationViewType.NoStack){
|
||||
noStackPush()
|
||||
}
|
||||
}
|
||||
|
@ -5,13 +5,7 @@ import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
enum LaunchMode{
|
||||
Standard = 0,
|
||||
SingleTask = 1,
|
||||
SingleTop = 2,
|
||||
SingleInstance = 3
|
||||
}
|
||||
property int launchMode: FluPage.SingleTop
|
||||
property int launchMode: FluPageType.SingleTop
|
||||
property bool animDisabled: false
|
||||
property string url : ""
|
||||
id: control
|
||||
|
@ -21,11 +21,11 @@ FluStatusView {
|
||||
asynchronous: true
|
||||
onStatusChanged: {
|
||||
if(status === Loader.Error){
|
||||
control.statusMode = FluStatusView.Error
|
||||
control.statusMode = FluStatusViewType.Error
|
||||
}else if(status === Loader.Loading){
|
||||
control.statusMode = FluStatusView.Loading
|
||||
control.statusMode = FluStatusViewType.Loading
|
||||
}else{
|
||||
control.statusMode = FluStatusView.Success
|
||||
control.statusMode = FluStatusViewType.Success
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ FluPage {
|
||||
FluStatusView{
|
||||
id:status_view
|
||||
color: "#00000000"
|
||||
statusMode: FluStatusView.Success
|
||||
statusMode: FluStatusViewType.Success
|
||||
onErrorClicked: control.errorClicked()
|
||||
anchors{
|
||||
left: parent.left
|
||||
|
@ -5,14 +5,8 @@ import FluentUI
|
||||
|
||||
Item{
|
||||
id:control
|
||||
enum StatusMode {
|
||||
Loading,
|
||||
Empty,
|
||||
Error,
|
||||
Success
|
||||
}
|
||||
default property alias content: container.data
|
||||
property int statusMode: FluStatusView.Loading
|
||||
property int statusMode: FluStatusViewType.Loading
|
||||
property string loadingText:"正在加载..."
|
||||
property string emptyText: "空空如也"
|
||||
property string errorText: "页面出错了.."
|
||||
@ -26,20 +20,20 @@ Item{
|
||||
Item{
|
||||
id:container
|
||||
anchors.fill: parent
|
||||
visible: statusMode===FluStatusView.Success
|
||||
visible: statusMode===FluStatusViewType.Success
|
||||
}
|
||||
Loader{
|
||||
id:loader
|
||||
anchors.fill: parent
|
||||
visible: statusMode!==FluStatusView.Success
|
||||
visible: statusMode!==FluStatusViewType.Success
|
||||
sourceComponent: {
|
||||
if(statusMode === FluStatusView.Loading){
|
||||
if(statusMode === FluStatusViewType.Loading){
|
||||
return loadingItem
|
||||
}
|
||||
if(statusMode === FluStatusView.Empty){
|
||||
if(statusMode === FluStatusViewType.Empty){
|
||||
return emptyItem
|
||||
}
|
||||
if(statusMode === FluStatusView.Error){
|
||||
if(statusMode === FluStatusViewType.Error){
|
||||
return errorItem
|
||||
}
|
||||
return undefined
|
||||
@ -108,15 +102,15 @@ Item{
|
||||
}
|
||||
}
|
||||
function showSuccessView(){
|
||||
statusMode = FluStatusView.Success
|
||||
statusMode = FluStatusViewType.Success
|
||||
}
|
||||
function showLoadingView(){
|
||||
statusMode = FluStatusView.Loading
|
||||
statusMode = FluStatusViewType.Loading
|
||||
}
|
||||
function showEmptyView(){
|
||||
statusMode = FluStatusView.Empty
|
||||
statusMode = FluStatusViewType.Empty
|
||||
}
|
||||
function showErrorView(){
|
||||
statusMode = FluStatusView.Error
|
||||
statusMode = FluStatusViewType.Error
|
||||
}
|
||||
}
|
||||
|
@ -4,18 +4,8 @@ import QtQuick.Layouts
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
enum TabWidthBehavior {
|
||||
Equal,
|
||||
SizeToContent,
|
||||
Compact
|
||||
}
|
||||
enum CloseButtonVisibility{
|
||||
Nerver,
|
||||
Always,
|
||||
OnHover
|
||||
}
|
||||
property int tabWidthBehavior : FluTabView.Equal
|
||||
property int closeButtonVisibility : FluTabView.Always
|
||||
property int tabWidthBehavior : FluTabViewType.Equal
|
||||
property int closeButtonVisibility : FluTabViewType.Always
|
||||
property int itemWidth: 146
|
||||
property bool addButtonVisibility: true
|
||||
signal newPressed
|
||||
@ -91,13 +81,13 @@ Item {
|
||||
property real timestamp: new Date().getTime()
|
||||
height: tab_nav.height
|
||||
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)
|
||||
}
|
||||
if(tabWidthBehavior === FluTabView.SizeToContent){
|
||||
if(tabWidthBehavior === FluTabViewType.SizeToContent){
|
||||
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 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
|
||||
Layout.leftMargin: 10
|
||||
visible: {
|
||||
if(tabWidthBehavior === FluTabView.Equal){
|
||||
if(tabWidthBehavior === FluTabViewType.Equal){
|
||||
return true
|
||||
}
|
||||
if(tabWidthBehavior === FluTabView.SizeToContent){
|
||||
if(tabWidthBehavior === FluTabViewType.SizeToContent){
|
||||
return true
|
||||
}
|
||||
if(tabWidthBehavior === FluTabView.Compact){
|
||||
if(tabWidthBehavior === FluTabViewType.Compact){
|
||||
return item_mouse_hove.containsMouse || item_btn_close.hovered || tab_nav.currentIndex === index
|
||||
}
|
||||
return false
|
||||
@ -256,9 +246,9 @@ Item {
|
||||
width: visible ? 24 : 0
|
||||
height: 24
|
||||
visible: {
|
||||
if(closeButtonVisibility === FluTabView.Nerver)
|
||||
if(closeButtonVisibility === FluTabViewType.Nerver)
|
||||
return false
|
||||
if(closeButtonVisibility === FluTabView.OnHover)
|
||||
if(closeButtonVisibility === FluTabViewType.OnHover)
|
||||
return item_mouse_hove.containsMouse || item_btn_close.hovered
|
||||
return true
|
||||
}
|
||||
|
@ -5,15 +5,11 @@ import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
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 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 int hourFormat: FluTimePicker.H
|
||||
property int isH: hourFormat === FluTimePicker.H
|
||||
property int hourFormat: FluTimePickerType.H
|
||||
property int isH: hourFormat === FluTimePickerType.H
|
||||
property var current
|
||||
id:control
|
||||
color: {
|
||||
@ -326,7 +322,7 @@ Rectangle {
|
||||
const period = text_ampm.text
|
||||
const date = new Date()
|
||||
var hours24 = parseInt(hours);
|
||||
if(control.hourFormat === FluTimePicker.H){
|
||||
if(control.hourFormat === FluTimePickerType.H){
|
||||
if (hours === "12") {
|
||||
hours24 = (period === "上午") ? 0 : 12;
|
||||
} else {
|
||||
|
@ -5,12 +5,7 @@ import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
enum TreeViewSelectionMode {
|
||||
None,
|
||||
Single,
|
||||
Multiple
|
||||
}
|
||||
property int selectionMode: FluTreeView.None
|
||||
property int selectionMode: FluTreeViewType.None
|
||||
property var currentElement
|
||||
property var currentParentElement
|
||||
property var rootModel: tree_model.get(0).items
|
||||
@ -83,12 +78,12 @@ Item {
|
||||
anchors.margins: 2
|
||||
color:{
|
||||
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 (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{
|
||||
if(item_layout.singleSelected && selectionMode === FluTreeView.Single){
|
||||
if(item_layout.singleSelected && selectionMode === FluTreeViewType.Single){
|
||||
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)
|
||||
@ -97,7 +92,7 @@ Item {
|
||||
Rectangle{
|
||||
width: 3
|
||||
color:FluTheme.primaryColor.dark
|
||||
visible: item_layout.singleSelected && (selectionMode === FluTreeView.Single)
|
||||
visible: item_layout.singleSelected && (selectionMode === FluTreeViewType.Single)
|
||||
radius: 3
|
||||
height: 20
|
||||
anchors{
|
||||
@ -115,10 +110,10 @@ Item {
|
||||
}
|
||||
}
|
||||
function onClickItem(){
|
||||
if(selectionMode === FluTreeView.None){
|
||||
if(selectionMode === FluTreeViewType.None){
|
||||
itemClicked(model)
|
||||
}
|
||||
if(selectionMode === FluTreeView.Single){
|
||||
if(selectionMode === FluTreeViewType.Single){
|
||||
currentElement = model
|
||||
if(item_layout.parent.parent.parent.itemModel){
|
||||
currentParentElement = item_layout.parent.parent.parent.itemModel
|
||||
@ -129,7 +124,7 @@ Item {
|
||||
}
|
||||
itemClicked(model)
|
||||
}
|
||||
if(selectionMode === FluTreeView.Multiple){
|
||||
if(selectionMode === FluTreeViewType.Multiple){
|
||||
|
||||
}
|
||||
}
|
||||
@ -144,7 +139,7 @@ Item {
|
||||
id:item_layout_checkbox
|
||||
text:""
|
||||
checked: itemModel.multipSelected
|
||||
visible: selectionMode === FluTreeView.Multiple
|
||||
visible: selectionMode === FluTreeViewType.Multiple
|
||||
Layout.leftMargin: 5
|
||||
function refreshCheckBox(){
|
||||
const stack = [tree_model.get(0)];
|
||||
|
@ -5,14 +5,9 @@ import QtQuick.Layouts
|
||||
import FluentUI
|
||||
|
||||
Window {
|
||||
enum LaunchMode {
|
||||
Standard,
|
||||
SingleTask,
|
||||
SingleInstance
|
||||
}
|
||||
default property alias content: container.data
|
||||
property bool closeDestory: true
|
||||
property int launchMode: FluWindow.Standard
|
||||
property int launchMode: FluWindowType.Standard
|
||||
property string route
|
||||
property var argument:({})
|
||||
property var pageRegister
|
||||
|
Loading…
Reference in New Issue
Block a user