417 lines
12 KiB
C++
417 lines
12 KiB
C++
![]() |
#include "SARibbonGallery.h"
|
|||
|
#include "SARibbonControlButton.h"
|
|||
|
#include <QIcon>
|
|||
|
#include <QApplication>
|
|||
|
#define ICON_ARROW_UP QIcon(":/image/resource/ArrowUp.png")
|
|||
|
#define ICON_ARROW_DOWN QIcon(":/image/resource/ArrowDown.png")
|
|||
|
#define ICON_ARROW_MORE QIcon(":/image/resource/ArrowMore.png")
|
|||
|
#include <QResizeEvent>
|
|||
|
#include <QDebug>
|
|||
|
#include <QVBoxLayout>
|
|||
|
#include <QScrollBar>
|
|||
|
#include <QLabel>
|
|||
|
#include "SARibbonElementManager.h"
|
|||
|
#include <QActionGroup>
|
|||
|
|
|||
|
/**
|
|||
|
* @brief The SARibbonGalleryPrivate class
|
|||
|
*/
|
|||
|
class SARibbonGallery::PrivateData
|
|||
|
{
|
|||
|
SA_RIBBON_DECLARE_PUBLIC(SARibbonGallery)
|
|||
|
public:
|
|||
|
static int sGalleryButtonMaximumWidth;
|
|||
|
SARibbonGalleryButton* mButtonUp { nullptr };
|
|||
|
SARibbonGalleryButton* mButtonDown { nullptr };
|
|||
|
SARibbonGalleryButton* mButtonMore { nullptr };
|
|||
|
#if 0
|
|||
|
SARibbonMenu *popupWidget;
|
|||
|
#else
|
|||
|
SARibbonGalleryViewport* mPopupWidget { nullptr };
|
|||
|
#endif
|
|||
|
SARibbonGalleryGroup* mViewportGroup { nullptr };
|
|||
|
QBoxLayout* mButtonLayout { nullptr };
|
|||
|
QBoxLayout* mLayout { nullptr };
|
|||
|
PrivateData(SARibbonGallery* p) : q_ptr(p)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
void init()
|
|||
|
{
|
|||
|
mButtonUp = new SARibbonGalleryButton(q_ptr);
|
|||
|
mButtonDown = new SARibbonGalleryButton(q_ptr);
|
|||
|
mButtonMore = new SARibbonGalleryButton(q_ptr);
|
|||
|
mButtonUp->setToolButtonStyle(Qt::ToolButtonIconOnly);
|
|||
|
mButtonDown->setToolButtonStyle(Qt::ToolButtonIconOnly);
|
|||
|
mButtonMore->setToolButtonStyle(Qt::ToolButtonIconOnly);
|
|||
|
mButtonUp->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
|
|||
|
mButtonDown->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
|
|||
|
mButtonMore->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
|
|||
|
mButtonUp->setObjectName(QStringLiteral("SARibbonGalleryButtonUp"));
|
|||
|
mButtonDown->setObjectName(QStringLiteral("SARibbonGalleryButtonDown"));
|
|||
|
mButtonMore->setObjectName(QStringLiteral("SARibbonGalleryButtonMore"));
|
|||
|
mButtonUp->setMaximumWidth(sGalleryButtonMaximumWidth);
|
|||
|
mButtonDown->setMaximumWidth(sGalleryButtonMaximumWidth);
|
|||
|
mButtonMore->setMaximumWidth(sGalleryButtonMaximumWidth);
|
|||
|
mButtonUp->setIcon(ICON_ARROW_UP);
|
|||
|
mButtonDown->setIcon(ICON_ARROW_DOWN);
|
|||
|
mButtonMore->setIcon(ICON_ARROW_MORE);
|
|||
|
q_ptr->connect(mButtonUp, &QAbstractButton::clicked, q_ptr, &SARibbonGallery::pageUp);
|
|||
|
q_ptr->connect(mButtonDown, &QAbstractButton::clicked, q_ptr, &SARibbonGallery::pageDown);
|
|||
|
q_ptr->connect(mButtonMore, &QAbstractButton::clicked, q_ptr, &SARibbonGallery::showMoreDetail);
|
|||
|
// 信号转发
|
|||
|
q_ptr->connect(q_ptr, &SARibbonGallery::triggered, q_ptr, &SARibbonGallery::onTriggered);
|
|||
|
mPopupWidget = nullptr;
|
|||
|
mViewportGroup = nullptr;
|
|||
|
mButtonLayout = new QBoxLayout(QBoxLayout::TopToBottom);
|
|||
|
mButtonLayout->setSpacing(0);
|
|||
|
mButtonLayout->setContentsMargins(0, 0, 0, 0);
|
|||
|
mButtonLayout->addWidget(mButtonUp);
|
|||
|
mButtonLayout->addWidget(mButtonDown);
|
|||
|
mButtonLayout->addWidget(mButtonMore);
|
|||
|
mLayout = new QBoxLayout(QBoxLayout::RightToLeft);
|
|||
|
mLayout->setSpacing(0);
|
|||
|
mLayout->setContentsMargins(0, 0, 0, 0);
|
|||
|
mLayout->addLayout(mButtonLayout);
|
|||
|
mLayout->addStretch();
|
|||
|
q_ptr->setLayout(mLayout);
|
|||
|
}
|
|||
|
|
|||
|
bool isValid() const
|
|||
|
{
|
|||
|
return (q_ptr != nullptr);
|
|||
|
}
|
|||
|
|
|||
|
void createPopupWidget()
|
|||
|
{
|
|||
|
if (nullptr == mPopupWidget) {
|
|||
|
#if 0
|
|||
|
popupWidget = new SARibbonMenu(Parent);
|
|||
|
#else
|
|||
|
mPopupWidget = new SARibbonGalleryViewport(q_ptr);
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void setViewPort(SARibbonGalleryGroup* v)
|
|||
|
{
|
|||
|
if (nullptr == mViewportGroup) {
|
|||
|
mViewportGroup = RibbonSubElementFactory->createRibbonGalleryGroup(q_ptr);
|
|||
|
mLayout->addWidget(mViewportGroup, 1);
|
|||
|
}
|
|||
|
mViewportGroup->setRecalcGridSizeBlock(true);
|
|||
|
mViewportGroup->setGalleryGroupStyle(v->galleryGroupStyle());
|
|||
|
mViewportGroup->setDisplayRow(v->displayRow());
|
|||
|
mViewportGroup->setSpacing(v->spacing());
|
|||
|
mViewportGroup->setGridMaximumWidth(v->gridMaximumWidth());
|
|||
|
mViewportGroup->setGridMinimumWidth(v->gridMinimumWidth());
|
|||
|
mViewportGroup->setRecalcGridSizeBlock(false);
|
|||
|
mViewportGroup->recalcGridSize(mViewportGroup->height());
|
|||
|
mViewportGroup->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|||
|
mViewportGroup->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|||
|
mViewportGroup->setModel(v->model());
|
|||
|
mViewportGroup->show();
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
// 静态变量初始化
|
|||
|
|
|||
|
/**
|
|||
|
* @brief SARibbonGalleryPrivate::sGalleryButtonMaximumWidth
|
|||
|
*/
|
|||
|
int SARibbonGallery::PrivateData::sGalleryButtonMaximumWidth = 15;
|
|||
|
|
|||
|
//===================================================
|
|||
|
// SARibbonGalleryButton
|
|||
|
//===================================================
|
|||
|
|
|||
|
SARibbonGalleryButton::SARibbonGalleryButton(QWidget* parent) : QToolButton(parent)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
//===================================================
|
|||
|
// SARibbonGalleryViewport
|
|||
|
//===================================================
|
|||
|
|
|||
|
SARibbonGalleryViewport::SARibbonGalleryViewport(QWidget* parent) : QWidget(parent)
|
|||
|
{
|
|||
|
setWindowFlags(Qt::Popup);
|
|||
|
QPalette pl = palette();
|
|||
|
pl.setBrush(QPalette::Window, pl.brush(QPalette::Base));
|
|||
|
setPalette(pl);
|
|||
|
m_layout = new QVBoxLayout(this);
|
|||
|
m_layout->setSpacing(0);
|
|||
|
m_layout->setContentsMargins(0, 0, 0, 0);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @brief 添加窗口不带标题
|
|||
|
* @param w
|
|||
|
*/
|
|||
|
void SARibbonGalleryViewport::addWidget(QWidget* w)
|
|||
|
{
|
|||
|
w->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
|
|||
|
m_layout->addWidget(w);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @brief 添加窗口,带标题
|
|||
|
* @param w
|
|||
|
* @param title
|
|||
|
*/
|
|||
|
void SARibbonGalleryViewport::addWidget(QWidget* w, const QString& title)
|
|||
|
{
|
|||
|
QLabel* label = new QLabel(this);
|
|||
|
label->setText(title);
|
|||
|
label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
|
|||
|
m_layout->addWidget(label);
|
|||
|
w->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
|
|||
|
m_layout->addWidget(w);
|
|||
|
_widgetToTitleLable[ w ] = label;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @brief 通过SARibbonGalleryGroup获取对应的标题,用户可以通过此函数设置QLabel的属性
|
|||
|
* @param g
|
|||
|
* @return 如果没有管理group,将返回nullptr
|
|||
|
*/
|
|||
|
QLabel* SARibbonGalleryViewport::titleLabel(QWidget* w)
|
|||
|
{
|
|||
|
return _widgetToTitleLable.value(w, nullptr);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @brief 移除窗口
|
|||
|
* @param w
|
|||
|
*/
|
|||
|
void SARibbonGalleryViewport::removeWidget(QWidget* w)
|
|||
|
{
|
|||
|
QLabel* label = titleLabel(w);
|
|||
|
if (label) {
|
|||
|
m_layout->removeWidget(label);
|
|||
|
}
|
|||
|
m_layout->removeWidget(w);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @brief widget的标题改变
|
|||
|
* @param g
|
|||
|
* @param title
|
|||
|
*/
|
|||
|
void SARibbonGalleryViewport::onTitleChanged(QWidget* w, const QString& title)
|
|||
|
{
|
|||
|
QLabel* l = titleLabel(w);
|
|||
|
if (l) {
|
|||
|
l->setText(title);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//===================================================
|
|||
|
// SARibbonGallery
|
|||
|
//===================================================
|
|||
|
|
|||
|
SARibbonGallery::SARibbonGallery(QWidget* parent) : QFrame(parent), d_ptr(new SARibbonGallery::PrivateData(this))
|
|||
|
{
|
|||
|
d_ptr->init();
|
|||
|
setFrameShape(QFrame::Box);
|
|||
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|||
|
setMinimumWidth(200);
|
|||
|
}
|
|||
|
|
|||
|
SARibbonGallery::~SARibbonGallery()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
QSize SARibbonGallery::sizeHint() const
|
|||
|
{
|
|||
|
return (QSize(100, 62));
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @brief 获取一个空白SARibbonGalleryGroup
|
|||
|
* @return
|
|||
|
*/
|
|||
|
SARibbonGalleryGroup* SARibbonGallery::addGalleryGroup()
|
|||
|
{
|
|||
|
SARibbonGalleryGroup* group = RibbonSubElementFactory->createRibbonGalleryGroup(this);
|
|||
|
addGalleryGroup(group);
|
|||
|
return (group);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @brief 添加一组SARibbonGalleryGroup
|
|||
|
* @param group
|
|||
|
*/
|
|||
|
void SARibbonGallery::addGalleryGroup(SARibbonGalleryGroup* group)
|
|||
|
{
|
|||
|
group->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
|||
|
SARibbonGalleryViewport* viewport = ensureGetPopupViewPort();
|
|||
|
viewport->addWidget(group, group->groupTitle());
|
|||
|
connect(group, &QAbstractItemView::clicked, this, &SARibbonGallery::onItemClicked);
|
|||
|
connect(group, &SARibbonGalleryGroup::groupTitleChanged, this, [ group, viewport ](const QString& t) {
|
|||
|
viewport->onTitleChanged(group, t);
|
|||
|
});
|
|||
|
connect(group, &SARibbonGalleryGroup::triggered, this, &SARibbonGallery::triggered);
|
|||
|
connect(group, &SARibbonGalleryGroup::hovered, this, &SARibbonGallery::hovered);
|
|||
|
setCurrentViewGroup(group);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @brief 添加一组actions
|
|||
|
* @param title actions组的名字
|
|||
|
* @param actions
|
|||
|
* @return 返回SARibbonGalleryGroup,用户可以通过修改SARibbonGalleryGroup属性控制其显示方法
|
|||
|
*/
|
|||
|
SARibbonGalleryGroup* SARibbonGallery::addCategoryActions(const QString& title, QList< QAction* > actions)
|
|||
|
{
|
|||
|
SARibbonGalleryGroup* group = RibbonSubElementFactory->createRibbonGalleryGroup(this);
|
|||
|
if (!title.isEmpty()) {
|
|||
|
group->setGroupTitle(title);
|
|||
|
}
|
|||
|
group->addActionItemList(actions);
|
|||
|
addGalleryGroup(group);
|
|||
|
return (group);
|
|||
|
}
|
|||
|
|
|||
|
void SARibbonGallery::setCurrentViewGroup(SARibbonGalleryGroup* group)
|
|||
|
{
|
|||
|
d_ptr->setViewPort(group);
|
|||
|
QApplication::postEvent(this, new QResizeEvent(size(), size()));
|
|||
|
}
|
|||
|
|
|||
|
SARibbonGalleryGroup* SARibbonGallery::currentViewGroup() const
|
|||
|
{
|
|||
|
return (d_ptr->mViewportGroup);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @brief 获取弹出窗口
|
|||
|
* @return
|
|||
|
*/
|
|||
|
SARibbonGalleryViewport* SARibbonGallery::getPopupViewPort() const
|
|||
|
{
|
|||
|
return d_ptr->mPopupWidget;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @brief 设置最右边三个控制按钮的最大宽度(默认15)
|
|||
|
* @param w
|
|||
|
*/
|
|||
|
void SARibbonGallery::setGalleryButtonMaximumWidth(int w)
|
|||
|
{
|
|||
|
SARibbonGallery::PrivateData::sGalleryButtonMaximumWidth = w;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @brief 上翻页
|
|||
|
*/
|
|||
|
void SARibbonGallery::pageDown()
|
|||
|
{
|
|||
|
if (d_ptr->mViewportGroup) {
|
|||
|
QScrollBar* vscrollBar = d_ptr->mViewportGroup->verticalScrollBar();
|
|||
|
int v = vscrollBar->value();
|
|||
|
v += vscrollBar->singleStep();
|
|||
|
vscrollBar->setValue(v);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @brief 下翻页
|
|||
|
*/
|
|||
|
void SARibbonGallery::pageUp()
|
|||
|
{
|
|||
|
if (d_ptr->mViewportGroup) {
|
|||
|
QScrollBar* vscrollBar = d_ptr->mViewportGroup->verticalScrollBar();
|
|||
|
int v = vscrollBar->value();
|
|||
|
v -= vscrollBar->singleStep();
|
|||
|
vscrollBar->setValue(v);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @brief 显示更多触发,默认弹出内部管理的SARibbonGalleryViewport,用户可重载此函数实现自定义的弹出
|
|||
|
*/
|
|||
|
void SARibbonGallery::showMoreDetail()
|
|||
|
{
|
|||
|
if (nullptr == d_ptr->mPopupWidget) {
|
|||
|
return;
|
|||
|
}
|
|||
|
QSize popupMenuSize = d_ptr->mPopupWidget->sizeHint();
|
|||
|
QPoint start = mapToGlobal(QPoint(0, 0));
|
|||
|
|
|||
|
int width = d_ptr->mViewportGroup->width(); // viewport
|
|||
|
|
|||
|
width += qApp->style()->pixelMetric(QStyle::PM_ScrollBarExtent); // scrollbar
|
|||
|
d_ptr->mPopupWidget->setGeometry(start.x(), start.y(), width, popupMenuSize.height());
|
|||
|
d_ptr->mPopupWidget->show();
|
|||
|
}
|
|||
|
|
|||
|
void SARibbonGallery::onItemClicked(const QModelIndex& index)
|
|||
|
{
|
|||
|
QObject* obj = sender();
|
|||
|
SARibbonGalleryGroup* group = qobject_cast< SARibbonGalleryGroup* >(obj);
|
|||
|
if (group) {
|
|||
|
setCurrentViewGroup(group);
|
|||
|
SARibbonGalleryGroup* curGroup = currentViewGroup();
|
|||
|
curGroup->scrollTo(index);
|
|||
|
curGroup->setCurrentIndex(index);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void SARibbonGallery::onTriggered(QAction* action)
|
|||
|
{
|
|||
|
Q_UNUSED(action);
|
|||
|
// 点击后关闭弹出窗口
|
|||
|
if (d_ptr->mPopupWidget) {
|
|||
|
if (d_ptr->mPopupWidget->isVisible()) {
|
|||
|
d_ptr->mPopupWidget->hide();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
SARibbonGalleryViewport* SARibbonGallery::ensureGetPopupViewPort()
|
|||
|
{
|
|||
|
if (nullptr == d_ptr->mPopupWidget) {
|
|||
|
d_ptr->createPopupWidget();
|
|||
|
}
|
|||
|
return (d_ptr->mPopupWidget);
|
|||
|
}
|
|||
|
|
|||
|
void SARibbonGallery::resizeEvent(QResizeEvent* event)
|
|||
|
{
|
|||
|
QFrame::resizeEvent(event);
|
|||
|
// 对SARibbonGalleryViewport所有SARibbonGalleryGroup重置尺寸
|
|||
|
int h = layout()->contentsRect().height();
|
|||
|
if (d_ptr->mViewportGroup) {
|
|||
|
h = d_ptr->mViewportGroup->height();
|
|||
|
d_ptr->mViewportGroup->recalcGridSize();
|
|||
|
}
|
|||
|
if (d_ptr->mPopupWidget) {
|
|||
|
QLayout* lay = d_ptr->mPopupWidget->layout();
|
|||
|
if (!lay) {
|
|||
|
return;
|
|||
|
}
|
|||
|
int c = lay->count();
|
|||
|
for (int i = 0; i < c; ++i) {
|
|||
|
QLayoutItem* item = lay->itemAt(i);
|
|||
|
if (!item) {
|
|||
|
continue;
|
|||
|
}
|
|||
|
QWidget* w = item->widget();
|
|||
|
if (!w) {
|
|||
|
continue;
|
|||
|
}
|
|||
|
SARibbonGalleryGroup* g = qobject_cast< SARibbonGalleryGroup* >(w);
|
|||
|
if (!g) {
|
|||
|
continue;
|
|||
|
}
|
|||
|
g->recalcGridSize(h);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void SARibbonGallery::paintEvent(QPaintEvent* event)
|
|||
|
{
|
|||
|
QFrame::paintEvent(event);
|
|||
|
}
|