From 9e2e8fb18d9329818039d801f72a04d35aebad30 Mon Sep 17 00:00:00 2001 From: donghualin Date: Wed, 19 Oct 2022 03:50:12 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=AB=98=E6=95=88=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8A=A0=E8=BD=BD=E6=8F=92=E4=BB=B6=E7=9A=84?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 删除原来的tray插件,高效模式下,加载插件使用时尚模式相同的加载插件的方式 Log: 增加高效模式加载插件的功能 Influence: 高效模式下加载插件 Task: https://pms.uniontech.com/task-view-112073.html Change-Id: I5766382fb64bd544b3c7a9c40d1ce4668613d508 --- debian/dde-dock.install | 2 - frame/controller/dockitemmanager.cpp | 81 +---- frame/controller/dockitemmanager.h | 4 - frame/controller/dockpluginscontroller.cpp | 163 --------- frame/controller/dockpluginscontroller.h | 62 ---- frame/controller/fixedplugincontroller.cpp | 83 ----- frame/controller/fixedplugincontroller.h | 56 --- frame/controller/proxyplugincontroller.cpp | 30 +- frame/controller/proxyplugincontroller.h | 3 +- frame/controller/quicksettingcontroller.cpp | 114 +++--- frame/controller/quicksettingcontroller.h | 24 +- frame/controller/toolapphelper.cpp | 145 ++++---- frame/controller/toolapphelper.h | 7 +- frame/dbus/dbusdockadaptors.cpp | 1 + frame/item/pluginsitem.h | 7 +- frame/item/quicksettingitem.cpp | 321 +++++++++++----- frame/item/quicksettingitem.h | 43 ++- frame/window/components/datetimedisplayer.cpp | 66 +++- frame/window/components/datetimedisplayer.h | 4 +- frame/window/docktraywindow.cpp | 342 ++++++++++++++++++ frame/window/docktraywindow.h | 91 +++++ frame/window/mainpanelcontrol.cpp | 65 ++-- frame/window/mainpanelcontrol.h | 7 +- frame/window/quickpluginwindow.cpp | 68 +++- frame/window/quickpluginwindow.h | 8 +- frame/window/quicksettingcontainer.cpp | 43 ++- frame/window/quicksettingcontainer.h | 7 +- frame/window/systempluginwindow.cpp | 95 +++-- frame/window/systempluginwindow.h | 15 +- .../window/tray/widgets/expandiconwidget.cpp | 182 +++++----- frame/window/tray/widgets/expandiconwidget.h | 25 +- frame/window/traymanagerwindow.cpp | 3 +- plugins/CMakeLists.txt | 6 +- 33 files changed, 1242 insertions(+), 931 deletions(-) delete mode 100644 frame/controller/dockpluginscontroller.cpp delete mode 100644 frame/controller/dockpluginscontroller.h delete mode 100644 frame/controller/fixedplugincontroller.cpp delete mode 100644 frame/controller/fixedplugincontroller.h create mode 100644 frame/window/docktraywindow.cpp create mode 100644 frame/window/docktraywindow.h diff --git a/debian/dde-dock.install b/debian/dde-dock.install index 1de3b1685..977d6ab70 100644 --- a/debian/dde-dock.install +++ b/debian/dde-dock.install @@ -1,10 +1,8 @@ usr/share usr/bin etc/dde-dock -usr/lib/dde-dock/plugins/libdatetime.so usr/lib/dde-dock/plugins/libshutdown.so usr/lib/dde-dock/plugins/libtrash.so -usr/lib/dde-dock/plugins/libtray.so usr/lib/dde-dock/plugins/liboverlay-warning.so usr/lib/dde-dock/plugins/system-trays usr/lib/dde-dock/plugins/quick-trays diff --git a/frame/controller/dockitemmanager.cpp b/frame/controller/dockitemmanager.cpp index 3742aec42..8a83ce2d6 100644 --- a/frame/controller/dockitemmanager.cpp +++ b/frame/controller/dockitemmanager.cpp @@ -26,6 +26,7 @@ #include "traypluginitem.h" #include "utils.h" #include "appmultiitem.h" +#include "quicksettingcontroller.h" #include #include @@ -40,7 +41,6 @@ const QGSettings *DockItemManager::m_dockedSettings = Utils::ModuleSettingsPtr(" DockItemManager::DockItemManager(QObject *parent) : QObject(parent) , m_appInter(new DockInter(dockServiceName(), dockServicePath(), QDBusConnection::sessionBus(), this)) - , m_pluginsInter(new DockPluginsController(this)) , m_loadFinished(false) { //固定区域:启动器 @@ -77,13 +77,6 @@ DockItemManager::DockItemManager(QObject *parent) connect(m_appInter, &DockInter::ShowMultiWindowChanged, this, &DockItemManager::onShowMultiWindowChanged); #endif - // 插件信号 - connect(m_pluginsInter, &DockPluginsController::pluginItemInserted, this, &DockItemManager::pluginItemInserted, Qt::QueuedConnection); - connect(m_pluginsInter, &DockPluginsController::pluginItemRemoved, this, &DockItemManager::pluginItemRemoved, Qt::QueuedConnection); - connect(m_pluginsInter, &DockPluginsController::pluginItemUpdated, this, &DockItemManager::itemUpdated, Qt::QueuedConnection); - connect(m_pluginsInter, &DockPluginsController::trayVisableCountChanged, this, &DockItemManager::trayVisableCountChanged, Qt::QueuedConnection); - connect(m_pluginsInter, &DockPluginsController::pluginLoaderFinished, this, &DockItemManager::onPluginLoadFinished, Qt::QueuedConnection); - DApplication *app = qobject_cast(qApp); if (app) { connect(app, &DApplication::iconThemeChanged, this, &DockItemManager::refreshItemsIcon); @@ -110,7 +103,7 @@ const QList> DockItemManager::itemList() const const QList DockItemManager::pluginList() const { - return m_pluginsInter->pluginsMap().keys(); + return QuickSettingController::instance()->pluginsMap().keys(); } bool DockItemManager::appIsOnDock(const QString &appDesktop) const @@ -268,76 +261,6 @@ void DockItemManager::appItemRemoved(AppItem *appItem) appItem->deleteLater(); } -void DockItemManager::pluginItemInserted(PluginsItem *item) -{ - manageItem(item); - - DockItem::ItemType pluginType = item->itemType(); - - // find first plugins item position - int firstPluginPosition = -1; - for (int i(0); i != m_itemList.size(); ++i) { - DockItem::ItemType type = m_itemList[i]->itemType(); - if (type != pluginType) - continue; - - firstPluginPosition = i; - break; - } - - if (firstPluginPosition == -1) - firstPluginPosition = m_itemList.size(); - - // find insert position - int insertIndex = 0; - const int itemSortKey = item->itemSortKey(); - if (itemSortKey == -1 || firstPluginPosition == -1) { - insertIndex = m_itemList.size(); - } else if (itemSortKey == 0) { - insertIndex = firstPluginPosition; - } else { - insertIndex = m_itemList.size(); - for (int i(firstPluginPosition + 1); i != m_itemList.size() + 1; ++i) { - PluginsItem *pItem = static_cast(m_itemList[i - 1].data()); - Q_ASSERT(pItem); - - const int sortKey = pItem->itemSortKey(); - if (pluginType == DockItem::FixedPlugin) { - if (sortKey != -1 && itemSortKey > sortKey) - continue; - insertIndex = i - 1; - break; - } - if (sortKey != -1 && itemSortKey > sortKey && pItem->itemType() != DockItem::FixedPlugin) - continue; - insertIndex = i - 1; - break; - } - } - - m_itemList.insert(insertIndex, item); - if(pluginType == DockItem::FixedPlugin) - insertIndex ++; - - if (!Utils::SettingValue(QString("com.deepin.dde.dock.module.") + item->pluginName(), QByteArray(), "enable", true).toBool()) - item->setVisible(false); - - emit itemInserted(insertIndex - firstPluginPosition, item); -} - -void DockItemManager::pluginItemRemoved(PluginsItem *item) -{ - item->hidePopup(); - - emit itemRemoved(item); - - m_itemList.removeOne(item); - - if (m_loadFinished) { - updatePluginsItemOrderKey(); - } -} - void DockItemManager::reloadAppItems() { // remove old item diff --git a/frame/controller/dockitemmanager.h b/frame/controller/dockitemmanager.h index 961229b47..41bc952cb 100644 --- a/frame/controller/dockitemmanager.h +++ b/frame/controller/dockitemmanager.h @@ -22,7 +22,6 @@ #ifndef DOCKITEMMANAGER_H #define DOCKITEMMANAGER_H -#include "dockpluginscontroller.h" #include "pluginsiteminterface.h" #include "dockitem.h" #include "appitem.h" @@ -75,8 +74,6 @@ private: void appItemAdded(const QDBusObjectPath &path, const int index); void appItemRemoved(const QString &appId); void appItemRemoved(AppItem *appItem); - void pluginItemInserted(PluginsItem *item); - void pluginItemRemoved(PluginsItem *item); void updatePluginsItemOrderKey(); void reloadAppItems(); void manageItem(DockItem *item); @@ -89,7 +86,6 @@ private: private: DockInter *m_appInter; - DockPluginsController *m_pluginsInter; static DockItemManager *INSTANCE; diff --git a/frame/controller/dockpluginscontroller.cpp b/frame/controller/dockpluginscontroller.cpp deleted file mode 100644 index 625771be0..000000000 --- a/frame/controller/dockpluginscontroller.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd. - * - * Author: sbw - * - * Maintainer: sbw - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "dockpluginscontroller.h" -#include "proxyplugincontroller.h" -#include "pluginsiteminterface.h" -#include "traypluginitem.h" - -#include -#include -#include - -DockPluginsController::DockPluginsController(QObject *parent) - : AbstractPluginsController(parent) -{ - setObjectName("DockPlugin"); - - ProxyPluginController::instance(PluginType::FixedSystemPlugin)->addProxyInterface(this); -} - -DockPluginsController::~DockPluginsController() -{ - ProxyPluginController::instance(PluginType::FixedSystemPlugin)->removeProxyInterface(this); -} - -void DockPluginsController::itemAdded(PluginsItemInterface *const itemInter, const QString &itemKey) -{ - QMap> &mPluginsMap = pluginsMap(); - - // check if same item added - if (mPluginsMap.contains(itemInter)) - if (mPluginsMap[itemInter].contains(itemKey)) - return; - - // 取 plugin api - ProxyPluginController *proxyController = ProxyPluginController::instance(itemInter); - if (!proxyController) - return; - - QPluginLoader *pluginLoader = proxyController->pluginLoader(itemInter); - if (!pluginLoader) - return; - - const QJsonObject &meta = pluginLoader->metaData().value("MetaData").toObject(); - - PluginsItem *item = nullptr; - if (itemInter->pluginName() == "tray") { - item = new TrayPluginItem(itemInter, itemKey, meta); - if (item->graphicsEffect()) { - item->graphicsEffect()->setEnabled(false); - } - connect(static_cast(item), &TrayPluginItem::trayVisableCountChanged, - this, &DockPluginsController::trayVisableCountChanged, Qt::UniqueConnection); - } else { - item = new PluginsItem(itemInter, itemKey, meta); - } - - mPluginsMap[itemInter][itemKey] = item; - - emit pluginItemInserted(item); -} - -void DockPluginsController::itemUpdate(PluginsItemInterface *const itemInter, const QString &itemKey) -{ - PluginsItem *item = getPluginItem(itemInter, itemKey); - if (!item) - return; - - item->update(); - - emit pluginItemUpdated(item); -} - -void DockPluginsController::itemRemoved(PluginsItemInterface *const itemInter, const QString &itemKey) -{ - PluginsItem *item = getPluginItem(itemInter, itemKey); - if (!item) - return; - - item->detachPluginWidget(); - - emit pluginItemRemoved(item); - - QMap> &mPluginsMap = pluginsMap(); - mPluginsMap[itemInter].remove(itemKey); - - // do not delete the itemWidget object(specified in the plugin interface) - item->centralWidget()->setParent(nullptr); - - if (item->isDragging()) { - QDrag::cancel(); - } - - // just delete our wrapper object(PluginsItem) - item->deleteLater(); -} - -void DockPluginsController::requestWindowAutoHide(PluginsItemInterface *const itemInter, const QString &itemKey, const bool autoHide) -{ - PluginsItem *item = getPluginItem(itemInter, itemKey); - if (!item) - return; - - Q_EMIT item->requestWindowAutoHide(autoHide); -} - -void DockPluginsController::requestRefreshWindowVisible(PluginsItemInterface *const itemInter, const QString &itemKey) -{ - PluginsItem *item = getPluginItem(itemInter, itemKey); - if (!item) - return; - - Q_EMIT item->requestRefreshWindowVisible(); -} - -void DockPluginsController::requestSetAppletVisible(PluginsItemInterface *const itemInter, const QString &itemKey, const bool visible) -{ - PluginsItem *item = getPluginItem(itemInter, itemKey); - if (!item) - return; - - if (visible) { - item->showPopupApplet(itemInter->itemPopupApplet(itemKey)); - } else { - item->hidePopup(); - } -} - -QMap> &DockPluginsController::pluginsMap() -{ - return ProxyPluginController::instance(PluginType::FixedSystemPlugin)->pluginsMap(); -} - -PluginsItem *DockPluginsController::getPluginItem(PluginsItemInterface * const itemInter, const QString &itemKey) const -{ - ProxyPluginController *proxyController = ProxyPluginController::instance(itemInter); - if (!proxyController) - return nullptr; - - const QMap> &plugins = proxyController->pluginsMap(); - if (plugins.contains(itemInter) && plugins[itemInter].contains(itemKey)) - return static_cast(plugins[itemInter][itemKey]); - - return nullptr; -} diff --git a/frame/controller/dockpluginscontroller.h b/frame/controller/dockpluginscontroller.h deleted file mode 100644 index 53143c195..000000000 --- a/frame/controller/dockpluginscontroller.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd. - * - * Author: sbw - * - * Maintainer: sbw - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef DOCKPLUGINSCONTROLLER_H -#define DOCKPLUGINSCONTROLLER_H - -#include "pluginsitem.h" -#include "pluginproxyinterface.h" -#include "abstractpluginscontroller.h" - -#include -#include -#include -#include - -class PluginsItemInterface; -class DockPluginsController : public AbstractPluginsController -{ - Q_OBJECT - -public: - explicit DockPluginsController(QObject *parent = nullptr); - ~DockPluginsController() override; - - // implements PluginProxyInterface - void itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey) override; - void itemUpdate(PluginsItemInterface * const itemInter, const QString &itemKey) override; - void itemRemoved(PluginsItemInterface * const itemInter, const QString &itemKey) override; - void requestWindowAutoHide(PluginsItemInterface * const itemInter, const QString &itemKey, const bool autoHide) override; - void requestRefreshWindowVisible(PluginsItemInterface * const itemInter, const QString &itemKey) override; - void requestSetAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool visible) override; - QMap> &pluginsMap(); - -private: - PluginsItem *getPluginItem(PluginsItemInterface * const itemInter, const QString &itemKey) const; - -signals: - void pluginItemInserted(PluginsItem *pluginItem) const; - void pluginItemRemoved(PluginsItem *pluginItem) const; - void pluginItemUpdated(PluginsItem *pluginItem) const; - void trayVisableCountChanged(const int &count) const; -}; - -#endif // DOCKPLUGINSCONTROLLER_H diff --git a/frame/controller/fixedplugincontroller.cpp b/frame/controller/fixedplugincontroller.cpp deleted file mode 100644 index 5e4b5545a..000000000 --- a/frame/controller/fixedplugincontroller.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd. - * - * Author: donghualin - * - * Maintainer: donghualin - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#include "fixedplugincontroller.h" -#include "utils.h" -#include "proxyplugincontroller.h" -#include "systempluginwindow.h" - -FixedPluginController::FixedPluginController(QObject *parent) - : AbstractPluginsController(parent) -{ - setObjectName("FixedPluginController"); - ProxyPluginController::instance(PluginType::FixedSystemPlugin)->addProxyInterface(this); -} - -FixedPluginController::~FixedPluginController() -{ - ProxyPluginController::instance(PluginType::FixedSystemPlugin)->removeProxyInterface(this); -} - -void FixedPluginController::itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey) -{ - StretchPluginsItem *item = new StretchPluginsItem(itemInter, itemKey); - m_pluginItems << item; - Q_EMIT pluginItemInserted(item); -} - -void FixedPluginController::itemUpdate(PluginsItemInterface * const itemInter, const QString &) -{ - for (StretchPluginsItem *item : m_pluginItems) { - if (item->pluginInter() == itemInter) { - Q_EMIT pluginItemUpdated(item); - break; - } - } -} - -void FixedPluginController::itemRemoved(PluginsItemInterface * const itemInter, const QString &) -{ - for (StretchPluginsItem *item : m_pluginItems) { - if (item->pluginInter() == itemInter) { - m_pluginItems.removeOne(item); - Q_EMIT pluginItemRemoved(item); - item->deleteLater(); - break; - } - } -} - -bool FixedPluginController::needLoad(PluginsItemInterface *itemInter) -{ - ProxyPluginController *controller = ProxyPluginController::instance(itemInter); - if (!controller) - return false; - - QPluginLoader *pluginLoader = controller->pluginLoader(itemInter); - if (!pluginLoader) - return false; - - // isFixed配置表示该插件在时尚模式下,显示在最右侧的图标,例如关机图标 - QJsonObject json = pluginLoader->metaData().value("MetaData").toObject(); - if (json.contains("fixed")) - return json.value("fixed").toBool(); - - return false; -} diff --git a/frame/controller/fixedplugincontroller.h b/frame/controller/fixedplugincontroller.h deleted file mode 100644 index 11ea4c227..000000000 --- a/frame/controller/fixedplugincontroller.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd. - * - * Author: donghualin - * - * Maintainer: donghualin - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef FIXEDPLUGINCONTROLLER_H -#define FIXEDPLUGINCONTROLLER_H - -#include "abstractpluginscontroller.h" - -class StretchPluginsItem; - -class FixedPluginController : public AbstractPluginsController -{ - Q_OBJECT - -public: - explicit FixedPluginController(QObject *parent = nullptr); - ~FixedPluginController() override; - -Q_SIGNALS: - void pluginItemInserted(StretchPluginsItem *); - void pluginItemRemoved(StretchPluginsItem *); - void pluginItemUpdated(StretchPluginsItem *); - -protected: - void itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey) override; - void itemUpdate(PluginsItemInterface * const itemInter, const QString &) override; - void itemRemoved(PluginsItemInterface * const itemInter, const QString &) override; - - void requestWindowAutoHide(PluginsItemInterface * const, const QString &, const bool) override {} - void requestRefreshWindowVisible(PluginsItemInterface * const, const QString &) override {} - void requestSetAppletVisible(PluginsItemInterface * const, const QString &, const bool) override {} - - bool needLoad(PluginsItemInterface *itemInter) override; - -private: - QList m_pluginItems; -}; - -#endif // FIXEDPLUGINCONTROLLER_H diff --git a/frame/controller/proxyplugincontroller.cpp b/frame/controller/proxyplugincontroller.cpp index a35d41432..66b4edaf6 100644 --- a/frame/controller/proxyplugincontroller.cpp +++ b/frame/controller/proxyplugincontroller.cpp @@ -37,39 +37,25 @@ static QStringList getPathFromConf(const QString &key) { static QMap getPluginPaths() { QMap plugins; - - // 添加系统目录 - { - QStringList pluginPaths; - #ifdef QT_DEBUG - pluginPaths << qApp->applicationDirPath() + "/../plugins"; - #else - pluginPaths << "/usr/lib/dde-dock/plugins"; - - const QStringList &pluginsDirs = getPathFromConf("PATH"); - if (!pluginsDirs.isEmpty()) - pluginPaths << pluginsDirs; - #endif - plugins[PluginType::FixedSystemPlugin] = pluginPaths; - } - // 添加快捷插件目录 { QStringList pluginPaths; #ifdef QT_DEBUG - pluginPaths << qApp->applicationDirPath() + "/../plugins/quick-trays"; + pluginPaths << qApp->applicationDirPath() + "/../plugins/quick-trays" + << qApp->applicationDirPath() + "/../plugins"; #else - pluginPaths << "/usr/lib/dde-dock/plugins/quick-trays"; + pluginPaths << "/usr/lib/dde-dock/plugins/quick-trays" + << "/usr/lib/dde-dock/plugins"; - const QStringList &pluginsDirs = getPathFromConf("QUICK_TRAY_PATH"); + const QStringList pluginsDirs = (getPathFromConf("QUICK_TRAY_PATH") << getPathFromConf("PATH")); if (!pluginsDirs.isEmpty()) - pluginPaths << pluginsDirs; + pluginPaths << pluginsDirs; #endif plugins[PluginType::QuickPlugin] = pluginPaths; } // 添加系统插件目录 - { + { QStringList pluginPaths; #ifdef QT_DEBUG pluginPaths << qApp->applicationDirPath() + "/../plugins/system-trays"; @@ -78,7 +64,7 @@ static QMap getPluginPaths() const QStringList &pluginsDirs = getPathFromConf("SYSTEM_TRAY_PATH"); if (!pluginsDirs.isEmpty()) - pluginPaths << pluginsDirs; + pluginPaths << pluginsDirs; #endif plugins[PluginType::SystemTrays] = pluginPaths; } diff --git a/frame/controller/proxyplugincontroller.h b/frame/controller/proxyplugincontroller.h index e76dcd04e..e475be82a 100644 --- a/frame/controller/proxyplugincontroller.h +++ b/frame/controller/proxyplugincontroller.h @@ -26,8 +26,7 @@ class PluginsItemInterface; // 加载的插件的类型(1 根目录下的插件 2 快捷设置插件 3 系统插件) enum class PluginType { - FixedSystemPlugin = 0, - QuickPlugin, + QuickPlugin = 0, SystemTrays }; diff --git a/frame/controller/quicksettingcontroller.cpp b/frame/controller/quicksettingcontroller.cpp index e507291b8..af78c1920 100644 --- a/frame/controller/quicksettingcontroller.cpp +++ b/frame/controller/quicksettingcontroller.cpp @@ -22,6 +22,7 @@ #include "quicksettingitem.h" #include "pluginsiteminterface.h" #include "proxyplugincontroller.h" +#include "pluginsitem.h" QuickSettingController::QuickSettingController(QObject *parent) : AbstractPluginsController(parent) @@ -35,78 +36,46 @@ QuickSettingController::~QuickSettingController() ProxyPluginController::instance(PluginType::QuickPlugin)->removeProxyInterface(this); } -void QuickSettingController::sortPlugins() -{ - QList primarySettingItems; - QList quickItems; - for (QuickSettingItem *item : m_quickSettingItems) { - if (item->isPrimary()) - primarySettingItems << item; - else - quickItems << item; - } - - static QStringList existKeys = {"network-item-key", "sound-item-key", "VPN", "PROJECTSCREEN"}; - qSort(primarySettingItems.begin(), primarySettingItems.end(), [ = ](QuickSettingItem *item1, QuickSettingItem *item2) { - int index1 = existKeys.indexOf(item1->itemKey()); - int index2 = existKeys.indexOf(item2->itemKey()); - if (index1 >= 0 || index2 >= 0) - return index1 < index2; - - return true; - }); - - m_quickSettingItems.clear(); - m_quickSettingItems << primarySettingItems << quickItems; -} - void QuickSettingController::itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey) { - QList::iterator findItemIterator = std::find_if(m_quickSettingItems.begin(), m_quickSettingItems.end(), - [ = ](QuickSettingItem *item) { - return item->itemKey() == itemKey; - }); - - if (findItemIterator != m_quickSettingItems.end()) - return; - + // 根据读取到的metaData数据获取当前插件的类型,提供给外部 + PluginAttribute pluginClass = PluginAttribute::Quick; QPluginLoader *pluginLoader = ProxyPluginController::instance(PluginType::QuickPlugin)->pluginLoader(itemInter); - QJsonObject metaData; - if (pluginLoader) - metaData = pluginLoader->metaData().value("MetaData").toObject(); - QuickSettingItem *quickItem = new QuickSettingItem(itemInter, itemKey, metaData); + QJsonObject meta; + if (pluginLoader) { + meta = pluginLoader->metaData().value("MetaData").toObject(); + if (meta.contains("tool") && meta.value("tool").toBool()) + pluginClass = PluginAttribute::Tool; + else if (meta.contains("fixed") && meta.value("fixed").toBool()) + pluginClass = PluginAttribute::Fixed; + } - m_quickSettingItems << quickItem; - sortPlugins(); + m_quickPlugins[pluginClass] << itemInter; + m_quickPluginsMap[itemInter] = itemKey; - emit pluginInserted(quickItem); + emit pluginInserted(itemInter, pluginClass); } void QuickSettingController::itemUpdate(PluginsItemInterface * const itemInter, const QString &) { - auto findItemIterator = std::find_if(m_quickSettingItems.begin(), m_quickSettingItems.end(), - [ = ](QuickSettingItem *item) { - return item->pluginItem() == itemInter; - }); - if (findItemIterator != m_quickSettingItems.end()) { - QuickSettingItem *settingItem = *findItemIterator; - settingItem->update(); - } } void QuickSettingController::itemRemoved(PluginsItemInterface * const itemInter, const QString &) { - // 删除本地记录的插件列表 - QList::iterator findItemIterator = std::find_if(m_quickSettingItems.begin(), m_quickSettingItems.end(), - [ = ](QuickSettingItem *item) { - return (item->pluginItem() == itemInter); - }); - if (findItemIterator != m_quickSettingItems.end()) { - QuickSettingItem *quickItem = *findItemIterator; - m_quickSettingItems.removeOne(quickItem); - Q_EMIT pluginRemoved(quickItem); - quickItem->deleteLater(); + for (auto it = m_quickPlugins.begin(); it != m_quickPlugins.end(); it++) { + QList &plugins = m_quickPlugins[it.key()]; + if (!plugins.contains(itemInter)) + continue; + + plugins.removeOne(itemInter); + if (plugins.isEmpty()) + m_quickPlugins.remove(it.key()); + + break; } + + m_quickPluginsMap.remove(itemInter); + Q_EMIT pluginRemoved(itemInter); } void QuickSettingController::updateDockInfo(PluginsItemInterface * const itemInter, const DockPart &part) @@ -119,3 +88,32 @@ QuickSettingController *QuickSettingController::instance() static QuickSettingController instance; return &instance; } + +QList QuickSettingController::pluginItems(const PluginAttribute &pluginClass) const +{ + return m_quickPlugins.value(pluginClass); +} + +QString QuickSettingController::itemKey(PluginsItemInterface *pluginItem) const +{ + return m_quickPluginsMap.value(pluginItem); +} + +QJsonObject QuickSettingController::metaData(PluginsItemInterface *pluginItem) const +{ + QPluginLoader *pluginLoader = ProxyPluginController::instance(PluginType::QuickPlugin)->pluginLoader(pluginItem); + if (!pluginLoader) + return QJsonObject(); + + return pluginLoader->metaData().value("MetaData").toObject(); +} + +PluginsItem *QuickSettingController::pluginItemWidget(PluginsItemInterface *pluginItem) +{ + if (m_pluginItemWidgetMap.contains(pluginItem)) + return m_pluginItemWidgetMap[pluginItem]; + + PluginsItem *widget = new PluginsItem(pluginItem, itemKey(pluginItem), metaData(pluginItem)); + m_pluginItemWidgetMap[pluginItem] = widget; + return widget; +} diff --git a/frame/controller/quicksettingcontroller.h b/frame/controller/quicksettingcontroller.h index fdd4a1936..eb5398643 100644 --- a/frame/controller/quicksettingcontroller.h +++ b/frame/controller/quicksettingcontroller.h @@ -24,18 +24,29 @@ #include "abstractpluginscontroller.h" class QuickSettingItem; +class PluginsItem; class QuickSettingController : public AbstractPluginsController { Q_OBJECT +public: + enum class PluginAttribute { + Quick = 0, + Tool, + Fixed + }; + public: static QuickSettingController *instance(); - const QList &settingItems() const { return m_quickSettingItems; } + QList pluginItems(const PluginAttribute &pluginClass) const; + QString itemKey(PluginsItemInterface *pluginItem) const; + QJsonObject metaData(PluginsItemInterface *pluginItem) const; + PluginsItem *pluginItemWidget(PluginsItemInterface *pluginItem); Q_SIGNALS: - void pluginInserted(QuickSettingItem *); - void pluginRemoved(QuickSettingItem *); + void pluginInserted(PluginsItemInterface *itemInter, const PluginAttribute &); + void pluginRemoved(PluginsItemInterface *itemInter); void pluginUpdated(PluginsItemInterface *, const DockPart &); protected: @@ -52,10 +63,9 @@ protected: void updateDockInfo(PluginsItemInterface * const itemInter, const DockPart &part) override; private: - void sortPlugins(); - -private: - QList m_quickSettingItems; + QMap> m_quickPlugins; + QMap m_quickPluginsMap; + QMap m_pluginItemWidgetMap; }; #endif // CONTAINERPLUGINSCONTROLLER_H diff --git a/frame/controller/toolapphelper.cpp b/frame/controller/toolapphelper.cpp index 1b0fc7bc1..d2215ad26 100644 --- a/frame/controller/toolapphelper.cpp +++ b/frame/controller/toolapphelper.cpp @@ -22,6 +22,7 @@ #include "toolapphelper.h" #include "dockitem.h" #include "pluginsitem.h" +#include "quicksettingcontroller.h" #include #include @@ -33,37 +34,23 @@ ToolAppHelper::ToolAppHelper(QWidget *pluginAreaWidget, QWidget *toolAreaWidget, , m_displayMode(DisplayMode::Efficient) , m_trashItem(nullptr) { + connect(QuickSettingController::instance(), &QuickSettingController::pluginInserted, this, [ = ](PluginsItemInterface *itemInter, const QuickSettingController::PluginAttribute &pluginClass) { + if (pluginClass != QuickSettingController::PluginAttribute::Tool) + return; + + pluginItemAdded(itemInter); + }); + + QList pluginItems = QuickSettingController::instance()->pluginItems(QuickSettingController::PluginAttribute::Tool); + for (PluginsItemInterface *pluginItem : pluginItems) + pluginItemAdded(pluginItem); } void ToolAppHelper::setDisplayMode(DisplayMode displayMode) { m_displayMode = displayMode; - resetPluginItems(); updateWidgetStatus(); -} - -void ToolAppHelper::addPluginItem(int index, DockItem *dockItem) -{ - if (pluginInTool(dockItem)) - appendToToolArea(index, dockItem); - else - appendToPluginArea(index, dockItem); - - // 将插件指针顺序保存到列表中 - if (index >= 0 && index < m_sequentPluginItems.size()) - m_sequentPluginItems.insert(index, dockItem); - else - m_sequentPluginItems << dockItem; - - // 保存垃圾箱插件指针 - PluginsItem *pluginsItem = qobject_cast(dockItem); - if (pluginsItem && pluginsItem->pluginName() == "trash") - m_trashItem = pluginsItem; - - if (!toolIsVisible()) - updateWidgetStatus(); - - Q_EMIT requestUpdate(); + moveToolWidget(); } void ToolAppHelper::removePluginItem(DockItem *dockItem) @@ -90,23 +77,16 @@ bool ToolAppHelper::toolIsVisible() const return m_toolAreaWidget->isVisible(); } -void ToolAppHelper::appendToPluginArea(int index, DockItem *dockItem) -{ - // 因为日期时间插件和其他插件的大小有异,为了方便设置边距,在插件区域布局再添加一层布局设置边距 - // 因此在处理插件图标时,需要通过两层布局判断是否为需要的插件,例如拖动插件位置等判断 - QBoxLayout *boxLayout = new QBoxLayout(QBoxLayout::LeftToRight, m_pluginAreaWidget); - boxLayout->addWidget(dockItem, 0, Qt::AlignCenter); - QBoxLayout *pluginLayout = static_cast(m_pluginAreaWidget->layout()); - pluginLayout->insertLayout(index, boxLayout, 0); -} - void ToolAppHelper::appendToToolArea(int index, DockItem *dockItem) { + dockItem->setParent(m_toolAreaWidget); QBoxLayout *boxLayout = static_cast(m_toolAreaWidget->layout()); if (index >= 0) boxLayout->insertWidget(index, dockItem); else boxLayout->addWidget(dockItem); + + Q_EMIT requestUpdate(); } bool ToolAppHelper::removePluginArea(DockItem *dockItem) @@ -141,28 +121,26 @@ bool ToolAppHelper::removeToolArea(DockItem *dockItem) return false; } -void ToolAppHelper::resetPluginItems() +void ToolAppHelper::moveToolWidget() { - if (m_displayMode == DisplayMode::Efficient) { - // 高效模式下, 让工具区域的插件移动到插件区域显示 - QList dockItems = dockItemOnWidget(true); - for (DockItem *dockItem : dockItems) { - // 从工具列表中移除插件, 将这些插件放入到插件区域 - removeToolArea(dockItem); - int index = itemIndex(dockItem, false); - appendToPluginArea(index, dockItem); - } - } else { - // 时尚模式下,将插件区域对应的插件移动到工具区域 - QList dockItems = dockItemOnWidget(false); - for (DockItem *dockItem : dockItems) { - if (!pluginInTool(dockItem)) - continue; + for (int i = m_toolAreaWidget->layout()->count() - 1; i >= 0; i--) { + QLayoutItem *layoutItem = m_toolAreaWidget->layout()->itemAt(i); + if (!layoutItem) + continue; - // 从插件区域中移除相关插件,并将其插入到工具区域中 - removePluginArea(dockItem); - int index = itemIndex(dockItem, true); - appendToToolArea(index, dockItem); + PluginsItem *pluginWidget = qobject_cast(layoutItem->widget()); + if (!pluginWidget) + continue; + + m_toolAreaWidget->layout()->removeWidget(pluginWidget); + } + + if (m_displayMode == Dock::DisplayMode::Fashion) { + QuickSettingController *quickController = QuickSettingController::instance(); + QList plugins = quickController->pluginItems(QuickSettingController::PluginAttribute::Tool); + for (PluginsItemInterface *plugin : plugins) { + PluginsItem *pluginWidget = quickController->pluginItemWidget(plugin); + m_toolAreaWidget->layout()->addWidget(pluginWidget); } } } @@ -186,9 +164,6 @@ void ToolAppHelper::updateWidgetStatus() bool ToolAppHelper::pluginInTool(DockItem *dockItem) const { - if (m_displayMode != DisplayMode::Fashion) - return false; - PluginsItem *pluginItem = qobject_cast(dockItem); if (!pluginItem) return false; @@ -238,19 +213,55 @@ QList ToolAppHelper::dockItemOnWidget(bool isTool) const } } else { QBoxLayout *pluginLayout = static_cast(m_pluginAreaWidget->layout()); - for (int i = 0; i < pluginLayout->count(); ++i) { - QLayoutItem *layoutItem = pluginLayout->itemAt(i); - QLayout *boxLayout = layoutItem->layout(); - if (!boxLayout) - continue; + if (pluginLayout) { + for (int i = 0; i < pluginLayout->count(); ++i) { + QLayoutItem *layoutItem = pluginLayout->itemAt(i); + QLayout *boxLayout = layoutItem->layout(); + if (!boxLayout) + continue; - DockItem *dockItem = qobject_cast(boxLayout->itemAt(0)->widget()); - if (!dockItem) - continue; + DockItem *dockItem = qobject_cast(boxLayout->itemAt(0)->widget()); + if (!dockItem) + continue; - dockItems << dockItem; + dockItems << dockItem; + } } } return dockItems; } + +void ToolAppHelper::pluginItemAdded(PluginsItemInterface *itemInter) +{ + if (m_displayMode != Dock::DisplayMode::Fashion || pluginExists(itemInter)) + return; + + QuickSettingController *quickController = QuickSettingController::instance(); + PluginsItem *pluginItem = quickController->pluginItemWidget(itemInter); + if (pluginInTool(pluginItem)) + appendToToolArea(0, pluginItem); +} + +bool ToolAppHelper::pluginExists(PluginsItemInterface *itemInter) const +{ + QBoxLayout *boxLayout = static_cast(m_toolAreaWidget->layout()); + if (!boxLayout) + return false; + + for (int i = 0; i < boxLayout->count() ; i++) { + QLayoutItem *layoutItem = boxLayout->itemAt(i); + if (!layoutItem) + continue; + + PluginsItem *pluginItem = qobject_cast(layoutItem->widget()); + if (!pluginItem) + continue; + + // 如果当前的插件的接口已经存在,则无需再次插入 + if (pluginItem->pluginItem() == itemInter) + return true; + } + + return false; +} diff --git a/frame/controller/toolapphelper.h b/frame/controller/toolapphelper.h index 8feee7919..dd3513ed8 100644 --- a/frame/controller/toolapphelper.h +++ b/frame/controller/toolapphelper.h @@ -29,6 +29,7 @@ class QWidget; class DockItem; class PluginsItem; +class PluginsItemInterface; using namespace Dock; @@ -40,7 +41,6 @@ public: explicit ToolAppHelper(QWidget *pluginAreaWidget, QWidget *toolAreaWidget, QObject *parent = nullptr); void setDisplayMode(DisplayMode displayMode); - void addPluginItem(int index, DockItem *dockItem); void removePluginItem(DockItem *dockItem); PluginsItem *trashPlugin() const; bool toolIsVisible() const; @@ -50,16 +50,17 @@ Q_SIGNALS: void toolVisibleChanged(bool); private: - void appendToPluginArea(int index, DockItem *dockItem); void appendToToolArea(int index, DockItem *dockItem); bool removePluginArea(DockItem *dockItem); bool removeToolArea(DockItem *dockItem); + void moveToolWidget(); - void resetPluginItems(); void updateWidgetStatus(); bool pluginInTool(DockItem *dockItem) const; int itemIndex(DockItem *dockItem, bool isTool) const; QList dockItemOnWidget(bool isTool) const; + void pluginItemAdded(PluginsItemInterface *itemInter); + bool pluginExists(PluginsItemInterface *itemInter) const; private: QWidget *m_pluginAreaWidget; diff --git a/frame/dbus/dbusdockadaptors.cpp b/frame/dbus/dbusdockadaptors.cpp index fe945a10c..6cc8b2102 100644 --- a/frame/dbus/dbusdockadaptors.cpp +++ b/frame/dbus/dbusdockadaptors.cpp @@ -24,6 +24,7 @@ #include "dockitemmanager.h" #include "windowmanager.h" #include "proxyplugincontroller.h" +#include "pluginsitem.h" #include #include diff --git a/frame/item/pluginsitem.h b/frame/item/pluginsitem.h index 008b6c5e9..7e3bfbb3d 100644 --- a/frame/item/pluginsitem.h +++ b/frame/item/pluginsitem.h @@ -26,12 +26,14 @@ #include "pluginsiteminterface.h" class QGSettings; + class PluginsItem : public DockItem { Q_OBJECT + friend class QuickSettingController; + public: - explicit PluginsItem(PluginsItemInterface *const pluginInter, const QString &itemKey, const QJsonObject &jsonData, QWidget *parent = nullptr); ~PluginsItem() override; int itemSortKey() const; @@ -58,6 +60,9 @@ public: public slots: void refreshIcon() override; +protected: + explicit PluginsItem(PluginsItemInterface *const pluginInter, const QString &itemKey, const QJsonObject &jsonData, QWidget *parent = nullptr); + private slots: void onGSettingsChanged(const QString &key); diff --git a/frame/item/quicksettingitem.cpp b/frame/item/quicksettingitem.cpp index 2e2e75063..eb922f886 100644 --- a/frame/item/quicksettingitem.cpp +++ b/frame/item/quicksettingitem.cpp @@ -28,6 +28,8 @@ #include #include +#include +#include #define ICONWIDTH 24 #define ICONHEIGHT 24 @@ -48,7 +50,13 @@ QuickSettingItem::QuickSettingItem(PluginsItemInterface *const pluginInter, cons , m_pluginInter(pluginInter) , m_itemKey(itemKey) , m_metaData(metaData) + , m_iconWidgetParent(new QWidget(this)) + , m_iconWidget(new QuickIconWidget(pluginInter, itemKey, isPrimary(), m_iconWidgetParent)) + , m_textWidget(new QWidget(this)) + , m_nameLabel(new QLabel(m_textWidget)) + , m_stateLabel(new QLabel(m_textWidget)) { + initUi(); setAcceptDrops(true); this->installEventFilter(this); } @@ -57,6 +65,32 @@ QuickSettingItem::~QuickSettingItem() { } +bool QuickSettingItem::eventFilter(QObject *obj, QEvent *event) +{ + if (event->type() == QEvent::MouseButtonRelease) { + if (obj->objectName() == "expandLabel") { + // 如果是鼠标的按下事件 + if (isPrimary()) + Q_EMIT detailClicked(m_pluginInter); + } else if (obj == this) { + const QString &command = m_pluginInter->itemCommand(m_itemKey); + if (!command.isEmpty()) + QProcess::startDetached(command); + + if (QWidget *w = m_pluginInter->itemPopupApplet(m_itemKey)) + showPopupApplet(w); + } + } else if (event->type() == QEvent::Resize) { + if (obj == m_nameLabel) { + m_nameLabel->setText(QFontMetrics(m_nameLabel->font()).elidedText(m_pluginInter->pluginDisplayName(), Qt::TextElideMode::ElideRight, m_nameLabel->width())); + } else if (obj == m_stateLabel) { + m_stateLabel->setText(QFontMetrics(m_stateLabel->font()).elidedText(m_pluginInter->description(), Qt::TextElideMode::ElideRight, m_stateLabel->width())); + } + } + + return DockItem::eventFilter(obj, event); +} + PluginsItemInterface *QuickSettingItem::pluginItem() const { return m_pluginInter; @@ -114,84 +148,9 @@ void QuickSettingItem::paintEvent(QPaintEvent *e) QPainterPath path; path.addRoundedRect(rect(), RADIUS, RADIUS); painter.setClipPath(path); - // 绘制背景色 DPalette dpa = DPaletteHelper::instance()->palette(this); - painter.fillRect(rect(), dpa.brush(DPalette::ColorRole::Mid)); - // 让图标填上前景色 - int pixmapWidth = static_cast(ICONWIDTH * qApp->devicePixelRatio()); - int pixmapHeight = static_cast(ICONHEIGHT * qApp->devicePixelRatio()); - QIcon icon = m_pluginInter->icon(DockPart::QuickPanel); - QList iconSizes = icon.availableSizes(); - if (iconSizes.size() > 0) { - QSize size = iconSizes[0]; - if (size.isValid() && !size.isEmpty() && !size.isNull()) { - pixmapWidth = size.width(); - pixmapHeight = size.height(); - } - } - QPixmap pm = icon.pixmap(pixmapWidth, pixmapHeight); - QPainter pa(&pm); - pa.setCompositionMode(QPainter::CompositionMode_SourceIn); - pa.fillRect(pm.rect(), painter.pen().brush()); - if (isPrimary()) { - // 如果是主图标,则显示阴影背景 - int marginYSpace = yMarginSpace(); - QRect iconBg(MARGINLEFTSPACE, marginYSpace, BGSIZE, BGSIZE); - painter.save(); - painter.setPen(Qt::NoPen); - painter.setBrush(dpa.brush(DPalette::ColorRole::Midlight)); - painter.drawEllipse(iconBg); - painter.restore(); - QRect rctIcon(iconBg.x() + (iconBg.width() - pixmapWidth) / 2, - iconBg.y() + (iconBg.height() - pixmapHeight) / 2, - pixmapWidth, pixmapHeight); - painter.drawPixmap(rctIcon, pm); - // 绘制文字 - painter.setPen(Qt::black); - - QRect rctPluginName(iconBg.right() + 10, iconBg.top(), BGWIDTH - BGSIZE - OPENICONSIZE - 10 * 2, BGSIZE / 2); - QFont font = DFontSizeManager::instance()->t6(); - font.setBold(true); - painter.setFont(font); - QTextOption textOption; - textOption.setAlignment(Qt::AlignLeft | Qt::AlignVCenter); - QString displayName = QFontMetrics(font).elidedText(m_pluginInter->pluginDisplayName(), Qt::TextElideMode::ElideRight, rctPluginName.width()); - painter.drawText(rctPluginName, displayName, textOption); - // 绘制下方啊的状态文字 - QRect rctPluginStatus(rctPluginName.x(), rctPluginName.bottom() + 1, - rctPluginName.width(), BGSIZE / 2); - font = DFontSizeManager::instance()->t10(); - painter.setFont(font); - QString description = QFontMetrics(font).elidedText(m_pluginInter->description(), Qt::TextElideMode::ElideRight, rctPluginStatus.width()); - painter.drawText(rctPluginStatus, description, textOption); - // 绘制右侧的展开按钮 - QPixmap expandPixmap = ImageUtil::loadSvg(expandFileName(), expandSize); - int iconRight = rect().width() - MARGINRIGHTSPACE; - QRect rectOfExpand(iconRight - expandSize.width(), - (rctIcon.y() + (rctIcon.height() - expandSize.height()) / 2), - expandSize.width(), expandSize.height()); - painter.drawPixmap(rectOfExpand, expandPixmap); - } else { - // 绘制图标 - QRect rctIcon = iconRect(); - painter.drawPixmap(rctIcon, pm); - // 绘制文字 - QFont ft; - ft.setPixelSize(FONTSIZE); - painter.setFont(ft); - QTextOption option; - option.setAlignment(Qt::AlignTop | Qt::AlignHCenter); - painter.drawText(QRect(QPoint(0, rctIcon.top() + ICONHEIGHT + ICONSPACE), - QPoint(width(), height())), m_pluginInter->pluginDisplayName(), option); - } -} - -QRect QuickSettingItem::iconRect() -{ - int left = (width() - ICONWIDTH) / 2; - int top = (height() - ICONHEIGHT - ICONSPACE - 10) / 2; - return QRect(left, top, ICONWIDTH, ICONHEIGHT); + painter.fillRect(rect(), Qt::white); } QColor QuickSettingItem::foregroundColor() const @@ -207,31 +166,96 @@ QColor QuickSettingItem::foregroundColor() const return dpa.color(DPalette::ColorGroup::Normal, DPalette::ColorRole::Text); } -void QuickSettingItem::mouseReleaseEvent(QMouseEvent *event) +void QuickSettingItem::initUi() { - // 如果是鼠标的按下事件 if (isPrimary()) { - QMouseEvent *mouseEvent = static_cast(event); - QRect rctExpand(rect().width() - MARGINRIGHTSPACE - expandSize.width(), - (rect().height() - expandSize.height()) / 2, - expandSize.width(), expandSize.height()); - if (rctExpand.contains(mapFromGlobal(mouseEvent->globalPos()))) - Q_EMIT detailClicked(m_pluginInter); + // 如果是占用两排的插件,则用横向Layout + QHBoxLayout *mainLayout = new QHBoxLayout(this); + mainLayout->setContentsMargins(10, 0, 10, 0); + mainLayout->setSpacing(0); + mainLayout->addStretch(10); + mainLayout->setAlignment(Qt::AlignCenter); + // 添加图标 + QVBoxLayout *iconLayout = new QVBoxLayout(m_iconWidgetParent); + iconLayout->setContentsMargins(0, 0, 0, 0); + iconLayout->setSpacing(0); + iconLayout->setAlignment(Qt::AlignCenter); + m_iconWidget->setFixedSize(BGSIZE, BGSIZE); + iconLayout->addWidget(m_iconWidget); + mainLayout->addWidget(m_iconWidgetParent); + mainLayout->addSpacing(10); + // 添加中间的名称部分 + QFont nameFont = DFontSizeManager::instance()->t6(); + nameFont.setBold(true); + QPalette pe; + pe.setColor(QPalette::WindowText, Qt::black); + m_nameLabel->setPalette(pe); + m_stateLabel->setPalette(pe); + m_nameLabel->setFont(nameFont); + m_stateLabel->setFont(DFontSizeManager::instance()->t10()); + m_nameLabel->setText(m_pluginInter->pluginDisplayName()); + m_stateLabel->setText(m_pluginInter->description()); + m_nameLabel->installEventFilter(this); + m_stateLabel->installEventFilter(this); + QVBoxLayout *textLayout = new QVBoxLayout(m_textWidget); + textLayout->setContentsMargins(0, 0, 0, 0); + textLayout->setSpacing(0); + textLayout->addWidget(m_nameLabel); + textLayout->addWidget(m_stateLabel); + textLayout->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); + mainLayout->addWidget(m_textWidget); + + // 添加右侧的展开按钮 + QWidget *expandWidgetParent = new QWidget(this); + QVBoxLayout *expandLayout = new QVBoxLayout(expandWidgetParent); + expandLayout->setSpacing(0); + QLabel *expandLabel = new QLabel(expandWidgetParent); + expandLabel->setObjectName("expandLabel"); + expandLabel->setPixmap(QPixmap(expandFileName())); + expandLabel->setFixedSize(expandSize); + expandLabel->setAutoFillBackground(true); + expandLabel->installEventFilter(this); + expandLayout->addWidget(expandLabel); + pe.setBrush(QPalette::Window, Qt::transparent); + expandLabel->setPalette(pe); + + mainLayout->addWidget(expandWidgetParent); } else { - const QString command = m_pluginInter->itemCommand(m_itemKey); - if (!command.isEmpty()) - QProcess::startDetached(command); + QHBoxLayout *iconLayout = new QHBoxLayout(m_iconWidgetParent); + iconLayout->setContentsMargins(0, 0, 0, 0); + iconLayout->setSpacing(0); + iconLayout->setAlignment(Qt::AlignHCenter); - if (QWidget *w = m_pluginInter->itemPopupApplet(m_itemKey)) - showPopupApplet(w); + m_iconWidgetParent->setFixedHeight(ICONHEIGHT); + m_iconWidget->setFixedSize(ICONWIDTH, ICONHEIGHT); + iconLayout->addWidget(m_iconWidget); + + QVBoxLayout *mainLayout = new QVBoxLayout(this); + mainLayout->setContentsMargins(0, 10, 0, 10); + mainLayout->setSpacing(7); + mainLayout->setAlignment(Qt::AlignCenter); + // 添加上方的图标 + mainLayout->addWidget(m_iconWidgetParent); + + // 添加下方的文字 + QHBoxLayout *textLayout = new QHBoxLayout(m_textWidget); + textLayout->setAlignment(Qt::AlignCenter); + textLayout->setContentsMargins(0, 0, 0, 0); + textLayout->setSpacing(0); + QFont nameFont = DFontSizeManager::instance()->t10(); + QPalette pe; + pe.setColor(QPalette::WindowText, Qt::black); + m_nameLabel->setFont(nameFont); + m_nameLabel->setPalette(pe); + m_nameLabel->setText(m_pluginInter->pluginDisplayName()); + textLayout->addWidget(m_nameLabel); + m_stateLabel->setVisible(false); + m_textWidget->setFixedHeight(11); + mainLayout->addWidget(m_textWidget); + installEventFilter(this); } } -int QuickSettingItem::yMarginSpace() -{ - return (rect().height() - BGSIZE) / 2; -} - QString QuickSettingItem::expandFileName() { if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType) @@ -239,3 +263,112 @@ QString QuickSettingItem::expandFileName() return QString(":/icons/resources/arrow-right.svg"); } + +QPixmap QuickSettingItem::pluginIcon() const +{ + QIcon icon = m_pluginInter->icon(DockPart::QuickPanel); + if (icon.isNull()) { + // 如果图标为空,就使用itemWidget的截图作为它的图标,这种一般是适用于老版本插件或者没有实现v23接口的插件 + QWidget *itemWidget = m_pluginInter->itemWidget(m_itemKey); + itemWidget->setFixedSize(ICONWIDTH, ICONHEIGHT); + QPixmap grabPixmap = itemWidget->grab(); + return grabPixmap; + } + + // 获取icon接口返回的图标 + int pixmapWidth = width(); + int pixmapHeight = height(); + QList iconSizes = icon.availableSizes(); + if (iconSizes.size() > 0) { + QSize size = iconSizes[0]; + if (size.isValid() && !size.isEmpty() && !size.isNull()) { + pixmapWidth = size.width(); + pixmapHeight = size.height(); + } + } + + return icon.pixmap(pixmapWidth, pixmapHeight); +} + +/** + * @brief QuickIconWidget::QuickIconWidget + * @param pluginInter + * @param parent + * 图标的widget + */ +QuickIconWidget::QuickIconWidget(PluginsItemInterface *pluginInter, const QString &itemKey, bool isPrimary, QWidget *parent) + : QWidget(parent) + , m_pluginInter(pluginInter) + , m_itemKey(itemKey) + , m_isPrimary(isPrimary) +{ +} + +void QuickIconWidget::paintEvent(QPaintEvent *event) +{ + QWidget::paintEvent(event); + QPixmap pm = pluginIcon(); + + QPainter painter(this); + painter.setRenderHint(QPainter::RenderHint::Antialiasing); + painter.setPen(foregroundColor()); + + if (m_isPrimary) { + DPalette dpa = DPaletteHelper::instance()->palette(this); + QPainter pa(&pm); + pa.setCompositionMode(QPainter::CompositionMode_SourceIn); + pa.fillRect(pm.rect(), painter.pen().brush()); + // 如果是主图标,则显示阴影背景 + painter.save(); + painter.setPen(Qt::NoPen); + painter.setBrush(dpa.brush(DPalette::ColorRole::Midlight)); + painter.drawEllipse(rect()); + painter.restore(); + QRect rctIcon((rect().width() - pm.width()) / 2, (rect().height() - pm.height()) / 2, pm.width(), pm.height()); + painter.drawPixmap(rctIcon, pm); + } else { + QRect rctIcon(0, 0, pm.width(), pm.height()); + painter.drawPixmap(rctIcon, pm); + } +} + +QColor QuickIconWidget::foregroundColor() const +{ + DPalette dpa = DPaletteHelper::instance()->palette(this); + // 此处的颜色是临时获取的,后期需要和设计师确认,改成正规的颜色 + if (m_pluginInter->status() == PluginsItemInterface::PluginStatus::Active) + return dpa.color(DPalette::ColorGroup::Active, DPalette::ColorRole::Text); + + if (m_pluginInter->status() == PluginsItemInterface::PluginStatus::Deactive) + return dpa.color(DPalette::ColorGroup::Disabled, DPalette::ColorRole::Text); + + return dpa.color(DPalette::ColorGroup::Normal, DPalette::ColorRole::Text); +} + +QPixmap QuickIconWidget::pluginIcon() const +{ + QIcon icon = m_pluginInter->icon(DockPart::QuickPanel); + if (icon.isNull()) { + // 如果图标为空,就使用itemWidget的截图作为它的图标,这种一般是适用于老版本插件或者没有实现v23接口的插件 + QWidget *itemWidget = m_pluginInter->itemWidget(m_itemKey); + if (itemWidget) { + itemWidget->setFixedSize(ICONWIDTH, ICONHEIGHT); + return itemWidget->grab(); + } + return QPixmap(); + } + + // 获取icon接口返回的图标 + int pixmapWidth = width(); + int pixmapHeight = height(); + QList iconSizes = icon.availableSizes(); + if (iconSizes.size() > 0) { + QSize size = iconSizes[0]; + if (size.isValid() && !size.isEmpty() && !size.isNull()) { + pixmapWidth = size.width(); + pixmapHeight = size.height(); + } + } + + return icon.pixmap(pixmapWidth, pixmapHeight); +} diff --git a/frame/item/quicksettingitem.h b/frame/item/quicksettingitem.h index 08c416395..97cb1b0f6 100644 --- a/frame/item/quicksettingitem.h +++ b/frame/item/quicksettingitem.h @@ -24,17 +24,18 @@ #include "dockitem.h" class PluginsItemInterface; +class QuickIconWidget; class QuickSettingItem : public DockItem { Q_OBJECT - friend class QuickSettingController; - Q_SIGNALS: void detailClicked(PluginsItemInterface *); public: + QuickSettingItem(PluginsItemInterface *const pluginInter, const QString &itemKey, const QJsonObject &metaData, QWidget *parent = nullptr); + ~QuickSettingItem() override; PluginsItemInterface *pluginItem() const; ItemType itemType() const override; const QPixmap dragPixmap(); @@ -42,23 +43,49 @@ public: bool isPrimary() const; protected: - QuickSettingItem(PluginsItemInterface *const pluginInter, const QString &itemKey, const QJsonObject &metaData, QWidget *parent = nullptr); - ~QuickSettingItem() override; + bool eventFilter(QObject *obj, QEvent *event) override; void paintEvent(QPaintEvent *e) override; - QRect iconRect(); QColor foregroundColor() const; - void mouseReleaseEvent(QMouseEvent *event) override; - private: - int yMarginSpace(); + void initUi(); QString expandFileName(); + QPixmap pluginIcon() const; private: PluginsItemInterface *m_pluginInter; QString m_itemKey; QJsonObject m_metaData; + QWidget *m_iconWidgetParent; + QuickIconWidget *m_iconWidget; + QWidget *m_textWidget; + QLabel *m_nameLabel; + QLabel *m_stateLabel; +}; + +/** + * @brief The QuickIconWidget class + * 图标的Widget + */ +class QuickIconWidget : public QWidget +{ + Q_OBJECT + +public: + explicit QuickIconWidget(PluginsItemInterface *pluginInter, const QString &itemKey, bool isPrimary, QWidget *parent = Q_NULLPTR); + +protected: + void paintEvent(QPaintEvent *event) override; + +private: + QColor foregroundColor() const; + QPixmap pluginIcon() const; + +private: + PluginsItemInterface *m_pluginInter; + QString m_itemKey; + bool m_isPrimary; }; #endif // QUICKSETTINGITEM_H diff --git a/frame/window/components/datetimedisplayer.cpp b/frame/window/components/datetimedisplayer.cpp index df5bc4e3f..48da1df2c 100644 --- a/frame/window/components/datetimedisplayer.cpp +++ b/frame/window/components/datetimedisplayer.cpp @@ -42,7 +42,7 @@ static QMap dateFormat{{ 0,"yyyy/M/d" }, { 1,"yyyy-M-d" }, { 2,"yy { 4,"yyyy-MM-dd" }, { 5,"yyyy.MM.dd" }, { 6,"yy/M/d" }, { 7,"yy-M-d" }, { 8,"yy.M.d" }}; static QMap timeFormat{{0, "h:mm"}, {1, "hh:mm"}}; -DateTimeDisplayer::DateTimeDisplayer(QWidget *parent) +DateTimeDisplayer::DateTimeDisplayer(bool showMultiRow, QWidget *parent) : QWidget (parent) , m_timedateInter(new Timedate("org.deepin.daemon.Timedate1", "/org/deepin/daemon/Timedate1", QDBusConnection::sessionBus(), this)) , m_position(Dock::Position::Bottom) @@ -52,6 +52,7 @@ DateTimeDisplayer::DateTimeDisplayer(QWidget *parent) , m_tipsTimer(new QTimer(this)) , m_currentSize(0) , m_oneRow(false) + , m_showMultiRow(showMultiRow) { m_tipPopupWindow.reset(new DockPopupWindow); // 日期格式变化的时候,需要重绘 @@ -131,12 +132,16 @@ QSize DateTimeDisplayer::suitableSize() const QSize DateTimeDisplayer::suitableSize(const Dock::Position &position) const { DateTimeInfo info = dateTimeInfo(position); - if (position == Dock::Position::Top || position == Dock::Position::Bottom) { - int width = info.m_timeRect.width() + info.m_dateRect.width() + 16; - return QSize(width, height()); + if (position == Dock::Position::Left || position == Dock::Position::Right) + return QSize(width(), info.m_timeRect.height() + info.m_dateRect.height()); + + // 如果在上下显示 + if (m_showMultiRow) { + // 如果显示多行的情况,一般是在高效模式下显示,因此,返回最大的尺寸 + return QSize(qMax(info.m_timeRect.width(), info.m_dateRect.width()), height()); } - return QSize(width(), info.m_timeRect.height() + info.m_dateRect.height()); + return QSize(info.m_timeRect.width() + info.m_dateRect.width() + 16, height()); } void DateTimeDisplayer::mousePressEvent(QMouseEvent *event) @@ -209,20 +214,29 @@ DateTimeDisplayer::DateTimeInfo DateTimeDisplayer::dateTimeInfo(const Dock::Posi info.m_time = getTimeString(position); info.m_date = getDateString(position); - if (position == Dock::Top || position == Dock::Bottom) { - int timeWidth = QFontMetrics(timeFont()).boundingRect(info.m_time).width() + 3; - int dateWidth = QFontMetrics(m_dateFont).boundingRect(info.m_date).width() + 2; + // 如果是左右方向 + if (position == Dock::Position::Left || position == Dock::Position::Right) { + int textWidth = rect().width(); + info.m_timeRect = QRect(0, 0, textWidth, DATETIMESIZE / 2); + info.m_dateRect = QRect(0, DATETIMESIZE / 2 + 1, textWidth, DATETIMESIZE / 2); + return info; + } + int timeWidth = QFontMetrics(timeFont()).boundingRect(info.m_time).width() + 3; + int dateWidth = QFontMetrics(m_dateFont).boundingRect(info.m_date).width() + 2; + // 如果是上下方向 + if (m_showMultiRow) { + // 日期时间多行显示(一般是高效模式下) + info.m_timeRect = QRect(0, 0, timeWidth, height() / 2); + info.m_dateRect = QRect(0, height() / 2, dateWidth, height() / 2); + } else { info.m_timeRect = QRect(ITEMSPACE, 0, timeWidth, height()); int dateX = rect().width() - QFontMetrics(m_dateFont).width(info.m_date) - 2 - ITEMSPACE; // 如果时间的X坐标小于日期的X坐标,需要手动设置坐标在日期坐标的右侧 if (dateX < info.m_timeRect.right()) dateX = info.m_timeRect.right(); info.m_dateRect = QRect(dateX, 0, dateWidth, height()); - } else { - int textWidth = rect().width(); - info.m_timeRect = QRect(0, 0, textWidth, DATETIMESIZE / 2); - info.m_dateRect = QRect(0, DATETIMESIZE / 2 + 1, textWidth, DATETIMESIZE / 2); } + return info; } @@ -260,16 +274,17 @@ void DateTimeDisplayer::paintEvent(QPaintEvent *e) painter.setRenderHint(QPainter::Antialiasing); painter.setPen(QPen(palette().brightText(), 1)); - int timeTextFlag = Qt::AlignCenter; - int dateTextFlag = Qt::AlignCenter; - if (m_position == Dock::Top || m_position == Dock::Bottom) { - timeTextFlag = Qt::AlignLeft | Qt::AlignVCenter; - dateTextFlag = Qt::AlignRight | Qt::AlignVCenter; + int timeAlignFlag = Qt::AlignCenter; + int dateAlignFlag = Qt::AlignCenter; + if (m_showMultiRow) { + timeAlignFlag = Qt::AlignHCenter | Qt::AlignBottom; + dateAlignFlag = Qt::AlignHCenter | Qt::AlignTop; } + painter.setFont(timeFont()); - painter.drawText(info.m_timeRect, timeTextFlag, info.m_time); + painter.drawText(textRect(info.m_timeRect), timeAlignFlag, info.m_time); painter.setFont(m_dateFont); - painter.drawText(info.m_dateRect, dateTextFlag, info.m_date); + painter.drawText(textRect(info.m_dateRect), dateAlignFlag, info.m_date); updateLastData(info); } @@ -352,6 +367,19 @@ void DateTimeDisplayer::createMenuItem() } } +QRect DateTimeDisplayer::textRect(const QRect &sourceRect) const +{ + // 如果是上下,则不做任何变化 + if (!m_showMultiRow && (m_position == Dock::Position::Top || m_position == Dock::Position::Bottom)) + return sourceRect; + + QRect resultRect = sourceRect; + QSize size = suitableSize(); + // 如果是左右或者上下多行显示,设置宽度 + resultRect.setWidth(size.width()); + return resultRect; +} + void DateTimeDisplayer::enterEvent(QEvent *event) { Q_UNUSED(event); diff --git a/frame/window/components/datetimedisplayer.h b/frame/window/components/datetimedisplayer.h index 587da8a11..37fa224f9 100644 --- a/frame/window/components/datetimedisplayer.h +++ b/frame/window/components/datetimedisplayer.h @@ -48,7 +48,7 @@ private: }; public: - explicit DateTimeDisplayer(QWidget *parent = nullptr); + explicit DateTimeDisplayer(bool showMultiRow, QWidget *parent = nullptr); ~DateTimeDisplayer() override; void setPositon(Dock::Position position); void setOneRow(bool oneRow); @@ -80,6 +80,7 @@ private: QFont timeFont() const; void createMenuItem(); + QRect textRect(const QRect &sourceRect) const; private Q_SLOTS: void onTimeChanged(); @@ -97,6 +98,7 @@ private: QString m_lastTimeString; int m_currentSize; bool m_oneRow; + bool m_showMultiRow; }; #endif // DATETIMEDISPLAYER_H diff --git a/frame/window/docktraywindow.cpp b/frame/window/docktraywindow.cpp new file mode 100644 index 000000000..12ddc1ea6 --- /dev/null +++ b/frame/window/docktraywindow.cpp @@ -0,0 +1,342 @@ +/* + * Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd. + * + * Author: donghualin + * + * Maintainer: donghualin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "docktraywindow.h" +#include "datetimedisplayer.h" +#include "systempluginwindow.h" +#include "quickpluginwindow.h" +#include "tray_gridview.h" +#include "tray_model.h" +#include "tray_delegate.h" +#include "quicksettingcontroller.h" +#include "pluginsitem.h" + +#include + +#include +#include + +#define FRONTSPACING 18 +#define SPLITERSIZE 2 +#define SPLITESPACE 10 + +DockTrayWindow::DockTrayWindow(DockInter *dockInter, QWidget *parent) + : QWidget(parent) + , m_dockInter(dockInter) + , m_position(Dock::Position::Bottom) + , m_displayMode(Dock::DisplayMode::Efficient) + , m_mainBoxLayout(new QBoxLayout(QBoxLayout::Direction::RightToLeft, this)) + , m_toolWidget(new QWidget(this)) + , m_toolLayout(new QBoxLayout(QBoxLayout::RightToLeft, m_toolWidget)) + , m_toolLineLabel(new QLabel(this)) + , m_dateTimeWidget(new DateTimeDisplayer(true, this)) + , m_systemPuginWidget(new SystemPluginWindow(this)) + , m_quickIconWidget(new QuickPluginWindow(this)) + , m_trayView(new TrayGridView(this)) + , m_model(new TrayModel(m_trayView, false, true, this)) + , m_delegate(new TrayDelegate(m_trayView, this)) +{ + initUi(); + initConnection(); + + m_trayView->setModel(m_model); + m_trayView->setItemDelegate(m_delegate); + m_trayView->openPersistentEditor(m_model->index(0, 0)); +} + +void DockTrayWindow::setPositon(const Dock::Position &position) +{ + m_position = position; + m_dateTimeWidget->setPositon(position); + m_systemPuginWidget->setPositon(position); + m_quickIconWidget->setPositon(position); + m_trayView->setPosition(position); + updateLayout(position); + onResetLayout(); +} + +void DockTrayWindow::setDisplayMode(const Dock::DisplayMode &displayMode) +{ + m_displayMode = displayMode; + moveToolPlugin(); +} + +QSize DockTrayWindow::suitableSize(const Dock::Position &position, const int &, const double &) const +{ + if (position == Dock::Position::Left || position == Dock::Position::Right) { + // 左右的尺寸 + int height = FRONTSPACING + + m_toolWidget->height() + + (SPLITESPACE * 2) + + SPLITERSIZE + + m_dateTimeWidget->suitableSize(position).height() + + m_systemPuginWidget->suitableSize(position).height() + + m_quickIconWidget->suitableSize(position).height() + + m_trayView->suitableSize(position).height(); + + return QSize(-1, height); + } + // 上下的尺寸 + int width = FRONTSPACING + + m_toolWidget->width() + + (SPLITESPACE * 2) + + SPLITERSIZE + + m_dateTimeWidget->width() + + m_systemPuginWidget->width() + + m_quickIconWidget->width() + + m_trayView->width(); + return QSize(width, -1); +} + +QSize DockTrayWindow::suitableSize() const +{ + return suitableSize(m_position, 0, 0); +} + +void DockTrayWindow::layoutWidget() +{ + resizeTool(); +} + +void DockTrayWindow::resizeEvent(QResizeEvent *event) +{ + Q_EMIT requestUpdate(); + // 当尺寸发生变化的时候,通知托盘区域刷新尺寸,让托盘图标始终保持居中显示 + Q_EMIT m_delegate->sizeHintChanged(m_model->index(0, 0)); + QWidget::resizeEvent(event); + switch (m_position) { + case Dock::Position::Left: + case Dock::Position::Right: + m_toolLineLabel->setFixedSize(width() * 0.6, SPLITERSIZE); + break; + case Dock::Position::Top: + case Dock::Position::Bottom: + m_toolLineLabel->setFixedSize(SPLITERSIZE, height() * 0.6); + break; + } +} + +void DockTrayWindow::paintEvent(QPaintEvent *event) +{ + QWidget::paintEvent(event); + QPainter painter(this); + QColor color; + if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType) { + color = Qt::black; + painter.setOpacity(0.5); + } else { + color = Qt::white; + painter.setOpacity(0.1); + } + + painter.fillRect(m_toolLineLabel->geometry(), color); +} + +/** 根据任务栏的位置来更新布局的方向 + * @brief DockTrayWindow::updateLayout + * @param position + */ +void DockTrayWindow::updateLayout(const Dock::Position &position) +{ + switch (position) { + case Dock::Position::Left: + case Dock::Position::Right: { + m_mainBoxLayout->setDirection(QBoxLayout::BottomToTop); + m_toolLayout->setDirection(QBoxLayout::BottomToTop); + break; + } + case Dock::Position::Top: + case Dock::Position::Bottom: { + m_mainBoxLayout->setDirection(QBoxLayout::RightToLeft); + m_toolLayout->setDirection(QBoxLayout::RightToLeft); + break; + } + } +} + +void DockTrayWindow::resizeTool() const +{ + int toolSize = 0; + int size = 0; + if (m_position == Dock::Position::Left || m_position == Dock::Position::Right) + size = width(); + else + size = height(); + + for (int i = 0; i < m_toolLayout->count(); i++) { + QLayoutItem *layoutItem = m_toolLayout->itemAt(i); + if (!layoutItem) + continue; + + PluginsItem *toolWidget = qobject_cast(layoutItem->widget()); + if (!toolWidget) + continue; + + toolWidget->setFixedSize(size, size); + toolSize += size; + } + + if (m_position == Dock::Position::Left || m_position == Dock::Position::Right) + m_toolWidget->setFixedHeight(toolSize); + else + m_toolWidget->setFixedWidth(toolSize); +} + +bool DockTrayWindow::pluginExists(PluginsItemInterface *itemInter) const +{ + for (int i = 0; i < m_toolLayout->count(); i++) { + QLayoutItem *layoutItem = m_toolLayout->itemAt(i); + if (!layoutItem) + continue; + + PluginsItem *pluginItem = qobject_cast(layoutItem->widget()); + if (!pluginItem) + continue; + + if (pluginItem->pluginItem() == itemInter) + return true; + } + + return false; +} + +void DockTrayWindow::moveToolPlugin() +{ + for (int i = m_toolLayout->count() - 1; i >= 0; i--) { + QLayoutItem *layoutItem = m_toolLayout->itemAt(i); + if (!layoutItem) + continue; + + PluginsItem *pluginWidget = qobject_cast(layoutItem->widget()); + if (!pluginWidget) + continue; + + m_toolLayout->removeWidget(pluginWidget); + } + if (m_displayMode == Dock::DisplayMode::Efficient) { + // 如果当前是高效模式,则将所有的工具插件移动到当前的工具区域 + QuickSettingController *quickController = QuickSettingController::instance(); + QList plugins = quickController->pluginItems(QuickSettingController::PluginAttribute::Tool); + for (PluginsItemInterface *pluginInter : plugins) { + PluginsItem *pluginWidget = quickController->pluginItemWidget(pluginInter); + m_toolLayout->addWidget(pluginWidget); + } + } +} + +void DockTrayWindow::initUi() +{ + m_toolLayout->setContentsMargins(0, 0, 0, 0); + m_toolLayout->setSpacing(0); + + m_systemPuginWidget->setDisplayMode(Dock::DisplayMode::Efficient); + m_mainBoxLayout->setContentsMargins(0, 0, 0, 0); + m_mainBoxLayout->setSpacing(0); + m_mainBoxLayout->addSpacing(FRONTSPACING); + m_mainBoxLayout->addWidget(m_toolWidget); + m_mainBoxLayout->addSpacing(SPLITESPACE); + m_mainBoxLayout->addWidget(m_toolLineLabel); + m_mainBoxLayout->addSpacing(SPLITESPACE); + m_mainBoxLayout->addWidget(m_dateTimeWidget); + m_mainBoxLayout->addWidget(m_systemPuginWidget); + m_mainBoxLayout->addWidget(m_quickIconWidget); + m_mainBoxLayout->addWidget(m_trayView); + m_mainBoxLayout->setAlignment(m_toolLineLabel, Qt::AlignCenter); + + WinInfo info; + info.type = TrayIconType::EXPANDICON; + m_model->addRow(info); + m_trayView->openPersistentEditor(m_model->index(0, 0)); + + m_toolLineLabel->setFixedSize(0, 0); + + m_mainBoxLayout->addStretch(); +} + +void DockTrayWindow::initConnection() +{ + connect(m_systemPuginWidget, &SystemPluginWindow::itemChanged, this, &DockTrayWindow::onResetLayout); + connect(m_dateTimeWidget, &DateTimeDisplayer::requestUpdate, this, &DockTrayWindow::onResetLayout); + connect(m_quickIconWidget, &QuickPluginWindow::itemCountChanged, this, &DockTrayWindow::onResetLayout); + connect(m_trayView, &TrayGridView::requestRemove, this, &DockTrayWindow::onResetLayout); + + connect(QuickSettingController::instance(), &QuickSettingController::pluginInserted, this, [ this ] (PluginsItemInterface *itemInter, const QuickSettingController::PluginAttribute &pluginClass) { + if (pluginClass != QuickSettingController::PluginAttribute::Tool) + return; + + onItemAdded(itemInter); + }); + + connect(QuickSettingController::instance(), &QuickSettingController::pluginRemoved, this, &DockTrayWindow::onItemRemove); +} + +void DockTrayWindow::onResetLayout() +{ + switch(m_position) { + case Dock::Position::Left: + case Dock::Position::Right: { + m_dateTimeWidget->setFixedSize(QWIDGETSIZE_MAX, m_dateTimeWidget->suitableSize().height()); + m_systemPuginWidget->setFixedSize(QWIDGETSIZE_MAX, m_systemPuginWidget->suitableSize().height()); + m_quickIconWidget->setFixedSize(QWIDGETSIZE_MAX, m_quickIconWidget->suitableSize().height()); + m_trayView->setFixedSize(QWIDGETSIZE_MAX, m_trayView->suitableSize().height()); + break; + } + case Dock::Position::Top: + case Dock::Position::Bottom: { + m_dateTimeWidget->setFixedSize(m_dateTimeWidget->suitableSize().width(), QWIDGETSIZE_MAX); + m_systemPuginWidget->setFixedSize(m_systemPuginWidget->suitableSize().width(), QWIDGETSIZE_MAX); + m_quickIconWidget->setFixedSize(m_quickIconWidget->suitableSize().width(), QWIDGETSIZE_MAX); + m_trayView->setFixedSize(m_trayView->suitableSize().width(), QWIDGETSIZE_MAX); + break; + } + } + Q_EMIT requestUpdate(); +} + +void DockTrayWindow::onItemAdded(PluginsItemInterface *itemInter) +{ + if (m_displayMode != Dock::DisplayMode::Efficient || pluginExists(itemInter)) + return; + + QuickSettingController *quickController = QuickSettingController::instance(); + PluginsItem *pluginItem = quickController->pluginItemWidget(itemInter); + pluginItem->setVisible(true); + + m_toolLayout->addWidget(pluginItem); + + Q_EMIT requestUpdate(); +} + +void DockTrayWindow::onItemRemove(PluginsItemInterface *itemInter) +{ + for (int i = 0; i < m_toolLayout->count(); i++) { + QLayoutItem *layoutItem = m_toolLayout->itemAt(i); + if (!layoutItem) + continue; + + PluginsItem *pluginItem = qobject_cast(layoutItem->widget()); + if (!pluginItem || pluginItem->pluginItem() != itemInter) + continue; + + m_toolLayout->removeWidget(pluginItem); + Q_EMIT requestUpdate(); + break; + } +} diff --git a/frame/window/docktraywindow.h b/frame/window/docktraywindow.h new file mode 100644 index 000000000..fb1bffbbf --- /dev/null +++ b/frame/window/docktraywindow.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd. + * + * Author: donghualin + * + * Maintainer: donghualin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef DOCKTRAYWINDOW_H +#define DOCKTRAYWINDOW_H + +#include "constants.h" +#include "dbusutil.h" + +#include + +class QBoxLayout; +class SystemPluginWindow; +class DateTimeDisplayer; +class QuickPluginWindow; +class TrayGridView; +class TrayModel; +class TrayDelegate; +class PluginsItem; +class PluginsItemInterface; +class QLabel; + +class DockTrayWindow : public QWidget +{ + Q_OBJECT + +public: + explicit DockTrayWindow(DockInter *dockInter, QWidget *parent = nullptr); + + void setPositon(const Dock::Position &position); + void setDisplayMode(const Dock::DisplayMode &displayMode); + + QSize suitableSize(const Dock::Position &position, const int &, const double &) const; + QSize suitableSize() const; + + void layoutWidget(); + +Q_SIGNALS: + void requestUpdate(); + +protected: + void resizeEvent(QResizeEvent *event) override; + void paintEvent(QPaintEvent *event) override; + +private: + void initUi(); + void initConnection(); + void updateLayout(const Dock::Position &position); + void resizeTool() const; + bool pluginExists(PluginsItemInterface *itemInter) const; + void moveToolPlugin(); + +private Q_SLOTS: + void onResetLayout(); + void onItemAdded(PluginsItemInterface *itemInter); + void onItemRemove(PluginsItemInterface *itemInter); + +private: + DockInter *m_dockInter; + Dock::Position m_position; + Dock::DisplayMode m_displayMode; + QBoxLayout *m_mainBoxLayout; + QWidget *m_toolWidget; + QBoxLayout *m_toolLayout; + QLabel *m_toolLineLabel; + DateTimeDisplayer *m_dateTimeWidget; // 日期时间 + SystemPluginWindow *m_systemPuginWidget; // 固定区域-一般是右侧的电源按钮 + QuickPluginWindow *m_quickIconWidget; // 插件区域-包括网络、蓝牙等 + TrayGridView *m_trayView; // 托盘区域视图 + TrayModel *m_model; // 托盘区域的model + TrayDelegate *m_delegate; // 托盘区域的视图代理 +}; + +#endif // DOCKTRAYWINDOW_H diff --git a/frame/window/mainpanelcontrol.cpp b/frame/window/mainpanelcontrol.cpp index 8548449d1..15d6327d1 100755 --- a/frame/window/mainpanelcontrol.cpp +++ b/frame/window/mainpanelcontrol.cpp @@ -39,6 +39,7 @@ #include "mainwindow.h" #include "appmultiitem.h" #include "dockscreen.h" +#include "docktraywindow.h" #include #include @@ -97,7 +98,7 @@ MainPanelControl::MainPanelControl(DockInter *dockInter, QWidget *parent) , m_placeholderItem(nullptr) , m_appDragWidget(nullptr) , m_displayMode(Efficient) - , m_tray(nullptr) + , m_tray(new DockTrayWindow(dockInter, this)) , m_dockInter(dockInter) , m_recentHelper(new RecentAppHelper(m_appAreaSonWidget, m_recentAreaWidget, m_dockInter, this)) , m_toolHelper(new ToolAppHelper(m_pluginAreaWidget, m_toolSonAreaWidget, this)) @@ -181,22 +182,28 @@ void MainPanelControl::initUI() m_toolSonLayout->setContentsMargins(0, 0, 0, 0); m_toolAreaLayout->addWidget(m_toolSonAreaWidget); + // 添加托盘区域(包括托盘图标和插件)等 + m_tray->setObjectName("tray"); + m_mainPanelLayout->addWidget(m_tray); + + m_trayAreaWidget->setVisible(false); + m_pluginAreaWidget->setVisible(false); /* 托盘区域 */ - m_trayAreaWidget->setObjectName("trayarea"); + /*m_trayAreaWidget->setObjectName("trayarea"); m_trayAreaWidget->setLayout(m_trayAreaLayout); m_trayAreaLayout->setSpacing(0); m_trayAreaLayout->setContentsMargins(0, 10, 0, 10); m_mainPanelLayout->addWidget(m_trayAreaWidget); m_traySpliter->setObjectName("spliter_tray"); - m_mainPanelLayout->addWidget(m_traySpliter); + m_mainPanelLayout->addWidget(m_traySpliter);*/ /* 插件区域 */ - m_pluginAreaWidget->setObjectName("pluginarea"); + /*m_pluginAreaWidget->setObjectName("pluginarea"); m_pluginAreaWidget->setLayout(m_pluginLayout); m_pluginLayout->setSpacing(10); m_pluginLayout->setContentsMargins(0, 0, 0, 0); - m_mainPanelLayout->addWidget(m_pluginAreaWidget, 0, Qt::AlignCenter); + m_mainPanelLayout->addWidget(m_pluginAreaWidget, 0, Qt::AlignCenter);*/ /* 桌面预览 */ m_desktopWidget->setObjectName("showdesktoparea"); @@ -218,6 +225,7 @@ void MainPanelControl::initConnection() connect(m_toolHelper, &ToolAppHelper::requestUpdate, this, &MainPanelControl::requestUpdate); connect(m_toolHelper, &ToolAppHelper::toolVisibleChanged, this, &MainPanelControl::onToolVisibleChanged); connect(m_multiHelper, &MultiWindowHelper::requestUpdate, this, &MainPanelControl::requestUpdate); + connect(m_tray, &DockTrayWindow::requestUpdate, this, &MainPanelControl::onTrayRequestUpdate); } /** @@ -231,6 +239,7 @@ void MainPanelControl::setDisplayMode(DisplayMode dislayMode) m_displayMode = dislayMode; m_recentHelper->setDisplayMode(dislayMode); + m_tray->setDisplayMode(dislayMode); m_toolHelper->setDisplayMode(dislayMode); m_multiHelper->setDisplayMode(dislayMode); updateDisplayMode(); @@ -310,13 +319,13 @@ void MainPanelControl::addFixedAreaItem(int index, QWidget *wdg) * @param index 位置索引,如果为负数则插入到最后,为正则插入到指定位置 * @param wdg 应用指针对象 */ -void MainPanelControl::addTrayAreaItem(int index, QWidget *wdg) +/*void MainPanelControl::addTrayAreaItem(int index, QWidget *wdg) { m_tray = static_cast(wdg); m_trayAreaLayout->insertWidget(index, wdg); if (m_tray) m_tray->installEventFilter(this); -} +}*/ /**移除固定区域某一应用 * @brief MainPanelControl::removeFixedAreaItem @@ -437,10 +446,12 @@ void MainPanelControl::insertItem(int index, DockItem *item) m_recentHelper->addAppItem(index, item); break; case DockItem::TrayPlugin: // 此处只会有一个tray系统托盘插件,微信、声音、网络蓝牙等等,都在系统托盘插件中处理的 - addTrayAreaItem(index, item); - break; + //addTrayAreaItem(index, item); + return; + //break; case DockItem::Plugins: - m_toolHelper->addPluginItem(index, item); + //m_toolHelper->addPluginItem(index, item); + return; break; case DockItem::AppMultiWindow: m_multiHelper->addMultiWindow(index, static_cast(item)); @@ -695,8 +706,8 @@ bool MainPanelControl::eventFilter(QObject *watched, QEvent *event) // 但是子部件的模式变化函数在FashionTrayItem部件中的 // NormalContainer部件尺寸变化完成之前就已经结束,导致 // NormalContainer没有更新自己的尺寸,引起插件区域拥挤 - if (m_tray && watched == m_tray && event->type() == QEvent::Resize) - m_tray->pluginItem()->displayModeChanged(m_displayMode); + //if (m_tray && watched == m_tray && event->type() == QEvent::Resize) + //m_tray->pluginItem()->displayModeChanged(m_displayMode); // 更新应用区域大小和任务栏图标大小 if (watched == m_appAreaSonWidget) { @@ -980,11 +991,11 @@ void MainPanelControl::updateModeChange() m_traySpliter->setVisible(m_displayMode == DisplayMode::Efficient); m_pluginAreaWidget->setVisible(m_displayMode == DisplayMode::Efficient); m_toolAreaWidget->setVisible(m_displayMode == DisplayMode::Fashion); + m_toolSonAreaWidget->setVisible(m_displayMode == DisplayMode::Fashion); onRecentVisibleChanged(m_recentHelper->recentIsVisible()); onDockAppVisibleChanged(m_recentHelper->dockAppIsVisible()); onToolVisibleChanged(m_toolHelper->toolIsVisible()); - if (m_tray) - m_tray->setVisible(m_displayMode == DisplayMode::Efficient); + m_tray->setVisible(m_displayMode == DisplayMode::Efficient); } /**把驻留应用和被打开的应用所在窗口移动到指定位置 @@ -1224,9 +1235,10 @@ void MainPanelControl::resizeDockIcon() } else { int totalLength = ((m_position == Position::Top) || (m_position == Position::Bottom)) ? width() : height(); // 减去托盘间隔区域 - if (m_tray) { + /*if (m_tray) { totalLength -= (m_tray->trayVisibleItemCount() + 1) * 10; - } + }*/ + totalLength -= m_tray->width(); // 减去3个分割线的宽度 totalLength -= 3 * SPLITER_SIZE; // 减去显示桌面图标宽度 @@ -1265,9 +1277,9 @@ void MainPanelControl::resizeDockIcon() return; // 参与计算的插件的个数包含托盘和插件 - int pluginCount = m_tray ? m_tray->trayVisibleItemCount() + calcPluginItemCount : calcPluginItemCount; +// int pluginCount = m_tray ? m_tray->trayVisibleItemCount() + calcPluginItemCount : calcPluginItemCount; // 需要计算的图标总数 - int iconCount = m_fixedAreaLayout->count() + m_appAreaSonLayout->count() + pluginCount; + int iconCount = m_fixedAreaLayout->count() + m_appAreaSonLayout->count()/* + pluginCount*/; if (iconCount <= 0) return; @@ -1290,8 +1302,8 @@ void MainPanelControl::resizeDockIcon() tray_item_size = 20; // 减去插件图标的大小后重新计算固定图标和应用图标的平均大小 - totalLength -= tray_item_size * pluginCount; - iconCount -= pluginCount; + totalLength -= m_tray->width();//tray_item_size * pluginCount; + //iconCount -= pluginCount; // 余数 yu = (totalLength % iconCount); @@ -1408,8 +1420,8 @@ void MainPanelControl::calcuDockIconSize(int w, int h, int traySize) } } - if (m_tray) - m_tray->centralWidget()->setProperty("iconSize", traySize); + /*if (m_tray) + m_tray->centralWidget()->setProperty("iconSize", traySize);*/ // 因为日期时间大小和其他插件大小有异,为了设置边距,在各插件中增加了一层布局 // 因此需要通过多一层布局来获取各插件 @@ -1502,6 +1514,15 @@ void MainPanelControl::onToolVisibleChanged(bool visible) m_recentSpliter->setVisible(visible); } +void MainPanelControl::onTrayRequestUpdate() +{ + m_tray->layoutWidget(); + if (m_position == Dock::Position::Left || m_position == Dock::Position::Right) + m_tray->setFixedHeight(m_tray->suitableSize().height()); + else + m_tray->setFixedWidth(m_tray->suitableSize().width()); +} + /**时尚模式没有‘显示桌面’区域 * @brief MainPanelControl::resizeDesktopWidget */ diff --git a/frame/window/mainpanelcontrol.h b/frame/window/mainpanelcontrol.h index cf4c7cc20..34d1c9cf5 100755 --- a/frame/window/mainpanelcontrol.h +++ b/frame/window/mainpanelcontrol.h @@ -31,7 +31,7 @@ using namespace Dock; class QBoxLayout; class QLabel; -class TrayPluginItem; +class DockTrayWindow; class PluginsItem; class DockItem; class PlaceholderItem; @@ -77,7 +77,7 @@ private: void addFixedAreaItem(int index, QWidget *wdg); void removeFixedAreaItem(QWidget *wdg); void removeAppAreaItem(QWidget *wdg); - void addTrayAreaItem(int index, QWidget *wdg); + //void addTrayAreaItem(int index, QWidget *wdg); void removeTrayAreaItem(QWidget *wdg); int getScreenSize() const; @@ -97,6 +97,7 @@ private Q_SLOTS: void onRecentVisibleChanged(bool visible); void onDockAppVisibleChanged(bool visible); void onToolVisibleChanged(bool visible); + void onTrayRequestUpdate(); protected: void dragMoveEvent(QDragMoveEvent *e) override; @@ -142,7 +143,7 @@ private: AppDragWidget *m_appDragWidget; DisplayMode m_displayMode; QPoint m_mousePressPos; - TrayPluginItem *m_tray; + DockTrayWindow *m_tray; int m_dragIndex = -1; // 记录应用区域被拖拽图标的位置 DockInter *m_dockInter; diff --git a/frame/window/quickpluginwindow.cpp b/frame/window/quickpluginwindow.cpp index 40604d604..66e9af47a 100644 --- a/frame/window/quickpluginwindow.cpp +++ b/frame/window/quickpluginwindow.cpp @@ -70,13 +70,13 @@ void QuickPluginWindow::initUi() m_mainLayout->setDirection(QBoxLayout::RightToLeft); m_mainLayout->setContentsMargins(ITEMSPACE, 0, ITEMSPACE, 0); m_mainLayout->setSpacing(ITEMSPACE); - const QList &items = QuickSettingController::instance()->settingItems(); - for (QuickSettingItem *settingItem : items) { - const QString pluginName = settingItem->pluginItem()->pluginName(); + QList items = QuickSettingController::instance()->pluginItems(QuickSettingController::PluginAttribute::Quick); + for (PluginsItemInterface *pluginItem : items) { + const QString pluginName = pluginItem->pluginName(); if (!fixedPluginNames.contains(pluginName)) continue; - addPlugin(settingItem); + addPlugin(pluginItem); } } @@ -137,8 +137,11 @@ QSize QuickPluginWindow::suitableSize() const return suitableSize(m_position); } -void QuickPluginWindow::addPlugin(QuickSettingItem *item) +void QuickPluginWindow::addPlugin(PluginsItemInterface *pluginItem) { + if (!isQuickPlugin(pluginItem)) + return; + for (int i = 0; i < m_mainLayout->count(); i++) { QLayoutItem *layoutItem = m_mainLayout->itemAt(i); if (!layoutItem) @@ -148,14 +151,14 @@ void QuickPluginWindow::addPlugin(QuickSettingItem *item) if (!dockItem) continue; - if (item->pluginItem() == dockItem->pluginItem()) { + if (pluginItem == dockItem->pluginItem()) { resetPluginDisplay(); return; } } - if (fixedPluginNames.contains(item->pluginItem()->pluginName())) { + if (fixedPluginNames.contains(pluginItem->pluginName())) { // 新插入的插件如果是固定插件,则将其插入到固定插件列表中,并对其进行排序 - m_fixedSettingItems << item->pluginItem(); + m_fixedSettingItems << pluginItem; qSort(m_fixedSettingItems.begin(), m_fixedSettingItems.end(), [](PluginsItemInterface *item1, PluginsItemInterface *item2) { int index1 = fixedPluginNames.indexOf(item1->pluginName()); int index2 = fixedPluginNames.indexOf(item2->pluginName()); @@ -163,7 +166,7 @@ void QuickPluginWindow::addPlugin(QuickSettingItem *item) }); } else { // 如果是非固定插件,则直接插入到末尾 - m_activeSettingItems << item->pluginItem(); + m_activeSettingItems << pluginItem; } resetPluginDisplay(); Q_EMIT itemCountChanged(); @@ -319,6 +322,15 @@ QuickDockItem *QuickPluginWindow::getDockItemByPlugin(PluginsItemInterface *item return nullptr; } +bool QuickPluginWindow::isQuickPlugin(PluginsItemInterface *pluginItem) +{ + QJsonObject metaData = QuickSettingController::instance()->metaData(pluginItem); + if (metaData.contains("tool")) + return !metaData.value("tool").toBool(); + + return true; +} + int QuickPluginWindow::getDropIndex(QPoint point) { QuickDockItem *targetItem = getDockItemByPlugin(findQuickSettingItem(point, m_activeSettingItems)); @@ -435,6 +447,7 @@ void QuickPluginWindow::resetPluginDisplay() } // 将列表中所有的控件按照顺序添加到布局上 auto addWidget = [ = ](const QList &items) { + QuickSettingController *quickController = QuickSettingController::instance(); for (PluginsItemInterface *item : items) { QuickDockItem *itemWidget = nullptr; if (pluginItems.contains(item)) { @@ -445,7 +458,7 @@ void QuickPluginWindow::resetPluginDisplay() if (pluginLoader) metaData = pluginLoader->metaData().value("MetaData").toObject(); - itemWidget = new QuickDockItem(item, metaData, this); + itemWidget = new QuickDockItem(item, metaData, quickController->itemKey(item), this); itemWidget->setFixedSize(ICONWIDTH, ICONHEIGHT); } connect(itemWidget, &QuickDockItem::clicked, this, &QuickPluginWindow::onFixedClick); @@ -460,16 +473,19 @@ void QuickPluginWindow::resetPluginDisplay() void QuickPluginWindow::initConnection() { - connect(QuickSettingController::instance(), &QuickSettingController::pluginInserted, this, [ this ](QuickSettingItem * settingItem) { - const QString pluginName = settingItem->pluginItem()->pluginName(); + connect(QuickSettingController::instance(), &QuickSettingController::pluginInserted, this, [ this ](PluginsItemInterface *itemInter, const QuickSettingController::PluginAttribute &pluginClass) { + if (pluginClass != QuickSettingController::PluginAttribute::Quick) + return; + + const QString pluginName = itemInter->pluginName(); if (!fixedPluginNames.contains(pluginName)) return; - addPlugin(settingItem); + addPlugin(itemInter); }); - connect(QuickSettingController::instance(), &QuickSettingController::pluginRemoved, this, [ this ] (QuickSettingItem *settingItem){ - removePlugin(settingItem->pluginItem()); + connect(QuickSettingController::instance(), &QuickSettingController::pluginRemoved, this, [ this ] (PluginsItemInterface *itemInter){ + removePlugin(itemInter); }); connect(QuickSettingController::instance(), &QuickSettingController::pluginUpdated, this, &QuickPluginWindow::onUpdatePlugin); @@ -480,10 +496,11 @@ void QuickPluginWindow::initConnection() * @param pluginItem * @param parent */ -QuickDockItem::QuickDockItem(PluginsItemInterface *pluginItem, const QJsonObject &metaData, QWidget *parent) +QuickDockItem::QuickDockItem(PluginsItemInterface *pluginItem, const QJsonObject &metaData, const QString itemKey, QWidget *parent) : QWidget(parent) , m_pluginItem(pluginItem) , m_metaData(metaData) + , m_itemKey(itemKey) { } @@ -509,8 +526,7 @@ void QuickDockItem::paintEvent(QPaintEvent *event) if (!m_pluginItem) return QWidget::paintEvent(event); - int pixmapSize = static_cast(ICONHEIGHT * qApp->devicePixelRatio()); - QPixmap pixmap = m_pluginItem->icon(DockPart::QuickPanel).pixmap(pixmapSize, pixmapSize); + QPixmap pixmap = iconPixmap(); QRect pixmapRect = QRect((rect().width() - ICONHEIGHT) / 2, (rect().height() - ICONHEIGHT) / 2, ICONHEIGHT, ICONHEIGHT); @@ -523,3 +539,19 @@ void QuickDockItem::mouseReleaseEvent(QMouseEvent *event) Q_EMIT clicked(); QWidget::mouseReleaseEvent(event); } + +QPixmap QuickDockItem::iconPixmap() const +{ + int pixmapSize = static_cast(ICONHEIGHT * qApp->devicePixelRatio()); + QIcon icon = m_pluginItem->icon(DockPart::QuickShow); + if (!icon.isNull()) + return icon.pixmap(pixmapSize, pixmapSize); + + QWidget *itemWidget = m_pluginItem->itemWidget(m_itemKey); + if (itemWidget) { + itemWidget->setFixedSize(ICONWIDTH, ICONHEIGHT); + return itemWidget->grab(); + } + + return QPixmap(); +} diff --git a/frame/window/quickpluginwindow.h b/frame/window/quickpluginwindow.h index a873e0882..44da684b4 100644 --- a/frame/window/quickpluginwindow.h +++ b/frame/window/quickpluginwindow.h @@ -62,7 +62,7 @@ protected: void mousePressEvent(QMouseEvent *event) override; private Q_SLOTS: - void addPlugin(QuickSettingItem *item); + void addPlugin(PluginsItemInterface *pluginItem); void removePlugin(PluginsItemInterface *item); void onPluginDropItem(QDropEvent *event); void onPluginDragMove(QDragMoveEvent *event); @@ -79,6 +79,7 @@ private: void resetPluginDisplay(); QPoint popupPoint() const; QuickDockItem *getDockItemByPlugin(PluginsItemInterface *item); + bool isQuickPlugin(PluginsItemInterface *pluginItem); private: QBoxLayout *m_mainLayout; @@ -93,7 +94,7 @@ class QuickDockItem : public QWidget Q_OBJECT public: - explicit QuickDockItem(PluginsItemInterface *pluginItem, const QJsonObject &metaData, QWidget *parent = nullptr); + explicit QuickDockItem(PluginsItemInterface *pluginItem, const QJsonObject &metaData, const QString itemKey, QWidget *parent = nullptr); ~QuickDockItem(); PluginsItemInterface *pluginItem(); @@ -106,9 +107,12 @@ protected: void paintEvent(QPaintEvent *event); void mouseReleaseEvent(QMouseEvent *event); + QPixmap iconPixmap() const; + private: PluginsItemInterface *m_pluginItem; QJsonObject m_metaData; + QString m_itemKey; }; #endif // QUICKPLUGINWINDOW_H diff --git a/frame/window/quicksettingcontainer.cpp b/frame/window/quicksettingcontainer.cpp index 82205c1bd..2d7e36fed 100644 --- a/frame/window/quicksettingcontainer.cpp +++ b/frame/window/quicksettingcontainer.cpp @@ -144,12 +144,14 @@ void QuickSettingContainer::setPosition(Position position) } } -void QuickSettingContainer::initQuickItem(QuickSettingItem *quickItem) +void QuickSettingContainer::initQuickItem(PluginsItemInterface *plugin) { + QuickSettingItem *quickItem = new QuickSettingItem(plugin, m_pluginLoader->itemKey(plugin), m_pluginLoader->metaData(plugin)); quickItem->setParent(m_pluginWidget); quickItem->setMouseTracking(true); quickItem->installEventFilter(this); connect(quickItem, &QuickSettingItem::detailClicked, this, &QuickSettingContainer::onItemDetailClick); + m_quickSettings << quickItem; } void QuickSettingContainer::onItemDetailClick(PluginsItemInterface *pluginInter) @@ -181,19 +183,31 @@ void QuickSettingContainer::showWidget(QWidget *widget, const QString &title) m_switchLayout->setCurrentWidget(m_childPage); } -void QuickSettingContainer::onPluginInsert(QuickSettingItem *quickItem) +void QuickSettingContainer::onPluginInsert(PluginsItemInterface * itemInter) { - initQuickItem(quickItem); + initQuickItem(itemInter); updateItemLayout(); onResizeView(); } -void QuickSettingContainer::onPluginRemove(QuickSettingItem *quickItem) +void QuickSettingContainer::onPluginRemove(PluginsItemInterface * itemInter) { + QuickSettingItem *quickItem = nullptr; + for (QuickSettingItem *settingItem : m_quickSettings) { + if (settingItem->pluginItem() != itemInter) + continue; + + quickItem = settingItem; + break; + } + if (!quickItem) + return; + disconnect(quickItem, &QuickSettingItem::detailClicked, this, &QuickSettingContainer::onItemDetailClick); quickItem->setParent(nullptr); quickItem->removeEventFilter(this); quickItem->setMouseTracking(false); + quickItem->deleteLater(); //调整子控件的位置 updateItemLayout(); @@ -258,8 +272,7 @@ void QuickSettingContainer::updateItemLayout() int row = 0; int column = 0; - QList quickSettings = m_pluginLoader->settingItems(); - for (QuickSettingItem *item : quickSettings) { + for (QuickSettingItem *item : m_quickSettings) { int usedColumn = item->isPrimary() ? 2 : 1; m_pluginLayout->addWidget(item, row, column, 1, usedColumn); column += usedColumn; @@ -309,9 +322,9 @@ void QuickSettingContainer::initUi() m_mainlayout->addWidget(m_componentWidget); // 加载所有的插件 - QList pluginItems = m_pluginLoader->settingItems(); - for (QuickSettingItem *quickItem: pluginItems) - initQuickItem(quickItem); + QList plugins = m_pluginLoader->pluginItems(QuickSettingController::PluginAttribute::Quick); + for (PluginsItemInterface *plugin : plugins) + initQuickItem(plugin); m_switchLayout->addWidget(m_mainWidget); m_switchLayout->addWidget(m_childPage); @@ -322,7 +335,7 @@ void QuickSettingContainer::initUi() setAcceptDrops(true); QMetaObject::invokeMethod(this, [ = ] { - if (pluginItems.size() > 0) + if (plugins.size() > 0) updateItemLayout(); // 设置当前窗口的大小 onResizeView(); @@ -334,7 +347,12 @@ void QuickSettingContainer::initUi() void QuickSettingContainer::initConnection() { - connect(m_pluginLoader, &QuickSettingController::pluginInserted, this, &QuickSettingContainer::onPluginInsert); + connect(m_pluginLoader, &QuickSettingController::pluginInserted, this, [ = ](PluginsItemInterface *itemInter, const QuickSettingController::PluginAttribute &pluginClass) { + if (pluginClass != QuickSettingController::PluginAttribute::Quick) + return; + + onPluginInsert(itemInter); + }); connect(m_pluginLoader, &QuickSettingController::pluginRemoved, this, &QuickSettingContainer::onPluginRemove); connect(m_playerWidget, &MediaWidget::visibleChanged, this, &QuickSettingContainer::onResizeView); connect(m_volumnWidget, &VolumeWidget::visibleChanged, this, &QuickSettingContainer::onResizeView); @@ -363,9 +381,8 @@ void QuickSettingContainer::initConnection() void QuickSettingContainer::onResizeView() { if (m_switchLayout->currentWidget() == m_mainWidget) { - QList pluginItems = m_pluginLoader->settingItems(); int selfPluginCount = 0; - for (QuickSettingItem *item : pluginItems) { + for (QuickSettingItem *item : m_quickSettings) { // 如果是置顶的插件,则认为它占用两个普通插件的位置 int increCount = (item->isPrimary() ? 2 : 1); selfPluginCount += increCount; diff --git a/frame/window/quicksettingcontainer.h b/frame/window/quicksettingcontainer.h index 91e077351..fec0ab53c 100644 --- a/frame/window/quicksettingcontainer.h +++ b/frame/window/quicksettingcontainer.h @@ -66,8 +66,8 @@ protected: void showHomePage(); private Q_SLOTS: - void onPluginInsert(QuickSettingItem *quickItem); - void onPluginRemove(QuickSettingItem *quickItem); + void onPluginInsert(PluginsItemInterface * itemInter); + void onPluginRemove(PluginsItemInterface * itemInter); void onItemDetailClick(PluginsItemInterface *pluginInter); bool eventFilter(QObject *watched, QEvent *event) override; void onResizeView(); @@ -80,7 +80,7 @@ private: // 调整控件位置 void updateItemLayout(); // 初始化控件项目 - void initQuickItem(QuickSettingItem *quickItem); + void initQuickItem(PluginsItemInterface *plugin); // 显示具体的窗体 void showWidget(QWidget *widget, const QString &title); // 清除移动轨迹 @@ -106,6 +106,7 @@ private: DisplaySettingWidget *m_displaySettingWidget; PluginChildPage *m_childPage; QPoint m_dragPluginPosition; + QList m_quickSettings; }; class QuickPluginMimeData : public QMimeData diff --git a/frame/window/systempluginwindow.cpp b/frame/window/systempluginwindow.cpp index d725d0ea7..6f67873b0 100644 --- a/frame/window/systempluginwindow.cpp +++ b/frame/window/systempluginwindow.cpp @@ -21,7 +21,7 @@ #include "systempluginwindow.h" #include "systemplugincontroller.h" #include "systempluginitem.h" -#include "fixedplugincontroller.h" +#include "quicksettingcontroller.h" #include #include @@ -35,21 +35,33 @@ SystemPluginWindow::SystemPluginWindow(QWidget *parent) : QWidget(parent) - , m_pluginController(new FixedPluginController(this)) , m_listView(new DListView(this)) + , m_displayMode(Dock::DisplayMode::Efficient) , m_position(Dock::Position::Bottom) , m_mainLayout(new QBoxLayout(QBoxLayout::Direction::LeftToRight, this)) { initUi(); - connect(m_pluginController, &FixedPluginController::pluginItemInserted, this, &SystemPluginWindow::onPluginItemAdded); - connect(m_pluginController, &FixedPluginController::pluginItemRemoved, this, &SystemPluginWindow::onPluginItemRemoved); - connect(m_pluginController, &FixedPluginController::pluginItemUpdated, this, &SystemPluginWindow::onPluginItemUpdated); + initConnection(); } SystemPluginWindow::~SystemPluginWindow() { } +void SystemPluginWindow::setDisplayMode(const DisplayMode &displayMode) +{ + m_displayMode = displayMode; + + QObjectList childObjects = children(); + for (QObject *childObject : childObjects) { + StretchPluginsItem *item = qobject_cast(childObject); + if (!item) + continue; + + item->setDisplayMode(displayMode); + } +} + void SystemPluginWindow::setPositon(Position position) { if (m_position == position) @@ -111,46 +123,66 @@ void SystemPluginWindow::initUi() m_mainLayout->setSpacing(0); } -bool SystemPluginWindow::pluginExist(StretchPluginsItem *pluginItem) +void SystemPluginWindow::initConnection() +{ + QuickSettingController *quickController = QuickSettingController::instance(); + connect(quickController, &QuickSettingController::pluginInserted, this, [ = ](PluginsItemInterface *itemInter, const QuickSettingController::PluginAttribute &pluginClass) { + if (pluginClass != QuickSettingController::PluginAttribute::Fixed) + return; + + pluginAdded(itemInter); + }); + + connect(quickController, &QuickSettingController::pluginRemoved, this, &SystemPluginWindow::onPluginItemRemoved); + connect(quickController, &QuickSettingController::pluginUpdated, this, &SystemPluginWindow::onPluginItemUpdated); + + QList plugins = quickController->pluginItems(QuickSettingController::PluginAttribute::Fixed); + for (int i = 0; i < plugins.size(); i++) + pluginAdded(plugins[i]); +} + +StretchPluginsItem *SystemPluginWindow::findPluginItemWidget(PluginsItemInterface *pluginItem) { for (int i = 0; i < m_mainLayout->count(); i++) { QLayoutItem *layoutItem = m_mainLayout->itemAt(i); if (!layoutItem) continue; - if (layoutItem->widget() == pluginItem) - return true; + StretchPluginsItem *itemWidget = qobject_cast(layoutItem->widget()); + if (itemWidget && itemWidget->pluginInter() == pluginItem) + return itemWidget; } - return false; + return nullptr; } -void SystemPluginWindow::onPluginItemAdded(StretchPluginsItem *pluginItem) +void SystemPluginWindow::pluginAdded(PluginsItemInterface *plugin) { - if (pluginExist(pluginItem)) - return; - - pluginItem->setPosition(m_position); - pluginItem->setParent(this); - pluginItem->show(); - m_mainLayout->addWidget(pluginItem); + StretchPluginsItem *item = new StretchPluginsItem(plugin, QuickSettingController::instance()->itemKey(plugin)); + item->setDisplayMode(m_displayMode); + item->setPosition(m_position); + item->setParent(this); + item->show(); + m_mainLayout->addWidget(item); Q_EMIT itemChanged(); } -void SystemPluginWindow::onPluginItemRemoved(StretchPluginsItem *pluginItem) +void SystemPluginWindow::onPluginItemRemoved(PluginsItemInterface *pluginItem) { - if (!pluginExist(pluginItem)) - return; - - pluginItem->setParent(nullptr); - pluginItem->hide(); - m_mainLayout->removeWidget(pluginItem); - Q_EMIT itemChanged(); + StretchPluginsItem *item = findPluginItemWidget(pluginItem); + if (item) { + item->setParent(nullptr); + item->hide(); + m_mainLayout->removeWidget(item); + Q_EMIT itemChanged(); + } } -void SystemPluginWindow::onPluginItemUpdated(StretchPluginsItem *pluginItem) +void SystemPluginWindow::onPluginItemUpdated(PluginsItemInterface *pluginItem) { - pluginItem->update(); + StretchPluginsItem *item = findPluginItemWidget(pluginItem); + if (item) + item->update(); } #define ICONSIZE 20 @@ -161,6 +193,7 @@ StretchPluginsItem::StretchPluginsItem(PluginsItemInterface * const pluginInter, : DockItem(parent) , m_pluginInter(pluginInter) , m_itemKey(itemKey) + , m_displayMode(Dock::DisplayMode::Efficient) , m_position(Dock::Position::Bottom) { } @@ -169,6 +202,11 @@ StretchPluginsItem::~StretchPluginsItem() { } +void StretchPluginsItem::setDisplayMode(const DisplayMode &displayMode) +{ + m_displayMode = displayMode; +} + void StretchPluginsItem::setPosition(Position position) { m_position = position; @@ -260,6 +298,9 @@ QFont StretchPluginsItem::textFont(const Position &position) const bool StretchPluginsItem::needShowText() const { + // 如果是高效模式,则不需要显示下面的文本 + if (m_displayMode == Dock::DisplayMode::Efficient) + return false; // 任务栏在上方或者下方显示的时候,根据设计图,只有在当前区域高度大于50的时候才同时显示文本和图标 if (m_position == Dock::Position::Top || m_position == Dock::Position::Bottom) return height() >= 50; diff --git a/frame/window/systempluginwindow.h b/frame/window/systempluginwindow.h index 0e92f0864..67af5bddc 100644 --- a/frame/window/systempluginwindow.h +++ b/frame/window/systempluginwindow.h @@ -26,7 +26,6 @@ #include -class FixedPluginController; class StretchPluginsItem; class QBoxLayout; class PluginsItemInterface; @@ -42,6 +41,7 @@ class SystemPluginWindow : public QWidget public: explicit SystemPluginWindow(QWidget *parent = nullptr); ~SystemPluginWindow() override; + void setDisplayMode(const Dock::DisplayMode &displayMode); void setPositon(Dock::Position position); QSize suitableSize() const; QSize suitableSize(const Dock::Position &position) const; @@ -51,16 +51,17 @@ Q_SIGNALS: private: void initUi(); - bool pluginExist(StretchPluginsItem *pluginItem); + void initConnection(); + StretchPluginsItem *findPluginItemWidget(PluginsItemInterface *pluginItem); + void pluginAdded(PluginsItemInterface *plugin); private Q_SLOTS: - void onPluginItemAdded(StretchPluginsItem *pluginItem); - void onPluginItemRemoved(StretchPluginsItem *pluginItem); - void onPluginItemUpdated(StretchPluginsItem *pluginItem); + void onPluginItemRemoved(PluginsItemInterface *pluginItem); + void onPluginItemUpdated(PluginsItemInterface *pluginItem); private: - FixedPluginController *m_pluginController; DListView *m_listView; + Dock::DisplayMode m_displayMode; Dock::Position m_position; QBoxLayout *m_mainLayout; }; @@ -72,6 +73,7 @@ class StretchPluginsItem : public DockItem public: StretchPluginsItem(PluginsItemInterface *const pluginInter, const QString &itemKey, QWidget *parent = nullptr); ~StretchPluginsItem() override; + void setDisplayMode(const Dock::DisplayMode &displayMode); void setPosition(Dock::Position position); PluginsItemInterface *pluginInter() const; QString itemKey() const; @@ -97,6 +99,7 @@ private: private: PluginsItemInterface *m_pluginInter; QString m_itemKey; + Dock::DisplayMode m_displayMode; Dock::Position m_position; QPoint m_mousePressPoint; }; diff --git a/frame/window/tray/widgets/expandiconwidget.cpp b/frame/window/tray/widgets/expandiconwidget.cpp index 0c858a142..2c5b89fb8 100644 --- a/frame/window/tray/widgets/expandiconwidget.cpp +++ b/frame/window/tray/widgets/expandiconwidget.cpp @@ -39,18 +39,11 @@ ExpandIconWidget::ExpandIconWidget(QWidget *parent, Qt::WindowFlags f) : BaseTrayWidget(parent, f) , m_regionInter(new DRegionMonitor(this)) , m_position(Dock::Position::Bottom) - , m_gridParentView(new RoundWidget(nullptr)) - , m_trayView(new TrayGridView(m_gridParentView)) - , m_trayDelegate(new TrayDelegate(m_trayView, m_trayView)) - , m_trayModel(new TrayModel(m_trayView, true, false)) { - initUi(); - initConnection(); } ExpandIconWidget::~ExpandIconWidget() { - m_gridParentView->deleteLater(); } void ExpandIconWidget::setPositonValue(Dock::Position position) @@ -69,17 +62,19 @@ void ExpandIconWidget::sendClick(uint8_t mouseButton, int x, int y) if (mouseButton != XCB_BUTTON_INDEX_1) return; - setTrayPanelVisible(!m_gridParentView->isVisible()); + QWidget *gridParentView = popupTrayView(); + setTrayPanelVisible(!gridParentView->isVisible()); } void ExpandIconWidget::setTrayPanelVisible(bool visible) { + QWidget *gridParentView = popupTrayView(); if (visible) { resetPosition(); - m_gridParentView->show(); + gridParentView->show(); m_regionInter->registerRegion(); } else { - m_gridParentView->hide(); + gridParentView->hide(); m_regionInter->unregisterRegion(); } } @@ -89,8 +84,11 @@ QPixmap ExpandIconWidget::icon() return QPixmap(dropIconFile()); } -void ExpandIconWidget::paintEvent(QPaintEvent *) +void ExpandIconWidget::paintEvent(QPaintEvent *event) { + if (popupTrayView()->trayView()->model()->rowCount() == 0) + return BaseTrayWidget::paintEvent(event); + QPainter painter(this); QPixmap pixmap = ImageUtil::loadSvg(dropIconFile(), QSize(ICON_SIZE, ICON_SIZE)); QRect rectOfPixmap(rect().x() + (rect().width() - ICON_SIZE) / 2, @@ -129,9 +127,72 @@ const QString ExpandIconWidget::dropIconFile() const return iconFile + ".svg"; } -QWidget *ExpandIconWidget::popupTrayView() +TrayGridWidget *ExpandIconWidget::popupTrayView() { - return m_gridParentView; + static TrayGridWidget *gridParentView = nullptr; + if (gridParentView) + return gridParentView; + + gridParentView = new TrayGridWidget(nullptr); + TrayGridView *trayView = new TrayGridView(gridParentView); + TrayDelegate *trayDelegate = new TrayDelegate(trayView, trayView); + TrayModel *trayModel = new TrayModel(trayView, true, false); + gridParentView->setTrayGridView(trayView); + + gridParentView->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); + trayView->setModel(trayModel); + trayView->setItemDelegate(trayDelegate); + trayView->setSpacing(ITEM_SPACING); + trayView->setDragDistance(2); + + QVBoxLayout *layout = new QVBoxLayout(gridParentView); + layout->setContentsMargins(ITEM_SPACING, ITEM_SPACING, ITEM_SPACING, ITEM_SPACING); + layout->setSpacing(0); + layout->addWidget(trayView); + + auto rowCountChanged = [ = ] { + int count = trayModel->rowCount(); + trayView->setFixedSize(trayView->suitableSize()); + gridParentView->setFixedSize(trayView->size() + QSize(ITEM_SPACING * 2, ITEM_SPACING * 2)); + if (count > 0) + resetPosition(); + else if (gridParentView->isVisible()) + gridParentView->hide(); + + Q_EMIT trayVisbleChanged(count > 0); + }; + + connect(trayView, &TrayGridView::rowCountChanged, this, rowCountChanged); + + connect(trayDelegate, &TrayDelegate::removeRow, this, [ = ](const QModelIndex &index) { + trayView->model()->removeRow(index.row(),index.parent()); + }); + connect(trayView, &TrayGridView::requestRemove, trayModel, &TrayModel::removeRow); + connect(m_regionInter, &DRegionMonitor::buttonPress, this, [ = ](const QPoint &mousePos, const int flag) { + // 如果当前是隐藏,那么在点击任何地方都隐藏 + if (!isVisible()) { + gridParentView->hide(); + return; + } + + if ((flag != DRegionMonitor::WatchedFlags::Button_Left) && (flag != DRegionMonitor::WatchedFlags::Button_Right)) + return; + + QPoint ptPos = parentWidget()->mapToGlobal(this->pos()); + const QRect rect = QRect(ptPos, size()); + if (rect.contains(mousePos)) + return; + + const QRect rctView(gridParentView->pos(), gridParentView->size()); + if (rctView.contains(mousePos)) + return; + + gridParentView->hide(); + }); + + QMetaObject::invokeMethod(this, rowCountChanged, Qt::QueuedConnection); + + return gridParentView; } void ExpandIconWidget::resetPosition() @@ -139,91 +200,29 @@ void ExpandIconWidget::resetPosition() if (!parentWidget()) return; + QWidget *gridParentView = popupTrayView(); QPoint ptPos = parentWidget()->mapToGlobal(this->pos()); switch (m_position) { case Dock::Position::Bottom: { - ptPos.setY(ptPos.y() - m_gridParentView->height()); - ptPos.setX(ptPos.x() - m_gridParentView->width()); + ptPos.setY(ptPos.y() - gridParentView->height()); + ptPos.setX(ptPos.x() - gridParentView->width()); break; } case Dock::Position::Top: { - ptPos.setY(ptPos.y() + m_gridParentView->height()); - ptPos.setX(ptPos.x() - m_gridParentView->width()); + ptPos.setY(ptPos.y() + gridParentView->height()); + ptPos.setX(ptPos.x() - gridParentView->width()); break; } case Dock::Position::Left: { - ptPos.setX(ptPos.x() + m_gridParentView->width() / 2); + ptPos.setX(ptPos.x() + gridParentView->width() / 2); break; } case Dock::Position::Right: { - ptPos.setX(ptPos.x() - m_gridParentView->width() / 2); + ptPos.setX(ptPos.x() - gridParentView->width() / 2); break; } } - m_gridParentView->move(ptPos); -} - -void ExpandIconWidget::initUi() -{ - m_gridParentView->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); - m_trayView->setModel(m_trayModel); - m_trayView->setItemDelegate(m_trayDelegate); - m_trayView->setSpacing(ITEM_SPACING); - m_trayView->setDragDistance(2); - - QVBoxLayout *layout = new QVBoxLayout(m_gridParentView); - layout->setContentsMargins(ITEM_SPACING, ITEM_SPACING, ITEM_SPACING, ITEM_SPACING); - layout->setSpacing(0); - layout->addWidget(m_trayView); -} - -void ExpandIconWidget::initConnection() -{ - connect(m_trayView, &TrayGridView::rowCountChanged, this, &ExpandIconWidget::onRowCountChanged); - - connect(m_trayDelegate, &TrayDelegate::removeRow, this, [ = ](const QModelIndex &index) { - m_trayView->model()->removeRow(index.row(),index.parent()); - }); - connect(m_trayView, &TrayGridView::requestRemove, m_trayModel, &TrayModel::removeRow); - connect(m_regionInter, &DRegionMonitor::buttonPress, this, &ExpandIconWidget::onGlobMousePress); - - QMetaObject::invokeMethod(this, &ExpandIconWidget::onRowCountChanged, Qt::QueuedConnection); -} - -void ExpandIconWidget::onRowCountChanged() -{ - int count = m_trayModel->rowCount(); - m_trayView->setFixedSize(m_trayView->suitableSize()); - m_gridParentView->setFixedSize(m_trayView->size() + QSize(ITEM_SPACING * 2, ITEM_SPACING * 2)); - if (count > 0) - resetPosition(); - else if (m_gridParentView->isVisible()) - m_gridParentView->hide(); - - Q_EMIT trayVisbleChanged(count > 0); -} - -void ExpandIconWidget::onGlobMousePress(const QPoint &mousePos, const int flag) -{ - // 如果当前是隐藏,那么在点击任何地方都隐藏 - if (!isVisible()) { - m_gridParentView->hide(); - return; - } - - if ((flag != DRegionMonitor::WatchedFlags::Button_Left) && (flag != DRegionMonitor::WatchedFlags::Button_Right)) - return; - - QPoint ptPos = parentWidget()->mapToGlobal(this->pos()); - const QRect rect = QRect(ptPos, size()); - if (rect.contains(mousePos)) - return; - - const QRect rctView(m_gridParentView->pos(), m_gridParentView->size()); - if (rctView.contains(mousePos)) - return; - - m_gridParentView->hide(); + gridParentView->move(ptPos); } /** @@ -231,14 +230,25 @@ void ExpandIconWidget::onGlobMousePress(const QPoint &mousePos, const int flag) * @param parent */ -RoundWidget::RoundWidget(QWidget *parent) +TrayGridWidget::TrayGridWidget(QWidget *parent) : QWidget (parent) , m_dockInter(new DockInter(dockServiceName(), dockServicePath(), QDBusConnection::sessionBus(), this)) + , m_trayGridView(nullptr) { setAttribute(Qt::WA_TranslucentBackground); } -void RoundWidget::paintEvent(QPaintEvent *event) +void TrayGridWidget::setTrayGridView(TrayGridView *trayView) +{ + m_trayGridView = trayView; +} + +TrayGridView *TrayGridWidget::trayView() const +{ + return m_trayGridView; +} + +void TrayGridWidget::paintEvent(QPaintEvent *event) { Q_UNUSED(event); @@ -252,7 +262,7 @@ void RoundWidget::paintEvent(QPaintEvent *event) painter.fillPath(path, maskColor()); } -QColor RoundWidget::maskColor() const +QColor TrayGridWidget::maskColor() const { QColor color = DGuiApplicationHelper::standardPalette(DGuiApplicationHelper::instance()->themeType()).window().color(); int maskAlpha(static_cast(255 * m_dockInter->opacity())); diff --git a/frame/window/tray/widgets/expandiconwidget.h b/frame/window/tray/widgets/expandiconwidget.h index 3560dae1f..57747f01f 100644 --- a/frame/window/tray/widgets/expandiconwidget.h +++ b/frame/window/tray/widgets/expandiconwidget.h @@ -28,6 +28,7 @@ class TrayGridView; class TrayModel; class TrayDelegate; +class TrayGridWidget; namespace Dtk { namespace Gui { class DRegionMonitor; } } @@ -45,41 +46,32 @@ public: QString itemKeyForConfig() override { return "Expand"; } void updateIcon() override {} QPixmap icon() override; - QWidget *popupTrayView(); + TrayGridWidget *popupTrayView(); Q_SIGNALS: void trayVisbleChanged(bool); -private Q_SLOTS: - void onGlobMousePress(const QPoint &mousePos, const int flag); - void onRowCountChanged(); - protected: - void paintEvent(QPaintEvent *) override; + void paintEvent(QPaintEvent *event) override; const QString dropIconFile() const; void resetPosition(); -private: - void initUi(); - void initConnection(); - private: Dtk::Gui::DRegionMonitor *m_regionInter; Dock::Position m_position; - QWidget *m_gridParentView; - TrayGridView *m_trayView; - TrayDelegate *m_trayDelegate; - TrayModel *m_trayModel; }; // 绘制圆角窗体 -class RoundWidget : public QWidget +class TrayGridWidget : public QWidget { Q_OBJECT public: - explicit RoundWidget(QWidget *parent); + explicit TrayGridWidget(QWidget *parent); + + void setTrayGridView(TrayGridView *trayView); + TrayGridView *trayView() const; protected: void paintEvent(QPaintEvent *event) override; @@ -89,6 +81,7 @@ private: private: DockInter *m_dockInter; + TrayGridView *m_trayGridView; }; #endif // EXPANDICONWIDGET_H diff --git a/frame/window/traymanagerwindow.cpp b/frame/window/traymanagerwindow.cpp index dbf0b6baf..285817621 100644 --- a/frame/window/traymanagerwindow.cpp +++ b/frame/window/traymanagerwindow.cpp @@ -55,7 +55,7 @@ TrayManagerWindow::TrayManagerWindow(QWidget *parent) , m_systemPluginWidget(new SystemPluginWindow(this)) , m_appPluginWidget(new QWidget(m_appPluginDatetimeWidget)) , m_quickIconWidget(new QuickPluginWindow(m_appPluginWidget)) - , m_dateTimeWidget(new DateTimeDisplayer(m_appPluginDatetimeWidget)) + , m_dateTimeWidget(new DateTimeDisplayer(false, m_appPluginDatetimeWidget)) , m_appPluginLayout(new QBoxLayout(QBoxLayout::Direction::LeftToRight, this)) , m_mainLayout(new QBoxLayout(QBoxLayout::Direction::LeftToRight, this)) , m_trayView(new TrayGridView(this)) @@ -217,6 +217,7 @@ void TrayManagerWindow::resizeEvent(QResizeEvent *event) void TrayManagerWindow::initUi() { + m_systemPluginWidget->setDisplayMode(Dock::DisplayMode::Fashion); m_trayView->setModel(m_model); m_trayView->setItemDelegate(m_delegate); m_trayView->setDragDistance(2); diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 3bcb30dc3..de79d7fd0 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -1,9 +1,9 @@ -add_subdirectory("datetime") +#add_subdirectory("datetime") #add_subdirectory("disk-mount") add_subdirectory("shutdown") add_subdirectory("power") -add_subdirectory("sound") -add_subdirectory("tray") +#add_subdirectory("sound") +#add_subdirectory("tray") add_subdirectory("trash") add_subdirectory("keyboard-layout") add_subdirectory("onboard")