feat: 添加ElaWidgetTool库
This commit is contained in:
259
ElaWidgetTools/ElaPromotionCard.cpp
Normal file
259
ElaWidgetTools/ElaPromotionCard.cpp
Normal file
@@ -0,0 +1,259 @@
|
||||
#include "ElaPromotionCard.h"
|
||||
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QPropertyAnimation>
|
||||
#include <QRadialGradient>
|
||||
#include <QtMath>
|
||||
|
||||
#include "ElaPromotionCardPrivate.h"
|
||||
#include "ElaTheme.h"
|
||||
Q_PROPERTY_CREATE_Q_CPP(ElaPromotionCard, int, BorderRadius)
|
||||
Q_PROPERTY_CREATE_Q_CPP(ElaPromotionCard, QPixmap, CardPixmap)
|
||||
Q_PROPERTY_CREATE_Q_CPP(ElaPromotionCard, QString, CardTitle)
|
||||
Q_PROPERTY_CREATE_Q_CPP(ElaPromotionCard, QString, PromotionTitle)
|
||||
Q_PROPERTY_CREATE_Q_CPP(ElaPromotionCard, QString, Title)
|
||||
Q_PROPERTY_CREATE_Q_CPP(ElaPromotionCard, QString, SubTitle)
|
||||
Q_PROPERTY_CREATE_Q_CPP(ElaPromotionCard, QColor, CardTitleColor)
|
||||
Q_PROPERTY_CREATE_Q_CPP(ElaPromotionCard, QColor, PromotionTitleColor)
|
||||
Q_PROPERTY_CREATE_Q_CPP(ElaPromotionCard, QColor, PromotionTitleBaseColor)
|
||||
Q_PROPERTY_CREATE_Q_CPP(ElaPromotionCard, QColor, TitleColor)
|
||||
Q_PROPERTY_CREATE_Q_CPP(ElaPromotionCard, QColor, SubTitleColor)
|
||||
Q_PROPERTY_CREATE_Q_CPP(ElaPromotionCard, int, CardTitlePixelSize)
|
||||
Q_PROPERTY_CREATE_Q_CPP(ElaPromotionCard, int, PromotionTitlePixelSize)
|
||||
Q_PROPERTY_CREATE_Q_CPP(ElaPromotionCard, int, TitlePixelSize)
|
||||
Q_PROPERTY_CREATE_Q_CPP(ElaPromotionCard, int, SubTitlePixelSize)
|
||||
ElaPromotionCard::ElaPromotionCard(QWidget* parent)
|
||||
: QWidget{parent}, d_ptr(new ElaPromotionCardPrivate())
|
||||
{
|
||||
Q_D(ElaPromotionCard);
|
||||
d->q_ptr = this;
|
||||
d->_pBorderRadius = 5;
|
||||
d->_pPressRadius = 0;
|
||||
d->_pHoverOpacity = 0;
|
||||
d->_pHorizontalCardPixmapRatio = 1;
|
||||
d->_pVerticalCardPixmapRatio = 1;
|
||||
d->_pCardTitle = "";
|
||||
d->_pPromotionTitle = "";
|
||||
d->_pTitle = "";
|
||||
d->_pSubTitle = "";
|
||||
d->_pCardTitleColor = Qt::white;
|
||||
d->_pPromotionTitleColor = Qt::white;
|
||||
d->_pTitleColor = Qt::white;
|
||||
d->_pSubTitleColor = Qt::white;
|
||||
d->_pPromotionTitleBaseColor = QColor(0, 0, 0, 120);
|
||||
d->_pCardTitlePixelSize = 22;
|
||||
d->_pPromotionTitlePixelSize = 12;
|
||||
d->_pTitlePixelSize = 25;
|
||||
d->_pSubTitlePixelSize = 16;
|
||||
setMouseTracking(true);
|
||||
setObjectName("ElaPromotionCard");
|
||||
setStyleSheet("#ElaPromotionCard{background-color:transparent;}");
|
||||
d->_hoverGradient = new QRadialGradient();
|
||||
d->_hoverGradient->setRadius(170);
|
||||
d->_hoverGradient->setColorAt(0, QColor(0xFF, 0xFF, 0xFF, 40));
|
||||
d->_hoverGradient->setColorAt(1, QColor(0xFF, 0xFF, 0xFF, 0));
|
||||
|
||||
d->_pressGradient = new QRadialGradient();
|
||||
d->_pressGradient->setRadius(170);
|
||||
d->_pressGradient->setColorAt(0, QColor(0xFF, 0xFF, 0xFF, 0));
|
||||
d->_pressGradient->setColorAt(1, QColor(0xFF, 0xFF, 0xFF, 40));
|
||||
}
|
||||
|
||||
ElaPromotionCard::~ElaPromotionCard()
|
||||
{
|
||||
Q_D(const ElaPromotionCard);
|
||||
delete d->_hoverGradient;
|
||||
delete d->_pressGradient;
|
||||
}
|
||||
|
||||
void ElaPromotionCard::setHorizontalCardPixmapRatio(qreal pixmapRatio)
|
||||
{
|
||||
Q_D(ElaPromotionCard);
|
||||
if (pixmapRatio > 0 && pixmapRatio <= 1)
|
||||
{
|
||||
Q_EMIT pHorizontalCardPixmapRatioChanged();
|
||||
d->_pHorizontalCardPixmapRatio = pixmapRatio;
|
||||
}
|
||||
}
|
||||
|
||||
qreal ElaPromotionCard::getHorizontalCardPixmapRatio() const
|
||||
{
|
||||
Q_D(const ElaPromotionCard);
|
||||
return d->_pHorizontalCardPixmapRatio;
|
||||
}
|
||||
|
||||
void ElaPromotionCard::setVerticalCardPixmapRatio(qreal pixmapRatio)
|
||||
{
|
||||
Q_D(ElaPromotionCard);
|
||||
if (pixmapRatio > 0 && pixmapRatio <= 1)
|
||||
{
|
||||
Q_EMIT pVerticalCardPixmapRatioChanged();
|
||||
d->_pVerticalCardPixmapRatio = pixmapRatio;
|
||||
}
|
||||
}
|
||||
|
||||
qreal ElaPromotionCard::getVerticalCardPixmapRatio() const
|
||||
{
|
||||
Q_D(const ElaPromotionCard);
|
||||
return d->_pVerticalCardPixmapRatio;
|
||||
}
|
||||
|
||||
bool ElaPromotionCard::event(QEvent* event)
|
||||
{
|
||||
Q_D(ElaPromotionCard);
|
||||
switch (event->type())
|
||||
{
|
||||
case QEvent::MouseButtonPress:
|
||||
{
|
||||
QMouseEvent* mouseEvent = dynamic_cast<QMouseEvent*>(event);
|
||||
QPropertyAnimation* opacityAnimation = new QPropertyAnimation(d, "pPressOpacity");
|
||||
connect(opacityAnimation, &QPropertyAnimation::valueChanged, this, [=](const QVariant& value) {
|
||||
update();
|
||||
});
|
||||
connect(opacityAnimation, &QPropertyAnimation::finished, this, [=]() {
|
||||
d->_isPressAnimationFinished = true;
|
||||
});
|
||||
opacityAnimation->setDuration(300);
|
||||
opacityAnimation->setEasingCurve(QEasingCurve::InQuad);
|
||||
opacityAnimation->setStartValue(1);
|
||||
opacityAnimation->setEndValue(0);
|
||||
opacityAnimation->start(QAbstractAnimation::DeleteWhenStopped);
|
||||
|
||||
QPropertyAnimation* pressAnimation = new QPropertyAnimation(d, "pPressRadius");
|
||||
connect(pressAnimation, &QPropertyAnimation::valueChanged, this, [=](const QVariant& value) {
|
||||
d->_pressGradient->setRadius(value.toReal());
|
||||
});
|
||||
pressAnimation->setDuration(300);
|
||||
pressAnimation->setEasingCurve(QEasingCurve::InQuad);
|
||||
pressAnimation->setStartValue(30);
|
||||
pressAnimation->setEndValue(d->_getLongestDistance(mouseEvent->pos()) * 1.8);
|
||||
pressAnimation->start(QAbstractAnimation::DeleteWhenStopped);
|
||||
d->_isPressAnimationFinished = false;
|
||||
d->_pressGradient->setFocalPoint(mouseEvent->pos());
|
||||
d->_pressGradient->setCenter(mouseEvent->pos());
|
||||
//点击后隐藏Hover效果
|
||||
d->_startHoverOpacityAnimation(false);
|
||||
break;
|
||||
}
|
||||
case QEvent::MouseButtonRelease:
|
||||
{
|
||||
Q_EMIT promotionCardClicked();
|
||||
break;
|
||||
}
|
||||
case QEvent::MouseMove:
|
||||
{
|
||||
QMouseEvent* mouseEvent = dynamic_cast<QMouseEvent*>(event);
|
||||
if (d->_pHoverOpacity < 1 && d->_isPressAnimationFinished)
|
||||
{
|
||||
d->_startHoverOpacityAnimation(true);
|
||||
}
|
||||
if (d->_isPressAnimationFinished)
|
||||
{
|
||||
d->_hoverGradient->setCenter(mouseEvent->pos());
|
||||
d->_hoverGradient->setFocalPoint(mouseEvent->pos());
|
||||
}
|
||||
update();
|
||||
break;
|
||||
}
|
||||
case QEvent::Enter:
|
||||
{
|
||||
d->_startHoverOpacityAnimation(true);
|
||||
break;
|
||||
}
|
||||
case QEvent::Leave:
|
||||
{
|
||||
d->_startHoverOpacityAnimation(false);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
void ElaPromotionCard::paintEvent(QPaintEvent* event)
|
||||
{
|
||||
Q_D(ElaPromotionCard);
|
||||
QPainter painter(this);
|
||||
painter.save();
|
||||
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
|
||||
painter.setPen(Qt::NoPen);
|
||||
//阴影绘制
|
||||
eTheme->drawEffectShadow(&painter, rect(), d->_shadowBorderWidth, d->_pBorderRadius);
|
||||
QRect foregroundRect(d->_shadowBorderWidth, d->_shadowBorderWidth, width() - 2 * d->_shadowBorderWidth, height() - 2 * d->_shadowBorderWidth);
|
||||
QPainterPath path;
|
||||
path.addRoundedRect(foregroundRect, d->_pBorderRadius, d->_pBorderRadius);
|
||||
painter.setClipPath(path);
|
||||
//背景图片绘制
|
||||
if (!d->_pCardPixmap.isNull())
|
||||
{
|
||||
//源区域计算
|
||||
QRect pixSourceRect = d->_pCardPixmap.rect();
|
||||
qreal horizontalOffset = d->_pCardPixmap.width() * (1 - d->_pHorizontalCardPixmapRatio) / 2;
|
||||
qreal verticalOffset = d->_pCardPixmap.height() * (1 - d->_pVerticalCardPixmapRatio) / 2;
|
||||
pixSourceRect.adjust(horizontalOffset, verticalOffset, -horizontalOffset, -verticalOffset);
|
||||
painter.drawPixmap(foregroundRect, d->_pCardPixmap, pixSourceRect);
|
||||
}
|
||||
//文字绘制
|
||||
painter.save();
|
||||
QFont font = painter.font();
|
||||
//卡片标题
|
||||
font.setWeight(QFont::Bold);
|
||||
font.setPixelSize(d->_pCardTitlePixelSize);
|
||||
painter.setFont(font);
|
||||
painter.setPen(d->_pCardTitleColor);
|
||||
painter.drawText(QRect(25, 25, foregroundRect.width() - 25, foregroundRect.height()), Qt::AlignLeft | Qt::AlignTop | Qt::TextSingleLine, d->_pCardTitle);
|
||||
//标题
|
||||
font.setWeight(QFont::Bold);
|
||||
font.setPixelSize(d->_pTitlePixelSize);
|
||||
painter.setFont(font);
|
||||
painter.setPen(d->_pTitleColor);
|
||||
int titleTextHeight = painter.fontMetrics().height();
|
||||
QRect titleRect(25, (height() - titleTextHeight) / 2, foregroundRect.width() - 25, titleTextHeight);
|
||||
painter.drawText(titleRect, Qt::AlignLeft | Qt::AlignBottom | Qt::TextSingleLine, d->_pTitle);
|
||||
//推广标题
|
||||
if (!d->_pPromotionTitle.isEmpty())
|
||||
{
|
||||
font.setWeight(QFont::Normal);
|
||||
font.setPixelSize(d->_pPromotionTitlePixelSize);
|
||||
painter.setFont(font);
|
||||
int promotionTitleTextWidth = painter.fontMetrics().horizontalAdvance(d->_pPromotionTitle);
|
||||
int promotionTitleTextHeight = painter.fontMetrics().height();
|
||||
QRect promotionTitleTextRect(32, titleRect.top() - promotionTitleTextHeight - 5, foregroundRect.width() / 2 - 25, promotionTitleTextHeight);
|
||||
//背景绘制
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.setBrush(d->_pPromotionTitleBaseColor);
|
||||
painter.drawRoundedRect(QRect(25, promotionTitleTextRect.top() - 2, promotionTitleTextWidth + 14, promotionTitleTextHeight + 4), 8, 8);
|
||||
//文字绘制
|
||||
painter.setPen(d->_pPromotionTitleColor);
|
||||
painter.drawText(promotionTitleTextRect, Qt::AlignLeft | Qt::AlignBottom | Qt::TextSingleLine, d->_pPromotionTitle);
|
||||
}
|
||||
//副标题
|
||||
font.setWeight(QFont::Medium);
|
||||
font.setPixelSize(d->_pSubTitlePixelSize);
|
||||
painter.setFont(font);
|
||||
painter.setPen(d->_pSubTitleColor);
|
||||
painter.drawText(QRect(25, titleRect.bottom(), foregroundRect.width() / 2 - 25, height() / 2), Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, d->_pSubTitle);
|
||||
|
||||
painter.restore();
|
||||
//效果阴影绘制
|
||||
if (d->_isPressAnimationFinished)
|
||||
{
|
||||
//覆盖阴影绘制
|
||||
painter.setOpacity(d->_pHoverOpacity);
|
||||
painter.setBrush(*d->_hoverGradient);
|
||||
painter.drawEllipse(d->_hoverGradient->center(), d->_hoverGradient->radius(), d->_hoverGradient->radius());
|
||||
}
|
||||
else
|
||||
{
|
||||
//点击阴影绘制
|
||||
painter.setOpacity(d->_pPressOpacity);
|
||||
painter.setBrush(*d->_pressGradient);
|
||||
painter.drawEllipse(d->_pressGradient->center(), d->_pPressRadius, d->_pPressRadius / 1.1);
|
||||
}
|
||||
painter.restore();
|
||||
}
|
||||
Reference in New Issue
Block a user