12#include <QLinearGradient>
16#include <QResizeEvent>
20RibbonPageScrollButton::RibbonPageScrollButton(Qt::ArrowType arr, QWidget *p)
32 , m_contentsMargins(1, 1, 1, 1)
33 , m_isRightScrollBtnShow(false)
34 , m_isLeftScrollBtnShow(false)
35 , m_isPageContext(false)
36 , m_isCanCustomize(true)
65 group->setWindowTitle(title);
66 group->setObjectName(title);
82 if (group->parentWidget() != q) {
95 group->setVisible(
true);
123 group->deleteLater();
131 QList<RibbonGroup *> res;
135 res.append(i.m_group);
157 QList<RibbonGroup *> groups =
groupList();
160 group->setGroupLayoutMode(m);
171 total += (m.left() + m.right());
175 if (item.isEmpty()) {
178 total += item.m_group->sizeHint().width();
179 if (item.m_separator) {
180 total += item.m_separator->sizeHint().width();
193 s.rheight() -= (m.top() + m.bottom());
194 s.rwidth() -= (m.right() + m.left());
204 int pageWidth = pageSize.width();
216 int canExpandingCount = 0;
220#ifdef QX_RIBBON_DEBUG_HELP_DRAW
221 qDebug() <<
"\r\n\r\n============================================="
222 <<
"\r\nRibbonPagePrivate::updateItemGeometry"
223 <<
"\r\npage name:" << page->windowTitle() <<
"\r\n first totalWidth:" << totalWidth <<
"\r\n y:" << y
224 <<
"\r\nexpandWidth:" << expandWidth;
227 if (totalWidth <= pageWidth) {
232 if (!item.isEmpty()) {
233 if (item.m_group->isExpanding()) {
240 if (canExpandingCount > 0) {
241 expandWidth = (pageWidth - totalWidth) / canExpandingCount;
251 if (item.isEmpty()) {
253 if (item.m_separator) {
255 item.m_separator->hide();
257 item.m_groupWillGeometry = QRect(0, 0, 0, 0);
258 item.m_separatorWillGeometry = QRect(0, 0, 0, 0);
263 qDebug() <<
"unknow widget in RibbonPageLayout";
266 QSize groupSize = group->
sizeHint();
267 QSize separatorSize(0, 0);
268 if (item.m_separator) {
269 separatorSize = item.m_separator->sizeHint();
273 groupSize.setWidth(groupSize.width() + expandWidth);
275 int w = groupSize.width();
276 item.m_groupWillGeometry = QRect(x, y, w, pageSize.height());
279 w = separatorSize.width();
280 item.m_separatorWillGeometry = QRect(x, y, w, pageSize.height());
286 if (totalWidth > pageWidth) {
292 }
else if (
m_XBase <= (pageWidth - totalWidth)) {
306 QWidget *par = page->parentWidget();
307 int parentHeight = (
Q_NULLPTR == par) ? pageSize.height() : par->height();
308 int parentWidth = (
Q_NULLPTR == par) ? totalWidth : par->width();
309 m_sizeHint = QSize(parentWidth, parentHeight);
321 QList<QWidget *> showWidgets, hideWidgets;
327 if (item.isEmpty()) {
328 hideWidgets << item.m_group;
329 if (item.m_separator) {
330 hideWidgets << item.m_separator;
335 item.m_group->setGeometry(item.m_groupWillGeometry);
336 showWidgets << item.m_group;
337 if (item.m_separator) {
338 item.m_separator->setGeometry(item.m_separatorWillGeometry);
339 showWidgets << item.m_separator;
341#ifdef QX_RIBBON_DEBUG_HELP_DRAW
342 qDebug() <<
"RibbonPagePrivate::doItemLayout() =";
343 qDebug() <<
"\r\n group:" << item.m_group->windowTitle()
344 <<
"\r\n group geo:" << item.m_groupWillGeometry
345 <<
"\r\n sep geo:" << item.m_separatorWillGeometry;
359 for (QWidget *w : std::as_const(showWidgets)) {
362 for (QWidget *w : std::as_const(hideWidgets)) {
372 if (totalWidth > pageWidth) {
374 QPoint numPixels =
event->pixelDelta();
375 QPoint numDegrees =
event->angleDelta() / 8;
380 if (!numPixels.isNull()) {
382 scrollpix = numPixels.y() / 4;
383 }
else if (!numDegrees.isNull()) {
385 scrollpix = numDegrees.y();
389 if (tmp < (pageWidth - totalWidth)) {
390 tmp = pageWidth - totalWidth;
413 if (totalWidth > pageWidth) {
436 if (totalWidth > pageWidth) {
444 if (tmp < (pageWidth - totalWidth)) {
445 tmp = pageWidth - totalWidth;
460 setAutoFillBackground(
true);
477 return windowTitle();
482 setWindowTitle(
title);
493 return d->m_groupLayoutMode;
499 d->setGroupLayoutMode(m);
513 return d->addGroup(
title);
535 return d->insertGroup(index,
title);
546 return d->m_itemList.value(index).m_group;
559 if (i.m_group->windowTitle() ==
title) {
577 if (i.m_group->objectName() == objname) {
595 for (
int i = 0; i < c; ++i) {
596 if (d->m_itemList[i].m_group ==
group) {
618 if (from < 0 || from >= c || to < 0 || to >= c) {
622 d->m_itemList.move(from, to);
623 d->updateItemGeometry();
629 return d->takeGroup(
group);
650 return d->removeGroup(
group);
671 if (
group->parent() ==
this) {
680 return d->groupList();
690 QPalette p = palette();
691 p.setBrush(QPalette::Window, brush);
698 return d->m_sizeHint;
708 return d->m_isPageContext;
714 return d->m_itemList.size();
720 return d->m_isCanCustomize;
726 d->m_isCanCustomize = b;
732 return d->m_ribbonBar;
745 d->updateItemGeometry();
767 case QEvent::LayoutRequest: {
768 d->updateItemGeometry();
774 return QWidget::event(e);
780 QWidget::resizeEvent(e);
781 d->updateItemGeometry();
787 d->doWheelEvent(
event);
790void RibbonPage::setRibbonBar(
RibbonBar *bar)
793 d->m_ribbonBar = bar;
RibbonBar 继承 QMenuBar, 在 RibbonWindow 中直接替换了原来的 QMenuBar
group 用于对 ribbon 页窗口中的控件进行分组
void setGroupLayoutMode(GroupLayoutMode mode)
virtual QSize sizeHint() const override
bool isExpanding() const
判断此group是否为(水平)扩展模式
void updateItemGeometry()
RibbonSeparator * m_separator
bool m_isLeftScrollBtnShow
QList< RibbonGroup * > groupList() const
void updateItemGeometry()
virtual ~RibbonPagePrivate()
int totalSizeHintWidth() const
RibbonGroup::GroupLayoutMode m_groupLayoutMode
RibbonGroup * insertGroup(int index, const QString &title)
void doWheelEvent(QWheelEvent *event)
QList< RibbonPageItem > m_itemList
void onLeftScrollButtonClicked()
QSize pageContentSize() const
QMargins m_contentsMargins
RibbonGroup * addGroup(const QString &title)
RibbonPageScrollButton * m_leftScrollBtn
bool takeGroup(RibbonGroup *group)
bool m_isRightScrollBtnShow
RibbonPageScrollButton * m_rightScrollBtn
void onRightScrollButtonClicked()
void setGroupLayoutMode(RibbonGroup::GroupLayoutMode m)
设置group的模式
bool removeGroup(RibbonGroup *group)
bool removeGroup(RibbonGroup *group)
移除Group,Page会直接回收RibbonGroup内存
void markIsPageContext(bool isPageContext=true)
标记这个是上下文标签
RibbonBar * ribbonBar() const
bool takeGroup(RibbonGroup *group)
QSize sizeHint() const override
bool isPageContext() const
如果是ContextPage,此函数返回true
RibbonGroup * group(int index) const
通过索引找到group,如果超过索引范围,会返回Q_NULLPTR
void moveGroup(int from, int to)
移动一个Group从from index到to index
void updateItemGeometry()
刷新page的布局,适用于改变ribbon的模式之后调用
RibbonGroup * insertGroup(int index, const QString &title)
新建一个group,并插入到index位置
RibbonGroup::GroupLayoutMode groupLayoutMode() const
void setBackgroundBrush(const QBrush &brush)
RibbonGroup * groupByName(const QString &title) const
通过名字查找group
int groupIndex(RibbonGroup *group) const
查找group对应的索引
QList< RibbonGroup * > groups() const
RibbonGroup * groupByObjectName(const QString &objname) const
通过ObjectName查找group
void resizeEvent(QResizeEvent *e) override
QList< RibbonGroup * > groupList() const
bool isCanCustomize() const
void setPageName(const QString &title)
void setTitle(const QString &title)
void setGroupLayoutMode(RibbonGroup::GroupLayoutMode m)
bool event(QEvent *e) override
RibbonGroup * addGroup(const QString &title)
添加group
RibbonPage(QWidget *parent=Q_NULLPTR)
void setCanCustomize(bool b)
void wheelEvent(QWheelEvent *event) override
#define QX_INIT_PRIVATE(Class)
#define Q_NULLPTR
Copyleft (C) 2025 maminjie canpool@163.com SPDX-License-Identifier: MulanPSL-2.0
#define QX_FINI_PRIVATE()
#define QX_RIBBON_END_NAMESPACE
#define QX_RIBBON_BEGIN_NAMESPACE