/** * @file PaiDialog.cpp * @date 2011-10-17 */ #include #include #include #include #include "PaiDialog.h" #include "PaiWidget.h" #include "Configure.h" using namespace pai::gui; const int WIDGET_MARGIN = 5; bool PaiDialog::m_InitWinChangeSizeMode = false; int PaiDialog::m_WinChangeSizeMode = 0;//默认采用鼠标改变窗体大小时,窗体实时改变显示,可在配置文件pai.conf修改 PaiDialog::PaiDialog(QWidget *pParent, Qt::WindowFlags flag) : QDialog(pParent, flag), m_ResizeDirction(ResizeDirction_None), m_IsPress(false), m_moved(false), m_TimerID(-1), m_ConstSize(false) { setMouseTracking(true); setWindowFlags(windowFlags() | Qt::FramelessWindowHint); m_pRubberBand = new QRubberBand(QRubberBand::Rectangle); m_pTitleBar = new pai::gui::PaiTitleBar(this); m_pTitleBar->SetTitleBarFlags(PaiTitleBar::CloseButtonHint); m_pContainer = new PaiWidget(this); m_pContainer->setObjectName("DialogMainWidget"); m_pContainer->setStyleSheet("QWidget#DialogMainWidget{background-color: #E4EEFA}"); if(!PaiDialog::m_InitWinChangeSizeMode) { PaiDialog::m_InitWinChangeSizeMode = true; // 设置鼠标改变窗体大小显示方式 pai::conf::CConfigure conf; QString winChangeSizeMode = QString::fromStdString(conf.GetValueByKey("WINDOW_CHANGESIZE_MODE")); if(!winChangeSizeMode.isEmpty()) { bool bOK; int mode = winChangeSizeMode.toInt(&bOK, 10); if(bOK) { PaiDialog::SetWindowChangeSizeMode(mode); } } } QVBoxLayout *pContainerLayout = new QVBoxLayout; pContainerLayout->setContentsMargins(WIDGET_MARGIN, 0, WIDGET_MARGIN, WIDGET_MARGIN); pContainerLayout->setSpacing(0); pContainerLayout->addWidget(m_pContainer); QVBoxLayout *pMainLayout = new QVBoxLayout(this); pMainLayout->setContentsMargins(1, 1, 1, 1); pMainLayout->setSpacing(0); pMainLayout->addWidget(m_pTitleBar); pMainLayout->addLayout(pContainerLayout); pMainLayout->setSizeConstraint(QLayout::SetDefaultConstraint); connect(m_pTitleBar, SIGNAL(HandleExitButton()), this, SIGNAL(CloseButtonClicked())); connect(m_pTitleBar, SIGNAL(HandleExitButton()), this, SLOT(close())); connect(m_pTitleBar, SIGNAL(HandleMinimumButton()), this, SLOT(showMinimized())); } PaiDialog::~PaiDialog() { if(m_pRubberBand) { delete m_pRubberBand; m_pRubberBand = NULL; } } void PaiDialog::setGeometry(int x, int y, int w, int h) { setGeometry(QRect(x, y, w, h)); } void PaiDialog::setGeometry(const QRect & rect) { QDialog::setGeometry(rect); QDesktopWidget *pDesktop = QApplication::desktop(); if(pDesktop) { QRect screenRect = pDesktop->availableGeometry(); if(screenRect.isValid() && screenRect.contains(QRect(rect))) { m_pTitleBar->ChangeRestoreButtonState(false); } } } void PaiDialog::mousePressEvent(QMouseEvent *pEvent) { QDialog::mousePressEvent(pEvent); // 鼠标在边界,要触发resize事件 m_IsPress = true; } void PaiDialog::mouseReleaseEvent(QMouseEvent *pEvent) { QDialog::mouseReleaseEvent(pEvent); m_pRubberBand->hide(); m_IsPress = false; if(m_moved && (pEvent->button() == Qt::LeftButton) && (m_ResizeDirction != ResizeDirction_None)) { m_moved = false; setGeometry(m_pRubberBand->geometry()); pEvent->accept(); } m_ResizeDirction = ResizeDirction_None; setCursor(Qt::ArrowCursor); } void PaiDialog::mouseMoveEvent(QMouseEvent *pEvent) { QDialog::mouseMoveEvent(pEvent); if(!m_ConstSize) { if(!m_IsPress) { SetCursorShape(pEvent->pos()); } if(pEvent->buttons() & Qt::LeftButton) { // resize事件 if(m_ResizeDirction != ResizeDirction_None) { m_moved = true; if(!m_pRubberBand->isVisible()) { m_pRubberBand->setGeometry(frameGeometry()); m_pRubberBand->show(); } ResizeFrame(pEvent->globalPos()); if(PaiDialog::m_WinChangeSizeMode != 0) { setGeometry(m_pRubberBand->geometry()); } pEvent->accept(); } } } } void PaiDialog::timerEvent(QTimerEvent *) { if(!m_IsPress) { SetCursorShape(mapFromGlobal(QCursor::pos())); } } void PaiDialog::SetCursorShape(const QPoint & mousePos) { QRect qRect = rect(); // 左上 if((qAbs(mousePos.x() - qRect.left()) <= 5) && (qAbs(mousePos.y() - qRect.top()) <= 5)) { setCursor(Qt::SizeFDiagCursor); m_ResizeDirction = ResizeDirction_TopLeft; } //左下 else if((qAbs(mousePos.x() - qRect.left()) <= 5) && (qAbs(mousePos.y() - qRect.bottom()) <= 5)) { setCursor(Qt::SizeBDiagCursor); m_ResizeDirction = ResizeDirction_BottomLeft; } //右上 else if((qAbs(mousePos.x() - qRect.right()) <= 5) && (qAbs(mousePos.y() - qRect.top()) <= 5)) { setCursor(Qt::SizeBDiagCursor); m_ResizeDirction = ResizeDirction_TopRight; } //右下 else if((qAbs(mousePos.x() - qRect.right()) <= 5) && (qAbs(mousePos.y() - qRect.bottom()) <= 5)) { setCursor(Qt::SizeFDiagCursor); m_ResizeDirction = ResizeDirction_BottomRight; } //左 else if((qAbs(mousePos.x() - qRect.left()) <= 5) && !(mousePos.y() - qRect.top() < 2 || qRect.bottom() - mousePos.y() < 2)) { setCursor(Qt::SizeHorCursor); m_ResizeDirction = ResizeDirction_Left; } //右 else if((qAbs(mousePos.x() - qRect.right()) <= 5) && !(mousePos.y() - qRect.top() < 2 || qRect.bottom() - mousePos.y() < 2)) { setCursor(Qt::SizeHorCursor); m_ResizeDirction = ResizeDirction_Right; } //上 else if((qAbs(mousePos.y() - qRect.top()) <= 5) && !(mousePos.x() - qRect.left() < 2 || qRect.right() - mousePos.x() < 2)) { setCursor(Qt::SizeVerCursor); m_ResizeDirction = ResizeDirction_Top; } //下 else if((qAbs(mousePos.y() - qRect.bottom()) <= 5) && !(mousePos.x() - qRect.left() < 2 || qRect.right() - mousePos.x() < 2)) { setCursor(Qt::SizeVerCursor); m_ResizeDirction = ResizeDirction_Bottom; } else { if(!m_IsPress) { setCursor(Qt::ArrowCursor); m_ResizeDirction = ResizeDirction_None; if(m_TimerID != -1) { killTimer(m_TimerID); m_TimerID = -1; } } } if(m_ResizeDirction != ResizeDirction_None) { if(m_TimerID == -1) { m_TimerID = startTimer(100); } } } void PaiDialog::ResizeFrame(const QPoint & mousePos) { QRect origRect = m_pRubberBand->frameGeometry(); int left = origRect.left(); int top = origRect.top(); int right = origRect.right(); int bottom = origRect.bottom(); origRect.getCoords(&left, &top, &right, &bottom); int minWidth = minimumWidth(); int minHeight = minimumHeight(); switch(m_ResizeDirction) { case ResizeDirction_Top: { top = mousePos.y(); } break; case ResizeDirction_Bottom: { bottom = mousePos.y(); } break; case ResizeDirction_Left: { left = mousePos.x(); } break; case ResizeDirction_Right: { right = mousePos.x(); } break; case ResizeDirction_TopLeft: { top = mousePos.y(); left = mousePos.x(); } break; case ResizeDirction_TopRight: { top = mousePos.y(); right = mousePos.x(); } break; case ResizeDirction_BottomLeft: { bottom = mousePos.y(); left = mousePos.x(); } break; case ResizeDirction_BottomRight: { bottom = mousePos.y(); right = mousePos.x(); } break; case ResizeDirction_None: default: break; } QRect newRect(QPoint(left, top), QPoint(right, bottom)); if(newRect.isValid()) { if(minWidth > newRect.width()) { if(left != origRect.left()) { newRect.setLeft(origRect.left()); } else { newRect.setRight(origRect.right()); } } if(minHeight > newRect.height()) { if(top != origRect.top()) { newRect.setTop(origRect.top()); } else { newRect.setBottom(origRect.bottom()); } } m_pRubberBand->setGeometry(newRect); } } QWidget* PaiDialog::GetContainer() { return m_pContainer; } void PaiDialog::setWindowTitle(const QString & windowTitle) { m_pTitleBar->SetTitle(windowTitle); } void PaiDialog::SetTitleBarFlags(PaiTitleBar::TitleBarFlags flags) { m_pTitleBar->SetTitleBarFlags(flags); if(flags & PaiTitleBar::MinimumButtonHint) { // add minimize button and close button, the default only contains close button. // window flag is needed, because the dialog flag will not accept the minimize flag. setWindowFlags(Qt::FramelessWindowHint | Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowMinimizeButtonHint); } } PaiTitleBar::TitleBarFlags PaiDialog::GetTitleBarFlags() const { return m_pTitleBar->GetTitleBarFlags(); } void PaiDialog::setLayout(QLayout *pLayout) { m_pContainer->setLayout(pLayout); } QLayout* PaiDialog::layout() const { return m_pContainer->layout(); } void PaiDialog::paintEvent(QPaintEvent *pEvent) { QDialog::paintEvent(pEvent); QPainter painter(this); painter.fillRect(rect(), QBrush(QColor("#C9DDEB"))); painter.setPen(QColor("#829BB5")); painter.drawRect(rect().adjusted(0, 0, -1, -1)); } void PaiDialog::InsertTitleBarWidget(QWidget *pWidget, Qt::Alignment alignment) { m_pTitleBar->InsertWidget(pWidget, alignment); } void PaiDialog::SetConstraintSize(bool constraint) { m_ConstSize = constraint; } void PaiDialog::show() { if(parentWidget() && (windowFlags() & Qt::WindowMinimizeButtonHint)) { QPoint centerPoint = parentWidget()->mapToGlobal(parentWidget()->geometry().center()); int x = centerPoint.x() - (sizeHint().width() / 2); int y = centerPoint.y() - (sizeHint().height() / 2) - 100; // 抬高100px move((x < 0) ? 0 : x, (y < 0) ? 0 : y); } QDialog::show(); } int PaiDialog::exec() { if(parentWidget() && (windowFlags() & Qt::WindowMinimizeButtonHint)) { QPoint centerPoint = parentWidget()->geometry().center(); int x = centerPoint.x() - (size().width() / 2); int y = centerPoint.y() - (size().height() / 2) - 60; // 抬高60px move((x < 0) ? 0 : x, (y < 0) ? 0 : y); } return QDialog::exec(); } void PaiDialog::SetWindowChangeSizeMode(int mode) { PaiDialog::m_WinChangeSizeMode = mode; }