instAdmin/Cpp/GisDes/SaRibbon/SARibbonBar/SARibbonSystemButtonBar.cpp
2024-10-29 22:24:50 +08:00

468 lines
13 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "SARibbonSystemButtonBar.h"
#include <QToolButton>
#include <QResizeEvent>
#include <QStyle>
#include <QDebug>
#include <QScopedPointer>
#include <QWindowStateChangeEvent>
#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::WindowCloseButtonHintQt::WindowMaximizeButtonHintQt::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();
}
}
}