From d88fe1614aae2c2d21c833fac57db60b28833e49 Mon Sep 17 00:00:00 2001 From: Fangxun Zhao Date: Tue, 23 Jun 2026 20:16:52 +0800 Subject: [PATCH] fix(dde-dock): add hover opacity effect to quick panel widgets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Add QGraphicsOpacityEffect and enterEvent/leaveEvent overrides to brightness, sound, media, and common quick panel widgets 2. Add per-element opacity effects (icon/name/state) to bluetooth, eye-comfort-mode, and wireless-casting quick panel widgets 3. Implement updateOpacity logic: icon follows hover or active state, text always follows hover 4. Set normal opacity to 0.7 and hover opacity to 1.0 for consistent visual feedback 5. Apply the same pattern to JumpSettingButton and PluginItemDelegate for unified dock hover behavior Log: Add hover highlight effect to all dock quick panel widgets for better visual feedback fix(dde-dock): 为所有快捷面板控件添加悬停透明度效果 1. 为亮度、声音、媒体和公共快捷面板控件添加 QGraphicsOpacityEffect 及 enterEvent/leaveEvent 重写 2. 为蓝牙、护眼模式和无线投屏控件添加逐元素(图标/名称/状态)透明度效果 3. 实现 updateOpacity 逻辑:图标跟随悬停或激活状态,文字始终跟随悬停 4. 设置常规透明度为 0.7,悬停透明度为 1.0,实现一致的视觉反馈 5. 对 JumpSettingButton 和 PluginItemDelegate 应用相同模式,统一 Dock 悬停行为 Log: 为所有 Dock 快捷面板控件添加悬停高亮效果,改善视觉反馈 PMS: BUG-314503 --- .../dde-dock/bluetooth/quickpanelwidget.cpp | 34 ++++++++++++++++ plugins/dde-dock/bluetooth/quickpanelwidget.h | 13 ++++++ .../brightness/brightnessquickpanel.cpp | 17 ++++++++ .../brightness/brightnessquickpanel.h | 7 ++++ plugins/dde-dock/common/jumpsettingbutton.cpp | 20 ++++++++++ plugins/dde-dock/common/jumpsettingbutton.h | 8 ++++ .../dde-dock/common/pluginitemdelegate.cpp | 18 +++++++++ plugins/dde-dock/common/pluginitemdelegate.h | 8 ++++ plugins/dde-dock/common/singlequickpanel.cpp | 31 ++++++++++++++ plugins/dde-dock/common/singlequickpanel.h | 13 +++++- .../eye-comfort-mode/quickpanelwidget.cpp | 40 +++++++++++++++++++ .../eye-comfort-mode/quickpanelwidget.h | 14 ++++++- plugins/dde-dock/media/quickpanelwidget.cpp | 17 ++++++++ plugins/dde-dock/media/quickpanelwidget.h | 11 ++++- plugins/dde-dock/sound/soundquickpanel.cpp | 17 ++++++++ plugins/dde-dock/sound/soundquickpanel.h | 7 ++++ .../src/quickpanelwidget.cpp | 34 ++++++++++++++++ .../src/quickpanelwidget.h | 13 ++++++ 18 files changed, 318 insertions(+), 4 deletions(-) diff --git a/plugins/dde-dock/bluetooth/quickpanelwidget.cpp b/plugins/dde-dock/bluetooth/quickpanelwidget.cpp index bbe7107d9..9d19e62c7 100644 --- a/plugins/dde-dock/bluetooth/quickpanelwidget.cpp +++ b/plugins/dde-dock/bluetooth/quickpanelwidget.cpp @@ -66,6 +66,9 @@ QuickPanelWidget::QuickPanelWidget(QWidget *parent) , m_nameLabel(new DLabel(this)) , m_stateLabel(new DLabel(this)) , m_expandLabel(new DIconButton(this)) + , m_iconEffect(new QGraphicsOpacityEffect(m_iconWidget)) + , m_nameEffect(new QGraphicsOpacityEffect(m_nameLabel)) + , m_stateEffect(new QGraphicsOpacityEffect(m_stateLabel)) { initUi(); initConnection(); @@ -90,7 +93,9 @@ void QuickPanelWidget::setDescription(const QString &description) void QuickPanelWidget::setActive(bool active) { + m_active = active; m_iconWidget->setBackgroundRole(active ? QPalette::Highlight : QPalette::BrightText); + updateOpacity(m_hovered); } void QuickPanelWidget::mousePressEvent(QMouseEvent *event) @@ -128,10 +133,14 @@ void QuickPanelWidget::initUi() m_nameLabel->setElideMode(Qt::ElideRight); m_nameLabel->setContentsMargins(0, 2, 0, 0); m_nameLabel->setForegroundRole(QPalette::BrightText); + m_nameEffect->setOpacity(kNormalOpacity); + m_nameLabel->setGraphicsEffect(m_nameEffect); DFontSizeManager::instance()->bind(m_stateLabel, DFontSizeManager::T10); DToolTip::setToolTipShowMode(m_stateLabel, DToolTip::ShowWhenElided); m_stateLabel->setElideMode(Qt::ElideRight); + m_stateEffect->setOpacity(kNormalOpacity); + m_stateLabel->setGraphicsEffect(m_stateEffect); QVBoxLayout *layout = new QVBoxLayout(labelWidget); layout->setContentsMargins(0, 8, 0, 8); @@ -143,6 +152,8 @@ void QuickPanelWidget::initUi() m_iconWidget->setEnabledCircle(true); m_iconWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); m_iconWidget->setIconSize(IconSize); + m_iconEffect->setOpacity(kNormalOpacity); + m_iconWidget->setGraphicsEffect(m_iconEffect); m_iconWidget->setCheckable(false); m_iconWidget->setFixedSize(QSize(40, 40)); m_iconWidget->setFocusPolicy(Qt::NoFocus); @@ -171,3 +182,26 @@ void QuickPanelWidget::initConnection() { connect(m_iconWidget, &DFloatingButton::clicked, this, &QuickPanelWidget::iconClicked); } + +void QuickPanelWidget::updateOpacity(bool hover) +{ + // icon: when active, always 1.0; otherwise follow hover + m_iconEffect->setOpacity((m_active || hover) ? kHoverOpacity : kNormalOpacity); + // text: always follow hover regardless of active state + m_nameEffect->setOpacity(hover ? kHoverOpacity : kNormalOpacity); + m_stateEffect->setOpacity(hover ? kHoverOpacity : kNormalOpacity); +} + +void QuickPanelWidget::enterEvent(QEnterEvent *event) +{ + m_hovered = true; + updateOpacity(true); + QWidget::enterEvent(event); +} + +void QuickPanelWidget::leaveEvent(QEvent *event) +{ + Q_UNUSED(event) + m_hovered = false; + updateOpacity(false); +} diff --git a/plugins/dde-dock/bluetooth/quickpanelwidget.h b/plugins/dde-dock/bluetooth/quickpanelwidget.h index 38b4808ef..e384122c4 100644 --- a/plugins/dde-dock/bluetooth/quickpanelwidget.h +++ b/plugins/dde-dock/bluetooth/quickpanelwidget.h @@ -6,6 +6,8 @@ #ifndef QUICKPANELWIDGET_H #define QUICKPANELWIDGET_H +#include + #include #include @@ -35,17 +37,28 @@ public Q_SLOTS: protected: void mousePressEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; + void enterEvent(QEnterEvent *event) override; + void leaveEvent(QEvent *event) override; private: void initUi(); void initConnection(); + void updateOpacity(bool hover); private: + static constexpr qreal kNormalOpacity = 0.7; + static constexpr qreal kHoverOpacity = 1.0; + QuickButton *m_iconWidget; Dtk::Widget::DLabel *m_nameLabel; Dtk::Widget::DLabel *m_stateLabel; Dtk::Widget::DIconButton *m_expandLabel; QPoint m_clickPoint; + bool m_active = false; + bool m_hovered = false; + QGraphicsOpacityEffect *m_iconEffect; + QGraphicsOpacityEffect *m_nameEffect; + QGraphicsOpacityEffect *m_stateEffect; }; #endif // QUICKPANELWIDGET_H diff --git a/plugins/dde-dock/brightness/brightnessquickpanel.cpp b/plugins/dde-dock/brightness/brightnessquickpanel.cpp index 1f854b528..9baa5cf17 100644 --- a/plugins/dde-dock/brightness/brightnessquickpanel.cpp +++ b/plugins/dde-dock/brightness/brightnessquickpanel.cpp @@ -24,7 +24,10 @@ BrightnessQuickPanel::BrightnessQuickPanel(QWidget* parent) : QWidget(parent) , m_sliderContainer(new SliderContainer(this)) , m_currentMonitor(nullptr) + , m_opacityEffect(new QGraphicsOpacityEffect(this)) { + m_opacityEffect->setOpacity(kNormalOpacity); + setGraphicsEffect(m_opacityEffect); initUi(); initConnection(); @@ -32,6 +35,7 @@ BrightnessQuickPanel::BrightnessQuickPanel(QWidget* parent) UpdateDisplayStatus(); } + BrightnessQuickPanel::~BrightnessQuickPanel() { } @@ -110,3 +114,16 @@ void BrightnessQuickPanel::refreshWidget() m_sliderContainer->updateSliderValue(m_currentMonitor->brightness() * 100); } } + +void BrightnessQuickPanel::enterEvent(QEnterEvent *event) +{ + m_opacityEffect->setOpacity(kHoverOpacity); + QWidget::enterEvent(event); +} + +void BrightnessQuickPanel::leaveEvent(QEvent *event) +{ + Q_UNUSED(event) + m_opacityEffect->setOpacity(kNormalOpacity); +} + diff --git a/plugins/dde-dock/brightness/brightnessquickpanel.h b/plugins/dde-dock/brightness/brightnessquickpanel.h index e9eb15872..00feb7f09 100644 --- a/plugins/dde-dock/brightness/brightnessquickpanel.h +++ b/plugins/dde-dock/brightness/brightnessquickpanel.h @@ -9,6 +9,7 @@ #include "monitor.h" #include +#include #include #include @@ -32,12 +33,18 @@ class BrightnessQuickPanel : public QWidget protected: void initUi(); void initConnection(); + void enterEvent(QEnterEvent *event) override; + void leaveEvent(QEvent *event) override; private Q_SLOTS: void refreshWidget(); void UpdateDisplayStatus(); private: + static constexpr qreal kNormalOpacity = 0.7; + static constexpr qreal kHoverOpacity = 1.0; + SliderContainer *m_sliderContainer; QPointer m_currentMonitor; + QGraphicsOpacityEffect *m_opacityEffect; }; diff --git a/plugins/dde-dock/common/jumpsettingbutton.cpp b/plugins/dde-dock/common/jumpsettingbutton.cpp index ada0b7b56..6729d212c 100644 --- a/plugins/dde-dock/common/jumpsettingbutton.cpp +++ b/plugins/dde-dock/common/jumpsettingbutton.cpp @@ -22,17 +22,24 @@ JumpSettingButton::JumpSettingButton(QWidget *parent) , m_autoShowPage(true) , m_iconButton(new CommonIconButton(this)) , m_descriptionLabel(new DLabel(this)) + , m_opacityEffect(new QGraphicsOpacityEffect(this)) { + m_opacityEffect->setOpacity(kNormalOpacity); + setGraphicsEffect(m_opacityEffect); initUI(); } + JumpSettingButton::JumpSettingButton(const QIcon& icon, const QString& description, QWidget* parent) : QFrame(parent) , m_hover(false) , m_autoShowPage(true) , m_iconButton(new CommonIconButton(this)) , m_descriptionLabel(new DLabel(this)) + , m_opacityEffect(new QGraphicsOpacityEffect(this)) { + m_opacityEffect->setOpacity(kNormalOpacity); + setGraphicsEffect(m_opacityEffect); initUI(); m_iconButton->setIcon(icon); @@ -143,3 +150,16 @@ void JumpSettingButton::setDccPage(const QString &first, const QString &second) m_fistPage = first; m_secondPage = second; } + +void JumpSettingButton::enterEvent(QEnterEvent *event) +{ + m_opacityEffect->setOpacity(kHoverOpacity); + QFrame::enterEvent(event); +} + +void JumpSettingButton::leaveEvent(QEvent *event) +{ + Q_UNUSED(event) + m_opacityEffect->setOpacity(kNormalOpacity); +} + diff --git a/plugins/dde-dock/common/jumpsettingbutton.h b/plugins/dde-dock/common/jumpsettingbutton.h index 9a6ba9e49..4ce86a0b2 100644 --- a/plugins/dde-dock/common/jumpsettingbutton.h +++ b/plugins/dde-dock/common/jumpsettingbutton.h @@ -7,6 +7,8 @@ #include "commoniconbutton.h" +#include + #include #include @@ -33,17 +35,23 @@ class JumpSettingButton : public QFrame bool event(QEvent* e) override; void paintEvent(QPaintEvent* e) override; void mouseReleaseEvent(QMouseEvent* event) override; + void enterEvent(QEnterEvent *event) override; + void leaveEvent(QEvent *event) override; private: void initUI(); private: + static constexpr qreal kNormalOpacity = 0.7; + static constexpr qreal kHoverOpacity = 1.0; + bool m_hover; bool m_autoShowPage; QString m_fistPage; QString m_secondPage; CommonIconButton *m_iconButton; Dtk::Widget::DLabel *m_descriptionLabel; + QGraphicsOpacityEffect *m_opacityEffect; }; #endif diff --git a/plugins/dde-dock/common/pluginitemdelegate.cpp b/plugins/dde-dock/common/pluginitemdelegate.cpp index d1ec91338..3f2a3ce72 100644 --- a/plugins/dde-dock/common/pluginitemdelegate.cpp +++ b/plugins/dde-dock/common/pluginitemdelegate.cpp @@ -191,6 +191,7 @@ PluginItemWidget::PluginItemWidget(PluginStandardItem *item, QWidget *parent) , m_connBtn(nullptr) , m_spinner(nullptr) , m_rightIconSpacerItem(new QSpacerItem(0, 0)) + , m_opacityEffect(new QGraphicsOpacityEffect(this)) { if (!m_item) { QLabel *err = new QLabel(this); @@ -242,8 +243,12 @@ PluginItemWidget::PluginItemWidget(PluginStandardItem *item, QWidget *parent) connect(m_item, &PluginStandardItem::stateChanged, this, &PluginItemWidget::updateState); connect(m_connBtn, &CommonIconButton::clicked, m_item, &PluginStandardItem::connectBtnClicked); + + m_opacityEffect->setOpacity(kNormalOpacity); + setGraphicsEffect(m_opacityEffect); } + PluginItemWidget::~PluginItemWidget() { } @@ -315,3 +320,16 @@ bool PluginItemWidget::event(QEvent *e) } return QWidget::event(e); } + +void PluginItemWidget::enterEvent(QEnterEvent *event) +{ + m_opacityEffect->setOpacity(kHoverOpacity); + QWidget::enterEvent(event); +} + +void PluginItemWidget::leaveEvent(QEvent *event) +{ + Q_UNUSED(event) + m_opacityEffect->setOpacity(kNormalOpacity); +} + diff --git a/plugins/dde-dock/common/pluginitemdelegate.h b/plugins/dde-dock/common/pluginitemdelegate.h index 51ec03bcf..9213e98c1 100644 --- a/plugins/dde-dock/common/pluginitemdelegate.h +++ b/plugins/dde-dock/common/pluginitemdelegate.h @@ -9,6 +9,8 @@ #include #include +#include + #include #include #include @@ -116,8 +118,13 @@ public Q_SLOTS: protected: bool event(QEvent *e) override; + void enterEvent(QEnterEvent *event) override; + void leaveEvent(QEvent *event) override; private: + static constexpr qreal kNormalOpacity = 0.7; + static constexpr qreal kHoverOpacity = 1.0; + PluginStandardItem *m_item; QHBoxLayout *m_mainLayout; @@ -126,4 +133,5 @@ public Q_SLOTS: CommonIconButton *m_connBtn; DSpinner *m_spinner; QSpacerItem *m_rightIconSpacerItem; + QGraphicsOpacityEffect *m_opacityEffect; }; diff --git a/plugins/dde-dock/common/singlequickpanel.cpp b/plugins/dde-dock/common/singlequickpanel.cpp index 64867a90c..64814b019 100644 --- a/plugins/dde-dock/common/singlequickpanel.cpp +++ b/plugins/dde-dock/common/singlequickpanel.cpp @@ -20,6 +20,8 @@ SignalQuickPanel::SignalQuickPanel(QWidget *parent) , m_icon(new CommonIconButton(this)) , m_description(new DLabel(this)) , m_active(false) + , m_iconEffect(new QGraphicsOpacityEffect(m_icon)) + , m_descEffect(new QGraphicsOpacityEffect(m_description)) { initUI(); connect(DGuiApplicationHelper::instance(), &DGuiApplicationHelper::themeTypeChanged, this, &SignalQuickPanel::refreshBg); @@ -34,10 +36,16 @@ void SignalQuickPanel::initUI() { m_icon->setFixedSize(QSize(24, 24)); + m_iconEffect->setOpacity(kNormalOpacity); + m_icon->setGraphicsEffect(m_iconEffect); + m_description->setElideMode(Qt::ElideRight); DToolTip::setToolTipShowMode(m_description, DToolTip::ShowWhenElided); DFontSizeManager::instance()->bind(m_description, DFontSizeManager::T10); + m_descEffect->setOpacity(kNormalOpacity); + m_description->setGraphicsEffect(m_descEffect); + auto layout = new QVBoxLayout; layout->setContentsMargins(8, 8, 8, 8); layout->setSpacing(0); @@ -68,6 +76,29 @@ void SignalQuickPanel::setWidgetState(WidgetState state) m_active = (WS_ACTIVE == state); refreshBg(); + updateOpacity(m_hovered); +} + +void SignalQuickPanel::updateOpacity(bool hover) +{ + // icon: when active, always 1.0; otherwise follow hover + m_iconEffect->setOpacity((m_active || hover) ? kHoverOpacity : kNormalOpacity); + // text: always follow hover regardless of active state + m_descEffect->setOpacity(hover ? kHoverOpacity : kNormalOpacity); +} + +void SignalQuickPanel::enterEvent(QEnterEvent *event) +{ + m_hovered = true; + updateOpacity(true); + QWidget::enterEvent(event); +} + +void SignalQuickPanel::leaveEvent(QEvent *event) +{ + Q_UNUSED(event) + m_hovered = false; + updateOpacity(false); } void SignalQuickPanel::mouseReleaseEvent(QMouseEvent *event) diff --git a/plugins/dde-dock/common/singlequickpanel.h b/plugins/dde-dock/common/singlequickpanel.h index 8c4c5f0ec..c2c369ec8 100644 --- a/plugins/dde-dock/common/singlequickpanel.h +++ b/plugins/dde-dock/common/singlequickpanel.h @@ -7,6 +7,7 @@ #include "commoniconbutton.h" +#include #include #include @@ -37,17 +38,27 @@ class SignalQuickPanel : public QWidget protected: void mouseReleaseEvent(QMouseEvent *event) override; + void enterEvent(QEnterEvent *event) override; + void leaveEvent(QEvent *event) override; private: void initUI(); + void updateOpacity(bool hover); private slots: void refreshBg(); private: + static constexpr qreal kNormalOpacity = 0.7; + static constexpr qreal kHoverOpacity = 1.0; + CommonIconButton *m_icon; DLabel *m_description; bool m_active; + bool m_hovered = false; + + QGraphicsOpacityEffect *m_iconEffect; + QGraphicsOpacityEffect *m_descEffect; }; -#endif \ No newline at end of file +#endif diff --git a/plugins/dde-dock/eye-comfort-mode/quickpanelwidget.cpp b/plugins/dde-dock/eye-comfort-mode/quickpanelwidget.cpp index 53eae1ebe..659dc6a88 100644 --- a/plugins/dde-dock/eye-comfort-mode/quickpanelwidget.cpp +++ b/plugins/dde-dock/eye-comfort-mode/quickpanelwidget.cpp @@ -64,11 +64,15 @@ QuickPanelWidget::QuickPanelWidget(QWidget *parent) , m_nameLabel(new DLabel(this)) , m_stateLabel(new DLabel(this)) , m_expandLabel(new DIconButton(this)) + , m_iconEffect(new QGraphicsOpacityEffect(m_iconWidget)) + , m_nameEffect(new QGraphicsOpacityEffect(m_nameLabel)) + , m_stateEffect(new QGraphicsOpacityEffect(m_stateLabel)) { initUi(); initConnection(); } + QuickPanelWidget::~QuickPanelWidget() { } void QuickPanelWidget::setIcon(const QIcon &icon) @@ -88,9 +92,12 @@ void QuickPanelWidget::setDescription(const QString &description) void QuickPanelWidget::setActive(bool active) { + m_active = active; m_iconWidget->setBackgroundRole(active ? QPalette::Highlight : QPalette::BrightText); + updateOpacity(m_hovered); } + void QuickPanelWidget::setButtonMode(QuickButton::ButtonMode mode) { m_iconWidget->setButtonMode(mode); @@ -131,10 +138,16 @@ void QuickPanelWidget::initUi() m_nameLabel->setElideMode(Qt::ElideRight); m_nameLabel->setContentsMargins(0, 2, 0, 0); m_nameLabel->setForegroundRole(QPalette::BrightText); + m_nameEffect->setOpacity(kNormalOpacity); + m_nameLabel->setGraphicsEffect(m_nameEffect); + DFontSizeManager::instance()->bind(m_stateLabel, DFontSizeManager::T10); DToolTip::setToolTipShowMode(m_stateLabel, DToolTip::ShowWhenElided); m_stateLabel->setElideMode(Qt::ElideRight); + m_stateEffect->setOpacity(kNormalOpacity); + m_stateLabel->setGraphicsEffect(m_stateEffect); + QVBoxLayout *layout = new QVBoxLayout(labelWidget); layout->setContentsMargins(0, 8, 8, 8); @@ -146,10 +159,13 @@ void QuickPanelWidget::initUi() m_iconWidget->setEnabledCircle(true); m_iconWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); m_iconWidget->setIconSize(IconSize); + m_iconEffect->setOpacity(kNormalOpacity); + m_iconWidget->setGraphicsEffect(m_iconEffect); m_iconWidget->setCheckable(false); m_iconWidget->setFixedSize(QSize(40, 40)); m_iconWidget->setFocusPolicy(Qt::NoFocus); + // 进入图标 m_expandLabel->setIcon(DStyle::standardIcon(style(), DStyle::SP_ArrowEnter)); m_expandLabel->setFlat(true); @@ -173,3 +189,27 @@ void QuickPanelWidget::initConnection() { connect(m_iconWidget, &DFloatingButton::clicked, this, &QuickPanelWidget::iconClicked); } + +void QuickPanelWidget::updateOpacity(bool hover) +{ + // icon: when active, always 1.0; otherwise follow hover + m_iconEffect->setOpacity((m_active || hover) ? kHoverOpacity : kNormalOpacity); + // text: always follow hover regardless of active state + m_nameEffect->setOpacity(hover ? kHoverOpacity : kNormalOpacity); + m_stateEffect->setOpacity(hover ? kHoverOpacity : kNormalOpacity); +} + +void QuickPanelWidget::enterEvent(QEnterEvent *event) +{ + m_hovered = true; + updateOpacity(true); + QWidget::enterEvent(event); +} + +void QuickPanelWidget::leaveEvent(QEvent *event) +{ + Q_UNUSED(event) + m_hovered = false; + updateOpacity(false); +} + diff --git a/plugins/dde-dock/eye-comfort-mode/quickpanelwidget.h b/plugins/dde-dock/eye-comfort-mode/quickpanelwidget.h index 59f9c52bb..16a544cc4 100644 --- a/plugins/dde-dock/eye-comfort-mode/quickpanelwidget.h +++ b/plugins/dde-dock/eye-comfort-mode/quickpanelwidget.h @@ -6,6 +6,8 @@ #ifndef QUICKPANELWIDGET_H #define QUICKPANELWIDGET_H +#include + #include #include #include @@ -32,7 +34,6 @@ class QuickButton : public DFloatingButton void setButtonMode(ButtonMode mode) { if (m_mode == mode) return; - m_mode = mode; DStyleOptionButton option; initStyleOption(&option); @@ -68,18 +69,29 @@ public Q_SLOTS: protected: void mousePressEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; + void enterEvent(QEnterEvent *event) override; + void leaveEvent(QEvent *event) override; private: void initUi(); void initConnection(); + void updateOpacity(bool hover); private: + static constexpr qreal kNormalOpacity = 0.7; + static constexpr qreal kHoverOpacity = 1.0; + QuickButton *m_iconWidget; Dtk::Widget::DLabel *m_nameLabel; Dtk::Widget::DLabel *m_stateLabel; Dtk::Widget::DIconButton *m_expandLabel; QPoint m_clickPoint; bool m_eyeComfortModeEnabled; + bool m_active = false; + bool m_hovered = false; + QGraphicsOpacityEffect *m_iconEffect; + QGraphicsOpacityEffect *m_nameEffect; + QGraphicsOpacityEffect *m_stateEffect; }; #endif // QUICKPANELWIDGET_H diff --git a/plugins/dde-dock/media/quickpanelwidget.cpp b/plugins/dde-dock/media/quickpanelwidget.cpp index 1f53b4b5e..069e0ef19 100644 --- a/plugins/dde-dock/media/quickpanelwidget.cpp +++ b/plugins/dde-dock/media/quickpanelwidget.cpp @@ -20,10 +20,14 @@ QuickPanelWidget::QuickPanelWidget(MediaController *controller, QWidget* parent) , m_artistLab(new DLabel(this)) , m_playButton(new CommonIconButton(this)) , m_nextButton(new CommonIconButton(this)) + , m_opacityEffect(new QGraphicsOpacityEffect(this)) { + m_opacityEffect->setOpacity(kNormalOpacity); + setGraphicsEffect(m_opacityEffect); init(); } + void QuickPanelWidget::init() { m_pixmap->setFixedWidth(32); @@ -127,6 +131,19 @@ void QuickPanelWidget::mouseReleaseEvent(QMouseEvent *event) return QWidget::mouseReleaseEvent(event); } +void QuickPanelWidget::enterEvent(QEnterEvent *event) +{ + m_opacityEffect->setOpacity(kHoverOpacity); + QWidget::enterEvent(event); +} + +void QuickPanelWidget::leaveEvent(QEvent *event) +{ + Q_UNUSED(event) + m_opacityEffect->setOpacity(kNormalOpacity); +} + + QuickPanelWidget::~QuickPanelWidget() { } diff --git a/plugins/dde-dock/media/quickpanelwidget.h b/plugins/dde-dock/media/quickpanelwidget.h index 4a7b70a4a..99521f68d 100644 --- a/plugins/dde-dock/media/quickpanelwidget.h +++ b/plugins/dde-dock/media/quickpanelwidget.h @@ -8,6 +8,7 @@ #include "commoniconbutton.h" #include "mediacontroller.h" +#include #include #include @@ -21,7 +22,9 @@ class QuickPanelWidget : public QWidget ~QuickPanelWidget(); protected: - void mouseReleaseEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event) override; + void enterEvent(QEnterEvent *event) override; + void leaveEvent(QEvent *event) override; Q_SIGNALS: void clicked(); @@ -32,6 +35,9 @@ class QuickPanelWidget : public QWidget void updateUI(); private: + static constexpr qreal kNormalOpacity = 0.7; + static constexpr qreal kHoverOpacity = 1.0; + MediaController *m_controller; DLabel *m_pixmap; @@ -39,6 +45,7 @@ class QuickPanelWidget : public QWidget DLabel *m_artistLab; CommonIconButton *m_playButton; CommonIconButton *m_nextButton; + QGraphicsOpacityEffect *m_opacityEffect; }; -#endif \ No newline at end of file +#endif diff --git a/plugins/dde-dock/sound/soundquickpanel.cpp b/plugins/dde-dock/sound/soundquickpanel.cpp index fba2f9727..ca9ef4ffb 100644 --- a/plugins/dde-dock/sound/soundquickpanel.cpp +++ b/plugins/dde-dock/sound/soundquickpanel.cpp @@ -33,11 +33,15 @@ DGUI_USE_NAMESPACE SoundQuickPanel::SoundQuickPanel(QWidget* parent) : QWidget(parent) , m_sliderContainer(new SliderContainer(this)) + , m_opacityEffect(new QGraphicsOpacityEffect(this)) { + m_opacityEffect->setOpacity(kNormalOpacity); + setGraphicsEffect(m_opacityEffect); initUi(); initConnection(); } + SoundQuickPanel::~SoundQuickPanel() { } @@ -161,3 +165,16 @@ int SoundQuickPanel::soundVolume() const { return SoundController::ref().existActiveOutputDevice() ? SoundModel::ref().volume() : 0; } + +void SoundQuickPanel::enterEvent(QEnterEvent *event) +{ + m_opacityEffect->setOpacity(kHoverOpacity); + QWidget::enterEvent(event); +} + +void SoundQuickPanel::leaveEvent(QEvent *event) +{ + Q_UNUSED(event) + m_opacityEffect->setOpacity(kNormalOpacity); +} + diff --git a/plugins/dde-dock/sound/soundquickpanel.h b/plugins/dde-dock/sound/soundquickpanel.h index c4de9880d..5422047b0 100644 --- a/plugins/dde-dock/sound/soundquickpanel.h +++ b/plugins/dde-dock/sound/soundquickpanel.h @@ -9,6 +9,7 @@ #include "soundcontroller.h" #include +#include #include class QDBusMessage; @@ -31,6 +32,8 @@ class SoundQuickPanel : public QWidget protected: void initUi(); void initConnection(); + void enterEvent(QEnterEvent *event) override; + void leaveEvent(QEvent *event) override; private: QString leftIcon(); @@ -42,7 +45,11 @@ private Q_SLOTS: void refreshWidget(); private: + static constexpr qreal kNormalOpacity = 0.7; + static constexpr qreal kHoverOpacity = 1.0; + SliderContainer *m_sliderContainer; + QGraphicsOpacityEffect *m_opacityEffect; }; #endif // VOLUMEWIDGET_H diff --git a/plugins/dde-network-display-ui/plugins/dock-wirelesscasting-plugin/src/quickpanelwidget.cpp b/plugins/dde-network-display-ui/plugins/dock-wirelesscasting-plugin/src/quickpanelwidget.cpp index e3f394f3e..8e8fb5671 100644 --- a/plugins/dde-network-display-ui/plugins/dock-wirelesscasting-plugin/src/quickpanelwidget.cpp +++ b/plugins/dde-network-display-ui/plugins/dock-wirelesscasting-plugin/src/quickpanelwidget.cpp @@ -61,6 +61,9 @@ QuickPanelWidget::QuickPanelWidget(QWidget *parent) , m_nameLabel(new DLabel(this)) , m_stateLabel(new DLabel(this)) , m_expandLabel(new DIconButton(this)) + , m_iconEffect(new QGraphicsOpacityEffect(m_iconWidget)) + , m_nameEffect(new QGraphicsOpacityEffect(m_nameLabel)) + , m_stateEffect(new QGraphicsOpacityEffect(m_stateLabel)) { initUi(); initConnection(); @@ -85,7 +88,9 @@ void QuickPanelWidget::setDescription(const QString &description) void QuickPanelWidget::setActive(bool active) { + m_active = active; m_iconWidget->setBackgroundRole(active ? QPalette::Highlight : QPalette::BrightText); + updateOpacity(m_hovered); } void QuickPanelWidget::mousePressEvent(QMouseEvent *event) @@ -123,10 +128,14 @@ void QuickPanelWidget::initUi() m_nameLabel->setElideMode(Qt::ElideRight); m_nameLabel->setContentsMargins(0, 2, 0, 0); m_nameLabel->setForegroundRole(QPalette::BrightText); + m_nameEffect->setOpacity(kNormalOpacity); + m_nameLabel->setGraphicsEffect(m_nameEffect); DFontSizeManager::instance()->bind(m_stateLabel, DFontSizeManager::T10); DToolTip::setToolTipShowMode(m_stateLabel, DToolTip::ShowWhenElided); m_stateLabel->setElideMode(Qt::ElideRight); + m_stateEffect->setOpacity(kNormalOpacity); + m_stateLabel->setGraphicsEffect(m_stateEffect); QVBoxLayout *layout = new QVBoxLayout(labelWidget); layout->setContentsMargins(0, 8, 0, 8); @@ -138,6 +147,8 @@ void QuickPanelWidget::initUi() m_iconWidget->setEnabledCircle(true); m_iconWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); m_iconWidget->setIconSize(IconSize); + m_iconEffect->setOpacity(kNormalOpacity); + m_iconWidget->setGraphicsEffect(m_iconEffect); m_iconWidget->setCheckable(false); m_iconWidget->setFixedSize(QSize(40, 40)); m_iconWidget->setFocusPolicy(Qt::NoFocus); @@ -166,5 +177,28 @@ void QuickPanelWidget::initConnection() connect(m_iconWidget, &DFloatingButton::clicked, this, &QuickPanelWidget::iconClicked); } +void QuickPanelWidget::updateOpacity(bool hover) +{ + // icon: when active, always 1.0; otherwise follow hover + m_iconEffect->setOpacity((m_active || hover) ? kHoverOpacity : kNormalOpacity); + // text: always follow hover regardless of active state + m_nameEffect->setOpacity(hover ? kHoverOpacity : kNormalOpacity); + m_stateEffect->setOpacity(hover ? kHoverOpacity : kNormalOpacity); +} + +void QuickPanelWidget::enterEvent(QEnterEvent *event) +{ + m_hovered = true; + updateOpacity(true); + QWidget::enterEvent(event); +} + +void QuickPanelWidget::leaveEvent(QEvent *event) +{ + Q_UNUSED(event) + m_hovered = false; + updateOpacity(false); +} + } // namespace wirelesscasting } // namespace dde diff --git a/plugins/dde-network-display-ui/plugins/dock-wirelesscasting-plugin/src/quickpanelwidget.h b/plugins/dde-network-display-ui/plugins/dock-wirelesscasting-plugin/src/quickpanelwidget.h index f9b40e18d..b3e9b8f35 100644 --- a/plugins/dde-network-display-ui/plugins/dock-wirelesscasting-plugin/src/quickpanelwidget.h +++ b/plugins/dde-network-display-ui/plugins/dock-wirelesscasting-plugin/src/quickpanelwidget.h @@ -5,6 +5,8 @@ #ifndef QUICKPANELWIDGET_H #define QUICKPANELWIDGET_H +#include + #include #include @@ -37,17 +39,28 @@ public Q_SLOTS: protected: void mousePressEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; + void enterEvent(QEnterEvent *event) override; + void leaveEvent(QEvent *event) override; private: void initUi(); void initConnection(); + void updateOpacity(bool hover); private: + static constexpr qreal kNormalOpacity = 0.7; + static constexpr qreal kHoverOpacity = 1.0; + QuickButton *m_iconWidget; Dtk::Widget::DLabel *m_nameLabel; Dtk::Widget::DLabel *m_stateLabel; Dtk::Widget::DIconButton *m_expandLabel; QPoint m_clickPoint; + bool m_active = false; + bool m_hovered = false; + QGraphicsOpacityEffect *m_iconEffect; + QGraphicsOpacityEffect *m_nameEffect; + QGraphicsOpacityEffect *m_stateEffect; }; } // namespace wirelesscasting } // namespace dde