diff --git a/include/widgets/dtoolbutton.h b/include/widgets/dtoolbutton.h index 95d4feb50..61982ea02 100644 --- a/include/widgets/dtoolbutton.h +++ b/include/widgets/dtoolbutton.h @@ -5,23 +5,34 @@ #ifndef DTOOLBUTTON_H #define DTOOLBUTTON_H -#include #include +#include + +#include +#include + DWIDGET_BEGIN_NAMESPACE +DGUI_USE_NAMESPACE -class LIBDTKWIDGETSHARED_EXPORT DToolButton : public QToolButton +class DToolButtonPrivate; +class LIBDTKWIDGETSHARED_EXPORT DToolButton : public QToolButton, public DCORE_NAMESPACE::DObject { Q_OBJECT public: DToolButton(QWidget *parent = nullptr); void setAlignment(Qt::Alignment flag); Qt::Alignment alignment() const; + void setDciIcon(const DDciIcon &dciIcon); protected: void paintEvent(QPaintEvent *event) override; void initStyleOption(QStyleOptionToolButton *option) const; QSize sizeHint() const override; + bool event(QEvent *e) override; + +private: + D_DECLARE_PRIVATE(DToolButton) }; DWIDGET_END_NAMESPACE diff --git a/src/widgets/assets/icons/bloom/checkbox_checked.dci b/src/widgets/assets/icons/bloom/checkbox_checked.dci new file mode 100644 index 000000000..de3949458 Binary files /dev/null and b/src/widgets/assets/icons/bloom/checkbox_checked.dci differ diff --git a/src/widgets/assets/icons/bloom/checkbox_unchecked.dci b/src/widgets/assets/icons/bloom/checkbox_unchecked.dci new file mode 100644 index 000000000..413e4145a Binary files /dev/null and b/src/widgets/assets/icons/bloom/checkbox_unchecked.dci differ diff --git a/src/widgets/assets/icons/bloom/radio_checked.dci b/src/widgets/assets/icons/bloom/radio_checked.dci new file mode 100644 index 000000000..69df89f3b Binary files /dev/null and b/src/widgets/assets/icons/bloom/radio_checked.dci differ diff --git a/src/widgets/assets/icons/bloom/radio_unchecked.dci b/src/widgets/assets/icons/bloom/radio_unchecked.dci new file mode 100644 index 000000000..792ce8ec2 Binary files /dev/null and b/src/widgets/assets/icons/bloom/radio_unchecked.dci differ diff --git a/src/widgets/assets/icons/dtk-icon-theme.qrc b/src/widgets/assets/icons/dtk-icon-theme.qrc index c4761d464..d0c68f8ba 100644 --- a/src/widgets/assets/icons/dtk-icon-theme.qrc +++ b/src/widgets/assets/icons/dtk-icon-theme.qrc @@ -72,5 +72,9 @@ bloom/window_maximize.dci bloom/window_minimize.dci bloom/window_normal.dci + bloom/radio_checked.dci + bloom/radio_unchecked.dci + bloom/checkbox_checked.dci + bloom/checkbox_unchecked.dci diff --git a/src/widgets/dtoolbutton.cpp b/src/widgets/dtoolbutton.cpp index a2ac4d42f..7ce71c191 100644 --- a/src/widgets/dtoolbutton.cpp +++ b/src/widgets/dtoolbutton.cpp @@ -2,13 +2,25 @@ // // SPDX-License-Identifier: LGPL-3.0-or-later -#include "dtoolbutton.h" +#include "private/dtoolbutton_p.h" + +#include +#include #include #include +#include +#include +#include DWIDGET_BEGIN_NAMESPACE +Dtk::Widget::DToolButtonPrivate::DToolButtonPrivate(DToolButton *qq) + : DObjectPrivate(qq) +{ + +} + /*! @~english @class Dtk::Widget::DToolButton @@ -17,8 +29,15 @@ DWIDGET_BEGIN_NAMESPACE DToolButton::DToolButton(QWidget *parent) : QToolButton(parent) + , DObject(*new DToolButtonPrivate(this)) { - + D_D(DToolButton); + connect(this, &DToolButton::pressed, this, [d]() { + d->m_dciPlayer.play(DDciIcon::Pressed); + }); + connect(this, &DToolButton::released, this, [d]() { + d->m_dciPlayer.play(DDciIcon::Normal); + }); } /*! @@ -30,10 +49,26 @@ DToolButton::DToolButton(QWidget *parent) void DToolButton::paintEvent(QPaintEvent *event) { + D_D(DToolButton); Q_UNUSED(event) QStylePainter p(this); QStyleOptionToolButton opt; initStyleOption(&opt); + + if (!d->m_dciIcon.isNull()) { + p.setRenderHint(QPainter::SmoothPixmapTransform); + p.drawImage(rect(), d->m_dciPlayer.currentImage()); + + if (opt.state & QStyle::State_HasFocus) { + p.setPen(QPen(palette().highlight().color(), 2)); + p.setBrush(Qt::NoBrush); + p.setRenderHint(QPainter::Antialiasing); + int radius = DStyle::pixelMetric(style(), DStyle::PM_FrameRadius); + p.drawRoundedRect(opt.rect.marginsRemoved(QMargins(1, 1, 1, 1)), radius, radius); + } + return; + } + p.drawComplexControl(QStyle::CC_ToolButton, opt); } @@ -60,6 +95,26 @@ QSize DToolButton::sizeHint() const return QToolButton::sizeHint(); } +bool DToolButton::event(QEvent *e) +{ + D_D(DToolButton); + if (d->m_dciIcon.isNull()) + return QToolButton::event(e); + + if (e->type() == QEvent::WindowActivate) { + auto palette = DDciIconPalette::fromQPalette(this->palette()); + d->m_dciPlayer.setPalette(palette); + d->m_dciPlayer.setTheme(DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::DarkType + ? DDciIcon::Dark : DDciIcon::Light); + d->m_dciPlayer.setMode(DDciIcon::Normal); + } else if (e->type() == QEvent::HoverEnter) { + d->m_dciPlayer.play(DDciIcon::Hover); + } else if (e->type() == QEvent::HoverLeave) { + d->m_dciPlayer.play(DDciIcon::Normal); + } + return QToolButton::event(e); +} + /*! @~english @fn void DToolButton::setAlignment(Qt::Alignment flag) @@ -85,4 +140,22 @@ Qt::Alignment DToolButton::alignment() const return Qt::AlignLeft; } +void DToolButton::setDciIcon(const DDciIcon &dciIcon) +{ + D_D(DToolButton); + d->m_dciIcon = dciIcon; + d->m_dciPlayer.setIcon(dciIcon); + d->m_dciPlayer.setIconSize(120); + + connect(&d->m_dciPlayer, &DDciIconPlayer::updated, this, [this]() { + update(); + }); + + connect(DGuiApplicationHelper::instance(), &DGuiApplicationHelper::themeTypeChanged, this, [this, d](DGuiApplicationHelper::ColorType colorType) { + auto palette = DDciIconPalette::fromQPalette(this->palette()); + d->m_dciPlayer.setPalette(palette); + d->m_dciPlayer.setTheme(colorType ? DDciIcon::Dark : DDciIcon::Light); + }); +} + DWIDGET_END_NAMESPACE diff --git a/src/widgets/private/dtoolbutton_p.h b/src/widgets/private/dtoolbutton_p.h new file mode 100644 index 000000000..ff90bf41e --- /dev/null +++ b/src/widgets/private/dtoolbutton_p.h @@ -0,0 +1,26 @@ +// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#ifndef DABOUTDIALOG_P_H +#define DABOUTDIALOG_P_H + +#include +#include + +DWIDGET_BEGIN_NAMESPACE + +class DToolButtonPrivate : public DCORE_NAMESPACE::DObjectPrivate +{ +public: + DToolButtonPrivate(DToolButton *qq); + + DDciIcon m_dciIcon; + DDciIconPlayer m_dciPlayer; + + Q_DECLARE_PUBLIC(DToolButton) +}; + +DWIDGET_END_NAMESPACE + +#endif // DABOUTDIALOG_P_H