instAdmin/Cpp/GisDes/SaRibbon/SARibbonBar/SARibbonSystemButtonBar.cpp

468 lines
13 KiB
C++
Raw Normal View History

2024-10-29 22:24:50 +08:00
#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 使flagsparent的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();
}
}
}