mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-01 07:05:48 +00:00
feat: 加载插件流程移动到插件里单独加载
将加载插件的流程和快捷面板的功能移动到单独的插件中,精简任务栏的代码 Log: Influence: 加载插件 Task: https://pms.uniontech.com/task-view-222353.html Change-Id: I9b2fbe4f32c852f6a3535daab87c63741bd8914a
This commit is contained in:
parent
978d7fe738
commit
4a2847f03f
1
debian/dde-dock.install
vendored
1
debian/dde-dock.install
vendored
@ -1,6 +1,7 @@
|
||||
usr/share
|
||||
usr/bin
|
||||
etc/dde-dock
|
||||
usr/lib/dde-dock/plugins/loader/libpluginmanager.so
|
||||
usr/lib/dde-dock/plugins/libshutdown.so
|
||||
usr/lib/dde-dock/plugins/libtrash.so
|
||||
usr/lib/dde-dock/plugins/liboverlay-warning.so
|
||||
|
@ -12,7 +12,7 @@ endif()
|
||||
generation_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/dbusinterface/xml ${CMAKE_CURRENT_SOURCE_DIR}/dbusinterface/generation_dbus_interface)
|
||||
|
||||
# Sources files
|
||||
file(GLOB_RECURSE SRCS "*.h" "*.cpp" "../widgets/*.h" "../widgets/*.cpp")
|
||||
file(GLOB_RECURSE SRCS "*.h" "*.cpp" "../widgets/*.h" "../widgets/*.cpp" "../interfaces/*.h")
|
||||
|
||||
# Find the library
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
44
interfaces/pluginmanagerinterface.h
Normal file
44
interfaces/pluginmanagerinterface.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2023 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef PLUGINMANAGERINTERFACE_H
|
||||
#define PLUGINMANAGERINTERFACE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QJsonObject>
|
||||
|
||||
class PluginsItemInterface;
|
||||
|
||||
class PluginManagerInterface : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
virtual QList<PluginsItemInterface *> plugins() const = 0;
|
||||
virtual QList<PluginsItemInterface *> pluginsInSetting() const = 0;
|
||||
virtual QList<PluginsItemInterface *> currentPlugins() const = 0;
|
||||
virtual QString itemKey(PluginsItemInterface *itemInter) const = 0;
|
||||
virtual QJsonObject metaData(PluginsItemInterface *itemInter) const = 0;
|
||||
|
||||
Q_SIGNALS:
|
||||
void pluginLoadFinished();
|
||||
};
|
||||
|
||||
#endif // PLUGINMANAGERINTERFACE_H
|
@ -4,7 +4,7 @@ add_subdirectory("power")
|
||||
add_subdirectory("sound")
|
||||
add_subdirectory("display")
|
||||
add_subdirectory("media")
|
||||
#add_subdirectory("tray")
|
||||
add_subdirectory("pluginmanager")
|
||||
add_subdirectory("trash")
|
||||
add_subdirectory("keyboard-layout")
|
||||
add_subdirectory("onboard")
|
||||
|
45
plugins/pluginmanager/CMakeLists.txt
Normal file
45
plugins/pluginmanager/CMakeLists.txt
Normal file
@ -0,0 +1,45 @@
|
||||
|
||||
set(PLUGIN_NAME "pluginmanager")
|
||||
|
||||
project(${PLUGIN_NAME})
|
||||
|
||||
# Sources files
|
||||
file(GLOB_RECURSE SRCS "*.h" "*.cpp" "*.qrc" "../../frame/drag/quickdragcore.h" "../../frame/drag/quickdragcore.cpp"
|
||||
"../../frame/util/settingconfig.h" "../../frame/util/settingconfig.cpp"
|
||||
"../../frame/util/pluginloader.h" "../../frame/util/pluginloader.cpp"
|
||||
"../../frame/dbus/dockinterface.h" "../../frame/dbus/dockinterface.cpp"
|
||||
"../../frame/dbusinterface/generation_dbus_interface/org_deepin_dde_daemon_dock1.h"
|
||||
"../../frame/dbusinterface/generation_dbus_interface/org_deepin_dde_daemon_dock1.cpp"
|
||||
"../../frame/dbusinterface/types/dockrect.h"
|
||||
"../../frame/dbusinterface/types/dockrect.cpp"
|
||||
"../../interfaces/pluginmanagerinterface.h"
|
||||
)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
find_package(Qt5Widgets REQUIRED)
|
||||
find_package(Qt5Svg REQUIRED)
|
||||
find_package(Qt5DBus REQUIRED)
|
||||
find_package(DtkWidget REQUIRED)
|
||||
pkg_check_modules(QGSettings REQUIRED gsettings-qt)
|
||||
|
||||
add_library(${PLUGIN_NAME} SHARED ${SRCS})
|
||||
set_target_properties(${PLUGIN_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ../loader/)
|
||||
target_include_directories(${PLUGIN_NAME} PUBLIC ${DtkWidget_INCLUDE_DIRS}
|
||||
${Qt5DBus_INCLUDE_DIRS}
|
||||
${QGSettings_INCLUDE_DIRS}
|
||||
./pluginadapter
|
||||
../../frame/drag
|
||||
../../frame/dbusinterface
|
||||
../../frame/dbusinterface/generation_dbus_interface/
|
||||
../../interfaces
|
||||
)
|
||||
|
||||
target_link_libraries(${PLUGIN_NAME} PRIVATE
|
||||
${DtkWidget_LIBRARIES}
|
||||
${Qt5Widgets_LIBRARIES}
|
||||
${Qt5Svg_LIBRARIES}
|
||||
${Qt5DBus_LIBRARIES}
|
||||
${QGSettings_LIBRARIES}
|
||||
)
|
||||
|
||||
install(TARGETS ${PLUGIN_NAME} LIBRARY DESTINATION lib/dde-dock/plugins/loader)
|
704
plugins/pluginmanager/dockplugincontroller.cpp
Normal file
704
plugins/pluginmanager/dockplugincontroller.cpp
Normal file
@ -0,0 +1,704 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dockplugincontroller.h"
|
||||
#include "pluginsiteminterface.h"
|
||||
#include "pluginsiteminterface_v20.h"
|
||||
#include "pluginadapter.h"
|
||||
#include "utils.h"
|
||||
#include "settingconfig.h"
|
||||
|
||||
#include <DNotifySender>
|
||||
#include <DSysInfo>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QMapIterator>
|
||||
#include <QPluginLoader>
|
||||
|
||||
#define PLUGININFO "pluginInfo"
|
||||
#define DOCK_QUICK_PLUGINS "Dock_Quick_Plugins"
|
||||
|
||||
static const QStringList CompatiblePluginApiList {
|
||||
"1.1.1",
|
||||
"1.2",
|
||||
"1.2.1",
|
||||
"1.2.2",
|
||||
DOCK_PLUGIN_API_VERSION
|
||||
};
|
||||
|
||||
class PluginInfo : public QObject
|
||||
{
|
||||
public:
|
||||
PluginInfo() : QObject(nullptr), m_loaded(false), m_visible(false) {}
|
||||
bool m_loaded;
|
||||
bool m_visible;
|
||||
QString m_itemKey;
|
||||
};
|
||||
|
||||
DockPluginController::DockPluginController(PluginProxyInterface *proxyInter, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_dbusDaemonInterface(QDBusConnection::sessionBus().interface())
|
||||
, m_dockDaemonInter(new DockInter(dockServiceName(), dockServicePath(), QDBusConnection::sessionBus(), this))
|
||||
, m_proxyInter(proxyInter)
|
||||
{
|
||||
qApp->installEventFilter(this);
|
||||
|
||||
refreshPluginSettings();
|
||||
|
||||
connect(SETTINGCONFIG, &SettingConfig::valueChanged, this, &DockPluginController::onConfigChanged);
|
||||
connect(m_dockDaemonInter, &DockInter::PluginSettingsSynced, this, &DockPluginController::refreshPluginSettings, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
DockPluginController::~DockPluginController()
|
||||
{
|
||||
for (auto inter : m_pluginsMap.keys()) {
|
||||
delete m_pluginsMap.value(inter).value("pluginloader");
|
||||
m_pluginsMap[inter]["pluginloader"] = nullptr;
|
||||
if (m_pluginsMap[inter].contains(PLUGININFO))
|
||||
m_pluginsMap[inter][PLUGININFO]->deleteLater();
|
||||
m_pluginsMap.remove(inter);
|
||||
delete inter;
|
||||
inter = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
QList<PluginsItemInterface *> DockPluginController::plugins() const
|
||||
{
|
||||
return m_pluginsMap.keys();
|
||||
}
|
||||
|
||||
QList<PluginsItemInterface *> DockPluginController::pluginsInSetting() const
|
||||
{
|
||||
// 插件有三种状态
|
||||
// 1、所有的插件,不管这个插件是否调用itemAdded方法,只要是通过dock加载的插件(换句话说,也就是在/lib/dde-dock/plugins目录下的插件)
|
||||
// 2、在1的基础上,插件自身调用了itemAdded方法的插件,例如机器上没有蓝牙设备,那么蓝牙插件就不会调用itemAdded方法,这时候就不算
|
||||
// 3、在2的基础上,由控制中心来决定那些插件是否在任务栏显示的插件
|
||||
// 此处返回的是第二种插件
|
||||
QList<PluginsItemInterface *> settingPlugins;
|
||||
QMap<PluginsItemInterface *, int> pluginSort;
|
||||
for (auto it = m_pluginsMap.begin(); it != m_pluginsMap.end(); it++) {
|
||||
PluginsItemInterface *plugin = it.key();
|
||||
qInfo() << plugin->pluginName();
|
||||
if (plugin->pluginDisplayName().isEmpty())
|
||||
continue;
|
||||
|
||||
QMap<QString, QObject *> pluginMap = it.value();
|
||||
// 如果不包含PLUGININFO这个key值,肯定是未加载
|
||||
if (!pluginMap.contains(PLUGININFO))
|
||||
continue;
|
||||
|
||||
PluginInfo *pluginInfo = static_cast<PluginInfo *>(pluginMap[PLUGININFO]);
|
||||
if (!pluginInfo->m_loaded)
|
||||
continue;
|
||||
|
||||
// 这里只需要返回插件为可以在控制中心设置的插件
|
||||
if (!(plugin->flags() & PluginFlag::Attribute_CanSetting))
|
||||
continue;
|
||||
|
||||
settingPlugins << plugin;
|
||||
pluginSort[plugin] = plugin->itemSortKey(pluginInfo->m_itemKey);
|
||||
}
|
||||
|
||||
std::sort(settingPlugins.begin(), settingPlugins.end(), [ pluginSort ](PluginsItemInterface *plugin1, PluginsItemInterface *plugin2) {
|
||||
return pluginSort[plugin1] < pluginSort[plugin2];
|
||||
});
|
||||
|
||||
return settingPlugins;
|
||||
}
|
||||
|
||||
QList<PluginsItemInterface *> DockPluginController::currentPlugins() const
|
||||
{
|
||||
QList<PluginsItemInterface *> loadedPlugins;
|
||||
|
||||
QMap<PluginsItemInterface *, int> pluginSortMap;
|
||||
for (auto it = m_pluginsMap.begin(); it != m_pluginsMap.end(); it++) {
|
||||
QMap<QString, QObject *> objectMap = it.value();
|
||||
if (!objectMap.contains(PLUGININFO))
|
||||
continue;
|
||||
|
||||
PluginInfo *pluginInfo = static_cast<PluginInfo *>(objectMap[PLUGININFO]);
|
||||
if (!pluginInfo->m_loaded)
|
||||
continue;
|
||||
|
||||
PluginsItemInterface *plugin = it.key();
|
||||
loadedPlugins << plugin;
|
||||
pluginSortMap[plugin] = plugin->itemSortKey(pluginInfo->m_itemKey);
|
||||
}
|
||||
|
||||
std::sort(loadedPlugins.begin(), loadedPlugins.end(), [ pluginSortMap ](PluginsItemInterface *pluginItem1, PluginsItemInterface *pluginItem2) {
|
||||
return pluginSortMap.value(pluginItem1) < pluginSortMap.value(pluginItem2);
|
||||
});
|
||||
return loadedPlugins;
|
||||
}
|
||||
|
||||
void DockPluginController::saveValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant &value)
|
||||
{
|
||||
savePluginValue(getPluginInterface(itemInter), key, value);
|
||||
}
|
||||
|
||||
const QVariant DockPluginController::getValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant &fallback)
|
||||
{
|
||||
return getPluginValue(getPluginInterface(itemInter), key, fallback);
|
||||
}
|
||||
|
||||
void DockPluginController::removeValue(PluginsItemInterface *const itemInter, const QStringList &keyList)
|
||||
{
|
||||
removePluginValue(getPluginInterface(itemInter), keyList);
|
||||
}
|
||||
|
||||
void DockPluginController::itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey)
|
||||
{
|
||||
PluginsItemInterface *pluginItem = getPluginInterface(itemInter);
|
||||
|
||||
PluginAdapter *pluginAdapter = dynamic_cast<PluginAdapter *>(pluginItem);
|
||||
if (pluginAdapter) {
|
||||
// 如果该插件可以正常转换为PluginAdapter插件,表示当前插件是v20插件,为了兼容v20插件
|
||||
// 中获取ICON,因此,使用调用插件的itemWidget来截图的方式返回QIcon,所以此处传入itemKey
|
||||
pluginAdapter->setItemKey(itemKey);
|
||||
}
|
||||
|
||||
// 如果是通过插件来调用m_proxyInter的
|
||||
PluginInfo *pluginInfo = nullptr;
|
||||
QMap<QString, QObject *> &interfaceData = m_pluginsMap[pluginItem];
|
||||
if (interfaceData.contains(PLUGININFO)) {
|
||||
pluginInfo = static_cast<PluginInfo *>(interfaceData[PLUGININFO]);
|
||||
// 如果插件已经加载,则无需再次加载(此处保证插件出现重复调用itemAdded的情况)
|
||||
if (pluginInfo->m_loaded)
|
||||
return;
|
||||
} else {
|
||||
pluginInfo = new PluginInfo;
|
||||
interfaceData[PLUGININFO] = pluginInfo;
|
||||
}
|
||||
pluginInfo->m_itemKey = itemKey;
|
||||
pluginInfo->m_loaded = true;
|
||||
|
||||
if (pluginCanDock(pluginItem))
|
||||
addPluginItem(pluginItem, itemKey);
|
||||
|
||||
Q_EMIT pluginInserted(pluginItem, itemKey);
|
||||
}
|
||||
|
||||
void DockPluginController::itemUpdate(PluginsItemInterface * const itemInter, const QString &itemKey)
|
||||
{
|
||||
m_proxyInter->itemUpdate(getPluginInterface(itemInter), itemKey);
|
||||
}
|
||||
|
||||
void DockPluginController::itemRemoved(PluginsItemInterface * const itemInter, const QString &itemKey)
|
||||
{
|
||||
PluginsItemInterface *pluginInter = getPluginInterface(itemInter);
|
||||
// 更新字段中的isLoaded字段,表示当前没有加载
|
||||
QMap<QString, QObject *> &interfaceData = m_pluginsMap[pluginInter];
|
||||
if (interfaceData.contains(PLUGININFO)) {
|
||||
PluginInfo *pluginInfo = static_cast<PluginInfo *>(interfaceData[PLUGININFO]);
|
||||
// 将是否加载的标记修改为未加载
|
||||
pluginInfo->m_loaded = false;
|
||||
}
|
||||
|
||||
removePluginItem(pluginInter, itemKey);
|
||||
Q_EMIT pluginRemoved(pluginInter);
|
||||
}
|
||||
|
||||
void DockPluginController::requestWindowAutoHide(PluginsItemInterface * const itemInter, const QString &itemKey, const bool autoHide)
|
||||
{
|
||||
m_proxyInter->requestWindowAutoHide(getPluginInterface(itemInter), itemKey, autoHide);
|
||||
}
|
||||
|
||||
void DockPluginController::requestRefreshWindowVisible(PluginsItemInterface * const itemInter, const QString &itemKey)
|
||||
{
|
||||
m_proxyInter->requestRefreshWindowVisible(getPluginInterface(itemInter), itemKey);
|
||||
}
|
||||
|
||||
// 请求页面显示或者隐藏,由插件内部来调用,例如在移除蓝牙插件后,如果已经弹出了蓝牙插件的面板,则隐藏面板
|
||||
void DockPluginController::requestSetAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool visible)
|
||||
{
|
||||
PluginsItemInterface *pluginInter = getPluginInterface(itemInter);
|
||||
Q_EMIT requestAppletVisible(pluginInter, itemKey, visible);
|
||||
m_proxyInter->requestSetAppletVisible(pluginInter, itemKey, visible);
|
||||
}
|
||||
|
||||
PluginsItemInterface *DockPluginController::getPluginInterface(PluginsItemInterface * const itemInter)
|
||||
{
|
||||
// 先从事先定义好的map中查找,如果没有找到,就是v23插件,直接返回当前插件的指针
|
||||
qulonglong pluginAddr = (qulonglong)itemInter;
|
||||
if (m_pluginAdapterMap.contains(pluginAddr))
|
||||
return m_pluginAdapterMap[pluginAddr];
|
||||
|
||||
return itemInter;
|
||||
}
|
||||
|
||||
void DockPluginController::addPluginItem(PluginsItemInterface * const itemInter, const QString &itemKey)
|
||||
{
|
||||
// 如果这个插件都没有加载,那么此处肯定是无需新增
|
||||
if (!m_pluginsMap.contains(itemInter))
|
||||
return;
|
||||
|
||||
PluginInfo *pluginInfo = nullptr;
|
||||
QMap<QString, QObject *> &interfaceData = m_pluginsMap[itemInter];
|
||||
// 此处的PLUGININFO的数据已经在前面调用的地方给填充了数据,如果没有获取到这个数据,则无需新增
|
||||
if (!interfaceData.contains(PLUGININFO))
|
||||
return;
|
||||
|
||||
pluginInfo = static_cast<PluginInfo *>(interfaceData[PLUGININFO]);
|
||||
pluginInfo->m_visible = true;
|
||||
|
||||
m_proxyInter->itemAdded(itemInter, itemKey);
|
||||
}
|
||||
|
||||
void DockPluginController::removePluginItem(PluginsItemInterface * const itemInter, const QString &itemKey)
|
||||
{
|
||||
if (!m_pluginsMap.contains(itemInter))
|
||||
return;
|
||||
|
||||
// 更新字段中的isLoaded字段,表示当前没有加载
|
||||
QMap<QString, QObject *> &interfaceData = m_pluginsMap[itemInter];
|
||||
if (!interfaceData.contains(PLUGININFO))
|
||||
return;
|
||||
|
||||
PluginInfo *pluginInfo = static_cast<PluginInfo *>(interfaceData[PLUGININFO]);
|
||||
// 将是否在任务栏显示的标记改为不显示
|
||||
pluginInfo->m_visible = false;
|
||||
m_proxyInter->itemRemoved(itemInter, itemKey);
|
||||
}
|
||||
|
||||
QString DockPluginController::itemKey(PluginsItemInterface *itemInter) const
|
||||
{
|
||||
if (!m_pluginsMap.contains(itemInter))
|
||||
return QString();
|
||||
|
||||
QMap<QString, QObject *> interfaceData = m_pluginsMap[itemInter];
|
||||
if (!interfaceData.contains(PLUGININFO))
|
||||
return QString();
|
||||
|
||||
PluginInfo *pluginInfo = static_cast<PluginInfo *>(interfaceData[PLUGININFO]);
|
||||
return pluginInfo->m_itemKey;
|
||||
}
|
||||
|
||||
QJsonObject DockPluginController::metaData(PluginsItemInterface *pluginItem)
|
||||
{
|
||||
if (!m_pluginsMap.contains(pluginItem))
|
||||
return QJsonObject();
|
||||
|
||||
QPluginLoader *pluginLoader = qobject_cast<QPluginLoader *>(m_pluginsMap[pluginItem].value("pluginloader"));
|
||||
|
||||
if (!pluginLoader)
|
||||
return QJsonObject();
|
||||
|
||||
return pluginLoader->metaData().value("MetaData").toObject();
|
||||
}
|
||||
|
||||
void DockPluginController::savePluginValue(PluginsItemInterface * const itemInter, const QString &key, const QVariant &value)
|
||||
{
|
||||
// is it necessary?
|
||||
// refreshPluginSettings();
|
||||
|
||||
// save to local cache
|
||||
QJsonObject localObject = m_pluginSettingsObject.value(itemInter->pluginName()).toObject();
|
||||
localObject.insert(key, QJsonValue::fromVariant(value)); //Note: QVariant::toJsonValue() not work in Qt 5.7
|
||||
|
||||
// save to daemon
|
||||
QJsonObject remoteObject, remoteObjectInter;
|
||||
remoteObjectInter.insert(key, QJsonValue::fromVariant(value)); //Note: QVariant::toJsonValue() not work in Qt 5.7
|
||||
remoteObject.insert(itemInter->pluginName(), remoteObjectInter);
|
||||
|
||||
if (itemInter->type() == PluginsItemInterface::Fixed && key == "enable" && !value.toBool()) {
|
||||
int fixedPluginCount = 0;
|
||||
// 遍历FixPlugin插件个数
|
||||
for (auto it(m_pluginsMap.begin()); it != m_pluginsMap.end();) {
|
||||
if (it.key()->type() == PluginsItemInterface::Fixed) {
|
||||
fixedPluginCount++;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
// 修改插件的order值,位置为队尾
|
||||
QString name = localObject.keys().last();
|
||||
// 此次做一下判断,有可能初始数据不存在pos_*字段,会导致enable字段被修改。或者此处可以循环所有字段是否存在pos_开头的字段?
|
||||
if (name != key) {
|
||||
localObject.insert(name, QJsonValue::fromVariant(fixedPluginCount)); //Note: QVariant::toJsonValue() not work in Qt 5.7
|
||||
// daemon中同样修改
|
||||
remoteObjectInter.insert(name, QJsonValue::fromVariant(fixedPluginCount)); //Note: QVariant::toJsonValue() not work in Qt 5.7
|
||||
remoteObject.insert(itemInter->pluginName(), remoteObjectInter);
|
||||
}
|
||||
}
|
||||
|
||||
m_pluginSettingsObject.insert(itemInter->pluginName(), localObject);
|
||||
m_dockDaemonInter->MergePluginSettings(QJsonDocument(remoteObject).toJson(QJsonDocument::JsonFormat::Compact));
|
||||
}
|
||||
|
||||
const QVariant DockPluginController::getPluginValue(PluginsItemInterface * const itemInter, const QString &key, const QVariant &fallback)
|
||||
{
|
||||
// load from local cache
|
||||
QVariant v = m_pluginSettingsObject.value(itemInter->pluginName()).toObject().value(key).toVariant();
|
||||
if (v.isNull() || !v.isValid()) {
|
||||
v = fallback;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
void DockPluginController::removePluginValue(PluginsItemInterface * const itemInter, const QStringList &keyList)
|
||||
{
|
||||
if (keyList.isEmpty()) {
|
||||
m_pluginSettingsObject.remove(itemInter->pluginName());
|
||||
} else {
|
||||
QJsonObject localObject = m_pluginSettingsObject.value(itemInter->pluginName()).toObject();
|
||||
for (auto key : keyList) {
|
||||
localObject.remove(key);
|
||||
}
|
||||
m_pluginSettingsObject.insert(itemInter->pluginName(), localObject);
|
||||
}
|
||||
|
||||
m_dockDaemonInter->RemovePluginSettings(itemInter->pluginName(), keyList);
|
||||
}
|
||||
|
||||
void DockPluginController::startLoadPlugin(const QStringList &dirs)
|
||||
{
|
||||
QDir dir;
|
||||
for (const QString &path : dirs) {
|
||||
if (!dir.exists(path))
|
||||
continue;
|
||||
|
||||
startLoader(new PluginLoader(path, this));
|
||||
}
|
||||
}
|
||||
|
||||
bool DockPluginController::isPluginLoaded(PluginsItemInterface *itemInter)
|
||||
{
|
||||
if (!m_pluginsMap.contains(itemInter))
|
||||
return false;
|
||||
|
||||
QMap<QString, QObject *> pluginObject = m_pluginsMap.value(itemInter);
|
||||
if (!pluginObject.contains(PLUGININFO))
|
||||
return false;
|
||||
|
||||
PluginInfo *pluginInfo = static_cast<PluginInfo *>(pluginObject.value(PLUGININFO));
|
||||
return pluginInfo->m_visible;
|
||||
}
|
||||
|
||||
QObject *DockPluginController::pluginItemAt(PluginsItemInterface *const itemInter, const QString &itemKey) const
|
||||
{
|
||||
if (!m_pluginsMap.contains(itemInter))
|
||||
return nullptr;
|
||||
|
||||
return m_pluginsMap[itemInter][itemKey];
|
||||
}
|
||||
|
||||
PluginsItemInterface *DockPluginController::pluginInterAt(const QString &itemKey)
|
||||
{
|
||||
QMapIterator<PluginsItemInterface *, QMap<QString, QObject *>> it(m_pluginsMap);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
if (it.value().keys().contains(itemKey)) {
|
||||
return it.key();
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PluginsItemInterface *DockPluginController::pluginInterAt(QObject *destItem)
|
||||
{
|
||||
QMapIterator<PluginsItemInterface *, QMap<QString, QObject *>> it(m_pluginsMap);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
if (it.value().values().contains(destItem)) {
|
||||
return it.key();
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void DockPluginController::startLoader(PluginLoader *loader)
|
||||
{
|
||||
connect(loader, &PluginLoader::finished, loader, &PluginLoader::deleteLater, Qt::QueuedConnection);
|
||||
connect(loader, &PluginLoader::pluginFounded, this, [ = ](const QString &pluginFile) {
|
||||
QPair<QString, PluginsItemInterface *> pair;
|
||||
pair.first = pluginFile;
|
||||
pair.second = nullptr;
|
||||
m_pluginLoadMap.insert(pair, false);
|
||||
});
|
||||
connect(loader, &PluginLoader::pluginFounded, this, &DockPluginController::loadPlugin, Qt::QueuedConnection);
|
||||
|
||||
int delay = Utils::SettingValue("com.deepin.dde.dock", "/com/deepin/dde/dock/", "delay-plugins-time", 0).toInt();
|
||||
QTimer::singleShot(delay, loader, [ = ] { loader->start(QThread::LowestPriority); });
|
||||
}
|
||||
|
||||
void DockPluginController::displayModeChanged()
|
||||
{
|
||||
const Dock::DisplayMode displayMode = qApp->property(PROP_DISPLAY_MODE).value<Dock::DisplayMode>();
|
||||
const auto inters = m_pluginsMap.keys();
|
||||
|
||||
for (auto inter : inters)
|
||||
inter->displayModeChanged(displayMode);
|
||||
}
|
||||
|
||||
void DockPluginController::positionChanged()
|
||||
{
|
||||
const Dock::Position position = qApp->property(PROP_POSITION).value<Dock::Position>();
|
||||
const auto inters = m_pluginsMap.keys();
|
||||
|
||||
for (auto inter : inters)
|
||||
inter->positionChanged(position);
|
||||
}
|
||||
|
||||
void DockPluginController::loadPlugin(const QString &pluginFile)
|
||||
{
|
||||
QPluginLoader *pluginLoader = new QPluginLoader(pluginFile, this);
|
||||
const QJsonObject &meta = pluginLoader->metaData().value("MetaData").toObject();
|
||||
const QString &pluginApi = meta.value("api").toString();
|
||||
bool pluginIsValid = true;
|
||||
if (pluginApi.isEmpty() || !CompatiblePluginApiList.contains(pluginApi)) {
|
||||
qDebug() << objectName()
|
||||
<< "plugin api version not matched! expect versions:" << CompatiblePluginApiList
|
||||
<< ", got version:" << pluginApi
|
||||
<< ", the plugin file is:" << pluginFile;
|
||||
|
||||
pluginIsValid = false;
|
||||
}
|
||||
|
||||
PluginsItemInterface *interface = qobject_cast<PluginsItemInterface *>(pluginLoader->instance());
|
||||
if (!interface) {
|
||||
// 如果识别当前插件失败,就认为这个插件是v20的插件,将其转换为v20插件接口
|
||||
PluginsItemInterface_V20 *interface_v20 = qobject_cast<PluginsItemInterface_V20 *>(pluginLoader->instance());
|
||||
if (interface_v20) {
|
||||
// 将v20插件接口通过适配器转换成v23的接口,方便在后面识别
|
||||
PluginAdapter *pluginAdapter = new PluginAdapter(interface_v20, pluginLoader);
|
||||
// 将适配器的地址保存到map列表中,因为适配器自己会调用itemAdded方法,转换成PluginsItemInterface类,但是实际上它
|
||||
// 对应的是PluginAdapter类,因此,这个map用于在后面的itemAdded方法中用来查找
|
||||
m_pluginAdapterMap[(qulonglong)(interface_v20)] = pluginAdapter;
|
||||
interface = pluginAdapter;
|
||||
}
|
||||
}
|
||||
|
||||
if (!interface) {
|
||||
qDebug() << objectName() << "load plugin failed!!!" << pluginLoader->errorString() << pluginFile;
|
||||
|
||||
pluginLoader->unload();
|
||||
pluginLoader->deleteLater();
|
||||
|
||||
pluginIsValid = false;
|
||||
}
|
||||
|
||||
if (!pluginIsValid) {
|
||||
for (auto &pair : m_pluginLoadMap.keys()) {
|
||||
if (pair.first == pluginFile) {
|
||||
m_pluginLoadMap.remove(pair);
|
||||
}
|
||||
}
|
||||
QString notifyMessage(tr("The plugin %1 is not compatible with the system."));
|
||||
Dtk::Core::DUtil::DNotifySender(notifyMessage.arg(QFileInfo(pluginFile).fileName())).appIcon("dialog-warning").call();
|
||||
return;
|
||||
}
|
||||
|
||||
if (interface->pluginName() == "multitasking" && (Utils::IS_WAYLAND_DISPLAY || Dtk::Core::DSysInfo::deepinType() == Dtk::Core::DSysInfo::DeepinServer)) {
|
||||
for (auto &pair : m_pluginLoadMap.keys()) {
|
||||
if (pair.first == pluginFile) {
|
||||
m_pluginLoadMap.remove(pair);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
QMapIterator<QPair<QString, PluginsItemInterface *>, bool> it(m_pluginLoadMap);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
if (it.key().first == pluginFile) {
|
||||
m_pluginLoadMap.remove(it.key());
|
||||
QPair<QString, PluginsItemInterface *> newPair;
|
||||
newPair.first = pluginFile;
|
||||
newPair.second = interface;
|
||||
m_pluginLoadMap.insert(newPair, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 保存 PluginLoader 对象指针
|
||||
QMap<QString, QObject *> interfaceData;
|
||||
interfaceData["pluginloader"] = pluginLoader;
|
||||
m_pluginsMap.insert(interface, interfaceData);
|
||||
QString dbusService = meta.value("depends-daemon-dbus-service").toString();
|
||||
if (!dbusService.isEmpty() && !m_dbusDaemonInterface->isServiceRegistered(dbusService).value()) {
|
||||
qDebug() << objectName() << dbusService << "daemon has not started, waiting for signal";
|
||||
connect(m_dbusDaemonInterface, &QDBusConnectionInterface::serviceOwnerChanged, this,
|
||||
[ = ](const QString & name, const QString & oldOwner, const QString & newOwner) {
|
||||
Q_UNUSED(oldOwner);
|
||||
if (name == dbusService && !newOwner.isEmpty()) {
|
||||
qDebug() << objectName() << dbusService << "daemon started, init plugin and disconnect";
|
||||
initPlugin(interface);
|
||||
disconnect(m_dbusDaemonInterface);
|
||||
}
|
||||
}
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE(justforlxz): 插件的所有初始化工作都在init函数中进行,
|
||||
// loadPlugin函数是按队列执行的,initPlugin函数会有可能导致
|
||||
// 函数执行被阻塞。
|
||||
QTimer::singleShot(1, this, [ = ] {
|
||||
initPlugin(interface);
|
||||
});
|
||||
}
|
||||
|
||||
void DockPluginController::initPlugin(PluginsItemInterface *interface)
|
||||
{
|
||||
if (!interface)
|
||||
return;
|
||||
|
||||
qDebug() << objectName() << "init plugin: " << interface->pluginName();
|
||||
interface->init(this);
|
||||
|
||||
for (const auto &pair : m_pluginLoadMap.keys()) {
|
||||
if (pair.second == interface)
|
||||
m_pluginLoadMap.insert(pair, true);
|
||||
}
|
||||
|
||||
bool loaded = true;
|
||||
for (int i = 0; i < m_pluginLoadMap.keys().size(); ++i) {
|
||||
if (!m_pluginLoadMap.values()[i]) {
|
||||
loaded = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 插件全部加载完成
|
||||
if (loaded) {
|
||||
emit pluginLoadFinished();
|
||||
}
|
||||
qDebug() << objectName() << "init plugin finished: " << interface->pluginName();
|
||||
}
|
||||
|
||||
void DockPluginController::refreshPluginSettings()
|
||||
{
|
||||
const QString &pluginSettings = m_dockDaemonInter->GetPluginSettings().value();
|
||||
if (pluginSettings.isEmpty()) {
|
||||
qDebug() << "Error! get plugin settings from dbus failed!";
|
||||
return;
|
||||
}
|
||||
|
||||
const QJsonObject &pluginSettingsObject = QJsonDocument::fromJson(pluginSettings.toLocal8Bit()).object();
|
||||
if (pluginSettingsObject.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// nothing changed
|
||||
if (pluginSettingsObject == m_pluginSettingsObject) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto pluginsIt = pluginSettingsObject.constBegin(); pluginsIt != pluginSettingsObject.constEnd(); ++pluginsIt) {
|
||||
const QString &pluginName = pluginsIt.key();
|
||||
const QJsonObject &settingsObject = pluginsIt.value().toObject();
|
||||
QJsonObject newSettingsObject = m_pluginSettingsObject.value(pluginName).toObject();
|
||||
for (auto settingsIt = settingsObject.constBegin(); settingsIt != settingsObject.constEnd(); ++settingsIt) {
|
||||
newSettingsObject.insert(settingsIt.key(), settingsIt.value());
|
||||
}
|
||||
// TODO: remove not exists key-values
|
||||
m_pluginSettingsObject.insert(pluginName, newSettingsObject);
|
||||
}
|
||||
|
||||
// not notify plugins to refresh settings if this update is not emit by dock daemon
|
||||
if (sender() != m_dockDaemonInter) {
|
||||
return;
|
||||
}
|
||||
|
||||
// notify all plugins to reload plugin settings
|
||||
for (PluginsItemInterface *pluginInter : m_pluginsMap.keys()) {
|
||||
pluginInter->pluginSettingsChanged();
|
||||
}
|
||||
|
||||
// reload all plugin items for sort order or container
|
||||
QMap<PluginsItemInterface *, QMap<QString, QObject *>> pluginsMapTemp = m_pluginsMap;
|
||||
for (auto it = pluginsMapTemp.constBegin(); it != pluginsMapTemp.constEnd(); ++it) {
|
||||
const QList<QString> &itemKeyList = it.value().keys();
|
||||
for (auto key : itemKeyList) {
|
||||
if (key != "pluginloader") {
|
||||
itemRemoved(it.key(), key);
|
||||
}
|
||||
}
|
||||
for (auto key : itemKeyList) {
|
||||
if (key != "pluginloader") {
|
||||
itemAdded(it.key(), key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool DockPluginController::eventFilter(QObject *object, QEvent *event)
|
||||
{
|
||||
if (object != qApp || event->type() != QEvent::DynamicPropertyChange)
|
||||
return false;
|
||||
|
||||
QDynamicPropertyChangeEvent *const dpce = static_cast<QDynamicPropertyChangeEvent *>(event);
|
||||
const QString propertyName = dpce->propertyName();
|
||||
|
||||
if (propertyName == PROP_POSITION)
|
||||
positionChanged();
|
||||
else if (propertyName == PROP_DISPLAY_MODE)
|
||||
displayModeChanged();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DockPluginController::pluginCanDock(PluginsItemInterface *plugin) const
|
||||
{
|
||||
// 观察插件是否已经驻留在任务栏上,如果已经驻留在任务栏,则始终显示
|
||||
if (plugin->flags() & PluginFlag::Attribute_ForceDock)
|
||||
return true;
|
||||
|
||||
const QStringList configPlugins = SETTINGCONFIG->value(DOCK_QUICK_PLUGINS).toStringList();
|
||||
return configPlugins.contains(plugin->pluginName());
|
||||
}
|
||||
|
||||
void DockPluginController::updateDockInfo(PluginsItemInterface * const itemInter, const DockPart &part)
|
||||
{
|
||||
m_proxyInter->updateDockInfo(itemInter, part);
|
||||
Q_EMIT pluginUpdated(itemInter, part);
|
||||
}
|
||||
|
||||
void DockPluginController::onConfigChanged(const QString &key, const QVariant &value)
|
||||
{
|
||||
if (key != DOCK_QUICK_PLUGINS)
|
||||
return;
|
||||
|
||||
QStringList pluginNames = value.toStringList();
|
||||
// 这里只处理工具插件(回收站)和系统插件(电源插件)
|
||||
for (PluginsItemInterface *plugin : plugins()) {
|
||||
QString itemKey = this->itemKey(plugin);
|
||||
if (!pluginNames.contains(plugin->pluginName()) && isPluginLoaded(plugin)) {
|
||||
// 如果当前配置中不包含当前插件,但是当前插件已经加载,那么就移除该插件
|
||||
removePluginItem(plugin, itemKey);
|
||||
QWidget *itemWidget = plugin->itemWidget(itemKey);
|
||||
if (itemWidget)
|
||||
itemWidget->setVisible(false);
|
||||
} else if (pluginNames.contains(plugin->pluginName()) && !isPluginLoaded(plugin)) {
|
||||
// 如果当前配置中包含当前插件,但是当前插件并未加载,那么就加载该插件
|
||||
addPluginItem(plugin, itemKey);
|
||||
// 只有工具插件是通过QWidget的方式进行显示的,因此,这里只处理工具插件
|
||||
if (plugin->flags() & PluginFlag::Type_Tool) {
|
||||
QWidget *itemWidget = plugin->itemWidget(itemKey);
|
||||
if (itemWidget)
|
||||
itemWidget->setVisible(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
116
plugins/pluginmanager/dockplugincontroller.h
Normal file
116
plugins/pluginmanager/dockplugincontroller.h
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DOCKPLUGINCONTROLLER_H
|
||||
#define DOCKPLUGINCONTROLLER_H
|
||||
|
||||
#include "pluginproxyinterface.h"
|
||||
#include "pluginloader.h"
|
||||
#include "dbusutil.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QDBusConnectionInterface>
|
||||
|
||||
class PluginsItemInterface;
|
||||
class PluginAdapter;
|
||||
|
||||
class DockPluginController : public QObject, protected PluginProxyInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DockPluginController(PluginProxyInterface *proxyInter, QObject *parent = Q_NULLPTR);
|
||||
~ DockPluginController() override;
|
||||
|
||||
QList<PluginsItemInterface *> plugins() const; // 所有的插件
|
||||
QList<PluginsItemInterface *> pluginsInSetting() const; // 控制中心用于可以设置是否显示或隐藏的插件
|
||||
QList<PluginsItemInterface *> currentPlugins() const; // 当前使用的插件
|
||||
|
||||
QString itemKey(PluginsItemInterface *itemInter) const;
|
||||
QJsonObject metaData(PluginsItemInterface *pluginItem);
|
||||
|
||||
virtual void savePluginValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant &value);
|
||||
virtual const QVariant getPluginValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant& fallback = QVariant());
|
||||
virtual void removePluginValue(PluginsItemInterface * const itemInter, const QStringList &keyList);
|
||||
void startLoadPlugin(const QStringList &dirs);
|
||||
|
||||
Q_SIGNALS:
|
||||
void pluginLoadFinished();
|
||||
void pluginInserted(PluginsItemInterface *itemInter, QString);
|
||||
void pluginRemoved(PluginsItemInterface *itemInter);
|
||||
void pluginUpdated(PluginsItemInterface *, const DockPart);
|
||||
void requestAppletVisible(PluginsItemInterface *, const QString &, bool);
|
||||
|
||||
protected:
|
||||
bool isPluginLoaded(PluginsItemInterface *itemInter);
|
||||
|
||||
QObject *pluginItemAt(PluginsItemInterface * const itemInter, const QString &itemKey) const;
|
||||
PluginsItemInterface *pluginInterAt(const QString &itemKey);
|
||||
PluginsItemInterface *pluginInterAt(QObject *destItem);
|
||||
bool eventFilter(QObject *object, QEvent *event) override;
|
||||
|
||||
bool pluginCanDock(PluginsItemInterface *plugin) const;
|
||||
void updateDockInfo(PluginsItemInterface * const itemInter, const DockPart &part) override;
|
||||
|
||||
private:
|
||||
// implements PluginProxyInterface
|
||||
void saveValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant &value) override;
|
||||
const QVariant getValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant& fallback = QVariant()) override;
|
||||
void removeValue(PluginsItemInterface * const itemInter, const QStringList &keyList) override;
|
||||
|
||||
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;
|
||||
PluginsItemInterface *getPluginInterface(PluginsItemInterface * const itemInter);
|
||||
|
||||
void addPluginItem(PluginsItemInterface * const itemInter, const QString &itemKey);
|
||||
void removePluginItem(PluginsItemInterface * const itemInter, const QString &itemKey);
|
||||
|
||||
private Q_SLOTS:
|
||||
void startLoader(PluginLoader *loader);
|
||||
void displayModeChanged();
|
||||
void positionChanged();
|
||||
void loadPlugin(const QString &pluginFile);
|
||||
void initPlugin(PluginsItemInterface *interface);
|
||||
void refreshPluginSettings();
|
||||
void onConfigChanged(const QString &key, const QVariant &value);
|
||||
|
||||
private:
|
||||
QDBusConnectionInterface *m_dbusDaemonInterface;
|
||||
DockInter *m_dockDaemonInter;
|
||||
|
||||
// interface, "pluginloader", PluginLoader指针对象
|
||||
QMap<PluginsItemInterface *, QMap<QString, QObject *>> m_pluginsMap;
|
||||
|
||||
// filepath, interface, loaded
|
||||
QMap<QPair<QString, PluginsItemInterface *>, bool> m_pluginLoadMap;
|
||||
|
||||
QJsonObject m_pluginSettingsObject;
|
||||
QMap<qulonglong, PluginAdapter *> m_pluginAdapterMap;
|
||||
|
||||
PluginProxyInterface *m_proxyInter;
|
||||
};
|
||||
|
||||
#endif // ABSTRACTPLUGINSCONTROLLER_H
|
122
plugins/pluginmanager/iconmanager.cpp
Normal file
122
plugins/pluginmanager/iconmanager.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (C) 2023 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "iconmanager.h"
|
||||
#include "dockplugincontroller.h"
|
||||
#include "pluginsiteminterface.h"
|
||||
|
||||
#include <DDciIcon>
|
||||
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
|
||||
#define ITEMSPACE 6
|
||||
#define ITEMHEIGHT 16
|
||||
#define ITEMWIDTH 18
|
||||
static QStringList pluginNames = {"power", "sound", "network"};
|
||||
|
||||
DGUI_USE_NAMESPACE
|
||||
|
||||
IconManager::IconManager(DockPluginController *pluginController, QObject *parent)
|
||||
: QObject{parent}
|
||||
, m_pluginController(pluginController)
|
||||
, m_size(QSize(ITEMWIDTH, ITEMHEIGHT))
|
||||
, m_position(Dock::Position::Bottom)
|
||||
{
|
||||
}
|
||||
|
||||
void IconManager::updateSize(QSize size)
|
||||
{
|
||||
m_size = size;
|
||||
}
|
||||
|
||||
void IconManager::setPosition(Dock::Position position)
|
||||
{
|
||||
m_position = position;
|
||||
}
|
||||
|
||||
QPixmap IconManager::pixmap() const
|
||||
{
|
||||
QList<PluginsItemInterface *> plugins;
|
||||
for (const QString &pluginName : pluginNames) {
|
||||
PluginsItemInterface *plugin = findPlugin(pluginName);
|
||||
if (plugin)
|
||||
plugins << plugin;
|
||||
}
|
||||
|
||||
if (plugins.size() < 2) {
|
||||
// 缺省图标
|
||||
DDciIcon::Theme theme = DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::DarkType ? DDciIcon::Light : DDciIcon::Dark;
|
||||
DDciIcon dciIcon(QString(":/resources/dock_control.dci"));
|
||||
return dciIcon.pixmap(QCoreApplication::testAttribute(Qt::AA_UseHighDpiPixmaps) ? 1 : qApp->devicePixelRatio(), ITEMHEIGHT, theme, DDciIcon::Normal);
|
||||
}
|
||||
|
||||
// 组合图标
|
||||
QPixmap pixmap;
|
||||
if (m_position == Dock::Position::Top || m_position == Dock::Position::Bottom) {
|
||||
pixmap = QPixmap(ITEMWIDTH * plugins.size() + ITEMSPACE * (plugins.size() + 1), m_size.height() - 8);
|
||||
} else {
|
||||
pixmap = QPixmap(m_size.width() - 8, ITEMWIDTH * plugins.size() + ITEMSPACE * (plugins.size() + 1));
|
||||
}
|
||||
|
||||
pixmap.fill(Qt::transparent);
|
||||
QPainter painter(&pixmap);
|
||||
painter.setRenderHints(QPainter::SmoothPixmapTransform | QPainter::Antialiasing);
|
||||
QColor backColor = DGuiApplicationHelper::ColorType::DarkType == DGuiApplicationHelper::instance()->themeType() ? QColor(20, 20, 20) : Qt::white;
|
||||
backColor.setAlphaF(0.2);
|
||||
QPainterPath path;
|
||||
path.addRoundedRect(pixmap.rect(), 5, 5);
|
||||
painter.fillPath(path, backColor);
|
||||
if (m_position == Dock::Position::Top || m_position == Dock::Position::Bottom) {
|
||||
QPoint pointPixmap(ITEMSPACE, (pixmap.height() - ITEMHEIGHT) / 2);
|
||||
for (PluginsItemInterface *plugin : plugins) {
|
||||
QIcon icon = plugin->icon(DockPart::QuickShow);
|
||||
QPixmap pixmapDraw = icon.pixmap(ITEMHEIGHT, ITEMHEIGHT);
|
||||
painter.drawPixmap(pointPixmap, pixmapDraw);
|
||||
pointPixmap.setX(pointPixmap.x() + ITEMWIDTH + ITEMSPACE);
|
||||
}
|
||||
} else {
|
||||
QPoint pointPixmap((pixmap.width() - ITEMWIDTH) / 2, ITEMSPACE);
|
||||
for (PluginsItemInterface *plugin : plugins) {
|
||||
QIcon icon = plugin->icon(DockPart::QuickShow);
|
||||
QPixmap pixmapDraw = icon.pixmap(ITEMHEIGHT, ITEMHEIGHT);
|
||||
painter.drawPixmap(pointPixmap, pixmapDraw);
|
||||
pointPixmap.setY(pointPixmap.y() + ITEMWIDTH + ITEMSPACE);
|
||||
}
|
||||
}
|
||||
painter.end();
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
bool IconManager::isFixedPlugin(PluginsItemInterface *plugin) const
|
||||
{
|
||||
return pluginNames.contains(plugin->pluginName());
|
||||
}
|
||||
|
||||
PluginsItemInterface *IconManager::findPlugin(const QString &pluginName) const
|
||||
{
|
||||
QList<PluginsItemInterface *> plugins = m_pluginController->currentPlugins();
|
||||
for (PluginsItemInterface *plugin : plugins) {
|
||||
if (plugin->pluginName() == pluginName)
|
||||
return plugin;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
52
plugins/pluginmanager/iconmanager.h
Normal file
52
plugins/pluginmanager/iconmanager.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2023 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef ICONMANAGER_H
|
||||
#define ICONMANAGER_H
|
||||
|
||||
#include "pluginsiteminterface.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QPixmap>
|
||||
|
||||
class DockPluginController;
|
||||
class PluginsItemInterface;
|
||||
|
||||
class IconManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit IconManager(DockPluginController *pluginController, QObject *parent = nullptr);
|
||||
void updateSize(QSize size);
|
||||
void setPosition(Dock::Position position);
|
||||
QPixmap pixmap() const;
|
||||
bool isFixedPlugin(PluginsItemInterface *plugin) const;
|
||||
|
||||
private:
|
||||
PluginsItemInterface *findPlugin(const QString &pluginName) const;
|
||||
|
||||
private:
|
||||
DockPluginController *m_pluginController;
|
||||
QSize m_size;
|
||||
Dock::Position m_position;
|
||||
};
|
||||
|
||||
#endif // ICONMANAGER_H
|
313
plugins/pluginmanager/largerquickitem.cpp
Normal file
313
plugins/pluginmanager/largerquickitem.cpp
Normal file
@ -0,0 +1,313 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "largerquickitem.h"
|
||||
#include "pluginsiteminterface.h"
|
||||
|
||||
#include <DFontSizeManager>
|
||||
#include <DGuiApplicationHelper>
|
||||
#include <DPaletteHelper>
|
||||
|
||||
#include <QLabel>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPainter>
|
||||
|
||||
#define BGSIZE 36
|
||||
#define ICONWIDTH 24
|
||||
#define ICONHEIGHT 24
|
||||
|
||||
DWIDGET_USE_NAMESPACE
|
||||
|
||||
static QSize expandSize = QSize(20, 20);
|
||||
|
||||
LargerQuickItem::LargerQuickItem(PluginsItemInterface *const pluginInter, const QString &itemKey, QWidget *parent)
|
||||
: QuickSettingItem(pluginInter, itemKey, parent)
|
||||
, m_iconWidget(nullptr)
|
||||
, m_nameLabel(nullptr)
|
||||
, m_stateLabel(nullptr)
|
||||
, m_itemWidgetParent(nullptr)
|
||||
{
|
||||
initUi();
|
||||
}
|
||||
|
||||
LargerQuickItem::~LargerQuickItem()
|
||||
{
|
||||
QWidget *itemWidget = pluginItem()->itemWidget(QUICK_ITEM_KEY);
|
||||
if (itemWidget)
|
||||
itemWidget->setParent(nullptr);
|
||||
}
|
||||
|
||||
void LargerQuickItem::doUpdate()
|
||||
{
|
||||
if (m_iconWidget && m_nameLabel && m_stateLabel) {
|
||||
m_iconWidget->update();
|
||||
m_nameLabel->setText(QFontMetrics(m_nameLabel->font()).elidedText(pluginItem()->pluginDisplayName(), Qt::TextElideMode::ElideRight, m_nameLabel->width()));
|
||||
m_stateLabel->setText(QFontMetrics(m_stateLabel->font()).elidedText(pluginItem()->description(), Qt::TextElideMode::ElideRight, m_stateLabel->width()));
|
||||
} else {
|
||||
QWidget *itemWidget = pluginItem()->itemWidget(QUICK_ITEM_KEY);
|
||||
if (itemWidget) {
|
||||
// 如果插件没有返回图标的显示,则获取插件的itemWidget
|
||||
itemWidget->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LargerQuickItem::detachPlugin()
|
||||
{
|
||||
QWidget *itemWidget = pluginItem()->itemWidget(QUICK_ITEM_KEY);
|
||||
if (itemWidget && itemWidget->parentWidget() == this)
|
||||
itemWidget->setParent(m_itemWidgetParent);
|
||||
}
|
||||
|
||||
QuickSettingItem::QuickItemStyle LargerQuickItem::type() const
|
||||
{
|
||||
return QuickSettingItem::QuickItemStyle::Larger;
|
||||
}
|
||||
|
||||
bool LargerQuickItem::eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
if (!m_iconWidget)
|
||||
return QuickSettingItem::eventFilter(obj, event);
|
||||
|
||||
switch (event->type()) {
|
||||
case QEvent::MouseButtonRelease: {
|
||||
if (obj->objectName() == "expandLabel") {
|
||||
// 如果是鼠标的按下事件
|
||||
QWidget *widget = pluginItem()->itemPopupApplet(QUICK_ITEM_KEY);
|
||||
if (widget)
|
||||
Q_EMIT requestShowChildWidget(widget);
|
||||
break;
|
||||
}
|
||||
if (obj == this) {
|
||||
QStringList commandArgumend = pluginItem()->itemCommand(itemKey()).split(" ");
|
||||
if (commandArgumend.size() == 0)
|
||||
break;
|
||||
|
||||
QString command = commandArgumend.first();
|
||||
commandArgumend.removeFirst();
|
||||
QProcess::startDetached(command, commandArgumend);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QEvent::Resize: {
|
||||
QLabel *labelWidget = qobject_cast<QLabel *>(obj);
|
||||
if (!labelWidget)
|
||||
break;
|
||||
|
||||
if (labelWidget == m_nameLabel) {
|
||||
labelWidget->setText(QFontMetrics(labelWidget->font()).elidedText(pluginItem()->pluginDisplayName(), Qt::TextElideMode::ElideRight, labelWidget->width()));
|
||||
break;
|
||||
}
|
||||
if (labelWidget == m_stateLabel) {
|
||||
labelWidget->setText(QFontMetrics(labelWidget->font()).elidedText(pluginItem()->description(), Qt::TextElideMode::ElideRight, labelWidget->width()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return QuickSettingItem::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
void LargerQuickItem::showEvent(QShowEvent *event)
|
||||
{
|
||||
QWidget *itemWidget = pluginItem()->itemWidget(QUICK_ITEM_KEY);
|
||||
if (pluginItem()->icon(DockPart::QuickPanel).isNull() && itemWidget) {
|
||||
itemWidget->setParent(this);
|
||||
itemWidget->setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
void LargerQuickItem::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QWidget *itemWidget = pluginItem()->itemWidget(QUICK_ITEM_KEY);
|
||||
if (pluginItem()->icon(DockPart::QuickPanel).isNull() && itemWidget) {
|
||||
itemWidget->setFixedSize(size());
|
||||
}
|
||||
|
||||
QuickSettingItem::resizeEvent(event);
|
||||
}
|
||||
|
||||
void LargerQuickItem::initUi()
|
||||
{
|
||||
QWidget *itemWidget = pluginItem()->itemWidget(QUICK_ITEM_KEY);
|
||||
if (pluginItem()->icon(DockPart::QuickPanel).isNull() && itemWidget) {
|
||||
m_itemWidgetParent = itemWidget->parentWidget();
|
||||
// 如果插件没有返回图标的显示,则获取插件的itemWidget
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout(this);
|
||||
itemWidget->setParent(this);
|
||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||
mainLayout->addWidget(itemWidget);
|
||||
itemWidget->setVisible(true);
|
||||
} else {
|
||||
// 如果插件获取到插件区域的图标,则让其按照图标来组合显示
|
||||
// 如果是占用两排的插件,则用横向Layout
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout(this);
|
||||
mainLayout->setContentsMargins(10, 0, 10, 0);
|
||||
mainLayout->setSpacing(0);
|
||||
mainLayout->addStretch(10);
|
||||
mainLayout->setAlignment(Qt::AlignCenter);
|
||||
|
||||
// 添加图标
|
||||
QWidget *iconWidgetParent = new QWidget(this);
|
||||
QVBoxLayout *iconLayout = new QVBoxLayout(iconWidgetParent);
|
||||
iconLayout->setContentsMargins(0, 0, 0, 0);
|
||||
iconLayout->setSpacing(0);
|
||||
iconLayout->setAlignment(Qt::AlignCenter);
|
||||
|
||||
m_iconWidget = new QuickIconWidget(pluginItem(), itemKey(), iconWidgetParent);
|
||||
m_iconWidget->setFixedSize(BGSIZE, BGSIZE);
|
||||
iconLayout->addWidget(m_iconWidget);
|
||||
mainLayout->addWidget(iconWidgetParent);
|
||||
mainLayout->addSpacing(10);
|
||||
|
||||
// 添加中间的名称部分
|
||||
QWidget *textWidget = new QWidget(this);
|
||||
m_nameLabel = new QLabel(textWidget);
|
||||
m_stateLabel = new QLabel(textWidget);
|
||||
m_nameLabel->setObjectName("nameLabel");
|
||||
m_stateLabel->setObjectName("stateLabel");
|
||||
|
||||
// 设置图标和文字的属性
|
||||
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(pluginItem()->pluginDisplayName());
|
||||
m_stateLabel->setText(pluginItem()->description());
|
||||
m_nameLabel->installEventFilter(this);
|
||||
m_stateLabel->installEventFilter(this);
|
||||
|
||||
QVBoxLayout *textLayout = new QVBoxLayout(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(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);
|
||||
}
|
||||
}
|
||||
|
||||
QString LargerQuickItem::expandFileName() const
|
||||
{
|
||||
if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType)
|
||||
return QString(":/icons/resources/arrow-right-dark.svg");
|
||||
|
||||
return QString(":/icons/resources/arrow-right.svg");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief QuickIconWidget::QuickIconWidget
|
||||
* @param pluginInter
|
||||
* @param parent
|
||||
* 图标的widget
|
||||
*/
|
||||
QuickIconWidget::QuickIconWidget(PluginsItemInterface *pluginInter, const QString &itemKey, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_pluginInter(pluginInter)
|
||||
, m_itemKey(itemKey)
|
||||
{
|
||||
}
|
||||
|
||||
void QuickIconWidget::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
QPixmap pixmapIcon = pluginIcon();
|
||||
if (pixmapIcon.isNull())
|
||||
return QWidget::paintEvent(event);
|
||||
|
||||
pixmapIcon = pluginIcon(true);
|
||||
QPainter painter(this);
|
||||
painter.setRenderHint(QPainter::RenderHint::Antialiasing);
|
||||
painter.setPen(foregroundColor());
|
||||
|
||||
DPalette dpa = DPaletteHelper::instance()->palette(this);
|
||||
QPainter pa(&pixmapIcon);
|
||||
pa.setCompositionMode(QPainter::CompositionMode_SourceIn);
|
||||
pa.fillRect(pixmapIcon.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() - pixmapIcon.width()) / 2, (rect().height() - pixmapIcon.height()) / 2, pixmapIcon.width(), pixmapIcon.height());
|
||||
painter.drawPixmap(rctIcon, pixmapIcon);
|
||||
}
|
||||
|
||||
QColor QuickIconWidget::foregroundColor() const
|
||||
{
|
||||
DPalette dpa = DPaletteHelper::instance()->palette(this);
|
||||
// TODO 此处的颜色是临时获取的,后期需要和设计师确认,改成正规的颜色
|
||||
if (m_pluginInter->status() == PluginsItemInterface::PluginMode::Active)
|
||||
return dpa.color(DPalette::ColorGroup::Active, DPalette::ColorRole::Text);
|
||||
|
||||
if (m_pluginInter->status() == PluginsItemInterface::PluginMode::Deactive)
|
||||
return dpa.color(DPalette::ColorGroup::Disabled, DPalette::ColorRole::Text);
|
||||
|
||||
return dpa.color(DPalette::ColorGroup::Normal, DPalette::ColorRole::Text);
|
||||
}
|
||||
|
||||
QPixmap QuickIconWidget::pluginIcon(bool contailGrab) const
|
||||
{
|
||||
QIcon icon = m_pluginInter->icon(DockPart::QuickPanel);
|
||||
if (icon.isNull() && contailGrab) {
|
||||
// 如果图标为空,就使用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<QSize> 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);
|
||||
}
|
82
plugins/pluginmanager/largerquickitem.h
Normal file
82
plugins/pluginmanager/largerquickitem.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef LARGERQUICKITEM_H
|
||||
#define LARGERQUICKITEM_H
|
||||
|
||||
#include <quicksettingitem.h>
|
||||
|
||||
class QuickIconWidget;
|
||||
class QWidget;
|
||||
class QLabel;
|
||||
|
||||
// 插件在快捷面板中的展示样式,这个为大图标,展示为两列的那种,例如网络和蓝牙
|
||||
class LargerQuickItem : public QuickSettingItem
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LargerQuickItem(PluginsItemInterface *const pluginInter, const QString &itemKey, QWidget *parent = nullptr);
|
||||
~LargerQuickItem() override;
|
||||
void doUpdate() override;
|
||||
void detachPlugin() override;
|
||||
|
||||
QuickItemStyle type() const override;
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
void showEvent(QShowEvent *event) override;
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
private:
|
||||
void initUi();
|
||||
QString expandFileName() const;
|
||||
|
||||
private:
|
||||
QuickIconWidget *m_iconWidget;
|
||||
QLabel *m_nameLabel;
|
||||
QLabel *m_stateLabel;
|
||||
QWidget *m_itemWidgetParent;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The QuickIconWidget class
|
||||
* 图标的Widget
|
||||
*/
|
||||
class QuickIconWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QuickIconWidget(PluginsItemInterface *pluginInter, const QString &itemKey, QWidget *parent = Q_NULLPTR);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
private:
|
||||
QColor foregroundColor() const;
|
||||
QPixmap pluginIcon(bool contailGrab = false) const;
|
||||
|
||||
private:
|
||||
PluginsItemInterface *m_pluginInter;
|
||||
QString m_itemKey;
|
||||
};
|
||||
|
||||
#endif // MULTIQUICKITEM_H
|
105
plugins/pluginmanager/linequickitem.cpp
Normal file
105
plugins/pluginmanager/linequickitem.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "linequickitem.h"
|
||||
#include "pluginsiteminterface.h"
|
||||
|
||||
#include <DBlurEffectWidget>
|
||||
|
||||
#include <QHBoxLayout>
|
||||
|
||||
DWIDGET_USE_NAMESPACE
|
||||
|
||||
LineQuickItem::LineQuickItem(PluginsItemInterface *const pluginInter, const QString &itemKey, QWidget *parent)
|
||||
: QuickSettingItem(pluginInter, itemKey, parent)
|
||||
, m_centerWidget(pluginInter->itemWidget(QUICK_ITEM_KEY))
|
||||
, m_centerParentWidget(nullptr)
|
||||
, m_effectWidget(new DBlurEffectWidget(this))
|
||||
{
|
||||
initUi();
|
||||
QMetaObject::invokeMethod(this, &LineQuickItem::resizeSelf, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
LineQuickItem::~LineQuickItem()
|
||||
{
|
||||
if (m_centerWidget)
|
||||
m_centerWidget->setParent(nullptr);
|
||||
}
|
||||
|
||||
void LineQuickItem::doUpdate()
|
||||
{
|
||||
if (m_centerWidget)
|
||||
m_centerWidget->update();
|
||||
}
|
||||
|
||||
void LineQuickItem::detachPlugin()
|
||||
{
|
||||
if (m_centerWidget)
|
||||
m_centerWidget->setParent(m_centerParentWidget);
|
||||
}
|
||||
|
||||
QuickSettingItem::QuickItemStyle LineQuickItem::type() const
|
||||
{
|
||||
return QuickSettingItem::QuickItemStyle::Line;
|
||||
}
|
||||
|
||||
bool LineQuickItem::eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
if (obj == m_centerWidget && event->type() == QEvent::Resize)
|
||||
resizeSelf();
|
||||
|
||||
return QuickSettingItem::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
void LineQuickItem::initUi()
|
||||
{
|
||||
QColor maskColor(Qt::white);
|
||||
maskColor.setAlphaF(0.8);
|
||||
m_effectWidget->setMaskColor(maskColor);
|
||||
m_effectWidget->setBlurRectXRadius(8);
|
||||
m_effectWidget->setBlurRectYRadius(8);
|
||||
|
||||
// 如果图标不为空
|
||||
if (!m_centerWidget)
|
||||
return;
|
||||
|
||||
m_centerWidget->setVisible(true);
|
||||
m_centerParentWidget = m_centerWidget->parentWidget();
|
||||
|
||||
QHBoxLayout *layout = new QHBoxLayout(m_effectWidget);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setAlignment(Qt::AlignHCenter);
|
||||
layout->addWidget(m_centerWidget);
|
||||
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout(this);
|
||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||
mainLayout->addWidget(m_effectWidget);
|
||||
|
||||
m_centerWidget->installEventFilter(this);
|
||||
}
|
||||
|
||||
void LineQuickItem::resizeSelf()
|
||||
{
|
||||
if (!m_centerWidget)
|
||||
return;
|
||||
|
||||
m_effectWidget->setFixedHeight(m_centerWidget->height());
|
||||
setFixedHeight(m_centerWidget->height());
|
||||
}
|
58
plugins/pluginmanager/linequickitem.h
Normal file
58
plugins/pluginmanager/linequickitem.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef LINEQUICKITEM_H
|
||||
#define LINEQUICKITEM_H
|
||||
|
||||
#include "quicksettingitem.h"
|
||||
|
||||
namespace Dtk {
|
||||
namespace Widget {
|
||||
class DBlurEffectWidget;
|
||||
}
|
||||
}
|
||||
|
||||
// 插件在快捷面板中的展示的样式,这个为整行显示的插件,例如声音,亮度调整和音乐播放等
|
||||
class LineQuickItem : public QuickSettingItem
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LineQuickItem(PluginsItemInterface *const pluginInter, const QString &itemKey, QWidget *parent = nullptr);
|
||||
~LineQuickItem() override;
|
||||
void doUpdate() override;
|
||||
void detachPlugin() override;
|
||||
|
||||
QuickItemStyle type() const override;
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
|
||||
private:
|
||||
void initUi();
|
||||
void resizeSelf();
|
||||
|
||||
private:
|
||||
QWidget *m_centerWidget;
|
||||
QWidget *m_centerParentWidget;
|
||||
Dtk::Widget::DBlurEffectWidget *m_effectWidget;
|
||||
};
|
||||
|
||||
#endif // FULLQUICKITEM_H
|
209
plugins/pluginmanager/pluginadapter/pluginadapter.cpp
Normal file
209
plugins/pluginmanager/pluginadapter/pluginadapter.cpp
Normal file
@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "pluginadapter.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#define ICONWIDTH 24
|
||||
#define ICONHEIGHT 24
|
||||
|
||||
PluginAdapter::PluginAdapter(PluginsItemInterface_V20 *pluginInter, QPluginLoader *pluginLoader)
|
||||
: m_pluginInter(pluginInter)
|
||||
, m_pluginLoader(pluginLoader)
|
||||
{
|
||||
}
|
||||
|
||||
PluginAdapter::~PluginAdapter()
|
||||
{
|
||||
delete m_pluginInter;
|
||||
}
|
||||
|
||||
const QString PluginAdapter::pluginName() const
|
||||
{
|
||||
return m_pluginInter->pluginName();
|
||||
}
|
||||
|
||||
const QString PluginAdapter::pluginDisplayName() const
|
||||
{
|
||||
return m_pluginInter->pluginDisplayName();
|
||||
}
|
||||
|
||||
void PluginAdapter::init(PluginProxyInterface *proxyInter)
|
||||
{
|
||||
m_pluginInter->init(proxyInter);
|
||||
}
|
||||
|
||||
QWidget *PluginAdapter::itemWidget(const QString &itemKey)
|
||||
{
|
||||
return m_pluginInter->itemWidget(itemKey);
|
||||
}
|
||||
|
||||
QWidget *PluginAdapter::itemTipsWidget(const QString &itemKey)
|
||||
{
|
||||
return m_pluginInter->itemTipsWidget(itemKey);
|
||||
}
|
||||
|
||||
QWidget *PluginAdapter::itemPopupApplet(const QString &itemKey)
|
||||
{
|
||||
return m_pluginInter->itemPopupApplet(itemKey);
|
||||
}
|
||||
|
||||
const QString PluginAdapter::itemCommand(const QString &itemKey)
|
||||
{
|
||||
return m_pluginInter->itemCommand(itemKey);
|
||||
}
|
||||
|
||||
const QString PluginAdapter::itemContextMenu(const QString &itemKey)
|
||||
{
|
||||
return m_pluginInter->itemContextMenu(itemKey);
|
||||
}
|
||||
|
||||
void PluginAdapter::invokedMenuItem(const QString &itemKey, const QString &menuId, const bool checked)
|
||||
{
|
||||
m_pluginInter->invokedMenuItem(itemKey, menuId, checked);
|
||||
}
|
||||
|
||||
int PluginAdapter::itemSortKey(const QString &itemKey)
|
||||
{
|
||||
return m_pluginInter->itemSortKey(itemKey);
|
||||
}
|
||||
|
||||
void PluginAdapter::setSortKey(const QString &itemKey, const int order)
|
||||
{
|
||||
m_pluginInter->setSortKey(itemKey, order);
|
||||
}
|
||||
|
||||
bool PluginAdapter::itemAllowContainer(const QString &itemKey)
|
||||
{
|
||||
return m_pluginInter->itemAllowContainer(itemKey);
|
||||
}
|
||||
|
||||
bool PluginAdapter::itemIsInContainer(const QString &itemKey)
|
||||
{
|
||||
return m_pluginInter->itemIsInContainer(itemKey);
|
||||
}
|
||||
|
||||
void PluginAdapter::setItemIsInContainer(const QString &itemKey, const bool container)
|
||||
{
|
||||
m_pluginInter->setItemIsInContainer(itemKey, container);
|
||||
}
|
||||
|
||||
bool PluginAdapter::pluginIsAllowDisable()
|
||||
{
|
||||
return m_pluginInter->pluginIsAllowDisable();
|
||||
}
|
||||
|
||||
bool PluginAdapter::pluginIsDisable()
|
||||
{
|
||||
return m_pluginInter->pluginIsDisable();
|
||||
}
|
||||
|
||||
void PluginAdapter::pluginStateSwitched()
|
||||
{
|
||||
m_pluginInter->pluginStateSwitched();
|
||||
}
|
||||
|
||||
void PluginAdapter::displayModeChanged(const Dock::DisplayMode displayMode)
|
||||
{
|
||||
m_pluginInter->displayModeChanged(displayMode);
|
||||
}
|
||||
|
||||
void PluginAdapter::positionChanged(const Dock::Position position)
|
||||
{
|
||||
m_pluginInter->positionChanged(position);
|
||||
}
|
||||
|
||||
void PluginAdapter::refreshIcon(const QString &itemKey)
|
||||
{
|
||||
m_pluginInter->refreshIcon(itemKey);
|
||||
}
|
||||
|
||||
void PluginAdapter::pluginSettingsChanged()
|
||||
{
|
||||
m_pluginInter->pluginSettingsChanged();
|
||||
}
|
||||
|
||||
PluginsItemInterface::PluginType PluginAdapter::type()
|
||||
{
|
||||
switch (m_pluginInter->type()) {
|
||||
case PluginsItemInterface_V20::PluginType::Fixed:
|
||||
return PluginsItemInterface::PluginType::Fixed;
|
||||
case PluginsItemInterface_V20::PluginType::Normal:
|
||||
return PluginsItemInterface::PluginType::Normal;
|
||||
}
|
||||
return PluginsItemInterface::PluginType::Normal;
|
||||
}
|
||||
|
||||
PluginsItemInterface::PluginSizePolicy PluginAdapter::pluginSizePolicy() const
|
||||
{
|
||||
switch (m_pluginInter->pluginSizePolicy()) {
|
||||
case PluginsItemInterface_V20::PluginSizePolicy::Custom:
|
||||
return PluginsItemInterface::PluginSizePolicy::Custom;
|
||||
case PluginsItemInterface_V20::PluginSizePolicy::System:
|
||||
return PluginsItemInterface::PluginSizePolicy::System;
|
||||
}
|
||||
return PluginsItemInterface::PluginSizePolicy::Custom;
|
||||
}
|
||||
|
||||
QIcon PluginAdapter::icon(const DockPart &dockPart, DGuiApplicationHelper::ColorType themeType)
|
||||
{
|
||||
QWidget *itemWidget = m_pluginInter->itemWidget(m_itemKey);
|
||||
if (!itemWidget)
|
||||
return QIcon();
|
||||
|
||||
switch (dockPart) {
|
||||
case DockPart::QuickPanel:
|
||||
case DockPart::SystemPanel: {
|
||||
// 如果图标为空,就使用itemWidget的截图作为它的图标,这种一般是适用于老版本插件或者没有实现v23接口的插件
|
||||
QSize oldSize = itemWidget->size();
|
||||
itemWidget->setFixedSize(ICONWIDTH, ICONHEIGHT);
|
||||
QPixmap pixmap = itemWidget->grab();
|
||||
itemWidget->setFixedSize(oldSize);
|
||||
return pixmap;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
|
||||
return QIcon();
|
||||
}
|
||||
|
||||
PluginsItemInterface::PluginMode PluginAdapter::status() const
|
||||
{
|
||||
return PluginMode::Active;
|
||||
}
|
||||
|
||||
QString PluginAdapter::description() const
|
||||
{
|
||||
return m_pluginInter->pluginDisplayName();
|
||||
}
|
||||
|
||||
PluginFlags PluginAdapter::flags() const
|
||||
{
|
||||
if (m_pluginLoader->fileName().contains(TRAY_PATH))
|
||||
return PluginFlag::Type_Tray | PluginFlag::Attribute_CanDrag | PluginFlag::Attribute_CanInsert;
|
||||
|
||||
return PluginsItemInterface::flags();
|
||||
}
|
||||
|
||||
void PluginAdapter::setItemKey(const QString &itemKey)
|
||||
{
|
||||
m_itemKey = itemKey;
|
||||
}
|
81
plugins/pluginmanager/pluginadapter/pluginadapter.h
Normal file
81
plugins/pluginmanager/pluginadapter/pluginadapter.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef PLUGINADAPTER_H
|
||||
#define PLUGINADAPTER_H
|
||||
|
||||
#include "pluginsiteminterface.h"
|
||||
#include "pluginsiteminterface_v20.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
/** 适配器,当加载到v20插件的时候,通过该接口来转成v23接口的插件
|
||||
* @brief The PluginAdapter class
|
||||
*/
|
||||
|
||||
class PluginAdapter : public QObject, public PluginsItemInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(PluginsItemInterface)
|
||||
|
||||
public:
|
||||
PluginAdapter(PluginsItemInterface_V20 *pluginInter, QPluginLoader *pluginLoader);
|
||||
~PluginAdapter();
|
||||
|
||||
const QString pluginName() const override;
|
||||
const QString pluginDisplayName() const override;
|
||||
void init(PluginProxyInterface *proxyInter) override;
|
||||
QWidget *itemWidget(const QString &itemKey) override;
|
||||
|
||||
QWidget *itemTipsWidget(const QString &itemKey) override;
|
||||
QWidget *itemPopupApplet(const QString &itemKey) override;
|
||||
const QString itemCommand(const QString &itemKey) override;
|
||||
const QString itemContextMenu(const QString &itemKey) override;
|
||||
void invokedMenuItem(const QString &itemKey, const QString &menuId, const bool checked) override;
|
||||
int itemSortKey(const QString &itemKey) override;
|
||||
void setSortKey(const QString &itemKey, const int order) override;
|
||||
bool itemAllowContainer(const QString &itemKey) override;
|
||||
bool itemIsInContainer(const QString &itemKey) override;
|
||||
void setItemIsInContainer(const QString &itemKey, const bool container) override;
|
||||
|
||||
bool pluginIsAllowDisable() override;
|
||||
bool pluginIsDisable() override;
|
||||
void pluginStateSwitched() override;
|
||||
void displayModeChanged(const Dock::DisplayMode displayMode) override;
|
||||
void positionChanged(const Dock::Position position) override;
|
||||
void refreshIcon(const QString &itemKey) override;
|
||||
void pluginSettingsChanged() override;
|
||||
PluginType type() override;
|
||||
PluginSizePolicy pluginSizePolicy() const override;
|
||||
|
||||
QIcon icon(const DockPart &dockPart, DGuiApplicationHelper::ColorType themeType = DGuiApplicationHelper::instance()->themeType()) override;
|
||||
PluginMode status() const override;
|
||||
QString description() const override;
|
||||
PluginFlags flags() const override;
|
||||
|
||||
void setItemKey(const QString &itemKey);
|
||||
|
||||
private:
|
||||
PluginsItemInterface_V20 *m_pluginInter;
|
||||
QString m_itemKey;
|
||||
QPluginLoader *m_pluginLoader;
|
||||
};
|
||||
|
||||
#endif // PLUGINADAPTER_H
|
261
plugins/pluginmanager/pluginadapter/pluginsiteminterface_v20.h
Normal file
261
plugins/pluginmanager/pluginadapter/pluginsiteminterface_v20.h
Normal file
@ -0,0 +1,261 @@
|
||||
/*
|
||||
* Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PLUGINSITEMINTERFACE_V20_H
|
||||
#define PLUGINSITEMINTERFACE_V20_H
|
||||
|
||||
#include "pluginproxyinterface.h"
|
||||
|
||||
#include <QIcon>
|
||||
#include <QtCore>
|
||||
|
||||
///
|
||||
/// \brief The PluginsItemInterface_V20 class
|
||||
/// the dock plugins item interface, all dock plugins should
|
||||
/// inheirt this class and override all pure virtual function.
|
||||
///
|
||||
class PluginsItemInterface_V20
|
||||
{
|
||||
public:
|
||||
enum PluginType {
|
||||
Normal,
|
||||
Fixed
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Plugin size policy
|
||||
*/
|
||||
enum PluginSizePolicy {
|
||||
System = 1 << 0, // Follow the system
|
||||
Custom = 1 << 1 // The custom
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief ~PluginsItemInterface_V20
|
||||
/// DON'T try to delete m_proxyInter.
|
||||
///
|
||||
virtual ~PluginsItemInterface_V20() {}
|
||||
|
||||
///
|
||||
/// \brief pluginName
|
||||
/// tell dock the unique plugin id
|
||||
/// \return
|
||||
///
|
||||
virtual const QString pluginName() const = 0;
|
||||
virtual const QString pluginDisplayName() const { return QString(); }
|
||||
|
||||
///
|
||||
/// \brief init
|
||||
/// init your plugins, you need to save proxyInter to m_proxyInter
|
||||
/// member variable. but you shouldn't free this pointer.
|
||||
/// \param proxyInter
|
||||
/// DON'T try to delete this pointer.
|
||||
///
|
||||
virtual void init(PluginProxyInterface *proxyInter) = 0;
|
||||
///
|
||||
/// \brief itemWidget
|
||||
/// your plugin item widget, each item should have a unique key.
|
||||
/// \param itemKey
|
||||
/// your widget' unqiue key.
|
||||
/// \return
|
||||
///
|
||||
virtual QWidget *itemWidget(const QString &itemKey) = 0;
|
||||
|
||||
///
|
||||
/// \brief itemTipsWidget
|
||||
/// override this function if your item want to have a tips.
|
||||
/// the tips will shown when user hover your item.
|
||||
/// nullptr will be ignored.
|
||||
/// \param itemKey
|
||||
/// \return
|
||||
///
|
||||
virtual QWidget *itemTipsWidget(const QString &itemKey) {Q_UNUSED(itemKey); return nullptr;}
|
||||
///
|
||||
/// \brief itemPopupApplet
|
||||
/// override this function if your item wants to have an popup applet.
|
||||
/// the popup applet will shown when user click your item.
|
||||
///
|
||||
/// Tips:
|
||||
/// dock should receive mouse press/release event to check user mouse operate,
|
||||
/// if your item filter mouse event, this function will not be called.
|
||||
/// so if you override mouse event and want to use popup applet, you
|
||||
/// should pass event to your parent use QWidget::someEvent(e);
|
||||
/// \param itemKey
|
||||
/// \return
|
||||
///
|
||||
virtual QWidget *itemPopupApplet(const QString &itemKey) {Q_UNUSED(itemKey); return nullptr;}
|
||||
///
|
||||
/// \brief itemCommand
|
||||
/// execute spec command when user clicked your item.
|
||||
/// ensure your command do not get user input.
|
||||
///
|
||||
/// empty string will be ignored.
|
||||
/// \param itemKey
|
||||
/// \return
|
||||
///
|
||||
virtual const QString itemCommand(const QString &itemKey) {Q_UNUSED(itemKey); return QString();}
|
||||
|
||||
///
|
||||
/// \brief itemContextMenu
|
||||
/// context menu is shown when RequestPopupMenu called.
|
||||
/// \param itemKey
|
||||
/// \return
|
||||
///
|
||||
virtual const QString itemContextMenu(const QString &itemKey) {Q_UNUSED(itemKey); return QString();}
|
||||
///
|
||||
/// \brief invokedMenuItem
|
||||
/// call if context menu item is clicked
|
||||
/// \param itemKey
|
||||
/// \param itemId
|
||||
/// menu item id
|
||||
/// \param checked
|
||||
///
|
||||
virtual void invokedMenuItem(const QString &itemKey, const QString &menuId, const bool checked) {Q_UNUSED(itemKey); Q_UNUSED(menuId); Q_UNUSED(checked);}
|
||||
|
||||
///
|
||||
/// \brief itemSortKey
|
||||
/// tell dock where your item wants to put on.
|
||||
///
|
||||
/// this index is start from 1 and
|
||||
/// 0 for left side
|
||||
/// -1 for right side
|
||||
/// \param itemKey
|
||||
/// \return
|
||||
///
|
||||
virtual int itemSortKey(const QString &itemKey) {Q_UNUSED(itemKey); return 1;}
|
||||
///
|
||||
/// \brief setSortKey
|
||||
/// save your item new position
|
||||
/// sort key will be changed when plugins order
|
||||
/// changed(by user drag-drop)
|
||||
/// \param itemKey
|
||||
/// \param order
|
||||
///
|
||||
virtual void setSortKey(const QString &itemKey, const int order) {Q_UNUSED(itemKey); Q_UNUSED(order);}
|
||||
|
||||
///
|
||||
/// \brief itemAllowContainer
|
||||
/// tell dock is your item allow to move into container
|
||||
///
|
||||
/// if your item placed into container, popup tips and popup
|
||||
/// applet will be disabled.
|
||||
/// \param itemKey
|
||||
/// \return
|
||||
///
|
||||
virtual bool itemAllowContainer(const QString &itemKey) {Q_UNUSED(itemKey); return false;}
|
||||
///
|
||||
/// \brief itemIsInContainer
|
||||
/// tell dock your item is in container, this function
|
||||
/// called at item init and if your item enable container.
|
||||
/// \param itemKey
|
||||
/// \return
|
||||
///
|
||||
virtual bool itemIsInContainer(const QString &itemKey) {Q_UNUSED(itemKey); return false;}
|
||||
///
|
||||
/// \brief setItemIsInContainer
|
||||
/// save your item new state.
|
||||
/// this function called when user drag out your item from
|
||||
/// container or user drop item into container(if your item
|
||||
/// allow drop into container).
|
||||
/// \param itemKey
|
||||
/// \param container
|
||||
///
|
||||
virtual void setItemIsInContainer(const QString &itemKey, const bool container) {Q_UNUSED(itemKey); Q_UNUSED(container);}
|
||||
|
||||
virtual bool pluginIsAllowDisable() { return false; }
|
||||
virtual bool pluginIsDisable() { return false; }
|
||||
virtual void pluginStateSwitched() {}
|
||||
|
||||
///
|
||||
/// \brief displayModeChanged
|
||||
/// override this function to receive display mode changed signal
|
||||
/// \param displayMode
|
||||
///
|
||||
virtual void displayModeChanged(const Dock::DisplayMode displayMode) {Q_UNUSED(displayMode);}
|
||||
///
|
||||
/// \brief positionChanged
|
||||
/// override this function to receive dock position changed signal
|
||||
/// \param position
|
||||
///
|
||||
virtual void positionChanged(const Dock::Position position) {Q_UNUSED(position);}
|
||||
|
||||
///
|
||||
/// \brief refreshIcon
|
||||
/// refresh item icon, its triggered when system icon theme changed.
|
||||
/// \param itemKey
|
||||
/// item key
|
||||
///
|
||||
virtual void refreshIcon(const QString &itemKey) { Q_UNUSED(itemKey); }
|
||||
|
||||
///
|
||||
/// \brief displayMode
|
||||
/// get current dock display mode
|
||||
/// \return
|
||||
///
|
||||
inline Dock::DisplayMode displayMode() const
|
||||
{
|
||||
return qApp->property(PROP_DISPLAY_MODE).value<Dock::DisplayMode>();
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief position
|
||||
/// get current dock position
|
||||
/// \return
|
||||
///
|
||||
inline Dock::Position position() const
|
||||
{
|
||||
return qApp->property(PROP_POSITION).value<Dock::Position>();
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief settingsChanged
|
||||
/// override this function to receive plugin settings changed signal(DeepinSync)
|
||||
///
|
||||
virtual void pluginSettingsChanged() {}
|
||||
|
||||
///
|
||||
/// \brief type
|
||||
/// default plugin add dock right,fixed plugin add to dock fixed area
|
||||
///
|
||||
virtual PluginType type() { return Normal; }
|
||||
|
||||
///
|
||||
/// \brief plugin size policy
|
||||
/// default plugin size policy
|
||||
///
|
||||
virtual PluginSizePolicy pluginSizePolicy() const { return System; }
|
||||
|
||||
protected:
|
||||
///
|
||||
/// \brief m_proxyInter
|
||||
/// NEVER delete this object.
|
||||
///
|
||||
PluginProxyInterface *m_proxyInter = nullptr;
|
||||
};
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#define ModuleInterfaceV20_iid "com.deepin.dock.PluginsItemInterface"
|
||||
|
||||
Q_DECLARE_INTERFACE(PluginsItemInterface_V20, ModuleInterfaceV20_iid)
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // PLUGINSITEMINTERFACE_H
|
146
plugins/pluginmanager/pluginchildpage.cpp
Normal file
146
plugins/pluginmanager/pluginchildpage.cpp
Normal file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "pluginchildpage.h"
|
||||
|
||||
#include <DStyle>
|
||||
#include <DGuiApplicationHelper>
|
||||
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include <QEvent>
|
||||
#include <QPainterPath>
|
||||
#include <QPushButton>
|
||||
|
||||
DWIDGET_USE_NAMESPACE
|
||||
DGUI_USE_NAMESPACE
|
||||
|
||||
PluginChildPage::PluginChildPage(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_headerWidget(new QWidget(this))
|
||||
, m_back(new QPushButton(m_headerWidget))
|
||||
, m_title(new QLabel(m_headerWidget))
|
||||
, m_container(new QWidget(this))
|
||||
, m_topWidget(nullptr)
|
||||
, m_containerLayout(new QVBoxLayout(m_container))
|
||||
{
|
||||
initUi();
|
||||
initConnection();
|
||||
}
|
||||
|
||||
PluginChildPage::~PluginChildPage()
|
||||
{
|
||||
}
|
||||
|
||||
void PluginChildPage::pushWidget(QWidget *widget)
|
||||
{
|
||||
// 首先将界面其他的窗体移除
|
||||
for (int i = m_containerLayout->count() - 1; i >= 0; i--) {
|
||||
QLayoutItem *item = m_containerLayout->itemAt(i);
|
||||
item->widget()->removeEventFilter(this);
|
||||
item->widget()->hide();
|
||||
m_containerLayout->removeItem(item);
|
||||
}
|
||||
m_topWidget = widget;
|
||||
if (widget) {
|
||||
widget->installEventFilter(this);
|
||||
m_containerLayout->addWidget(widget);
|
||||
widget->show();
|
||||
}
|
||||
QMetaObject::invokeMethod(this, &PluginChildPage::resetHeight, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void PluginChildPage::setTitle(const QString &text)
|
||||
{
|
||||
m_title->setText(text);
|
||||
}
|
||||
|
||||
void PluginChildPage::initUi()
|
||||
{
|
||||
m_back->setIcon(backPixmap());
|
||||
m_back->setFixedWidth(24);
|
||||
m_back->setFlat(true);
|
||||
m_title->setAlignment(Qt::AlignCenter);
|
||||
QHBoxLayout *headerLayout = new QHBoxLayout(m_headerWidget);
|
||||
headerLayout->setContentsMargins(11, 12, 24 + 11, 12);
|
||||
headerLayout->setSpacing(0);
|
||||
headerLayout->addWidget(m_back);
|
||||
headerLayout->addWidget(m_title);
|
||||
m_headerWidget->setFixedHeight(48);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout(this);
|
||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||
mainLayout->setSpacing(0);
|
||||
|
||||
mainLayout->addWidget(m_headerWidget);
|
||||
mainLayout->addWidget(m_container);
|
||||
m_containerLayout->setContentsMargins(11, 0, 11, 0);
|
||||
m_containerLayout->setSpacing(0);
|
||||
}
|
||||
|
||||
void PluginChildPage::initConnection()
|
||||
{
|
||||
connect(m_back, &QPushButton::clicked, this, &PluginChildPage::back);
|
||||
}
|
||||
|
||||
bool PluginChildPage::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
if (watched == m_topWidget && event->type() == QEvent::Resize) {
|
||||
resetHeight();
|
||||
}
|
||||
return QWidget::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
void PluginChildPage::resetHeight()
|
||||
{
|
||||
QMargins m = m_containerLayout->contentsMargins();
|
||||
m_container->setFixedHeight(m.top() + m.bottom() + (m_topWidget ? m_topWidget->height() : 0));
|
||||
setFixedHeight(m_headerWidget->height() + m_container->height());
|
||||
}
|
||||
|
||||
QPixmap PluginChildPage::backPixmap() const
|
||||
{
|
||||
QPixmap pixmap(16, 16);
|
||||
pixmap.fill(Qt::transparent);
|
||||
|
||||
// 设置背景色
|
||||
QColor backColor;
|
||||
if (DGuiApplicationHelper::ColorType::DarkType == DGuiApplicationHelper::instance()->themeType()) {
|
||||
backColor = Qt::black;
|
||||
backColor.setAlphaF(0.05);
|
||||
} else {
|
||||
backColor = Qt::white;
|
||||
backColor.setAlphaF(0.2);
|
||||
}
|
||||
QPainter painter(&pixmap);
|
||||
painter.setRenderHints(QPainter::SmoothPixmapTransform | QPainter::Antialiasing);
|
||||
painter.setPen(Qt::NoPen);
|
||||
QPainterPath path;
|
||||
path.addEllipse(pixmap.rect());
|
||||
painter.fillPath(path, backColor);
|
||||
QSize arrowSize(10, 10);
|
||||
QPixmap arrowPixmap = DStyle::standardIcon(style(), DStyle::SP_ArrowLeave).pixmap(arrowSize);
|
||||
// 让其居中显示
|
||||
QSize backSize = pixmap.size();
|
||||
painter.drawPixmap((backSize.width() - arrowSize.width()) / 2, (backSize.height() - arrowSize.height()) / 2,
|
||||
arrowSize.width(), arrowSize.height(), arrowPixmap);
|
||||
painter.end();
|
||||
return pixmap;
|
||||
}
|
61
plugins/pluginmanager/pluginchildpage.h
Normal file
61
plugins/pluginmanager/pluginchildpage.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef PLUGINCHILDPAGE_H
|
||||
#define PLUGINCHILDPAGE_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QPushButton;
|
||||
class QLabel;
|
||||
class QVBoxLayout;
|
||||
|
||||
class PluginChildPage : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PluginChildPage(QWidget *parent);
|
||||
~PluginChildPage() override;
|
||||
void pushWidget(QWidget *widget);
|
||||
void setTitle(const QString &text);
|
||||
|
||||
Q_SIGNALS:
|
||||
void back();
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *watched, QEvent *event) override;
|
||||
|
||||
private:
|
||||
void initUi();
|
||||
void initConnection();
|
||||
void resetHeight();
|
||||
QPixmap backPixmap() const;
|
||||
|
||||
private:
|
||||
QWidget *m_headerWidget;
|
||||
QPushButton *m_back;
|
||||
QLabel *m_title;
|
||||
QWidget *m_container;
|
||||
QWidget *m_topWidget;
|
||||
QVBoxLayout *m_containerLayout;
|
||||
};
|
||||
|
||||
#endif // PLUGINCHILDPAGE_H
|
195
plugins/pluginmanager/pluginmanager.cpp
Normal file
195
plugins/pluginmanager/pluginmanager.cpp
Normal file
@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright (C) 2023 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "pluginmanager.h"
|
||||
#include "dockplugincontroller.h"
|
||||
#include "quicksettingcontainer.h"
|
||||
#include "iconmanager.h"
|
||||
|
||||
#include <QResizeEvent>
|
||||
|
||||
PluginManager::PluginManager(QObject *parent)
|
||||
: m_dockController(nullptr)
|
||||
, m_iconManager(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
const QString PluginManager::pluginName() const
|
||||
{
|
||||
return "pluginManager";
|
||||
}
|
||||
|
||||
const QString PluginManager::pluginDisplayName() const
|
||||
{
|
||||
return "pluginManager";
|
||||
}
|
||||
|
||||
void PluginManager::init(PluginProxyInterface *proxyInter)
|
||||
{
|
||||
if (m_proxyInter == proxyInter)
|
||||
return;
|
||||
|
||||
m_proxyInter = proxyInter;
|
||||
|
||||
m_dockController.reset(new DockPluginController(proxyInter));
|
||||
m_quickContainer.reset(new QuickSettingContainer(m_dockController.data()));
|
||||
m_iconManager.reset(new IconManager(m_dockController.data()));
|
||||
m_iconManager->setPosition(position());
|
||||
|
||||
connect(m_dockController.data(), &DockPluginController::pluginInserted, this, [ this ](PluginsItemInterface *itemInter) {
|
||||
if (m_iconManager->isFixedPlugin(itemInter)) {
|
||||
m_proxyInter->itemUpdate(this, pluginName());
|
||||
}
|
||||
});
|
||||
connect(m_dockController.data(), &DockPluginController::pluginUpdated, this, [ this ](PluginsItemInterface *itemInter) {
|
||||
if (m_iconManager->isFixedPlugin(itemInter)) {
|
||||
m_proxyInter->itemUpdate(this, pluginName());
|
||||
}
|
||||
});
|
||||
connect(m_dockController.data(), &DockPluginController::pluginRemoved, this, [ this ](PluginsItemInterface *itemInter) {
|
||||
if (m_iconManager->isFixedPlugin(itemInter)) {
|
||||
m_proxyInter->itemUpdate(this, pluginName());
|
||||
}
|
||||
});
|
||||
connect(m_dockController.data(), &DockPluginController::requestAppletVisible, this, [ this ](PluginsItemInterface *itemInter, const QString &itemKey, bool visible) {
|
||||
if (visible) {
|
||||
QWidget *appletWidget = itemInter->itemPopupApplet(itemKey);
|
||||
if (appletWidget)
|
||||
m_quickContainer->showPage(appletWidget, itemInter);
|
||||
} else {
|
||||
// 显示主面板
|
||||
m_quickContainer->topLevelWidget()->hide();
|
||||
}
|
||||
});
|
||||
connect(m_dockController.data(), &DockPluginController::pluginLoadFinished, this, &PluginManager::pluginLoadFinished);
|
||||
|
||||
// 开始加载插件
|
||||
m_dockController->startLoadPlugin(getPluginPaths());
|
||||
|
||||
m_proxyInter->itemAdded(this, pluginName());
|
||||
}
|
||||
|
||||
QWidget *PluginManager::itemWidget(const QString &itemKey)
|
||||
{
|
||||
Q_UNUSED(itemKey);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QWidget *PluginManager::itemPopupApplet(const QString &itemKey)
|
||||
{
|
||||
if (itemKey == QUICK_ITEM_KEY) {
|
||||
// 返回快捷面板
|
||||
return m_quickContainer.data();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QIcon PluginManager::icon(const DockPart &dockPart, DGuiApplicationHelper::ColorType themeType)
|
||||
{
|
||||
if (dockPart == DockPart::QuickShow) {
|
||||
return m_iconManager->pixmap();
|
||||
}
|
||||
|
||||
return QIcon();
|
||||
}
|
||||
|
||||
PluginFlags PluginManager::flags() const
|
||||
{
|
||||
// 当前快捷插件组合区域只支持在快捷区域显示
|
||||
return PluginFlag::Type_Common | PluginFlag::Attribute_ForceDock;
|
||||
}
|
||||
|
||||
PluginsItemInterface::PluginSizePolicy PluginManager::pluginSizePolicy() const
|
||||
{
|
||||
return PluginSizePolicy::Custom;
|
||||
}
|
||||
|
||||
bool PluginManager::eventHandler(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::Resize) {
|
||||
QResizeEvent *resizeEvent = static_cast<QResizeEvent *>(event);
|
||||
m_iconManager->updateSize(resizeEvent->size());
|
||||
}
|
||||
return PluginsItemInterface::eventHandler(event);
|
||||
}
|
||||
|
||||
void PluginManager::positionChanged(const Dock::Position position)
|
||||
{
|
||||
m_iconManager->setPosition(position);
|
||||
m_proxyInter->itemUpdate(this, pluginName());
|
||||
}
|
||||
|
||||
QList<PluginsItemInterface *> PluginManager::plugins() const
|
||||
{
|
||||
return m_dockController->plugins();
|
||||
}
|
||||
|
||||
QList<PluginsItemInterface *> PluginManager::pluginsInSetting() const
|
||||
{
|
||||
return m_dockController->pluginsInSetting();
|
||||
}
|
||||
|
||||
QList<PluginsItemInterface *> PluginManager::currentPlugins() const
|
||||
{
|
||||
return m_dockController->currentPlugins();
|
||||
}
|
||||
|
||||
QString PluginManager::itemKey(PluginsItemInterface *itemInter) const
|
||||
{
|
||||
return m_dockController->itemKey(itemInter);
|
||||
}
|
||||
|
||||
QJsonObject PluginManager::metaData(PluginsItemInterface *itemInter) const
|
||||
{
|
||||
return m_dockController->metaData(itemInter);
|
||||
}
|
||||
|
||||
#ifndef QT_DEBUG
|
||||
static QStringList getPathFromConf(const QString &key) {
|
||||
QSettings set("/etc/deepin/dde-dock.conf", QSettings::IniFormat);
|
||||
auto value = set.value(key).toString();
|
||||
if (!value.isEmpty()) {
|
||||
return value.split(':');
|
||||
}
|
||||
|
||||
return QStringList();
|
||||
}
|
||||
#endif
|
||||
|
||||
QStringList PluginManager::getPluginPaths() const
|
||||
{
|
||||
QStringList pluginPaths;
|
||||
#ifdef QT_DEBUG
|
||||
pluginPaths << QString("%1/..%2").arg(qApp->applicationDirPath()).arg(QUICK_PATH)
|
||||
<< QString("%1/..%2").arg(qApp->applicationDirPath()).arg(PLUGIN_PATH)
|
||||
<< QString("%1/..%2").arg(qApp->applicationDirPath()).arg(TRAY_PATH);
|
||||
#else
|
||||
pluginPaths << QString("/usr/lib/dde-dock%1").arg(QUICK_PATH)
|
||||
<< QString("/usr/lib/dde-dock%1").arg(PLUGIN_PATH)
|
||||
<< QString("/usr/lib/dde-dock%1").arg(TRAY_PATH);
|
||||
|
||||
const QStringList pluginsDirs = (getPathFromConf("PATH") << getPathFromConf("SYSTEM_TRAY_PATH"));
|
||||
if (!pluginsDirs.isEmpty())
|
||||
pluginPaths << pluginsDirs;
|
||||
#endif
|
||||
|
||||
return pluginPaths;
|
||||
}
|
72
plugins/pluginmanager/pluginmanager.h
Normal file
72
plugins/pluginmanager/pluginmanager.h
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2023 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef PLUGINMANAGER_H
|
||||
#define PLUGINMANAGER_H
|
||||
|
||||
#include "pluginsiteminterface.h"
|
||||
#include "pluginmanagerinterface.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class DockPluginController;
|
||||
class QuickSettingContainer;
|
||||
class IconManager;
|
||||
|
||||
class PluginManager : public PluginManagerInterface, public PluginsItemInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(PluginsItemInterface)
|
||||
Q_PLUGIN_METADATA(IID "com.deepin.dock.PluginsItemInterface" FILE "pluginmanager.json")
|
||||
|
||||
public:
|
||||
explicit PluginManager(QObject *parent = nullptr);
|
||||
|
||||
const QString pluginName() const override;
|
||||
const QString pluginDisplayName() const override;
|
||||
void init(PluginProxyInterface *proxyInter) override;
|
||||
QWidget *itemWidget(const QString &itemKey) override;
|
||||
QWidget *itemPopupApplet(const QString &itemKey) override;
|
||||
QIcon icon(const DockPart &dockPart, DGuiApplicationHelper::ColorType themeType) override;
|
||||
PluginFlags flags() const override;
|
||||
PluginSizePolicy pluginSizePolicy() const override;
|
||||
|
||||
protected:
|
||||
bool eventHandler(QEvent *event) override;
|
||||
void positionChanged(const Dock::Position position) override;
|
||||
|
||||
protected:
|
||||
// 实现PluginManagerInterface接口,用于向dock提供所有已经加载的插件
|
||||
QList<PluginsItemInterface *> plugins() const override;
|
||||
QList<PluginsItemInterface *> pluginsInSetting() const override;
|
||||
QList<PluginsItemInterface *> currentPlugins() const override;
|
||||
QString itemKey(PluginsItemInterface *itemInter) const override;
|
||||
QJsonObject metaData(PluginsItemInterface *itemInter) const override;
|
||||
|
||||
private:
|
||||
QStringList getPluginPaths() const;
|
||||
|
||||
private:
|
||||
QSharedPointer<DockPluginController> m_dockController;
|
||||
QSharedPointer<QuickSettingContainer> m_quickContainer;
|
||||
QSharedPointer<IconManager> m_iconManager;
|
||||
};
|
||||
|
||||
#endif // PLUGINMANAGER_H
|
4
plugins/pluginmanager/pluginmanager.json
Normal file
4
plugins/pluginmanager/pluginmanager.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"api": "2.0.0",
|
||||
"order":0
|
||||
}
|
5
plugins/pluginmanager/pluginmanager.qrc
Normal file
5
plugins/pluginmanager/pluginmanager.qrc
Normal file
@ -0,0 +1,5 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>resources/dock_control.dci</file>
|
||||
</qresource>
|
||||
</RCC>
|
415
plugins/pluginmanager/quicksettingcontainer.cpp
Normal file
415
plugins/pluginmanager/quicksettingcontainer.cpp
Normal file
@ -0,0 +1,415 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "quicksettingcontainer.h"
|
||||
#include "dockplugincontroller.h"
|
||||
#include "pluginsiteminterface.h"
|
||||
#include "quicksettingitem.h"
|
||||
#include "pluginchildpage.h"
|
||||
#include "utils.h"
|
||||
#include "quickdragcore.h"
|
||||
|
||||
#include <DListView>
|
||||
#include <DStyle>
|
||||
|
||||
#include <QDrag>
|
||||
#include <QVBoxLayout>
|
||||
#include <QMetaObject>
|
||||
#include <QStackedLayout>
|
||||
#include <QMouseEvent>
|
||||
#include <QLabel>
|
||||
#include <QBitmap>
|
||||
#include <QPainterPath>
|
||||
|
||||
DWIDGET_USE_NAMESPACE
|
||||
|
||||
struct QuickDragInfo {
|
||||
QPoint dragPosition;
|
||||
QWidget *dragItem = nullptr;
|
||||
PluginsItemInterface *pluginInter = nullptr;
|
||||
void reset() {
|
||||
dragPosition.setX(0);
|
||||
dragPosition.setY(0);
|
||||
dragItem = nullptr;
|
||||
pluginInter = nullptr;
|
||||
}
|
||||
bool isNull() {
|
||||
return !dragItem;
|
||||
}
|
||||
} QuickDragInfo;
|
||||
|
||||
#define ITEMWIDTH 70
|
||||
#define ITEMHEIGHT 60
|
||||
#define ITEMSPACE 10
|
||||
#define COLUMNCOUNT 4
|
||||
|
||||
QuickSettingContainer::QuickSettingContainer(DockPluginController *pluginController, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_switchLayout(new QStackedLayout(this))
|
||||
, m_mainWidget(new QWidget(this))
|
||||
, m_pluginWidget(new QWidget(m_mainWidget))
|
||||
, m_pluginLayout(new QGridLayout(m_pluginWidget))
|
||||
, m_componentWidget(new QWidget(m_mainWidget))
|
||||
, m_mainlayout(new QVBoxLayout(m_mainWidget))
|
||||
, m_pluginController(pluginController)
|
||||
, m_childPage(new PluginChildPage(this))
|
||||
, m_dragInfo(new struct QuickDragInfo)
|
||||
, m_childShowPlugin(nullptr)
|
||||
{
|
||||
initUi();
|
||||
initConnection();
|
||||
m_childPage->installEventFilter(this);
|
||||
setMouseTracking(true);
|
||||
}
|
||||
|
||||
QuickSettingContainer::~QuickSettingContainer()
|
||||
{
|
||||
delete m_dragInfo;
|
||||
}
|
||||
|
||||
void QuickSettingContainer::showPage(QWidget *widget, PluginsItemInterface *pluginInter)
|
||||
{
|
||||
if (widget && pluginInter && widget != m_mainWidget) {
|
||||
m_childShowPlugin = pluginInter;
|
||||
m_childPage->setTitle(pluginInter->pluginDisplayName());
|
||||
m_childPage->pushWidget(widget);
|
||||
m_switchLayout->setCurrentWidget(m_childPage);
|
||||
} else {
|
||||
m_childShowPlugin = nullptr;
|
||||
m_switchLayout->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
onResizeView();
|
||||
}
|
||||
|
||||
bool QuickSettingContainer::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
switch (event->type()) {
|
||||
case QEvent::Resize: {
|
||||
onResizeView();
|
||||
break;
|
||||
}
|
||||
case QEvent::MouseButtonPress: {
|
||||
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
|
||||
QuickSettingItem *item = qobject_cast<QuickSettingItem *>(watched);
|
||||
if (item) {
|
||||
m_dragInfo->dragPosition = mouseEvent->pos();
|
||||
m_dragInfo->dragItem = item;
|
||||
m_dragInfo->pluginInter = item->pluginItem();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QEvent::MouseButtonRelease: {
|
||||
m_dragInfo->reset();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return QWidget::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
void QuickSettingContainer::showEvent(QShowEvent *event)
|
||||
{
|
||||
// 当面板显示的时候,直接默认显示快捷面板的窗口
|
||||
QWidget::showEvent(event);
|
||||
if (m_switchLayout->currentWidget() != m_mainWidget) {
|
||||
m_childPage->pushWidget(nullptr);
|
||||
m_switchLayout->setCurrentWidget(m_mainWidget);
|
||||
onResizeView();
|
||||
}
|
||||
}
|
||||
|
||||
void QuickSettingContainer::appendPlugin(PluginsItemInterface *itemInter, QString itemKey, bool needLayout)
|
||||
{
|
||||
QuickSettingItem *quickItem = QuickSettingFactory::createQuickWidget(itemInter, itemKey);
|
||||
if (!quickItem)
|
||||
return;
|
||||
|
||||
quickItem->setParent(m_pluginWidget);
|
||||
quickItem->setMouseTracking(true);
|
||||
quickItem->installEventFilter(this);
|
||||
connect(quickItem, &QuickSettingItem::requestShowChildWidget, this, &QuickSettingContainer::onShowChildWidget);
|
||||
m_quickSettings << quickItem;
|
||||
if (quickItem->type() == QuickSettingItem::QuickItemStyle::Line) {
|
||||
// 插件位置占据整行,例如声音、亮度和音乐等
|
||||
m_componentWidget->layout()->addWidget(quickItem);
|
||||
updateFullItemLayout();
|
||||
} else if (needLayout) {
|
||||
// 插件占据两行或者一行
|
||||
updateItemLayout();
|
||||
}
|
||||
|
||||
onResizeView();
|
||||
}
|
||||
|
||||
void QuickSettingContainer::onPluginRemove(PluginsItemInterface *itemInter)
|
||||
{
|
||||
QList<QuickSettingItem *>::Iterator removeItemIter = std::find_if(m_quickSettings.begin(), m_quickSettings.end(), [ = ](QuickSettingItem *item)->bool {
|
||||
return item->pluginItem() == itemInter;
|
||||
});
|
||||
|
||||
if (removeItemIter == m_quickSettings.end())
|
||||
return;
|
||||
|
||||
QuickSettingItem *removeItem = *removeItemIter;
|
||||
removeItem->detachPlugin();
|
||||
|
||||
if (removeItem->type() == QuickSettingItem::QuickItemStyle::Line)
|
||||
m_componentWidget->layout()->removeWidget(removeItem);
|
||||
else
|
||||
m_pluginLayout->removeWidget(removeItem);
|
||||
|
||||
m_quickSettings.removeOne(removeItem);
|
||||
removeItem->deleteLater();
|
||||
if (m_childShowPlugin == itemInter)
|
||||
showPage(nullptr);
|
||||
|
||||
updateItemLayout();
|
||||
updateFullItemLayout();
|
||||
onResizeView();
|
||||
}
|
||||
|
||||
void QuickSettingContainer::onShowChildWidget(QWidget *childWidget)
|
||||
{
|
||||
QuickSettingItem *quickWidget = qobject_cast<QuickSettingItem *>(sender());
|
||||
if (!quickWidget)
|
||||
return;
|
||||
|
||||
showPage(childWidget, quickWidget->pluginItem());
|
||||
}
|
||||
|
||||
void QuickSettingContainer::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if (m_dragInfo->isNull())
|
||||
return;
|
||||
|
||||
QPoint pointCurrent = event->pos();
|
||||
if (qAbs(m_dragInfo->dragPosition.x() - pointCurrent.x()) > 5
|
||||
|| qAbs(m_dragInfo->dragPosition.y() - pointCurrent.y()) > 5) {
|
||||
QuickSettingItem *moveItem = qobject_cast<QuickSettingItem *>(m_dragInfo->dragItem);
|
||||
QuickIconDrag *drag = new QuickIconDrag(this, moveItem->dragPixmap());
|
||||
QuickPluginMimeData *mimedata = new QuickPluginMimeData(m_dragInfo->pluginInter, drag);
|
||||
drag->setMimeData(mimedata);
|
||||
drag->setDragHotPot(m_dragInfo->dragPosition);
|
||||
|
||||
m_dragInfo->reset();
|
||||
drag->exec(Qt::CopyAction);
|
||||
}
|
||||
}
|
||||
|
||||
void QuickSettingContainer::updateItemLayout()
|
||||
{
|
||||
// 清空之前的控件,重新添加
|
||||
while (m_pluginLayout->count() > 0)
|
||||
m_pluginLayout->takeAt(0);
|
||||
|
||||
// 将插件按照两列和一列的顺序来进行排序
|
||||
QMap<QuickSettingItem::QuickItemStyle, QList<QuickSettingItem *>> quickSettings;
|
||||
QMap<QuickSettingItem::QuickItemStyle, QMap<QuickSettingItem *, int>> orderQuickSettings;
|
||||
for (QuickSettingItem *item : m_quickSettings) {
|
||||
QuickSettingItem::QuickItemStyle type = item->type();
|
||||
if (type == QuickSettingItem::QuickItemStyle::Line)
|
||||
continue;
|
||||
|
||||
QJsonObject metaData = m_pluginController->metaData(item->pluginItem());
|
||||
if (metaData.contains("order"))
|
||||
orderQuickSettings[type][item] = metaData.value("order").toInt();
|
||||
else
|
||||
quickSettings[type] << item;
|
||||
}
|
||||
// 将需要排序的插件按照顺序插入到原来的数组中
|
||||
for (auto itQuick = orderQuickSettings.begin(); itQuick != orderQuickSettings.end(); itQuick++) {
|
||||
QuickSettingItem::QuickItemStyle type = itQuick.key();
|
||||
QMap<QuickSettingItem *, int> &orderQuicks = itQuick.value();
|
||||
for (auto it = orderQuicks.begin(); it != orderQuicks.end(); it++) {
|
||||
int index = it.value();
|
||||
if (index >= 0 && index < quickSettings[type].size())
|
||||
quickSettings[type][index] = it.key();
|
||||
else
|
||||
quickSettings[type] << it.key();
|
||||
}
|
||||
}
|
||||
auto insertQuickSetting = [ quickSettings, this ](QuickSettingItem::QuickItemStyle type, int &row, int &column) {
|
||||
if (!quickSettings.contains(type))
|
||||
return;
|
||||
|
||||
int usedColumn = (type == QuickSettingItem::QuickItemStyle::Larger ? 2 : 1);
|
||||
QList<QuickSettingItem *> quickPlugins = quickSettings[type];
|
||||
for (QuickSettingItem *quickItem : quickPlugins) {
|
||||
quickItem->setVisible(true);
|
||||
m_pluginLayout->addWidget(quickItem, row, column, 1, usedColumn);
|
||||
column += usedColumn;
|
||||
if (column >= COLUMNCOUNT) {
|
||||
row++;
|
||||
column = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int row = 0;
|
||||
int column = 0;
|
||||
insertQuickSetting(QuickSettingItem::QuickItemStyle::Larger, row, column);
|
||||
insertQuickSetting(QuickSettingItem::QuickItemStyle::Standard, row, column);
|
||||
}
|
||||
|
||||
void QuickSettingContainer::updateFullItemLayout()
|
||||
{
|
||||
while (m_componentWidget->layout()->count() > 0)
|
||||
m_componentWidget->layout()->takeAt(0);
|
||||
|
||||
QList<QuickSettingItem *> fullItems;
|
||||
QMap<QuickSettingItem *, int> fullItemOrder;
|
||||
for (QuickSettingItem *item : m_quickSettings) {
|
||||
if (item->type() != QuickSettingItem::QuickItemStyle::Line)
|
||||
continue;
|
||||
|
||||
fullItems << item;
|
||||
int order = -1;
|
||||
QJsonObject metaData = m_pluginController->metaData(item->pluginItem());
|
||||
if (metaData.contains("order"))
|
||||
order = metaData.value("order").toInt();
|
||||
|
||||
fullItemOrder[item] = order;
|
||||
}
|
||||
|
||||
std::sort(fullItems.begin(), fullItems.end(), [ fullItemOrder, fullItems ](QuickSettingItem *item1, QuickSettingItem *item2) {
|
||||
int order1 = fullItemOrder.value(item1, -1);
|
||||
int order2 = fullItemOrder.value(item2, -1);
|
||||
if (order1 == order2) {
|
||||
// 如果两个值相等,就根据他们的加载顺序进行排序
|
||||
return fullItems.indexOf(item1) < fullItems.indexOf(item2);
|
||||
}
|
||||
if (order1 == -1)
|
||||
return false;
|
||||
if (order2 == -1)
|
||||
return true;
|
||||
|
||||
return order1 < order2;
|
||||
});
|
||||
|
||||
for (QuickSettingItem *item : fullItems) {
|
||||
item->setVisible(true);
|
||||
m_componentWidget->layout()->addWidget(item);
|
||||
}
|
||||
}
|
||||
|
||||
void QuickSettingContainer::initUi()
|
||||
{
|
||||
m_mainlayout->setSpacing(ITEMSPACE);
|
||||
m_mainlayout->setContentsMargins(ITEMSPACE, ITEMSPACE, ITEMSPACE, ITEMSPACE);
|
||||
|
||||
m_pluginLayout->setContentsMargins(0, 0, 0, 0);
|
||||
m_pluginLayout->setSpacing(ITEMSPACE);
|
||||
m_pluginLayout->setAlignment(Qt::AlignLeft);
|
||||
for (int i = 0; i < COLUMNCOUNT; i++)
|
||||
m_pluginLayout->setColumnMinimumWidth(i, ITEMWIDTH);
|
||||
|
||||
m_pluginWidget->setLayout(m_pluginLayout);
|
||||
m_mainlayout->addWidget(m_pluginWidget);
|
||||
|
||||
QVBoxLayout *ctrlLayout = new QVBoxLayout(m_componentWidget);
|
||||
ctrlLayout->setContentsMargins(0, 0, 0, 0);
|
||||
ctrlLayout->setSpacing(ITEMSPACE);
|
||||
ctrlLayout->setDirection(QBoxLayout::BottomToTop);
|
||||
|
||||
m_mainlayout->addWidget(m_componentWidget);
|
||||
// 加载所有的可以在快捷面板显示的插件
|
||||
QList<PluginsItemInterface *> plugins = m_pluginController->currentPlugins();
|
||||
for (PluginsItemInterface *plugin : plugins) {
|
||||
appendPlugin(plugin, m_pluginController->itemKey(plugin), false);
|
||||
}
|
||||
|
||||
m_switchLayout->addWidget(m_mainWidget);
|
||||
m_switchLayout->addWidget(m_childPage);
|
||||
|
||||
setMouseTracking(true);
|
||||
setAcceptDrops(true);
|
||||
|
||||
QMetaObject::invokeMethod(this, [ = ] {
|
||||
if (plugins.size() > 0) {
|
||||
updateItemLayout();
|
||||
updateFullItemLayout();
|
||||
}
|
||||
// 设置当前窗口的大小
|
||||
onResizeView();
|
||||
setFixedWidth(ITEMWIDTH * 4 + (ITEMSPACE * 5));
|
||||
}, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void QuickSettingContainer::initConnection()
|
||||
{
|
||||
connect(m_pluginController, &DockPluginController::pluginInserted, this, [ = ](PluginsItemInterface *itemInter, QString itemKey) {
|
||||
appendPlugin(itemInter, itemKey);
|
||||
});
|
||||
connect(m_pluginController, &DockPluginController::pluginRemoved, this, &QuickSettingContainer::onPluginRemove);
|
||||
connect(m_pluginController, &DockPluginController::pluginUpdated, this, &QuickSettingContainer::onPluginUpdated);
|
||||
|
||||
connect(m_childPage, &PluginChildPage::back, this, [ this ] {
|
||||
showPage(m_mainWidget);
|
||||
});
|
||||
}
|
||||
|
||||
// 调整尺寸
|
||||
void QuickSettingContainer::onResizeView()
|
||||
{
|
||||
if (m_switchLayout->currentWidget() == m_mainWidget) {
|
||||
int selfPluginCount = 0;
|
||||
int fullItemHeight = 0;
|
||||
int widgetCount = 0;
|
||||
for (QuickSettingItem *item : m_quickSettings) {
|
||||
item->setFixedHeight(ITEMHEIGHT);
|
||||
if (item->type() == QuickSettingItem::QuickItemStyle::Line) {
|
||||
fullItemHeight += item->height();
|
||||
widgetCount++;
|
||||
continue;
|
||||
}
|
||||
// 如果是置顶的插件,则认为它占用两个普通插件的位置
|
||||
int increCount = (item->type() == QuickSettingItem::QuickItemStyle::Larger ? 2 : 1);
|
||||
selfPluginCount += increCount;
|
||||
}
|
||||
|
||||
int rowCount = selfPluginCount / COLUMNCOUNT;
|
||||
if (selfPluginCount % COLUMNCOUNT > 0)
|
||||
rowCount++;
|
||||
|
||||
m_pluginWidget->setFixedHeight(ITEMHEIGHT * rowCount + ITEMSPACE * (rowCount - 1));
|
||||
m_componentWidget->setFixedHeight(fullItemHeight + (widgetCount - 1) * ITEMSPACE);
|
||||
|
||||
setFixedHeight(ITEMSPACE * 3 + m_pluginWidget->height() + m_componentWidget->height());
|
||||
} else if (m_switchLayout->currentWidget() == m_childPage) {
|
||||
setFixedHeight(m_childPage->height());
|
||||
}
|
||||
}
|
||||
|
||||
void QuickSettingContainer::onPluginUpdated(PluginsItemInterface *itemInter, const DockPart dockPart)
|
||||
{
|
||||
if (dockPart != DockPart::QuickPanel)
|
||||
return;
|
||||
|
||||
for (QuickSettingItem *settingItem : m_quickSettings) {
|
||||
if (settingItem->pluginItem() != itemInter)
|
||||
continue;
|
||||
|
||||
settingItem->doUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
94
plugins/pluginmanager/quicksettingcontainer.h
Normal file
94
plugins/pluginmanager/quicksettingcontainer.h
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef QUICKSETTINGCONTAINER_H
|
||||
#define QUICKSETTINGCONTAINER_H
|
||||
|
||||
#include "pluginproxyinterface.h"
|
||||
|
||||
#include "dtkwidget_global.h"
|
||||
|
||||
#include <DListView>
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class DockItem;
|
||||
class QVBoxLayout;
|
||||
class DockPluginController;
|
||||
class BrightnessModel;
|
||||
class BrightnessWidget;
|
||||
class QuickSettingItem;
|
||||
class QStackedLayout;
|
||||
class VolumeDevicesWidget;
|
||||
class QLabel;
|
||||
class PluginChildPage;
|
||||
class QGridLayout;
|
||||
class DisplaySettingWidget;
|
||||
struct QuickDragInfo;
|
||||
|
||||
DWIDGET_USE_NAMESPACE
|
||||
|
||||
class QuickSettingContainer : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
void showPage(QWidget *widget, PluginsItemInterface *pluginInter = nullptr);
|
||||
explicit QuickSettingContainer(DockPluginController *pluginController, QWidget *parent = nullptr);
|
||||
~QuickSettingContainer() override;
|
||||
|
||||
protected:
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
bool eventFilter(QObject *watched, QEvent *event) override;
|
||||
void showEvent(QShowEvent *event) override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onPluginRemove(PluginsItemInterface *itemInter);
|
||||
void onShowChildWidget(QWidget *childWidget);
|
||||
void onResizeView();
|
||||
void onPluginUpdated(PluginsItemInterface *itemInter, const DockPart dockPart);
|
||||
|
||||
private:
|
||||
// 加载UI
|
||||
void initUi();
|
||||
// 初始化槽函数
|
||||
void initConnection();
|
||||
// 调整控件位置
|
||||
void updateItemLayout();
|
||||
// 调整全列插件的位置
|
||||
void updateFullItemLayout();
|
||||
// 插入插件
|
||||
void appendPlugin(PluginsItemInterface *itemInter, QString itemKey, bool needLayout = true);
|
||||
|
||||
private:
|
||||
QStackedLayout *m_switchLayout;
|
||||
QWidget *m_mainWidget;
|
||||
QWidget *m_pluginWidget;
|
||||
QGridLayout *m_pluginLayout;
|
||||
QWidget *m_componentWidget;
|
||||
QVBoxLayout *m_mainlayout;
|
||||
DockPluginController *m_pluginController;
|
||||
PluginChildPage *m_childPage;
|
||||
QuickDragInfo *m_dragInfo;
|
||||
QList<QuickSettingItem *> m_quickSettings;
|
||||
PluginsItemInterface *m_childShowPlugin;
|
||||
};
|
||||
|
||||
#endif // PLUGINCONTAINER_H
|
148
plugins/pluginmanager/quicksettingitem.cpp
Normal file
148
plugins/pluginmanager/quicksettingitem.cpp
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "quicksettingitem.h"
|
||||
#include "pluginsiteminterface.h"
|
||||
#include "imageutil.h"
|
||||
#include "largerquickitem.h"
|
||||
#include "standardquickitem.h"
|
||||
#include "linequickitem.h"
|
||||
|
||||
#include <DGuiApplicationHelper>
|
||||
#include <DFontSizeManager>
|
||||
#include <DPaletteHelper>
|
||||
|
||||
#include <QIcon>
|
||||
#include <QPainterPath>
|
||||
#include <QPushButton>
|
||||
#include <QFontMetrics>
|
||||
#include <QPainter>
|
||||
|
||||
#define ICONWIDTH 24
|
||||
#define ICONHEIGHT 24
|
||||
#define ICONSPACE 10
|
||||
#define RADIUS 8
|
||||
#define FONTSIZE 10
|
||||
|
||||
#define BGWIDTH 128
|
||||
#define BGSIZE 36
|
||||
#define MARGINLEFTSPACE 10
|
||||
#define OPENICONSIZE 12
|
||||
#define MARGINRIGHTSPACE 9
|
||||
|
||||
DWIDGET_USE_NAMESPACE
|
||||
|
||||
QuickSettingItem::QuickSettingItem(PluginsItemInterface *const pluginInter, const QString &itemKey, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_pluginInter(pluginInter)
|
||||
, m_itemKey(itemKey)
|
||||
{
|
||||
setAcceptDrops(true);
|
||||
this->installEventFilter(this);
|
||||
}
|
||||
|
||||
QuickSettingItem::~QuickSettingItem()
|
||||
{
|
||||
}
|
||||
|
||||
PluginsItemInterface *QuickSettingItem::pluginItem() const
|
||||
{
|
||||
return m_pluginInter;
|
||||
}
|
||||
|
||||
const QPixmap QuickSettingItem::dragPixmap()
|
||||
{
|
||||
QPixmap pluginPixmap = m_pluginInter->icon(DockPart::QuickPanel, DGuiApplicationHelper::instance()->themeType()).pixmap(ICONWIDTH, ICONHEIGHT);
|
||||
|
||||
QPainter foregroundPainter(&pluginPixmap);
|
||||
foregroundPainter.setPen(foregroundColor());
|
||||
foregroundPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
|
||||
foregroundPainter.fillRect(pluginPixmap.rect(), foregroundColor());
|
||||
|
||||
QPixmap pixmapDrag(ICONWIDTH + ICONSPACE + FONTSIZE * 2, ICONHEIGHT + ICONSPACE + FONTSIZE * 2);
|
||||
pixmapDrag.fill(Qt::transparent);
|
||||
QPainter painter(&pixmapDrag);
|
||||
painter.drawPixmap(QPoint((ICONSPACE + FONTSIZE * 2) / 2, 0), pluginPixmap);
|
||||
painter.setPen(foregroundPainter.pen());
|
||||
|
||||
QFont font;
|
||||
font.setPixelSize(FONTSIZE);
|
||||
painter.setFont(font);
|
||||
QTextOption option;
|
||||
option.setAlignment(Qt::AlignTop | Qt::AlignHCenter);
|
||||
painter.drawText(QRect(QPoint(0, ICONHEIGHT + ICONSPACE),
|
||||
QPoint(pixmapDrag.width(), pixmapDrag.height())), m_pluginInter->pluginDisplayName(), option);
|
||||
return pixmapDrag;
|
||||
}
|
||||
|
||||
const QString QuickSettingItem::itemKey() const
|
||||
{
|
||||
return m_itemKey;
|
||||
}
|
||||
|
||||
void QuickSettingItem::paintEvent(QPaintEvent *e)
|
||||
{
|
||||
QWidget::paintEvent(e);
|
||||
QPainter painter(this);
|
||||
painter.setRenderHint(QPainter::RenderHint::Antialiasing);
|
||||
painter.setPen(foregroundColor());
|
||||
QPainterPath path;
|
||||
path.addRoundedRect(rect(), RADIUS, RADIUS);
|
||||
painter.setClipPath(path);
|
||||
// 绘制背景色
|
||||
QColor backColor(Qt::white);
|
||||
if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::ColorType::DarkType) {
|
||||
backColor = Qt::black;
|
||||
backColor.setAlphaF(0.5);
|
||||
}
|
||||
DPalette dpa = DPaletteHelper::instance()->palette(this);
|
||||
painter.fillRect(rect(), backColor);
|
||||
}
|
||||
|
||||
QColor QuickSettingItem::foregroundColor() const
|
||||
{
|
||||
DPalette dpa = DPaletteHelper::instance()->palette(this);
|
||||
// TODO: 此处的颜色是临时获取的,后期需要和设计师确认,改成正规的颜色
|
||||
if (m_pluginInter->status() == PluginsItemInterface::PluginMode::Active)
|
||||
return dpa.color(DPalette::ColorGroup::Active, DPalette::ColorRole::Text);
|
||||
|
||||
if (m_pluginInter->status() == PluginsItemInterface::PluginMode::Deactive)
|
||||
return dpa.color(DPalette::ColorGroup::Disabled, DPalette::ColorRole::Text);
|
||||
|
||||
return dpa.color(DPalette::ColorGroup::Normal, DPalette::ColorRole::Text);
|
||||
}
|
||||
|
||||
QuickSettingItem *QuickSettingFactory::createQuickWidget(PluginsItemInterface * const pluginInter, const QString &itemKey)
|
||||
{
|
||||
// 如果显示在面板的图标或者Widget为空,则不让显示(例如电池插件)
|
||||
if (!(pluginInter->flags() & PluginFlag::Type_Common))
|
||||
return nullptr;
|
||||
|
||||
if (pluginInter->flags() & PluginFlag::Quick_Multi)
|
||||
return new LargerQuickItem(pluginInter, itemKey);
|
||||
|
||||
if (pluginInter->flags() & PluginFlag::Quick_Full)
|
||||
return new LineQuickItem(pluginInter, itemKey);
|
||||
|
||||
if (pluginInter->flags() & PluginFlag::Quick_Single)
|
||||
return new StandardQuickItem(pluginInter, itemKey);
|
||||
|
||||
return nullptr;
|
||||
}
|
69
plugins/pluginmanager/quicksettingitem.h
Normal file
69
plugins/pluginmanager/quicksettingitem.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef QUICKSETTINGITEM_H
|
||||
#define QUICKSETTINGITEM_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class PluginsItemInterface;
|
||||
class QuickIconWidget;
|
||||
|
||||
class QuickSettingItem : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum class QuickItemStyle {
|
||||
Standard = 1, // 插件的UI显示单列
|
||||
Larger, // 插件的UI显示双列,例如网络和蓝牙等
|
||||
Line // 插件的UI整行显示,例如声音,亮度、音乐播放等
|
||||
};
|
||||
|
||||
public:
|
||||
QuickSettingItem(PluginsItemInterface *const pluginInter, const QString &itemKey, QWidget *parent = nullptr);
|
||||
~QuickSettingItem() override;
|
||||
PluginsItemInterface *pluginItem() const;
|
||||
virtual const QPixmap dragPixmap();
|
||||
virtual void doUpdate() {}
|
||||
virtual void detachPlugin() {}
|
||||
const QString itemKey() const;
|
||||
|
||||
virtual QuickItemStyle type() const = 0;
|
||||
|
||||
Q_SIGNALS:
|
||||
void requestShowChildWidget(QWidget *);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
QColor foregroundColor() const;
|
||||
|
||||
private:
|
||||
PluginsItemInterface *m_pluginInter;
|
||||
QString m_itemKey;
|
||||
};
|
||||
|
||||
class QuickSettingFactory
|
||||
{
|
||||
public:
|
||||
static QuickSettingItem *createQuickWidget(PluginsItemInterface *const pluginInter, const QString &itemKey);
|
||||
};
|
||||
|
||||
#endif // QUICKSETTINGITEM_H
|
BIN
plugins/pluginmanager/resources/dock_control.dci
Normal file
BIN
plugins/pluginmanager/resources/dock_control.dci
Normal file
Binary file not shown.
200
plugins/pluginmanager/standardquickitem.cpp
Normal file
200
plugins/pluginmanager/standardquickitem.cpp
Normal file
@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "standardquickitem.h"
|
||||
#include "pluginsiteminterface.h"
|
||||
|
||||
#include <DFontSizeManager>
|
||||
#include <DGuiApplicationHelper>
|
||||
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
|
||||
#define ICONHEIGHT 24
|
||||
#define ICONWIDTH 24
|
||||
#define TEXTHEIGHT 11
|
||||
|
||||
DWIDGET_USE_NAMESPACE
|
||||
|
||||
StandardQuickItem::StandardQuickItem(PluginsItemInterface *const pluginInter, const QString &itemKey, QWidget *parent)
|
||||
: QuickSettingItem(pluginInter, itemKey, parent)
|
||||
, m_itemParentWidget(nullptr)
|
||||
, m_needPaint(true)
|
||||
{
|
||||
initUi();
|
||||
}
|
||||
|
||||
StandardQuickItem::~StandardQuickItem()
|
||||
{
|
||||
}
|
||||
|
||||
QuickSettingItem::QuickItemStyle StandardQuickItem::type() const
|
||||
{
|
||||
return QuickSettingItem::QuickItemStyle::Standard;
|
||||
}
|
||||
|
||||
void StandardQuickItem::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
QStringList commandArgument = pluginItem()->itemCommand(itemKey()).split(" ");
|
||||
if (commandArgument.size() > 0) {
|
||||
QString command = commandArgument.first();
|
||||
commandArgument.removeFirst();
|
||||
QProcess::startDetached(command, commandArgument);
|
||||
}
|
||||
}
|
||||
|
||||
void StandardQuickItem::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
doUpdate();
|
||||
QuickSettingItem::resizeEvent(event);
|
||||
}
|
||||
|
||||
void StandardQuickItem::initUi()
|
||||
{
|
||||
QWidget *topWidget = iconWidget(this);
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->addWidget(topWidget);
|
||||
installEventFilter(this);
|
||||
}
|
||||
|
||||
QWidget *StandardQuickItem::iconWidget(QWidget *parent)
|
||||
{
|
||||
// 显示图标的窗体
|
||||
QWidget *widget = new QWidget(parent);
|
||||
m_needPaint = true;
|
||||
QIcon icon = pluginItem()->icon(DockPart::QuickPanel);
|
||||
if (icon.isNull()) {
|
||||
// 如果图标为空,则将获取itemWidget作为它的显示
|
||||
QWidget *itemWidget = pluginItem()->itemWidget(QUICK_ITEM_KEY);
|
||||
if (itemWidget) {
|
||||
m_itemParentWidget = itemWidget->parentWidget();
|
||||
QHBoxLayout *layout = new QHBoxLayout(widget);
|
||||
layout->setContentsMargins(0, 0, 0 ,0);
|
||||
itemWidget->setParent(widget);
|
||||
layout->addWidget(itemWidget);
|
||||
itemWidget->setVisible(true);
|
||||
m_needPaint = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_needPaint) {
|
||||
// 如果没有子窗体,则需要添加下方的文字
|
||||
QVBoxLayout *layout = new QVBoxLayout(widget);
|
||||
layout->setAlignment(Qt::AlignVCenter);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setSpacing(0);
|
||||
QLabel *imageLabel = new QLabel(widget);
|
||||
imageLabel->setObjectName("imageLabel");
|
||||
imageLabel->setFixedHeight(ICONHEIGHT);
|
||||
imageLabel->setAlignment(Qt::AlignCenter);
|
||||
|
||||
QLabel *labelText = new QLabel(widget);
|
||||
labelText->setObjectName("textLabel");
|
||||
labelText->setFixedHeight(TEXTHEIGHT);
|
||||
updatePluginName(labelText);
|
||||
labelText->setAlignment(Qt::AlignCenter);
|
||||
labelText->setFont(DFontSizeManager::instance()->t10());
|
||||
layout->addWidget(imageLabel);
|
||||
layout->addSpacing(7);
|
||||
layout->addWidget(labelText);
|
||||
}
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
QPixmap StandardQuickItem::pixmap() const
|
||||
{
|
||||
// 如果快捷面板区域的图标为空,那么就获取itemWidget的截图
|
||||
QIcon icon = pluginItem()->icon(DockPart::QuickPanel);
|
||||
if (icon.isNull())
|
||||
return QPixmap();
|
||||
|
||||
int pixmapWidth = ICONWIDTH;
|
||||
int pixmapHeight = ICONHEIGHT;
|
||||
QList<QSize> 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 / qApp->devicePixelRatio(), pixmapHeight / qApp->devicePixelRatio());
|
||||
}
|
||||
|
||||
QLabel *StandardQuickItem::findChildLabel(QWidget *parent, const QString &childObjectName) const
|
||||
{
|
||||
QList<QObject *> childrends = parent->children();
|
||||
for (QObject *child : childrends) {
|
||||
QWidget *widget = qobject_cast<QWidget *>(child);
|
||||
if (!widget)
|
||||
continue;
|
||||
|
||||
QLabel *label = qobject_cast<QLabel *>(child);
|
||||
if (label && widget->objectName() == childObjectName)
|
||||
return label;
|
||||
|
||||
label = findChildLabel(widget, childObjectName);
|
||||
if (label)
|
||||
return label;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void StandardQuickItem::updatePluginName(QLabel *textLabel)
|
||||
{
|
||||
if (!textLabel)
|
||||
return;
|
||||
|
||||
QString text = pluginItem()->description();
|
||||
if (text.isEmpty())
|
||||
text = pluginItem()->pluginDisplayName();
|
||||
QFontMetrics ftm(textLabel->font());
|
||||
text = ftm.elidedText(text, Qt::TextElideMode::ElideRight, textLabel->width());
|
||||
textLabel->setText(text);
|
||||
}
|
||||
|
||||
void StandardQuickItem::doUpdate()
|
||||
{
|
||||
if (m_needPaint) {
|
||||
QLabel *imageLabel = findChildLabel(this, "imageLabel");
|
||||
if (imageLabel) {
|
||||
// 更新图像
|
||||
imageLabel->setPixmap(pixmap());
|
||||
}
|
||||
updatePluginName(findChildLabel(this, "textLabel"));
|
||||
} else {
|
||||
QWidget *itemWidget = pluginItem()->itemWidget(QUICK_ITEM_KEY);
|
||||
if (itemWidget)
|
||||
itemWidget->update();
|
||||
}
|
||||
}
|
||||
|
||||
void StandardQuickItem::detachPlugin()
|
||||
{
|
||||
QWidget *itemWidget = pluginItem()->itemWidget(QUICK_ITEM_KEY);
|
||||
if (itemWidget && !m_needPaint)
|
||||
itemWidget->setParent(m_itemParentWidget);
|
||||
}
|
57
plugins/pluginmanager/standardquickitem.h
Normal file
57
plugins/pluginmanager/standardquickitem.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* Maintainer: donghualin <donghualin@uniontech.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef STANDARDQUICKITEM_H
|
||||
#define STANDARDQUICKITEM_H
|
||||
|
||||
#include "quicksettingitem.h"
|
||||
|
||||
class QLabel;
|
||||
|
||||
// 插件在快捷面板中展示的样式,这个为默认,展示一行一列的那种
|
||||
class StandardQuickItem : public QuickSettingItem
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
StandardQuickItem(PluginsItemInterface *const pluginInter, const QString &itemKey, QWidget *parent = nullptr);
|
||||
~StandardQuickItem() override;
|
||||
|
||||
QuickItemStyle type() const override;
|
||||
void doUpdate() override;
|
||||
void detachPlugin() override;
|
||||
|
||||
protected:
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
private:
|
||||
void initUi();
|
||||
QWidget *iconWidget(QWidget *parent);
|
||||
QPixmap pixmap() const;
|
||||
QLabel *findChildLabel(QWidget *parent, const QString &childObjectName) const;
|
||||
void updatePluginName(QLabel *textLabel);
|
||||
|
||||
private:
|
||||
QWidget *m_itemParentWidget;
|
||||
bool m_needPaint;
|
||||
};
|
||||
|
||||
#endif // SINGLEQUICKITEM_H
|
Loading…
x
Reference in New Issue
Block a user