#include "SARibbonGallery.h" #include "SARibbonControlButton.h" #include #include #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 #include #include #include #include #include "SARibbonElementManager.h" #include /** * @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); }