#include "calendarex.h" #include #include #include #include #include #include #include #include "scopeselectionmodel.h" #include "PaintHelper/painthelper.h" CalendarInterface::CalendarInterface(QWidget *parent) : QWidget(parent) , IDropShadowable(this) , m_pLayout(new QHBoxLayout) { setWindowFlag(Qt::Popup); setWindowFlag(Qt::NoDropShadowWindowHint); //设置无边框属性 setWindowFlag(Qt::FramelessWindowHint); //设置背景透明属性 setAttribute(Qt::WA_TranslucentBackground, true); //关闭对话框时,删除自身对象 setAttribute(Qt::WA_DeleteOnClose, true); } CalendarInterface::~CalendarInterface() { //qDebug()<<"~ScopeCalendar"; } /** * @brief 这个只是坐标位移? * @param q */ void CalendarInterface::positionCalendarPopup(QWidget *q) { if (nullptr == m_pLayout) return; QPoint pos = (q->layoutDirection() == Qt::RightToLeft) ? q->rect().bottomRight() : q->rect().bottomLeft(); QPoint pos2 = (q->layoutDirection() == Qt::RightToLeft) ? q->rect().topRight() : q->rect().topLeft(); pos = q->mapToGlobal(pos); pos2 = q->mapToGlobal(pos2); QSize size = QSize(CALENDAR_WIDTH * m_pLayout->count() + 2 * SHADOW_RADIUS, CALENDAR_HEIGHT + 2 * SHADOW_RADIUS); //QRect screen = QApplication::desktop()->availableGeometry(pos); QRect screen = QGuiApplication::screenAt(pos)->availableGeometry(); //handle popup falling "off screen" if (q->layoutDirection() == Qt::RightToLeft) { pos.setX(pos.x()-size.width()); pos2.setX(pos2.x()-size.width()); if (pos.x() < screen.left()) pos.setX(qMax(pos.x(), screen.left())); else if (pos.x()+size.width() > screen.right()) pos.setX(qMax(pos.x()-size.width(), screen.right()-size.width())); } else { if (pos.x()+size.width() > screen.right()) pos.setX(screen.right()-size.width()); pos.setX(qMax(pos.x(), screen.left())); } if (pos.y() + size.height() > screen.bottom()) pos.setY(pos2.y() - size.height()); else if (pos.y() < screen.top()) pos.setY(screen.top()); if (pos.y() < screen.top()) pos.setY(screen.top()); if (pos.y()+size.height() > screen.bottom()) pos.setY(screen.bottom()-size.height()); pos.setX(pos.rx() - SHADOW_RADIUS); pos.setY(pos.ry() - SHADOW_RADIUS + SPACING); move(pos); } CalendarEx::CalendarEx(const QDate& defaultDate, QWidget* parent) : CalendarInterface(parent), m_pCalendar(nullptr) { QHBoxLayout* pLay = new QHBoxLayout(this); QWidget* pMain = new QWidget(this); pMain->setLayout(m_pLayout); pLay->addWidget(pMain); pLay->setMargin(SHADOW_RADIUS); m_pCalendar = new CalendarWidgetEx(this); m_pCalendar->setStyleSheet("QCalendarView{background-color: transparent;}"); m_pLayout->addWidget(m_pCalendar); connect(m_pCalendar, &CalendarWidgetEx::clicked, this, [this](const QDate& date){ emit sig_DateChanged(date); close(); }); m_pLayout->setMargin(0); pMain->resize(CALENDAR_WIDTH, CALENDAR_HEIGHT); SetCalendarSync(defaultDate); /* 设置大小,包含阴影的大小 */ resize(CALENDAR_WIDTH + 2 * SHADOW_RADIUS, CALENDAR_HEIGHT + 2 * SHADOW_RADIUS); /* 设置阴影 */ SetDropShadow(BoxShadow{0, 0, SHADOW_RADIUS, 0, QColor(0, 0, 0, 60), QSize(0, 0), QImage()}, pMain->size()); } void CalendarEx::SetCalendarSync(const QDate &defaultDate) { if (nullptr == m_pCalendar || !defaultDate.isValid()) return; m_pCalendar->setCurrentPage(defaultDate.year(), defaultDate.month()); m_pCalendar->setSelectedDate(defaultDate); } ScopedCalendar::ScopedCalendar(const QDate &from, const QDate &to, QWidget *parent) : CalendarInterface(parent), m_pCalendar_L(nullptr), m_pCalendar_R(nullptr) { QHBoxLayout* pLay = new QHBoxLayout(this); QWidget* pMain = new QWidget(this); pMain->setLayout(m_pLayout); pLay->addWidget(pMain); pLay->setMargin(SHADOW_RADIUS); ScopeSelectionModel *pDateScopeModel = new ScopeSelectionModel(); if(from.isValid() && to.isValid()) { pDateScopeModel->dtFirst = from; pDateScopeModel->dtSecond = to; pDateScopeModel->bLocked = true; } m_pCalendar_L = new CalendarWidgetEx(this); m_pCalendar_L->setStyleSheet("QCalendarView{background-color: transparent;}"); m_pCalendar_L->SetSelectMode(CalendarWidgetEx::Scope, pDateScopeModel); m_pCalendar_L->hideNavigatioinButton(false, false, true, true); m_pLayout->addWidget(m_pCalendar_L); m_pCalendar_R = new CalendarWidgetEx(this); m_pCalendar_R->setStyleSheet("QCalendarView{background-color: transparent;}"); m_pCalendar_R->SetSelectMode(CalendarWidgetEx::Scope, pDateScopeModel); m_pCalendar_R->hideNavigatioinButton(true, true, false, false); m_pLayout->addWidget(m_pCalendar_R); m_pLayout->setSpacing(0); m_pLayout->setMargin(0); pMain->resize(2 * CALENDAR_WIDTH, CALENDAR_HEIGHT); SetCalendarSync(from); connect(pDateScopeModel, &ScopeSelectionModel::sig_ScopeSelected, this, &ScopedCalendar::OnScopeSelected); resize(2 * CALENDAR_WIDTH + 2 * SHADOW_RADIUS, CALENDAR_HEIGHT + 2 * SHADOW_RADIUS); SetDropShadow(BoxShadow{0, 0, SHADOW_RADIUS, 0, QColor(0, 0, 0, 60), QSize(0, 0), QImage()}, pMain->size()); } void ScopedCalendar::SetMinimumDate(const QDate &date) { if (nullptr == m_pCalendar_L || nullptr == m_pCalendar_R) return; m_pCalendar_L->setMinimumDate(date); m_pCalendar_R->setMinimumDate(date); } void ScopedCalendar::SetMaximumDate(const QDate &date) { if (nullptr == m_pCalendar_L || nullptr == m_pCalendar_R) return; m_pCalendar_L->setMaximumDate(date); m_pCalendar_R->setMaximumDate(date); } void ScopedCalendar::OnScopeSelected(const QDate &from, const QDate &to) { emit sig_ScopeSelected(from, to); close(); } void ScopedCalendar::SetCalendarSync(const QDate &defaultDate) { if (nullptr == m_pCalendar_L || nullptr == m_pCalendar_R || !defaultDate.isValid()) return; m_pCalendar_L->setCurrentPage(defaultDate.year(), defaultDate.month()); connect(m_pCalendar_L, &QCalendarWidget::currentPageChanged, this, [&](int year, int month) { QDate nextMonth = QDate(year, month, 1).addMonths(1); m_pCalendar_R->setCurrentPage(nextMonth.year(), nextMonth.month()); }); m_pCalendar_R->setCurrentPage(defaultDate.addMonths(1).year(), defaultDate.addMonths(1).month()); connect(m_pCalendar_R, &QCalendarWidget::currentPageChanged, this, [&](int year, int month) { QDate prevMonth = QDate(year, month, 1).addMonths(-1); m_pCalendar_L->setCurrentPage(prevMonth.year(), prevMonth.month()); }); }