/** * @file PaiTitleBar.cpp * @date 2012-11-29 */ #include #include #include #include #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}"); } }