436 lines
11 KiB
C++
436 lines
11 KiB
C++
/**
|
||
* @file PaiWindow.cpp
|
||
* @date 2012-12-13
|
||
*/
|
||
#include <QMouseEvent>
|
||
#include <QDesktopWidget>
|
||
#include <QApplication>
|
||
#include <QPainter>
|
||
|
||
#include "PaiWindow.h"
|
||
#include "PaiWidget.h"
|
||
#include "PaiWorkspace.h"
|
||
#include "Configure.h"
|
||
#include "GlobalUtility.h"
|
||
|
||
using namespace pai::gui;
|
||
|
||
const int WIDGET_MARGIN = 5;
|
||
|
||
bool PaiWindow::m_IsInitWinChangeSizeMode = false;
|
||
int PaiWindow::m_WinChangeSizeMode = 0; // 默认采用鼠标改变窗体大小时,窗体实时改变显示,可在配置文件pai.conf修改
|
||
|
||
PaiWindow::PaiWindow(QWidget *pParent) :
|
||
QFrame(pParent),
|
||
m_ResizeDirction(ResizeDirction_None),
|
||
m_IsPress(false),
|
||
m_IsMoved(false),
|
||
m_TimerID(-1)
|
||
{
|
||
setMouseTracking(true);
|
||
setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::Window);
|
||
setFrameShape(QFrame::Panel);
|
||
setFrameShadow(QFrame::Plain);
|
||
setObjectName("PaiWindow");
|
||
setStyleSheet("QWidget#PaiWindow{background-color: #E4EEFA}");
|
||
|
||
m_pRubberBand = new QRubberBand(QRubberBand::Rectangle);
|
||
|
||
m_pSystemMenu = new QMenu(this);
|
||
m_pSettingMenu = new QMenu(this);
|
||
|
||
m_pTitleBar = new pai::gui::PaiTitleBar(this);
|
||
m_pContainerWidget = new PaiWidget(this);
|
||
m_pStatusBar = new pai::gui::PaiStatusBar(this);
|
||
m_pStatusBar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||
|
||
if(!PaiWindow::m_IsInitWinChangeSizeMode)
|
||
{
|
||
PaiWindow::m_IsInitWinChangeSizeMode = 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)
|
||
{
|
||
PaiWindow::SetWindowChangeSizeMode(mode);
|
||
}
|
||
}
|
||
}
|
||
|
||
QVBoxLayout *pContainerLayout = new QVBoxLayout;
|
||
pContainerLayout->setContentsMargins(WIDGET_MARGIN, 0, WIDGET_MARGIN, 0);
|
||
pContainerLayout->setSpacing(0);
|
||
pContainerLayout->addWidget(m_pContainerWidget);
|
||
|
||
QVBoxLayout *pMainLayout = new QVBoxLayout(this);
|
||
pMainLayout->setContentsMargins(1, 1, 1, 1);
|
||
pMainLayout->setSpacing(0);
|
||
pMainLayout->addWidget(m_pTitleBar);
|
||
pMainLayout->addLayout(pContainerLayout);
|
||
pMainLayout->addWidget(m_pStatusBar);
|
||
pMainLayout->setSizeConstraint(QLayout::SetDefaultConstraint);
|
||
|
||
connect(m_pTitleBar, SIGNAL(HandleExitButton()), this, SLOT(close()));
|
||
connect(m_pTitleBar, SIGNAL(HandleMinimumButton()), this, SLOT(showMinimized()));
|
||
}
|
||
|
||
PaiWindow::~PaiWindow()
|
||
{
|
||
if (m_pRubberBand)
|
||
{
|
||
delete m_pRubberBand;
|
||
m_pRubberBand = NULL;
|
||
}
|
||
}
|
||
|
||
void PaiWindow::mousePressEvent(QMouseEvent *pEvent)
|
||
{
|
||
QFrame::mousePressEvent(pEvent);
|
||
// 鼠标在边界,要触发resize事件
|
||
m_IsPress = true;
|
||
if((pEvent->button() == Qt::LeftButton) && (m_ResizeDirction != ResizeDirction_None))
|
||
{
|
||
m_pRubberBand->setGeometry(frameGeometry());
|
||
m_pRubberBand->show();
|
||
pEvent->accept();
|
||
}
|
||
}
|
||
|
||
void PaiWindow::mouseReleaseEvent(QMouseEvent *pEvent)
|
||
{
|
||
QFrame::mouseReleaseEvent(pEvent);
|
||
m_pRubberBand->hide();
|
||
m_IsPress = false;
|
||
if(m_IsMoved && (pEvent->button() == Qt::LeftButton) && (m_ResizeDirction != ResizeDirction_None))
|
||
{
|
||
m_IsMoved = false;
|
||
setGeometry(m_pRubberBand->geometry());
|
||
pEvent->accept();
|
||
}
|
||
m_ResizeDirction = ResizeDirction_None;
|
||
setCursor(Qt::ArrowCursor);
|
||
}
|
||
|
||
void PaiWindow::mouseMoveEvent(QMouseEvent *pEvent)
|
||
{
|
||
QFrame::mouseMoveEvent(pEvent);
|
||
if(!m_IsPress)
|
||
{
|
||
setCursorShape(pEvent->pos());
|
||
}
|
||
if(pEvent->buttons() & Qt::LeftButton)
|
||
{
|
||
// resize事件
|
||
if(m_ResizeDirction != ResizeDirction_None)
|
||
{
|
||
m_IsMoved = true;
|
||
resizeFrame(pEvent->globalPos());
|
||
if(PaiWindow::m_WinChangeSizeMode != 0)
|
||
{
|
||
setGeometry(m_pRubberBand->geometry());
|
||
}
|
||
pEvent->accept();
|
||
}
|
||
}
|
||
}
|
||
|
||
void PaiWindow::timerEvent(QTimerEvent *)
|
||
{
|
||
if(!m_IsPress)
|
||
{
|
||
setCursorShape(mapFromGlobal(QCursor::pos()));
|
||
}
|
||
}
|
||
|
||
void PaiWindow::paintEvent(QPaintEvent *pEvent)
|
||
{
|
||
QFrame::paintEvent(pEvent);
|
||
|
||
QPainter painter(this);
|
||
|
||
painter.fillRect(rect(), QBrush(QColor("#C9DDEB")));
|
||
|
||
painter.setPen(QColor("#829BB5"));
|
||
painter.drawRect(rect().adjusted(0, 0, -1, -1));
|
||
}
|
||
|
||
void PaiWindow::closeEvent(QCloseEvent *pEvent)
|
||
{
|
||
PaiWorkspace *pWorkspace = findChild< PaiWorkspace* > ();
|
||
if(pWorkspace && (!IsCloseable(pWorkspace)))
|
||
{
|
||
pEvent->ignore();
|
||
return;
|
||
}
|
||
QWidget::closeEvent(pEvent);
|
||
}
|
||
|
||
void PaiWindow::setCursorShape(const QPoint & mousePos)
|
||
{
|
||
QRect r = rect();
|
||
bool isMaximizedState = isMaximized();
|
||
// 左上
|
||
if((qAbs(mousePos.x() - r.left()) <= 15) && (qAbs(mousePos.y() - r.top()) <= 30) && (!isMaximizedState))
|
||
{
|
||
setCursor(Qt::SizeFDiagCursor);
|
||
m_ResizeDirction = ResizeDirction_TopLeft;
|
||
}
|
||
// 左下
|
||
else if((qAbs(mousePos.x() - r.left()) <= 15) && (qAbs(mousePos.y() - r.bottom()) <= 30) && (!isMaximizedState))
|
||
{
|
||
setCursor(Qt::SizeBDiagCursor);
|
||
m_ResizeDirction = ResizeDirction_BottomLeft;
|
||
}
|
||
// 右上
|
||
else if((qAbs(mousePos.x() - r.right()) <= 15) && (qAbs(mousePos.y() - r.top()) <= 30) && (!isMaximizedState))
|
||
{
|
||
setCursor(Qt::SizeBDiagCursor);
|
||
m_ResizeDirction = ResizeDirction_TopRight;
|
||
}
|
||
// 右下
|
||
else if((qAbs(mousePos.x() - r.right()) <= 15) && (qAbs(mousePos.y() - r.bottom()) <= 30) && (!isMaximizedState))
|
||
{
|
||
setCursor(Qt::SizeFDiagCursor);
|
||
m_ResizeDirction = ResizeDirction_BottomRight;
|
||
}
|
||
// 左
|
||
else if((qAbs(mousePos.x() - r.left()) <= 5) && (!isMaximizedState))
|
||
{
|
||
setCursor(Qt::SizeHorCursor);
|
||
m_ResizeDirction = ResizeDirction_Left;
|
||
}
|
||
// 右
|
||
else if((qAbs(mousePos.x() - r.right()) <= 5) && (!isMaximizedState))
|
||
{
|
||
setCursor(Qt::SizeHorCursor);
|
||
m_ResizeDirction = ResizeDirction_Right;
|
||
}
|
||
// 上
|
||
else if((qAbs(mousePos.y() - r.top()) <= 5) && (!isMaximizedState))
|
||
{
|
||
setCursor(Qt::SizeVerCursor);
|
||
m_ResizeDirction = ResizeDirction_Top;
|
||
}
|
||
// 下
|
||
else if((qAbs(mousePos.y() - r.bottom()) <= 5) && (!isMaximizedState))
|
||
{
|
||
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) && (m_TimerID == -1))
|
||
{
|
||
m_TimerID = startTimer(100);
|
||
}
|
||
}
|
||
|
||
void PaiWindow::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);
|
||
}
|
||
}
|
||
|
||
void PaiWindow::setWindowTitle(const QString & titleBarName)
|
||
{
|
||
m_pTitleBar->SetTitle(titleBarName);
|
||
}
|
||
|
||
void PaiWindow::SetTitleBarFlags(PaiTitleBar::TitleBarFlags flags)
|
||
{
|
||
m_pTitleBar->SetTitleBarFlags(flags);
|
||
}
|
||
|
||
void PaiWindow::SetStatusBarVisible(bool visible)
|
||
{
|
||
if(visible)
|
||
{
|
||
QFrame::layout()->setContentsMargins(1, 1, 1, 1);
|
||
}
|
||
else
|
||
{
|
||
QFrame::layout()->setContentsMargins(1, 1, 1, WIDGET_MARGIN);
|
||
}
|
||
m_pStatusBar->setVisible(visible);
|
||
}
|
||
|
||
void PaiWindow::SetTitleBarVisible(bool visible)
|
||
{
|
||
m_pTitleBar->setVisible(visible);
|
||
}
|
||
|
||
void PaiWindow::setLayout(QLayout *pLayout)
|
||
{
|
||
m_pContainerWidget->setLayout(pLayout);
|
||
}
|
||
|
||
QLayout* PaiWindow::layout() const
|
||
{
|
||
return m_pContainerWidget->layout();
|
||
}
|
||
|
||
QStatusBar* PaiWindow::statusBar()
|
||
{
|
||
return m_pStatusBar;
|
||
}
|
||
|
||
QMenu* PaiWindow::systemMenu()
|
||
{
|
||
return m_pSystemMenu;
|
||
}
|
||
|
||
QMenu* PaiWindow::settingMenu()
|
||
{
|
||
return m_pSettingMenu;
|
||
}
|
||
|
||
void PaiWindow::setGeometry(int x, int y, int w, int h)
|
||
{
|
||
setGeometry(QRect(x, y, w, h));
|
||
}
|
||
|
||
void PaiWindow::setGeometry(const QRect & rect)
|
||
{
|
||
QFrame::setGeometry(rect);
|
||
QDesktopWidget *pDesktop = QApplication::desktop();
|
||
if(pDesktop)
|
||
{
|
||
QRect screenRect = pDesktop->availableGeometry();
|
||
if(screenRect.isValid() && screenRect.contains(QRect(rect)))
|
||
{
|
||
m_pTitleBar->ChangeRestoreButtonState(false);
|
||
}
|
||
}
|
||
}
|
||
|
||
void PaiWindow::setWindowState(Qt::WindowStates state)
|
||
{
|
||
QFrame::setWindowState(state);
|
||
if (windowState() & Qt::WindowMaximized)
|
||
{
|
||
m_pTitleBar->ChangeRestoreButtonState(true);
|
||
}
|
||
else
|
||
{
|
||
m_pTitleBar->ChangeRestoreButtonState(false);
|
||
}
|
||
}
|
||
|
||
QWidget* PaiWindow::GetContainer()
|
||
{
|
||
return m_pContainerWidget;
|
||
}
|
||
|
||
void PaiWindow::updateMenu()
|
||
{
|
||
m_pTitleBar->CreateSystemMenu(m_pSystemMenu);
|
||
}
|
||
|
||
void PaiWindow::InsertTitleBarWidget(QWidget *pWidget, Qt::Alignment alignment)
|
||
{
|
||
m_pTitleBar->InsertWidget(pWidget, alignment);
|
||
}
|
||
|
||
void PaiWindow::SetWindowChangeSizeMode(int mode)
|
||
{
|
||
PaiWindow::m_WinChangeSizeMode = mode;
|
||
}
|