#include "ElaPromotionViewPrivate.h" #include #include "ElaPromotionCard.h" #include "ElaPromotionView.h" ElaPromotionViewPrivate::ElaPromotionViewPrivate(QObject *parent) : QObject{parent} {} ElaPromotionViewPrivate::~ElaPromotionViewPrivate() {} void ElaPromotionViewPrivate::onPromotionCardClicked(ElaPromotionCard *clickedCard) { Q_Q(ElaPromotionView); int newCurrentIndex = _promotionCardList.indexOf(clickedCard); int oldCurrentIndex = _pCurrentIndex; if (newCurrentIndex == oldCurrentIndex) { return; } // 卡片移动动画 bool isRightToLeft = _promotionCardList[oldCurrentIndex]->x() < _promotionCardList[newCurrentIndex]->x(); int originIndex = _getAdjacentIndex(Qt::RightToLeft, newCurrentIndex); for (int i = 0; i < _promotionCardList.count(); i++) { ElaPromotionCard *card = _promotionCardList[originIndex]; QPropertyAnimation *geometryAnimation = new QPropertyAnimation(card, "geometry"); QRect geometry = card->geometry(); geometryAnimation->setEasingCurve(QEasingCurve::OutCubic); geometryAnimation->setDuration(650); geometryAnimation->setStartValue(geometry); if (i == 0) { // 最左侧卡片 QRect targetGeometry(-_pCardCollapseWidth + _leftPadding, 0, _pCardCollapseWidth, q->height() - _bottomMargin); if (_promotionCardList.count() > 2) { if (!isRightToLeft) { geometryAnimation->setKeyValueAt( 0.7, QRect(geometry.x() + _pCardCollapseWidth * 0.7 + _cardSpacing, 0, _pCardCollapseWidth, q->height() - _bottomMargin)); geometryAnimation->setKeyValueAt(0.71, QRect(-_pCardCollapseWidth, 0, _pCardCollapseWidth, q->height() - _bottomMargin)); } geometryAnimation->setEndValue(targetGeometry); } else { if (isRightToLeft) { geometryAnimation->setEndValue(targetGeometry); } else { geometryAnimation->setEndValue( QRect(_leftPadding + _pCardExpandWidth + _cardSpacing * 2, 0, _pCardCollapseWidth, q->height() - _bottomMargin)); } } _startHorizontalCardPixmapRatioAnimation(card, card->getHorizontalCardPixmapRatio(), 0.5); } else if (i == 1) { // 展开的卡片 geometryAnimation->setEndValue(QRect(_leftPadding + _cardSpacing, 0, _pCardExpandWidth, q->height() - _bottomMargin)); _startHorizontalCardPixmapRatioAnimation(card, card->getHorizontalCardPixmapRatio(), 1); } else { QRect targetGeometry(_leftPadding + _pCardExpandWidth + _cardSpacing * i + _pCardCollapseWidth * (i - 2), 0, _pCardCollapseWidth, q->height() - _bottomMargin); if (isRightToLeft && targetGeometry.x() > card->x()) { connect(geometryAnimation, &QPropertyAnimation::valueChanged, this, [=]() { if (card->geometry().right() <= 0) { geometryAnimation->pause(); qreal timeRatio = geometryAnimation->currentTime() / 650.0; geometryAnimation->setKeyValueAt( timeRatio, QRect(_promotionCardList[_getAdjacentIndex(Qt::RightToLeft, originIndex)]->geometry().right() + _pCardCollapseWidth * (1 - timeRatio), 0, _pCardCollapseWidth, q->height() - _bottomMargin)); geometryAnimation->setEndValue(targetGeometry); geometryAnimation->resume(); } }); geometryAnimation->setEndValue(QRect(-_pCardCollapseWidth * 2 + _leftPadding, 0, _pCardCollapseWidth, q->height() - _bottomMargin)); } else { geometryAnimation->setEndValue(targetGeometry); } card->setHorizontalCardPixmapRatio(0.5); } originIndex = _getAdjacentIndex(Qt::LeftToRight, originIndex); geometryAnimation->start(QAbstractAnimation::DeleteWhenStopped); } _pCurrentIndex = newCurrentIndex; q->update(); Q_EMIT q->pCurrentIndexChanged(); } void ElaPromotionViewPrivate::_startCardGeometryAnimation(ElaPromotionCard *card, QRect start, QRect end) { QPropertyAnimation *geometryAnimation = new QPropertyAnimation(card, "geometry"); geometryAnimation->setEasingCurve(QEasingCurve::OutCubic); geometryAnimation->setDuration(650); geometryAnimation->setStartValue(start); geometryAnimation->setEndValue(end); geometryAnimation->start(QAbstractAnimation::DeleteWhenStopped); } void ElaPromotionViewPrivate::_startHorizontalCardPixmapRatioAnimation(ElaPromotionCard *card, qreal start, qreal end) { QPropertyAnimation *ratioAnimation = new QPropertyAnimation(card, "pHorizontalCardPixmapRatio"); ratioAnimation->setEasingCurve(QEasingCurve::OutCubic); ratioAnimation->setDuration(650); ratioAnimation->setStartValue(start); ratioAnimation->setEndValue(end); ratioAnimation->start(QAbstractAnimation::DeleteWhenStopped); } void ElaPromotionViewPrivate::_updatePromotionCardGeometry() { Q_Q(ElaPromotionView); if (_promotionCardList.count() < 3) { if (_promotionCardList.count() == 1) { _promotionCardList[0]->setGeometry(_leftPadding + _cardSpacing, 0, _pCardExpandWidth, q->height() - _bottomMargin); } else { _promotionCardList[0]->setGeometry(_leftPadding + _cardSpacing, 0, _pCardExpandWidth, q->height() - _bottomMargin); QRect lastGeometry = _promotionCardList[0]->geometry(); _promotionCardList[1]->setGeometry( QRect(lastGeometry.right() + _cardSpacing, lastGeometry.y(), _pCardCollapseWidth, lastGeometry.height())); _promotionCardList[1]->setHorizontalCardPixmapRatio(0.5); } } else { for (int i = 0; i < _promotionCardList.count(); i++) { if (i == 0) { // 展开的卡片 _promotionCardList[i]->setGeometry(_leftPadding + _cardSpacing, 0, _pCardExpandWidth, q->height() - _bottomMargin); _promotionCardList[i]->setHorizontalCardPixmapRatio(1); } else if (i == _promotionCardList.count() - 1) { // 最左侧卡片 _promotionCardList[i]->setGeometry(-_pCardCollapseWidth + _leftPadding, 0, _pCardCollapseWidth, q->height() - _bottomMargin); _promotionCardList[i]->setHorizontalCardPixmapRatio(0.5); } else { QRect lastGeometry = _promotionCardList[i - 1]->geometry(); _promotionCardList[i]->setGeometry( QRect(lastGeometry.right() + _cardSpacing, lastGeometry.y(), _pCardCollapseWidth, lastGeometry.height())); _promotionCardList[i]->setHorizontalCardPixmapRatio(0.5); } } } } int ElaPromotionViewPrivate::_getAdjacentIndex(Qt::LayoutDirection direction, int index) { if (direction == Qt::LeftToRight) { if (index == _promotionCardList.count() - 1) { return 0; } return index + 1; } else { if (index > 0) { return index - 1; } return _promotionCardList.count() - 1; } } int ElaPromotionViewPrivate::_getRightLimitX() { int count = _promotionCardList.count(); return _leftPadding + _pCardExpandWidth + _cardSpacing * (count - 1) + _pCardCollapseWidth * (count - 3); }