1- // SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
1+ // SPDX-FileCopyrightText: 2024 - 2026 UnionTech Software Technology Co., Ltd.
22//
33// SPDX-License-Identifier: LGPL-3.0-or-later
44
99
1010#include < QMouseEvent>
1111#include < QMenu>
12+ #include < QLabel>
13+ #include < QSlider>
14+ #include < QAbstractButton>
15+ #include < QGraphicsOpacityEffect>
1216
1317namespace {
1418class Q_DECL_HIDDEN EventFilter : public QObject
@@ -96,13 +100,42 @@ class Q_DECL_HIDDEN ItemWidgetEventFilter : public QObject
96100
97101 QuickPluginItem *m_target = nullptr ;
98102};
103+
104+ class Q_DECL_HIDDEN HoverEventFilter : public QObject
105+ {
106+ public:
107+ explicit HoverEventFilter (QuickPluginItem *target)
108+ : QObject(target)
109+ , m_target(target)
110+ {
111+ }
112+
113+ bool eventFilter (QObject *watched, QEvent *event) override
114+ {
115+ if (event->type () != QEvent::Enter && event->type () != QEvent::Leave)
116+ return false ;
117+
118+ // underMouse() is updated before event filter runs in Qt's event delivery;
119+ // centralWidget()->window() => the quick panel's top-level window
120+ bool isUnder = false ;
121+ if (auto *w = m_target->centralWidget ()) {
122+ if (auto *win = w->window ())
123+ isUnder = win->underMouse ();
124+ }
125+ m_target->updatePluginHoverState (isUnder);
126+ return false ;
127+ }
128+
129+ QuickPluginItem *m_target = nullptr ;
130+ };
99131}
100132
101133QuickPluginItem::QuickPluginItem (PluginsItemInterface *pluginInterface, const QString &itemKey, QWidget *parent)
102134 : PluginItem(pluginInterface, itemKey, parent)
103135 , m_onDockAction(nullptr )
104136{
105137 qApp->installEventFilter (new EventFilter (this ));
138+ installEventFilter (new HoverEventFilter (this ));
106139}
107140
108141void QuickPluginItem::init ()
@@ -111,6 +144,7 @@ void QuickPluginItem::init()
111144 if (auto widget = centralWidget ()) {
112145 widget->installEventFilter (new ItemWidgetEventFilter (this ));
113146 }
147+ updatePluginHoverState (false );
114148}
115149
116150QWidget *QuickPluginItem::centralWidget ()
@@ -215,3 +249,45 @@ void QuickPluginItem::requestActiveState()
215249 }
216250 }
217251}
252+
253+ void QuickPluginItem::updatePluginHoverState (bool hovered)
254+ {
255+ if (m_hoverStateApplied && m_pluginHovered == hovered)
256+ return ;
257+
258+ m_pluginHovered = hovered;
259+ m_hoverStateApplied = true ;
260+
261+ static constexpr qreal kNormalAlpha = 0.7 ;
262+ static constexpr qreal kHoverAlpha = 1.0 ;
263+ const qreal targetAlpha = hovered ? kHoverAlpha : kNormalAlpha ;
264+
265+ // Single pass: no redundant findChildren calls.
266+ // CommonIconButton → invokeMethod (fallback to QGraphicsOpacityEffect)
267+ // QSlider → property + update()
268+ // QLabel / QAbstractButton → QGraphicsOpacityEffect
269+ // These branches are mutually exclusive in the widget hierarchy.
270+ for (auto *child : findChildren<QWidget *>()) {
271+ if (child->inherits (" CommonIconButton" )) {
272+ bool invoked = QMetaObject::invokeMethod (child, " setParentHovered" , Q_ARG (bool , hovered));
273+ if (!invoked) {
274+ auto *effect = qobject_cast<QGraphicsOpacityEffect *>(child->graphicsEffect ());
275+ if (!effect) {
276+ effect = new QGraphicsOpacityEffect (child);
277+ child->setGraphicsEffect (effect);
278+ }
279+ effect->setOpacity (targetAlpha);
280+ }
281+ } else if (qobject_cast<QSlider *>(child)) {
282+ child->setProperty (" _dtl_plugin_hovered" , hovered);
283+ child->update ();
284+ } else if (qobject_cast<QLabel *>(child) || qobject_cast<QAbstractButton *>(child)) {
285+ auto *effect = qobject_cast<QGraphicsOpacityEffect *>(child->graphicsEffect ());
286+ if (!effect) {
287+ effect = new QGraphicsOpacityEffect (child);
288+ child->setGraphicsEffect (effect);
289+ }
290+ effect->setOpacity (targetAlpha);
291+ }
292+ }
293+ }
0 commit comments