feat: 图标增加toolTip和菜单

分别在QuickDockItem类,SystemPluginItem类和SystemPluginItem类中增加如下处理
1、增加toolTip功能
2、增加右键菜单功能

Log: 图标增加toolTip和菜单
Influence: 鼠标放入到托盘区域、快捷插件区域,关机区域,观察是否存在toolTip,右键,观察是否弹出菜单
Task: https://pms.uniontech.com/task-view-112073.html
Change-Id: I7a700d9b9e4ee3c0681ae0de39712f3f5ae83224
This commit is contained in:
donghualin 2022-10-18 10:24:21 +00:00
parent 91d5bfbf07
commit db3e5f79da
8 changed files with 208 additions and 47 deletions

View File

@ -36,6 +36,7 @@
#include <QMouseEvent>
#include <QBoxLayout>
#include <QGuiApplication>
#include <QMenu>
#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<QWidget *>(this->parent());
while (w) {
p += w->pos();
w = qobject_cast<QWidget *>(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;
}

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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);
}
}

View File

@ -21,7 +21,7 @@
#include "snitrayitemwidget.h"
#include "themeappicon.h"
//#include "test/tipswidget.h"
#include "tipswidget.h"
#include <dbusmenu-qt5/dbusmenuimporter.h>
@ -43,8 +43,9 @@ const QStringList ItemCategoryList {"ApplicationStatus", "Communications", "Syst
const QStringList ItemStatusList {"Passive", "Active", "NeedsAttention"};
const QStringList LeftClickInvalidIdList {"sogou-qimpanel",};
QPointer<DockPopupWindow> 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);
}
}

View File

@ -30,13 +30,12 @@
#include <QMenu>
#include <QDBusObjectPath>
//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<QPoint, Qt::MouseButton> m_lastMouseReleaseData;
static Dock::Position DockPosition;
static QPointer<DockPopupWindow> PopupWindow;
// Dock::TipsWidget *m_tipsLabel;
Dock::TipsWidget *m_tipsLabel;
bool m_popupShown;
};

View File

@ -30,7 +30,7 @@
#include <xcb/xproto.h>
Dock::Position SystemPluginItem::DockPosition = Dock::Position::Top;
Dock::Position SystemPluginItem::DockPosition = Dock::Position::Bottom;
QPointer<DockPopupWindow> SystemPluginItem::PopupWindow = nullptr;
SystemPluginItem::SystemPluginItem(PluginsItemInterface *const pluginInter, const QString &itemKey, QWidget *parent)