#include "SARibbonSystemButtonBar.h" #include #include #include #include #include #include #include "SARibbonMainWindow.h" #include "SARibbonBar.h" #include "SARibbonElementManager.h" #include "SARibbonButtonGroupWidget.h" // 为了避免使用此框架的app设置了全局的qpushbutton 的 qss样式影响此按钮,定义了一个类 /** * @brief The SARibbonSystemButtonBar class */ class SARibbonSystemButtonBar::PrivateData { SA_RIBBON_DECLARE_PUBLIC(SARibbonSystemButtonBar) public: SARibbonSystemToolButton* buttonClose { nullptr }; SARibbonSystemToolButton* buttonMinimize { nullptr }; SARibbonSystemToolButton* buttonMaximize { nullptr }; int mCloseStretch { 4 }; int mMaxStretch { 3 }; int mMinStretch { 3 }; int mWindowButtonWidth { 35 }; int mTitleBarHeight { 28 }; Qt::WindowFlags mFlags { Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint }; SARibbonButtonGroupWidget* mButtonGroup; public: PrivateData(SARibbonSystemButtonBar* p) : q_ptr(p) { mButtonGroup = new SARibbonButtonGroupWidget(p); mButtonGroup->setObjectName("SASystemButtonGroup"); } void setupMinimizeButton(bool on) { SARibbonSystemButtonBar* par = q_ptr; if (on) { if (buttonMinimize) { buttonMinimize->deleteLater(); buttonMinimize = nullptr; } buttonMinimize = new SARibbonSystemToolButton(par); buttonMinimize->setObjectName(QStringLiteral("SAMinimizeWindowButton")); buttonMinimize->setFocusPolicy(Qt::NoFocus); // 避免铺抓到 buttonMinimize->show(); par->connect(buttonMinimize, &QAbstractButton::clicked, par, &SARibbonSystemButtonBar::minimizeWindow); } else { if (buttonMinimize) { buttonMinimize->deleteLater(); buttonMinimize = nullptr; } } updateSize(); } void setupMaximizeButton(bool on) { SARibbonSystemButtonBar* par = q_ptr; if (on) { if (buttonMaximize) { buttonMaximize->deleteLater(); buttonMaximize = nullptr; } buttonMaximize = new SARibbonSystemToolButton(par); buttonMaximize->setObjectName(QStringLiteral("SAMaximizeWindowButton")); buttonMaximize->setCheckable(true); buttonMaximize->setFocusPolicy(Qt::NoFocus); // 避免铺抓到 // buttonMaximize->setIconSize(buttonMaximize->size() * mIconscale); buttonMaximize->show(); par->connect(buttonMaximize, &QAbstractButton::clicked, par, &SARibbonSystemButtonBar::maximizeWindow); } else { if (buttonMaximize) { buttonMaximize->deleteLater(); ; buttonMaximize = nullptr; } } updateSize(); } void setupCloseButton(bool on) { SARibbonSystemButtonBar* par = q_ptr; if (on) { if (buttonClose) { buttonClose->deleteLater(); buttonClose = nullptr; } buttonClose = new SARibbonSystemToolButton(par); buttonClose->setObjectName(QStringLiteral("SACloseWindowButton")); buttonClose->setFocusPolicy(Qt::NoFocus); // 避免铺抓到 // buttonClose->setFlat(true); par->connect(buttonClose, &QAbstractButton::clicked, par, &SARibbonSystemButtonBar::closeWindow); // buttonClose->setIconSize(buttonClose->size() * mIconscale); buttonClose->show(); } else { if (buttonClose) { buttonClose->deleteLater(); ; buttonClose = nullptr; } } updateSize(); } void updateSize() { resizeElement(q_ptr->size()); } void resizeElement(QSize size) { int x = size.width(); if (buttonClose) { int w = closeButtonWidthHint(); x -= w; buttonClose->setGeometry(x, 0, w, size.height()); } if (buttonMaximize) { int w = maxButtonWidthHint(); x -= w; buttonMaximize->setGeometry(x, 0, w, size.height()); } if (buttonMinimize) { int w = minButtonWidthHint(); x -= w; buttonMinimize->setGeometry(x, 0, w, size.height()); } if (mButtonGroup) { mButtonGroup->setGeometry(0, 0, x, size.height()); } } int closeButtonWidthHint() const { qreal t = mCloseStretch + mMaxStretch + mMinStretch; return (mCloseStretch * (3 * mWindowButtonWidth)) / t; } int maxButtonWidthHint() const { qreal t = mCloseStretch + mMaxStretch + mMinStretch; return (mMaxStretch * (3 * mWindowButtonWidth)) / t; } int minButtonWidthHint() const { qreal t = mCloseStretch + mMaxStretch + mMinStretch; return (mMinStretch * (3 * mWindowButtonWidth)) / t; } QSize sizeHint() const { int height = mTitleBarHeight; if (height < 20) { height = 20; } QSize res(0, 0); if (mButtonGroup) { res = mButtonGroup->sizeHint(); } res.setHeight(height); if (buttonClose) { res.setWidth(res.width() + closeButtonWidthHint()); } if (buttonMaximize) { res.setWidth(res.width() + maxButtonWidthHint()); } if (buttonMinimize) { res.setWidth(res.width() + minButtonWidthHint()); } return res; } }; //=================================================== // SARibbonSystemToolButton //=================================================== SARibbonSystemToolButton::SARibbonSystemToolButton(QWidget* p) : QToolButton(p) { setAutoRaise(true); } //=================================================== // SARibbonSystemButtonBar //=================================================== SARibbonSystemButtonBar::SARibbonSystemButtonBar(QWidget* parent) : QFrame(parent), d_ptr(new SARibbonSystemButtonBar::PrivateData(this)) { updateWindowFlag(); } /** * @brief 构造函数,强制使用flags,而不是用parent的flags进行构造 * @param parent * @param flags */ SARibbonSystemButtonBar::SARibbonSystemButtonBar(QWidget* parent, Qt::WindowFlags flags) : QFrame(parent), d_ptr(new SARibbonSystemButtonBar::PrivateData(this)) { d_ptr->mFlags = flags; updateWindowFlag(); } SARibbonSystemButtonBar::~SARibbonSystemButtonBar() { } void SARibbonSystemButtonBar::setupMinimizeButton(bool on) { d_ptr->setupMinimizeButton(on); } void SARibbonSystemButtonBar::setupMaximizeButton(bool on) { d_ptr->setupMaximizeButton(on); } void SARibbonSystemButtonBar::setupCloseButton(bool on) { d_ptr->setupCloseButton(on); } void SARibbonSystemButtonBar::updateWindowFlag() { QWidget* topedWidget = this; // 找到最顶层窗口 while (topedWidget->parentWidget()) { topedWidget = topedWidget->parentWidget(); } Qt::WindowFlags flags = topedWidget->windowFlags(); updateWindowFlag(flags); } /** * @brief 此函数仅用于控制最小最大化和关闭按钮的显示 * @param flags */ void SARibbonSystemButtonBar::updateWindowFlag(Qt::WindowFlags flags) { d_ptr->mFlags = flags; setupMinimizeButton(flags & Qt::WindowMinimizeButtonHint); setupMaximizeButton(flags & Qt::WindowMaximizeButtonHint); setupCloseButton(flags & Qt::WindowCloseButtonHint); } /** * @brief 设置按钮的宽度比例,最终按钮宽度将按照此比例进行设置 * @param close 关闭按钮比例 * @param max 最大化按钮比例 * @param min 最小化按钮比例 */ void SARibbonSystemButtonBar::setButtonWidthStretch(int close, int max, int min) { d_ptr->mMaxStretch = max; d_ptr->mMinStretch = min; d_ptr->mCloseStretch = close; } /** * @brief 标题栏高度 * * 标题栏高度会影响sizeHint * @param h */ void SARibbonSystemButtonBar::setWindowTitleHeight(int h) { d_ptr->mTitleBarHeight = h; } /** * @brief 标题栏高度 * @return */ int SARibbonSystemButtonBar::windowTitleHeight() const { return d_ptr->mTitleBarHeight; } /** * @brief 系统按钮的宽度 * @param w */ void SARibbonSystemButtonBar::setWindowButtonWidth(int w) { d_ptr->mWindowButtonWidth = w; } /** * @brief 系统按钮的宽度 * @param w */ int SARibbonSystemButtonBar::windowButtonWidth() const { return d_ptr->mWindowButtonWidth; } /** * @brief 设置窗口状态(最大最小化按钮状态) * @param s */ void SARibbonSystemButtonBar::setWindowStates(Qt::WindowStates s) { if (d_ptr->buttonMaximize) { bool on = s.testFlag(Qt::WindowMaximized); d_ptr->buttonMaximize->setChecked(on); d_ptr->buttonMaximize->setToolTip(on ? tr("Restore") : tr("Maximize")); } } /** * @brief 此函数返回的flags仅包括 Qt::WindowCloseButtonHint,Qt::WindowMaximizeButtonHint,Qt::WindowMinimizeButtonHint * 三个 * * @return */ Qt::WindowFlags SARibbonSystemButtonBar::windowButtonFlags() const { Qt::WindowFlags f = Qt::Widget; // widget是000 if (d_ptr->mFlags & Qt::WindowCloseButtonHint) { f |= Qt::WindowCloseButtonHint; } if (d_ptr->mFlags & Qt::WindowMaximizeButtonHint) { f |= Qt::WindowMaximizeButtonHint; } if (d_ptr->mFlags & Qt::WindowMinimizeButtonHint) { f |= Qt::WindowMinimizeButtonHint; } return (f); } QSize SARibbonSystemButtonBar::sizeHint() const { return (d_ptr->sizeHint()); } bool SARibbonSystemButtonBar::eventFilter(QObject* obj, QEvent* event) { if (obj == parent()) { // SARibbonMainWindow的事件 if (event->type() == QEvent::Resize) { SARibbonMainWindow* mainWindow = qobject_cast< SARibbonMainWindow* >(obj); if (!mainWindow) { // 所有事件都不消费 return QFrame::eventFilter(obj, event); } SARibbonBar* ribbonBar = mainWindow->ribbonBar(); if (!ribbonBar) { // 所有事件都不消费 return QFrame::eventFilter(obj, event); } const int th = ribbonBar->titleBarHeight(); if (th != height()) { setWindowTitleHeight(th); } QRect fr = mainWindow->geometry(); QSize wgSizeHint = sizeHint(); setGeometry(fr.width() - wgSizeHint.width(), 0, wgSizeHint.width(), wgSizeHint.height()); // 把设置好的尺寸给ribbonbar ribbonBar->setWindowButtonGroupSize(size()); } else if (event->type() == QEvent::WindowStateChange) { SARibbonMainWindow* mainWindow = qobject_cast< SARibbonMainWindow* >(obj); if (!mainWindow) { // 所有事件都不消费 return QFrame::eventFilter(obj, event); } setWindowStates(mainWindow->windowState()); } } return QFrame::eventFilter(obj, event); } QAbstractButton* SARibbonSystemButtonBar::minimizeButton() const { return d_ptr->buttonMinimize; } QAbstractButton* SARibbonSystemButtonBar::maximizeButton() const { return d_ptr->buttonMaximize; } QAbstractButton* SARibbonSystemButtonBar::closeButton() const { return d_ptr->buttonClose; } void SARibbonSystemButtonBar::setIconSize(const QSize& ic) { d_ptr->mButtonGroup->setIconSize(ic); } QSize SARibbonSystemButtonBar::iconSize() const { return d_ptr->mButtonGroup->iconSize(); } QAction* SARibbonSystemButtonBar::addAction(QAction* a, Qt::ToolButtonStyle buttonStyle, QToolButton::ToolButtonPopupMode popMode) { return d_ptr->mButtonGroup->addAction(a, buttonStyle, popMode); } QAction* SARibbonSystemButtonBar::addAction(const QString& text, const QIcon& icon, Qt::ToolButtonStyle buttonStyle, QToolButton::ToolButtonPopupMode popMode) { return d_ptr->mButtonGroup->addAction(text, icon, buttonStyle, popMode); } QAction* SARibbonSystemButtonBar::addMenu(QMenu* menu, Qt::ToolButtonStyle buttonStyle, QToolButton::ToolButtonPopupMode popMode) { return d_ptr->mButtonGroup->addMenu(menu, buttonStyle, popMode); } QAction* SARibbonSystemButtonBar::addSeparator() { return d_ptr->mButtonGroup->addSeparator(); } QAction* SARibbonSystemButtonBar::addWidget(QWidget* w) { return d_ptr->mButtonGroup->addWidget(w); } void SARibbonSystemButtonBar::resizeEvent(QResizeEvent* e) { Q_UNUSED(e); d_ptr->resizeElement(size()); } void SARibbonSystemButtonBar::closeWindow() { if (parentWidget()) { parentWidget()->close(); } } void SARibbonSystemButtonBar::minimizeWindow() { if (parentWidget()) { parentWidget()->showMinimized(); } } void SARibbonSystemButtonBar::maximizeWindow() { QWidget* par = parentWidget(); if (par) { if (par->isMaximized()) { par->showNormal(); } else { par->showMaximized(); } } }