#include "ElaCalendarPrivate.h" #include #include #include #include "ElaBaseListView.h" #include "ElaCalendar.h" #include "ElaCalendarDelegate.h" #include "ElaCalendarModel.h" #include "ElaToolButton.h" ElaCalendarPrivate::ElaCalendarPrivate(QObject *parent) : QObject{parent} { _pZoomRatio = 1; _pPixOpacity = 1; } ElaCalendarPrivate::~ElaCalendarPrivate() {} void ElaCalendarPrivate::onSwitchButtonClicked() { if (!_isSwitchAnimationFinished) { return; } Q_Q(ElaCalendar); ElaCalendarType displayMode = _calendarModel->getDisplayMode(); if (displayMode == ElaCalendarType::DayMode) { _oldCalendarViewPix = q->grab(QRect(_borderWidth, _borderWidth + 45, q->width() - 2 * _borderWidth, q->height() - 2 * _borderWidth - 45)); _calendarModel->setDisplayMode(ElaCalendarType::MonthMode); _calendarTitleView->setVisible(false); QApplication::processEvents(); _calendarView->setSpacing(15); _scrollToDate(_pSelectedDate.isValid() ? _pSelectedDate : QDate::currentDate()); _newCalendarViewPix = q->grab(QRect(_borderWidth, _borderWidth + 45, q->width() - 2 * _borderWidth, q->height() - 2 * _borderWidth - 45)); _doSwitchAnimation(false); } else if (displayMode == ElaCalendarType::MonthMode) { _oldCalendarViewPix = q->grab(QRect(_borderWidth, _borderWidth + 45, q->width() - 2 * _borderWidth, q->height() - 2 * _borderWidth - 45)); _calendarModel->setDisplayMode(ElaCalendarType::YearMode); _scrollToDate(_pSelectedDate.isValid() ? _pSelectedDate : QDate::currentDate()); _newCalendarViewPix = q->grab(QRect(_borderWidth, _borderWidth + 45, q->width() - 2 * _borderWidth, q->height() - 2 * _borderWidth - 45)); _doSwitchAnimation(false); } } void ElaCalendarPrivate::onCalendarViewClicked(const QModelIndex &index) { Q_Q(ElaCalendar); if (!_isSwitchAnimationFinished) { return; } switch (_calendarModel->getDisplayMode()) { case YearMode: { _oldCalendarViewPix = q->grab(QRect(_borderWidth, _borderWidth + 45, q->width() - 2 * _borderWidth, q->height() - 2 * _borderWidth - 45)); _lastSelectedYear = _calendarModel->getMinimumDate().year() + index.row(); _calendarModel->setDisplayMode(ElaCalendarType::MonthMode); _scrollToDate(QDate(_lastSelectedYear, _lastSelectedMonth, 15)); _newCalendarViewPix = q->grab(QRect(_borderWidth, _borderWidth + 45, q->width() - 2 * _borderWidth, q->height() - 2 * _borderWidth - 45)); _doSwitchAnimation(true); break; } case MonthMode: { _oldCalendarViewPix = q->grab(QRect(_borderWidth, _borderWidth + 45, q->width() - 2 * _borderWidth, q->height() - 2 * _borderWidth - 45)); _lastSelectedMonth = index.row() % 12 + 1; _calendarModel->setDisplayMode(ElaCalendarType::DayMode); _calendarTitleView->setVisible(true); _calendarView->setSpacing(0); _scrollToDate(QDate(_lastSelectedYear, _lastSelectedMonth, 15)); _calendarView->selectionModel()->setCurrentIndex(_calendarModel->getIndexFromDate(_pSelectedDate), QItemSelectionModel::Select); _newCalendarViewPix = q->grab(QRect(_borderWidth, _borderWidth + 45, q->width() - 2 * _borderWidth, q->height() - 2 * _borderWidth - 45)); _calendarTitleView->setVisible(false); _doSwitchAnimation(true); break; } case DayMode: { QDate date = _calendarModel->getDateFromIndex(index); if (date.isValid()) { _calendarView->clearSelection(); q->setSelectedDate(date); } Q_EMIT q->clicked(_pSelectedDate); break; } } } void ElaCalendarPrivate::onUpButtonClicked() { QScrollBar *vscrollBar = _calendarView->verticalScrollBar(); QPropertyAnimation *scrollAnimation = new QPropertyAnimation(vscrollBar, "value"); scrollAnimation->setEasingCurve(QEasingCurve::OutSine); scrollAnimation->setDuration(300); scrollAnimation->setStartValue(vscrollBar->value()); scrollAnimation->setEndValue(vscrollBar->value() - 150); scrollAnimation->start(QAbstractAnimation::DeleteWhenStopped); } void ElaCalendarPrivate::onDownButtonClicked() { QScrollBar *vscrollBar = _calendarView->verticalScrollBar(); QPropertyAnimation *scrollAnimation = new QPropertyAnimation(vscrollBar, "value"); scrollAnimation->setEasingCurve(QEasingCurve::OutSine); scrollAnimation->setDuration(300); scrollAnimation->setStartValue(vscrollBar->value()); scrollAnimation->setEndValue(vscrollBar->value() + 150); scrollAnimation->start(QAbstractAnimation::DeleteWhenStopped); } void ElaCalendarPrivate::_scrollToDate(QDate date) { int index = _calendarModel->getIndexFromDate(date).row(); switch (_calendarModel->getDisplayMode()) { case YearMode: case MonthMode: { _calendarView->scrollTo(_calendarModel->index(index - 4), QAbstractItemView::PositionAtTop); break; } case DayMode: { _calendarView->scrollTo(_calendarModel->index(index - 14), QAbstractItemView::PositionAtTop); break; } } } void ElaCalendarPrivate::_doSwitchAnimation(bool isZoomIn) { Q_Q(ElaCalendar); if (!_isSwitchAnimationFinished) { return; } _isDrawNewPix = false; _isSwitchAnimationFinished = false; _calendarDelegate->setIsTransparent(true); QPropertyAnimation *oldPixZoomAnimation = new QPropertyAnimation(this, "pZoomRatio"); connect(oldPixZoomAnimation, &QPropertyAnimation::valueChanged, this, [=]() { q->update(); }); connect(oldPixZoomAnimation, &QPropertyAnimation::finished, this, [=]() { _isDrawNewPix = true; QPropertyAnimation *newPixZoomAnimation = new QPropertyAnimation(this, "pZoomRatio"); connect(newPixZoomAnimation, &QPropertyAnimation::valueChanged, this, [=]() { q->update(); }); connect(newPixZoomAnimation, &QPropertyAnimation::finished, this, [=]() { if (_calendarModel->getDisplayMode() == ElaCalendarType::DayMode) { _calendarTitleView->setVisible(true); } _isSwitchAnimationFinished = true; _calendarDelegate->setIsTransparent(false); }); if (isZoomIn) { // 放大 年-月-日 newPixZoomAnimation->setStartValue(0.85); newPixZoomAnimation->setEndValue(1); } else { newPixZoomAnimation->setStartValue(1.5); newPixZoomAnimation->setEndValue(1); } newPixZoomAnimation->setDuration(300); newPixZoomAnimation->setEasingCurve(QEasingCurve::OutCubic); newPixZoomAnimation->start(QAbstractAnimation::DeleteWhenStopped); }); if (isZoomIn) { // 放大 年-月-日 oldPixZoomAnimation->setStartValue(1); oldPixZoomAnimation->setEndValue(1.15); } else { // 缩小 日-月-年 oldPixZoomAnimation->setStartValue(1); oldPixZoomAnimation->setEndValue(0.85); } oldPixZoomAnimation->setDuration(150); oldPixZoomAnimation->start(QAbstractAnimation::DeleteWhenStopped); QPropertyAnimation *oldPixOpacityAnimation = new QPropertyAnimation(this, "pPixOpacity"); connect(oldPixZoomAnimation, &QPropertyAnimation::finished, this, [=]() { QPropertyAnimation *newPixOpacityAnimation = new QPropertyAnimation(this, "pPixOpacity"); newPixOpacityAnimation->setStartValue(0); newPixOpacityAnimation->setEndValue(1); newPixOpacityAnimation->setDuration(300); newPixOpacityAnimation->start(QAbstractAnimation::DeleteWhenStopped); }); oldPixOpacityAnimation->setStartValue(1); oldPixOpacityAnimation->setEndValue(0); oldPixOpacityAnimation->setDuration(150); oldPixOpacityAnimation->start(QAbstractAnimation::DeleteWhenStopped); } void ElaCalendarPrivate::_updateSwitchButtonText() { QModelIndex modelIndex = _calendarView->indexAt(QPoint(_calendarView->rect().center().x() - 20, _calendarView->rect().center().y())); if (!modelIndex.isValid()) { return; } ElaCalendarData data = _calendarModel->data(modelIndex, Qt::UserRole).value(); switch (_calendarModel->getDisplayMode()) { case YearMode: { _modeSwitchButton->setText(QString("%1-%2").arg(data.year - 5).arg(data.year + 10)); break; } case MonthMode: { _modeSwitchButton->setText(QString("%1年").arg(data.year)); break; } case DayMode: { _modeSwitchButton->setText(QString("%1年%2月").arg(data.year).arg(data.month)); break; } } }