422 lines
11 KiB
C++
422 lines
11 KiB
C++
/**
|
||
* @file PaiDialog.cpp
|
||
* @date 2011-10-17
|
||
*/
|
||
#include <QMouseEvent>
|
||
#include <QPainter>
|
||
#include <QDesktopWidget>
|
||
#include <QApplication>
|
||
|
||
#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;
|
||
}
|