logplus/Workflow/WFWidget/src/PaiTitleBar.cpp

387 lines
13 KiB
C++
Raw Normal View History

2026-01-16 17:18:41 +08:00
/**
* @file PaiTitleBar.cpp
* @date 2012-11-29
*/
#include <QMouseEvent>
#include <QHBoxLayout>
#include <QPainter>
#include <QMenu>
#include "PaiTitleBar.h"
#include "PaiToolButton.h"
using namespace pai::gui;
const int titleBarHeight = 30;
const int titleNameCenterStand = 1300; // titlename默认采用titlebar整个宽幅居中当titlebar宽幅小于此值时为显示美观及避免文字被遮挡采用titlebar空白居中
const int titleSpaceCenterStand = 300; // 当titlebar整个除去标题文字后的空白小于此值时为显示美观采用titlebar空白居中
PaiStatusBar::PaiStatusBar(QWidget *pParent) :
QStatusBar(pParent)
{
setObjectName("PaiStatusBar");
setSizeGripEnabled(false);
setStyleSheet("QStatusBar#PaiStatusBar{background-color: #E4EEFA}");
}
PaiStatusBar::~PaiStatusBar()
{
}
///////////////////////////////////////////////
PaiTitleBar::PaiTitleBar(QWidget *parent) :
QWidget(parent)
{
setMaximumHeight(titleBarHeight);
setMinimumHeight(titleBarHeight);
setContentsMargins(0, 0, 0, 0);
m_pMinimumButton = new PaiToolButton(this);
m_pMinimumButton->setObjectName("MinimumButton");
m_pMaximumButton = new PaiToolButton(this);
m_pMaximumButton->setObjectName("MaximumButton");
m_pExitButton = new PaiToolButton(this);
m_pExitButton->setObjectName("ExitButton");
m_pLogoButton = new PaiToolButton(this);
m_pLogoButton->setObjectName("LogoButton");
QSize size = QSize(titleBarHeight, titleBarHeight);
m_pMinimumButton->setFocusPolicy(Qt::NoFocus);
m_pMinimumButton->setMaximumSize(size);
m_pMinimumButton->setMinimumSize(size);
m_pMaximumButton->setFocusPolicy(Qt::NoFocus);
m_pMaximumButton->setMaximumSize(size);
m_pMaximumButton->setMinimumSize(size);
m_pExitButton->setFocusPolicy(Qt::NoFocus);
m_pExitButton->setMaximumSize(QSize(size.width() + 10, size.height()));
m_pExitButton->setMinimumSize(QSize(size.width() + 10, size.height()));
m_pLogoButton->setFocusPolicy(Qt::NoFocus);
m_pLogoButton->setMaximumSize(size);
m_pLogoButton->setMinimumSize(size);
m_pRightHLayout = new QHBoxLayout;
m_pRightHLayout->setContentsMargins(0, 0, 0, 0);
m_pRightHLayout->setSpacing(0);
m_pRightHLayout->setSizeConstraint(QLayout::SetDefaultConstraint);
m_pLeftHLayout = new QHBoxLayout;
m_pLeftHLayout->setContentsMargins(0, 0, 0, 0);
m_pLeftHLayout->setSpacing(0);
m_pLeftHLayout->setSizeConstraint(QLayout::SetDefaultConstraint);
QHBoxLayout *pMainHLayout = new QHBoxLayout(this);
pMainHLayout->setContentsMargins(0, 0, 0, 0);
pMainHLayout->setSpacing(0);
pMainHLayout->setSizeConstraint(QLayout::SetDefaultConstraint);
m_pLeftHLayout->addWidget(m_pLogoButton);
m_pRightHLayout->addWidget(m_pMinimumButton);
m_pRightHLayout->addWidget(m_pMaximumButton);
m_pRightHLayout->addWidget(m_pExitButton);
pMainHLayout->addLayout(m_pLeftHLayout);
pMainHLayout->addStretch(1);
pMainHLayout->addLayout(m_pRightHLayout);
setLayout(pMainHLayout);
connect(m_pExitButton, SIGNAL(clicked()), this, SIGNAL(HandleExitButton()));
connect(m_pMinimumButton, SIGNAL(clicked()), this, SIGNAL(HandleMinimumButton()));
connect(m_pMaximumButton, SIGNAL(clicked()), this, SIGNAL(HandleMaximumButton()));
connect(m_pMaximumButton, SIGNAL(clicked()), this, SLOT(ChangeRestoreButtonState()));
connect(m_pLogoButton, SIGNAL(pressed()), m_pLogoButton, SLOT(showMenu()));
setStyleSheet("QToolButton{background-color:qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 #F3F9FE,stop:1 #C9DDEB);"
" border:0px}"
"QToolButton::menu-indicator{image:None}"
"QToolButton#ExitButton{border-image:url(:/Close_a.png)}"
"QToolButton#ExitButton:hover{background-image:url(:/Close_hover.png);"
" border-style:none}"
"QToolButton#ExitButton:pressed{background-image:url(:/Close_click.png);"
" border-style:none}"
"QToolButton#MaximumButton{border-image:url(:/minimize_status.png)}"
"QToolButton#MaximumButton:hover{background-image:url(:/Minimize_hover.png);"
" border-style:none}"
"QToolButton#MaximumButton:pressed{background-image:url(:/Minimize_click.png);"
" border-style:none}"
"QToolButton#MinimumButton{border-image:url(:/Minimize.png)}"
"QToolButton#MinimumButton:hover{background-image:url(:/Minimize_hover.png);"
" border-style:none}"
"QToolButton#MinimumButton:pressed{background-image:url(:/Minimize_click.png);"
" border-style:none}"
"QToolButton#LogoButton{border-image:url(:/Logo_a.png)}");
// 默认仅显示最小化,最大化和关闭按钮
SetTitleBarFlags(CloseButtonHint | MaximumButtonHint | MinimumButtonHint);
}
PaiTitleBar::~PaiTitleBar()
{
}
void PaiTitleBar::resizeEvent(QResizeEvent *pEvent)
{
int nowSizeWidth = pEvent->size().width();
int basicStringWidth = 20;
int buttonWidth = 0;
QList< PaiToolButton * > lstToolButton;
if(m_titleBarFlags & PaiTitleBar::LogoButtonHint)
{
lstToolButton.append(m_pLogoButton);
}
if(m_titleBarFlags & PaiTitleBar::CloseButtonHint)
{
lstToolButton.append(m_pExitButton);
}
if(m_titleBarFlags & PaiTitleBar::MaximumButtonHint)
{
lstToolButton.append(m_pMaximumButton);
}
if(m_titleBarFlags & PaiTitleBar::MinimumButtonHint)
{
lstToolButton.append(m_pMinimumButton);
}
for(int i = 0; i < lstToolButton.size(); ++i)
{
lstToolButton[i]->hide();
}
for(int i = 0; i < lstToolButton.size(); ++i)
{
buttonWidth += lstToolButton[i]->size().width();
if(nowSizeWidth - buttonWidth > basicStringWidth)
{
lstToolButton[i]->show();
}
}
QWidget::resizeEvent(pEvent);
}
void PaiTitleBar::paintEvent(QPaintEvent *pEvent)
{
int iPixelTitile = fontMetrics().width(m_title);
QRect titleRect = GetTitleNameRect(iPixelTitile);
QString elidedTitle = fontMetrics().elidedText(m_title, Qt::ElideRight, titleRect.width());
QLinearGradient linearGradient(0, 0, 0, titleBarHeight);
linearGradient.setColorAt(0.0, QColor("#F3F9FE"));
linearGradient.setColorAt(1.0, QColor("#C9DDEB"));
QWidget::paintEvent(pEvent);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.fillRect(rect(), QBrush(linearGradient));
painter.setBrush(QBrush(Qt::black));
painter.drawText(titleRect, Qt::AlignCenter, elidedTitle);
}
QRect PaiTitleBar::GetTitleNameRect(int pixelTitle)
{
QRect titleRect;
int wdif = qAbs(m_pRightHLayout->geometry().width() - m_pLeftHLayout->geometry().width());
int iSpaceWidth = this->width() - m_pRightHLayout->geometry().width() - m_pLeftHLayout->geometry().width();
int iSpaceLeave = (titleSpaceCenterStand >= wdif) ? titleSpaceCenterStand : wdif;
if(iSpaceWidth - pixelTitle <= iSpaceLeave) // 如果空白区域少于指定值,采用空白居中
{
titleRect = QRect(m_pLeftHLayout->geometry().topRight(), m_pRightHLayout->geometry().bottomLeft());
}
else
{
float fScale = 0.5; // 渐变因子
int iPosx = titleNameCenterStand - wdif / fScale; // 由空白居中到标题栏居中渐变的起始宽度
if(this->width() <= iPosx) // 当标题栏宽度小于起始宽度时,直接采用空白居中
{
titleRect = QRect(m_pLeftHLayout->geometry().topRight(), m_pRightHLayout->geometry().bottomLeft());
}
else
{
int offset = (this->width() - iPosx) * fScale; // 偏移量
if(offset >= wdif) // 当偏移量大于宽度差值,采用标题栏居中
{
int iPox2 = m_pRightHLayout->geometry().width()
+ m_pLeftHLayout->geometry().width()
+ pixelTitle
+ iSpaceLeave
+ wdif / fScale;//标题文字较长时,由标题栏到空白居中渐变的起始宽度
QPoint bottomleftPt = m_pRightHLayout->geometry().bottomRight();
if(this->width() < iPox2) // 当标题栏宽度小于渐变宽度时,采用标题栏-offset居中
{
offset = (iPox2 - this->width()) * fScale;
if(offset < wdif)
{
bottomleftPt.setX(bottomleftPt.x() - offset);
}
}
titleRect = QRect(m_pLeftHLayout->geometry().topLeft(), bottomleftPt);
}
else // 当偏移量小于宽度差值,采用空白+offset居中
{
QPoint bottomleftPt = m_pRightHLayout->geometry().bottomLeft();
bottomleftPt.setX(bottomleftPt.x() + offset);
titleRect = QRect(m_pLeftHLayout->geometry().topRight(), bottomleftPt);
}
}
}
return titleRect;
}
void PaiTitleBar::mousePressEvent(QMouseEvent *pEvent)
{
QWidget::mousePressEvent(pEvent);
// 左键+有父控件+没触发resize事件暂时用鼠标样式判断
if((pEvent->button() == Qt::LeftButton) && parentWidget() && (cursor().shape() == Qt::ArrowCursor))
{
m_MovePosition = pEvent->globalPos() - parentWidget()->frameGeometry().topLeft();
pEvent->accept();
}
else
{
pEvent->ignore();
}
}
void PaiTitleBar::mouseReleaseEvent(QMouseEvent *pEvent)
{
QWidget::mouseReleaseEvent(pEvent);
// 左键+有父控件+没触发resize事件暂时用鼠标样式判断
if((pEvent->button() == Qt::LeftButton) && parentWidget() && (cursor().shape() == Qt::ArrowCursor))
{
m_MovePosition = QPoint(-1, -1);
pEvent->accept();
}
else
{
pEvent->ignore();
}
}
void PaiTitleBar::mouseMoveEvent(QMouseEvent *pEvent)
{
QWidget::mouseMoveEvent(pEvent);
// 左键+有父控件+没触发resize事件暂时用鼠标样式判断
if((pEvent->buttons() & Qt::LeftButton) && parentWidget() && (cursor().shape() == Qt::ArrowCursor))
{
if(m_MovePosition != QPoint(-1, -1))
{
// 主窗口move事件
parentWidget()->move(pEvent->globalPos() - m_MovePosition);
pEvent->accept();
}
else
{
pEvent->ignore();
}
}
}
void PaiTitleBar::mouseDoubleClickEvent(QMouseEvent *pEvent)
{
QWidget::mouseDoubleClickEvent(pEvent);
// 左键+有父控件+没触发resize事件暂时用鼠标样式判断
if((pEvent->button() == Qt::LeftButton && parentWidget()) && (cursor().shape() == Qt::ArrowCursor))
{
if(parentWidget()->isMaximized())
{
parentWidget()->showNormal();
ChangeRestoreButtonState(false);
}
else
{
parentWidget()->showMaximized();
ChangeRestoreButtonState(true);
}
}
}
void PaiTitleBar::SetTitle(const QString & strTitle)
{
m_title = strTitle;
update();
}
void PaiTitleBar::SetTitleBarFlags(TitleBarFlags flags)
{
m_pExitButton->setVisible(flags & PaiTitleBar::CloseButtonHint);
m_pMaximumButton->setVisible(flags & PaiTitleBar::MaximumButtonHint);
m_pMinimumButton->setVisible(flags & PaiTitleBar::MinimumButtonHint);
m_pLogoButton->setVisible(flags & PaiTitleBar::LogoButtonHint);
m_titleBarFlags = flags;
}
PaiTitleBar::TitleBarFlags PaiTitleBar::GetTitleBarFlags() const
{
return m_titleBarFlags;
}
void PaiTitleBar::CreateSystemMenu(QMenu *pMenu)
{
m_pLogoButton->setMenu(pMenu);
}
void PaiTitleBar::InsertWidget(QWidget *pWidget, Qt::Alignment alignment)
{
if(alignment == Qt::AlignRight)
{
m_pRightHLayout->insertWidget(0, pWidget);
}
else if(alignment == Qt::AlignLeft)
{
m_pLeftHLayout->addWidget(pWidget);
}
}
void PaiTitleBar::ChangeRestoreButtonState()
{
if(parentWidget())
{
if(parentWidget()->isMaximized())
{
parentWidget()->showNormal();
ChangeRestoreButtonState(false);
}
else
{
parentWidget()->showMaximized();
ChangeRestoreButtonState(true);
}
}
}
void PaiTitleBar::ChangeRestoreButtonState(bool maximized)
{
if(maximized)
{
m_pMaximumButton->setStyleSheet("QToolButton#MaximumButton{border-image:url(:/minimize_status.png)}"
"QToolButton#MaximumButton:hover{background-image:url(:/Minimize_hover.png);"
" border-style:none}"
"QToolButton#MaximumButton:pressed{background-image:url(:/Minimize_click.png);"
" border-style:none}");
}
else
{
m_pMaximumButton->setStyleSheet("QToolButton#MaximumButton{border-image:url(:/maximum.png)}"
"QToolButton#MaximumButton:hover{background-image:url(:/maximum_hover.png);"
" border-style:none}"
"QToolButton#MaximumButton:pressed{background-image:url(:/maximum_click.png);"
" border-style:none}");
}
}