261 lines
7.2 KiB
C++
261 lines
7.2 KiB
C++
![]() |
#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的事件
|
|||
|
*
|
|||
|
* 这里处理了ActionAdded,ActionChanged,ActionRemoved三个事件
|
|||
|
* 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);
|
|||
|
}
|