From db3e5f79da3bf7662f3cde24073797966322c675 Mon Sep 17 00:00:00 2001 From: donghualin Date: Tue, 18 Oct 2022 10:24:21 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=9B=BE=E6=A0=87=E5=A2=9E=E5=8A=A0too?= =?UTF-8?q?lTip=E5=92=8C=E8=8F=9C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 分别在QuickDockItem类,SystemPluginItem类和SystemPluginItem类中增加如下处理 1、增加toolTip功能 2、增加右键菜单功能 Log: 图标增加toolTip和菜单 Influence: 鼠标放入到托盘区域、快捷插件区域,关机区域,观察是否存在toolTip,右键,观察是否弹出菜单 Task: https://pms.uniontech.com/task-view-112073.html Change-Id: I7a700d9b9e4ee3c0681ae0de39712f3f5ae83224 --- frame/window/quickpluginwindow.cpp | 142 +++++++++++++++++- frame/window/quickpluginwindow.h | 16 +- frame/window/systempluginwindow.cpp | 5 + frame/window/systempluginwindow.h | 2 + frame/window/tray/tray_delegate.cpp | 3 +- .../window/tray/widgets/snitrayitemwidget.cpp | 70 +++++---- frame/window/tray/widgets/snitrayitemwidget.h | 15 +- .../window/tray/widgets/systempluginitem.cpp | 2 +- 8 files changed, 208 insertions(+), 47 deletions(-) diff --git a/frame/window/quickpluginwindow.cpp b/frame/window/quickpluginwindow.cpp index 66e9af47a..efe58c51a 100644 --- a/frame/window/quickpluginwindow.cpp +++ b/frame/window/quickpluginwindow.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #define ITEMSIZE 22 #define ITEMSPACE 6 @@ -501,11 +502,28 @@ QuickDockItem::QuickDockItem(PluginsItemInterface *pluginItem, const QJsonObject , m_pluginItem(pluginItem) , m_metaData(metaData) , m_itemKey(itemKey) + , m_position(Dock::Position::Bottom) + , m_popupWindow(new DockPopupWindow) + , m_contextMenu(new QMenu(this)) { + m_popupWindow->setShadowBlurRadius(20); + m_popupWindow->setRadius(6); + m_popupWindow->setShadowYOffset(2); + m_popupWindow->setShadowXOffset(0); + m_popupWindow->setArrowWidth(18); + m_popupWindow->setArrowHeight(10); + m_popupWindow->setObjectName("quickitempopup"); + if (Utils::IS_WAYLAND_DISPLAY) { + Qt::WindowFlags flags = m_popupWindow->windowFlags() | Qt::FramelessWindowHint; + m_popupWindow->setWindowFlags(flags); + } + + connect(qApp, &QApplication::aboutToQuit, m_popupWindow, &DockPopupWindow::deleteLater); } QuickDockItem::~QuickDockItem() { + m_popupWindow->deleteLater(); } PluginsItemInterface *QuickDockItem::pluginItem() @@ -534,10 +552,79 @@ void QuickDockItem::paintEvent(QPaintEvent *event) painter.drawPixmap(pixmapRect, pixmap); } -void QuickDockItem::mouseReleaseEvent(QMouseEvent *event) +void QuickDockItem::mousePressEvent(QMouseEvent *event) { - Q_EMIT clicked(); - QWidget::mouseReleaseEvent(event); + switch (event->button()) { + case Qt::LeftButton: { + Q_EMIT clicked(); + break; + } + case Qt::RightButton: { + if (m_contextMenu->actions().isEmpty()) { + const QString menuJson = m_pluginItem->itemContextMenu(m_itemKey); + if (menuJson.isEmpty()) + return; + + QJsonDocument jsonDocument = QJsonDocument::fromJson(menuJson.toLocal8Bit().data()); + if (jsonDocument.isNull()) + return; + + QJsonObject jsonMenu = jsonDocument.object(); + + QJsonArray jsonMenuItems = jsonMenu.value("items").toArray(); + for (auto item : jsonMenuItems) { + QJsonObject itemObj = item.toObject(); + QAction *action = new QAction(itemObj.value("itemText").toString()); + action->setCheckable(itemObj.value("isCheckable").toBool()); + action->setChecked(itemObj.value("checked").toBool()); + action->setData(itemObj.value("itemId").toString()); + action->setEnabled(itemObj.value("isActive").toBool()); + m_contextMenu->addAction(action); + } + } + + m_contextMenu->exec(QCursor::pos()); + break; + } + default: + break; + } + QWidget::mousePressEvent(event); +} + +void QuickDockItem::enterEvent(QEvent *event) +{ + QWidget::enterEvent(event); + + QWidget *tipWidget = m_pluginItem->itemTipsWidget(m_itemKey); + if (!tipWidget) + return; + + switch (m_position) { + case Top: + m_popupWindow->setArrowDirection(DockPopupWindow::ArrowTop); + break; + case Bottom: + m_popupWindow->setArrowDirection(DockPopupWindow::ArrowBottom); + break; + case Left: + m_popupWindow->setArrowDirection(DockPopupWindow::ArrowLeft); + break; + case Right: + m_popupWindow->setArrowDirection(DockPopupWindow::ArrowRight); + break; + } + + m_popupWindow->resize(tipWidget->sizeHint()); + m_popupWindow->setContent(tipWidget); + + m_popupWindow->show(popupMarkPoint()); +} + +void QuickDockItem::leaveEvent(QEvent *event) +{ + QWidget::leaveEvent(event); + m_popupWindow->hide(); } QPixmap QuickDockItem::iconPixmap() const @@ -555,3 +642,52 @@ QPixmap QuickDockItem::iconPixmap() const return QPixmap(); } + +QPoint QuickDockItem::topleftPoint() const +{ + QPoint p = this->pos(); + /* 由于点击范围的问题,在图标的外面加了一层布局,这个布局的边距需要考虑 */ + switch (m_position) { + case Top: + p.setY(p.y() * 2); + break; + case Bottom: + p.setY(0); + break; + case Left: + p.setX(p.x() * 2); + break; + case Right: + p.setX(0); + break; + } + + QWidget *w = qobject_cast(this->parent()); + while (w) { + p += w->pos(); + w = qobject_cast(w->parent()); + } + + return p; +} + +QPoint QuickDockItem::popupMarkPoint() const +{ + QPoint p(topleftPoint()); + const QRect r = rect(); + switch (m_position) { + case Top: + p += QPoint(r.width() / 2, r.height()); + break; + case Bottom: + p += QPoint(r.width() / 2, 0); + break; + case Left: + p += QPoint(r.width(), r.height() / 2); + break; + case Right: + p += QPoint(0, r.height() / 2); + break; + } + return p; +} diff --git a/frame/window/quickpluginwindow.h b/frame/window/quickpluginwindow.h index 44da684b4..27bdd52c4 100644 --- a/frame/window/quickpluginwindow.h +++ b/frame/window/quickpluginwindow.h @@ -34,6 +34,8 @@ class QStandardItem; class QMouseEvent; class QBoxLayout; class QuickDockItem; +class DockPopupWindow; +class QMenu; enum class DockPart; namespace Dtk { namespace Gui { class DRegionMonitor; } @@ -97,6 +99,7 @@ public: explicit QuickDockItem(PluginsItemInterface *pluginItem, const QJsonObject &metaData, const QString itemKey, QWidget *parent = nullptr); ~QuickDockItem(); + void setPositon(Dock::Position position); PluginsItemInterface *pluginItem(); bool isPrimary() const; @@ -104,15 +107,24 @@ Q_SIGNALS: void clicked(); protected: - void paintEvent(QPaintEvent *event); - void mouseReleaseEvent(QMouseEvent *event); + void paintEvent(QPaintEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; + void enterEvent(QEvent *event) override; + void leaveEvent(QEvent *event) override; QPixmap iconPixmap() const; +private: + QPoint topleftPoint() const; + QPoint popupMarkPoint() const; + private: PluginsItemInterface *m_pluginItem; QJsonObject m_metaData; QString m_itemKey; + Dock::Position m_position; + DockPopupWindow *m_popupWindow; + QMenu *m_contextMenu; }; #endif // QUICKPLUGINWINDOW_H diff --git a/frame/window/systempluginwindow.cpp b/frame/window/systempluginwindow.cpp index bfa651fdc..cd17498e7 100644 --- a/frame/window/systempluginwindow.cpp +++ b/frame/window/systempluginwindow.cpp @@ -318,6 +318,11 @@ void StretchPluginsItem::invokedMenuItem(const QString &itemId, const bool check m_pluginInter->invokedMenuItem(m_itemKey, itemId, checked); } +QWidget *StretchPluginsItem::popupTips() +{ + return m_pluginInter->itemTipsWidget(m_itemKey); +} + void StretchPluginsItem::mousePressEvent(QMouseEvent *e) { m_hover = false; diff --git a/frame/window/systempluginwindow.h b/frame/window/systempluginwindow.h index 67af5bddc..9a74aca1d 100644 --- a/frame/window/systempluginwindow.h +++ b/frame/window/systempluginwindow.h @@ -90,6 +90,8 @@ protected: const QString contextMenu() const override; void invokedMenuItem(const QString &itemId, const bool checked) override; + QWidget *popupTips() override; + private: void mouseClick(); QFont textFont() const; diff --git a/frame/window/tray/tray_delegate.cpp b/frame/window/tray/tray_delegate.cpp index 1cef0370e..a9bd34b5f 100644 --- a/frame/window/tray/tray_delegate.cpp +++ b/frame/window/tray/tray_delegate.cpp @@ -53,6 +53,8 @@ TrayDelegate::TrayDelegate(QListView *view, QObject *parent) void TrayDelegate::setPositon(Dock::Position position) { m_position = position; + SNITrayItemWidget::setDockPostion(position); + SystemPluginItem::setDockPostion(m_position); } QWidget *TrayDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const @@ -107,7 +109,6 @@ QWidget *TrayDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem PluginsItemInterface *pluginInter = (PluginsItemInterface *)(index.data(TrayModel::PluginInterfaceRole).toULongLong()); if (pluginInter) { const QString itemKey = QuickSettingController::instance()->itemKey(pluginInter); - SystemPluginItem::setDockPostion(m_position); trayWidget = new SystemPluginItem(pluginInter, itemKey, parent); } } diff --git a/frame/window/tray/widgets/snitrayitemwidget.cpp b/frame/window/tray/widgets/snitrayitemwidget.cpp index e21befa84..820e8bedd 100644 --- a/frame/window/tray/widgets/snitrayitemwidget.cpp +++ b/frame/window/tray/widgets/snitrayitemwidget.cpp @@ -21,7 +21,7 @@ #include "snitrayitemwidget.h" #include "themeappicon.h" -//#include "test/tipswidget.h" +#include "tipswidget.h" #include @@ -43,8 +43,9 @@ const QStringList ItemCategoryList {"ApplicationStatus", "Communications", "Syst const QStringList ItemStatusList {"Passive", "Active", "NeedsAttention"}; const QStringList LeftClickInvalidIdList {"sogou-qimpanel",}; QPointer SNITrayItemWidget::PopupWindow = nullptr; -Dock::Position SNITrayItemWidget::DockPosition = Dock::Position::Top; +Dock::Position SNITrayItemWidget::DockPosition = Dock::Position::Bottom; using namespace Dock; + SNITrayItemWidget::SNITrayItemWidget(const QString &sniServicePath, QWidget *parent) : BaseTrayWidget(parent), m_menu(nullptr), @@ -54,6 +55,8 @@ SNITrayItemWidget::SNITrayItemWidget(const QString &sniServicePath, QWidget *par , m_sniServicePath(sniServicePath) , m_popupTipsDelayTimer(new QTimer(this)) , m_handleMouseReleaseTimer(new QTimer(this)) + , m_tipsLabel(new TipsWidget) + , m_popupShown(false) { m_popupTipsDelayTimer->setInterval(500); m_popupTipsDelayTimer->setSingleShot(true); @@ -152,22 +155,12 @@ SNITrayItemWidget::SNITrayItemWidget(const QString &sniServicePath, QWidget *par onSNIStatusChanged(m_sniInter->status()); }); - QMetaObject::invokeMethod(this, [ this ] { - m_sniIconName = m_sniInter->iconName(); - m_sniIconPixmap = m_sniInter->iconPixmap(); - m_sniIconThemePath = m_sniInter->iconThemePath(); - m_updateIconTimer->start(); + QMetaObject::invokeMethod(this, &SNITrayItemWidget::initMember, Qt::QueuedConnection); +} - m_sniOverlayIconName = m_sniInter->overlayIconName(); - m_sniOverlayIconPixmap = m_sniInter->overlayIconPixmap(); - m_sniIconThemePath = m_sniInter->iconThemePath(); - m_updateOverlayIconTimer->start(); - - m_sniAttentionIconName = m_sniInter->attentionIconName(); - m_sniAttentionIconPixmap = m_sniInter->attentionIconPixmap(); - m_sniIconThemePath = m_sniInter->iconThemePath(); - m_updateAttentionIconTimer->start(); - }, Qt::QueuedConnection); +SNITrayItemWidget::~SNITrayItemWidget() +{ + m_tipsLabel->deleteLater(); } QString SNITrayItemWidget::itemKeyForConfig() @@ -643,16 +636,31 @@ void SNITrayItemWidget::handleMouseRelease() } } +void SNITrayItemWidget::initMember() +{ + onSNIAttentionIconNameChanged(m_sniInter->attentionIconName()); + onSNIAttentionIconPixmapChanged(m_sniInter->attentionIconPixmap()); + onSNIAttentionMovieNameChanged(m_sniInter->attentionMovieName()); + onSNICategoryChanged(m_sniInter->category()); + onSNIIconNameChanged(m_sniInter->iconName()); + onSNIIconPixmapChanged(m_sniInter->iconPixmap()); + onSNIIconThemePathChanged(m_sniInter->iconThemePath()); + onSNIIdChanged(m_sniInter->id()); + onSNIMenuChanged(m_sniInter->menu()); + onSNIOverlayIconNameChanged(m_sniInter->overlayIconName()); + onSNIOverlayIconPixmapChanged(m_sniInter->overlayIconPixmap()); + onSNIStatusChanged(m_sniInter->status()); + + m_updateIconTimer->start(); + m_updateOverlayIconTimer->start(); + m_updateAttentionIconTimer->start(); +} + void SNITrayItemWidget::showHoverTips() { if (PopupWindow->model()) return; - // if not in geometry area - const QRect r(topleftPoint(), size()); - if (!r.contains(QCursor::pos())) - return; - QProcess p; p.start("qdbus", {m_dbusService}); if (!p.waitForFinished(1000)) { @@ -669,20 +677,16 @@ void SNITrayItemWidget::showHoverTips() if (tooltip.title.isEmpty()) return; -#ifdef QT_DEBUG - setToolTip(tooltip.title); -#else -// // 当提示信息中有换行符时,需要使用setTextList -// if (tooltip.title.contains('\n')) -// m_tipsLabel->setTextList(tooltip.title.split('\n')); -// else -// m_tipsLabel->setText(tooltip.title); + // 当提示信息中有换行符时,需要使用setTextList + if (tooltip.title.contains('\n')) + m_tipsLabel->setTextList(tooltip.title.split('\n')); + else + m_tipsLabel->setText(tooltip.title); -// m_tipsLabel->setAccessibleName(itemKeyForConfig().replace("sni:","")); + m_tipsLabel->setAccessibleName(itemKeyForConfig().replace("sni:","")); -// showPopupWindow(m_tipsLabel); -#endif + showPopupWindow(m_tipsLabel); } } diff --git a/frame/window/tray/widgets/snitrayitemwidget.h b/frame/window/tray/widgets/snitrayitemwidget.h index 1af8f46c3..e2d278df0 100644 --- a/frame/window/tray/widgets/snitrayitemwidget.h +++ b/frame/window/tray/widgets/snitrayitemwidget.h @@ -30,13 +30,12 @@ #include #include -//DWIDGET_USE_NAMESPACE -//DGUI_USE_NAMESPACE + class DBusMenuImporter; -//namespace Dock { -//class TipsWidget; -//} -//using namespace com::deepin::dde; +namespace Dock { +class TipsWidget; +} + using namespace org::kde; /** @@ -54,6 +53,7 @@ public: public: SNITrayItemWidget(const QString &sniServicePath, QWidget *parent = Q_NULLPTR); + ~SNITrayItemWidget(); QString itemKeyForConfig() override; void updateIcon() override; @@ -112,6 +112,7 @@ private: QPixmap newIconPixmap(IconType iconType); void setMouseData(QMouseEvent *e); void handleMouseRelease(); + void initMember(); private: StatusNotifierItem *m_sniInter; @@ -148,7 +149,7 @@ private: QPair m_lastMouseReleaseData; static Dock::Position DockPosition; static QPointer PopupWindow; -// Dock::TipsWidget *m_tipsLabel; + Dock::TipsWidget *m_tipsLabel; bool m_popupShown; }; diff --git a/frame/window/tray/widgets/systempluginitem.cpp b/frame/window/tray/widgets/systempluginitem.cpp index bac7752bd..bc21dca9b 100644 --- a/frame/window/tray/widgets/systempluginitem.cpp +++ b/frame/window/tray/widgets/systempluginitem.cpp @@ -30,7 +30,7 @@ #include -Dock::Position SystemPluginItem::DockPosition = Dock::Position::Top; +Dock::Position SystemPluginItem::DockPosition = Dock::Position::Bottom; QPointer SystemPluginItem::PopupWindow = nullptr; SystemPluginItem::SystemPluginItem(PluginsItemInterface *const pluginInter, const QString &itemKey, QWidget *parent)