387 lines
13 KiB
C++
387 lines
13 KiB
C++
/**
|
||
* @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}");
|
||
}
|
||
}
|
||
|