diff --git a/styleplugins/chameleon/chameleonstyle.cpp b/styleplugins/chameleon/chameleonstyle.cpp index 8a67b7a..2bcde5c 100644 --- a/styleplugins/chameleon/chameleonstyle.cpp +++ b/styleplugins/chameleon/chameleonstyle.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017 - 2023 UnionTech Software Technology Co., Ltd. + * SPDX-FileCopyrightText: 2017 - 2024 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "chameleonstyle.h" @@ -114,6 +114,49 @@ static QRect spinboxIndicatorRect(const QRect &r) return QRect(xOffset, yOffset, size, size); } +static void checkDciIconEngine(bool checked, const QString &checkedIconName, const QString &uncheckedIconName + , QEvent *event, DDciIconPlayer *dciIconPlayer, QWidget *widget) { + DDciIcon icon = checked ? DDciIcon::fromTheme(checkedIconName) : DDciIcon::fromTheme(uncheckedIconName); + if (event->type() == QEvent::Paint) { + DDciIconPalette palette; + palette.setHighlight(widget->palette().highlight().color()); + dciIconPlayer->setPalette(palette); + } + if (event->type() == QEvent::WindowActivate) { + dciIconPlayer->setIcon(icon); + dciIconPlayer->setMode(DDciIcon::Normal); + } + if (event->type() == QEvent::MouseButtonPress) { + dciIconPlayer->setIcon(icon); + dciIconPlayer->play(DDciIcon::Pressed); + } else if (event->type() == QEvent::HoverEnter) { + dciIconPlayer->setIcon(icon); + dciIconPlayer->play(DDciIcon::Hover); + } else if (event->type() == QEvent::MouseButtonRelease) { + icon = !checked ? DDciIcon::fromTheme(checkedIconName) : DDciIcon::fromTheme(uncheckedIconName); + dciIconPlayer->setIcon(icon); + dciIconPlayer->play(DDciIcon::Hover); + } else if (event->type() == QEvent::HoverLeave) { + dciIconPlayer->setIcon(icon); + dciIconPlayer->play(DDciIcon::Normal); + } else if (event->type() == QEvent::KeyPress) { + if (auto key = dynamic_cast(event)) { + if (key->key() == Qt::Key_Space) { + dciIconPlayer->setIcon(icon); + dciIconPlayer->play(DDciIcon::Pressed); + } + } + } else if (event->type() == QEvent::KeyRelease) { + if (auto key = dynamic_cast(event)) { + if (key->key() == Qt::Key_Space) { + icon = !checked ? DDciIcon::fromTheme(checkedIconName) : DDciIcon::fromTheme(uncheckedIconName); + dciIconPlayer->setIcon(icon); + dciIconPlayer->play(DDciIcon::Normal); + } + } + } +} + // the object is the class's instance. template inline static bool isTheClassObject(QObject *object) @@ -439,67 +482,31 @@ void ChameleonStyle::drawPrimitive(QStyle::PrimitiveElement pe, const QStyleOpti return; } case PE_IndicatorRadioButton: { - QRect standard = opt->rect; - - p->setRenderHint(QPainter::Antialiasing, true); - - if (opt->state & State_On) { //Qt::Checked - int padding = qCeil(standard.width() / 2.0 / 2.0); - QPainterPath path; + auto radioButton = qobject_cast(opt->styleObject); + if (!radioButton) + radioButton = dynamic_cast(p->device()); - path.addEllipse(standard); - path.addEllipse(standard.adjusted(padding, padding, -padding, -padding)); - - p->fillPath(path, getColor(opt, DPalette::Highlight)); + if (!radioButton) + return; - // 内圈填充 - QPainterPath innerCirclePath; - innerCirclePath.addEllipse(standard.adjusted(padding, padding, -padding, -padding)); - p->fillPath(innerCirclePath, getThemTypeColor(Qt::white, Qt::black)); - } else if (opt->state & State_Off) { - p->setPen(QPen(getColor(opt, DPalette::WindowText), 1)); - p->drawEllipse(standard.adjusted(1, 1, -1, -1)); - - // 内圈填充 - QPainterPath innerCirclePath; - innerCirclePath.addEllipse(standard.adjusted(1, 1, -1, -1)); - p->fillPath(innerCirclePath, getThemTypeColor(Qt::transparent, QColor(0, 0, 0, qCeil(255 * 0.5)))); - } + auto dciIconPlayer = dciIconPlayers.value(radioButton); + p->setRenderHint(QPainter::SmoothPixmapTransform); + p->drawImage(opt->rect.adjusted(-1, -1, 1, 1), dciIconPlayer->currentImage()); return; } case PE_IndicatorCheckBox: { - QRectF standard = opt->rect; - - if (opt->state & State_NoChange) { //Qt::PartiallyChecked - DDrawUtils::drawBorder(p, standard, getColor(opt, DPalette::WindowText), 1, 2); - - // 内部矩形填充 - p->setBrush(getThemTypeColor(Qt::transparent, QColor(0, 0, 0, qCeil(255 * 0.5)))); - p->drawRoundedRect(standard.adjusted(1, 1, -1, -1), 2, 2); - - QRectF lineRect(0, 0, standard.width() / 2.0, 2); - lineRect.moveCenter(standard.center()); - p->fillRect(lineRect, getColor(opt, DPalette::TextTitle, w)); - } else if (opt->state & State_On) { //Qt::Checked - // 填充整个矩形 - p->setPen(Qt::NoPen); - p->setBrush(getThemTypeColor(Qt::transparent, Qt::black)); - p->drawRoundedRect(standard.adjusted(1, 1, -1, -1), 2, 2); + auto checkBox = qobject_cast(opt->styleObject); + if (!checkBox) + checkBox = dynamic_cast(p->device()); - p->setPen(getColor(opt, DPalette::Highlight)); - p->setBrush(Qt::NoBrush); - - QIcon icon = QIcon::fromTheme("checked"); - icon.paint(p, opt->rect.adjusted(-1, -1, 1, 1)); - } else { - DDrawUtils::drawBorder(p, standard, getColor(opt, DPalette::WindowText), 1, 2); + if (!checkBox) + return; - // 内部矩形填充 - p->setBrush(getThemTypeColor(Qt::transparent, getThemTypeColor(Qt::transparent, QColor(0, 0, 0, qCeil(255 * 0.5))))); - p->drawRoundedRect(standard.adjusted(1, 1, -1, -1), 2, 2); - } + auto dciIconPlayer = dciIconPlayers.value(checkBox); + p->setRenderHint(QPainter::SmoothPixmapTransform); + p->drawImage(opt->rect.adjusted(-1, -1, 1, 1), dciIconPlayer->currentImage()); return; } case PE_IndicatorTabClose: { @@ -4495,6 +4502,53 @@ void ChameleonStyle::resetAttribute(QWidget *w, bool polish) scrollbar->setProperty("_d_dtk_scrollbar_visible", true); scrollbar->setAttribute(Qt::WA_OpaquePaintEvent, !polish); } + + if (auto radioButton = qobject_cast(w)) { + if (polish) { + radioButton->installEventFilter(this); + } else { + radioButton->removeEventFilter(this); + } + auto dciIconPlayer = new DDciIconPlayer(radioButton); + connect(dciIconPlayer, &DDciIconPlayer::updated, radioButton, [radioButton]() { + radioButton->update(); + }); + dciIconPlayers.insert(radioButton, dciIconPlayer); + } + + if (auto checkBox = qobject_cast(w)) { + if (polish) { + checkBox->installEventFilter(this); + } else { + checkBox->removeEventFilter(this); + } + auto dciIconPlayer = new DDciIconPlayer(checkBox); + connect(dciIconPlayer, &DDciIconPlayer::updated, checkBox, [checkBox]() { + checkBox->update(); + }); + dciIconPlayers.insert(checkBox, dciIconPlayer); + } +} + +bool ChameleonStyle::eventFilter(QObject *watched, QEvent *event) +{ + if (auto radioButton = qobject_cast(watched)) { + checkDciIconEngine(radioButton->isChecked() + , "radio_checked" + , "radio_unchecked" + , event + , dciIconPlayers.value(radioButton) + , radioButton); + } + if (auto checkBox = qobject_cast(watched)) { + checkDciIconEngine(checkBox->isChecked() + , "checkbox_checked" + , "checkbox_unchecked" + , event + , dciIconPlayers.value(checkBox) + , checkBox); + } + return false; } static void updateWeekendTextFormat(QCalendarWidget *calendar, QColor) diff --git a/styleplugins/chameleon/chameleonstyle.h b/styleplugins/chameleon/chameleonstyle.h index f4c5eb8..f239645 100644 --- a/styleplugins/chameleon/chameleonstyle.h +++ b/styleplugins/chameleon/chameleonstyle.h @@ -1,11 +1,12 @@ /* - * SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. + * SPDX-FileCopyrightText: 2017 - 2024 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #ifndef CHAMELEONSTYLE_H #define CHAMELEONSTYLE_H #include +#include #include DWIDGET_USE_NAMESPACE @@ -125,6 +126,9 @@ class ChameleonStyle : public DStyle private: mutable QHash animations; + mutable QHash dciIconPlayers; + + bool eventFilter(QObject *watched, QEvent *event) override; }; } // namespace chameleon