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

261 lines
7.2 KiB
C++
Raw Normal View History

2024-10-29 22:24:50 +08:00
#include "SARibbonButtonGroupWidget.h"
#include <QHBoxLayout>
#include <QDebug>
#include <QMargins>
#include <QChildEvent>
#include <QActionEvent>
#include <QWidgetAction>
#include <QApplication>
#include "SARibbonControlButton.h"
#include "SARibbonElementManager.h"
#include "SARibbonSeparatorWidget.h"
#include "SARibbonPannel.h"
//===================================================
// SARibbonButtonGroupWidget::PrivateData
//===================================================
class SARibbonButtonGroupWidget::PrivateData
{
SA_RIBBON_DECLARE_PUBLIC(SARibbonButtonGroupWidget)
public:
PrivateData(SARibbonButtonGroupWidget* p);
void init();
void removeAction(QAction* a);
public:
QSize mIconSize { 20, 20 };
};
SARibbonButtonGroupWidget::PrivateData::PrivateData(SARibbonButtonGroupWidget* p) : q_ptr(p)
{
}
void SARibbonButtonGroupWidget::PrivateData::init()
{
QHBoxLayout* layout = new QHBoxLayout(q_ptr);
// 上下保留一点间隙
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(1);
q_ptr->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
}
void SARibbonButtonGroupWidget::PrivateData::removeAction(QAction* a)
{
QLayout* lay = q_ptr->layout();
int c = lay->count();
QList< QLayoutItem* > willRemoveItems;
for (int i = 0; i < c; ++i) {
QLayoutItem* item = lay->itemAt(i);
SARibbonControlButton* btn = qobject_cast< SARibbonControlButton* >(item->widget());
if (nullptr == btn) {
continue;
}
if (a == btn->defaultAction()) {
willRemoveItems.push_back(item);
}
}
// 从尾部删除
for (auto i = willRemoveItems.rbegin(); i != willRemoveItems.rend(); ++i) {
lay->removeItem(*i);
}
}
//===================================================
// SARibbonButtonGroupWidget
//===================================================
SARibbonButtonGroupWidget::SARibbonButtonGroupWidget(QWidget* parent)
: QFrame(parent), d_ptr(new SARibbonButtonGroupWidget::PrivateData(this))
{
d_ptr->init();
}
SARibbonButtonGroupWidget::~SARibbonButtonGroupWidget()
{
}
/**
* @brief
* @param iconSize
*/
void SARibbonButtonGroupWidget::setIconSize(const QSize& ic)
{
d_ptr->mIconSize = ic;
iterate([ ic ](SARibbonControlButton* btn) -> bool {
btn->setIconSize(ic);
return true;
});
}
/**
* @brief
* @return
*/
QSize SARibbonButtonGroupWidget::iconSize() const
{
return d_ptr->mIconSize;
}
QAction* SARibbonButtonGroupWidget::addAction(QAction* a, Qt::ToolButtonStyle buttonStyle, QToolButton::ToolButtonPopupMode popMode)
{
SARibbonPannel::setActionToolButtonStyleProperty(a, buttonStyle);
SARibbonPannel::setActionToolButtonPopupModeProperty(a, popMode);
QWidget::addAction(a);
return (a);
}
/**
* @brief action
* @note action的所有权归SARibbonButtonGroupWidget
* @param text
* @param icon
* @param popMode
* @return
*/
QAction* SARibbonButtonGroupWidget::addAction(const QString& text, const QIcon& icon, Qt::ToolButtonStyle buttonStyle, QToolButton::ToolButtonPopupMode popMode)
{
QAction* a = new QAction(icon, text, this);
addAction(a, buttonStyle, popMode);
return (a);
}
QAction* SARibbonButtonGroupWidget::addMenu(QMenu* menu, Qt::ToolButtonStyle buttonStyle, QToolButton::ToolButtonPopupMode popMode)
{
QAction* a = menu->menuAction();
addAction(a, buttonStyle, popMode);
return (a);
}
QAction* SARibbonButtonGroupWidget::addSeparator()
{
QAction* a = new QAction(this);
a->setSeparator(true);
addAction(a);
return (a);
}
QAction* SARibbonButtonGroupWidget::addWidget(QWidget* w)
{
QWidgetAction* a = new QWidgetAction(this);
a->setDefaultWidget(w);
w->setAttribute(Qt::WA_Hover);
addAction(a);
return (a);
}
SARibbonControlButton* SARibbonButtonGroupWidget::actionToRibbonControlToolButton(QAction* action)
{
SARibbonControlButton* res = nullptr;
iterate([ &res, action ](SARibbonControlButton* btn) -> bool {
if (btn->defaultAction() == action) {
res = btn;
return false; // 返回false退出迭代
}
return true;
});
return (res);
}
QSize SARibbonButtonGroupWidget::sizeHint() const
{
return (layout()->sizeHint());
}
QSize SARibbonButtonGroupWidget::minimumSizeHint() const
{
return (layout()->minimumSize());
}
/**
* @brief SARibbonButtonGroupWidget下的所有SARibbonControlButton(bool(SARibbonControlButton*))false则停止迭代
* @param fp
* @return 退false
*/
bool SARibbonButtonGroupWidget::iterate(SARibbonButtonGroupWidget::FpButtonIterate fp)
{
QLayout* lay = layout();
int c = lay->count();
for (int i = 0; i < c; ++i) {
auto item = lay->itemAt(i);
if (!item) {
continue;
}
SARibbonControlButton* btn = qobject_cast< SARibbonControlButton* >(item->widget());
if (!btn) {
continue;
}
if (!fp(btn)) {
return false;
}
}
return true;
}
/**
* @brief action的事件
*
* ActionAddedActionChangedActionRemoved三个事件
* ActionAdded时会生成窗口
* @param e
*/
void SARibbonButtonGroupWidget::actionEvent(QActionEvent* e)
{
QAction* a = e->action();
if (!a) {
return;
}
switch (e->type()) {
case QEvent::ActionAdded: {
QWidget* w = nullptr;
if (QWidgetAction* widgetAction = qobject_cast< QWidgetAction* >(a)) {
widgetAction->setParent(this);
w = widgetAction->requestWidget(this);
if (w != nullptr) {
w->setAttribute(Qt::WA_LayoutUsesWidgetRect);
w->show();
}
} else if (a->isSeparator()) {
SARibbonSeparatorWidget* sp = RibbonSubElementFactory->createRibbonSeparatorWidget(this);
w = sp;
}
// 不是widget自动生成ButtonTyle
if (!w) {
SARibbonControlButton* button = RibbonSubElementFactory->createRibbonControlButton(this);
button->setAutoRaise(true);
button->setIconSize(d_ptr->mIconSize);
button->setFocusPolicy(Qt::NoFocus);
button->setDefaultAction(a);
// 属性设置
QToolButton::ToolButtonPopupMode popMode = SARibbonPannel::getActionToolButtonPopupModeProperty(a);
button->setPopupMode(popMode);
Qt::ToolButtonStyle buttonStyle = SARibbonPannel::getActionToolButtonStyleProperty(a);
button->setToolButtonStyle(buttonStyle);
// 根据QAction的属性设置按钮的大小
connect(button, &SARibbonToolButton::triggered, this, &SARibbonButtonGroupWidget::actionTriggered);
w = button;
}
layout()->addWidget(w);
updateGeometry();
} break;
case QEvent::ActionChanged: {
// 让布局重新绘制
layout()->invalidate();
updateGeometry();
} break;
case QEvent::ActionRemoved: {
d_ptr->removeAction(e->action());
updateGeometry();
} break;
default:
break;
}
QFrame::actionEvent(e);
}