logplus/Workflow/WFWidget/src/PaiDialog.cpp

422 lines
11 KiB
C++
Raw Normal View History

2026-01-16 17:18:41 +08:00
/**
* @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;
}