From 1c45a010df770abad578316fa0fc987a80930a79 Mon Sep 17 00:00:00 2001 From: czyt1988 Date: Mon, 11 Dec 2023 23:43:31 +0800 Subject: [PATCH 01/16] =?UTF-8?q?=E4=B8=80=E4=BA=9B=E7=BB=86=E8=8A=82?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修正quickaccessbar的尺寸在刚启动时刷新的问题 调整了一个接口名字paintBackground->paintTabbarBaseLine --- src/SARibbonBar/SARibbonBar.cpp | 74 ++++++++------------ src/SARibbonBar/SARibbonBar.h | 2 +- src/SARibbonBar/SARibbonCtrlContainer.cpp | 11 ++- src/SARibbonBar/SARibbonCtrlContainer.h | 1 + src/SARibbonBar/SARibbonPannel.cpp | 2 +- src/SARibbonBar/SARibbonToolButton.cpp | 4 +- src/example/MainWindowExample/mainwindow.cpp | 14 ++-- src/example/WidgetWithRibbon/Widget.cpp | 5 +- 8 files changed, 54 insertions(+), 59 deletions(-) diff --git a/src/SARibbonBar/SARibbonBar.cpp b/src/SARibbonBar/SARibbonBar.cpp index 124c80d8..1fcf543d 100644 --- a/src/SARibbonBar/SARibbonBar.cpp +++ b/src/SARibbonBar/SARibbonBar.cpp @@ -242,6 +242,7 @@ class SARibbonBar::PrivateData SARibbonBar::SARibbonBar(QWidget* parent) : QMenuBar(parent), d_ptr(new SARibbonBar::PrivateData(this)) { d_ptr->init(); + ensurePolished(); setNativeMenuBar(false); // #ifdef Q_OS_MACOS // setNativeMenuBar(false); @@ -1395,6 +1396,13 @@ bool SARibbonBar::isTitleVisible() const void SARibbonBar::setEnableUserDefineAccessBarIconSize(bool on) { d_ptr->mEnableUserDefineAccessBarIconSize = on; + if (!(d_ptr->mEnableUserDefineAccessBarIconSize)) { //允许用户自定义AccessBar的IconSize就不进入此条件重置大小 + // 变更iconsize + QSize btnIconSize = PrivateData::calcIconSizeByHeight(titleBarHeight()); + if (btnIconSize != d_ptr->mQuickAccessBar->iconSize()) { + d_ptr->mQuickAccessBar->setIconSize(btnIconSize); + } + } } /** @@ -1418,6 +1426,13 @@ bool SARibbonBar::isEnableUserDefineAccessBarIconSize() const void SARibbonBar::setEnableUserDefineRightBarIconSize(bool on) { d_ptr->mEnableUserDefineRightBarIconSize = on; + // 变更iconsize + if (!(d_ptr->mEnableUserDefineRightBarIconSize)) { + QSize btnIconSize = PrivateData::calcIconSizeByHeight(titleBarHeight()); + if (btnIconSize != d_ptr->mRightButtonGroup->iconSize()) { + d_ptr->mRightButtonGroup->setIconSize(btnIconSize); + } + } } /** @@ -1561,6 +1576,7 @@ void SARibbonBar::updateCategoryTitleToTabName() } } } + repaint(); } void SARibbonBar::paintEvent(QPaintEvent* e) @@ -1584,11 +1600,11 @@ void SARibbonBar::paintInNormalStyle() QPainter p(this); //! - paintBackground(p); + paintTabbarBaseLine(p); //! 显示上下文标签 p.save(); QList< _SAContextCategoryManagerData > contextCategoryDataList = d_ptr->mCurrentShowingContextCategory; - bool isCurrentSelectContextCategoryPage = false; + // bool isCurrentSelectContextCategoryPage = false; QPoint contextCategoryRegion(width(), -1); QMargins border = contentsMargins(); @@ -1615,16 +1631,16 @@ void SARibbonBar::paintInNormalStyle() contextCategoryRegion.setY(contextTitleRect.right()); } } - isCurrentSelectContextCategoryPage = indexs.contains(d_ptr->mRibbonTabBar->currentIndex()); - if (isCurrentSelectContextCategoryPage) { - QPen pen; - pen.setColor(clr); - pen.setWidth(1); - p.setPen(pen); - p.setBrush(Qt::NoBrush); - p.drawRect(d_ptr->mStackedContainerWidget->geometry()); - isCurrentSelectContextCategoryPage = false; - } + // isCurrentSelectContextCategoryPage = indexs.contains(d_ptr->mRibbonTabBar->currentIndex()); + // if (isCurrentSelectContextCategoryPage) { + // QPen pen; + // pen.setColor(clr); + // pen.setWidth(1); + // p.setPen(pen); + // p.setBrush(Qt::NoBrush); + // p.drawRect(d_ptr->mStackedContainerWidget->geometry()); + // isCurrentSelectContextCategoryPage = false; + // } } p.restore(); //! 显示标题等 @@ -1667,7 +1683,7 @@ void SARibbonBar::paintInWpsLiteStyle() { QPainter p(this); //! - paintBackground(p); + paintTabbarBaseLine(p); //! 显示上下文标签 p.save(); QList< _SAContextCategoryManagerData > contextCategoryDataList = d_ptr->mCurrentShowingContextCategory; @@ -1885,14 +1901,7 @@ void SARibbonBar::resizeInOfficeStyle() } QSize quickAccessBarSize = d_ptr->mQuickAccessBar->sizeHint(); // 上下留1px的边线 - d_ptr->mQuickAccessBar->setGeometry(x, y + 1, quickAccessBarSize.width(), validTitleBarHeight - 2); - if (!(d_ptr->mEnableUserDefineAccessBarIconSize)) { //允许用户自定义AccessBar的IconSize就不进入此条件重置大小 - // 变更iconsize - QSize btnIconSize = PrivateData::calcIconSizeByHeight(validTitleBarHeight - 2); - if (btnIconSize != d_ptr->mQuickAccessBar->iconSize()) { - d_ptr->mQuickAccessBar->setIconSize(btnIconSize); - } - } + d_ptr->mQuickAccessBar->setGeometry(x, y + 1, quickAccessBarSize.width(), validTitleBarHeight); } } // 第二行,开始布局applicationButton,tabbar,tabBarRightSizeButtonGroupWidget,TopRightCorner @@ -1933,13 +1942,6 @@ void SARibbonBar::resizeInOfficeStyle() endX -= wSize.width(); // 上下留1px的边线 d_ptr->mRightButtonGroup->setGeometry(endX, y + 1, wSize.width(), tabH - 2); - // 变更iconsize - if (!(d_ptr->mEnableUserDefineRightBarIconSize)) { - QSize btnIconSize = PrivateData::calcIconSizeByHeight(tabH - 2); - if (btnIconSize != d_ptr->mRightButtonGroup->iconSize()) { - d_ptr->mRightButtonGroup->setIconSize(btnIconSize); - } - } } // 最后确定tabbar宽度 int tabBarAllowedWidth = endX - x; @@ -1994,13 +1996,6 @@ void SARibbonBar::resizeInWpsLiteStyle() endX -= wSize.width(); // 上下留1px的边线 d_ptr->mRightButtonGroup->setGeometry(endX, y + 1, wSize.width(), validTitleBarHeight - 2); - // 变更iconsize - if (!(d_ptr->mEnableUserDefineRightBarIconSize)) { - QSize btnIconSize = PrivateData::calcIconSizeByHeight(validTitleBarHeight - 2); - if (btnIconSize != d_ptr->mRightButtonGroup->iconSize()) { - d_ptr->mRightButtonGroup->setIconSize(btnIconSize); - } - } } // quick access bar定位 if (d_ptr->mQuickAccessBar) { @@ -2009,13 +2004,6 @@ void SARibbonBar::resizeInWpsLiteStyle() endX -= quickAccessBarSize.width(); // 上下留1px的边线 d_ptr->mQuickAccessBar->setGeometry(endX, y + 1, quickAccessBarSize.width(), validTitleBarHeight - 2); - // 变更iconsize - if (!(d_ptr->mEnableUserDefineAccessBarIconSize)) { //允许用户自定义AccessBar的IconSize就不进入此条件重置大小 - QSize btnIconSize = PrivateData::calcIconSizeByHeight(validTitleBarHeight - 2); - if (btnIconSize != d_ptr->mQuickAccessBar->iconSize()) { - d_ptr->mQuickAccessBar->setIconSize(btnIconSize); - } - } } } // cornerWidget - TopLeftCorner @@ -2077,7 +2065,7 @@ void SARibbonBar::resizeInWpsLiteStyle() resizeStackedContainerWidget(); } -void SARibbonBar::paintBackground(QPainter& painter) +void SARibbonBar::paintTabbarBaseLine(QPainter& painter) { painter.save(); // 在tabbar下绘制一条线 diff --git a/src/SARibbonBar/SARibbonBar.h b/src/SARibbonBar/SARibbonBar.h index be03b26b..f0a974a0 100644 --- a/src/SARibbonBar/SARibbonBar.h +++ b/src/SARibbonBar/SARibbonBar.h @@ -367,7 +367,7 @@ protected slots: virtual void resizeEvent(QResizeEvent* e) Q_DECL_OVERRIDE; virtual void moveEvent(QMoveEvent* e) Q_DECL_OVERRIDE; virtual void changeEvent(QEvent* e) Q_DECL_OVERRIDE; - virtual void paintBackground(QPainter& painter); + virtual void paintTabbarBaseLine(QPainter& painter); virtual void paintWindowTitle(QPainter& painter, const QString& title, const QRect& titleRegion); virtual void paintContextCategoryTab(QPainter& painter, const QString& title, QRect contextRect, const QColor& color); }; diff --git a/src/SARibbonBar/SARibbonCtrlContainer.cpp b/src/SARibbonBar/SARibbonCtrlContainer.cpp index 67721ea4..dcc2f705 100644 --- a/src/SARibbonBar/SARibbonCtrlContainer.cpp +++ b/src/SARibbonBar/SARibbonCtrlContainer.cpp @@ -5,7 +5,6 @@ #include #include #include -#include "SARibbonDrawHelper.h" /** * @brief The SARibbonCtrlContainerPrivate class @@ -117,8 +116,14 @@ bool SARibbonCtrlContainer::hasContainerWidget() const */ void SARibbonCtrlContainer::setIcon(const QIcon& i) { - d_ptr->icon = i; - d_ptr->labelPixmap->setPixmap(i.pixmap(d_ptr->iconSize)); + d_ptr->icon = i; + QPixmap pixmap = i.pixmap(d_ptr->iconSize); + d_ptr->labelPixmap->setPixmap(pixmap); +} + +void SARibbonCtrlContainer::setIcon(const QPixmap& pixmap) +{ + d_ptr->labelPixmap->setPixmap(pixmap); } /** diff --git a/src/SARibbonBar/SARibbonCtrlContainer.h b/src/SARibbonBar/SARibbonCtrlContainer.h index d8ea31d2..4f98e583 100644 --- a/src/SARibbonBar/SARibbonCtrlContainer.h +++ b/src/SARibbonBar/SARibbonCtrlContainer.h @@ -26,6 +26,7 @@ class SA_RIBBON_EXPORT SARibbonCtrlContainer : public QWidget bool hasContainerWidget() const; //图标 void setIcon(const QIcon& i); + void setIcon(const QPixmap& pixmap); QIcon getIcon() const; //图标 void setText(const QString& t); diff --git a/src/SARibbonBar/SARibbonPannel.cpp b/src/SARibbonBar/SARibbonPannel.cpp index 6bbe1b74..cba6b92c 100644 --- a/src/SARibbonBar/SARibbonPannel.cpp +++ b/src/SARibbonBar/SARibbonPannel.cpp @@ -728,7 +728,7 @@ void SARibbonPannel::resizeEvent(QResizeEvent* event) if (ThreeRowMode == pannelLayoutMode()) { d_ptr->m_optionActionButton->move(width() - d_ptr->m_optionActionButton->width() - 2, height() - titleHeight() - + (titleHeight() - d_ptr->m_optionActionButton->height()) / 2); + + (titleHeight() - d_ptr->m_optionActionButton->height()) / 2); } else { d_ptr->m_optionActionButton->move(width() - d_ptr->m_optionActionButton->width(), height() - d_ptr->m_optionActionButton->height()); diff --git a/src/SARibbonBar/SARibbonToolButton.cpp b/src/SARibbonBar/SARibbonToolButton.cpp index 6cfe0868..5e494eda 100644 --- a/src/SARibbonBar/SARibbonToolButton.cpp +++ b/src/SARibbonBar/SARibbonToolButton.cpp @@ -484,7 +484,7 @@ QSize SARibbonToolButton::PrivateData::calcLargeButtonSizeHint(const QStyleOptio int h = opt.fontMetrics.lineSpacing() * 4.5; // 3*1.5 int minW = h * 0.75; //最小宽度,在pannel里面的按钮,最小宽度要和icon适应 if (mDrawIconRect.isValid()) { - minW = mDrawIconRect.height(); + minW = mDrawIconRect.width(); } if (SARibbonPannel* pannel = qobject_cast< SARibbonPannel* >(q_ptr->parent())) { //对于建立在SARibbonPannel的基础上的大按钮,把高度设置为SARibbonPannel计算的大按钮高度 @@ -539,7 +539,6 @@ int SARibbonToolButton::PrivateData::estimateLargeButtonTextWidth(int buttonHeig float widthHeightRatio, int maxTrycount) { - QSize textSize; int space = SA_FONTMETRICS_WIDTH(fm, (QLatin1Char(' '))) * 2; int hintMaxWidth = buttonHeight * widthHeightRatio; ///< 建议的宽度 @@ -1064,7 +1063,6 @@ void SARibbonToolButton::updateRect() { QStyleOptionToolButton opt; initStyleOption(&opt); - // d_ptr->updateSizeHint(opt); d_ptr->updateDrawRect(opt); } diff --git a/src/example/MainWindowExample/mainwindow.cpp b/src/example/MainWindowExample/mainwindow.cpp index b7fc42c9..19b3ff98 100644 --- a/src/example/MainWindowExample/mainwindow.cpp +++ b/src/example/MainWindowExample/mainwindow.cpp @@ -179,7 +179,7 @@ void MainWindow::createRibbonApplicationButton() btn = new SARibbonApplicationButton(this); ribbon->setApplicationButton(btn); } - ribbon->applicationButton()->setText((" File ")); // 文字两边留有间距,好看一点 + ribbon->applicationButton()->setText((" File ")); // 文字两边留有间距,好看一点 // cn: SARibbonMenu和QMenu的操作是一样的 // en: The operations of SARibbonMenu and QMenu are the same if (!mMenuApplicationBtn) { @@ -217,14 +217,14 @@ void MainWindow::onStyleClicked(int id) switch (ribbonStyle) { case SARibbonBar::RibbonStyleLooseThreeRow: mTextedit->append( - tr("\nchange ribbon style to office style,The standard office style text display is line wrapped, " - "and you can also control whether it wrap through SARibbonToolButton::setEnableWordWrap")); // cn:标准的office样式的文字显示是换行的,你也可以通过SARibbonToolButton::setEnableWordWrap来控制它是否换行 + tr("\nchange ribbon style to office style,The standard office style text display is line wrapped, " + "and you can also control whether it wrap through SARibbonToolButton::setEnableWordWrap")); // cn:标准的office样式的文字显示是换行的,你也可以通过SARibbonToolButton::setEnableWordWrap来控制它是否换行 mTextedit->append(tr("ribbonBar()->setRibbonStyle(SARibbonBar::OfficeStyle);")); break; case SARibbonBar::RibbonStyleLooseTwoRow: mTextedit->append( - tr("\nchange ribbon style to office style 2 row,All text in 2-line mode does not wrap, and you " - "can also control whether it wraps through SARibbonToolButton: setEnableWordWrap")); // cn:所有2行模式的文字都是不换行的,你也可以通过SARibbonToolButton::setEnableWordWrap来控制它是否换行 + tr("\nchange ribbon style to office style 2 row,All text in 2-line mode does not wrap, and you " + "can also control whether it wraps through SARibbonToolButton: setEnableWordWrap")); // cn:所有2行模式的文字都是不换行的,你也可以通过SARibbonToolButton::setEnableWordWrap来控制它是否换行 mTextedit->append(tr("ribbonBar()->setRibbonStyle(SARibbonBar::OfficeStyleTwoRow);")); break; case SARibbonBar::RibbonStyleCompactThreeRow: @@ -298,7 +298,7 @@ void MainWindow::onActionHelpTriggered() "\n Author:czy" "\n Email:czy.t@163.com" "\n ===============") - .arg(SARibbonBar::versionString())); + .arg(SARibbonBar::versionString())); } void MainWindow::onActionRemoveAppBtnTriggered(bool b) @@ -430,7 +430,7 @@ void MainWindow::onColorButtonColorClicked(const QColor& c, bool on) void MainWindow::onRibbonThemeComboBoxCurrentIndexChanged(int index) { SARibbonMainWindow::RibbonTheme t = static_cast< SARibbonMainWindow::RibbonTheme >( - mComboboxRibbonTheme->itemData(index).toInt()); + mComboboxRibbonTheme->itemData(index).toInt()); setRibbonTheme(t); } diff --git a/src/example/WidgetWithRibbon/Widget.cpp b/src/example/WidgetWithRibbon/Widget.cpp index b2d88e41..64b353a3 100644 --- a/src/example/WidgetWithRibbon/Widget.cpp +++ b/src/example/WidgetWithRibbon/Widget.cpp @@ -38,7 +38,10 @@ void Widget::buildRibbon(SARibbonBar* bar) page1->setCategoryName("page1"); SARibbonPannel* pannel1 = new SARibbonPannel("pannel1", page1); page1->addPannel(pannel1); - pannel1->addLargeAction(createAction("save", ":/icon/icon/save.svg")); + QAction* act = createAction(" save ", ":/icon/icon/save.svg"); + act->setIconText(" save "); + pannel1->addLargeAction(act); + pannel1->addLargeAction(createAction("open", ":/icon/icon/folder-star.svg")); pannel1->addSmallAction(createAction("action1", ":/icon/icon/action.svg")); pannel1->addSmallAction(createAction("action2", ":/icon/icon/action2.svg")); From 33de0e9381374671b5811d5386f0447d9fd235e9 Mon Sep 17 00:00:00 2001 From: czyt1988 Date: Thu, 14 Dec 2023 17:26:26 +0800 Subject: [PATCH 02/16] =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=B0=BA=E5=AF=B8?= =?UTF-8?q?=E8=AE=A1=E7=AE=97=E7=AD=96=E7=95=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SARibbonBar/SARibbonBar.cpp | 480 +++++++++++++------ src/SARibbonBar/SARibbonBar.h | 51 +- src/SARibbonBar/SARibbonMainWindow.cpp | 1 - src/SARibbonBar/SARibbonStyleOption.h | 16 +- src/SARibbonBar/SARibbonToolButton.cpp | 190 ++++---- src/SARibbonBar/SAWindowButtonGroup.cpp | 26 +- src/SARibbonBar/SAWindowButtonGroup.h | 8 +- src/example/MainWindowExample/main.cpp | 39 +- src/example/MainWindowExample/mainwindow.cpp | 4 - 9 files changed, 479 insertions(+), 336 deletions(-) diff --git a/src/SARibbonBar/SARibbonBar.cpp b/src/SARibbonBar/SARibbonBar.cpp index 1d66b3f9..97d60e4e 100644 --- a/src/SARibbonBar/SARibbonBar.cpp +++ b/src/SARibbonBar/SARibbonBar.cpp @@ -79,6 +79,8 @@ class SARibbonBar::PrivateData bool mEnableUserDefineAccessBarIconSize; ///< 允许用户自定义AccessBar的IconSize bool mEnableUserDefineRightBarIconSize; ///< 允许用户自定义RightBar的IconSize SARibbonAlignment mRibbonAlignment; ///< 对齐方式 + int mTitleBarHeight; ///< 标题栏高度 + int mMainBarHeight; ///< 固定高度 public: PrivateData(SARibbonBar* par) : q_ptr(par) @@ -99,137 +101,246 @@ class SARibbonBar::PrivateData , mEnableUserDefineAccessBarIconSize(false) , mEnableUserDefineRightBarIconSize(false) , mRibbonAlignment(SARibbonAlignment::AlignLeft) + , mTitleBarHeight(30) + , mMainBarHeight(200) { mContextCategoryColorList = SARibbonBar::getDefaultContextCategoryColorList(); } - void init() - { - mApplicationButton = RibbonSubElementDelegate->createRibbonApplicationButton(q_ptr); - q_ptr->connect(mApplicationButton, &QAbstractButton::clicked, q_ptr, &SARibbonBar::applicationButtonClicked); - mRibbonTabBar = RibbonSubElementDelegate->createRibbonTabBar(q_ptr); - mRibbonTabBar->setObjectName(QStringLiteral("objSARibbonTabBar")); - mRibbonTabBar->setDrawBase(false); - q_ptr->connect(mRibbonTabBar, &QTabBar::currentChanged, q_ptr, &SARibbonBar::onCurrentRibbonTabChanged); - q_ptr->connect(mRibbonTabBar, &QTabBar::tabBarClicked, q_ptr, &SARibbonBar::onCurrentRibbonTabClicked); - q_ptr->connect(mRibbonTabBar, &QTabBar::tabBarDoubleClicked, q_ptr, &SARibbonBar::onCurrentRibbonTabDoubleClicked); - q_ptr->connect(mRibbonTabBar, &QTabBar::tabMoved, q_ptr, &SARibbonBar::onTabMoved); - // - mStackedContainerWidget = RibbonSubElementDelegate->createRibbonStackedWidget(q_ptr); - mStackedContainerWidget->setObjectName(QStringLiteral("objSAStackedContainerWidget")); - mStackedContainerWidget->connect(mStackedContainerWidget, &SARibbonStackedWidget::hidWindow, q_ptr, &SARibbonBar::onStackWidgetHided); - mStackedContainerWidget->installEventFilter(q_ptr); - setNormalMode(); - // - mQuickAccessBar = RibbonSubElementDelegate->createQuickAccessBar(q_ptr); - mQuickAccessBar->setObjectName(QStringLiteral("objSARibbonQuickAccessBar")); - mQuickAccessBar->setIcon(q_ptr->windowIcon()); - // - mRightButtonGroup = RibbonSubElementDelegate->craeteButtonGroupWidget(q_ptr); - mRightButtonGroup->setFrameShape(QFrame::NoFrame); - } - - void setApplicationButton(QAbstractButton* btn) - { - if (mApplicationButton) { - delete mApplicationButton; - } - if (btn) { - if (btn->parent() != q_ptr) { - btn->setParent(q_ptr); - } - btn->move(0, q_ptr->titleBarHeight()); - q_ptr->connect(btn, &QAbstractButton::clicked, q_ptr, &SARibbonBar::applicationButtonClicked); - } - mApplicationButton = btn; + // 计算tabbar高度 + int calcTabBarHeight(const QFontMetrics& fm); + // 根据字体信息计算标题栏高度 + int calcTitleBarHeight(const QFontMetrics& fm); + // 计算tabbar高度 + int calcMainBarHeight(SARibbonBar::RibbonStyle s, const QFontMetrics& fm, int tabH, int titleH); + // + int calcMinimumModeMainBarHeight() const; + + void resetSize(); + + void init(); + + void setApplicationButton(QAbstractButton* btn); + + bool isContainContextCategoryInList(SARibbonContextCategory* contextCategory); + + void setHideMode(); + + void setNormalMode(); + + QColor getContextCategoryColor(); + + void updateTabData(); + /** + * @brief 通过输入高度计算iconSize + * @param h + * @return + */ + static QSize calcIconSizeByHeight(int h); +}; + +int SARibbonBar::PrivateData::calcTabBarHeight(const QFontMetrics& fm) +{ + int r = fm.height() * 1.5; + if (r < 20) { + r = 20; } + return r; +} - bool isContainContextCategoryInList(SARibbonContextCategory* contextCategory) - { - for (int i = 0; i < mCurrentShowingContextCategory.size(); ++i) { - if (mCurrentShowingContextCategory[ i ] == contextCategory) { - return (true); - } - } - return (false); +int SARibbonBar::PrivateData::calcTitleBarHeight(const QFontMetrics& fm) +{ + int r = fm.height() * 1.8; + if (r < 20) { + r = 20; } + return r; +} - void setHideMode() - { - mCurrentRibbonMode = SARibbonBar::MinimumRibbonMode; - this->mStackedContainerWidget->setPopupMode(); - this->mStackedContainerWidget->setFocusPolicy(Qt::NoFocus); - this->mStackedContainerWidget->clearFocus(); - this->mRibbonTabBar->setFocus(); - this->mStackedContainerWidget->hide(); - q_ptr->setFixedHeight(mRibbonTabBar->geometry().bottom()); +int SARibbonBar::PrivateData::calcMainBarHeight(SARibbonBar::RibbonStyle s, const QFontMetrics& fm, int tabH, int titleH) +{ + int textH = fm.height(); + int pannelTitleHeight = SARibbonPannel::pannelTitleHeight(); + QMargins pannelMargins = SARibbonPannelLayout::pannelContentsMargins(); + int pannelHPadding = pannelMargins.bottom() + pannelMargins.top(); + int mainbarH = 200; + switch (s) { + case SARibbonBar::RibbonStyleLooseThreeRow: { + mainbarH = tabH + titleH + (textH * 1.5) * 3 + pannelTitleHeight + pannelHPadding; + } break; + case SARibbonBar::RibbonStyleCompactThreeRow: { + // 标题栏是存在,只是把bar画在标题栏上,相当于没有bar + mainbarH = titleH + (textH * 1.5) * 3 + pannelTitleHeight + pannelHPadding; + } break; + case SARibbonBar::RibbonStyleLooseTwoRow: { + mainbarH = tabH + titleH + (textH * 1.5) * 2 + pannelTitleHeight + pannelHPadding; + } break; + case SARibbonBar::RibbonStyleCompactTwoRow: { + mainbarH = titleH + (textH * 1.5) * 2 + pannelTitleHeight + pannelHPadding; + } break; + default: { + qWarning() << "unknow SARibbonBar::RibbonStyle:" << s; } + } + return mainbarH; +} - void setNormalMode() - { - mCurrentRibbonMode = SARibbonBar::NormalRibbonMode; - this->mStackedContainerWidget->setNormalMode(); - this->mStackedContainerWidget->setFocus(); - this->mStackedContainerWidget->show(); +int SARibbonBar::PrivateData::calcMinimumModeMainBarHeight() const +{ + switch (mRibbonStyle) { + case RibbonStyleLooseThreeRow: + case RibbonStyleLooseTwoRow: { + return mTitleBarHeight + mRibbonTabBar->height(); + } + case RibbonStyleCompactThreeRow: + case RibbonStyleCompactTwoRow: { + return mTitleBarHeight; } + default: + break; + } + return mTitleBarHeight + mRibbonTabBar->height(); +} - QColor getContextCategoryColor() - { - if (mContextCategoryColorList.isEmpty()) { - mContextCategoryColorListIndex = -1; - return (QColor()); +void SARibbonBar::PrivateData::resetSize() +{ + auto fm = q_ptr->fontMetrics(); + mTitleBarHeight = calcTitleBarHeight(fm); + int tabH = calcTabBarHeight(fm); + mRibbonTabBar->setFixedHeight(tabH); + mMainBarHeight = calcMainBarHeight(q_ptr->currentRibbonStyle(), fm, tabH, mTitleBarHeight); + if (MinimumRibbonMode == mCurrentRibbonMode) { + // 处于最小模式下时,bar的高度为tabbar的bottom,这个调整必须在resize event之后 + q_ptr->setFixedHeight(calcMinimumModeMainBarHeight()); + } else { + q_ptr->setFixedHeight(mMainBarHeight); + } +} + +void SARibbonBar::PrivateData::init() +{ + mApplicationButton = RibbonSubElementDelegate->createRibbonApplicationButton(q_ptr); + q_ptr->connect(mApplicationButton, &QAbstractButton::clicked, q_ptr, &SARibbonBar::applicationButtonClicked); + mRibbonTabBar = RibbonSubElementDelegate->createRibbonTabBar(q_ptr); + mRibbonTabBar->setObjectName(QStringLiteral("objSARibbonTabBar")); + mRibbonTabBar->setDrawBase(false); + q_ptr->connect(mRibbonTabBar, &QTabBar::currentChanged, q_ptr, &SARibbonBar::onCurrentRibbonTabChanged); + q_ptr->connect(mRibbonTabBar, &QTabBar::tabBarClicked, q_ptr, &SARibbonBar::onCurrentRibbonTabClicked); + q_ptr->connect(mRibbonTabBar, &QTabBar::tabBarDoubleClicked, q_ptr, &SARibbonBar::onCurrentRibbonTabDoubleClicked); + q_ptr->connect(mRibbonTabBar, &QTabBar::tabMoved, q_ptr, &SARibbonBar::onTabMoved); + // + mStackedContainerWidget = RibbonSubElementDelegate->createRibbonStackedWidget(q_ptr); + mStackedContainerWidget->setObjectName(QStringLiteral("objSAStackedContainerWidget")); + mStackedContainerWidget->connect(mStackedContainerWidget, &SARibbonStackedWidget::hidWindow, q_ptr, &SARibbonBar::onStackWidgetHided); + mStackedContainerWidget->installEventFilter(q_ptr); + // + mQuickAccessBar = RibbonSubElementDelegate->createQuickAccessBar(q_ptr); + mQuickAccessBar->setObjectName(QStringLiteral("objSARibbonQuickAccessBar")); + mQuickAccessBar->setIcon(q_ptr->windowIcon()); + // + mRightButtonGroup = RibbonSubElementDelegate->craeteButtonGroupWidget(q_ptr); + mRightButtonGroup->setFrameShape(QFrame::NoFrame); + // + setNormalMode(); +} + +void SARibbonBar::PrivateData::setApplicationButton(QAbstractButton* btn) +{ + if (mApplicationButton) { + delete mApplicationButton; + } + if (btn) { + if (btn->parent() != q_ptr) { + btn->setParent(q_ptr); } - ++mContextCategoryColorListIndex; - if ((mContextCategoryColorListIndex >= mContextCategoryColorList.size()) || (mContextCategoryColorListIndex < 0)) { - mContextCategoryColorListIndex = 0; + btn->move(0, q_ptr->titleBarHeight()); + q_ptr->connect(btn, &QAbstractButton::clicked, q_ptr, &SARibbonBar::applicationButtonClicked); + } + mApplicationButton = btn; +} + +bool SARibbonBar::PrivateData::isContainContextCategoryInList(SARibbonContextCategory* contextCategory) +{ + for (int i = 0; i < mCurrentShowingContextCategory.size(); ++i) { + if (mCurrentShowingContextCategory[ i ] == contextCategory) { + return (true); } - return (mContextCategoryColorList.at(mContextCategoryColorListIndex)); } + return (false); +} - void updateTabData() - { - int tabcount = mRibbonTabBar->count(); - - for (int i = 0; i < tabcount; ++i) { - QVariant var = mRibbonTabBar->tabData(i); - if (var.isValid()) { - _SARibbonTabData p = var.value< _SARibbonTabData >(); - p.index = i; - mRibbonTabBar->setTabData(i, QVariant::fromValue(p)); - } +void SARibbonBar::PrivateData::setHideMode() +{ + mCurrentRibbonMode = SARibbonBar::MinimumRibbonMode; + this->mStackedContainerWidget->setPopupMode(); + this->mStackedContainerWidget->setFocusPolicy(Qt::NoFocus); + this->mStackedContainerWidget->clearFocus(); + this->mRibbonTabBar->setFocus(); + this->mStackedContainerWidget->hide(); + resetSize(); +} + +void SARibbonBar::PrivateData::setNormalMode() +{ + mCurrentRibbonMode = SARibbonBar::NormalRibbonMode; + this->mStackedContainerWidget->setNormalMode(); + this->mStackedContainerWidget->setFocus(); + this->mStackedContainerWidget->show(); + resetSize(); +} + +QColor SARibbonBar::PrivateData::getContextCategoryColor() +{ + if (mContextCategoryColorList.isEmpty()) { + mContextCategoryColorListIndex = -1; + return (QColor()); + } + ++mContextCategoryColorListIndex; + if ((mContextCategoryColorListIndex >= mContextCategoryColorList.size()) || (mContextCategoryColorListIndex < 0)) { + mContextCategoryColorListIndex = 0; + } + return (mContextCategoryColorList.at(mContextCategoryColorListIndex)); +} + +void SARibbonBar::PrivateData::updateTabData() +{ + int tabcount = mRibbonTabBar->count(); + + for (int i = 0; i < tabcount; ++i) { + QVariant var = mRibbonTabBar->tabData(i); + if (var.isValid()) { + _SARibbonTabData p = var.value< _SARibbonTabData >(); + p.index = i; + mRibbonTabBar->setTabData(i, QVariant::fromValue(p)); } - // 刷新完tabdata信息也要接着刷新ContextCategory信息 - for (_SAContextCategoryManagerData& cd : mCurrentShowingContextCategory) { - cd.tabPageIndex.clear(); - for (int i = 0; i < cd.contextCategory->categoryCount(); ++i) { - SARibbonCategory* category = cd.contextCategory->categoryPage(i); - for (int t = 0; t < tabcount; ++t) { - QVariant v = mRibbonTabBar->tabData(t); - if (v.isValid()) { - _SARibbonTabData d = v.value< _SARibbonTabData >(); - if (d.category == category) { - cd.tabPageIndex.append(t); - } - } else { - cd.tabPageIndex.append(-1); + } + // 刷新完tabdata信息也要接着刷新ContextCategory信息 + for (_SAContextCategoryManagerData& cd : mCurrentShowingContextCategory) { + cd.tabPageIndex.clear(); + for (int i = 0; i < cd.contextCategory->categoryCount(); ++i) { + SARibbonCategory* category = cd.contextCategory->categoryPage(i); + for (int t = 0; t < tabcount; ++t) { + QVariant v = mRibbonTabBar->tabData(t); + if (v.isValid()) { + _SARibbonTabData d = v.value< _SARibbonTabData >(); + if (d.category == category) { + cd.tabPageIndex.append(t); } + } else { + cd.tabPageIndex.append(-1); } } } } - /** - * @brief 通过输入高度计算iconSize - * @param h - * @return - */ - static QSize calcIconSizeByHeight(int h) - { - if (h - 8 >= 20) { - return QSize(h - 8, h - 8); - } - return QSize(h - 4, h - 4); +} + +QSize SARibbonBar::PrivateData::calcIconSizeByHeight(int h) +{ + if (h - 8 >= 20) { + return QSize(h - 8, h - 8); } -}; + return QSize(h - 4, h - 4); +} //=================================================== // SARibbonBar @@ -301,7 +412,7 @@ QList< QColor > SARibbonBar::getDefaultContextCategoryColorList() << QColor(14, 81, 167) // 蓝 << QColor(228, 0, 69) // 红 << QColor(67, 148, 0) // 绿 - ; + ; return res; } @@ -895,14 +1006,49 @@ bool SARibbonBar::haveShowMinimumModeButton() const return (nullptr != d_ptr->mMinimumCategoryButton); } +/** + @brief tabBar的高度 + @return + */ int SARibbonBar::tabBarHeight() const { - return (RibbonSubElementStyleOpt.tabBarHeight()); + return d_ptr->mRibbonTabBar->height(); +} + +/** + @brief 设置tabbar的高度 + @param h + */ +void SARibbonBar::setTabBarHeight(int h) +{ + d_ptr->mRibbonTabBar->setFixedHeight(h); } +/** + @brief 返回标题栏高度 + @sa setTitleBarHeight + @return + */ int SARibbonBar::titleBarHeight() const { - return (RibbonSubElementStyleOpt.titleBarHeight()); + return d_ptr->mTitleBarHeight; +} + +/** + @brief 设置标题栏的高度 + @sa titleBarHeight + @note 此操作会发射@ref titleBarHeightChanged 信号 + @param h + */ +void SARibbonBar::setTitleBarHeight(int h) +{ + if (d_ptr->mTitleBarHeight == h) { + return; + } + int oldHeight = d_ptr->mTitleBarHeight; + d_ptr->mTitleBarHeight = h; + updateRibbonGeometry(); + emit titleBarHeightChanged(oldHeight, h); } void SARibbonBar::onWindowTitleChanged(const QString& title) @@ -1110,11 +1256,6 @@ void SARibbonBar::synchronousCategoryLayoutMode(bool autoUpdate) c->setRibbonPannelLayoutMode(SARibbonBar::isTwoRowStyle(currentRibbonStyle()) ? SARibbonPannel::TwoRowMode : SARibbonPannel::ThreeRowMode); } - - // 根据样式调整bar的高度 - if (NormalRibbonMode == currentRibbonState()) { - setFixedHeight(mainBarHeight()); - } //! 直接给一个resizeevent,让所有刷新 if (autoUpdate) { QResizeEvent* e = new QResizeEvent(size(), QSize()); @@ -1122,19 +1263,42 @@ void SARibbonBar::synchronousCategoryLayoutMode(bool autoUpdate) } } -void SARibbonBar::activeRightButtonGroup() +/** + @brief 激活tabbar右边的按钮群 + @return 返回右边的按钮群指针 + */ +SARibbonButtonGroupWidget* SARibbonBar::activeRightButtonGroup() { if (nullptr == d_ptr->mRightButtonGroup) { d_ptr->mRightButtonGroup = RibbonSubElementDelegate->craeteButtonGroupWidget(this); d_ptr->mRightButtonGroup->setFrameShape(QFrame::NoFrame); } d_ptr->mRightButtonGroup->show(); + return d_ptr->mRightButtonGroup; } +/** + @brief 返回右边的按钮群指针 + @return 如果没有创建,返回nullptr + */ SARibbonButtonGroupWidget* SARibbonBar::rightButtonGroup() { - activeRightButtonGroup(); - return (d_ptr->mRightButtonGroup); + return d_ptr->mRightButtonGroup; +} + +/** + @brief 激活QuickAccessBar + @return + */ +SARibbonQuickAccessBar* SARibbonBar::activeQuickAccessBar() +{ + if (nullptr == d_ptr->mQuickAccessBar) { + d_ptr->mQuickAccessBar = RibbonSubElementDelegate->createQuickAccessBar(this); + d_ptr->mQuickAccessBar->setObjectName(QStringLiteral("objSARibbonQuickAccessBar")); + d_ptr->mQuickAccessBar->setIcon(windowIcon()); + } + d_ptr->mQuickAccessBar->show(); + return d_ptr->mQuickAccessBar; } SARibbonQuickAccessBar* SARibbonBar::quickAccessBar() @@ -1158,18 +1322,21 @@ void SARibbonBar::setRibbonStyle(SARibbonBar::RibbonStyle v) // 默认情况下2行模式不换行 // 如果想在两行模式换行,在调用SARibbonBar::setRibbonStyle后,再SARibbonToolButton::setEnableWordWrap(true) SARibbonToolButton::setEnableWordWrap(!isTwoRowStyle(v)); - - synchronousCategoryLayoutMode(false); //这里不急着刷新,下面会继续刷新 + d_ptr->resetSize(); + if (MinimumRibbonMode == currentRibbonState()) { + // 处于最小模式下时,bar的高度为tabbar的bottom,这个调整必须在resize event之后 + setFixedHeight(minimumModeMainBarHeight()); + } else { + setFixedHeight(mainBarHeight()); + } + synchronousCategoryLayoutMode(false); // 这里不急着刷新,下面会继续刷新 QSize oldSize = size(); QSize newSize(oldSize.width(), mainBarHeight()); QResizeEvent es(newSize, oldSize); QApplication::sendEvent(this, &es); - if (MinimumRibbonMode == currentRibbonState()) { - // 处于最小模式下时,bar的高度为tabbar的bottom,这个调整必须在resize event之后 - setFixedHeight(d_ptr->mRibbonTabBar->geometry().bottom()); - } + emit ribbonStyleChanged(d_ptr->mRibbonStyle); } @@ -1295,26 +1462,9 @@ QColor SARibbonBar::tabBarBaseLineColor() const */ void SARibbonBar::updateRibbonGeometry() { - // updateRibbonElementGeometry(); - // QList< SARibbonCategory* > categorys = categoryPages(); - // for (SARibbonCategory* c : qAsConst(categorys)) { - // c->updateItemGeometry(); - // } - // //重新调整尺寸 - // resizeAll(); - // - // auto fnUpdate = [](QWidget* w) { - // if (w) { - // if (w->layout()) { - // w->layout()->invalidate(); - // } - // w->updateGeometry(); - // w->adjustSize(); - // } - // }; - // fnUpdate(d_ptr->mQuickAccessBar); - // fnUpdate(d_ptr->mRightButtonGroup); updateGeometry(); + d_ptr->resetSize(); + QList< SARibbonCategory* > categorys = categoryPages(); for (SARibbonCategory* c : qAsConst(categorys)) { c->updateItemGeometry(); @@ -1449,7 +1599,7 @@ void SARibbonBar::setContextCategoryColorList(const QList< QColor >& cls) d_ptr->mContextCategoryColorList = getDefaultContextCategoryColorList(); } d_ptr->mContextCategoryColorListIndex = 0; - //这时需要对已经显示的contextCategoryData的颜色进行重新设置 + // 这时需要对已经显示的contextCategoryData的颜色进行重新设置 for (SARibbonContextCategory* c : d_ptr->mContextCategoryList) { c->setContextColor(d_ptr->getContextCategoryColor()); } @@ -1547,7 +1697,25 @@ int SARibbonBar::calcMinTabBarWidth() const */ int SARibbonBar::mainBarHeight() const { - return RibbonSubElementStyleOpt.ribbonBarHeight(currentRibbonStyle()); + return d_ptr->mMainBarHeight; +} + +/** + @brief 设置mainBar高度 + @param m + */ +void SARibbonBar::setMainBarHeight(int m) +{ + d_ptr->mMainBarHeight = m; +} + +/** + @brief 最小模式下的高度 + @return + */ +int SARibbonBar::minimumModeMainBarHeight() const +{ + return d_ptr->calcMinimumModeMainBarHeight(); } /** @@ -1643,7 +1811,7 @@ void SARibbonBar::paintInNormalStyle() titleRegion.setRect(d_ptr->mQuickAccessBar->geometry().right() + 1, border.top(), width() - d_ptr->mIconRightBorderPosition - border.right() - - d_ptr->mWindowButtonSize.width() - d_ptr->mQuickAccessBar->geometry().right() - 1, + - d_ptr->mWindowButtonSize.width() - d_ptr->mQuickAccessBar->geometry().right() - 1, titleBarHeight()); } else { int leftwidth = contextCategoryRegion.x() - d_ptr->mQuickAccessBar->geometry().right() - d_ptr->mIconRightBorderPosition; @@ -1893,7 +2061,7 @@ void SARibbonBar::resizeInOfficeStyle() QSize quickAccessBarSize = d_ptr->mQuickAccessBar->sizeHint(); // 上下留1px的边线 d_ptr->mQuickAccessBar->setGeometry(x, y + 1, quickAccessBarSize.width(), validTitleBarHeight - 2); - if (!(d_ptr->mEnableUserDefineAccessBarIconSize)) { //允许用户自定义AccessBar的IconSize就不进入此条件重置大小 + if (!(d_ptr->mEnableUserDefineAccessBarIconSize)) { // 允许用户自定义AccessBar的IconSize就不进入此条件重置大小 // 变更iconsize QSize btnIconSize = PrivateData::calcIconSizeByHeight(validTitleBarHeight - 2); if (btnIconSize != d_ptr->mQuickAccessBar->iconSize()) { @@ -1953,14 +2121,14 @@ void SARibbonBar::resizeInOfficeStyle() if (getRibbonAlignment() == SARibbonAlignment::AlignLeft) { d_ptr->mRibbonTabBar->setGeometry(x, y, tabBarAllowedWidth, tabH); } else { - //居中对齐的情况下,Tab要居中显示 - //得到tab的推荐尺寸 + // 居中对齐的情况下,Tab要居中显示 + // 得到tab的推荐尺寸 int mintabBarWidth = calcMinTabBarWidth(); if (mintabBarWidth >= tabBarAllowedWidth) { - //这时tabbar没有居中对齐的必要性,空间位置不够了 + // 这时tabbar没有居中对齐的必要性,空间位置不够了 d_ptr->mRibbonTabBar->setGeometry(x, y, tabBarAllowedWidth, tabH); } else { - //说明tabbar的宽度有居中的可能性 + // 说明tabbar的宽度有居中的可能性 int xoffset = (tabBarAllowedWidth - mintabBarWidth) / 2; d_ptr->mRibbonTabBar->setGeometry(x + xoffset, y, mintabBarWidth, tabH); } @@ -2017,7 +2185,7 @@ void SARibbonBar::resizeInWpsLiteStyle() // 上下留1px的边线 d_ptr->mQuickAccessBar->setGeometry(endX, y + 1, quickAccessBarSize.width(), validTitleBarHeight - 2); // 变更iconsize - if (!(d_ptr->mEnableUserDefineAccessBarIconSize)) { //允许用户自定义AccessBar的IconSize就不进入此条件重置大小 + if (!(d_ptr->mEnableUserDefineAccessBarIconSize)) { // 允许用户自定义AccessBar的IconSize就不进入此条件重置大小 QSize btnIconSize = PrivateData::calcIconSizeByHeight(validTitleBarHeight - 2); if (btnIconSize != d_ptr->mQuickAccessBar->iconSize()) { d_ptr->mQuickAccessBar->setIconSize(btnIconSize); @@ -2070,12 +2238,12 @@ void SARibbonBar::resizeInWpsLiteStyle() } d_ptr->mRibbonTabBar->setGeometry(x, y, tabBarAllowedWidth, tabH); } else { - //居中对齐 + // 居中对齐 if (mintabBarWidth >= tabBarAllowedWidth) { - //这时tabbar没有居中对齐的必要性,空间位置不够了 + // 这时tabbar没有居中对齐的必要性,空间位置不够了 d_ptr->mRibbonTabBar->setGeometry(x, y, tabBarAllowedWidth, tabH); } else { - //说明tabbar的宽度有居中的可能性 + // 说明tabbar的宽度有居中的可能性 int xoffset = (tabBarAllowedWidth - mintabBarWidth) / 2; d_ptr->mRibbonTabBar->setGeometry(x + xoffset, y, mintabBarWidth, tabH); } diff --git a/src/SARibbonBar/SARibbonBar.h b/src/SARibbonBar/SARibbonBar.h index be03b26b..287d1462 100644 --- a/src/SARibbonBar/SARibbonBar.h +++ b/src/SARibbonBar/SARibbonBar.h @@ -104,14 +104,14 @@ class SA_RIBBON_EXPORT SARibbonBar : public QMenuBar */ enum RibbonStyle { - RibbonStyleLooseThreeRow = 0x0000, ///< 宽松结构,3行模式 - RibbonStyleCompactThreeRow = 0x0001, ///< 紧凑结构,3行模式 - RibbonStyleLooseTwoRow = 0x0100, ///< 宽松结构,2行模式 - RibbonStyleCompactTwoRow = 0x0101, ///< 紧凑结构,2行模式 - // 以下枚举将组件淘汰 - OfficeStyle = RibbonStyleLooseThreeRow, ///< 类似office 的ribbon风格 - WpsLiteStyle = RibbonStyleCompactThreeRow, ///< 类似wps的紧凑风格 - OfficeStyleTwoRow = RibbonStyleLooseTwoRow, ///< 类似office 的ribbon风格 2行工具栏 三行布局模式,office就是三行布局模式,pannel能布置3行小toolbutton,默认模式 + RibbonStyleLooseThreeRow = 0x0000, ///< 宽松结构,3行模式 + RibbonStyleCompactThreeRow = 0x0001, ///< 紧凑结构,3行模式 + RibbonStyleLooseTwoRow = 0x0100, ///< 宽松结构,2行模式 + RibbonStyleCompactTwoRow = 0x0101, ///< 紧凑结构,2行模式 + // 以下枚举将组件淘汰 + OfficeStyle = RibbonStyleLooseThreeRow, ///< 类似office 的ribbon风格 + WpsLiteStyle = RibbonStyleCompactThreeRow, ///< 类似wps的紧凑风格 + OfficeStyleTwoRow = RibbonStyleLooseTwoRow, ///< 类似office 的ribbon风格 2行工具栏 三行布局模式,office就是三行布局模式,pannel能布置3行小toolbutton,默认模式 WpsLiteStyleTwoRow = RibbonStyleCompactTwoRow ///< 类似wps的紧凑风格 2行工具栏 }; Q_ENUM(RibbonStyle) @@ -136,7 +136,7 @@ class SA_RIBBON_EXPORT SARibbonBar : public QMenuBar // 获取版本信息 static QString versionString(); - //获取默认的上下文标签颜色列表 + // 获取默认的上下文标签颜色列表 static QList< QColor > getDefaultContextCategoryColorList(); public: @@ -229,16 +229,21 @@ class SA_RIBBON_EXPORT SARibbonBar : public QMenuBar // ribbon tab的高度 int tabBarHeight() const; - + void setTabBarHeight(int h); // 标题栏的高度 int titleBarHeight() const; - + void setTitleBarHeight(int h); + // 获取mainBar的高度 + int mainBarHeight() const; + void setMainBarHeight(int m); + // 最小模式下的MainBar高度 + int minimumModeMainBarHeight() const; // 激活tabbar右边的按钮群 - void activeRightButtonGroup(); - + SARibbonButtonGroupWidget* activeRightButtonGroup(); // 右侧按钮群 SARibbonButtonGroupWidget* rightButtonGroup(); - + // 激活QuickAccessBar + SARibbonQuickAccessBar* activeQuickAccessBar(); // 快速响应栏 SARibbonQuickAccessBar* quickAccessBar(); @@ -288,16 +293,16 @@ class SA_RIBBON_EXPORT SARibbonBar : public QMenuBar // 设置是否显示标题 void setTitleVisible(bool on = false); bool isTitleVisible() const; - //允许用户自定义AccessBar图标尺寸,默认为false + // 允许用户自定义AccessBar图标尺寸,默认为false void setEnableUserDefineAccessBarIconSize(bool on = true); bool isEnableUserDefineAccessBarIconSize() const; - //允许用户自定义RightBar图标尺寸,默认为false + // 允许用户自定义RightBar图标尺寸,默认为false void setEnableUserDefineRightBarIconSize(bool on = true); bool isEnableUserDefineRightBarIconSize() const; - //上下文标签的颜色列表,上下文标签显示的时候,会从颜色列表中取颜色进行标签的渲染 + // 上下文标签的颜色列表,上下文标签显示的时候,会从颜色列表中取颜色进行标签的渲染 void setContextCategoryColorList(const QList< QColor >& cls); QList< QColor > getContextCategoryColorList() const; - //设置ribbon的对齐方式 + // 设置ribbon的对齐方式 void setRibbonAlignment(SARibbonAlignment al); SARibbonAlignment getRibbonAlignment() const; signals: @@ -327,14 +332,18 @@ class SA_RIBBON_EXPORT SARibbonBar : public QMenuBar */ void ribbonStyleChanged(SARibbonBar::RibbonStyle nowStyle); + /** + @brief 标题栏高度发生了变化的信号 + @param oldHeight + @param newHeight + */ + void titleBarHeightChanged(int oldHeight, int newHeight); + protected: bool eventFilter(QObject* obj, QEvent* e) override; // 根据情况重置tabbar的宽度,主要针对wps模式 int calcMinTabBarWidth() const; - - // 根据currentRibbonStyle计算mainBar的高度 - virtual int mainBarHeight() const; // 更新 void updateCategoryTitleToTabName(); protected slots: diff --git a/src/SARibbonBar/SARibbonMainWindow.cpp b/src/SARibbonBar/SARibbonMainWindow.cpp index f4920a90..762cabc2 100644 --- a/src/SARibbonBar/SARibbonMainWindow.cpp +++ b/src/SARibbonBar/SARibbonMainWindow.cpp @@ -67,7 +67,6 @@ SARibbonMainWindow::SARibbonMainWindow(QWidget* parent, bool useRibbon, const Qt if (useRibbon) { installRibbonBar(createRibbonBar()); setRibbonTheme(ribbonTheme()); - qDebug() << RibbonSubElementStyleOpt; } } diff --git a/src/SARibbonBar/SARibbonStyleOption.h b/src/SARibbonBar/SARibbonStyleOption.h index 084d33be..c70f3287 100644 --- a/src/SARibbonBar/SARibbonStyleOption.h +++ b/src/SARibbonBar/SARibbonStyleOption.h @@ -25,25 +25,25 @@ class SA_RIBBON_EXPORT SARibbonStyleOption // ribbonBar的高度 virtual int ribbonBarHeight(SARibbonBar::RibbonStyle s) const; - //标题栏的高度,对于wps模式,此参数没有用 + // 标题栏的高度,对于wps模式,此参数没有用 virtual int titleBarHeight() const; - //标签栏高度 + // 标签栏高度 virtual int tabBarHeight() const; - //在改变了参数后对需要计算的变量从新计算 + // 在改变了参数后对需要计算的变量从新计算 virtual void recalc(); protected: - //通过已有参数计算pannel的高度 - // int calcPannelHeight(SARibbonPannel::PannelLayoutMode lm) const; - //计算ribbon的高度 + // 通过已有参数计算pannel的高度 + // int calcPannelHeight(SARibbonPannel::PannelLayoutMode lm) const; + // 计算ribbon的高度 int calcMainbarHeight(SARibbonBar::RibbonStyle s) const; private: - //初始化 + // 初始化 void init(); - //计算pannel的高度 + // 计算pannel的高度 void updateMainbarHeight(); private: diff --git a/src/SARibbonBar/SARibbonToolButton.cpp b/src/SARibbonBar/SARibbonToolButton.cpp index 6cfe0868..7ab0d9ec 100644 --- a/src/SARibbonBar/SARibbonToolButton.cpp +++ b/src/SARibbonBar/SARibbonToolButton.cpp @@ -91,40 +91,40 @@ class SARibbonToolButton::PrivateData SA_RIBBON_DECLARE_PUBLIC(SARibbonToolButton) public: PrivateData(SARibbonToolButton* p); - //根据鼠标位置更新按钮的信息 + // 根据鼠标位置更新按钮的信息 void updateStatusByMousePosition(const QPoint& pos); - //更新绘图相关的尺寸 + // 更新绘图相关的尺寸 void updateDrawRect(const QStyleOptionToolButton& opt); - //更新SizeHint + // 更新SizeHint void updateSizeHint(const QStyleOptionToolButton& opt); - //计算涉及到的rect尺寸 + // 计算涉及到的rect尺寸 void calcDrawRects(const QStyleOptionToolButton& opt, QRect& iconRect, QRect& textRect, QRect& indicatorArrowRect, int spacing, int indicatorLen) const; - //计算小按钮模式下的尺寸 + // 计算小按钮模式下的尺寸 void calcSmallButtonDrawRects(const QStyleOptionToolButton& opt, QRect& iconRect, QRect& textRect, QRect& indicatorArrowRect, int spacing, int indicatorLen) const; - //计算大按钮模式下的尺寸 + // 计算大按钮模式下的尺寸 void calcLargeButtonDrawRects(const QStyleOptionToolButton& opt, QRect& iconRect, QRect& textRect, QRect& indicatorArrowRect, int spacing, int indicatorLen) const; - //根据按钮的尺寸调节iconsize(注意这里的buttonRect是已经减去mSpacing的情况) + // 根据按钮的尺寸调节iconsize(注意这里的buttonRect是已经减去mSpacing的情况) QSize adjustIconSize(const QRect& buttonRect, const QSize& originIconSize) const; - //判断是否有Indicator + // 判断是否有Indicator bool hasIndicator(const QStyleOptionToolButton& opt) const; - //计算sizehint + // 计算sizehint QSize calcSizeHint(const QStyleOptionToolButton& opt); QSize calcSmallButtonSizeHint(const QStyleOptionToolButton& opt); QSize calcLargeButtonSizeHint(const QStyleOptionToolButton& opt); - //计算文本绘制矩形的高度 + // 计算文本绘制矩形的高度 int calcTextDrawRectHeight(const QStyleOptionToolButton& opt) const; - //估算一个最优的文本宽度 + // 估算一个最优的文本宽度 int estimateLargeButtonTextWidth(int buttonHeight, int textDrawRectHeight, const QString& text, @@ -132,11 +132,11 @@ class SARibbonToolButton::PrivateData float widthHeightRatio = SARIBBONTOOLBUTTON_WORDWRAP_WIDTH_PER_HEIGHT_RATIO, int maxTrycount = 3); QPixmap createIconPixmap(const QStyleOptionToolButton& opt, const QSize& iconsize) const; - //获取文字的对其方式 + // 获取文字的对其方式 int getTextAlignment() const; - //确认文字是否确切要换行显示 + // 确认文字是否确切要换行显示 bool isTextNeedWrap() const; - //仅仅对\n进行剔除,和QString::simplified不一样 + // 仅仅对\n进行剔除,和QString::simplified不一样 static QString simplified(const QString& str); public: @@ -155,7 +155,7 @@ class SARibbonToolButton::PrivateData static bool s_enableWordWrap; ///< 在lite模式下是否允许文字换行,如果允许,则图标相对比较小,默认不允许 }; -//静态参数初始化 +// 静态参数初始化 bool SARibbonToolButton::PrivateData::s_enableWordWrap = false; SARibbonToolButton::PrivateData::PrivateData(SARibbonToolButton* p) : q_ptr(p) @@ -174,13 +174,13 @@ void SARibbonToolButton::PrivateData::updateStatusByMousePosition(const QPoint& if (SARibbonToolButton::LargeButton == mButtonType) { isMouseOnSubControl = mDrawTextRect.united(mDrawIndicatorArrowRect).contains(pos); } else { - //小按钮模式就和普通toolbutton一样 + // 小按钮模式就和普通toolbutton一样 isMouseOnSubControl = mDrawIndicatorArrowRect.contains(pos); } if (mMouseOnSubControl != isMouseOnSubControl) { mMouseOnSubControl = isMouseOnSubControl; - //从icon变到text过程中刷新一次 + // 从icon变到text过程中刷新一次 q_ptr->update(); } } @@ -203,13 +203,13 @@ void SARibbonToolButton::PrivateData::updateDrawRect(const QStyleOptionToolButto if (!mSizeHint.isValid()) { updateSizeHint(opt); } - //先更新IndicatorLen + // 先更新IndicatorLen mIndicatorLen = q_ptr->style()->pixelMetric(QStyle::PM_MenuButtonIndicator, &opt, q_ptr); if (mIndicatorLen < 3) { if (SARibbonToolButton::LargeButton == mButtonType) { mIndicatorLen = 8; } else { - mIndicatorLen = 12; //小按钮模式下设置为10 + mIndicatorLen = 12; // 小按钮模式下设置为10 } } calcDrawRects(opt, mDrawIconRect, mDrawTextRect, mDrawIndicatorArrowRect, mSpacing, mIndicatorLen); @@ -268,25 +268,25 @@ void SARibbonToolButton::PrivateData::calcSmallButtonDrawRects(const QStyleOptio case Qt::ToolButtonIconOnly: { if (hasIndicator(opt)) { // 在仅有图标的小模式显示时,预留一个下拉箭头位置 - iconRect = opt.rect.adjusted(spacing, spacing, -indicatorLen - spacing, -spacing); + iconRect = opt.rect.adjusted(spacing, spacing, -indicatorLen - spacing, -spacing); indicatorArrowRect = QRect(opt.rect.right() - indicatorLen - spacing, iconRect.y(), indicatorLen, iconRect.height()); } else { iconRect = opt.rect.adjusted(spacing, spacing, -spacing, -spacing); indicatorArrowRect = QRect(); } - //文本区域为空 + // 文本区域为空 textRect = QRect(); } break; case Qt::ToolButtonTextOnly: { if (hasIndicator(opt)) { // 在仅有图标的小模式显示时,预留一个下拉箭头位置 - textRect = opt.rect.adjusted(spacing, spacing, -indicatorLen - spacing, -spacing); + textRect = opt.rect.adjusted(spacing, spacing, -indicatorLen - spacing, -spacing); indicatorArrowRect = QRect(opt.rect.right() - indicatorLen - spacing, spacing, indicatorLen, textRect.height()); } else { textRect = opt.rect.adjusted(spacing, spacing, -spacing, -spacing); indicatorArrowRect = QRect(); } - //绘图区域为空 + // 绘图区域为空 iconRect = QRect(); } break; default: { @@ -294,27 +294,27 @@ void SARibbonToolButton::PrivateData::calcSmallButtonDrawRects(const QStyleOptio // icon Beside和under都是一样的 QRect buttonRect = q_ptr->rect(); buttonRect.adjust(spacing, spacing, -spacing, -spacing); - //先设置IconRect + // 先设置IconRect if (opt.icon.isNull()) { - //没有图标 + // 没有图标 iconRect = QRect(); } else { QSize iconSize = adjustIconSize(buttonRect, opt.iconSize); iconRect = QRect(buttonRect.x(), buttonRect.y(), iconSize.width(), qMax(iconSize.height(), buttonRect.height())); } - //后设置TextRect + // 后设置TextRect if (opt.text.isEmpty()) { textRect = QRect(); } else { - //分有菜单和没菜单两种情况 - int adjx = iconRect.isValid() ? (iconRect.width() + spacing) : 0; //在buttonRect上变换,因此如果没有图标是不用偏移spacing + // 分有菜单和没菜单两种情况 + int adjx = iconRect.isValid() ? (iconRect.width() + spacing) : 0; // 在buttonRect上变换,因此如果没有图标是不用偏移spacing if (hasInd) { textRect = buttonRect.adjusted(adjx, 0, -indicatorLen, 0); } else { - textRect = buttonRect.adjusted(adjx, 0, 0, 0); //在buttonRect上变换,因此如果没有图标是不用偏移spacing + textRect = buttonRect.adjusted(adjx, 0, 0, 0); // 在buttonRect上变换,因此如果没有图标是不用偏移spacing } } - //最后设置Indicator + // 最后设置Indicator if (hasInd) { if (textRect.isValid()) { indicatorArrowRect = QRect(buttonRect.right() - indicatorLen + 1, textRect.y(), indicatorLen, textRect.height()); @@ -347,26 +347,26 @@ void SARibbonToolButton::PrivateData::calcLargeButtonDrawRects(const QStyleOptio int indicatorLen) const { //! 3行模式的图标比较大,文字换行情况下,indicator会动态调整 - //先获取文字矩形的高度 + // 先获取文字矩形的高度 int textHeight = calcTextDrawRectHeight(opt); bool hIndicator = hasIndicator(opt); if (!hIndicator) { - //没有菜单,把len设置为0 + // 没有菜单,把len设置为0 indicatorLen = 0; indicatorArrowRect = QRect(); } - //这里要判断文字是否要换行显示,换行显示的文字的indicatorArrowRect所处的位置不一样 - //先布置textRect + // 这里要判断文字是否要换行显示,换行显示的文字的indicatorArrowRect所处的位置不一样 + // 先布置textRect if (isEnableWordWrap()) { - //在换行模式下 + // 在换行模式下 if (isTextNeedWrap()) { - //如果文字的确换行,indicator放在最右边 + // 如果文字的确换行,indicator放在最右边 textRect = QRect(spacing, opt.rect.bottom() - spacing - textHeight, opt.rect.width() - 2 * spacing - indicatorLen, textHeight); if (hIndicator) { indicatorArrowRect = QRect(textRect.right(), textRect.y() + textRect.height() / 2, indicatorLen, textHeight / 2); } } else { - //如果文字不需要换行,indicator在下板行 + // 如果文字不需要换行,indicator在下板行 textRect = QRect(spacing, opt.rect.bottom() - spacing - textHeight, opt.rect.width() - 2 * spacing, textHeight); if (hIndicator) { int dy = textRect.height() / 2; @@ -375,17 +375,17 @@ void SARibbonToolButton::PrivateData::calcLargeButtonDrawRects(const QStyleOptio } } } else { - //文字不换行,indicator放在最右边 + // 文字不换行,indicator放在最右边 int y = opt.rect.bottom() - spacing - textHeight; if (hIndicator) { - //先布置indicator + // 先布置indicator indicatorArrowRect = QRect(opt.rect.right() - indicatorLen - spacing, y, indicatorLen, textHeight); textRect = QRect(spacing, y, indicatorArrowRect.x() - spacing, textHeight); } else { textRect = QRect(spacing, y, opt.rect.width() - 2 * spacing, textHeight); } } - //剩下就是icon区域 + // 剩下就是icon区域 iconRect = QRect(spacing, spacing, opt.rect.width() - 2 * spacing, textRect.top() - 2 * spacing); } @@ -399,9 +399,9 @@ QSize SARibbonToolButton::PrivateData::adjustIconSize(const QRect& buttonRect, c { QSize iconSize = originIconSize; if (iconSize.height() > buttonRect.height()) { - //说明图标的icon过大,要匹配到buttonRect + // 说明图标的icon过大,要匹配到buttonRect iconSize.setHeight(buttonRect.height()); - //等比例设置宽度 + // 等比例设置宽度 iconSize.setWidth(originIconSize.width() * iconSize.height() / originIconSize.height()); } return iconSize; @@ -449,10 +449,10 @@ QSize SARibbonToolButton::PrivateData::calcSmallButtonSizeHint(const QStyleOptio h = textSize.height() + 2 * mSpacing; } break; default: { - //先加入icon的尺寸 + // 先加入icon的尺寸 w = opt.iconSize.width() + 2 * mSpacing; h = opt.iconSize.height() + 2 * mSpacing; - //再加入文本的长度 + // 再加入文本的长度 if (!opt.text.isEmpty()) { QSize textSize = opt.fontMetrics.size(Qt::TextShowMnemonic, simplified(opt.text)); textSize.setWidth(textSize.width() + SA_FONTMETRICS_WIDTH(opt.fontMetrics, (QLatin1Char(' '))) * 2); @@ -461,14 +461,14 @@ QSize SARibbonToolButton::PrivateData::calcSmallButtonSizeHint(const QStyleOptio w += textSize.width(); h = qMax(h, (textSize.height() + (2 * mSpacing))); } else { - //没有文本的时候也要设置一下高度 + // 没有文本的时候也要设置一下高度 QSize textSize = opt.fontMetrics.size(Qt::TextShowMnemonic, " "); h = qMax(h, (textSize.height() + (2 * mSpacing))); } } } if (hasIndicator(opt)) { - //存在indicator的按钮,宽度尺寸要扩展 + // 存在indicator的按钮,宽度尺寸要扩展 w += mIndicatorLen; } if (w < 16) { @@ -482,18 +482,18 @@ QSize SARibbonToolButton::PrivateData::calcLargeButtonSizeHint(const QStyleOptio { int w = 0; int h = opt.fontMetrics.lineSpacing() * 4.5; // 3*1.5 - int minW = h * 0.75; //最小宽度,在pannel里面的按钮,最小宽度要和icon适应 + int minW = h * 0.75; // 最小宽度,在pannel里面的按钮,最小宽度要和icon适应 if (mDrawIconRect.isValid()) { minW = mDrawIconRect.height(); } if (SARibbonPannel* pannel = qobject_cast< SARibbonPannel* >(q_ptr->parent())) { - //对于建立在SARibbonPannel的基础上的大按钮,把高度设置为SARibbonPannel计算的大按钮高度 + // 对于建立在SARibbonPannel的基础上的大按钮,把高度设置为SARibbonPannel计算的大按钮高度 h = pannel->largeHeight(); } - //估算字体的宽度作为宽度 + // 估算字体的宽度作为宽度 w = estimateLargeButtonTextWidth(h, calcTextDrawRectHeight(opt), opt.text, opt.fontMetrics); w += (2 * mSpacing); - //判断是否需要加上indicator + // 判断是否需要加上indicator if (isEnableWordWrap() && isTextNeedWrap()) { w += mIndicatorLen; } @@ -519,7 +519,7 @@ int SARibbonToolButton::PrivateData::calcTextDrawRectHeight(const QStyleOptionTo return opt.fontMetrics.lineSpacing() * SARIBBONTOOLBUTTON_NOWORDWRAP_TEXT_FACTOR; } } - //小按钮 + // 小按钮 return opt.fontMetrics.lineSpacing() * SARIBBONTOOLBUTTON_SMALLBUTTON_TEXT_FACTOR; } @@ -553,9 +553,9 @@ int SARibbonToolButton::PrivateData::estimateLargeButtonTextWidth(int buttonHeig return textSize.width(); } - //这时候需要估算文本的长度 + // 这时候需要估算文本的长度 if (textSize.width() <= hintMaxWidth) { - //范围合理,直接返回 + // 范围合理,直接返回 mIsTextNeedWrap = false; // 文字不需要换行显示,标记起来 return textSize.width(); } @@ -564,7 +564,7 @@ int SARibbonToolButton::PrivateData::estimateLargeButtonTextWidth(int buttonHeig //! 这里先对文本长度逐渐加长估算,一直到和原来长度一致为止 int trycount = 0; int alignment = Qt::TextShowMnemonic | Qt::TextWordWrap; - //对于英文字体,直接宽度减半是无法满足完全显示两行的,需要进行预估 + // 对于英文字体,直接宽度减半是无法满足完全显示两行的,需要进行预估 QRect textRect(0, 0, textSize.width(), textDrawRectHeight); do { //! 先计算两行文本的紧凑矩形 @@ -575,7 +575,7 @@ int SARibbonToolButton::PrivateData::estimateLargeButtonTextWidth(int buttonHeig textRect.setWidth(textSize.width() / 2 + (textSize.width() / 2) * (float(trycount) / maxTrycount)); textRect = fm.boundingRect(textRect, alignment, text); if (textRect.height() <= (fm.lineSpacing() * 2)) { - //保证在两行 + // 保证在两行 mIsTextNeedWrap = true; // 文字需要换行显示,标记起来 return textRect.width(); } @@ -587,22 +587,22 @@ int SARibbonToolButton::PrivateData::estimateLargeButtonTextWidth(int buttonHeig } #endif } while (trycount < 3); - //到这里说明前面的尝试失败,最终使用原始的长度 + // 到这里说明前面的尝试失败,最终使用原始的长度 return textSize.width(); } //! 说明是不换行 mIsTextNeedWrap = false; // 文字不需要换行显示,标记起来 - //文字不换行情况下,做simplified处理 + // 文字不换行情况下,做simplified处理 textSize = fm.size(Qt::TextShowMnemonic, simplified(text)); textSize.setWidth(textSize.width() + space); if (textSize.width() < hintMaxWidth) { - //范围合理,直接返回 + // 范围合理,直接返回 return textSize.width(); } if (textSize.width() > q_ptr->maximumWidth()) { - //超出了极限,就返回极限 + // 超出了极限,就返回极限 return q_ptr->maximumWidth(); } return hintMaxWidth; @@ -610,7 +610,7 @@ int SARibbonToolButton::PrivateData::estimateLargeButtonTextWidth(int buttonHeig QPixmap SARibbonToolButton::PrivateData::createIconPixmap(const QStyleOptionToolButton& opt, const QSize& iconsize) const { - if (opt.icon.isNull()) { //没有有图标 + if (opt.icon.isNull()) { // 没有有图标 return (QPixmap()); } QIcon::State state = (opt.state & QStyle::State_On) ? QIcon::On : QIcon::Off; @@ -630,7 +630,7 @@ int SARibbonToolButton::PrivateData::getTextAlignment() const int alignment = Qt::TextShowMnemonic; if (SARibbonToolButton::LargeButton == mButtonType) { if (isEnableWordWrap()) { - alignment |= Qt::TextWordWrap | Qt::AlignTop | Qt::AlignHCenter; //换行的情况下,顶部对齐 + alignment |= Qt::TextWordWrap | Qt::AlignTop | Qt::AlignHCenter; // 换行的情况下,顶部对齐 } else { alignment |= Qt::AlignCenter; } @@ -758,7 +758,7 @@ void SARibbonToolButton::resizeEvent(QResizeEvent* e) #if SA_RIBBON_TOOLBUTTON_DEBUG_PRINT qDebug() << "SARibbonToolButton::resizeEvent, text=" << text() << " obj=" << objectName() << " size=" << e->size(); #endif - //在resizeevent计算绘图所需的尺寸,避免在绘图过程中实时绘制提高效率 + // 在resizeevent计算绘图所需的尺寸,避免在绘图过程中实时绘制提高效率 QToolButton::resizeEvent(e); updateRect(); } @@ -788,7 +788,7 @@ void SARibbonToolButton::paintEvent(QPaintEvent* e) QStyleOptionToolButton opt; initStyleOption(&opt); if (opt.features & QStyleOptionToolButton::MenuButtonPopup || opt.features & QStyleOptionToolButton::HasMenu) { - //在菜单弹出消失后,需要通过此方法取消掉鼠标停留 + // 在菜单弹出消失后,需要通过此方法取消掉鼠标停留 if (!rect().contains(mapFromGlobal(QCursor::pos()))) { opt.state &= ~QStyle::State_MouseOver; } @@ -811,10 +811,10 @@ void SARibbonToolButton::paintButton(QPainter& p, const QStyleOptionToolButton& // QStyle::State_MouseOver 代表当前鼠标位于按钮上面 QStyleOption tool = opt; bool autoRaise = opt.state & QStyle::State_AutoRaise; - //绘制按钮 + // 绘制按钮 if (autoRaise) { - //这个是为了实现按钮点击下去后(QStyle::State_Sunken),能出现选中的状态 - //先绘制一个鼠标不在按钮上的状态 + // 这个是为了实现按钮点击下去后(QStyle::State_Sunken),能出现选中的状态 + // 先绘制一个鼠标不在按钮上的状态 if (opt.state & QStyle::State_Sunken) { tool.state &= ~QStyle::State_MouseOver; } @@ -822,15 +822,15 @@ void SARibbonToolButton::paintButton(QPainter& p, const QStyleOptionToolButton& } else { style()->drawPrimitive(QStyle::PE_PanelButtonBevel, &tool, &p, this); } - //针对MenuButtonPopup的ribbon样式的特殊绘制 + // 针对MenuButtonPopup的ribbon样式的特殊绘制 if ((opt.subControls & QStyle::SC_ToolButton) && (opt.features & QStyleOptionToolButton::MenuButtonPopup)) { - if (opt.state & QStyle::State_MouseOver) { //鼠标在按钮上才进行绘制 - if (!(opt.activeSubControls & QStyle::SC_ToolButtonMenu)) { //按钮的菜单弹出时不做处理 - if (LargeButton == d_ptr->mButtonType) { //大按钮模式 - if (d_ptr->mMouseOnSubControl) { //此时鼠标在indecater那 - //鼠标在文字区,把图标显示为正常(就是鼠标不放上去的状态) + if (opt.state & QStyle::State_MouseOver) { // 鼠标在按钮上才进行绘制 + if (!(opt.activeSubControls & QStyle::SC_ToolButtonMenu)) { // 按钮的菜单弹出时不做处理 + if (LargeButton == d_ptr->mButtonType) { // 大按钮模式 + if (d_ptr->mMouseOnSubControl) { // 此时鼠标在indecater那 + // 鼠标在文字区,把图标显示为正常(就是鼠标不放上去的状态) tool.rect = d_ptr->mDrawIconRect; - tool.state |= (QStyle::State_Raised); //把图标区域显示为正常 + tool.state |= (QStyle::State_Raised); // 把图标区域显示为正常 tool.state &= ~QStyle::State_MouseOver; if (autoRaise) { style()->drawPrimitive(QStyle::PE_PanelButtonTool, &tool, &p, this); @@ -838,10 +838,10 @@ void SARibbonToolButton::paintButton(QPainter& p, const QStyleOptionToolButton& style()->drawPrimitive(QStyle::PE_PanelButtonBevel, &tool, &p, this); } } else { - //鼠标在图标区,把文字显示为正常 - tool.state |= (QStyle::State_Raised); //把图标区域显示为正常 + // 鼠标在图标区,把文字显示为正常 + tool.state |= (QStyle::State_Raised); // 把图标区域显示为正常 tool.state &= ~QStyle::State_MouseOver; - //文字和Indicator都显示正常 + // 文字和Indicator都显示正常 tool.rect = d_ptr->mDrawTextRect.united(d_ptr->mDrawIndicatorArrowRect); if (autoRaise) { style()->drawPrimitive(QStyle::PE_PanelButtonTool, &tool, &p, this); @@ -849,20 +849,20 @@ void SARibbonToolButton::paintButton(QPainter& p, const QStyleOptionToolButton& style()->drawPrimitive(QStyle::PE_PanelButtonBevel, &tool, &p, this); } } - } else { //小按钮模式 - if (d_ptr->mMouseOnSubControl) { //此时鼠标在indecater那 - //鼠标在文字区,把图标和文字显示为正常 + } else { // 小按钮模式 + if (d_ptr->mMouseOnSubControl) { // 此时鼠标在indecater那 + // 鼠标在文字区,把图标和文字显示为正常 tool.rect = d_ptr->mDrawIconRect.united(d_ptr->mDrawTextRect); - tool.state = (QStyle::State_Raised); //把图标区域显示为正常 + tool.state = (QStyle::State_Raised); // 把图标区域显示为正常 if (autoRaise) { style()->drawPrimitive(QStyle::PE_PanelButtonTool, &tool, &p, this); } else { style()->drawPrimitive(QStyle::PE_PanelButtonBevel, &tool, &p, this); } } else { - //鼠标在图标区,把文字显示为正常 - tool.state = (QStyle::State_Raised); //把图标区域显示为正常 - //文字和Indicator都显示正常 + // 鼠标在图标区,把文字显示为正常 + tool.state = (QStyle::State_Raised); // 把图标区域显示为正常 + // 文字和Indicator都显示正常 tool.rect = d_ptr->mDrawIndicatorArrowRect; if (autoRaise) { style()->drawPrimitive(QStyle::PE_PanelButtonTool, &tool, &p, this); @@ -874,13 +874,13 @@ void SARibbonToolButton::paintButton(QPainter& p, const QStyleOptionToolButton& } } } - //绘制Focus - // if (opt.state & QStyle::State_HasFocus) { - // QStyleOptionFocusRect fr; - // fr.QStyleOption::operator=(opt); - // fr.rect.adjust(d_ptr->mSpacing, d_ptr->mSpacing, -d_ptr->mSpacing, -d_ptr->mSpacing); - // style()->drawPrimitive(QStyle::PE_FrameFocusRect, &fr, &p, this); - // } + // 绘制Focus + // if (opt.state & QStyle::State_HasFocus) { + // QStyleOptionFocusRect fr; + // fr.QStyleOption::operator=(opt); + // fr.rect.adjust(d_ptr->mSpacing, d_ptr->mSpacing, -d_ptr->mSpacing, -d_ptr->mSpacing); + // style()->drawPrimitive(QStyle::PE_FrameFocusRect, &fr, &p, this); + // } } /** @@ -1016,8 +1016,8 @@ SARibbonToolButton::RibbonButtonType SARibbonToolButton::buttonType() const void SARibbonToolButton::setButtonType(const RibbonButtonType& buttonType) { d_ptr->mButtonType = buttonType; - //计算iconrect - //根据字体计算文字的高度 + // 计算iconrect + // 根据字体计算文字的高度 if (LargeButton == buttonType) { setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding); @@ -1071,10 +1071,6 @@ void SARibbonToolButton::updateRect() /** * @brief 设置在lite模式下是否允许文字换行,如果允许,则图标相对比较小,默认不允许 * @param on - * @note 此函数的调用最好在ribbonbar布局之前设置,且调用之后需要调用@sa SARibbonStyleOption::recalc 刷新 - * @code - * RibbonSubElementStyleOpt.recalc(); - * @endcode */ void SARibbonToolButton::setEnableWordWrap(bool on) { @@ -1113,7 +1109,7 @@ void SARibbonToolButton::changeEvent(QEvent* e) { if (e) { if (e->type() == QEvent::FontChange) { - //说明字体改变,需要重新计算和字体相关的信息 + // 说明字体改变,需要重新计算和字体相关的信息 updateRect(); } } diff --git a/src/SARibbonBar/SAWindowButtonGroup.cpp b/src/SARibbonBar/SAWindowButtonGroup.cpp index 91ee80f0..e526deea 100644 --- a/src/SARibbonBar/SAWindowButtonGroup.cpp +++ b/src/SARibbonBar/SAWindowButtonGroup.cpp @@ -5,7 +5,7 @@ #include #include #include "SARibbonElementManager.h" -//为了避免使用此框架的app设置了全局的qpushbutton 的 qss样式影响此按钮,定义了一个类 +// 为了避免使用此框架的app设置了全局的qpushbutton 的 qss样式影响此按钮,定义了一个类 /** * @brief The SAWindowButtonGroupPrivate class @@ -37,8 +37,8 @@ class SAWindowButtonGroup::PrivateData } buttonMinimize = new SAWindowToolButton(par); buttonMinimize->setObjectName(QStringLiteral("SAMinimizeWindowButton")); - buttonMinimize->setFixedSize(30, RibbonSubElementStyleOpt.titleBarHeight() - 2); - buttonMinimize->setFocusPolicy(Qt::NoFocus); //避免铺抓到 + buttonMinimize->setFixedSize(30, par->height() - 2); + buttonMinimize->setFocusPolicy(Qt::NoFocus); // 避免铺抓到 buttonMinimize->setIconSize(buttonMinimize->size() * mIconscale); buttonMinimize->show(); par->connect(buttonMinimize, &QAbstractButton::clicked, par, &SAWindowButtonGroup::minimizeWindow); @@ -62,9 +62,9 @@ class SAWindowButtonGroup::PrivateData } buttonMaximize = new SAWindowToolButton(par); buttonMaximize->setObjectName(QStringLiteral("SAMaximizeWindowButton")); - buttonMaximize->setFixedSize(30, RibbonSubElementStyleOpt.titleBarHeight() - 2); + buttonMaximize->setFixedSize(30, par->height() - 2); buttonMaximize->setCheckable(true); - buttonMaximize->setFocusPolicy(Qt::NoFocus); //避免铺抓到 + buttonMaximize->setFocusPolicy(Qt::NoFocus); // 避免铺抓到 buttonMaximize->setIconSize(buttonMaximize->size() * mIconscale); buttonMaximize->show(); par->connect(buttonMaximize, &QAbstractButton::clicked, par, &SAWindowButtonGroup::maximizeWindow); @@ -88,8 +88,8 @@ class SAWindowButtonGroup::PrivateData } buttonClose = new SAWindowToolButton(par); buttonClose->setObjectName(QStringLiteral("SACloseWindowButton")); - buttonClose->setFixedSize(40, RibbonSubElementStyleOpt.titleBarHeight() - 2); - buttonClose->setFocusPolicy(Qt::NoFocus); //避免铺抓到 + buttonClose->setFixedSize(40, par->height() - 2); + buttonClose->setFocusPolicy(Qt::NoFocus); // 避免铺抓到 // buttonClose->setFlat(true); par->connect(buttonClose, &QAbstractButton::clicked, par, &SAWindowButtonGroup::closeWindow); buttonClose->setIconSize(buttonClose->size() * mIconscale); @@ -122,14 +122,14 @@ class SAWindowButtonGroup::PrivateData if (buttonMinimize) { tw += mMinStretch; } - //调整按钮 + // 调整按钮 int x = 0; if (buttonMinimize) { int w = (mMinStretch / tw) * size.width(); // buttonMinimize->setGeometry(x, 0, w, size.height()); - //受到qss样式影响会导致最小宽度、高度设置不了,因此要设置fixsize再move + // 受到qss样式影响会导致最小宽度、高度设置不了,因此要设置fixsize再move buttonMinimize->setFixedSize(w, size.height()); buttonMinimize->move(x, 0); x += w; @@ -137,7 +137,7 @@ class SAWindowButtonGroup::PrivateData if (buttonMaximize) { int w = (mMaxStretch / tw) * size.width(); // buttonMaximize->setGeometry(x, 0, w, size.height()); - //受到qss样式影响会导致最小宽度、高度设置不了,因此要设置fixsize再move + // 受到qss样式影响会导致最小宽度、高度设置不了,因此要设置fixsize再move buttonMaximize->setFixedSize(w, size.height()); buttonMaximize->move(x, 0); x += w; @@ -145,7 +145,7 @@ class SAWindowButtonGroup::PrivateData if (buttonClose) { int w = (mCloseStretch / tw) * size.width(); // buttonClose->setGeometry(x, 0, w, size.height()); - //受到qss样式影响会导致最小宽度、高度设置不了,因此要设置fixsize再move + // 受到qss样式影响会导致最小宽度、高度设置不了,因此要设置fixsize再move buttonClose->setFixedSize(w, size.height()); buttonClose->move(x, 0); } @@ -327,7 +327,7 @@ QSize SAWindowButtonGroup::sizeHint() const bool SAWindowButtonGroup::eventFilter(QObject* watched, QEvent* e) { - //用于监听父窗口改变尺寸 + // 用于监听父窗口改变尺寸 if (watched == parentWidget()) { switch (e->type()) { case QEvent::Resize: @@ -338,7 +338,7 @@ bool SAWindowButtonGroup::eventFilter(QObject* watched, QEvent* e) break; } } - return (false); //不截断任何事件 + return (false); // 不截断任何事件 } void SAWindowButtonGroup::parentResize() diff --git a/src/SARibbonBar/SAWindowButtonGroup.h b/src/SARibbonBar/SAWindowButtonGroup.h index 885376e1..9e777304 100644 --- a/src/SARibbonBar/SAWindowButtonGroup.h +++ b/src/SARibbonBar/SAWindowButtonGroup.h @@ -21,16 +21,16 @@ class SA_RIBBON_EXPORT SAWindowButtonGroup : public QWidget void updateWindowFlag(); void updateWindowFlag(Qt::WindowFlags flags); - //设置按钮的宽度比例,最终按钮宽度将按照此比例进行设置 + // 设置按钮的宽度比例,最终按钮宽度将按照此比例进行设置 void setButtonWidthStretch(int close = 4, int max = 3, int min = 3); - //设置按钮的缩放比例 + // 设置按钮的缩放比例 void setIconScale(qreal iconscale = 0.5); - //设置Qt::WindowStates + // 设置Qt::WindowStates void setWindowStates(Qt::WindowStates s); - //仅获取按钮的状态 + // 仅获取按钮的状态 Qt::WindowFlags windowButtonFlags() const; virtual QSize sizeHint() const Q_DECL_OVERRIDE; diff --git a/src/example/MainWindowExample/main.cpp b/src/example/MainWindowExample/main.cpp index 4114b014..99fc93fc 100644 --- a/src/example/MainWindowExample/main.cpp +++ b/src/example/MainWindowExample/main.cpp @@ -3,7 +3,7 @@ #include #include -//重定向qdebug的打印 +// 重定向qdebug的打印 void log_out_put(QtMsgType type, const QMessageLogContext& context, const QString& msg); /** @@ -18,12 +18,7 @@ void log_out_put(QtMsgType type, const QMessageLogContext& context, const QStrin switch (type) { case QtDebugMsg: - fprintf(stdout, - "[Debug] %s \n-------------->(%s:%u, %s)\n", - localMsg.constData(), - context.file, - context.line, - context.function); + fprintf(stdout, "[Debug] %s \n-------------->(%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; // case QtInfoMsg: @@ -31,40 +26,20 @@ void log_out_put(QtMsgType type, const QMessageLogContext& context, const QStrin // context.function); break; case QtWarningMsg: - fprintf(stdout, - "[Warning] %s \n-------------->(%s:%u, %s)\n", - localMsg.constData(), - context.file, - context.line, - context.function); + fprintf(stdout, "[Warning] %s \n-------------->(%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; case QtCriticalMsg: - fprintf(stdout, - "[Critical] %s \n-------------->(%s:%u, %s)\n", - localMsg.constData(), - context.file, - context.line, - context.function); + fprintf(stdout, "[Critical] %s \n-------------->(%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; case QtFatalMsg: - fprintf(stdout, - "Fatal: %s \n-------------->(%s:%u, %s)\n", - localMsg.constData(), - context.file, - context.line, - context.function); + fprintf(stdout, "Fatal: %s \n-------------->(%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); abort(); break; default: - fprintf(stdout, - "[Debug] %s \n-------------->(%s:%u, %s)\n", - localMsg.constData(), - context.file, - context.line, - context.function); + fprintf(stdout, "[Debug] %s \n-------------->(%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; } #ifndef QT_NO_DEBUG_OUTPUT @@ -74,7 +49,7 @@ void log_out_put(QtMsgType type, const QMessageLogContext& context, const QStrin int main(int argc, char* argv[]) { - //以下是针对高分屏的设置,有高分屏需求都需要按照下面进行设置 + // 以下是针对高分屏的设置,有高分屏需求都需要按照下面进行设置 #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); #endif diff --git a/src/example/MainWindowExample/mainwindow.cpp b/src/example/MainWindowExample/mainwindow.cpp index b7fc42c9..37ad4e10 100644 --- a/src/example/MainWindowExample/mainwindow.cpp +++ b/src/example/MainWindowExample/mainwindow.cpp @@ -157,12 +157,8 @@ MainWindow::MainWindow(QWidget* par) //! If the actions are created before, the actions added to the ribbon need to be manually managed in the ActionManager. //! The ActionManager can also manage actions not in the ribbon bar createActionsManager(); - setMinimumWidth(500); - // showMaximized(); - // onStyleClicked(SARibbonBar::RibbonStyleLooseThreeRow); - // setWindowIcon(QIcon(":/icon/icon/SA.svg")); } From 1b32431765932580038725511f01fabf473974ae Mon Sep 17 00:00:00 2001 From: czyt1988 Date: Fri, 15 Dec 2023 00:00:07 +0800 Subject: [PATCH 03/16] =?UTF-8?q?=E5=9B=BE=E7=89=87=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E9=AB=98=E5=88=86=E5=B1=8F=E6=AF=94=E4=BE=8B=E7=BC=A9=E6=94=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SARibbonBar/CMakeLists.txt | 2 - src/SARibbonBar/SARibbonBar.pri | 2 - src/SARibbonBar/SARibbonButtonGroupWidget.cpp | 1 - src/SARibbonBar/SARibbonColorToolButton.cpp | 11 +- src/SARibbonBar/SARibbonCtrlContainer.cpp | 6 +- src/SARibbonBar/SARibbonDrawHelper.cpp | 101 ------------------ src/SARibbonBar/SARibbonDrawHelper.h | 38 ------- src/SARibbonBar/SARibbonGlobal.h | 9 ++ src/SARibbonBar/SARibbonMainWindow.cpp | 1 - src/SARibbonBar/SARibbonStyleOption.cpp | 5 + src/SARibbonBar/SARibbonToolButton.cpp | 11 +- 11 files changed, 36 insertions(+), 151 deletions(-) delete mode 100644 src/SARibbonBar/SARibbonDrawHelper.cpp delete mode 100644 src/SARibbonBar/SARibbonDrawHelper.h diff --git a/src/SARibbonBar/CMakeLists.txt b/src/SARibbonBar/CMakeLists.txt index e0f58a42..9f3a8725 100644 --- a/src/SARibbonBar/CMakeLists.txt +++ b/src/SARibbonBar/CMakeLists.txt @@ -219,7 +219,6 @@ SET(SARIBBON_HEADER_FILES SARibbonComboBox.h SARibbonElementFactory.h SARibbonElementManager.h - SARibbonDrawHelper.h SARibbonLineEdit.h SARibbonCheckBox.h SARibbonButtonGroupWidget.h @@ -261,7 +260,6 @@ SET(SARIBBON_SOURCE_FILES SARibbonComboBox.cpp SARibbonElementFactory.cpp SARibbonElementManager.cpp - SARibbonDrawHelper.cpp SARibbonLineEdit.cpp SARibbonCheckBox.cpp SARibbonButtonGroupWidget.cpp diff --git a/src/SARibbonBar/SARibbonBar.pri b/src/SARibbonBar/SARibbonBar.pri index 3d7bb6da..bfd200e0 100644 --- a/src/SARibbonBar/SARibbonBar.pri +++ b/src/SARibbonBar/SARibbonBar.pri @@ -68,7 +68,6 @@ SOURCES += \ $$PWD/SARibbonGalleryItem.cpp \ $$PWD/SARibbonComboBox.cpp \ $$PWD/SARibbonElementManager.cpp \ - $$PWD/SARibbonDrawHelper.cpp \ $$PWD/SARibbonLineEdit.cpp \ $$PWD/SARibbonCheckBox.cpp \ $$PWD/SARibbonButtonGroupWidget.cpp \ @@ -108,7 +107,6 @@ HEADERS += \ $$PWD/SARibbonGalleryItem.h \ $$PWD/SARibbonComboBox.h \ $$PWD/SARibbonElementManager.h \ - $$PWD/SARibbonDrawHelper.h \ $$PWD/SARibbonLineEdit.h \ $$PWD/SARibbonCheckBox.h \ $$PWD/SARibbonButtonGroupWidget.h \ diff --git a/src/SARibbonBar/SARibbonButtonGroupWidget.cpp b/src/SARibbonBar/SARibbonButtonGroupWidget.cpp index 07882f00..cd227c69 100644 --- a/src/SARibbonBar/SARibbonButtonGroupWidget.cpp +++ b/src/SARibbonBar/SARibbonButtonGroupWidget.cpp @@ -115,7 +115,6 @@ QAction* SARibbonButtonGroupWidget::addAction(QAction* a) QAction* SARibbonButtonGroupWidget::addAction(const QString& text, const QIcon& icon, QToolButton::ToolButtonPopupMode popMode) { QAction* a = new QAction(icon, text, this); - addAction(a); ButtonTyle* btn = qobject_cast< ButtonTyle* >(d_ptr->mItems.back().widget); btn->setPopupMode(popMode); diff --git a/src/SARibbonBar/SARibbonColorToolButton.cpp b/src/SARibbonBar/SARibbonColorToolButton.cpp index 8c3d271c..fead4468 100644 --- a/src/SARibbonBar/SARibbonColorToolButton.cpp +++ b/src/SARibbonBar/SARibbonColorToolButton.cpp @@ -42,15 +42,22 @@ QPixmap SARibbonColorToolButton::PrivateData::createIconPixmap(const QStyleOptio mode = QIcon::Normal; } QSize realIconSize = iconsize - QSize(0, c_ribbonbutton_color_height + 1); + realIconSize *= q_ptr->devicePixelRatioF(); QPixmap pixmap = opt.icon.pixmap(q_ptr->window()->windowHandle(), realIconSize, mode, state); + pixmap.setDevicePixelRatio(q_ptr->devicePixelRatioF()); QPixmap res(pixmap.size() + QSize(4, c_ribbonbutton_color_height + 4)); //宽度上,颜色块多出2px + res.setDevicePixelRatio(q_ptr->devicePixelRatioF()); res.fill(Qt::transparent); QPainter painter(&res); int xpixmap = (res.width() - pixmap.width()) / 2; int ypixmap = (res.height() - c_ribbonbutton_color_height - 2 - pixmap.height()) / 2; //这里要减去2而不是1,这样奇数偶数都不会影响 - QRect rpixmap = QRect(xpixmap, ypixmap, pixmap.width(), pixmap.height()); + xpixmap /= q_ptr->devicePixelRatioF(); + ypixmap /= q_ptr->devicePixelRatioF(); + int w = pixmap.width()/q_ptr->devicePixelRatioF(); + int h = pixmap.height()/q_ptr->devicePixelRatioF(); + QRect rpixmap = QRect(xpixmap, ypixmap, w, h); painter.drawPixmap(rpixmap, pixmap); - QRect colorRect = rpixmap.adjusted(0, pixmap.height() + 1, 0, c_ribbonbutton_color_height + 1); + QRect colorRect = rpixmap.adjusted(0, h + 1, 0, c_ribbonbutton_color_height + 1); if (mColor.isValid()) { painter.fillRect(colorRect, mColor); } else { diff --git a/src/SARibbonBar/SARibbonCtrlContainer.cpp b/src/SARibbonBar/SARibbonCtrlContainer.cpp index dcc2f705..ef8f8639 100644 --- a/src/SARibbonBar/SARibbonCtrlContainer.cpp +++ b/src/SARibbonBar/SARibbonCtrlContainer.cpp @@ -5,7 +5,8 @@ #include #include #include - +#include +#include /** * @brief The SARibbonCtrlContainerPrivate class */ @@ -117,7 +118,8 @@ bool SARibbonCtrlContainer::hasContainerWidget() const void SARibbonCtrlContainer::setIcon(const QIcon& i) { d_ptr->icon = i; - QPixmap pixmap = i.pixmap(d_ptr->iconSize); + QPixmap pixmap = i.pixmap(d_ptr->iconSize * devicePixelRatioF()); + pixmap.setDevicePixelRatio(devicePixelRatioF()); d_ptr->labelPixmap->setPixmap(pixmap); } diff --git a/src/SARibbonBar/SARibbonDrawHelper.cpp b/src/SARibbonBar/SARibbonDrawHelper.cpp deleted file mode 100644 index 901fafc6..00000000 --- a/src/SARibbonBar/SARibbonDrawHelper.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include "SARibbonDrawHelper.h" - -SARibbonDrawHelper::SARibbonDrawHelper() -{ -} - -QPixmap SARibbonDrawHelper::iconToPixmap(const QIcon& icon, QWidget* widget, const QStyleOption* opt, const QSize& icoSize) -{ - QIcon::Mode mode; - QIcon::State state; - - if (!(opt->state & QStyle::State_Enabled)) { - mode = QIcon::Disabled; - } else if ((opt->state & QStyle::State_MouseOver) && (opt->state & QStyle::State_AutoRaise)) { - mode = QIcon::Active; - } else { - mode = QIcon::Normal; - } - - if (opt->state & QStyle::State_Selected || opt->state & QStyle::State_On) { - state = QIcon::On; - } else { - state = QIcon::Off; - } - return (icon.pixmap(icoSize, mode, state)); -} - -void SARibbonDrawHelper::drawIcon(const QIcon& icon, QPainter* painter, const QStyleOption* opt, int x, int y, int width, int height) -{ - QIcon::Mode mode; - QIcon::State state; - - if (!(opt->state & QStyle::State_Enabled)) { - mode = QIcon::Disabled; - } else if ((opt->state & QStyle::State_MouseOver) && (opt->state & QStyle::State_AutoRaise)) { - mode = QIcon::Active; - } else { - mode = QIcon::Normal; - } - - if (opt->state & QStyle::State_Selected || opt->state & QStyle::State_On) { - state = QIcon::On; - } else { - state = QIcon::Off; - } - - icon.paint(painter, x, y, width, height, Qt::AlignCenter, mode, state); -} - -void SARibbonDrawHelper::drawIcon(const QIcon& icon, QPainter* painter, const QStyleOption* opt, const QRect& rect) -{ - QIcon::Mode mode; - QIcon::State state; - - if (!(opt->state & QStyle::State_Enabled)) { - mode = QIcon::Disabled; - } else if ((opt->state & QStyle::State_MouseOver) && (opt->state & QStyle::State_AutoRaise)) { - mode = QIcon::Active; - } else { - mode = QIcon::Normal; - } - - if (opt->state & QStyle::State_Selected || opt->state & QStyle::State_On) { - state = QIcon::On; - } else { - state = QIcon::Off; - } - - icon.paint(painter, rect, Qt::AlignCenter, mode, state); -} - -QSize SARibbonDrawHelper::iconActualSize(const QIcon& icon, const QStyleOption* opt, const QSize& iconSize) -{ - QIcon::Mode mode; - QIcon::State state; - - if (!(opt->state & QStyle::State_Enabled)) { - mode = QIcon::Disabled; - } else if ((opt->state & QStyle::State_MouseOver) && (opt->state & QStyle::State_AutoRaise)) { - mode = QIcon::Active; - } else { - mode = QIcon::Normal; - } - - if (opt->state & QStyle::State_Selected || opt->state & QStyle::State_On) { - state = QIcon::On; - } else { - state = QIcon::Off; - } - return (icon.actualSize(iconSize, mode, state)); -} - -void SARibbonDrawHelper::drawText(const QString& text, QStylePainter* painter, const QStyleOption* opt, Qt::Alignment al, int x, int y, int width, int height) -{ - painter->drawItemText(QRect(x, y, width, height), al, opt->palette, opt->state & QStyle::State_Enabled, text); -} - -void SARibbonDrawHelper::drawText(const QString& text, QStylePainter* painter, const QStyleOption* opt, Qt::Alignment al, const QRect& rect) -{ - painter->drawItemText(rect, al, opt->palette, opt->state & QStyle::State_Enabled, text); -} diff --git a/src/SARibbonBar/SARibbonDrawHelper.h b/src/SARibbonBar/SARibbonDrawHelper.h deleted file mode 100644 index 257992bc..00000000 --- a/src/SARibbonBar/SARibbonDrawHelper.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef SARIBBONDRAWHELPER_H -#define SARIBBONDRAWHELPER_H -#include -#include -#include -#include -#include "SARibbonGlobal.h" - -/** - * @def QFontMetrics::horizontalAdvance(str)/QFontMetrics::width(str) 为了兼容5.11以下的qt版本,定义的兼容宏 - */ -#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)) -#ifndef SA_FONTMETRICS_WIDTH -#define SA_FONTMETRICS_WIDTH(fm, str) fm.horizontalAdvance(str) -#endif -#else -#ifndef SA_FONTMETRICS_WIDTH -#define SA_FONTMETRICS_WIDTH(fm, str) fm.width(str) -#endif -#endif - -/// -/// \brief 绘图辅助 -/// -class SA_RIBBON_EXPORT SARibbonDrawHelper -{ -public: - SARibbonDrawHelper(); - static QPixmap iconToPixmap(const QIcon& icon, QWidget* widget, const QStyleOption* opt, const QSize& icoSize); - static void drawIcon(const QIcon& icon, QPainter* painter, const QStyleOption* opt, int x, int y, int width, int height); - static void drawIcon(const QIcon& icon, QPainter* painter, const QStyleOption* opt, const QRect& rect); - static QSize iconActualSize(const QIcon& icon, const QStyleOption* opt, const QSize& iconSize); - - static void drawText(const QString& text, QStylePainter* painter, const QStyleOption* opt, Qt::Alignment al, int x, int y, int width, int height); - static void drawText(const QString& text, QStylePainter* painter, const QStyleOption* opt, Qt::Alignment al, const QRect& rect); -}; - -#endif // SARIBBONDRAWHELPER_H diff --git a/src/SARibbonBar/SARibbonGlobal.h b/src/SARibbonBar/SARibbonGlobal.h index aa6bda95..b7472a15 100644 --- a/src/SARibbonBar/SARibbonGlobal.h +++ b/src/SARibbonBar/SARibbonGlobal.h @@ -169,4 +169,13 @@ enum class SARibbonAlignment */ // #define SARIBBON_USE_3RDPARTY_FRAMELESSHELPER 0 +#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)) +#ifndef SA_FONTMETRICS_WIDTH +#define SA_FONTMETRICS_WIDTH(fm, str) fm.horizontalAdvance(str) +#endif +#else +#ifndef SA_FONTMETRICS_WIDTH +#define SA_FONTMETRICS_WIDTH(fm, str) fm.width(str) +#endif +#endif #endif // SARIBBONGLOBAL_H diff --git a/src/SARibbonBar/SARibbonMainWindow.cpp b/src/SARibbonBar/SARibbonMainWindow.cpp index f4920a90..52ebd75d 100644 --- a/src/SARibbonBar/SARibbonMainWindow.cpp +++ b/src/SARibbonBar/SARibbonMainWindow.cpp @@ -1,6 +1,5 @@ #include "SARibbonMainWindow.h" #include "SARibbonBar.h" -#include "SARibbonDrawHelper.h" #include "SARibbonElementManager.h" #include "SARibbonTabBar.h" #include diff --git a/src/SARibbonBar/SARibbonStyleOption.cpp b/src/SARibbonBar/SARibbonStyleOption.cpp index 4b427e37..64cfbe81 100644 --- a/src/SARibbonBar/SARibbonStyleOption.cpp +++ b/src/SARibbonBar/SARibbonStyleOption.cpp @@ -1,6 +1,7 @@ #include "SARibbonStyleOption.h" #include #include +#include SARibbonStyleOption::SARibbonStyleOption() { init(); @@ -73,7 +74,10 @@ int SARibbonStyleOption::calcMainbarHeight(SARibbonBar::RibbonStyle s) const void SARibbonStyleOption::init() { QFontMetrics fm = QApplication::fontMetrics(); + qreal dr = QApplication::primaryScreen()->devicePixelRatio(); + int lineSpacing = fm.lineSpacing(); + lineSpacing *= dr; m_titleBarHeight = lineSpacing * 1.8; m_tabBarHeight = lineSpacing * 1.5; @@ -102,6 +106,7 @@ QDebug operator<<(QDebug debug, const SARibbonStyleOption& c) QDebugStateSaver saver(debug); Q_UNUSED(saver); debug.nospace() << "fontMetrics.lineSpacing=" << QApplication::fontMetrics().lineSpacing() + << "fontMetrics.height=" << QApplication::fontMetrics().height() << ",SARibbonStyleOption(titleBarHeight=" << c.titleBarHeight() << ",tabBarHeight=" << c.tabBarHeight() << "\n,ribbonBarHeight(OfficeStyle)=" << c.ribbonBarHeight(SARibbonBar::RibbonStyleLooseThreeRow) << "\n,ribbonBarHeight(OfficeStyleTwoRow)=" << c.ribbonBarHeight(SARibbonBar::RibbonStyleLooseTwoRow) diff --git a/src/SARibbonBar/SARibbonToolButton.cpp b/src/SARibbonBar/SARibbonToolButton.cpp index 5e494eda..ebee4365 100644 --- a/src/SARibbonBar/SARibbonToolButton.cpp +++ b/src/SARibbonBar/SARibbonToolButton.cpp @@ -1,5 +1,4 @@ #include "SARibbonToolButton.h" -#include "SARibbonDrawHelper.h" #include "SARibbonElementManager.h" #include #include @@ -11,6 +10,8 @@ #include #include #include +#include +#include /** * @def 定义文字换行时2行文本的矩形高度系数,此系数决定文字区域的高度 * @@ -621,7 +622,13 @@ QPixmap SARibbonToolButton::PrivateData::createIconPixmap(const QStyleOptionTool } else { mode = QIcon::Normal; } - return (opt.icon.pixmap(iconsize - QSize(2, 2), mode, state)); + //添加高分屏支持 + qreal pr = QApplication::primaryScreen()->devicePixelRatio(); + QSize pxiampSize = iconsize - QSize(2, 2); + pxiampSize *= pr; + QPixmap px = opt.icon.pixmap(pxiampSize, mode, state); + px.setDevicePixelRatio(pr); + return px; } int SARibbonToolButton::PrivateData::getTextAlignment() const From e3bbaf30a6609f3131a224934527fd73d5588ff2 Mon Sep 17 00:00:00 2001 From: czyt1988 Date: Fri, 15 Dec 2023 09:04:36 +0800 Subject: [PATCH 04/16] =?UTF-8?q?=E8=B0=83=E6=95=B4=E9=AB=98=E5=88=86?= =?UTF-8?q?=E5=B1=8F=E7=9A=84=E6=98=BE=E7=A4=BA=E6=95=88=E6=9E=9C=EF=BC=8C?= =?UTF-8?q?=E5=8E=BB=E9=99=A4=E6=B2=A1=E7=94=A8=E7=9A=84=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SARibbonBar/SARibbonBar.pri | 2 - src/SARibbonBar/SARibbonElementFactory.cpp | 16 +- src/SARibbonBar/SARibbonElementFactory.h | 11 +- src/SARibbonBar/SARibbonGalleryGroup.cpp | 3 +- src/SARibbonBar/SARibbonPannel.cpp | 4 +- src/SARibbonBar/SARibbonPannelLayout.cpp | 144 ++++--- src/SARibbonBar/SARibbonStyleOption.cpp | 116 ------ src/SARibbonBar/SARibbonStyleOption.h | 59 --- src/SARibbonBar/SAWindowButtonGroup.cpp | 2 +- .../resource/theme-office2013-em.qss | 387 ++++++++++++++++++ src/SARibbonBar/resource/theme-office2013.qss | 83 ++-- 11 files changed, 504 insertions(+), 323 deletions(-) delete mode 100644 src/SARibbonBar/SARibbonStyleOption.cpp delete mode 100644 src/SARibbonBar/SARibbonStyleOption.h create mode 100644 src/SARibbonBar/resource/theme-office2013-em.qss diff --git a/src/SARibbonBar/SARibbonBar.pri b/src/SARibbonBar/SARibbonBar.pri index bfd200e0..844a6332 100644 --- a/src/SARibbonBar/SARibbonBar.pri +++ b/src/SARibbonBar/SARibbonBar.pri @@ -50,7 +50,6 @@ SOURCES += \ $$PWD/SARibbonCustomizeWidget.cpp \ $$PWD/SARibbonElementFactory.cpp \ $$PWD/SARibbonMainWindow.cpp \ - $$PWD/SARibbonStyleOption.cpp \ $$PWD/SAWindowButtonGroup.cpp \ $$PWD/SARibbonApplicationButton.cpp \ $$PWD/SARibbonTabBar.cpp \ @@ -88,7 +87,6 @@ HEADERS += \ $$PWD/SARibbonCustomizeWidget.h \ $$PWD/SARibbonElementFactory.h \ $$PWD/SARibbonMainWindow.h \ - $$PWD/SARibbonStyleOption.h \ $$PWD/SAWindowButtonGroup.h \ $$PWD/SARibbonApplicationButton.h \ $$PWD/SARibbonTabBar.h \ diff --git a/src/SARibbonBar/SARibbonElementFactory.cpp b/src/SARibbonBar/SARibbonElementFactory.cpp index e2bc230b..b4645bea 100644 --- a/src/SARibbonBar/SARibbonElementFactory.cpp +++ b/src/SARibbonBar/SARibbonElementFactory.cpp @@ -16,7 +16,7 @@ #include "SARibbonPannelOptionButton.h" #include "SARibbonPannelLayout.h" -SARibbonElementFactory::SARibbonElementFactory() : mStyleOption(new SARibbonStyleOption()) +SARibbonElementFactory::SARibbonElementFactory() { } @@ -94,20 +94,6 @@ SARibbonQuickAccessBar* SARibbonElementFactory::createQuickAccessBar(QWidget* pa return (new SARibbonQuickAccessBar(parent)); } -SARibbonStyleOption& SARibbonElementFactory::getRibbonStyleOption() -{ - return (*mStyleOption); -} - -/** - * @brief 设置style配置 - * @param opt - */ -void SARibbonElementFactory::setRibbonStyleOption(SARibbonStyleOption* opt) -{ - mStyleOption.reset(opt); -} - /** * @brief 创建SARibbonPannelOptionButton * @param pannel 附属的pannel diff --git a/src/SARibbonBar/SARibbonElementFactory.h b/src/SARibbonBar/SARibbonElementFactory.h index 0c70d193..2248eb3e 100644 --- a/src/SARibbonBar/SARibbonElementFactory.h +++ b/src/SARibbonBar/SARibbonElementFactory.h @@ -7,7 +7,6 @@ #include #include "SARibbonBar.h" #include "SARibbonPannel.h" -#include "SARibbonStyleOption.h" class QWidget; class SARibbonBar; class SARibbonTabBar; @@ -50,16 +49,8 @@ class SA_RIBBON_EXPORT SARibbonElementFactory virtual SARibbonStackedWidget* createRibbonStackedWidget(SARibbonBar* parent); virtual SARibbonButtonGroupWidget* craeteButtonGroupWidget(QWidget* parent); virtual SARibbonQuickAccessBar* createQuickAccessBar(QWidget* parent); - - // SARibbonStyleOption可以进行继承,此函数无需设置为虚函数 - SARibbonStyleOption& getRibbonStyleOption(); - void setRibbonStyleOption(SARibbonStyleOption* opt); - - //创建SARibbonPannelOptionButton + // 创建SARibbonPannelOptionButton virtual SARibbonPannelOptionButton* createRibbonPannelOptionButton(SARibbonPannel* pannel); - -private: - QScopedPointer< SARibbonStyleOption > mStyleOption; }; #endif // SARIBBONELEMENTCREATEDELEGATE_H diff --git a/src/SARibbonBar/SARibbonGalleryGroup.cpp b/src/SARibbonBar/SARibbonGalleryGroup.cpp index eb504151..10f20937 100644 --- a/src/SARibbonBar/SARibbonGalleryGroup.cpp +++ b/src/SARibbonBar/SARibbonGalleryGroup.cpp @@ -4,7 +4,6 @@ #include #include #include "SARibbonElementManager.h" -#include "SARibbonStyleOption.h" /** * @brief The SARibbonGalleryGroupPrivate class */ @@ -262,7 +261,7 @@ void SARibbonGalleryGroup::recalcGridSize(int galleryHeight) } } setGridSize(QSize(w, h)); - //在通过GalleryGroupStyle确定icon的尺寸 + // 在通过GalleryGroupStyle确定icon的尺寸 const int shiftpix = 4; // 这个是移动像素,qt在鼠标移动到图标上时会移动一下,给用户明确的动态,导致如果布局很满会超出显示范围,因此要在此基础上缩放一点 switch (getGalleryGroupStyle()) { case IconWithText: { diff --git a/src/SARibbonBar/SARibbonPannel.cpp b/src/SARibbonBar/SARibbonPannel.cpp index cba6b92c..09aa83fe 100644 --- a/src/SARibbonBar/SARibbonPannel.cpp +++ b/src/SARibbonBar/SARibbonPannel.cpp @@ -664,8 +664,6 @@ int SARibbonPannel::pannelTitleHeight() /** * @brief 设置pannel的全局高度,此函数是个全局的影响 - * @note SARibbonStyleOption会用到此函数,调用设置函数后需要手动重新计算SARibbonStyleOption的内容,@sa SARibbonStyleOption::recalc - * @sa SARibbonStyleOption * @param h */ void SARibbonPannel::setPannelTitleHeight(int h) @@ -728,7 +726,7 @@ void SARibbonPannel::resizeEvent(QResizeEvent* event) if (ThreeRowMode == pannelLayoutMode()) { d_ptr->m_optionActionButton->move(width() - d_ptr->m_optionActionButton->width() - 2, height() - titleHeight() - + (titleHeight() - d_ptr->m_optionActionButton->height()) / 2); + + (titleHeight() - d_ptr->m_optionActionButton->height()) / 2); } else { d_ptr->m_optionActionButton->move(width() - d_ptr->m_optionActionButton->width(), height() - d_ptr->m_optionActionButton->height()); diff --git a/src/SARibbonBar/SARibbonPannelLayout.cpp b/src/SARibbonBar/SARibbonPannelLayout.cpp index 6bf8a68e..a09d39f3 100644 --- a/src/SARibbonBar/SARibbonPannelLayout.cpp +++ b/src/SARibbonBar/SARibbonPannelLayout.cpp @@ -82,7 +82,7 @@ void SARibbonPannelLayout::insertAction(int index, QAction* act, SARibbonPannelI if (item) { m_items.insert(index, item); - //标记需要重新计算尺寸 + // 标记需要重新计算尺寸 invalidate(); } } @@ -245,8 +245,6 @@ const QMargins& SARibbonPannelLayout::pannelContentsMargins() /** * @brief 全局的contentsMargins - * @note SARibbonStyleOption会用到此函数,调用设置函数后需要手动重新计算SARibbonStyleOption的内容,@sa SARibbonStyleOption::recalc - * @sa SARibbonStyleOption * @param m */ void SARibbonPannelLayout::setPannelContentsMargins(const QMargins& m) @@ -313,20 +311,20 @@ SARibbonPannelItem* SARibbonPannelLayout::createItem(QAction* action, SARibbonPa SARibbonPannel* pannel = qobject_cast< SARibbonPannel* >(parentWidget()); if (!pannel) { - //在没有pannel这个函数会返回nullptr + // 在没有pannel这个函数会返回nullptr return (nullptr); } if (QWidgetAction* widgetAction = qobject_cast< QWidgetAction* >(action)) { widget = widgetAction->requestWidget(pannel); if (widget != nullptr) { widget->setAttribute(Qt::WA_LayoutUsesWidgetRect); - customWidget = true; //标记为true,在移除的时候是不会对这个窗口进行删除,false默认会进行删除如SARibbonSeparatorWidget和SARibbonToolButton + customWidget = true; // 标记为true,在移除的时候是不会对这个窗口进行删除,false默认会进行删除如SARibbonSeparatorWidget和SARibbonToolButton } } else if (action->isSeparator()) { SARibbonSeparatorWidget* sep = RibbonSubElementDelegate->createRibbonSeparatorWidget(pannel); widget = sep; } - //不是widget,自动生成SARibbonToolbutton + // 不是widget,自动生成SARibbonToolbutton if (!widget) { SARibbonToolButton::RibbonButtonType buttonType = ((rp == SARibbonPannelItem::Large) ? SARibbonToolButton::LargeButton : SARibbonToolButton::SmallButton); @@ -335,12 +333,12 @@ SARibbonPannelItem* SARibbonPannelLayout::createItem(QAction* action, SARibbonPa button->setFocusPolicy(Qt::NoFocus); button->setButtonType(buttonType); button->setDefaultAction(action); - //根据QAction的属性设置按钮的大小 + // 根据QAction的属性设置按钮的大小 QObject::connect(button, &SARibbonToolButton::triggered, pannel, &SARibbonPannel::actionTriggered); widget = button; } - //这时总会有widget + // 这时总会有widget widget->hide(); SARibbonPannelItem* result = new SARibbonPannelItem(widget); @@ -368,14 +366,14 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) const QMargins& mag = pannelContentsMargins(); const int spacing = this->spacing(); int x = mag.left(); - //获取pannel的布局模式 3行或者2行 - // rowcount 是ribbon的行,有2行和3行两种 + // 获取pannel的布局模式 3行或者2行 + // rowcount 是ribbon的行,有2行和3行两种 const short rowCount = (pannel->pannelLayoutMode() == SARibbonPannel::ThreeRowMode) ? 3 : 2; // largeHeight是对应large占比的高度,pannel->titleHeight()在两行模式返回0 const int largeHeight = calcLargeHeight(setrect, pannel); m_largeHeight = largeHeight; - //计算smallHeight的高度 + // 计算smallHeight的高度 const int smallHeight = (largeHeight - (rowCount - 1) * spacing) / rowCount; // Medium行的y位置 const int yMediumRow0 = (2 == rowCount) ? mag.top() : (mag.top() + ((largeHeight - 2 * smallHeight) / 3)); @@ -389,9 +387,9 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) // item->rowIndex主要用于SARibbonPannelItem::Medium short row = 0; int column = 0; - //记录每列最大的宽度 + // 记录每列最大的宽度 int columMaxWidth = 0; - //记录总宽度 + // 记录总宽度 int totalWidth = 0; int itemCount = m_items.count(); @@ -403,13 +401,13 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) << "\r\n largeHeight:" << largeHeight << "\r\n smallHeight:" << smallHeight << "\r\n rowCount:" << rowCount; #endif - //本列第一、二行占比 + // 本列第一、二行占比 SARibbonPannelItem::RowProportion thisColumnRP0 = SARibbonPannelItem::None; - SARibbonPannelItem* lastGeomItem = nullptr; //记录最后一个设置位置的item + SARibbonPannelItem* lastGeomItem = nullptr; // 记录最后一个设置位置的item for (int i = 0; i < itemCount; ++i) { SARibbonPannelItem* item = m_items.at(i); if (item->isEmpty()) { - //如果是hide就直接跳过 + // 如果是hide就直接跳过 #if SARibbonPannelLayout_DEBUG_PRINT qDebug() << item->widget()->metaObject()->className() << "is hide" << " row:" << row << " col:" << column; @@ -423,21 +421,21 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) Qt::Orientations exp = item->expandingDirections(); if (item->widget()) { - //有窗口是水平扩展,则标记为扩展 + // 有窗口是水平扩展,则标记为扩展 if ((item->widget()->sizePolicy().horizontalPolicy() & QSizePolicy::ExpandFlag)) { m_expandFlag = true; } } SARibbonPannelItem::RowProportion rp = item->rowProportion; if (SARibbonPannelItem::None == rp) { - //为定义行占比但是垂直扩展,就定义为Large占比,否则就是small占比 + // 为定义行占比但是垂直扩展,就定义为Large占比,否则就是small占比 if (exp & Qt::Vertical) { rp = SARibbonPannelItem::Large; } else { rp = SARibbonPannelItem::Small; } } - //开始根据占比和layoutmode来布局 + // 开始根据占比和layoutmode来布局 switch (rp) { case SARibbonPannelItem::Large: { // !!在Large,如果不是处于新列的第一行,就需要进行换列处理 @@ -453,7 +451,7 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) item->columnIndex = column; item->itemWillSetGeometry = QRect(x, mag.top(), hint.width(), largeHeight); columMaxWidth = hint.width(); - //换列,x自动递增到下个坐标,列数增加,行数归零,最大列宽归零 + // 换列,x自动递增到下个坐标,列数增加,行数归零,最大列宽归零 x += (columMaxWidth + spacing); row = 0; columMaxWidth = 0; @@ -469,16 +467,16 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) item->itemWillSetGeometry = QRect(x, yMediumRow0, hint.width(), smallHeight); thisColumnRP0 = SARibbonPannelItem::Medium; columMaxWidth = hint.width(); - //下个row为1 + // 下个row为1 row = 1; // x不变 } else { item->rowIndex = 1; item->columnIndex = column; item->itemWillSetGeometry = QRect(x, yMediumRow1, hint.width(), smallHeight); - //和上个进行比较得到最长宽度 + // 和上个进行比较得到最长宽度 columMaxWidth = qMax(columMaxWidth, hint.width()); - //换列,x自动递增到下个坐标,列数增加,行数归零,最大列宽归零 + // 换列,x自动递增到下个坐标,列数增加,行数归零,最大列宽归零 x += (columMaxWidth + spacing); row = 0; columMaxWidth = 0; @@ -499,18 +497,18 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) item->columnIndex = column; item->itemWillSetGeometry = QRect(x, yMediumRow1, hint.width(), smallHeight); columMaxWidth = qMax(columMaxWidth, hint.width()); - //换列,x自动递增到下个坐标,列数增加,行数归零,最大列宽归零 + // 换列,x自动递增到下个坐标,列数增加,行数归零,最大列宽归零 x += (columMaxWidth + spacing); row = 0; columMaxWidth = 0; ++column; } else { - //这种模式一般情况会发生在当前列前两行是Small,添加了一个Medium - //这时需要先换列 - //换列,x自动递增到下个坐标,列数增加,行数归零,最大列宽归零 + // 这种模式一般情况会发生在当前列前两行是Small,添加了一个Medium + // 这时需要先换列 + // 换列,x自动递增到下个坐标,列数增加,行数归零,最大列宽归零 x += (columMaxWidth + spacing); ++column; - //换列后此时等价于0 == row + // 换列后此时等价于0 == row item->rowIndex = 0; item->columnIndex = column; item->itemWillSetGeometry = QRect(x, yMediumRow0, hint.width(), smallHeight); @@ -523,55 +521,55 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) case SARibbonPannelItem::Small: { if (0 == row) { - //第一行 + // 第一行 item->rowIndex = 0; item->columnIndex = column; item->itemWillSetGeometry = QRect(x, ySmallRow0, hint.width(), smallHeight); thisColumnRP0 = SARibbonPannelItem::Small; columMaxWidth = hint.width(); - //下个row为1 + // 下个row为1 row = 1; // x不变 } else if (1 == row) { - //第二行 + // 第二行 item->rowIndex = 1; item->columnIndex = column; item->itemWillSetGeometry = QRect(x, ySmallRow1, hint.width(), smallHeight); if ((3 == rowCount) && (SARibbonPannelItem::Medium == thisColumnRP0)) { - //三行模式,并且第一行是Medium + // 三行模式,并且第一行是Medium item->itemWillSetGeometry = QRect(x, yMediumRow1, hint.width(), smallHeight); } - //和上个进行比较得到最长宽度 + // 和上个进行比较得到最长宽度 columMaxWidth = qMax(columMaxWidth, hint.width()); - //这里要看两行还是三行,确定是否要换列 + // 这里要看两行还是三行,确定是否要换列 if (2 == rowCount) { - //两行模式,换列 - //换列,x自动递增到下个坐标,列数增加,行数归零,最大列宽归零 + // 两行模式,换列 + // 换列,x自动递增到下个坐标,列数增加,行数归零,最大列宽归零 x += (columMaxWidth + spacing); row = 0; columMaxWidth = 0; ++column; } else { - //三行模式,继续增加行数 + // 三行模式,继续增加行数 row = 2; // x不变 } if ((3 == rowCount) && (SARibbonPannelItem::Medium == thisColumnRP0)) { - //三行模式,并且第一行是Medium,换列 - //换列,x自动递增到下个坐标,列数增加,行数归零,最大列宽归零 + // 三行模式,并且第一行是Medium,换列 + // 换列,x自动递增到下个坐标,列数增加,行数归零,最大列宽归零 x += (columMaxWidth + spacing); row = 0; columMaxWidth = 0; ++column; } } else { - //第三行 + // 第三行 item->rowIndex = 2; item->columnIndex = column; item->itemWillSetGeometry = QRect(x, ySmallRow2, hint.width(), smallHeight); - //和上个进行比较得到最长宽度 + // 和上个进行比较得到最长宽度 columMaxWidth = qMax(columMaxWidth, hint.width()); - //换列,x自动递增到下个坐标,列数增加,行数归零,最大列宽归零 + // 换列,x自动递增到下个坐标,列数增加,行数归零,最大列宽归零 x += (columMaxWidth + spacing); row = 0; columMaxWidth = 0; @@ -580,7 +578,7 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) } break; default: - //不可能出现 + // 不可能出现 break; } lastGeomItem = item; @@ -590,30 +588,30 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) << " itemWillSetGeometry:" << item->itemWillSetGeometry << " sizeHint:" << hint << " x:" << x; #endif } - //最后一个元素,更新列数 - // 2022-06-20 此句本来在循环里面,如果最后一个元素隐藏,会导致无法到达此判断导致异常 - if (lastGeomItem) { //最后一个元素,更新totalWidth + // 最后一个元素,更新列数 + // 2022-06-20 此句本来在循环里面,如果最后一个元素隐藏,会导致无法到达此判断导致异常 + if (lastGeomItem) { // 最后一个元素,更新totalWidth if (lastGeomItem->columnIndex != column) { - //说明最后一个元素处于最后位置,触发了换列,此时真实列数需要减1,直接等于column索引 + // 说明最后一个元素处于最后位置,触发了换列,此时真实列数需要减1,直接等于column索引 m_columnCount = column; - //由于最后一个元素触发了换列,x值是新一列的位置,直接作为totalWidth + // 由于最后一个元素触发了换列,x值是新一列的位置,直接作为totalWidth totalWidth = x + mag.right(); } else { - //说明最后一个元素处于非最后位置,没有触发下一个换列,此时真实列数等于column索引+1 + // 说明最后一个元素处于非最后位置,没有触发下一个换列,此时真实列数等于column索引+1 m_columnCount = column + 1; - //由于最后一个元素未触发换列,需要计算totalWidth + // 由于最后一个元素未触发换列,需要计算totalWidth totalWidth = x + columMaxWidth + spacing + mag.right(); } } - //在有optionButton情况下,的2行模式,需要调整totalWidth + // 在有optionButton情况下,的2行模式,需要调整totalWidth if (pannel->isTwoRow()) { if (pannel->isHaveOptionAction()) { totalWidth += pannel->optionActionButtonSize().width(); } } - //在设置完所有窗口后,再设置扩展属性的窗口 + // 在设置完所有窗口后,再设置扩展属性的窗口 if (totalWidth < setrect.width()) { - //说明可以设置扩展属性的窗口 + // 说明可以设置扩展属性的窗口 recalcExpandGeomArray(setrect); } this->m_sizeHint = QSize(totalWidth, height); @@ -624,14 +622,14 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) void SARibbonPannelLayout::recalcExpandGeomArray(const QRect& setrect) { - //计算能扩展的尺寸 + // 计算能扩展的尺寸 int expandwidth = setrect.width() - this->m_sizeHint.width(); if (expandwidth <= 0) { - //没有必要设置 + // 没有必要设置 return; } - //列扩展信息 + // 列扩展信息 struct _columnExpandInfo { int oldColumnWidth = 0; ///< 原来的列宽 @@ -639,12 +637,12 @@ void SARibbonPannelLayout::recalcExpandGeomArray(const QRect& setrect) int columnExpandedWidth = 0; ///< 扩展后列的宽度 QList< SARibbonPannelItem* > expandItems; }; - //此变量用于记录可以水平扩展的列和控件,在布局结束后,如果还有空间,就把水平扩展的控件进行扩展 + // 此变量用于记录可以水平扩展的列和控件,在布局结束后,如果还有空间,就把水平扩展的控件进行扩展 QMap< int, _columnExpandInfo > columnExpandInfo; for (SARibbonPannelItem* item : qAsConst(m_items)) { if ((!item->isEmpty()) && item->expandingDirections() & Qt::Horizontal) { - //只获取可见的 + // 只获取可见的 QMap< int, _columnExpandInfo >::iterator i = columnExpandInfo.find(item->columnIndex); if (i == columnExpandInfo.end()) { i = columnExpandInfo.insert(item->columnIndex, _columnExpandInfo()); @@ -653,11 +651,11 @@ void SARibbonPannelLayout::recalcExpandGeomArray(const QRect& setrect) } } if (columnExpandInfo.size() <= 0) { - //没有需要扩展的就退出 + // 没有需要扩展的就退出 return; } - //获取完可扩展的列和控件后,计算对应的列的尺寸 - //计算能扩展的尺寸 + // 获取完可扩展的列和控件后,计算对应的列的尺寸 + // 计算能扩展的尺寸 int oneColCanexpandWidth = expandwidth / columnExpandInfo.size(); for (QMap< int, _columnExpandInfo >::iterator i = columnExpandInfo.begin(); i != columnExpandInfo.end();) { @@ -665,41 +663,41 @@ void SARibbonPannelLayout::recalcExpandGeomArray(const QRect& setrect) int& columnMaximumWidth = i.value().columnMaximumWidth; this->columnWidthInfo(i.key(), oldColumnWidth, columnMaximumWidth); if ((oldColumnWidth <= 0) || (oldColumnWidth > columnMaximumWidth)) { - //如果小于0说明没有这个列,这种属于异常,删除继续 - // oldColumnWidth > columnMaximumWidth也是异常 + // 如果小于0说明没有这个列,这种属于异常,删除继续 + // oldColumnWidth > columnMaximumWidth也是异常 i = columnExpandInfo.erase(i); continue; } - //开始调整 - int colwidth = oneColCanexpandWidth + oldColumnWidth; //先扩展了 + // 开始调整 + int colwidth = oneColCanexpandWidth + oldColumnWidth; // 先扩展了 if (colwidth >= columnMaximumWidth) { - //过最大宽度要求 + // 过最大宽度要求 i.value().columnExpandedWidth = columnMaximumWidth; } else { i.value().columnExpandedWidth = colwidth; } ++i; } - //从新调整尺寸 - //由于会涉及其他列的变更,因此需要所有都遍历一下 + // 从新调整尺寸 + // 由于会涉及其他列的变更,因此需要所有都遍历一下 for (auto i = columnExpandInfo.begin(); i != columnExpandInfo.end(); ++i) { int moveXLen = i.value().columnExpandedWidth - i.value().oldColumnWidth; for (SARibbonPannelItem* item : qAsConst(m_items)) { if (item->isEmpty() || (item->columnIndex < i.key())) { - //之前的列不用管 + // 之前的列不用管 continue; } if (item->columnIndex == i.key()) { - //此列的扩展 + // 此列的扩展 if (i.value().expandItems.contains(item)) { - //此列需要扩展的item才扩展尺寸 + // 此列需要扩展的item才扩展尺寸 item->itemWillSetGeometry.setWidth(i.value().columnExpandedWidth); } else { - //此列不扩展的模块保持原来的尺寸 + // 此列不扩展的模块保持原来的尺寸 continue; } } else { - //后面的移动 + // 后面的移动 item->itemWillSetGeometry.moveLeft(item->itemWillSetGeometry.x() + moveXLen); } } diff --git a/src/SARibbonBar/SARibbonStyleOption.cpp b/src/SARibbonBar/SARibbonStyleOption.cpp deleted file mode 100644 index 64cfbe81..00000000 --- a/src/SARibbonBar/SARibbonStyleOption.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include "SARibbonStyleOption.h" -#include -#include -#include -SARibbonStyleOption::SARibbonStyleOption() -{ - init(); -} - -SARibbonStyleOption::~SARibbonStyleOption() -{ -} - -int SARibbonStyleOption::ribbonBarHeight(SARibbonBar::RibbonStyle s) const -{ - switch (s) { - case SARibbonBar::RibbonStyleLooseThreeRow: - return m_ribbonbarHeightOfficeStyleThreeRow; - case SARibbonBar::RibbonStyleLooseTwoRow: - return m_ribbonbarHeightOfficeStyleTwoRow; - case SARibbonBar::RibbonStyleCompactThreeRow: - return m_ribbonbarHeightWPSStyleThreeRow; - case SARibbonBar::RibbonStyleCompactTwoRow: - return m_ribbonbarHeightWPSStyleTwoRow; - default: - break; - } - return m_ribbonbarHeightOfficeStyleThreeRow; -} - -/** - * @brief 标题栏高度 - * @return - */ -int SARibbonStyleOption::titleBarHeight() const -{ - return m_titleBarHeight; -} - -int SARibbonStyleOption::tabBarHeight() const -{ - return m_tabBarHeight; -} - -void SARibbonStyleOption::recalc() -{ - updateMainbarHeight(); -} - -/** - * @brief 计算ribbon的高度 - * - * @note 调用此函数之前必须调用 - * @param s - * @return - */ -int SARibbonStyleOption::calcMainbarHeight(SARibbonBar::RibbonStyle s) const -{ - switch (s) { - case SARibbonBar::RibbonStyleCompactThreeRow: - // 不是减去m_titleBarHeight原因是绘制wps的样式时,标题栏是存在,只是把bar画在标题栏上,相当于没有bar - return m_ribbonbarHeightOfficeStyleThreeRow - m_tabBarHeight; - case SARibbonBar::RibbonStyleCompactTwoRow: - //两行模式把标题栏去掉 - return m_ribbonbarHeightOfficeStyleThreeRow * 0.9 - m_tabBarHeight - SARibbonPannel::pannelTitleHeight(); - case SARibbonBar::RibbonStyleLooseTwoRow: - return m_ribbonbarHeightOfficeStyleThreeRow * 0.9 - SARibbonPannel::pannelTitleHeight(); - default: - break; - } - return m_ribbonbarHeightOfficeStyleThreeRow; -} - -void SARibbonStyleOption::init() -{ - QFontMetrics fm = QApplication::fontMetrics(); - qreal dr = QApplication::primaryScreen()->devicePixelRatio(); - - int lineSpacing = fm.lineSpacing(); - lineSpacing *= dr; - - m_titleBarHeight = lineSpacing * 1.8; - m_tabBarHeight = lineSpacing * 1.5; - m_ribbonbarHeightOfficeStyleThreeRow = m_titleBarHeight + m_tabBarHeight + (lineSpacing * 1.5) * 3 - + SARibbonPannel::pannelTitleHeight() - + SARibbonPannelLayout::pannelContentsMargins().bottom() - + SARibbonPannelLayout::pannelContentsMargins().top(); - updateMainbarHeight(); -} - -void SARibbonStyleOption::updateMainbarHeight() -{ - m_ribbonbarHeightWPSStyleThreeRow = calcMainbarHeight(SARibbonBar::RibbonStyleCompactThreeRow); - m_ribbonbarHeightOfficeStyleTwoRow = calcMainbarHeight(SARibbonBar::RibbonStyleLooseTwoRow); - m_ribbonbarHeightWPSStyleTwoRow = calcMainbarHeight(SARibbonBar::RibbonStyleCompactTwoRow); -} - -/** - * @brief 对SARibbonStyleOption输出 - * @param debug - * @param c - * @return - */ -QDebug operator<<(QDebug debug, const SARibbonStyleOption& c) -{ - QDebugStateSaver saver(debug); - Q_UNUSED(saver); - debug.nospace() << "fontMetrics.lineSpacing=" << QApplication::fontMetrics().lineSpacing() - << "fontMetrics.height=" << QApplication::fontMetrics().height() - << ",SARibbonStyleOption(titleBarHeight=" << c.titleBarHeight() << ",tabBarHeight=" << c.tabBarHeight() - << "\n,ribbonBarHeight(OfficeStyle)=" << c.ribbonBarHeight(SARibbonBar::RibbonStyleLooseThreeRow) - << "\n,ribbonBarHeight(OfficeStyleTwoRow)=" << c.ribbonBarHeight(SARibbonBar::RibbonStyleLooseTwoRow) - << "\n,ribbonBarHeight(WpsLiteStyle)=" << c.ribbonBarHeight(SARibbonBar::RibbonStyleCompactThreeRow) - << "\n,ribbonBarHeight(WpsLiteStyleTwoRow)=" << c.ribbonBarHeight(SARibbonBar::RibbonStyleCompactTwoRow); - return debug; -} diff --git a/src/SARibbonBar/SARibbonStyleOption.h b/src/SARibbonBar/SARibbonStyleOption.h deleted file mode 100644 index c70f3287..00000000 --- a/src/SARibbonBar/SARibbonStyleOption.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef SARIBBONSTYLEOPTION_H -#define SARIBBONSTYLEOPTION_H -#include "SARibbonGlobal.h" -#include "SARibbonBar.h" -#include -/** - * @brief 定义了saribbon所有尺寸相关信息,saribbon的建立都基于此类的尺寸,如果想调整, - * 可以通过 @ref SARibbonElementCreateDelegate(通过SARibbonElementManager单例管理) 的 @ref setRibbonStyleOption 函数设置自己的SARibbonStyleOption - * - * @sa SARibbonElementManager - * - * 一般SARibbonElementCreateDelegate::setRibbonStyleOption函数最好在ribbonbar构建之前调用 - * - * @note 此类定义了ribbonbar和pannel的高度信息,并通过字体提前计算好一些布局信息 - * - * @todo 后续开发通过配置文件定义ribbon的尺寸布局 - */ -class SA_RIBBON_EXPORT SARibbonStyleOption -{ -public: - SARibbonStyleOption(); - virtual ~SARibbonStyleOption(); - -public: - // ribbonBar的高度 - virtual int ribbonBarHeight(SARibbonBar::RibbonStyle s) const; - - // 标题栏的高度,对于wps模式,此参数没有用 - virtual int titleBarHeight() const; - - // 标签栏高度 - virtual int tabBarHeight() const; - - // 在改变了参数后对需要计算的变量从新计算 - virtual void recalc(); - -protected: - // 通过已有参数计算pannel的高度 - // int calcPannelHeight(SARibbonPannel::PannelLayoutMode lm) const; - // 计算ribbon的高度 - int calcMainbarHeight(SARibbonBar::RibbonStyle s) const; - -private: - // 初始化 - void init(); - // 计算pannel的高度 - void updateMainbarHeight(); - -private: - int m_tabBarHeight; ///< ribbon tab 的高度 - int m_titleBarHeight; ///< 标题栏高度 - int m_ribbonbarHeightOfficeStyleThreeRow; ///< office样式的3行高度 - int m_ribbonbarHeightWPSStyleThreeRow; ///< wps样式3行的高度 - int m_ribbonbarHeightWPSStyleTwoRow; ///< wps样式2行的高度 - int m_ribbonbarHeightOfficeStyleTwoRow; ///< office样式2行的高度 -}; - -SA_RIBBON_EXPORT QDebug operator<<(QDebug debug, const SARibbonStyleOption& c); -#endif // SARIBBONSTYLEOPTION_H diff --git a/src/SARibbonBar/SAWindowButtonGroup.cpp b/src/SARibbonBar/SAWindowButtonGroup.cpp index e526deea..1d6f56ff 100644 --- a/src/SARibbonBar/SAWindowButtonGroup.cpp +++ b/src/SARibbonBar/SAWindowButtonGroup.cpp @@ -154,7 +154,7 @@ class SAWindowButtonGroup::PrivateData QSize sizeHint() const { int width = 0; - int height = RibbonSubElementStyleOpt.titleBarHeight(); + int height = 30; if (buttonClose) { width += 40; diff --git a/src/SARibbonBar/resource/theme-office2013-em.qss b/src/SARibbonBar/resource/theme-office2013-em.qss new file mode 100644 index 00000000..6f8b8ded --- /dev/null +++ b/src/SARibbonBar/resource/theme-office2013-em.qss @@ -0,0 +1,387 @@ +/* +这是模仿office2013的白色风格主题 +start ribbon set +*/ + +/*SARibbonBar*/ +SARibbonBar { + background-color: white; + border: solid #707070; + color:#b2b2b2; + /* border-width: 0.02em 0.02em 0em 0.02em; */ +} + +/*SARibbonButtonGroupWidget*/ +SARibbonButtonGroupWidget { + background-color: transparent; +} + + +/*SARibbonQuickAccessBar*/ +SARibbonQuickAccessBar { + background-color: #cee8fc; +} + +/*SARibbonCtrlContainer*/ +SARibbonCtrlContainer { + background-color: transparent; +} + +/*SARibbonCategory*/ +SARibbonCategory:focus { + outline: none; +} + +SARibbonCategory { + background-color: #fcfdfe; +} + +/*SARibbonStackedWidget*/ +SARibbonStackedWidget { + background-color: white; + border: 1pt solid #c5d2e0; + border-top-width: 0px; +} + +SARibbonStackedWidget:focus { + outline: none; +} + +/*SARibbonApplicationButton*/ +SARibbonApplicationButton { + color: white; + border-top-left-radius: 0.1em; + border-top-right-radius: 0.1em; + background-color: #2b579a; +} + +SARibbonApplicationButton:hover { + background-color: #5888d0; +} + +SARibbonApplicationButton:pressed { + background-color: #3369b9; +} + +SARibbonApplicationButton:focus { + outline: none; +} + +SARibbonApplicationButton::menu-indicator { + subcontrol-position: right; +} + +/*SARibbonTabBar*/ +SARibbonTabBar { + background-color: transparent; +} + + +SARibbonTabBar::tab { + color: #5779af; + border: none; + background: transparent; + margin-top: 0em; + margin-right: 0em; + margin-left: 0.2em; + margin-bottom: 0em; + min-width: 3em; + max-width: 10em; + min-height: 1.2em; + max-height: 1.2em; + padding-left: 0.2em; + padding-right: 0.2em; + padding-top: 0.1em; + padding-bottom: 0.2em; +} + +SARibbonTabBar::tab:selected, SARibbonTabBar::tab:hover { + border-top-left-radius: 0px; + border-top-right-radius: 0px; +} + +SARibbonTabBar::tab:selected { + color: #5779af; + border: 0.05em solid #c5d2e0; + background: white; + border-bottom: none; +} + +SARibbonTabBar::tab:hover:!selected { + border:0.05em solid #c5d2e0; + border-bottom: none; + color: #5779af; +} + +SARibbonTabBar::tab:!selected { + margin-top: 0px; +} + +/*SARibbonToolButton*/ +/* +SARibbonToolButton的背景颜色必须和pannel或者category的颜色一致 +不能设置为transparent,否则在ActionMenu模式下,上下区分的按钮无法显示 +*/ +SARibbonToolButton { + border: none; + color: #333; + background-color: white; +} + +SARibbonToolButton:focus { + border: 0.05em solid #b9defa; + color: #333; + background-color: #fcfdfe; +} + +SARibbonToolButton:pressed { + color: #000; + border: 0.05em solid #269bf4; + background-color: #9ed2f9; +} + +SARibbonToolButton:checked { + color: #333; + border: 0.05em solid #b9defa; + background-color: #cee8fc; +} + +SARibbonToolButton:hover { + color: #000; + border: 0.05em solid #badffa; + background-color: #cee7fc; +} + +/*SARibbonControlButton*/ + +SARibbonControlButton { + background-color: transparent; + border: 0.05em solid transparent; + color: #333; +} + +SARibbonControlButton:pressed { + border: 0.05em solid #269bf4; + background-color: #9ed2f9; +} + +SARibbonControlButton:checked { + border: 0.05em solid #b9defa; + background-color: #cee8fc; +} + +SARibbonControlButton:hover { + border: 0.05em solid #badffa; + background-color: #cee7fc; +} +SARibbonControlButton#SARibbonGalleryButtonUp, #SARibbonGalleryButtonDown, #SARibbonGalleryButtonMore { + border: 0.05em solid #cee8fc; +} + +SARibbonControlButton#SARibbonBarHidePannelButton { + border: 0.05em solid transparent; +} + + + +/*SARibbonMenu*/ + +SARibbonMenu { + color: #333; + background-color: #FCFCFC; + border: 0.05em solid #c2d0df; +} + +SARibbonMenu::item { + padding: 5px 5px 5px 5px; + background-color: transparent; +} + +SARibbonMenu::item:selected { + background-color: #cee8fc; +} + +SARibbonMenu::item:hover { + color: #000; + background-color: #cee7fc; + border: 0.05em solid #badffa; +} + +SARibbonMenu::icon { + margin-left: 0.05em; +} + +/*SARibbonPannelOptionButton*/ + +SARibbonPannelOptionButton { + background-color: transparent; + color: #333; +} + +SARibbonPannelOptionButton:hover { + background-color: #cee7fc; + border: 0px; +} + +/*SARibbonPannel*/ + +SARibbonPannel { + background-color: white; + border: 0px; + color: #666666; +} + +SARibbonPannel > SARibbonButtonGroupWidget { + border: 0.05em solid #c2d0df; +} + +/*SARibbonGallery*/ + +SARibbonGallery { + border: 0.05em solid #c2d0df; + background-color: transparent; + color: #333; +} + +/*SARibbonGalleryGroup*/ + +SARibbonGalleryGroup { + show-decoration-selected: 1; + background-color: transparent; + color: #333; + border: 0.05em solid #c2d0df; +} + +SARibbonGalleryGroup::item:selected { + background-color: #9ed2f9; + color: black; +} + +SARibbonGalleryGroup::item:hover { + border: 0.1em solid #badffa; + background-color: #cee7fc; +} + +/*RibbonGalleryViewport*/ + +SARibbonGalleryViewport { + background-color: #ffffff; +} + +/*SARibbonLineEdit*/ + +SARibbonLineEdit { + border: 0.05em solid #C0C2C4; + background: #FFF; + selection-background-color: #9BBBF7; + selection-color: #000; +} + +/*SARibbonComboBox*/ + +SARibbonComboBox { + border: 0.05em solid #c2d0df; + background-color: white; +} + +SARibbonComboBox:hover { + border: 0.05em solid #269bf4; + color: #000; +} + +SARibbonComboBox:editable { + color: #000; + background: white; + selection-background-color: #9BBBF7; + selection-color: #000; +} + +SARibbonComboBox::drop-down { + subcontrol-origin: padding; + subcontrol-position: top right; + width: 1em; + border: none; +} + +SARibbonComboBox::drop-down:hover { + border: 0.05em solid #FDEEB3; + background-color: #9ed2f9; +} + +SARibbonComboBox::down-arrow { + image: url(:/image/resource/ArrowDown.png); +} + +/*SARibbonSeparatorWidget*/ + +SARibbonSeparatorWidget { + /*background-color: transparent;*/ + background-color: white; +} + +SARibbonCategoryScrollButton { + border: 0.05em solid #c5d2e0; + color: #333; + background-color: white; +} + +SARibbonCategoryScrollButton[arrowType="3"] { + border-right-width: 0.05em; +} + +SARibbonCategoryScrollButton[arrowType="4"] { + border-left-width: 0.05em; +} + +SARibbonCategoryScrollButton:hover { + color: #000000; + background-color: #cee7fc; +} + +SAWindowToolButton { + background-color: transparent; + border:none; +} + +SAWindowToolButton:focus { + outline: none; +} + +SAWindowToolButton#SAMinimizeWindowButton { + image: url(:/image/resource/Titlebar_Min.png); +} + +SAWindowToolButton#SAMaximizeWindowButton:checked { + image:url(:/image/resource/Titlebar_Normal.png); +} + +SAWindowToolButton#SAMaximizeWindowButton { + image:url(:/image/resource/Titlebar_Max.png); +} + +SAWindowToolButton#SAMinimizeWindowButton:hover,#SAMaximizeWindowButton:hover { + background-color: #e5e5e5; +} + +SAWindowToolButton#SAMinimizeWindowButton:pressed,#SAMaximizeWindowButton:pressed { + background-color: #cacacb; +} + +SAWindowToolButton#SACloseWindowButton { + image: url(:/image/resource/Titlebar_Close.png); +} + +SAWindowToolButton#SACloseWindowButton:hover { + background-color: #e81123; + image: url(:/image/resource/Titlebar_Close_Hover.png); +} + +SAWindowToolButton#SACloseWindowButton:pressed { + background-color: #f1707a; + image: url(:/image/resource/Titlebar_Close_Hover.png); +} + +SAWindowToolButton#SARibbonBarHidePannelButton { + titlebar-shade-icon: url(:/image/resource/Titlebar_Shade.png); + titlebar-unshade-icon: url(:/image/resource/Titlebar_Unshade.png); +} diff --git a/src/SARibbonBar/resource/theme-office2013.qss b/src/SARibbonBar/resource/theme-office2013.qss index 6f8b8ded..04940334 100644 --- a/src/SARibbonBar/resource/theme-office2013.qss +++ b/src/SARibbonBar/resource/theme-office2013.qss @@ -8,7 +8,6 @@ SARibbonBar { background-color: white; border: solid #707070; color:#b2b2b2; - /* border-width: 0.02em 0.02em 0em 0.02em; */ } /*SARibbonButtonGroupWidget*/ @@ -50,8 +49,8 @@ SARibbonStackedWidget:focus { /*SARibbonApplicationButton*/ SARibbonApplicationButton { color: white; - border-top-left-radius: 0.1em; - border-top-right-radius: 0.1em; + border-top-left-radius: 2px; + border-top-right-radius: 2px; background-color: #2b579a; } @@ -81,18 +80,18 @@ SARibbonTabBar::tab { color: #5779af; border: none; background: transparent; - margin-top: 0em; - margin-right: 0em; - margin-left: 0.2em; - margin-bottom: 0em; - min-width: 3em; - max-width: 10em; - min-height: 1.2em; - max-height: 1.2em; - padding-left: 0.2em; - padding-right: 0.2em; - padding-top: 0.1em; - padding-bottom: 0.2em; + margin-top: 0px; + margin-right: 0px; + margin-left: 5px; + margin-bottom: 0px; + min-width: 50px; + max-width: 200px; + min-height: 20px; + max-height: 20px; + padding-left: 5px; + padding-right: 5px; + padding-top: 2px; + padding-bottom: 5px; } SARibbonTabBar::tab:selected, SARibbonTabBar::tab:hover { @@ -102,13 +101,13 @@ SARibbonTabBar::tab:selected, SARibbonTabBar::tab:hover { SARibbonTabBar::tab:selected { color: #5779af; - border: 0.05em solid #c5d2e0; + border: 1px solid #c5d2e0; background: white; border-bottom: none; } SARibbonTabBar::tab:hover:!selected { - border:0.05em solid #c5d2e0; + border:1px solid #c5d2e0; border-bottom: none; color: #5779af; } @@ -129,26 +128,26 @@ SARibbonToolButton { } SARibbonToolButton:focus { - border: 0.05em solid #b9defa; + border: 1px solid #b9defa; color: #333; background-color: #fcfdfe; } SARibbonToolButton:pressed { color: #000; - border: 0.05em solid #269bf4; + border: 1px solid #269bf4; background-color: #9ed2f9; } SARibbonToolButton:checked { color: #333; - border: 0.05em solid #b9defa; + border: 1px solid #b9defa; background-color: #cee8fc; } SARibbonToolButton:hover { color: #000; - border: 0.05em solid #badffa; + border: 1px solid #badffa; background-color: #cee7fc; } @@ -156,30 +155,30 @@ SARibbonToolButton:hover { SARibbonControlButton { background-color: transparent; - border: 0.05em solid transparent; + border: 1px solid transparent; color: #333; } SARibbonControlButton:pressed { - border: 0.05em solid #269bf4; + border: 1px solid #269bf4; background-color: #9ed2f9; } SARibbonControlButton:checked { - border: 0.05em solid #b9defa; + border: 1px solid #b9defa; background-color: #cee8fc; } SARibbonControlButton:hover { - border: 0.05em solid #badffa; + border: 1px solid #badffa; background-color: #cee7fc; } SARibbonControlButton#SARibbonGalleryButtonUp, #SARibbonGalleryButtonDown, #SARibbonGalleryButtonMore { - border: 0.05em solid #cee8fc; + border: 1px solid #cee8fc; } SARibbonControlButton#SARibbonBarHidePannelButton { - border: 0.05em solid transparent; + border: 1px solid transparent; } @@ -189,7 +188,7 @@ SARibbonControlButton#SARibbonBarHidePannelButton { SARibbonMenu { color: #333; background-color: #FCFCFC; - border: 0.05em solid #c2d0df; + border: 1px solid #c2d0df; } SARibbonMenu::item { @@ -204,11 +203,11 @@ SARibbonMenu::item:selected { SARibbonMenu::item:hover { color: #000; background-color: #cee7fc; - border: 0.05em solid #badffa; + border: 1px solid #badffa; } SARibbonMenu::icon { - margin-left: 0.05em; + margin-left: 1px; } /*SARibbonPannelOptionButton*/ @@ -232,13 +231,13 @@ SARibbonPannel { } SARibbonPannel > SARibbonButtonGroupWidget { - border: 0.05em solid #c2d0df; + border: 1px solid #c2d0df; } /*SARibbonGallery*/ SARibbonGallery { - border: 0.05em solid #c2d0df; + border: 1px solid #c2d0df; background-color: transparent; color: #333; } @@ -249,7 +248,7 @@ SARibbonGalleryGroup { show-decoration-selected: 1; background-color: transparent; color: #333; - border: 0.05em solid #c2d0df; + border: 1px solid #c2d0df; } SARibbonGalleryGroup::item:selected { @@ -258,7 +257,7 @@ SARibbonGalleryGroup::item:selected { } SARibbonGalleryGroup::item:hover { - border: 0.1em solid #badffa; + border: 1px solid #badffa; background-color: #cee7fc; } @@ -271,7 +270,7 @@ SARibbonGalleryViewport { /*SARibbonLineEdit*/ SARibbonLineEdit { - border: 0.05em solid #C0C2C4; + border: 1px solid #C0C2C4; background: #FFF; selection-background-color: #9BBBF7; selection-color: #000; @@ -280,12 +279,12 @@ SARibbonLineEdit { /*SARibbonComboBox*/ SARibbonComboBox { - border: 0.05em solid #c2d0df; + border: 1px solid #c2d0df; background-color: white; } SARibbonComboBox:hover { - border: 0.05em solid #269bf4; + border: 1px solid #269bf4; color: #000; } @@ -299,12 +298,12 @@ SARibbonComboBox:editable { SARibbonComboBox::drop-down { subcontrol-origin: padding; subcontrol-position: top right; - width: 1em; + width: 15px; border: none; } SARibbonComboBox::drop-down:hover { - border: 0.05em solid #FDEEB3; + border: 1px solid #FDEEB3; background-color: #9ed2f9; } @@ -320,17 +319,17 @@ SARibbonSeparatorWidget { } SARibbonCategoryScrollButton { - border: 0.05em solid #c5d2e0; + border: 1px solid #c5d2e0; color: #333; background-color: white; } SARibbonCategoryScrollButton[arrowType="3"] { - border-right-width: 0.05em; + border-right-width: 1px; } SARibbonCategoryScrollButton[arrowType="4"] { - border-left-width: 0.05em; + border-left-width: 1px; } SARibbonCategoryScrollButton:hover { From bd495cc5fe0206faec9a250cd9b8dfee24b0c7e6 Mon Sep 17 00:00:00 2001 From: czyt1988 Date: Fri, 15 Dec 2023 09:27:56 +0800 Subject: [PATCH 05/16] =?UTF-8?q?=E5=AE=8C=E5=96=84=E9=AB=98=E5=88=86?= =?UTF-8?q?=E5=B1=8F=E6=98=BE=E7=A4=BA=E6=95=88=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- readme-cn.md | 2 ++ readme.md | 2 ++ src/SARibbonBar/SARibbonBar.cpp | 2 -- src/SARibbonBar/SARibbonButtonGroupWidget.cpp | 1 + src/SARibbonBar/SARibbonColorToolButton.cpp | 21 +++++++------------ src/SARibbonBar/SARibbonCtrlContainer.cpp | 5 ++--- src/SARibbonBar/SARibbonToolButton.cpp | 8 ++----- src/example/MainWindowExample/main.cpp | 1 + 8 files changed, 18 insertions(+), 24 deletions(-) diff --git a/readme-cn.md b/readme-cn.md index 6e8edf6c..daf54728 100644 --- a/readme-cn.md +++ b/readme-cn.md @@ -682,6 +682,7 @@ int main(int argc, char* argv[]) { #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); #endif QApplication a(argc, argv); ...... @@ -697,6 +698,7 @@ int main(int argc, char* argv[]) { #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); #endif #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); diff --git a/readme.md b/readme.md index 5b328344..77f3c79a 100644 --- a/readme.md +++ b/readme.md @@ -682,6 +682,7 @@ int main(int argc, char* argv[]) { #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); #endif QApplication a(argc, argv); ...... @@ -697,6 +698,7 @@ int main(int argc, char* argv[]) { #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); #endif #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); diff --git a/src/SARibbonBar/SARibbonBar.cpp b/src/SARibbonBar/SARibbonBar.cpp index 1e9939b0..2743bd07 100644 --- a/src/SARibbonBar/SARibbonBar.cpp +++ b/src/SARibbonBar/SARibbonBar.cpp @@ -239,7 +239,6 @@ void SARibbonBar::PrivateData::init() mQuickAccessBar->setIcon(q_ptr->windowIcon()); // mRightButtonGroup = RibbonSubElementDelegate->craeteButtonGroupWidget(q_ptr); - mRightButtonGroup->setFrameShape(QFrame::NoFrame); // setNormalMode(); } @@ -1265,7 +1264,6 @@ SARibbonButtonGroupWidget* SARibbonBar::activeRightButtonGroup() { if (nullptr == d_ptr->mRightButtonGroup) { d_ptr->mRightButtonGroup = RibbonSubElementDelegate->craeteButtonGroupWidget(this); - d_ptr->mRightButtonGroup->setFrameShape(QFrame::NoFrame); } d_ptr->mRightButtonGroup->show(); return d_ptr->mRightButtonGroup; diff --git a/src/SARibbonBar/SARibbonButtonGroupWidget.cpp b/src/SARibbonBar/SARibbonButtonGroupWidget.cpp index cd227c69..07882f00 100644 --- a/src/SARibbonBar/SARibbonButtonGroupWidget.cpp +++ b/src/SARibbonBar/SARibbonButtonGroupWidget.cpp @@ -115,6 +115,7 @@ QAction* SARibbonButtonGroupWidget::addAction(QAction* a) QAction* SARibbonButtonGroupWidget::addAction(const QString& text, const QIcon& icon, QToolButton::ToolButtonPopupMode popMode) { QAction* a = new QAction(icon, text, this); + addAction(a); ButtonTyle* btn = qobject_cast< ButtonTyle* >(d_ptr->mItems.back().widget); btn->setPopupMode(popMode); diff --git a/src/SARibbonBar/SARibbonColorToolButton.cpp b/src/SARibbonBar/SARibbonColorToolButton.cpp index fead4468..8aae58fa 100644 --- a/src/SARibbonBar/SARibbonColorToolButton.cpp +++ b/src/SARibbonBar/SARibbonColorToolButton.cpp @@ -28,10 +28,10 @@ SARibbonColorToolButton::PrivateData::PrivateData(SARibbonColorToolButton* p) : QPixmap SARibbonColorToolButton::PrivateData::createIconPixmap(const QStyleOptionToolButton& opt, const QSize& iconsize) const { - if (opt.icon.isNull()) { //没有有图标 + if (opt.icon.isNull()) { // 没有有图标 return QPixmap(); } - //有icon,在icon下方加入颜色 + // 有icon,在icon下方加入颜色 QIcon::State state = (opt.state & QStyle::State_On) ? QIcon::On : QIcon::Off; QIcon::Mode mode; if (!(opt.state & QStyle::State_Enabled)) { @@ -42,19 +42,14 @@ QPixmap SARibbonColorToolButton::PrivateData::createIconPixmap(const QStyleOptio mode = QIcon::Normal; } QSize realIconSize = iconsize - QSize(0, c_ribbonbutton_color_height + 1); - realIconSize *= q_ptr->devicePixelRatioF(); QPixmap pixmap = opt.icon.pixmap(q_ptr->window()->windowHandle(), realIconSize, mode, state); - pixmap.setDevicePixelRatio(q_ptr->devicePixelRatioF()); - QPixmap res(pixmap.size() + QSize(4, c_ribbonbutton_color_height + 4)); //宽度上,颜色块多出2px - res.setDevicePixelRatio(q_ptr->devicePixelRatioF()); + QPixmap res(pixmap.size() + QSize(4, c_ribbonbutton_color_height + 4)); // 宽度上,颜色块多出2px res.fill(Qt::transparent); QPainter painter(&res); - int xpixmap = (res.width() - pixmap.width()) / 2; - int ypixmap = (res.height() - c_ribbonbutton_color_height - 2 - pixmap.height()) / 2; //这里要减去2而不是1,这样奇数偶数都不会影响 - xpixmap /= q_ptr->devicePixelRatioF(); - ypixmap /= q_ptr->devicePixelRatioF(); - int w = pixmap.width()/q_ptr->devicePixelRatioF(); - int h = pixmap.height()/q_ptr->devicePixelRatioF(); + int xpixmap = (res.width() - pixmap.width()) / 2; + int ypixmap = (res.height() - c_ribbonbutton_color_height - 2 - pixmap.height()) / 2; // 这里要减去2而不是1,这样奇数偶数都不会影响 + int w = pixmap.width(); + int h = pixmap.height(); QRect rpixmap = QRect(xpixmap, ypixmap, w, h); painter.drawPixmap(rpixmap, pixmap); QRect colorRect = rpixmap.adjusted(0, h + 1, 0, c_ribbonbutton_color_height + 1); @@ -204,7 +199,7 @@ void SARibbonColorToolButton::onButtonClicked(bool checked) void SARibbonColorToolButton::paintIcon(QPainter& p, const QStyleOptionToolButton& opt, const QRect& iconDrawRect) { if (ColorUnderIcon == colorStyle()) { - //有icon + // 有icon QPixmap pm = d_ptr->createIconPixmap(opt, iconDrawRect.size()); style()->drawItemPixmap(&p, iconDrawRect, Qt::AlignCenter, pm); } else { diff --git a/src/SARibbonBar/SARibbonCtrlContainer.cpp b/src/SARibbonBar/SARibbonCtrlContainer.cpp index ef8f8639..7b2b67ea 100644 --- a/src/SARibbonBar/SARibbonCtrlContainer.cpp +++ b/src/SARibbonBar/SARibbonCtrlContainer.cpp @@ -40,7 +40,7 @@ class SARibbonCtrlContainer::PrivateData void setContainerWidget(QWidget* w) { if (containerWidget) { - //原来有widget + // 原来有widget QWidget* oldwidget = containerWidget; takeContainerWidget(oldwidget); oldwidget->deleteLater(); @@ -118,8 +118,7 @@ bool SARibbonCtrlContainer::hasContainerWidget() const void SARibbonCtrlContainer::setIcon(const QIcon& i) { d_ptr->icon = i; - QPixmap pixmap = i.pixmap(d_ptr->iconSize * devicePixelRatioF()); - pixmap.setDevicePixelRatio(devicePixelRatioF()); + QPixmap pixmap = i.pixmap(d_ptr->iconSize); d_ptr->labelPixmap->setPixmap(pixmap); } diff --git a/src/SARibbonBar/SARibbonToolButton.cpp b/src/SARibbonBar/SARibbonToolButton.cpp index aa19e9c1..de4a5fb6 100644 --- a/src/SARibbonBar/SARibbonToolButton.cpp +++ b/src/SARibbonBar/SARibbonToolButton.cpp @@ -622,13 +622,9 @@ QPixmap SARibbonToolButton::PrivateData::createIconPixmap(const QStyleOptionTool } else { mode = QIcon::Normal; } - //添加高分屏支持 - qreal pr = QApplication::primaryScreen()->devicePixelRatio(); + // 添加高分屏支持 QSize pxiampSize = iconsize - QSize(2, 2); - pxiampSize *= pr; - QPixmap px = opt.icon.pixmap(pxiampSize, mode, state); - px.setDevicePixelRatio(pr); - return px; + return opt.icon.pixmap(pxiampSize, mode, state); } int SARibbonToolButton::PrivateData::getTextAlignment() const diff --git a/src/example/MainWindowExample/main.cpp b/src/example/MainWindowExample/main.cpp index 99fc93fc..1af1ec7b 100644 --- a/src/example/MainWindowExample/main.cpp +++ b/src/example/MainWindowExample/main.cpp @@ -52,6 +52,7 @@ int main(int argc, char* argv[]) // 以下是针对高分屏的设置,有高分屏需求都需要按照下面进行设置 #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); #endif #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); From 24098ced4ade68d8fe1ae69688519cfa5a40d64f Mon Sep 17 00:00:00 2001 From: czyt1988 Date: Fri, 15 Dec 2023 11:24:24 +0800 Subject: [PATCH 06/16] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dcmake=E4=B8=AD=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E7=9A=84=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SARibbonBar/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/SARibbonBar/CMakeLists.txt b/src/SARibbonBar/CMakeLists.txt index 9f3a8725..68c7f57e 100644 --- a/src/SARibbonBar/CMakeLists.txt +++ b/src/SARibbonBar/CMakeLists.txt @@ -193,7 +193,6 @@ SET(SACOLOR_SOURCE_FILES # cn:头文件 SET(SARIBBON_HEADER_FILES SAFramelessHelper.h - SARibbonStyleOption.h SARibbonActionsManager.h SARibbonBar.h SARibbonCustomizeData.h @@ -235,7 +234,6 @@ SET(SARIBBON_HEADER_FILES # cn:cpp文件 SET(SARIBBON_SOURCE_FILES SAFramelessHelper.cpp - SARibbonStyleOption.cpp SARibbonActionsManager.cpp SARibbonBar.cpp SARibbonCustomizeData.cpp From 4b0e69bd9aede057f519f5d71140d6f41a423314 Mon Sep 17 00:00:00 2001 From: czyt1988 Date: Fri, 15 Dec 2023 17:31:26 +0800 Subject: [PATCH 07/16] =?UTF-8?q?=E6=9B=BF=E6=8D=A2=E8=B5=84=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- readme-cn.md | 21 ++++ src/SARibbonBar/SARibbonMainWindow.cpp | 30 ++++- src/SARibbonBar/SARibbonMainWindow.h | 7 +- src/SARibbonBar/SAWindowButtonGroup.cpp | 22 +++- src/SARibbonBar/resource.qrc | 13 ++- src/SARibbonBar/resource/Titlebar_Close.png | Bin 349 -> 0 bytes src/SARibbonBar/resource/Titlebar_Close.svg | 1 + .../resource/Titlebar_Close_Hover.png | Bin 325 -> 0 bytes .../resource/Titlebar_Close_Hover.svg | 1 + src/SARibbonBar/resource/Titlebar_Max.png | Bin 301 -> 0 bytes src/SARibbonBar/resource/Titlebar_Max.svg | 1 + .../resource/Titlebar_Max_Hover.svg | 1 + src/SARibbonBar/resource/Titlebar_Min.png | Bin 294 -> 0 bytes src/SARibbonBar/resource/Titlebar_Min.svg | 1 + .../resource/Titlebar_Min_Hover.svg | 1 + src/SARibbonBar/resource/Titlebar_Normal.png | Bin 325 -> 0 bytes src/SARibbonBar/resource/Titlebar_Normal.svg | 1 + .../resource/Titlebar_Normal_Hover.svg | 1 + src/SARibbonBar/resource/theme-dark.qss | 47 ++++---- src/SARibbonBar/resource/theme-office2013.qss | 45 +++++--- .../resource/theme-office2016-blue.qss | 46 ++++---- .../resource/theme-office2021-blue.qss | 46 ++++---- src/SARibbonBar/resource/theme-win7.qss | 61 ++++++----- src/example/CMakeLists.txt | 3 +- .../NormalMenuBarExample/CMakeLists.txt | 103 ++++++++++++++++++ 25 files changed, 331 insertions(+), 121 deletions(-) delete mode 100644 src/SARibbonBar/resource/Titlebar_Close.png create mode 100644 src/SARibbonBar/resource/Titlebar_Close.svg delete mode 100644 src/SARibbonBar/resource/Titlebar_Close_Hover.png create mode 100644 src/SARibbonBar/resource/Titlebar_Close_Hover.svg delete mode 100644 src/SARibbonBar/resource/Titlebar_Max.png create mode 100644 src/SARibbonBar/resource/Titlebar_Max.svg create mode 100644 src/SARibbonBar/resource/Titlebar_Max_Hover.svg delete mode 100644 src/SARibbonBar/resource/Titlebar_Min.png create mode 100644 src/SARibbonBar/resource/Titlebar_Min.svg create mode 100644 src/SARibbonBar/resource/Titlebar_Min_Hover.svg delete mode 100644 src/SARibbonBar/resource/Titlebar_Normal.png create mode 100644 src/SARibbonBar/resource/Titlebar_Normal.svg create mode 100644 src/SARibbonBar/resource/Titlebar_Normal_Hover.svg create mode 100644 src/example/NormalMenuBarExample/CMakeLists.txt diff --git a/readme-cn.md b/readme-cn.md index daf54728..0b96742d 100644 --- a/readme-cn.md +++ b/readme-cn.md @@ -171,6 +171,27 @@ SARibbon提供了合并好的`SARibbon.h`文件和`SARibbon.cpp`文件,只需 ..\..\..\SARibbon\src\SARibbonBar\3rdparty\framelesshelper\src\core\framelessmanager.cpp(563): fatal error C1083: 无法打开包括文件: “framelessmanager.moc”: No such file or directory ``` +### visual studio引入lib + +有些工程直接使用vs引入lib,而不是通过cmake和qmake来管理,这里介绍一下如何通过visual studio的界面引用库 + +在引入lib后,还需要做如下事情: + +1. 首先要在vs中添加include目录 + +``` +{yourPath}\include\SARibbon +{yourPath}\include\SARibbon\3rdparty\framelesshelper\include +{yourPath}\include\SARibbon\3rdparty\framelesshelper\qmake\inc\core +``` + +2. 前处理添加预定义宏 + +``` +SARIBBON_USE_3RDPARTY_FRAMELESSHELPER=1 +FRAMELESSHELPER_FEATURE_static_build=-1 +``` + # 使用方法 ## 引入库 diff --git a/src/SARibbonBar/SARibbonMainWindow.cpp b/src/SARibbonBar/SARibbonMainWindow.cpp index 9ceadefb..36f0be81 100644 --- a/src/SARibbonBar/SARibbonMainWindow.cpp +++ b/src/SARibbonBar/SARibbonMainWindow.cpp @@ -66,6 +66,8 @@ SARibbonMainWindow::SARibbonMainWindow(QWidget* parent, bool useRibbon, const Qt if (useRibbon) { installRibbonBar(createRibbonBar()); setRibbonTheme(ribbonTheme()); + } else { + setupNormalWindow(); } } @@ -108,6 +110,11 @@ bool SARibbonMainWindow::eventFilter(QObject* obj, QEvent* e) } return (QMainWindow::eventFilter(obj, e)); } +#else +FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessWidgetsHelper*) SARibbonMainWindow::framelessHelper() +{ + return FramelessWidgetsHelper::get(this); +} #endif /** * @brief 此函数仅用于控制最小最大化和关闭按钮的显示 @@ -259,9 +266,6 @@ void SARibbonMainWindow::installRibbonBar(SARibbonBar* bar) if (nullptr == d_ptr->mWindowButtonGroup) { d_ptr->mWindowButtonGroup = new SAWindowButtonGroup(this); } - QSize s = d_ptr->mWindowButtonGroup->sizeHint(); - s.setHeight(bar->titleBarHeight()); - d_ptr->mWindowButtonGroup->setFixedSize(s); d_ptr->mWindowButtonGroup->setWindowStates(windowState()); d_ptr->mWindowButtonGroup->show(); helper->setHitTestVisible(d_ptr->mWindowButtonGroup); // IMPORTANT! @@ -292,6 +296,22 @@ void SARibbonMainWindow::installRibbonBar(SARibbonBar* bar) #endif } +/** + @brief 构建为普通窗口 + */ +void SARibbonMainWindow::setupNormalWindow() +{ +#if SARIBBON_USE_3RDPARTY_FRAMELESSHELPER + auto helper = FramelessWidgetsHelper::get(this); + // 设置window按钮 + if (nullptr == d_ptr->mWindowButtonGroup) { + d_ptr->mWindowButtonGroup = new SAWindowButtonGroup(this); + } + d_ptr->mWindowButtonGroup->setWindowStates(windowState()); + d_ptr->mWindowButtonGroup->show(); +#endif +} + void sa_set_ribbon_theme(QWidget* w, SARibbonMainWindow::RibbonTheme theme) { QFile file; @@ -318,5 +338,7 @@ void sa_set_ribbon_theme(QWidget* w, SARibbonMainWindow::RibbonTheme theme) if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return; } - w->setStyleSheet(file.readAll()); + // 有反馈用qstring接住文件内容,再设置进去才能生效(qt5.7版本) + QString qss = file.readAll(); + w->setStyleSheet(qss); } diff --git a/src/SARibbonBar/SARibbonMainWindow.h b/src/SARibbonBar/SARibbonMainWindow.h index 1a38cf0d..aa62554a 100644 --- a/src/SARibbonBar/SARibbonMainWindow.h +++ b/src/SARibbonBar/SARibbonMainWindow.h @@ -7,6 +7,7 @@ #include "FramelessHelper/Widgets/framelessmainwindow.h" FRAMELESSHELPER_BEGIN_NAMESPACE class StandardTitleBar; +class FramelessWidgetsHelper; FRAMELESSHELPER_END_NAMESPACE #else class SAFramelessHelper; @@ -74,6 +75,8 @@ class SA_RIBBON_EXPORT SARibbonMainWindow : public QMainWindow SAFramelessHelper* framelessHelper(); // 把ribbonbar的事件传递到frameless virtual bool eventFilter(QObject* obj, QEvent* e) Q_DECL_OVERRIDE; +#else + FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessWidgetsHelper*) framelessHelper(); #endif // 此函数仅用于控制最小最大化和关闭按钮的显示 void updateWindowFlag(Qt::WindowFlags flags); @@ -83,7 +86,7 @@ class SA_RIBBON_EXPORT SARibbonMainWindow : public QMainWindow RibbonTheme ribbonTheme() const; // 判断当前是否使用ribbon模式 bool isUseRibbon() const; - //获取左上角按钮组(最大化,最小化,关闭) + // 获取左上角按钮组(最大化,最小化,关闭) SAWindowButtonGroup* windowButtonGroup() const; protected: @@ -95,6 +98,8 @@ class SA_RIBBON_EXPORT SARibbonMainWindow : public QMainWindow private: // 安装ribbon void installRibbonBar(SARibbonBar* bar); + // 构建为普通窗口 + void setupNormalWindow(); }; /** diff --git a/src/SARibbonBar/SAWindowButtonGroup.cpp b/src/SARibbonBar/SAWindowButtonGroup.cpp index 1d6f56ff..6408aa80 100644 --- a/src/SARibbonBar/SAWindowButtonGroup.cpp +++ b/src/SARibbonBar/SAWindowButtonGroup.cpp @@ -4,6 +4,8 @@ #include #include #include +#include "SARibbonMainWindow.h" +#include "SARibbonBar.h" #include "SARibbonElementManager.h" // 为了避免使用此框架的app设置了全局的qpushbutton 的 qss样式影响此按钮,定义了一个类 @@ -39,7 +41,7 @@ class SAWindowButtonGroup::PrivateData buttonMinimize->setObjectName(QStringLiteral("SAMinimizeWindowButton")); buttonMinimize->setFixedSize(30, par->height() - 2); buttonMinimize->setFocusPolicy(Qt::NoFocus); // 避免铺抓到 - buttonMinimize->setIconSize(buttonMinimize->size() * mIconscale); + // buttonMinimize->setIconSize(buttonMinimize->size() * mIconscale); buttonMinimize->show(); par->connect(buttonMinimize, &QAbstractButton::clicked, par, &SAWindowButtonGroup::minimizeWindow); } else { @@ -65,7 +67,7 @@ class SAWindowButtonGroup::PrivateData buttonMaximize->setFixedSize(30, par->height() - 2); buttonMaximize->setCheckable(true); buttonMaximize->setFocusPolicy(Qt::NoFocus); // 避免铺抓到 - buttonMaximize->setIconSize(buttonMaximize->size() * mIconscale); + // buttonMaximize->setIconSize(buttonMaximize->size() * mIconscale); buttonMaximize->show(); par->connect(buttonMaximize, &QAbstractButton::clicked, par, &SAWindowButtonGroup::maximizeWindow); } else { @@ -92,7 +94,7 @@ class SAWindowButtonGroup::PrivateData buttonClose->setFocusPolicy(Qt::NoFocus); // 避免铺抓到 // buttonClose->setFlat(true); par->connect(buttonClose, &QAbstractButton::clicked, par, &SAWindowButtonGroup::closeWindow); - buttonClose->setIconSize(buttonClose->size() * mIconscale); + // buttonClose->setIconSize(buttonClose->size() * mIconscale); buttonClose->show(); } else { if (buttonClose) { @@ -176,7 +178,9 @@ SAWindowToolButton::SAWindowToolButton(QWidget* p) : QPushButton(p) { setFlat(true); } - +//=================================================== +// SAWindowButtonGroup +//=================================================== SAWindowButtonGroup::SAWindowButtonGroup(QWidget* parent) : QWidget(parent), d_ptr(new SAWindowButtonGroup::PrivateData(this)) { @@ -344,7 +348,15 @@ bool SAWindowButtonGroup::eventFilter(QObject* watched, QEvent* e) void SAWindowButtonGroup::parentResize() { QWidget* par = parentWidget(); - + if (SARibbonMainWindow* rb = qobject_cast< SARibbonMainWindow* >(par)) { + if (SARibbonBar* bar = rb->ribbonBar()) { + // 先看看titlebar多高 + if (height() != bar->titleBarHeight()) { + setFixedHeight(bar->titleBarHeight()); + } + d_ptr->resize(QSize(width(), height())); + } + } if (par) { QSize parSize = par->size(); move(parSize.width() - width() - 1, 0); diff --git a/src/SARibbonBar/resource.qrc b/src/SARibbonBar/resource.qrc index 320501b8..42dbd038 100644 --- a/src/SARibbonBar/resource.qrc +++ b/src/SARibbonBar/resource.qrc @@ -4,14 +4,17 @@ resource/ArrowDown.png resource/ArrowMore.png resource/ArrowUp.png - resource/Titlebar_Close.png - resource/Titlebar_Close_Hover.png - resource/Titlebar_Max.png - resource/Titlebar_Min.png - resource/Titlebar_Normal.png resource/Titlebar_Shade.png resource/Titlebar_Unshade.png resource/define-color.svg + resource/Titlebar_Close.svg + resource/Titlebar_Close_Hover.svg + resource/Titlebar_Max.svg + resource/Titlebar_Max_Hover.svg + resource/Titlebar_Min.svg + resource/Titlebar_Min_Hover.svg + resource/Titlebar_Normal.svg + resource/Titlebar_Normal_Hover.svg resource/theme-win7.qss diff --git a/src/SARibbonBar/resource/Titlebar_Close.png b/src/SARibbonBar/resource/Titlebar_Close.png deleted file mode 100644 index 2a9c37464ae6a99bc6d2526dacc707350e72d5c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 349 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2ZGmxy8xzq=wSkfJR9T^xl_H+M9WCijSl0AZa z85pWm85kOx85n;42huMY7)lKo7+xhXFj&oCU=Yur6o1qWsFpv#C&cytf1nbEGiT1Q zvU330e6#CHfqcf2AirP+hi5m^K%69RcNc~ZR#^`qhqJ&VvY3H^TNs2H8D`Cq01C2~ zc>21sKjmO$l{XaM6Rrys()4t34B@z*ERd9t5ReiOmXKh?q^QvB7 \ No newline at end of file diff --git a/src/SARibbonBar/resource/Titlebar_Close_Hover.png b/src/SARibbonBar/resource/Titlebar_Close_Hover.png deleted file mode 100644 index 2a9a0d0a5d2a3757c627fea479eb909431b5390d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 325 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V3y@T|W;X*;Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CDO3=9p;3=BX21L>Cx45bDP46hOx7_4S6Fo@?*ia+WGRLhj)?e4 \ No newline at end of file diff --git a/src/SARibbonBar/resource/Titlebar_Max.png b/src/SARibbonBar/resource/Titlebar_Max.png deleted file mode 100644 index b3146f4fc3a905fde2e8978a053b9c481b644f78..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 301 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V3y@T|W;X*;Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CDO3=9p;3=BX21L>Cx45bDP46hOx7_4S6Fo@?*ia+WGRLhj)?e4@cf*{CqT8TC9V-ADTyViR>?)FK#IZ0z{pV7z(Uu+ zD8$If%D}?P&`29d8W_yHXfzK+LvDUbW?CgegGq>yp_Q?rm5C)pgXZxWu|N$Bp00i_ I>zopr0D*^0ng9R* diff --git a/src/SARibbonBar/resource/Titlebar_Max.svg b/src/SARibbonBar/resource/Titlebar_Max.svg new file mode 100644 index 00000000..d0f03060 --- /dev/null +++ b/src/SARibbonBar/resource/Titlebar_Max.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/SARibbonBar/resource/Titlebar_Max_Hover.svg b/src/SARibbonBar/resource/Titlebar_Max_Hover.svg new file mode 100644 index 00000000..e3238a09 --- /dev/null +++ b/src/SARibbonBar/resource/Titlebar_Max_Hover.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/SARibbonBar/resource/Titlebar_Min.png b/src/SARibbonBar/resource/Titlebar_Min.png deleted file mode 100644 index 4c29eed32d638c154fe3f8c66dfd010116269717..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 294 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V3y@T|W;X*;Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CDO3=9p;3=BX21L>Cx45bDP46hOx7_4S6Fo@?*ia+WGRLhj)?e4=G)e_f;l9a@fRIB8oR3OD*WME{dYha;kU=(6xWMyDs zWoV=gBn=E^UNoAAq9HdwB{QuOp}{1?$k58z(8|OTqCxZcj98!s22WQ%mvv4FO#l^Y BNxuL9 diff --git a/src/SARibbonBar/resource/Titlebar_Min.svg b/src/SARibbonBar/resource/Titlebar_Min.svg new file mode 100644 index 00000000..f6cfd192 --- /dev/null +++ b/src/SARibbonBar/resource/Titlebar_Min.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/SARibbonBar/resource/Titlebar_Min_Hover.svg b/src/SARibbonBar/resource/Titlebar_Min_Hover.svg new file mode 100644 index 00000000..f9f4a7e2 --- /dev/null +++ b/src/SARibbonBar/resource/Titlebar_Min_Hover.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/SARibbonBar/resource/Titlebar_Normal.png b/src/SARibbonBar/resource/Titlebar_Normal.png deleted file mode 100644 index b76c171d09a2fe6e1c24176865530dfddbf65e12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 325 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V3y@T|W;X*;Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CDO3=9p;3=BX21L>Cx45bDP46hOx7_4S6Fo@?*ia+WGRLhj)?e47Zr8VB~OIQ3atzd9W5Sf1_n=8KbLh*2~7YAjate8 diff --git a/src/SARibbonBar/resource/Titlebar_Normal.svg b/src/SARibbonBar/resource/Titlebar_Normal.svg new file mode 100644 index 00000000..e86f22d1 --- /dev/null +++ b/src/SARibbonBar/resource/Titlebar_Normal.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/SARibbonBar/resource/Titlebar_Normal_Hover.svg b/src/SARibbonBar/resource/Titlebar_Normal_Hover.svg new file mode 100644 index 00000000..c285a88a --- /dev/null +++ b/src/SARibbonBar/resource/Titlebar_Normal_Hover.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/SARibbonBar/resource/theme-dark.qss b/src/SARibbonBar/resource/theme-dark.qss index b5c89567..099bb8da 100644 --- a/src/SARibbonBar/resource/theme-dark.qss +++ b/src/SARibbonBar/resource/theme-dark.qss @@ -313,47 +313,54 @@ SARibbonCategoryScrollButton[arrowType="4"] { border-left-width: 0.05em; } /*SAWindowToolButton*/ -SAWindowToolButton { - background-color: transparent; + +SAWindowToolButton { + background-color: transparent; border:none; } SAWindowToolButton:focus { outline: none; } - +/*Min*/ SAWindowToolButton#SAMinimizeWindowButton { - image: url(:/image/resource/Titlebar_Min.png); -} - -SAWindowToolButton#SAMaximizeWindowButton:checked { - image:url(:/image/resource/Titlebar_Normal.png); + qproperty-iconSize: 16px 16px; + qproperty-icon: url(:/image/resource/Titlebar_Min.svg) center; } - -SAWindowToolButton#SAMaximizeWindowButton { - image:url(:/image/resource/Titlebar_Max.png); -} - SAWindowToolButton#SAMinimizeWindowButton:hover,#SAMaximizeWindowButton:hover { background-color: #e5e5e5; + qproperty-iconSize: 16px 16px; + qproperty-icon: url(:/image/resource/Titlebar_Min_Hover.svg) center; } - SAWindowToolButton#SAMinimizeWindowButton:pressed,#SAMaximizeWindowButton:pressed { background-color: #cacacb; } +/*Max*/ +SAWindowToolButton#SAMaximizeWindowButton { + qproperty-iconSize: 16px 16px; + qproperty-icon: url(:/image/resource/Titlebar_Max.svg) center; +} +SAWindowToolButton#SAMaximizeWindowButton:checked { + qproperty-icon: url(:/image/resource/Titlebar_Normal.svg) center; +} +SAWindowToolButton#SAMaximizeWindowButton:hover { + background-color: #e5e5e5; + qproperty-icon: url(:/image/resource/Titlebar_Max_Hover.svg) center; +} + +/*Close*/ SAWindowToolButton#SACloseWindowButton { - image: url(:/image/resource/Titlebar_Close_Hover.png); + qproperty-iconSize: 16px 16px; + qproperty-icon: url(:/image/resource/Titlebar_Close.svg) center; } - SAWindowToolButton#SACloseWindowButton:hover { background-color: #e81123; - image: url(:/image/resource/Titlebar_Close.png); + qproperty-icon: url(:/image/resource/Titlebar_Close_Hover.svg) center; } - SAWindowToolButton#SACloseWindowButton:pressed { - background-color: #f1707a; - image: url(:/image/resource/Titlebar_Close.png); + background-color: #f1707a; + qproperty-icon: url(:/image/resource/Titlebar_Close_Hover.svg) center; } SAWindowToolButton#SARibbonBarHidePannelButton { diff --git a/src/SARibbonBar/resource/theme-office2013.qss b/src/SARibbonBar/resource/theme-office2013.qss index 04940334..063b5581 100644 --- a/src/SARibbonBar/resource/theme-office2013.qss +++ b/src/SARibbonBar/resource/theme-office2013.qss @@ -337,6 +337,9 @@ SARibbonCategoryScrollButton:hover { background-color: #cee7fc; } + +/*SAWindowToolButton*/ + SAWindowToolButton { background-color: transparent; border:none; @@ -345,39 +348,45 @@ SAWindowToolButton { SAWindowToolButton:focus { outline: none; } - +/*Min*/ SAWindowToolButton#SAMinimizeWindowButton { - image: url(:/image/resource/Titlebar_Min.png); -} - -SAWindowToolButton#SAMaximizeWindowButton:checked { - image:url(:/image/resource/Titlebar_Normal.png); + qproperty-iconSize: 16px 16px; + qproperty-icon: url(:/image/resource/Titlebar_Min.svg) center; } - -SAWindowToolButton#SAMaximizeWindowButton { - image:url(:/image/resource/Titlebar_Max.png); -} - SAWindowToolButton#SAMinimizeWindowButton:hover,#SAMaximizeWindowButton:hover { background-color: #e5e5e5; + qproperty-iconSize: 16px 16px; + qproperty-icon: url(:/image/resource/Titlebar_Min_Hover.svg) center; } - SAWindowToolButton#SAMinimizeWindowButton:pressed,#SAMaximizeWindowButton:pressed { background-color: #cacacb; } +/*Max*/ +SAWindowToolButton#SAMaximizeWindowButton { + qproperty-iconSize: 16px 16px; + qproperty-icon: url(:/image/resource/Titlebar_Max.svg) center; +} +SAWindowToolButton#SAMaximizeWindowButton:checked { + qproperty-icon: url(:/image/resource/Titlebar_Normal.svg) center; +} +SAWindowToolButton#SAMaximizeWindowButton:hover { + background-color: #e5e5e5; + qproperty-icon: url(:/image/resource/Titlebar_Max_Hover.svg) center; +} + +/*Close*/ SAWindowToolButton#SACloseWindowButton { - image: url(:/image/resource/Titlebar_Close.png); + qproperty-iconSize: 16px 16px; + qproperty-icon: url(:/image/resource/Titlebar_Close.svg) center; } - SAWindowToolButton#SACloseWindowButton:hover { background-color: #e81123; - image: url(:/image/resource/Titlebar_Close_Hover.png); + qproperty-icon: url(:/image/resource/Titlebar_Close_Hover.svg) center; } - SAWindowToolButton#SACloseWindowButton:pressed { - background-color: #f1707a; - image: url(:/image/resource/Titlebar_Close_Hover.png); + background-color: #f1707a; + qproperty-icon: url(:/image/resource/Titlebar_Close_Hover.svg) center; } SAWindowToolButton#SARibbonBarHidePannelButton { diff --git a/src/SARibbonBar/resource/theme-office2016-blue.qss b/src/SARibbonBar/resource/theme-office2016-blue.qss index a6dc6890..c90c6cc1 100644 --- a/src/SARibbonBar/resource/theme-office2016-blue.qss +++ b/src/SARibbonBar/resource/theme-office2016-blue.qss @@ -400,47 +400,53 @@ SARibbonSeparatorWidget { /*SAWindowToolButton*/ -SAWindowToolButton { - background-color: transparent; +SAWindowToolButton { + background-color: transparent; border:none; } SAWindowToolButton:focus { outline: none; } - +/*Min*/ SAWindowToolButton#SAMinimizeWindowButton { - image: url(:/image/resource/Titlebar_Min.png); -} - -SAWindowToolButton#SAMaximizeWindowButton:checked { - image:url(:/image/resource/Titlebar_Normal.png); + qproperty-iconSize: 16px 16px; + qproperty-icon: url(:/image/resource/Titlebar_Min.svg) center; } - -SAWindowToolButton#SAMaximizeWindowButton { - image:url(:/image/resource/Titlebar_Max.png); -} - SAWindowToolButton#SAMinimizeWindowButton:hover,#SAMaximizeWindowButton:hover { background-color: #e5e5e5; + qproperty-iconSize: 16px 16px; + qproperty-icon: url(:/image/resource/Titlebar_Min_Hover.svg) center; } - SAWindowToolButton#SAMinimizeWindowButton:pressed,#SAMaximizeWindowButton:pressed { background-color: #cacacb; } +/*Max*/ +SAWindowToolButton#SAMaximizeWindowButton { + qproperty-iconSize: 16px 16px; + qproperty-icon: url(:/image/resource/Titlebar_Max.svg) center; +} +SAWindowToolButton#SAMaximizeWindowButton:checked { + qproperty-icon: url(:/image/resource/Titlebar_Normal.svg) center; +} +SAWindowToolButton#SAMaximizeWindowButton:hover { + background-color: #e5e5e5; + qproperty-icon: url(:/image/resource/Titlebar_Max_Hover.svg) center; +} + +/*Close*/ SAWindowToolButton#SACloseWindowButton { - image: url(:/image/resource/Titlebar_Close.png); + qproperty-iconSize: 16px 16px; + qproperty-icon: url(:/image/resource/Titlebar_Close.svg) center; } - SAWindowToolButton#SACloseWindowButton:hover { background-color: #e81123; - image: url(:/image/resource/Titlebar_Close_Hover.png); + qproperty-icon: url(:/image/resource/Titlebar_Close_Hover.svg) center; } - SAWindowToolButton#SACloseWindowButton:pressed { - background-color: #f1707a; - image: url(:/image/resource/Titlebar_Close_Hover.png); + background-color: #f1707a; + qproperty-icon: url(:/image/resource/Titlebar_Close_Hover.svg) center; } SAWindowToolButton#SARibbonBarHidePannelButton { diff --git a/src/SARibbonBar/resource/theme-office2021-blue.qss b/src/SARibbonBar/resource/theme-office2021-blue.qss index 0bdb994e..6e978076 100644 --- a/src/SARibbonBar/resource/theme-office2021-blue.qss +++ b/src/SARibbonBar/resource/theme-office2021-blue.qss @@ -424,47 +424,53 @@ SARibbonSeparatorWidget { /*SAWindowToolButton*/ -SAWindowToolButton { - background-color: transparent; +SAWindowToolButton { + background-color: transparent; border:none; } SAWindowToolButton:focus { outline: none; } - +/*Min*/ SAWindowToolButton#SAMinimizeWindowButton { - image: url(:/image/resource/Titlebar_Min.png); -} - -SAWindowToolButton#SAMaximizeWindowButton:checked { - image:url(:/image/resource/Titlebar_Normal.png); + qproperty-iconSize: 16px 16px; + qproperty-icon: url(:/image/resource/Titlebar_Min.svg) center; } - -SAWindowToolButton#SAMaximizeWindowButton { - image:url(:/image/resource/Titlebar_Max.png); -} - SAWindowToolButton#SAMinimizeWindowButton:hover,#SAMaximizeWindowButton:hover { background-color: #e5e5e5; + qproperty-iconSize: 16px 16px; + qproperty-icon: url(:/image/resource/Titlebar_Min_Hover.svg) center; } - SAWindowToolButton#SAMinimizeWindowButton:pressed,#SAMaximizeWindowButton:pressed { background-color: #cacacb; } +/*Max*/ +SAWindowToolButton#SAMaximizeWindowButton { + qproperty-iconSize: 16px 16px; + qproperty-icon: url(:/image/resource/Titlebar_Max.svg) center; +} +SAWindowToolButton#SAMaximizeWindowButton:checked { + qproperty-icon: url(:/image/resource/Titlebar_Normal.svg) center; +} +SAWindowToolButton#SAMaximizeWindowButton:hover { + background-color: #e5e5e5; + qproperty-icon: url(:/image/resource/Titlebar_Max_Hover.svg) center; +} + +/*Close*/ SAWindowToolButton#SACloseWindowButton { - image: url(:/image/resource/Titlebar_Close.png); + qproperty-iconSize: 16px 16px; + qproperty-icon: url(:/image/resource/Titlebar_Close.svg) center; } - SAWindowToolButton#SACloseWindowButton:hover { background-color: #e81123; - image: url(:/image/resource/Titlebar_Close_Hover.png); + qproperty-icon: url(:/image/resource/Titlebar_Close_Hover.svg) center; } - SAWindowToolButton#SACloseWindowButton:pressed { - background-color: #f1707a; - image: url(:/image/resource/Titlebar_Close_Hover.png); + background-color: #f1707a; + qproperty-icon: url(:/image/resource/Titlebar_Close_Hover.svg) center; } SAWindowToolButton#SARibbonBarHidePannelButton { diff --git a/src/SARibbonBar/resource/theme-win7.qss b/src/SARibbonBar/resource/theme-win7.qss index 2a02738f..8aca1d44 100644 --- a/src/SARibbonBar/resource/theme-win7.qss +++ b/src/SARibbonBar/resource/theme-win7.qss @@ -306,50 +306,57 @@ SARibbonCategoryScrollButton[arrowType="4"] { } /*SAWindowToolButton*/ -SAWindowToolButton { - background-color: transparent; + +SAWindowToolButton { + background-color: transparent; border:none; } SAWindowToolButton:focus { outline: none; } - -#SAMinimizeWindowButton { - image: url(:/image/resource/Titlebar_Min.png); -} - -#SAMaximizeWindowButton:checked { - image:url(:/image/resource/Titlebar_Normal.png); -} - -#SAMaximizeWindowButton { - image:url(:/image/resource/Titlebar_Max.png); +/*Min*/ +SAWindowToolButton#SAMinimizeWindowButton { + qproperty-iconSize: 16px 16px; + qproperty-icon: url(:/image/resource/Titlebar_Min.svg) center; } - -#SAMinimizeWindowButton:hover,#SAMaximizeWindowButton:hover { +SAWindowToolButton#SAMinimizeWindowButton:hover,#SAMaximizeWindowButton:hover { background-color: #e5e5e5; + qproperty-iconSize: 16px 16px; + qproperty-icon: url(:/image/resource/Titlebar_Min_Hover.svg) center; } - -#SAMinimizeWindowButton:pressed,#SAMaximizeWindowButton:pressed { +SAWindowToolButton#SAMinimizeWindowButton:pressed,#SAMaximizeWindowButton:pressed { background-color: #cacacb; } - -#SACloseWindowButton { - image: url(:/image/resource/Titlebar_Close.png); +/*Max*/ +SAWindowToolButton#SAMaximizeWindowButton { + qproperty-iconSize: 16px 16px; + qproperty-icon: url(:/image/resource/Titlebar_Max.svg) center; +} +SAWindowToolButton#SAMaximizeWindowButton:checked { + qproperty-icon: url(:/image/resource/Titlebar_Normal.svg) center; +} +SAWindowToolButton#SAMaximizeWindowButton:hover { + background-color: #e5e5e5; + qproperty-icon: url(:/image/resource/Titlebar_Max_Hover.svg) center; } -#SACloseWindowButton:hover { + +/*Close*/ +SAWindowToolButton#SACloseWindowButton { + qproperty-iconSize: 16px 16px; + qproperty-icon: url(:/image/resource/Titlebar_Close.svg) center; +} +SAWindowToolButton#SACloseWindowButton:hover { background-color: #e81123; - image: url(:/image/resource/Titlebar_Close_Hover.png); + qproperty-icon: url(:/image/resource/Titlebar_Close_Hover.svg) center; } - -#SACloseWindowButton:pressed { - background-color: #f1707a; - image: url(:/image/resource/Titlebar_Close_Hover.png); +SAWindowToolButton#SACloseWindowButton:pressed { + background-color: #f1707a; + qproperty-icon: url(:/image/resource/Titlebar_Close_Hover.svg) center; } -#SARibbonBarHidePannelButton { +SAWindowToolButton#SARibbonBarHidePannelButton { titlebar-shade-icon: url(:/image/resource/Titlebar_Shade.png); titlebar-unshade-icon: url(:/image/resource/Titlebar_Unshade.png); } diff --git a/src/example/CMakeLists.txt b/src/example/CMakeLists.txt index 652c6d53..c9706228 100644 --- a/src/example/CMakeLists.txt +++ b/src/example/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_minimum_required(VERSION 3.5) project(SARibbonExamples LANGUAGES CXX) add_subdirectory(MainWindowExample) -add_subdirectory(WidgetWithRibbon) \ No newline at end of file +add_subdirectory(WidgetWithRibbon) +add_subdirectory(NormalMenuBarExample) diff --git a/src/example/NormalMenuBarExample/CMakeLists.txt b/src/example/NormalMenuBarExample/CMakeLists.txt new file mode 100644 index 00000000..5c4e9996 --- /dev/null +++ b/src/example/NormalMenuBarExample/CMakeLists.txt @@ -0,0 +1,103 @@ +cmake_minimum_required(VERSION 3.5) +SET(VERSION_SHORT 0.1) +project(NormalMenuBarExample VERSION ${VERSION_SHORT}) +set(SARIBBON_EXPAMPLE_NAME NormalMenuBarExample) +set(CMAKE_INCLUDE_CURRENT_DIR ON) +# 显示定义FRAMELESSHELPER_FEATURE_static_build为-1 否则库引用会失败 +add_definitions(-DFRAMELESSHELPER_FEATURE_static_build=-1) +# qt库加载,最低要求5.9 +find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} 5.9 COMPONENTS Core Gui Widgets REQUIRED) + +# 在加载qt版本后,需要下面这段开判断是否使用framelss +# 根据qt版本选择是否使用frameless库,目前frameless库支持qt5.14,qt5.15,qt6.4+,除了上诉版本,都使用不了 +function(setup_custom_moc_macros) + cmake_parse_arguments(arg "" "" "TARGETS" ${ARGN}) + if(arg_UNPARSED_ARGUMENTS) + message(AUTHOR_WARNING "setup_custom_moc_macros: Unrecognized arguments: ${arg_UNPARSED_ARGUMENTS}") + endif() + foreach(__target ${arg_TARGETS}) + if(NOT TARGET ${__target}) + message(AUTHOR_WARNING "${__target} is not a valid CMake target!") + continue() + endif() + set_property(TARGET ${__target} APPEND PROPERTY AUTOMOC_MACRO_NAMES "FRAMELESSHELPER_QT_CLASS;FRAMELESSHELPER_PUBLIC_QT_CLASS;FRAMELESSHELPER_PRIVATE_QT_CLASS") + endforeach() +endfunction() +if(${QT_VERSION_MAJOR} EQUAL 5) + # qt版本为5,判断是否小版本大于14 + if(${QT_VERSION_MINOR} GREATER_EQUAL 14) + #5.14和5.15可以使用frameless + set(SARIBBON_USE_FRAMELESS_LIB ON) + else() + set(SARIBBON_USE_FRAMELESS_LIB OFF) + endif() +elseif(${QT_VERSION_MAJOR} EQUAL 6) + # qt版本为6,判断是否小版本大于4 + if(${QT_VERSION_MINOR} GREATER_EQUAL 4) + #6.4及以上可以使用frameless + set(SARIBBON_USE_FRAMELESS_LIB ON) + else() + set(SARIBBON_USE_FRAMELESS_LIB OFF) + endif() +endif() +if(SARIBBON_USE_FRAMELESS_LIB) + #使用frameless必须设置SARIBBON_USE_3RDPARTY_FRAMELESSHELPER宏为1 + add_definitions(-DSARIBBON_USE_3RDPARTY_FRAMELESSHELPER=1) + setup_custom_moc_macros(TARGETS ${SARIBBON_EXPAMPLE_NAME}) +else() + #不使用frameless必须设置SARIBBON_USE_3RDPARTY_FRAMELESSHELPER宏为0 + add_definitions(-DSARIBBON_USE_3RDPARTY_FRAMELESSHELPER=0) +endif() + + + +add_executable(${SARIBBON_EXPAMPLE_NAME} + MainWindow.h + MainWindow.cpp + MainWindow.ui + main.cpp +) + +target_include_directories(${SARIBBON_EXPAMPLE_NAME} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../SARibbonBar") + +target_link_libraries(${SARIBBON_EXPAMPLE_NAME} PRIVATE SARibbonBar) +target_link_libraries(${SARIBBON_EXPAMPLE_NAME} PUBLIC + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Widgets) + +set_target_properties(${SARIBBON_EXPAMPLE_NAME} PROPERTIES + AUTOMOC ON + AUTORCC ON + AUTOUIC ON + CXX_EXTENSIONS OFF + DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX} + VERSION ${SARIBBON_VERSION} + EXPORT_NAME ${SARIBBON_EXPAMPLE_NAME} + ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" +) + +install(TARGETS ${SARIBBON_EXPAMPLE_NAME} RUNTIME DESTINATION bin LIBRARY DESTINATION bin ARCHIVE DESTINATION lib) + +# 会有一个FAILED: src/example/MainWindowExample/CMakeFiles/MainWindowExample.dir/MainWindowExample.rc.res +# 暂时注释 +# +# if(WIN32) +# add_custom_command(TARGET ${SARIBBON_EXPAMPLE_NAME} +# POST_BUILD +# COMMAND ${CMAKE_COMMAND} -E +# copy_if_different +# "$" +# "$" +# ) +# create_win32_resource_version( +# TARGET ${SARIBBON_EXPAMPLE_NAME} +# FILENAME ${SARIBBON_EXPAMPLE_NAME} +# EXT "exe" +# DESCRIPTION "Example application for Qt Ribbon Control" +# ) +# visual_studio_qt_helper(${SARIBBON_EXPAMPLE_NAME}) +# endif() From 14a676374754de845b8f863c0d98d62be0105a8d Mon Sep 17 00:00:00 2001 From: czyt1988 Date: Sun, 17 Dec 2023 00:07:22 +0800 Subject: [PATCH 08/16] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E5=88=B7=E6=96=B0?= =?UTF-8?q?=E8=BF=87=E4=BA=8E=E9=A2=91=E7=B9=81=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SARibbonBar/SARibbonBar.cpp | 22 ++- src/SARibbonBar/SARibbonBar.h | 17 +-- src/SARibbonBar/SARibbonButtonGroupWidget.cpp | 3 - src/SARibbonBar/SARibbonCategory.cpp | 106 +++++++------- src/SARibbonBar/SARibbonCategory.h | 8 +- src/SARibbonBar/SARibbonCategoryLayout.cpp | 8 +- src/SARibbonBar/SARibbonGlobal.h | 10 ++ src/SARibbonBar/SARibbonPannel.cpp | 136 +++++++++++------- src/SARibbonBar/SARibbonPannel.h | 13 +- src/SARibbonBar/SARibbonPannelLayout.cpp | 36 +++-- src/SARibbonBar/SARibbonToolButton.h | 3 +- src/example/MainWindowExample/mainwindow.cpp | 1 - 12 files changed, 219 insertions(+), 144 deletions(-) diff --git a/src/SARibbonBar/SARibbonBar.cpp b/src/SARibbonBar/SARibbonBar.cpp index 2743bd07..f726eec5 100644 --- a/src/SARibbonBar/SARibbonBar.cpp +++ b/src/SARibbonBar/SARibbonBar.cpp @@ -412,7 +412,7 @@ QList< QColor > SARibbonBar::getDefaultContextCategoryColorList() << QColor(14, 81, 167) // 蓝 << QColor(228, 0, 69) // 红 << QColor(67, 148, 0) // 绿 - ; + ; return res; } @@ -492,7 +492,6 @@ void SARibbonBar::addCategoryPage(SARibbonCategory* category) tabdata.category = category; tabdata.index = index; - category->setRibbonBar(this); d_ptr->mRibbonTabBar->setTabData(index, QVariant::fromValue(tabdata)); d_ptr->mStackedContainerWidget->insertWidget(index, category); @@ -971,11 +970,11 @@ void SARibbonBar::showMinimumModeButton(bool isShow) d_ptr->mMinimumCategoryButtonAction = new QAction(this); d_ptr->mMinimumCategoryButtonAction->setIcon( - style()->standardIcon(isMinimumMode() ? QStyle::SP_TitleBarUnshadeButton : QStyle::SP_TitleBarShadeButton, nullptr)); + style()->standardIcon(isMinimumMode() ? QStyle::SP_TitleBarUnshadeButton : QStyle::SP_TitleBarShadeButton, nullptr)); connect(d_ptr->mMinimumCategoryButtonAction, &QAction::triggered, this, [ this ]() { this->setMinimumMode(!isMinimumMode()); this->d_ptr->mMinimumCategoryButtonAction->setIcon( - style()->standardIcon(isMinimumMode() ? QStyle::SP_TitleBarUnshadeButton : QStyle::SP_TitleBarShadeButton, nullptr)); + style()->standardIcon(isMinimumMode() ? QStyle::SP_TitleBarUnshadeButton : QStyle::SP_TitleBarShadeButton, nullptr)); }); d_ptr->mRightButtonGroup->addAction(d_ptr->mMinimumCategoryButtonAction); @@ -1818,7 +1817,7 @@ void SARibbonBar::paintInNormalStyle() titleRegion.setRect(d_ptr->mQuickAccessBar->geometry().right() + 1, border.top(), width() - d_ptr->mIconRightBorderPosition - border.right() - - d_ptr->mWindowButtonSize.width() - d_ptr->mQuickAccessBar->geometry().right() - 1, + - d_ptr->mWindowButtonSize.width() - d_ptr->mQuickAccessBar->geometry().right() - 1, titleBarHeight()); } else { int leftwidth = contextCategoryRegion.x() - d_ptr->mQuickAccessBar->geometry().right() - d_ptr->mIconRightBorderPosition; @@ -2035,6 +2034,19 @@ void SARibbonBar::changeEvent(QEvent* e) QMenuBar::changeEvent(e); } +bool SARibbonBar::event(QEvent* e) +{ + switch (e->type()) { + case QEvent::Show: + //第一次显示刷新 + updateRibbonGeometry(); + break; + default: + break; + } + return QMenuBar::event(e); +} + void SARibbonBar::resizeInOfficeStyle() { synchronousCategoryLayoutMode(false); diff --git a/src/SARibbonBar/SARibbonBar.h b/src/SARibbonBar/SARibbonBar.h index c791e9b6..e6899d81 100644 --- a/src/SARibbonBar/SARibbonBar.h +++ b/src/SARibbonBar/SARibbonBar.h @@ -104,14 +104,14 @@ class SA_RIBBON_EXPORT SARibbonBar : public QMenuBar */ enum RibbonStyle { - RibbonStyleLooseThreeRow = 0x0000, ///< 宽松结构,3行模式 - RibbonStyleCompactThreeRow = 0x0001, ///< 紧凑结构,3行模式 - RibbonStyleLooseTwoRow = 0x0100, ///< 宽松结构,2行模式 - RibbonStyleCompactTwoRow = 0x0101, ///< 紧凑结构,2行模式 - // 以下枚举将组件淘汰 - OfficeStyle = RibbonStyleLooseThreeRow, ///< 类似office 的ribbon风格 - WpsLiteStyle = RibbonStyleCompactThreeRow, ///< 类似wps的紧凑风格 - OfficeStyleTwoRow = RibbonStyleLooseTwoRow, ///< 类似office 的ribbon风格 2行工具栏 三行布局模式,office就是三行布局模式,pannel能布置3行小toolbutton,默认模式 + RibbonStyleLooseThreeRow = 0x0000, ///< 宽松结构,3行模式 + RibbonStyleCompactThreeRow = 0x0001, ///< 紧凑结构,3行模式 + RibbonStyleLooseTwoRow = 0x0100, ///< 宽松结构,2行模式 + RibbonStyleCompactTwoRow = 0x0101, ///< 紧凑结构,2行模式 + // 以下枚举将组件淘汰 + OfficeStyle = RibbonStyleLooseThreeRow, ///< 类似office 的ribbon风格 + WpsLiteStyle = RibbonStyleCompactThreeRow, ///< 类似wps的紧凑风格 + OfficeStyleTwoRow = RibbonStyleLooseTwoRow, ///< 类似office 的ribbon风格 2行工具栏 三行布局模式,office就是三行布局模式,pannel能布置3行小toolbutton,默认模式 WpsLiteStyleTwoRow = RibbonStyleCompactTwoRow ///< 类似wps的紧凑风格 2行工具栏 }; Q_ENUM(RibbonStyle) @@ -376,6 +376,7 @@ protected slots: virtual void resizeEvent(QResizeEvent* e) Q_DECL_OVERRIDE; virtual void moveEvent(QMoveEvent* e) Q_DECL_OVERRIDE; virtual void changeEvent(QEvent* e) Q_DECL_OVERRIDE; + virtual bool event(QEvent* e) Q_DECL_OVERRIDE; virtual void paintTabbarBaseLine(QPainter& painter); virtual void paintWindowTitle(QPainter& painter, const QString& title, const QRect& titleRegion); virtual void paintContextCategoryTab(QPainter& painter, const QString& title, QRect contextRect, const QColor& color); diff --git a/src/SARibbonBar/SARibbonButtonGroupWidget.cpp b/src/SARibbonBar/SARibbonButtonGroupWidget.cpp index 07882f00..4f31d5e7 100644 --- a/src/SARibbonBar/SARibbonButtonGroupWidget.cpp +++ b/src/SARibbonBar/SARibbonButtonGroupWidget.cpp @@ -225,14 +225,12 @@ void SARibbonButtonGroupWidget::actionEvent(QActionEvent* e) } layout()->addWidget(item.widget); d_ptr->mItems.append(item); - layout()->invalidate(); updateGeometry(); } break; case QEvent::ActionChanged: { // 让布局重新绘制 layout()->invalidate(); - updateGeometry(); } break; case QEvent::ActionRemoved: { @@ -250,7 +248,6 @@ void SARibbonButtonGroupWidget::actionEvent(QActionEvent* e) i = d_ptr->mItems.erase(i); } layout()->invalidate(); - updateGeometry(); } break; default: diff --git a/src/SARibbonBar/SARibbonCategory.cpp b/src/SARibbonBar/SARibbonCategory.cpp index e4faf415..30b43286 100644 --- a/src/SARibbonBar/SARibbonCategory.cpp +++ b/src/SARibbonBar/SARibbonCategory.cpp @@ -5,13 +5,11 @@ #include #include #include -#include "SARibbonToolButton.h" #include #include #include #include #include "SARibbonCategoryLayout.h" -#include "SARibbonSeparatorWidget.h" #include "SARibbonElementManager.h" /// @@ -52,7 +50,6 @@ class SARibbonCategory::PrivateData bool mIsContextCategory { false }; ///< 标记是否是上下文标签 bool mIsCanCustomize { true }; ///< 标记是否可以自定义 SARibbonPannel::PannelLayoutMode mDefaultPannelLayoutMode { SARibbonPannel::ThreeRowMode }; - SARibbonBar* mBar { nullptr }; }; SARibbonCategory::PrivateData::PrivateData(SARibbonCategory* p) : q_ptr(p) { @@ -96,7 +93,6 @@ void SARibbonCategory::PrivateData::insertPannel(int index, SARibbonPannel* pann pannel->setParent(q_ptr); } pannel->setPannelLayoutMode(ribbonPannelLayoutMode()); - pannel->installEventFilter(q_ptr); index = qMax(0, index); index = qMin(lay->pannelCount(), index); lay->addPannel(pannel); @@ -160,10 +156,10 @@ const SARibbonCategory* SARibbonCategory::PrivateData::ribbonCategory() const */ void SARibbonCategory::PrivateData::setRibbonPannelLayoutMode(SARibbonPannel::PannelLayoutMode m) { - // 不做相同判断,这样可以通过此函数强制重新布局 - // if (mDefaultPannelLayoutMode == m) { - // return; - // } + if (mDefaultPannelLayoutMode == m) { + return; + } + mDefaultPannelLayoutMode = m; QList< SARibbonPannel* > ps = pannelList(); @@ -180,9 +176,11 @@ SARibbonPannel::PannelLayoutMode SARibbonCategory::PrivateData::ribbonPannelLayo void SARibbonCategory::PrivateData::updateItemGeometry() { +#if SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "SARibbonCategory::PrivateData::updateItemGeometry,categoryName=" << q_ptr->categoryName(); +#endif if (SARibbonCategoryLayout* lay = qobject_cast< SARibbonCategoryLayout* >(q_ptr->layout())) { lay->invalidate(); - lay->doLayout(); } return; } @@ -274,6 +272,11 @@ void SARibbonCategory::setRibbonPannelLayoutMode(SARibbonPannel::PannelLayoutMod d_ptr->setRibbonPannelLayoutMode(m); } +bool SARibbonCategory::event(QEvent* e) +{ + return QWidget::event(e); +} + SARibbonPannel::PannelLayoutMode SARibbonCategory::ribbonPannelLayoutMode() const { return (d_ptr->ribbonPannelLayoutMode()); @@ -514,7 +517,12 @@ void SARibbonCategory::setCanCustomize(bool b) */ SARibbonBar* SARibbonCategory::ribbonBar() const { - return (d_ptr->mBar); + if (QWidget* par = parentWidget()) { + if (SARibbonBar* ribbon = qobject_cast< SARibbonBar* >(par->parentWidget())) { + return ribbon; + } + } + return nullptr; } /** @@ -522,16 +530,10 @@ SARibbonBar* SARibbonCategory::ribbonBar() const */ void SARibbonCategory::updateItemGeometry() { - QList< SARibbonPannel* > pannels = pannelList(); - for (SARibbonPannel* p : qAsConst(pannels)) { - p->updateItemGeometry(); - } - if (QLayout* lay = layout()) { - lay->invalidate(); - updateGeometry(); - QResizeEvent* e = new QResizeEvent(size(), QSize()); - QApplication::postEvent(this, e); - } +#if SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "SARibbonCategory name=" << categoryName() << " updateItemGeometry"; +#endif + d_ptr->updateItemGeometry(); } /** @@ -559,32 +561,6 @@ SARibbonAlignment SARibbonCategory::getCategoryAlignment() const return SARibbonAlignment::AlignLeft; } -bool SARibbonCategory::eventFilter(QObject* watched, QEvent* event) -{ - if (nullptr == watched) { - return (false); - } - SARibbonPannel* pannel = qobject_cast< SARibbonPannel* >(watched); - - if (pannel) { - switch (event->type()) { - case QEvent::HideToParent: { - // 隐藏和显示都要重新布局 - layout()->invalidate(); - } break; - - case QEvent::ShowToParent: { - // 隐藏和显示都要重新布局 - layout()->invalidate(); - } break; - - default: - break; - } - } - return (false); -} - /** * @brief 在超出边界情况下,滚轮可滚动pannel * @param event @@ -594,6 +570,35 @@ void SARibbonCategory::wheelEvent(QWheelEvent* event) d_ptr->doWheelEvent(event); } +void SARibbonCategory::changeEvent(QEvent* event) +{ + switch (event->type()) { + case QEvent::StyleChange: { + if (layout()) { +#if SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "SARibbonCategory changeEvent(StyleChange),categoryName=" << categoryName(); +#endif + layout()->invalidate(); + } + } break; + case QEvent::FontChange: { +#if SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "SARibbonCategory changeEvent(FontChange),categoryName=" << categoryName(); +#endif + QList< SARibbonPannel* > pannels = pannelList(); + for (SARibbonPannel* p : qAsConst(pannels)) { + p->setFont(font()); + } + if (layout()) { + layout()->invalidate(); + } + } break; + default: + break; + }; + return QWidget::changeEvent(event); +} + /** * @brief 标记这个是上下文标签 * @param isContextCategory @@ -612,15 +617,6 @@ SARibbonCategoryLayout* SARibbonCategory::categoryLayout() const return qobject_cast< SARibbonCategoryLayout* >(layout()); } -/** - * @brief 设置ribbonbar,此函数仅提供给ribbonbar调用 - * @param bar ribbonbar指针 - */ -void SARibbonCategory::setRibbonBar(SARibbonBar* bar) -{ - d_ptr->mBar = bar; -} - //=================================================== // SARibbonCategoryScrollButton //=================================================== diff --git a/src/SARibbonBar/SARibbonCategory.h b/src/SARibbonBar/SARibbonCategory.h index fff9a8b9..742b0331 100644 --- a/src/SARibbonBar/SARibbonCategory.h +++ b/src/SARibbonBar/SARibbonCategory.h @@ -100,10 +100,11 @@ class SA_RIBBON_EXPORT SARibbonCategory : public QWidget protected: //设置pannel的模式 void setRibbonPannelLayoutMode(SARibbonPannel::PannelLayoutMode m); - bool eventFilter(QObject* watched, QEvent* event) Q_DECL_OVERRIDE; - + virtual bool event(QEvent* e) Q_DECL_OVERRIDE; //处理滚轮事件 void wheelEvent(QWheelEvent* event) Q_DECL_OVERRIDE; + // + void changeEvent(QEvent* event) Q_DECL_OVERRIDE; //标记这个是上下文标签 void markIsContextCategory(bool isContextCategory = true); @@ -114,9 +115,6 @@ class SA_RIBBON_EXPORT SARibbonCategory : public QWidget //设置Category的对齐方式 void setCategoryAlignment(SARibbonAlignment al); SARibbonAlignment getCategoryAlignment() const; - -private: - void setRibbonBar(SARibbonBar* bar); }; /** diff --git a/src/SARibbonBar/SARibbonCategoryLayout.cpp b/src/SARibbonBar/SARibbonCategoryLayout.cpp index 60ef1ab8..a94368e7 100644 --- a/src/SARibbonBar/SARibbonCategoryLayout.cpp +++ b/src/SARibbonBar/SARibbonCategoryLayout.cpp @@ -255,7 +255,6 @@ void SARibbonCategoryLayout::updateGeometryArr() if (nullptr == category) { return; } - int categoryWidth = category->width(); QMargins mag = contentsMargins(); int height = category->height(); @@ -379,6 +378,10 @@ void SARibbonCategoryLayout::updateGeometryArr() } #endif d_ptr->mSizeHint = QSize(parentWidth, parentHeight); +#if SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "SARibbonCategory name=" << category->categoryName() + << " SARibbonCategoryLayout updateGeometryArr,SizeHint=" << d_ptr->mSizeHint; +#endif } /** @@ -433,6 +436,9 @@ void SARibbonCategoryLayout::doLayout() for (QWidget* w : qAsConst(hideWidgets)) { w->hide(); } +#if SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "SARibbonCategory name=" << category->categoryName() << " SARibbonCategoryLayout doLayout"; +#endif } /** diff --git a/src/SARibbonBar/SARibbonGlobal.h b/src/SARibbonBar/SARibbonGlobal.h index b7472a15..d992261a 100644 --- a/src/SARibbonBar/SARibbonGlobal.h +++ b/src/SARibbonBar/SARibbonGlobal.h @@ -178,4 +178,14 @@ enum class SARibbonAlignment #define SA_FONTMETRICS_WIDTH(fm, str) fm.width(str) #endif #endif + +#ifndef SA_DEBUG_PRINT_SIZE_HINT +/** + @def 定义此宏,将打印和尺寸刷新相关的信息 + + 仅用于调试 + */ +#define SA_DEBUG_PRINT_SIZE_HINT 0 +#endif + #endif // SARIBBONGLOBAL_H diff --git a/src/SARibbonBar/SARibbonPannel.cpp b/src/SARibbonBar/SARibbonPannel.cpp index 09aa83fe..b2653058 100644 --- a/src/SARibbonBar/SARibbonPannel.cpp +++ b/src/SARibbonBar/SARibbonPannel.cpp @@ -2,7 +2,6 @@ #include "SARibbonCategory.h" #include "SARibbonElementManager.h" #include "SARibbonGallery.h" -#include "SARibbonMenu.h" #include "SARibbonPannelLayout.h" #include "SARibbonPannelOptionButton.h" #include "SARibbonSeparatorWidget.h" @@ -155,6 +154,10 @@ void SARibbonPannel::setActionRowProportion(QAction* action, SARibbonPannelItem: SARibbonPannelItem* it = lay->pannelItem(action); if (it) { it->rowProportion = rp; +#if SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "SARibbonPannel setActionRowProportion,pannelName=" << pannelName() + << ",action name=" << action->text() << ",rp=" << static_cast< int >(rp); +#endif lay->invalidate(); } } @@ -442,13 +445,12 @@ QList< SARibbonToolButton* > SARibbonPannel::ribbonToolButtons() const */ void SARibbonPannel::setPannelLayoutMode(SARibbonPannel::PannelLayoutMode mode) { - // 不做相同判断,这样可以进行强制布局 - // if (d_ptr->m_pannelLayoutMode == mode) { - // return; - // } + if (d_ptr->m_pannelLayoutMode == mode) { + return; + } d_ptr->m_pannelLayoutMode = mode; - resetLayout(mode); resetLargeToolButtonStyle(); + resetLayout(mode); } SARibbonPannel::PannelLayoutMode SARibbonPannel::pannelLayoutMode() const @@ -490,7 +492,7 @@ bool SARibbonPannel::isHaveOptionAction() const return (d_ptr->m_optionActionButton != nullptr); } -void SARibbonPannel::paintEvent(QPaintEvent* event) +void SARibbonPannel::paintEvent(QPaintEvent* e) { QPainter p(this); @@ -518,7 +520,7 @@ void SARibbonPannel::paintEvent(QPaintEvent* event) } } - QWidget::paintEvent(event); + QWidget::paintEvent(e); } QSize SARibbonPannel::sizeHint() const @@ -685,21 +687,46 @@ SARibbonPannelLayout* SARibbonPannel::pannelLayout() const */ void SARibbonPannel::updateItemGeometry() { +#if SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "SARibbonPannel updateItemGeometry,pannelName=" << pannelName(); +#endif if (QLayout* lay = layout()) { lay->invalidate(); } - updateGeometry(); - QResizeEvent* e = new QResizeEvent(size(), QSize()); - QApplication::postEvent(this, e); +} + +/** + @brief 获取category指针,如果没有parent,或者不在category管理,返回nullptr + @return + */ +SARibbonCategory* SARibbonPannel::category() const +{ + return qobject_cast< SARibbonCategory* >(parent()); +} + +/** + @brief 获取ribbonBar指针,如果没有返回nullptr + @return + */ +SARibbonBar* SARibbonPannel::ribbonBar() const +{ + if (SARibbonCategory* c = category()) { + return c->ribbonBar(); + } + return nullptr; } void SARibbonPannel::resetLayout(PannelLayoutMode newmode) { Q_UNUSED(newmode); - if (QLayout* ly = layout()) { - ly->invalidate(); - layout()->setSpacing(TwoRowMode == newmode ? 4 : 2); - updateGeometry(); // 通知layout进行重新布局 +#if SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "SARibbonPannel resetLayout,pannelName=" << pannelName(); +#endif + if (ribbonBar()) { + if (QLayout* ly = layout()) { + layout()->setSpacing(TwoRowMode == newmode ? 4 : 2); + ly->invalidate(); + } } } @@ -719,14 +746,29 @@ void SARibbonPannel::resetLargeToolButtonStyle() } } -void SARibbonPannel::resizeEvent(QResizeEvent* event) +bool SARibbonPannel::event(QEvent* e) +{ + // if (SARibbonPannelLayout* lay = pannelLayout()) { + // if (lay->isDirty() && e->type() == QEvent::LayoutRequest) { + // if (QWidget* parw = parentWidget()) { + // if (QLayout* pl = parw->layout()) { + // pl->invalidate(); + // } + // } + // lay->m_dirty = false; + // } + // } + return QWidget::event(e); +} + +void SARibbonPannel::resizeEvent(QResizeEvent* e) { //! 1.移动操作按钮到角落 if (d_ptr->m_optionActionButton) { if (ThreeRowMode == pannelLayoutMode()) { d_ptr->m_optionActionButton->move(width() - d_ptr->m_optionActionButton->width() - 2, height() - titleHeight() - + (titleHeight() - d_ptr->m_optionActionButton->height()) / 2); + + (titleHeight() - d_ptr->m_optionActionButton->height()) / 2); } else { d_ptr->m_optionActionButton->move(width() - d_ptr->m_optionActionButton->width(), height() - d_ptr->m_optionActionButton->height()); @@ -734,7 +776,7 @@ void SARibbonPannel::resizeEvent(QResizeEvent* event) } //! 2.resize后,重新设置分割线的高度 //! 由于分割线在布局中,只要分割线足够高就可以,不需要重新设置 - return (QWidget::resizeEvent(event)); + return (QWidget::resizeEvent(e)); } /** @@ -776,42 +818,36 @@ void SARibbonPannel::actionEvent(QActionEvent* e) } lay->insertAction(index, action, getActionRowProportionProperty(action)); // 由于pannel的尺寸发生变化,需要让category也调整 - if (QWidget* parw = parentWidget()) { - if (QLayout* pl = parw->layout()) { - pl->invalidate(); - } - } + // if (QWidget* parw = parentWidget()) { + // if (QLayout* pl = parw->layout()) { + // pl->invalidate(); + // } + // } } break; case QEvent::ActionChanged: { // 让布局重新绘制 layout()->invalidate(); - updateGeometry(); + // updateGeometry(); // 由于pannel的尺寸发生变化,需要让category也调整 if (QWidget* parw = parentWidget()) { -#if SARibbonPannel_DEBUG_PRINT - if (SARibbonCategory* category = qobject_cast< SARibbonCategory* >(parw)) { - qDebug() << "pannel (" << pannelName() << ") action(" << action->text() << ") Changed,at category" - << category->categoryName(); - } -#endif if (QLayout* pl = parw->layout()) { pl->invalidate(); } - //! 强制发送一个resizeevent,让Category能重绘,如果没有这个函数,发现Category的layout虽然设置了invalidate(标记缓存失效) - //! 但并没有按顺序在pannel尺寸更新后更新Category的尺寸,导致有些pannel的尺寸识别出现异常 - //! 重打印信息上看,pannel的尺寸有进行更新,category的尺寸也进行了更新,但更新的次数和调用invalidate的次数不一样,需要手动触发ResizeEvent - //! 尝试过调用QEvent::LayoutRequest没有效果: - //! @code - //! QEvent* e = new QEvent(QEvent::LayoutRequest); - //! QApplication::postEvent(parw, e); - //! @endcode - //! - //! 调用parw->updateGeometry();也没有效果,目前看使用resizeevent是最有效果的 - //! - parw->updateGeometry(); - QResizeEvent* e = new QResizeEvent(parw->size(), QSize()); - QApplication::postEvent(parw, e); + // //! 强制发送一个resizeevent,让Category能重绘,如果没有这个函数,发现Category的layout虽然设置了invalidate(标记缓存失效) + // //! 但并没有按顺序在pannel尺寸更新后更新Category的尺寸,导致有些pannel的尺寸识别出现异常 + // //! 重打印信息上看,pannel的尺寸有进行更新,category的尺寸也进行了更新,但更新的次数和调用invalidate的次数不一样,需要手动触发ResizeEvent + // //! 尝试过调用QEvent::LayoutRequest没有效果: + // //! @code + // //! QEvent* el = new QEvent(QEvent::LayoutRequest); + // //! QApplication::postEvent(parw, el); + // //! @endcode + // //! + // //! 调用parw->updateGeometry();也没有效果,目前看使用resizeevent是最有效果的 + // //! + // // parw->updateGeometry(); + // QResizeEvent* ersize = new QResizeEvent(parw->size(), QSize()); + // QApplication::postEvent(parw, ersize); } } break; @@ -824,11 +860,11 @@ void SARibbonPannel::actionEvent(QActionEvent* e) delete item; } // 由于pannel的尺寸发生变化,需要让category也调整 - if (QWidget* parw = parentWidget()) { - if (QLayout* pl = parw->layout()) { - pl->invalidate(); - } - } + // if (QWidget* parw = parentWidget()) { + // if (QLayout* pl = parw->layout()) { + // pl->invalidate(); + // } + // } } break; default: @@ -854,8 +890,8 @@ void SARibbonPannel::changeEvent(QEvent* e) if (QLayout* lay = layout()) { lay->invalidate(); } - QWidget::changeEvent(e); } + QWidget::changeEvent(e); } /** diff --git a/src/SARibbonBar/SARibbonPannel.h b/src/SARibbonBar/SARibbonPannel.h index 76871f4e..f2d9f717 100644 --- a/src/SARibbonBar/SARibbonPannel.h +++ b/src/SARibbonBar/SARibbonPannel.h @@ -11,7 +11,8 @@ class SARibbonGallery; class QGridLayout; class SARibbonPannelOptionButton; class SARibbonPannelLayout; - +class SARibbonCategory; +class SARibbonBar; /** * @brief pannel页窗口,pannel是ribbon的面板用于承放控件 * @@ -31,6 +32,7 @@ class SA_RIBBON_EXPORT SARibbonPannel : public QWidget friend class SARibbonCategory; friend class SARibbonCategoryPrivate; friend class SARibbonCustomizeWidgetPrivate; + friend class SARibbonPannelLayout; Q_PROPERTY(bool isCanCustomize READ isCanCustomize WRITE setCanCustomize) Q_PROPERTY(bool isExpanding READ isExpanding WRITE setExpanding) Q_PROPERTY(QString pannelName READ pannelName WRITE setPannelName) @@ -171,6 +173,10 @@ class SA_RIBBON_EXPORT SARibbonPannel : public QWidget SARibbonPannelLayout* pannelLayout() const; // 更新布局 void updateItemGeometry(); + //获取category指针,如果没有parent,或者不在category管理,返回nullptr + SARibbonCategory* category() const; + //获取ribbonBar指针,如果没有返回nullptr + SARibbonBar* ribbonBar() const; signals: /** @@ -186,8 +192,9 @@ class SA_RIBBON_EXPORT SARibbonPannel : public QWidget void resetLargeToolButtonStyle(); protected: - virtual void paintEvent(QPaintEvent* event) Q_DECL_OVERRIDE; - virtual void resizeEvent(QResizeEvent* event) Q_DECL_OVERRIDE; + virtual bool event(QEvent* e) Q_DECL_OVERRIDE; + virtual void paintEvent(QPaintEvent* e) Q_DECL_OVERRIDE; + virtual void resizeEvent(QResizeEvent* e) Q_DECL_OVERRIDE; virtual void actionEvent(QActionEvent* e) Q_DECL_OVERRIDE; virtual void changeEvent(QEvent* e) Q_DECL_OVERRIDE; }; diff --git a/src/SARibbonBar/SARibbonPannelLayout.cpp b/src/SARibbonBar/SARibbonPannelLayout.cpp index a09d39f3..30d6f0e8 100644 --- a/src/SARibbonBar/SARibbonPannelLayout.cpp +++ b/src/SARibbonBar/SARibbonPannelLayout.cpp @@ -1,12 +1,9 @@ #include "SARibbonPannelLayout.h" #include "SARibbonPannelOptionButton.h" #include "SARibbonSeparatorWidget.h" -#include "SARibbonGallery.h" #include "SARibbonElementManager.h" -#include "SARibbonMenu.h" #include #include -#include #include "SARibbonPannel.h" #include "SARibbonPannelItem.h" #define SARibbonPannelLayout_DEBUG_PRINT 0 @@ -36,6 +33,7 @@ SARibbonPannelLayout::SARibbonPannelLayout(QWidget* p) SARibbonPannelLayout::~SARibbonPannelLayout() { + //参考QToolBarLayout while (!m_items.isEmpty()) { SARibbonPannelItem* item = m_items.takeFirst(); if (QWidgetAction* widgetAction = qobject_cast< QWidgetAction* >(item->action)) { @@ -123,6 +121,7 @@ int SARibbonPannelLayout::count() const bool SARibbonPannelLayout::isEmpty() const { + return (m_items.isEmpty()); } @@ -215,6 +214,8 @@ void SARibbonPannelLayout::move(int from, int to) */ bool SARibbonPannelLayout::isDirty() const { + SARibbonPannelLayout* that = const_cast< SARibbonPannelLayout* >(this); + that->updateGeomArray(QRect()); return (m_dirty); } @@ -289,6 +290,11 @@ void SARibbonPannelLayout::layoutActions() for (QWidget* w : qAsConst(hideWidgets)) { w->hide(); } +#if SA_DEBUG_PRINT_SIZE_HINT + if (SARibbonPannel* pannel = qobject_cast< SARibbonPannel* >(parentWidget())) { + qDebug() << "SARibbonPannelLayout layoutActions,pannel name = " << pannel->pannelName(); + } +#endif } /** @@ -408,17 +414,18 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) SARibbonPannelItem* item = m_items.at(i); if (item->isEmpty()) { // 如果是hide就直接跳过 -#if SARibbonPannelLayout_DEBUG_PRINT - qDebug() << item->widget()->metaObject()->className() << "is hide" - << " row:" << row << " col:" << column; -#endif item->rowIndex = -1; item->columnIndex = -1; continue; } QSize hint = item->sizeHint(); - +#if SA_DEBUG_PRINT_SIZE_HINT + if (SARibbonToolButton* tb = qobject_cast< SARibbonToolButton* >(item->widget())) { + qDebug() << "SARibbonPannelItem sizeHint=" << hint << " SARibbonToolButton::sizeHint=" << tb->sizeHint() + << " ,name=" << tb->text(); + } +#endif Qt::Orientations exp = item->expandingDirections(); if (item->widget()) { // 有窗口是水平扩展,则标记为扩展 @@ -443,8 +450,6 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) if (row != 0) { x += (columMaxWidth + spacing); ++column; - row = 0; - columMaxWidth = 0; } // item->rowIndex = 0; @@ -615,8 +620,15 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) recalcExpandGeomArray(setrect); } this->m_sizeHint = QSize(totalWidth, height); -#if SARibbonPannelLayout_DEBUG_PRINT - qDebug() << "SARibbonPannelLayout::updateGeomArray,m_sizeHint=" << m_sizeHint; +#if SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "SARibbonPannelLayout updateGeomArray,pannel name = " << pannel->pannelName() + << "\n size hint =" << this->m_sizeHint // + << "\n spacing=" << spacing // + << "\n mag=" << mag // + << "\n largeHeight=" << largeHeight // + << "\n smallHeight=" << smallHeight // + ; + ; #endif } diff --git a/src/SARibbonBar/SARibbonToolButton.h b/src/SARibbonBar/SARibbonToolButton.h index b26116e6..51bdd2b4 100644 --- a/src/SARibbonBar/SARibbonToolButton.h +++ b/src/SARibbonBar/SARibbonToolButton.h @@ -44,6 +44,8 @@ class SA_RIBBON_EXPORT SARibbonToolButton : public QToolButton //更新尺寸 void updateRect(); + virtual QSize sizeHint() const Q_DECL_OVERRIDE; + public: //在lite模式下是否允许文字换行 static void setEnableWordWrap(bool on); @@ -58,7 +60,6 @@ class SA_RIBBON_EXPORT SARibbonToolButton : public QToolButton virtual void focusOutEvent(QFocusEvent* e) Q_DECL_OVERRIDE; virtual void leaveEvent(QEvent* e) Q_DECL_OVERRIDE; virtual bool hitButton(const QPoint& pos) const Q_DECL_OVERRIDE; - virtual QSize sizeHint() const Q_DECL_OVERRIDE; virtual bool event(QEvent* e) Q_DECL_OVERRIDE; //事件改变 - 主要为了捕获字体的改变 virtual void changeEvent(QEvent* e) Q_DECL_OVERRIDE; diff --git a/src/example/MainWindowExample/mainwindow.cpp b/src/example/MainWindowExample/mainwindow.cpp index 650277a7..ab07da87 100644 --- a/src/example/MainWindowExample/mainwindow.cpp +++ b/src/example/MainWindowExample/mainwindow.cpp @@ -11,7 +11,6 @@ #include "SARibbonComboBox.h" #include "SARibbonCustomizeDialog.h" #include "SARibbonCustomizeWidget.h" -#include "SARibbonElementManager.h" #include "SARibbonGallery.h" #include "SARibbonLineEdit.h" #include "SARibbonMenu.h" From 97d128b1a2027b18e9e788e086a969f60c2e7e6c Mon Sep 17 00:00:00 2001 From: czyt1988 Date: Sun, 17 Dec 2023 00:23:43 +0800 Subject: [PATCH 09/16] =?UTF-8?q?=E6=8C=89=E9=92=AE=E7=9A=84=E6=9C=80?= =?UTF-8?q?=E5=B0=8F=E5=AE=BD=E5=BA=A6=E4=B8=8D=E4=BC=9A=E5=B0=8F=E4=BA=8E?= =?UTF-8?q?=E5=9B=BE=E6=A0=87=E5=AE=BD=E5=BA=A6=EF=BC=8C=E9=81=BF=E5=85=8D?= =?UTF-8?q?=E6=8C=89=E9=92=AE=E7=9A=84=E5=AE=BD=E5=BA=A6=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SARibbonBar/SARibbonToolButton.cpp | 22 +++++++++++--------- src/example/MainWindowExample/mainwindow.cpp | 3 +++ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/SARibbonBar/SARibbonToolButton.cpp b/src/SARibbonBar/SARibbonToolButton.cpp index de4a5fb6..42dbf958 100644 --- a/src/SARibbonBar/SARibbonToolButton.cpp +++ b/src/SARibbonBar/SARibbonToolButton.cpp @@ -269,7 +269,7 @@ void SARibbonToolButton::PrivateData::calcSmallButtonDrawRects(const QStyleOptio case Qt::ToolButtonIconOnly: { if (hasIndicator(opt)) { // 在仅有图标的小模式显示时,预留一个下拉箭头位置 - iconRect = opt.rect.adjusted(spacing, spacing, -indicatorLen - spacing, -spacing); + iconRect = opt.rect.adjusted(spacing, spacing, -indicatorLen - spacing, -spacing); indicatorArrowRect = QRect(opt.rect.right() - indicatorLen - spacing, iconRect.y(), indicatorLen, iconRect.height()); } else { iconRect = opt.rect.adjusted(spacing, spacing, -spacing, -spacing); @@ -281,7 +281,7 @@ void SARibbonToolButton::PrivateData::calcSmallButtonDrawRects(const QStyleOptio case Qt::ToolButtonTextOnly: { if (hasIndicator(opt)) { // 在仅有图标的小模式显示时,预留一个下拉箭头位置 - textRect = opt.rect.adjusted(spacing, spacing, -indicatorLen - spacing, -spacing); + textRect = opt.rect.adjusted(spacing, spacing, -indicatorLen - spacing, -spacing); indicatorArrowRect = QRect(opt.rect.right() - indicatorLen - spacing, spacing, indicatorLen, textRect.height()); } else { textRect = opt.rect.adjusted(spacing, spacing, -spacing, -spacing); @@ -484,26 +484,28 @@ QSize SARibbonToolButton::PrivateData::calcLargeButtonSizeHint(const QStyleOptio int w = 0; int h = opt.fontMetrics.lineSpacing() * 4.5; // 3*1.5 int minW = h * 0.75; // 最小宽度,在pannel里面的按钮,最小宽度要和icon适应 - if (mDrawIconRect.isValid()) { - minW = mDrawIconRect.width(); - } + if (SARibbonPannel* pannel = qobject_cast< SARibbonPannel* >(q_ptr->parent())) { // 对于建立在SARibbonPannel的基础上的大按钮,把高度设置为SARibbonPannel计算的大按钮高度 h = pannel->largeHeight(); } + int textHeight = calcTextDrawRectHeight(opt); + if (mDrawIconRect.isValid()) { + minW = qMax(mDrawIconRect.width(), h - textHeight); + } // 估算字体的宽度作为宽度 - w = estimateLargeButtonTextWidth(h, calcTextDrawRectHeight(opt), opt.text, opt.fontMetrics); + w = estimateLargeButtonTextWidth(h, textHeight, opt.text, opt.fontMetrics); w += (2 * mSpacing); // 判断是否需要加上indicator if (isEnableWordWrap() && isTextNeedWrap()) { w += mIndicatorLen; } - if (w < minW) { - w = minW; - } + // if (w < minW) { + // w = minW; + // } //! Qt6.4 取消了QApplication::globalStrut - return QSize(w, h).expandedTo(QSize(2, 2)); + return QSize(w, h).expandedTo(QSize(minW, textHeight)); } /** diff --git a/src/example/MainWindowExample/mainwindow.cpp b/src/example/MainWindowExample/mainwindow.cpp index ab07da87..dd61bbe6 100644 --- a/src/example/MainWindowExample/mainwindow.cpp +++ b/src/example/MainWindowExample/mainwindow.cpp @@ -1071,6 +1071,9 @@ void MainWindow::createContextCategoryPage1(SARibbonCategory* page) mActionDisable->setEnabled(true); mActionDisable->setText(("Enabled")); }); + auto act = createAction(tr("1"), ":/icon/icon/unlock.svg"); + act->setToolTip(tr("very short string")); + pannel->addLargeAction(act); mActionSetTextTest = createAction("set text", ":/icon/icon/setText.svg"); From c754b2026cf38538205d5c937317951a79a60179 Mon Sep 17 00:00:00 2001 From: czyt1988 Date: Sun, 17 Dec 2023 23:42:07 +0800 Subject: [PATCH 10/16] =?UTF-8?q?SARibbonCategory=E5=8F=AF=E9=80=9A?= =?UTF-8?q?=E8=BF=87qss=E8=AE=BE=E7=BD=AE=E8=83=8C=E6=99=AF=E9=A2=9C?= =?UTF-8?q?=E8=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SARibbonBar/SARibbonCategory.cpp | 2 ++ src/SARibbonBar/resource/theme-dark.qss | 8 ++++---- src/SARibbonBar/resource/theme-office2013.qss | 7 +++---- src/SARibbonBar/resource/theme-office2016-blue.qss | 7 +++---- src/SARibbonBar/resource/theme-office2021-blue.qss | 1 - src/SARibbonBar/resource/theme-win7.qss | 1 - src/example/MainWindowExample/mainwindow.cpp | 14 +++++++++++--- 7 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/SARibbonBar/SARibbonCategory.cpp b/src/SARibbonBar/SARibbonCategory.cpp index 30b43286..632761df 100644 --- a/src/SARibbonBar/SARibbonCategory.cpp +++ b/src/SARibbonBar/SARibbonCategory.cpp @@ -228,12 +228,14 @@ void SARibbonCategory::PrivateData::doWheelEvent(QWheelEvent* event) SARibbonCategory::SARibbonCategory(QWidget* p) : QWidget(p), d_ptr(new SARibbonCategory::PrivateData(this)) { + setAttribute(Qt::WA_StyledBackground); setLayout(new SARibbonCategoryLayout(this)); } SARibbonCategory::SARibbonCategory(const QString& name, QWidget* p) : QWidget(p), d_ptr(new SARibbonCategory::PrivateData(this)) { + setAttribute(Qt::WA_StyledBackground); setLayout(new SARibbonCategoryLayout(this)); setCategoryName(name); } diff --git a/src/SARibbonBar/resource/theme-dark.qss b/src/SARibbonBar/resource/theme-dark.qss index 099bb8da..4ec45baf 100644 --- a/src/SARibbonBar/resource/theme-dark.qss +++ b/src/SARibbonBar/resource/theme-dark.qss @@ -28,17 +28,17 @@ SARibbonCtrlContainer { } /*SARibbonCategory*/ +SARibbonCategory { + background-color: #b2b2b2; +} SARibbonCategory:focus { outline: none; } -SARibbonCategory { - background-color: #b2b2b2; -} + /*SARibbonStackedWidget*/ SARibbonStackedWidget{ - background-color: #b2b2b2; border-top-width: 0px; } SARibbonStackedWidget:focus{ diff --git a/src/SARibbonBar/resource/theme-office2013.qss b/src/SARibbonBar/resource/theme-office2013.qss index 063b5581..d7635f64 100644 --- a/src/SARibbonBar/resource/theme-office2013.qss +++ b/src/SARibbonBar/resource/theme-office2013.qss @@ -27,17 +27,16 @@ SARibbonCtrlContainer { } /*SARibbonCategory*/ +SARibbonCategory { + background-color: #fcfdfe; +} SARibbonCategory:focus { outline: none; } -SARibbonCategory { - background-color: #fcfdfe; -} /*SARibbonStackedWidget*/ SARibbonStackedWidget { - background-color: white; border: 1pt solid #c5d2e0; border-top-width: 0px; } diff --git a/src/SARibbonBar/resource/theme-office2016-blue.qss b/src/SARibbonBar/resource/theme-office2016-blue.qss index c90c6cc1..99c19ab9 100644 --- a/src/SARibbonBar/resource/theme-office2016-blue.qss +++ b/src/SARibbonBar/resource/theme-office2016-blue.qss @@ -95,13 +95,13 @@ SARibbonCtrlContainer { } /*SARibbonCategory*/ -SARibbonCategory:focus { - outline: none; -} SARibbonCategory { background-color: #f1f1f1;/* {Category.BKColor} */ } +SARibbonCategory:focus { + outline: none; +} /*SARibbonCategoryScrollButton*/ @@ -131,7 +131,6 @@ SARibbonPannel > SARibbonButtonGroupWidget { /*SARibbonStackedWidget*/ SARibbonStackedWidget { - background-color: #f1f1f1;/* {Category.BKColor} */ border: 1pt solid #f1f1f1;/* {Category.BorderColor} */ border-top-width: 0px; } diff --git a/src/SARibbonBar/resource/theme-office2021-blue.qss b/src/SARibbonBar/resource/theme-office2021-blue.qss index 6e978076..cbbca157 100644 --- a/src/SARibbonBar/resource/theme-office2021-blue.qss +++ b/src/SARibbonBar/resource/theme-office2021-blue.qss @@ -130,7 +130,6 @@ SARibbonPannel > SARibbonButtonGroupWidget { /*SARibbonStackedWidget*/ SARibbonStackedWidget { - background-color: #ffffff;/* {Category.BKColor} */ border: 1pt solid #ffffff;/* {Category.BorderColor} */ border-top-width: 0px; } diff --git a/src/SARibbonBar/resource/theme-win7.qss b/src/SARibbonBar/resource/theme-win7.qss index 8aca1d44..a2b085f1 100644 --- a/src/SARibbonBar/resource/theme-win7.qss +++ b/src/SARibbonBar/resource/theme-win7.qss @@ -36,7 +36,6 @@ SARibbonCategory{ /*SARibbonStackedWidget*/ SARibbonStackedWidget{ - background-color: white; border-top-width: 0px; } SARibbonStackedWidget:focus{ diff --git a/src/example/MainWindowExample/mainwindow.cpp b/src/example/MainWindowExample/mainwindow.cpp index dd61bbe6..43ebb17a 100644 --- a/src/example/MainWindowExample/mainwindow.cpp +++ b/src/example/MainWindowExample/mainwindow.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #define PRINT_COST_START() \ QElapsedTimer __TMP_COST; \ __TMP_COST.start(); \ @@ -509,12 +510,17 @@ void MainWindow::createCategoryMain(SARibbonCategory* page) SARibbonPannel* pannelStyle = page->addPannel(("ribbon style")); QAction* actSave = createAction(tr("Save"), ":/icon/icon/save.svg"); - actSave->setShortcut(QKeySequence(QLatin1String("Ctrl+S"))); - pannelStyle->addLargeAction(actSave); + //这样设置快捷键 + QShortcut* shortCut = new QShortcut(QKeySequence(QLatin1String("Ctrl+S")), this); + connect(shortCut, &QShortcut::activated, this, [ actSave ]() { actSave->trigger(); }); + //这样设置是无效的 + // actSave->setShortcut(QKeySequence(QLatin1String("Ctrl+S"))); + connect(actSave, &QAction::triggered, this, [ this ](bool b) { Q_UNUSED(b); this->mTextedit->append("actSaveion clicked"); }); + pannelStyle->addLargeAction(actSave); QAction* actHideRibbon = createAction(tr("hide ribbon"), ":/icon/icon/hideRibbon.svg", "actHideRibbon"); actHideRibbon->setCheckable(true); @@ -1065,6 +1071,7 @@ void MainWindow::createContextCategoryPage1(SARibbonCategory* page) mActionUnlock = createAction(tr("unlock"), ":/icon/icon/unlock.svg"); mActionUnlock->setShortcut(QKeySequence(QLatin1String("Ctrl+E"))); + mActionUnlock->setShortcutContext(Qt::ApplicationShortcut); pannel->addLargeAction(mActionUnlock); connect(mActionUnlock, &QAction::triggered, this, [ this ](bool b) { Q_UNUSED(b); @@ -1079,6 +1086,7 @@ void MainWindow::createContextCategoryPage1(SARibbonCategory* page) mActionSetTextTest->setCheckable(true); mActionSetTextTest->setShortcut(QKeySequence(QLatin1String("Ctrl+D"))); + mActionSetTextTest->setShortcutContext(Qt::ApplicationShortcut); pannel->addLargeAction(mActionSetTextTest); connect(mActionSetTextTest, &QAction::toggled, this, [ this ](bool b) { @@ -1095,7 +1103,7 @@ void MainWindow::createContextCategoryPage1(SARibbonCategory* page) pannel->addLargeAction(mActionShowTest); mPannelVisbileExample = page->addPannel(tr("show/hide")); - + //重复添加 mPannelVisbileExample->addLargeAction(mActionSetTextTest); connect(mActionShowTest, &QAction::toggled, this, [ this ](bool b) { From 02577aec6cb747d7539af2ce8ab0f49eeeba4587 Mon Sep 17 00:00:00 2001 From: czyt1988 Date: Fri, 22 Dec 2023 17:32:42 +0800 Subject: [PATCH 11/16] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SARibbonBar/SARibbonGlobal.h | 24 ++--- src/SARibbonBar/SARibbonPannel.cpp | 116 ++++++++++------------- src/SARibbonBar/SARibbonPannel.h | 14 +-- src/SARibbonBar/SARibbonPannelItem.h | 19 +++- src/SARibbonBar/SARibbonPannelLayout.cpp | 17 +++- 5 files changed, 100 insertions(+), 90 deletions(-) diff --git a/src/SARibbonBar/SARibbonGlobal.h b/src/SARibbonBar/SARibbonGlobal.h index d992261a..46d2b84b 100644 --- a/src/SARibbonBar/SARibbonGlobal.h +++ b/src/SARibbonBar/SARibbonGlobal.h @@ -110,16 +110,7 @@ * @def ribbon的数字版本 MAJ.MIN.{PAT} */ #ifndef SA_RIBBON_BAR_VERSION_PAT -#define SA_RIBBON_BAR_VERSION_PAT 6 -#endif - -/** - * @def 属性,用于标记是否可以进行自定义,用于动态设置到@ref SARibbonCategory 和@ref SARibbonPannel - * 值为bool,在为true时,可以通过@ref SARibbonCustomizeWidget 改变这个SARibbonCategory和SARibbonPannel的布局, - * 默认不会有此属性,仅在有此属性且为true时才会在SARibbonCustomizeWidget中能显示为可设置 - */ -#ifndef SA_RIBBON_BAR_PROP_CAN_CUSTOMIZE -#define SA_RIBBON_BAR_PROP_CAN_CUSTOMIZE "_sa_isCanCustomize" +#define SA_RIBBON_BAR_VERSION_PAT 7 #endif #ifndef SA_RIBBON_BAR_NO_EXPORT @@ -150,7 +141,7 @@ #define SA_RIBBON_DECLARE_PUBLIC(classname) \ friend class classname; \ classname* q_ptr { nullptr }; \ - PrivateData(const PrivateData&) = delete; \ + PrivateData(const PrivateData&) = delete; \ PrivateData& operator=(const PrivateData&) = delete; #endif @@ -163,6 +154,15 @@ enum class SARibbonAlignment AlignCenter ///< 居中对其,tab栏居中对齐,同时category也是居中对齐 }; +/** + * @def 属性,用于标记是否可以进行自定义,用于动态设置到@ref SARibbonCategory 和@ref SARibbonPannel + * 值为bool,在为true时,可以通过@ref SARibbonCustomizeWidget 改变这个SARibbonCategory和SARibbonPannel的布局, + * 默认不会有此属性,仅在有此属性且为true时才会在SARibbonCustomizeWidget中能显示为可设置 + */ +#ifndef SA_RIBBON_BAR_PROP_CAN_CUSTOMIZE +#define SA_RIBBON_BAR_PROP_CAN_CUSTOMIZE "_sa_isCanCustomize" +#endif + /** * @def 定义此宏用第三方的frameless作为无边框方案 * 此宏在qmake或在cmake中定义,不需要在此显示定义 @@ -185,7 +185,7 @@ enum class SARibbonAlignment 仅用于调试 */ -#define SA_DEBUG_PRINT_SIZE_HINT 0 +#define SA_DEBUG_PRINT_SIZE_HINT 1 #endif #endif // SARIBBONGLOBAL_H diff --git a/src/SARibbonBar/SARibbonPannel.cpp b/src/SARibbonBar/SARibbonPannel.cpp index b2653058..0c6b6cb8 100644 --- a/src/SARibbonBar/SARibbonPannel.cpp +++ b/src/SARibbonBar/SARibbonPannel.cpp @@ -120,7 +120,7 @@ void SARibbonPannel::setActionRowProportionProperty(QAction* action, SARibbonPan if (action == nullptr) { return; } - action->setProperty(SARibbonPannelItemRowProportionPropertyName, int(rp)); + action->setProperty(SA_ActionPropertyName_RowProportion, static_cast< int >(rp)); } /** @@ -131,7 +131,7 @@ void SARibbonPannel::setActionRowProportionProperty(QAction* action, SARibbonPan SARibbonPannelItem::RowProportion SARibbonPannel::getActionRowProportionProperty(QAction* action) { bool isok = false; - int r = action->property(SARibbonPannelItemRowProportionPropertyName).toInt(&isok); + int r = action->property(SA_ActionPropertyName_RowProportion).toInt(&isok); if (isok) { return (static_cast< SARibbonPannelItem::RowProportion >(r)); @@ -150,67 +150,56 @@ void SARibbonPannel::setActionRowProportion(QAction* action, SARibbonPannelItem: return; } setActionRowProportionProperty(action, rp); - if (SARibbonPannelLayout* lay = pannelLayout()) { - SARibbonPannelItem* it = lay->pannelItem(action); - if (it) { - it->rowProportion = rp; -#if SA_DEBUG_PRINT_SIZE_HINT - qDebug() << "SARibbonPannel setActionRowProportion,pannelName=" << pannelName() - << ",action name=" << action->text() << ",rp=" << static_cast< int >(rp); -#endif - lay->invalidate(); - } - } } /** - * @brief 添加action - * @param action action - * @param rp 指定action的行占比 - * @return 返回对应的SARibbonToolButton,如果是窗口,返回的toolbutton为nullptr + @brief 添加action + + action实际对应了一个toolbutton,如果想找到对应的toolbutton,使用@ref actionToRibbonToolButton + @param action action + @param rp 指定action的行占比 + @sa actionToRibbonToolButton */ -SARibbonToolButton* SARibbonPannel::addAction(QAction* action, SARibbonPannelItem::RowProportion rp) +void SARibbonPannel::addAction(QAction* action, SARibbonPannelItem::RowProportion rp) { - if (action == nullptr) { - return nullptr; - } + Q_CHECK_PTR(action); setActionRowProportionProperty(action, rp); addAction(action); - - return (d_ptr->lastAddActionButton()); } /** - * @brief 添加大图标 - * - * @param action - * @sa 如果想获取actiom对应的SARibbonToolButton,可以使用@ref actionToRibbonToolButton 函数 + @brief 添加大图标 + + action实际对应了一个toolbutton,如果想找到对应的toolbutton,使用@ref actionToRibbonToolButton + @param action */ -SARibbonToolButton* SARibbonPannel::addLargeAction(QAction* action) +void SARibbonPannel::addLargeAction(QAction* action) { - return (addAction(action, SARibbonPannelItem::Large)); + addAction(action, SARibbonPannelItem::Large); } /** - * @brief 在三栏模式下,强制加为2栏action - * @note 在两行模式下,Medium和Small等价 - * 主要应用在ThreeRowMode下 - * @param action - * @sa 如果想获取actiom对应的SARibbonToolButton,可以使用@ref actionToRibbonToolButton 函数 + @brief 在三栏模式下,强制加为2栏action + @note 在两行模式下,Medium和Small等价 + 主要应用在ThreeRowMode下 + + action实际对应了一个toolbutton,如果想找到对应的toolbutton,使用@ref actionToRibbonToolButton + @param action */ -SARibbonToolButton* SARibbonPannel::addMediumAction(QAction* action) +void SARibbonPannel::addMediumAction(QAction* action) { - return (addAction(action, SARibbonPannelItem::Medium)); + addAction(action, SARibbonPannelItem::Medium); } /** - * @brief 添加小图标 - * @param action - * @sa 如果想获取actiom对应的SARibbonToolButton,可以使用@ref actionToRibbonToolButton 函数 + @brief 添加小图标 + + action实际对应了一个toolbutton,如果想找到对应的toolbutton,使用@ref actionToRibbonToolButton + @param action */ -SARibbonToolButton* SARibbonPannel::addSmallAction(QAction* action) +void SARibbonPannel::addSmallAction(QAction* action) { - return (addAction(action, SARibbonPannelItem::Small)); + addAction(action, SARibbonPannelItem::Small); } /** @@ -221,16 +210,10 @@ SARibbonToolButton* SARibbonPannel::addSmallAction(QAction* action) */ void SARibbonPannel::addAction(QAction* act, QToolButton::ToolButtonPopupMode popMode, SARibbonPannelItem::RowProportion rp) { - if (act == nullptr) { - return; - } + Q_CHECK_PTR(act); setActionRowProportionProperty(act, rp); + act->setProperty(SA_ActionPropertyName_ToolButtonPopupMode, static_cast< int >(popMode)); addAction(act); - SARibbonToolButton* btn = d_ptr->lastAddActionButton(); - - if (btn) { - btn->setPopupMode(popMode); - } } /** @@ -263,16 +246,15 @@ QAction* SARibbonPannel::addAction(const QString& text, const QIcon& icon, QTool */ SARibbonToolButton* SARibbonPannel::addMenu(QMenu* menu, SARibbonPannelItem::RowProportion rp, QToolButton::ToolButtonPopupMode popMode) { - if (menu == nullptr) { - return nullptr; - } + Q_CHECK_PTR(menu); QAction* action = menu->menuAction(); addAction(action, rp); - SARibbonToolButton* btn = d_ptr->lastAddActionButton(); - - btn->setPopupMode(popMode); - return (btn); + if (SARibbonToolButton* btn = d_ptr->lastAddActionButton()) { + btn->setPopupMode(popMode); + return (btn); + } + return nullptr; } /** @@ -284,6 +266,10 @@ SARibbonToolButton* SARibbonPannel::addMenu(QMenu* menu, SARibbonPannelItem::Row */ SARibbonToolButton* SARibbonPannel::addActionMenu(QAction* action, QMenu* menu, SARibbonPannelItem::RowProportion rp) { + Q_CHECK_PTR(action); + Q_CHECK_PTR(menu); + action->setProperty(SA_ActionPropertyName_IsActionMenu, true); + action->setProperty(SA_ActionPropertyName_MenuPointer, QVariant::fromValue(void*(menu))); SARibbonToolButton* btn = addAction(action, rp); if (nullptr == btn) { return nullptr; @@ -368,13 +354,14 @@ QAction* SARibbonPannel::addLargeWidget(QWidget* w) * @return * @note SARibbonPannel将拥有SARibbonGallery的管理权 */ -SARibbonGallery* SARibbonPannel::addGallery() +SARibbonGallery* SARibbonPannel::addGallery(bool expanding) { SARibbonGallery* gallery = RibbonSubElementDelegate->createRibbonGallery(this); addWidget(gallery, SARibbonPannelItem::Large); - - setExpanding(); + if (expanding) { + setExpanding(expanding); + } return (gallery); } @@ -389,14 +376,9 @@ QAction* SARibbonPannel::addSeparator(int top, int bottom) action->setSeparator(true); setActionRowProportionProperty(action, SARibbonPannelItem::Large); + action->setProperty(SA_ActionPropertyName_SeparatorTop, top); + action->setProperty(SA_ActionPropertyName_SeparatorBottom, bottom); addAction(action); - if (SARibbonPannelLayout* lay = pannelLayout()) { - QWidget* w = lay->lastWidget(); - SARibbonSeparatorWidget* sep = qobject_cast< SARibbonSeparatorWidget* >(w); - if (sep) { - sep->setTopBottomMargins(top, bottom); - } - } return (action); } @@ -768,7 +750,7 @@ void SARibbonPannel::resizeEvent(QResizeEvent* e) if (ThreeRowMode == pannelLayoutMode()) { d_ptr->m_optionActionButton->move(width() - d_ptr->m_optionActionButton->width() - 2, height() - titleHeight() - + (titleHeight() - d_ptr->m_optionActionButton->height()) / 2); + + (titleHeight() - d_ptr->m_optionActionButton->height()) / 2); } else { d_ptr->m_optionActionButton->move(width() - d_ptr->m_optionActionButton->width(), height() - d_ptr->m_optionActionButton->height()); diff --git a/src/SARibbonBar/SARibbonPannel.h b/src/SARibbonBar/SARibbonPannel.h index f2d9f717..f5fc2d26 100644 --- a/src/SARibbonBar/SARibbonPannel.h +++ b/src/SARibbonBar/SARibbonPannel.h @@ -58,16 +58,16 @@ class SA_RIBBON_EXPORT SARibbonPannel : public QWidget void setActionRowProportion(QAction* action, SARibbonPannelItem::RowProportion rp); // 把action加入到pannel - SARibbonToolButton* addAction(QAction* action, SARibbonPannelItem::RowProportion rp); + void addAction(QAction* action, SARibbonPannelItem::RowProportion rp); // 把action加入到pannel,并以大图标显示 - SARibbonToolButton* addLargeAction(QAction* action); + void addLargeAction(QAction* action); // 把action加入到pannel,在三行模式下会以中图标显示 - SARibbonToolButton* addMediumAction(QAction* action); + void addMediumAction(QAction* action); // 把action加入到pannel,并以小图标显示 - SARibbonToolButton* addSmallAction(QAction* action); + void addSmallAction(QAction* action); // 生成并添加一个action void addAction(QAction* act, QToolButton::ToolButtonPopupMode popMode, SARibbonPannelItem::RowProportion rp = SARibbonPannelItem::Large); @@ -107,7 +107,7 @@ class SA_RIBBON_EXPORT SARibbonPannel : public QWidget QAction* addLargeWidget(QWidget* w); // 添加一个Gallery - SARibbonGallery* addGallery(); + SARibbonGallery* addGallery(bool expanding = true); // 添加分割线 QAction* addSeparator(int top = 6, int bottom = 6); @@ -173,9 +173,9 @@ class SA_RIBBON_EXPORT SARibbonPannel : public QWidget SARibbonPannelLayout* pannelLayout() const; // 更新布局 void updateItemGeometry(); - //获取category指针,如果没有parent,或者不在category管理,返回nullptr + // 获取category指针,如果没有parent,或者不在category管理,返回nullptr SARibbonCategory* category() const; - //获取ribbonBar指针,如果没有返回nullptr + // 获取ribbonBar指针,如果没有返回nullptr SARibbonBar* ribbonBar() const; signals: diff --git a/src/SARibbonBar/SARibbonPannelItem.h b/src/SARibbonBar/SARibbonPannelItem.h index 578826c4..7717bbee 100644 --- a/src/SARibbonBar/SARibbonPannelItem.h +++ b/src/SARibbonBar/SARibbonPannelItem.h @@ -37,7 +37,22 @@ class SA_RIBBON_EXPORT SARibbonPannelItem : public QWidgetItem bool customWidget; ///< 对于没有窗口的action,实际也会有一个SARibbonToolButton,在销毁时要delete掉 SARibbonPannelItem::RowProportion rowProportion; ///< 行的占比,ribbon中有large,media和small三种占比,见@ref RowProportion }; -#ifndef SARibbonPannelItemRowProportionPropertyName -#define SARibbonPannelItemRowProportionPropertyName "SARibbonPannelItem_RowProportion" +#ifndef SA_ActionPropertyName_RowProportion +#define SA_ActionPropertyName_RowProportion "_sa_RowProportion" +#endif +#ifndef SA_ActionPropertyName_SeparatorTop +#define SA_ActionPropertyName_SeparatorTop "_sa_SeparatorTop" +#endif +#ifndef SA_ActionPropertyName_SeparatorBottom +#define SA_ActionPropertyName_SeparatorBottom "_sa_SeparatorBottom" +#endif +#ifndef SA_ActionPropertyName_ToolButtonPopupMode +#define SA_ActionPropertyName_ToolButtonPopupMode "_sa_ToolButtonPopupMode" +#endif +#ifndef SA_ActionPropertyName_IsActionMenu +#define SA_ActionPropertyName_IsActionMenu "_sa_IsActionMenu" +#endif +#ifndef SA_ActionPropertyName_MenuPointer +#define SA_ActionPropertyName_MenuPointer "_sa_MenuPointer" #endif #endif // SARIBBONPANNELITEM_H diff --git a/src/SARibbonBar/SARibbonPannelLayout.cpp b/src/SARibbonBar/SARibbonPannelLayout.cpp index 30d6f0e8..47d5d42f 100644 --- a/src/SARibbonBar/SARibbonPannelLayout.cpp +++ b/src/SARibbonBar/SARibbonPannelLayout.cpp @@ -33,7 +33,7 @@ SARibbonPannelLayout::SARibbonPannelLayout(QWidget* p) SARibbonPannelLayout::~SARibbonPannelLayout() { - //参考QToolBarLayout + // 参考QToolBarLayout while (!m_items.isEmpty()) { SARibbonPannelItem* item = m_items.takeFirst(); if (QWidgetAction* widgetAction = qobject_cast< QWidgetAction* >(item->action)) { @@ -329,6 +329,9 @@ SARibbonPannelItem* SARibbonPannelLayout::createItem(QAction* action, SARibbonPa } else if (action->isSeparator()) { SARibbonSeparatorWidget* sep = RibbonSubElementDelegate->createRibbonSeparatorWidget(pannel); widget = sep; + auto t = action->property(SA_ActionPropertyName_SeparatorTop).toInt(); + auto b = action->property(SA_ActionPropertyName_SeparatorBottom).toInt(); + sep->setTopBottomMargins(t, b); } // 不是widget,自动生成SARibbonToolbutton if (!widget) { @@ -339,6 +342,16 @@ SARibbonPannelItem* SARibbonPannelLayout::createItem(QAction* action, SARibbonPa button->setFocusPolicy(Qt::NoFocus); button->setButtonType(buttonType); button->setDefaultAction(action); + // 属性检查 + auto var = action->property(SA_ActionPropertyName_ToolButtonPopupMode); + if (var.isValid()) { + bool isok = false; + int iv = var.toInt(&isok); + if (isok) { + QToolButton::ToolButtonPopupMode pm = static_cast< QToolButton::ToolButtonPopupMode >(iv); + button->setPopupMode(pm); + } + } // 根据QAction的属性设置按钮的大小 QObject::connect(button, &SARibbonToolButton::triggered, pannel, &SARibbonPannel::actionTriggered); @@ -627,7 +640,7 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) << "\n mag=" << mag // << "\n largeHeight=" << largeHeight // << "\n smallHeight=" << smallHeight // - ; + ; ; #endif } From f48ea94fa2c8318906200a853a0a9bb1621c8e38 Mon Sep 17 00:00:00 2001 From: czyt1988 Date: Sat, 23 Dec 2023 16:43:09 +0800 Subject: [PATCH 12/16] =?UTF-8?q?=E5=AE=8C=E6=88=90SARibbonPannel=E7=B1=BB?= =?UTF-8?q?API=E7=9A=84=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SARibbonBar/SARibbonCategoryLayout.cpp | 11 +- src/SARibbonBar/SARibbonPannel.cpp | 151 +++++++++---------- src/SARibbonBar/SARibbonPannel.h | 46 +++--- src/SARibbonBar/SARibbonPannelItem.h | 7 +- src/SARibbonBar/SARibbonPannelLayout.cpp | 33 ++-- src/SARibbonBar/SARibbonPannelLayout.h | 3 + src/example/MainWindowExample/mainwindow.cpp | 22 +-- 7 files changed, 139 insertions(+), 134 deletions(-) diff --git a/src/SARibbonBar/SARibbonCategoryLayout.cpp b/src/SARibbonBar/SARibbonCategoryLayout.cpp index a94368e7..0f8f9f09 100644 --- a/src/SARibbonBar/SARibbonCategoryLayout.cpp +++ b/src/SARibbonBar/SARibbonCategoryLayout.cpp @@ -345,7 +345,7 @@ void SARibbonCategoryLayout::updateGeometryArr() qDebug() << "unknow widget in SARibbonCategoryLayout"; continue; } - p->layout()->update(); + // p->layout()->update(); QSize pannelSize = p->sizeHint(); QSize SeparatorSize(0, 0); if (item->separatorWidget) { @@ -650,9 +650,16 @@ void SARibbonCategoryLayout::onRightScrollButtonClicked() void SARibbonCategoryLayout::setGeometry(const QRect& rect) { + QRect old = geometry(); + if (old == rect) { + return; + } +#if SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "SARibbonCategoryLayout " << ribbonCategory()->categoryName() << " setGeometry=" << rect; +#endif + QLayout::setGeometry(rect); d_ptr->mDirty = false; updateGeometryArr(); - QLayout::setGeometry(rect); doLayout(); } //============================================================= diff --git a/src/SARibbonBar/SARibbonPannel.cpp b/src/SARibbonBar/SARibbonPannel.cpp index 0c6b6cb8..eb1a5d32 100644 --- a/src/SARibbonBar/SARibbonPannel.cpp +++ b/src/SARibbonBar/SARibbonPannel.cpp @@ -4,7 +4,6 @@ #include "SARibbonGallery.h" #include "SARibbonPannelLayout.h" #include "SARibbonPannelOptionButton.h" -#include "SARibbonSeparatorWidget.h" #include "SARibbonToolButton.h" #include #include @@ -117,9 +116,7 @@ SARibbonPannel::~SARibbonPannel() */ void SARibbonPannel::setActionRowProportionProperty(QAction* action, SARibbonPannelItem::RowProportion rp) { - if (action == nullptr) { - return; - } + Q_CHECK_PTR(action); action->setProperty(SA_ActionPropertyName_RowProportion, static_cast< int >(rp)); } @@ -140,25 +137,39 @@ SARibbonPannelItem::RowProportion SARibbonPannel::getActionRowProportionProperty } /** - * @brief 设置action的行行为,行属性决定了ribbon pannel的显示方式 - * @param action 需要设置的action,此action必须已经被pannel添加过 - * @param rp 行为 + * @brief 设置action的ToolButtonPopupMode属性 + * @param action + * @param popMode */ -void SARibbonPannel::setActionRowProportion(QAction* action, SARibbonPannelItem::RowProportion rp) +void SARibbonPannel::setActionToolButtonPopupModeProperty(QAction* action, QToolButton::ToolButtonPopupMode popMode) { - if (action == nullptr) { - return; - } - setActionRowProportionProperty(action, rp); + Q_CHECK_PTR(action); + action->setProperty(SA_ActionPropertyName_ToolButtonPopupMode, static_cast< int >(popMode)); } /** - @brief 添加action + * @brief 获取action的ToolButtonPopupMode属性 + * @param action + * @return + */ +QToolButton::ToolButtonPopupMode SARibbonPannel::getActionToolButtonPopupModeProperty(QAction* action) +{ + bool isok = false; + int r = action->property(SA_ActionPropertyName_ToolButtonPopupMode).toInt(&isok); - action实际对应了一个toolbutton,如果想找到对应的toolbutton,使用@ref actionToRibbonToolButton - @param action action - @param rp 指定action的行占比 - @sa actionToRibbonToolButton + if (isok) { + return (static_cast< QToolButton::ToolButtonPopupMode >(r)); + } + return (QToolButton::InstantPopup); +} + +/** + * @brief 添加action + * + * action实际对应了一个toolbutton,如果想找到对应的toolbutton,使用@ref actionToRibbonToolButton + * @param action + * @param rp 指定action的行占比 + * @param popMode 菜单弹出样式 */ void SARibbonPannel::addAction(QAction* action, SARibbonPannelItem::RowProportion rp) { @@ -167,6 +178,20 @@ void SARibbonPannel::addAction(QAction* action, SARibbonPannelItem::RowProportio addAction(action); } +/** + * @brief 添加一个action + * @param act + * @param popMode 按钮的样式 + * @param rp action在pannel中的占位情况,默认是大图标 + */ +void SARibbonPannel::addAction(QAction* act, QToolButton::ToolButtonPopupMode popMode, SARibbonPannelItem::RowProportion rp) +{ + Q_CHECK_PTR(act); + setActionRowProportionProperty(act, rp); + setActionToolButtonPopupModeProperty(act, popMode); + addAction(act); +} + /** @brief 添加大图标 @@ -202,18 +227,19 @@ void SARibbonPannel::addSmallAction(QAction* action) addAction(action, SARibbonPannelItem::Small); } -/** - * @brief 添加一个action - * @param act - * @param popMode 按钮的样式 - * @param rp action在pannel中的占位情况,默认是大图标 - */ -void SARibbonPannel::addAction(QAction* act, QToolButton::ToolButtonPopupMode popMode, SARibbonPannelItem::RowProportion rp) +void SARibbonPannel::addSmallAction(QAction* action, QToolButton::ToolButtonPopupMode popMode) { - Q_CHECK_PTR(act); - setActionRowProportionProperty(act, rp); - act->setProperty(SA_ActionPropertyName_ToolButtonPopupMode, static_cast< int >(popMode)); - addAction(act); + addAction(action, popMode, SARibbonPannelItem::Small); +} + +void SARibbonPannel::addLargeAction(QAction* action, QToolButton::ToolButtonPopupMode popMode) +{ + addAction(action, popMode, SARibbonPannelItem::Large); +} + +void SARibbonPannel::addMediumAction(QAction* action, QToolButton::ToolButtonPopupMode popMode) +{ + addAction(action, popMode, SARibbonPannelItem::Medium); } /** @@ -244,60 +270,21 @@ QAction* SARibbonPannel::addAction(const QString& text, const QIcon& icon, QTool * @param popMode,菜单弹出模式,默认InstantPopup模式 * @return */ -SARibbonToolButton* SARibbonPannel::addMenu(QMenu* menu, SARibbonPannelItem::RowProportion rp, QToolButton::ToolButtonPopupMode popMode) +void SARibbonPannel::addMenu(QMenu* menu, SARibbonPannelItem::RowProportion rp, QToolButton::ToolButtonPopupMode popMode) { Q_CHECK_PTR(menu); QAction* action = menu->menuAction(); - - addAction(action, rp); - if (SARibbonToolButton* btn = d_ptr->lastAddActionButton()) { - btn->setPopupMode(popMode); - return (btn); - } - return nullptr; -} - -/** - * @brief 添加一个ActionMenu - * @param action - * @param menu - * @param rp - * @return - */ -SARibbonToolButton* SARibbonPannel::addActionMenu(QAction* action, QMenu* menu, SARibbonPannelItem::RowProportion rp) -{ - Q_CHECK_PTR(action); - Q_CHECK_PTR(menu); - action->setProperty(SA_ActionPropertyName_IsActionMenu, true); - action->setProperty(SA_ActionPropertyName_MenuPointer, QVariant::fromValue(void*(menu))); - SARibbonToolButton* btn = addAction(action, rp); - if (nullptr == btn) { - return nullptr; - } - btn->setMenu(menu); - btn->setPopupMode(QToolButton::MenuButtonPopup); - return (btn); -} - -/** - * @brief 添加action menu,action menu是一个特殊的menu,即可点击触发action,也可弹出菜单 - * @param action 点击触发的action,在pannel中,图标以此action的图标为准 - * @param menu 需要弹出的menu - * @return 返回 - */ -SARibbonToolButton* SARibbonPannel::addLargeActionMenu(QAction* action, QMenu* menu) -{ - return (addActionMenu(action, menu, SARibbonPannelItem::Large)); + addAction(action, popMode, rp); } -SARibbonToolButton* SARibbonPannel::addLargeMenu(QMenu* menu, QToolButton::ToolButtonPopupMode popMode) +void SARibbonPannel::addLargeMenu(QMenu* menu, QToolButton::ToolButtonPopupMode popMode) { - return (addMenu(menu, SARibbonPannelItem::Large, popMode)); + addMenu(menu, SARibbonPannelItem::Large, popMode); } -SARibbonToolButton* SARibbonPannel::addSmallMenu(QMenu* menu, QToolButton::ToolButtonPopupMode popMode) +void SARibbonPannel::addSmallMenu(QMenu* menu, QToolButton::ToolButtonPopupMode popMode) { - return (addMenu(menu, SARibbonPannelItem::Small, popMode)); + addMenu(menu, SARibbonPannelItem::Small, popMode); } /** @@ -389,6 +376,7 @@ QAction* SARibbonPannel::addSeparator(int top, int bottom) */ SARibbonToolButton* SARibbonPannel::actionToRibbonToolButton(QAction* action) { +#if 0 SARibbonPannelLayout* lay = qobject_cast< SARibbonPannelLayout* >(layout()); if (lay) { @@ -401,6 +389,18 @@ SARibbonToolButton* SARibbonPannel::actionToRibbonToolButton(QAction* action) return (btn); } return (nullptr); +#else + for (auto obj : qAsConst(children())) { + if (obj->isWidgetType()) { + if (SARibbonToolButton* btn = qobject_cast< SARibbonToolButton* >(obj)) { + if (btn->defaultAction() == action) { + return btn; + } + } + } + } + return (nullptr); +#endif } /** @@ -724,7 +724,6 @@ void SARibbonPannel::resetLargeToolButtonStyle() continue; } b->updateRect(); - b->repaint(); } } @@ -750,7 +749,7 @@ void SARibbonPannel::resizeEvent(QResizeEvent* e) if (ThreeRowMode == pannelLayoutMode()) { d_ptr->m_optionActionButton->move(width() - d_ptr->m_optionActionButton->width() - 2, height() - titleHeight() - + (titleHeight() - d_ptr->m_optionActionButton->height()) / 2); + + (titleHeight() - d_ptr->m_optionActionButton->height()) / 2); } else { d_ptr->m_optionActionButton->move(width() - d_ptr->m_optionActionButton->width(), height() - d_ptr->m_optionActionButton->height()); @@ -793,7 +792,7 @@ void SARibbonPannel::actionEvent(QActionEvent* e) int index = layout()->count(); if (e->before()) { // 说明是插入 - index = lay->indexOf(action); + index = lay->indexOf(e->before()); if (-1 == index) { index = layout()->count(); // 找不到的时候就插入到最后 } diff --git a/src/SARibbonBar/SARibbonPannel.h b/src/SARibbonBar/SARibbonPannel.h index f5fc2d26..06de8f80 100644 --- a/src/SARibbonBar/SARibbonPannel.h +++ b/src/SARibbonBar/SARibbonPannel.h @@ -48,29 +48,23 @@ class SA_RIBBON_EXPORT SARibbonPannel : public QWidget TwoRowMode ///< 两行布局模式,wps的后续布局模式就是两行布局模式,pannel能布置2行小toolbutton }; - // 把action的行属性设置进action中,action自身携带了行属性 - static void setActionRowProportionProperty(QAction* action, SARibbonPannelItem::RowProportion rp); - - // 获取action的行属性 - static SARibbonPannelItem::RowProportion getActionRowProportionProperty(QAction* action); - - // 设置action的行行为,行属性决定了ribbon pannel的显示方式 - void setActionRowProportion(QAction* action, SARibbonPannelItem::RowProportion rp); - // 把action加入到pannel void addAction(QAction* action, SARibbonPannelItem::RowProportion rp); - + // 生成并添加一个action + void addAction(QAction* act, QToolButton::ToolButtonPopupMode popMode, SARibbonPannelItem::RowProportion rp = SARibbonPannelItem::Large); // 把action加入到pannel,并以大图标显示 void addLargeAction(QAction* action); - // 把action加入到pannel,在三行模式下会以中图标显示 void addMediumAction(QAction* action); - // 把action加入到pannel,并以小图标显示 void addSmallAction(QAction* action); - // 生成并添加一个action - void addAction(QAction* act, QToolButton::ToolButtonPopupMode popMode, SARibbonPannelItem::RowProportion rp = SARibbonPannelItem::Large); + // 把action加入到pannel,并以小图标显示 + void addSmallAction(QAction* action, QToolButton::ToolButtonPopupMode popMode); + // 把action加入到pannel,并以大图标显示 + void addLargeAction(QAction* action, QToolButton::ToolButtonPopupMode popMode); + // 把action加入到pannel,在三行模式下会以中图标显示 + void addMediumAction(QAction* action, QToolButton::ToolButtonPopupMode popMode); QAction* addAction(const QString& text, const QIcon& icon, @@ -78,21 +72,13 @@ class SA_RIBBON_EXPORT SARibbonPannel : public QWidget SARibbonPannelItem::RowProportion rp = SARibbonPannelItem::Large); // 添加menu - SARibbonToolButton* addMenu(QMenu* menu, - SARibbonPannelItem::RowProportion rp, - QToolButton::ToolButtonPopupMode popMode = QToolButton::InstantPopup); - - // 添加action menu - SARibbonToolButton* addActionMenu(QAction* action, QMenu* menu, SARibbonPannelItem::RowProportion rp); - - // action menu,action menu是一个特殊的menu,即可点击触发action,也可弹出菜单 - SARibbonToolButton* addLargeActionMenu(QAction* action, QMenu* menu); + void addMenu(QMenu* menu, SARibbonPannelItem::RowProportion rp, QToolButton::ToolButtonPopupMode popMode = QToolButton::InstantPopup); // 添加普通大菜单 - SARibbonToolButton* addLargeMenu(QMenu* menu, QToolButton::ToolButtonPopupMode popMode = QToolButton::InstantPopup); + void addLargeMenu(QMenu* menu, QToolButton::ToolButtonPopupMode popMode = QToolButton::InstantPopup); // 添加普通小按钮菜单 - SARibbonToolButton* addSmallMenu(QMenu* menu, QToolButton::ToolButtonPopupMode popMode = QToolButton::InstantPopup); + void addSmallMenu(QMenu* menu, QToolButton::ToolButtonPopupMode popMode = QToolButton::InstantPopup); // 添加窗口 QAction* addWidget(QWidget* w, SARibbonPannelItem::RowProportion rp); @@ -185,6 +171,16 @@ class SA_RIBBON_EXPORT SARibbonPannel : public QWidget */ void actionTriggered(QAction* action); +public: + // 把action的行属性设置进action中,action自身携带了行属性 + static void setActionRowProportionProperty(QAction* action, SARibbonPannelItem::RowProportion rp); + // 获取action的行属性 + static SARibbonPannelItem::RowProportion getActionRowProportionProperty(QAction* action); + // 把action的行属性设置进action中,action自身携带了行属性 + static void setActionToolButtonPopupModeProperty(QAction* action, QToolButton::ToolButtonPopupMode popMode); + // 获取action的行属性 + static QToolButton::ToolButtonPopupMode getActionToolButtonPopupModeProperty(QAction* action); + protected: // 设置PannelLayoutMode,此函数设置为protect避免误调用 void setPannelLayoutMode(PannelLayoutMode mode); diff --git a/src/SARibbonBar/SARibbonPannelItem.h b/src/SARibbonBar/SARibbonPannelItem.h index 7717bbee..99af5115 100644 --- a/src/SARibbonBar/SARibbonPannelItem.h +++ b/src/SARibbonBar/SARibbonPannelItem.h @@ -3,7 +3,6 @@ #include "SARibbonGlobal.h" #include #include -#include class SARibbonToolButton; /** * @brief 是对pannel所有子窗口的抽象,参考qt的toolbar @@ -40,15 +39,15 @@ class SA_RIBBON_EXPORT SARibbonPannelItem : public QWidgetItem #ifndef SA_ActionPropertyName_RowProportion #define SA_ActionPropertyName_RowProportion "_sa_RowProportion" #endif +#ifndef SA_ActionPropertyName_ToolButtonPopupMode +#define SA_ActionPropertyName_ToolButtonPopupMode "_sa_ToolButtonPopupMode" +#endif #ifndef SA_ActionPropertyName_SeparatorTop #define SA_ActionPropertyName_SeparatorTop "_sa_SeparatorTop" #endif #ifndef SA_ActionPropertyName_SeparatorBottom #define SA_ActionPropertyName_SeparatorBottom "_sa_SeparatorBottom" #endif -#ifndef SA_ActionPropertyName_ToolButtonPopupMode -#define SA_ActionPropertyName_ToolButtonPopupMode "_sa_ToolButtonPopupMode" -#endif #ifndef SA_ActionPropertyName_IsActionMenu #define SA_ActionPropertyName_IsActionMenu "_sa_IsActionMenu" #endif diff --git a/src/SARibbonBar/SARibbonPannelLayout.cpp b/src/SARibbonBar/SARibbonPannelLayout.cpp index 47d5d42f..2a42e4a0 100644 --- a/src/SARibbonBar/SARibbonPannelLayout.cpp +++ b/src/SARibbonBar/SARibbonPannelLayout.cpp @@ -60,6 +60,15 @@ int SARibbonPannelLayout::indexOf(QAction* action) const return (-1); } +/** + * @brief 获取ribbonpannel + * @return + */ +SARibbonPannel* SARibbonPannelLayout::ribbonPannel() const +{ + return qobject_cast< SARibbonPannel* >(parentWidget()); +} + void SARibbonPannelLayout::addItem(QLayoutItem* item) { Q_UNUSED(item); @@ -342,16 +351,9 @@ SARibbonPannelItem* SARibbonPannelLayout::createItem(QAction* action, SARibbonPa button->setFocusPolicy(Qt::NoFocus); button->setButtonType(buttonType); button->setDefaultAction(action); - // 属性检查 - auto var = action->property(SA_ActionPropertyName_ToolButtonPopupMode); - if (var.isValid()) { - bool isok = false; - int iv = var.toInt(&isok); - if (isok) { - QToolButton::ToolButtonPopupMode pm = static_cast< QToolButton::ToolButtonPopupMode >(iv); - button->setPopupMode(pm); - } - } + // 属性设置 + QToolButton::ToolButtonPopupMode popMode = SARibbonPannel::getActionToolButtonPopupModeProperty(action); + button->setPopupMode(popMode); // 根据QAction的属性设置按钮的大小 QObject::connect(button, &SARibbonToolButton::triggered, pannel, &SARibbonPannel::actionTriggered); @@ -640,7 +642,7 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) << "\n mag=" << mag // << "\n largeHeight=" << largeHeight // << "\n smallHeight=" << smallHeight // - ; + ; ; #endif } @@ -775,8 +777,15 @@ void SARibbonPannelLayout::columnWidthInfo(int colindex, int& width, int& maximu void SARibbonPannelLayout::setGeometry(const QRect& rect) { + QRect old = geometry(); + if (old == rect) { + return; + } +#if SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "SARibbonPannelLayout " << ribbonPannel()->pannelName() << " setGeometry=" << rect; +#endif + QLayout::setGeometry(rect); m_dirty = false; updateGeomArray(rect); - QLayout::setGeometry(rect); layoutActions(); } diff --git a/src/SARibbonBar/SARibbonPannelLayout.h b/src/SARibbonBar/SARibbonPannelLayout.h index 4b36f0b4..b9348eed 100644 --- a/src/SARibbonBar/SARibbonPannelLayout.h +++ b/src/SARibbonBar/SARibbonPannelLayout.h @@ -24,6 +24,9 @@ class SA_RIBBON_EXPORT SARibbonPannelLayout : public QLayout ~SARibbonPannelLayout(); virtual int indexOf(QAction* action) const; + //获取ribbonpannel + SARibbonPannel* ribbonPannel() const; + // SARibbonPannelLayout additem 无效 void addItem(QLayoutItem* item) Q_DECL_OVERRIDE; diff --git a/src/example/MainWindowExample/mainwindow.cpp b/src/example/MainWindowExample/mainwindow.cpp index 43ebb17a..691087b8 100644 --- a/src/example/MainWindowExample/mainwindow.cpp +++ b/src/example/MainWindowExample/mainwindow.cpp @@ -599,7 +599,6 @@ void MainWindow::createCategoryMain(SARibbonCategory* page) SARibbonPannel* pannelToolButtonStyle = page->addPannel(("sa ribbon toolbutton style")); - SARibbonToolButton* btn; SARibbonMenu* menu = new SARibbonMenu(this); QAction* a = nullptr; { @@ -613,48 +612,41 @@ void MainWindow::createCategoryMain(SARibbonCategory* page) QAction* act = createAction(tr("test 1"), ":/icon/icon/test1.svg"); act->setMenu(menu); act->setToolTip(tr("use QToolButton::MenuButtonPopup mode")); - btn = pannelToolButtonStyle->addSmallAction(act); - btn->setPopupMode(QToolButton::MenuButtonPopup); + pannelToolButtonStyle->addSmallAction(act, QToolButton::MenuButtonPopup); act = createAction(tr("test 2"), ":/icon/icon/test2.svg"); act->setMenu(menu); act->setToolTip(tr("use QToolButton::InstantPopup mode")); - btn = pannelToolButtonStyle->addSmallAction(act); - btn->setPopupMode(QToolButton::InstantPopup); + pannelToolButtonStyle->addSmallAction(act, QToolButton::InstantPopup); pannelToolButtonStyle->addSeparator(); act = createAction(tr("Delayed\nPopup"), ":/icon/icon/folder-cog.svg"); act->setMenu(menu); - btn = pannelToolButtonStyle->addLargeAction(act); - btn->setPopupMode(QToolButton::DelayedPopup); + pannelToolButtonStyle->addLargeAction(act, QToolButton::DelayedPopup); connect(act, &QAction::triggered, this, &MainWindow::onDelayedPopupCheckabletriggered); act = createAction(tr("Menu Button Popup"), ":/icon/icon/folder-star.svg"); act->setMenu(menu); - btn = pannelToolButtonStyle->addLargeAction(act); - btn->setPopupMode(QToolButton::MenuButtonPopup); + pannelToolButtonStyle->addLargeAction(act, QToolButton::MenuButtonPopup); connect(act, &QAction::triggered, this, &MainWindow::onMenuButtonPopupCheckabletriggered); act = createAction(tr("Instant Popup"), ":/icon/icon/folder-stats.svg"); act->setMenu(menu); - btn = pannelToolButtonStyle->addLargeAction(act); - btn->setPopupMode(QToolButton::InstantPopup); + pannelToolButtonStyle->addLargeAction(act, QToolButton::InstantPopup); connect(act, &QAction::triggered, this, &MainWindow::onInstantPopupCheckabletriggered); act = createAction(tr("Delayed Popup checkable"), ":/icon/icon/folder-table.svg"); act->setCheckable(true); act->setMenu(menu); - btn = pannelToolButtonStyle->addLargeAction(act); - btn->setPopupMode(QToolButton::DelayedPopup); + pannelToolButtonStyle->addLargeAction(act, QToolButton::DelayedPopup); connect(act, &QAction::triggered, this, &MainWindow::onDelayedPopupCheckableTest); act = createAction(tr("Menu Button Popup checkable"), ":/icon/icon/folder-checkmark.svg"); act->setCheckable(true); act->setMenu(menu); - btn = pannelToolButtonStyle->addLargeAction(act); - btn->setPopupMode(QToolButton::MenuButtonPopup); + pannelToolButtonStyle->addLargeAction(act, QToolButton::MenuButtonPopup); connect(act, &QAction::triggered, this, &MainWindow::onMenuButtonPopupCheckableTest); act = createAction(tr("disable action"), ":/icon/icon/disable.svg"); From aa16e1267487d78d01f42ee7fba899ade4fab1a0 Mon Sep 17 00:00:00 2001 From: czyt1988 Date: Sun, 24 Dec 2023 16:00:53 +0800 Subject: [PATCH 13/16] =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=B8=83=E5=B1=80?= =?UTF-8?q?=E5=A4=84=E7=90=86=EF=BC=8C=E5=AE=8C=E5=96=84=E8=B0=83=E8=AF=95?= =?UTF-8?q?=E6=89=93=E5=8D=B0=E6=8E=A7=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SARibbonBar/SARibbonCategory.cpp | 9 +- src/SARibbonBar/SARibbonCategoryLayout.cpp | 120 +++++++++++++-------- src/SARibbonBar/SARibbonGlobal.h | 9 +- src/SARibbonBar/SARibbonPannel.cpp | 35 +++--- src/SARibbonBar/SARibbonPannelItem.cpp | 2 +- src/SARibbonBar/SARibbonPannelLayout.cpp | 84 +++++++-------- src/example/MainWindowExample/main.cpp | 14 +-- 7 files changed, 160 insertions(+), 113 deletions(-) diff --git a/src/SARibbonBar/SARibbonCategory.cpp b/src/SARibbonBar/SARibbonCategory.cpp index 632761df..f38cf915 100644 --- a/src/SARibbonBar/SARibbonCategory.cpp +++ b/src/SARibbonBar/SARibbonCategory.cpp @@ -276,6 +276,11 @@ void SARibbonCategory::setRibbonPannelLayoutMode(SARibbonPannel::PannelLayoutMod bool SARibbonCategory::event(QEvent* e) { +#if SA_DEBUG_PRINT_EVENT + if (e->type() != QEvent::Paint) { + qDebug() << "SARibbonCategory event(" << e->type() << "),name=" << categoryName(); + } +#endif return QWidget::event(e); } @@ -468,10 +473,10 @@ QList< SARibbonPannel* > SARibbonCategory::pannelList() const QSize SARibbonCategory::sizeHint() const { - if (QLayout* lay = layout()) { + if (SARibbonCategoryLayout* lay = categoryLayout()) { return lay->sizeHint(); } - return QSize(500, 200); + return QSize(1000, 100); } /** diff --git a/src/SARibbonBar/SARibbonCategoryLayout.cpp b/src/SARibbonBar/SARibbonCategoryLayout.cpp index 0f8f9f09..da70419b 100644 --- a/src/SARibbonBar/SARibbonCategoryLayout.cpp +++ b/src/SARibbonBar/SARibbonCategoryLayout.cpp @@ -1,7 +1,6 @@ #include "SARibbonCategoryLayout.h" #include #include "SARibbonPannel.h" -#include "SARibbonToolButton.h" #include "SARibbonElementManager.h" #include "SARibbonSeparatorWidget.h" #include @@ -29,7 +28,8 @@ class SARibbonCategoryLayout::PrivateData SARibbonCategoryScrollButton* mRightScrollBtn { nullptr }; ///< 在区域无法显示时显示的按钮 int mTotalWidth { 0 }; int mXBase { 0 }; - QSize mSizeHint { 50, 50 }; + QSize mSizeHint; + QSize mMinSizeHint; QList< SARibbonCategoryLayoutItem* > mItemList; SARibbonAlignment mCategoryAlignment { SARibbonAlignment::AlignLeft }; ///< 对齐方式 }; @@ -50,16 +50,27 @@ int SARibbonCategoryLayout::PrivateData::totalSizeHintWidth() const { int total = 0; QMargins mag = q_ptr->contentsMargins(); - +#if SA_DEBUG_PRINT_SIZE_HINT + int debug_i__ = 0; + QString debug_totalSizeHintWidth__; +#endif if (!mag.isNull()) { total += (mag.left() + mag.right()); } //先计算总长 for (SARibbonCategoryLayoutItem* item : qAsConst(mItemList)) { if (item->isEmpty()) { - //如果是hide就直接跳过 +//如果是hide就直接跳过 +#if SA_DEBUG_PRINT_SIZE_HINT + ++debug_i__; + debug_totalSizeHintWidth__ += QString(" [%1](%2)is empty skip\n") + .arg(debug_i__) + .arg(item->toPannelWidget()->pannelName()); +#endif continue; } + //这里要使用widget()->sizeHint(),因为pannel的标题会影总体布局,此处需要修改 + // TODO QSize pannelSize = item->widget()->sizeHint(); QSize SeparatorSize(0, 0); if (item->separatorWidget) { @@ -67,7 +78,21 @@ int SARibbonCategoryLayout::PrivateData::totalSizeHintWidth() const } total += pannelSize.width(); total += SeparatorSize.width(); +#if SA_DEBUG_PRINT_SIZE_HINT + ++debug_i__; + debug_totalSizeHintWidth__ += QString("|-[%1]pannelSize=(%2,%3),SeparatorSize=(%4,%5),name=(%6) \n") + .arg(debug_i__) + .arg(pannelSize.width()) + .arg(pannelSize.height()) + .arg(SeparatorSize.width()) + .arg(SeparatorSize.height()) + .arg(item->toPannelWidget()->pannelName()); +#endif } +#if SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "SARibbonCategoryLayout.totalSizeHintWidth=" << total; + qDebug().noquote() << debug_totalSizeHintWidth__; +#endif return (total); } @@ -89,7 +114,7 @@ SARibbonCategoryLayout::SARibbonCategoryLayout(SARibbonCategory* parent) SARibbonCategoryLayout::~SARibbonCategoryLayout() { - while (QLayoutItem* item = takeAt(0)) { + while (auto item = takePannelItem(0)) { delete item; } } @@ -126,13 +151,14 @@ QLayoutItem* SARibbonCategoryLayout::itemAt(int index) const */ QLayoutItem* SARibbonCategoryLayout::takeAt(int index) { - return (takePannelItem(index)); + QLayoutItem* r = takePannelItem(index); + invalidate(); + return r; } SARibbonCategoryLayoutItem* SARibbonCategoryLayout::takePannelItem(int index) { if ((index >= 0) && (index < d_ptr->mItemList.size())) { - invalidate(); SARibbonCategoryLayoutItem* item = d_ptr->mItemList.takeAt(index); if (item->widget()) { item->widget()->hide(); @@ -170,6 +196,7 @@ bool SARibbonCategoryLayout::takePannel(SARibbonPannel* pannel) sp->deleteLater(); } delete i; + invalidate(); return true; } return false; @@ -208,12 +235,20 @@ void SARibbonCategoryLayout::insertPannel(int index, SARibbonPannel* pannel) QSize SARibbonCategoryLayout::sizeHint() const { + if (d_ptr->mSizeHint.isNull()) { + SARibbonCategoryLayout* that = const_cast< SARibbonCategoryLayout* >(this); + that->updateGeometryArr(); + } return (d_ptr->mSizeHint); } QSize SARibbonCategoryLayout::minimumSize() const { - return (d_ptr->mSizeHint); + if (d_ptr->mMinSizeHint.isNull()) { + SARibbonCategoryLayout* that = const_cast< SARibbonCategoryLayout* >(this); + that->updateGeometryArr(); + } + return (d_ptr->mMinSizeHint); } /** @@ -251,7 +286,7 @@ QSize SARibbonCategoryLayout::categoryContentSize() const */ void SARibbonCategoryLayout::updateGeometryArr() { - SARibbonCategory* category = qobject_cast< SARibbonCategory* >(parentWidget()); + SARibbonCategory* category = ribbonCategory(); if (nullptr == category) { return; } @@ -273,11 +308,14 @@ void SARibbonCategoryLayout::updateGeometryArr() //如果total < categoryWidth,m_d->mXBase可以设置为0 //判断是否超过总长度 -#if SARibbonCategoryLayout_DEBUG_PRINT - qDebug() << "\r\n\r\n==========================(" << category->categoryName() << ")=======" - << "\r\nSARibbonCategoryLayout::updateGeometryArr" - << "\r\npannel name:" << category->windowTitle() << "\r\n height:" << height - << "\r\n first total:" << total << "\r\n y:" << y << "\r\n expandWidth:" << expandWidth; +#if SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "SARibbonCategoryLayout::updateGeometryArr" + << "\n|-category name=" << category->categoryName() // + << "\n|-category height=" << height // + << "\n|-totalSizeHintWidth=" << total // + << "\n|-y=" << y // + << "\n|-expandWidth:" << expandWidth // + << "\n|-mag=" << mag; #endif if (total > categoryWidth) { //超过总长度,需要显示滚动按钮 @@ -364,23 +402,12 @@ void SARibbonCategoryLayout::updateGeometryArr() x += w; total += w; } - d_ptr->mTotalWidth = total; - QWidget* cp = category->parentWidget(); - int parentHeight = (nullptr == cp) ? height : cp->height(); - int parentWidth = (nullptr == cp) ? total : cp->width(); -#if SARibbonCategoryLayout_DEBUG_PRINT - qDebug() << "\r\n mSizeHint:[ " << parentHeight << "," << parentWidth << "]"; - for (int i = 0; i < d_ptr->mItemList.size(); ++i) { - qDebug() << "\r\n [ " << i << "] (pannel name=" << d_ptr->mItemList[ i ]->toPannelWidget()->pannelName() - << "),sizeHint=" << d_ptr->mItemList[ i ]->toPannelWidget()->sizeHint() - << "\r\n geo:" << d_ptr->mItemList[ i ]->mWillSetGeometry - << ", Separator geo:" << d_ptr->mItemList[ i ]->mWillSetSeparatorGeometry; - } -#endif - d_ptr->mSizeHint = QSize(parentWidth, parentHeight); + d_ptr->mTotalWidth = total; + d_ptr->mSizeHint = QSize(d_ptr->mTotalWidth, height); + d_ptr->mMinSizeHint = QSize(categoryWidth, height); #if SA_DEBUG_PRINT_SIZE_HINT - qDebug() << "SARibbonCategory name=" << category->categoryName() - << " SARibbonCategoryLayout updateGeometryArr,SizeHint=" << d_ptr->mSizeHint; + qDebug() << "SARibbonCategoryLayout updateGeometryArr,SizeHint=" << d_ptr->mSizeHint + << ",Category name=" << category->categoryName(); #endif } @@ -392,18 +419,25 @@ void SARibbonCategoryLayout::doLayout() if (d_ptr->mDirty) { updateGeometryArr(); } - SARibbonCategory* category = qobject_cast< SARibbonCategory* >(parentWidget()); + SARibbonCategory* category = ribbonCategory(); //两个滚动按钮的位置永远不变 d_ptr->mLeftScrollBtn->setGeometry(0, 0, 12, category->height()); d_ptr->mRightScrollBtn->setGeometry(category->width() - 12, 0, 12, category->height()); QList< QWidget* > showWidgets, hideWidgets; - +#ifdef SA_DEBUG_PRINT_SIZE_HINT + int debug_i__(0); + qDebug() << "SARibbonCategoryLayout::doLayout(),name=" << category->categoryName(); +#endif for (SARibbonCategoryLayoutItem* item : qAsConst(d_ptr->mItemList)) { if (item->isEmpty()) { hideWidgets << item->widget(); if (item->separatorWidget) { hideWidgets << item->separatorWidget; } +#ifdef SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "|-[" << debug_i__ << "]pannelName(" << item->toPannelWidget()->pannelName() << ",will hide"; + ++debug_i__; +#endif } else { item->widget()->setFixedSize(item->mWillSetGeometry.size()); item->widget()->move(item->mWillSetGeometry.topLeft()); @@ -413,10 +447,11 @@ void SARibbonCategoryLayout::doLayout() item->separatorWidget->setGeometry(item->mWillSetSeparatorGeometry); showWidgets << item->separatorWidget; } -#ifdef SA_RIBBON_DEBUG_HELP_DRAW - qDebug() << "SARibbonCategoryLayout::doLayout() ="; - qDebug() << "\r\n pannel:" << item->widget()->windowTitle() << "\r\n pannel geo:" << item->mWillSetGeometry - << "\r\n sep geo:" << item->mWillSetSeparatorGeometry; +#ifdef SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "|-[" << debug_i__ << "]pannelName(" << item->toPannelWidget()->pannelName() + << "),willSetGeometry:" << item->mWillSetGeometry + << ",WillSetSeparatorGeometry:" << item->mWillSetSeparatorGeometry; + ++debug_i__; #endif } } @@ -431,14 +466,15 @@ void SARibbonCategoryLayout::doLayout() } // 不在上面那里进行show和hide因为这会触发SARibbonPannelLayout的重绘,导致循环绘制,非常影响效率 for (QWidget* w : qAsConst(showWidgets)) { - w->show(); + if (!w->isVisible()) { + w->show(); + } } for (QWidget* w : qAsConst(hideWidgets)) { - w->hide(); + if (w->isVisible()) { + w->hide(); + } } -#if SA_DEBUG_PRINT_SIZE_HINT - qDebug() << "SARibbonCategory name=" << category->categoryName() << " SARibbonCategoryLayout doLayout"; -#endif } /** @@ -655,7 +691,7 @@ void SARibbonCategoryLayout::setGeometry(const QRect& rect) return; } #if SA_DEBUG_PRINT_SIZE_HINT - qDebug() << "SARibbonCategoryLayout " << ribbonCategory()->categoryName() << " setGeometry=" << rect; + qDebug() << "===========SARibbonCategoryLayout.setGeometry(" << rect << "(" << ribbonCategory()->categoryName() << ")======="; #endif QLayout::setGeometry(rect); d_ptr->mDirty = false; diff --git a/src/SARibbonBar/SARibbonGlobal.h b/src/SARibbonBar/SARibbonGlobal.h index 46d2b84b..3137071b 100644 --- a/src/SARibbonBar/SARibbonGlobal.h +++ b/src/SARibbonBar/SARibbonGlobal.h @@ -141,7 +141,7 @@ #define SA_RIBBON_DECLARE_PUBLIC(classname) \ friend class classname; \ classname* q_ptr { nullptr }; \ - PrivateData(const PrivateData&) = delete; \ + PrivateData(const PrivateData&) = delete; \ PrivateData& operator=(const PrivateData&) = delete; #endif @@ -187,5 +187,12 @@ enum class SARibbonAlignment */ #define SA_DEBUG_PRINT_SIZE_HINT 1 #endif +#ifndef SA_DEBUG_PRINT_EVENT +/** + @def 定义此宏,将打印事件 + 仅用于调试 + */ +#define SA_DEBUG_PRINT_EVENT 0 +#endif #endif // SARIBBONGLOBAL_H diff --git a/src/SARibbonBar/SARibbonPannel.cpp b/src/SARibbonBar/SARibbonPannel.cpp index eb1a5d32..1af94d8a 100644 --- a/src/SARibbonBar/SARibbonPannel.cpp +++ b/src/SARibbonBar/SARibbonPannel.cpp @@ -507,20 +507,24 @@ void SARibbonPannel::paintEvent(QPaintEvent* e) QSize SARibbonPannel::sizeHint() const { - QSize laySize = layout()->sizeHint(); - int maxWidth = laySize.width() + 2; - - if (ThreeRowMode == pannelLayoutMode()) { - // 三行模式 - QFontMetrics fm = fontMetrics(); - QSize titleSize = fm.size(Qt::TextShowMnemonic, pannelName()); - if (d_ptr->m_optionActionButton) { - // optionActionButton的宽度需要预留 - titleSize.setWidth(titleSize.width() + d_ptr->m_optionActionButton->width() + 4); + int shWidth = 500; + int shHeight = 80; + if (QLayout* lay = layout()) { + QSize laySize = layout()->sizeHint(); + shWidth = laySize.width(); + shHeight = laySize.height(); + if (ThreeRowMode == pannelLayoutMode()) { + // 三行模式 + QFontMetrics fm = fontMetrics(); + QSize titleSize = fm.size(Qt::TextShowMnemonic, pannelName()); + if (d_ptr->m_optionActionButton) { + // optionActionButton的宽度需要预留 + titleSize.setWidth(titleSize.width() + d_ptr->m_optionActionButton->width() + 4); + } + shWidth = qMax(shWidth, titleSize.width()); } - maxWidth = qMax(maxWidth, titleSize.width()); } - return (QSize(maxWidth, laySize.height())); + return QSize(shWidth, shHeight); } QSize SARibbonPannel::minimumSizeHint() const @@ -729,6 +733,11 @@ void SARibbonPannel::resetLargeToolButtonStyle() bool SARibbonPannel::event(QEvent* e) { +#if SA_DEBUG_PRINT_EVENT + if (e->type() != QEvent::Paint) { + qDebug() << "SARibbonPannel event(" << e->type() << "),name=" << pannelName(); + } +#endif // if (SARibbonPannelLayout* lay = pannelLayout()) { // if (lay->isDirty() && e->type() == QEvent::LayoutRequest) { // if (QWidget* parw = parentWidget()) { @@ -809,6 +818,7 @@ void SARibbonPannel::actionEvent(QActionEvent* e) case QEvent::ActionChanged: { // 让布局重新绘制 layout()->invalidate(); + // updateGeometry(); // 由于pannel的尺寸发生变化,需要让category也调整 if (QWidget* parw = parentWidget()) { @@ -826,7 +836,6 @@ void SARibbonPannel::actionEvent(QActionEvent* e) // //! // //! 调用parw->updateGeometry();也没有效果,目前看使用resizeevent是最有效果的 // //! - // // parw->updateGeometry(); // QResizeEvent* ersize = new QResizeEvent(parw->size(), QSize()); // QApplication::postEvent(parw, ersize); } diff --git a/src/SARibbonBar/SARibbonPannelItem.cpp b/src/SARibbonBar/SARibbonPannelItem.cpp index 1699d5b7..02be2c1a 100644 --- a/src/SARibbonBar/SARibbonPannelItem.cpp +++ b/src/SARibbonBar/SARibbonPannelItem.cpp @@ -7,5 +7,5 @@ SARibbonPannelItem::SARibbonPannelItem(QWidget* widget) bool SARibbonPannelItem::isEmpty() const { - return (action == 0 || !action->isVisible()); + return (action == nullptr || !action->isVisible()); } diff --git a/src/SARibbonBar/SARibbonPannelLayout.cpp b/src/SARibbonBar/SARibbonPannelLayout.cpp index 2a42e4a0..29d03b84 100644 --- a/src/SARibbonBar/SARibbonPannelLayout.cpp +++ b/src/SARibbonBar/SARibbonPannelLayout.cpp @@ -267,16 +267,16 @@ void SARibbonPannelLayout::setPannelContentsMargins(const QMargins& m) */ void SARibbonPannelLayout::layoutActions() { +#if SA_DEBUG_PRINT_SIZE_HINT + if (SARibbonPannel* pannel = qobject_cast< SARibbonPannel* >(parentWidget())) { + qDebug() << "| |-SARibbonPannelLayout layoutActions,pannel name = " << pannel->pannelName(); + } +#endif if (m_dirty) { updateGeomArray(geometry()); } QList< QWidget* > showWidgets, hideWidgets; -#if SARibbonPannelLayout_DEBUG_PRINT - qDebug() << "\r\n\r\n ==============================================" - "\r\n SARibbonPannelLayout::layoutActions" - << " \r\n name:" << parentWidget()->windowTitle() << " sizehint:" << this->sizeHint(); -#endif for (SARibbonPannelItem* item : qAsConst(m_items)) { if (item->isEmpty()) { hideWidgets << item->widget(); @@ -285,25 +285,18 @@ void SARibbonPannelLayout::layoutActions() // item->widget()->setFixedSize(item->itemWillSetGeometry.size()); // item->widget()->move(item->itemWillSetGeometry.topLeft()); showWidgets << item->widget(); -#if SARibbonPannelLayout_DEBUG_PRINT - qDebug() << "[" << item->rowIndex << "," << item->columnIndex << "]" - << " -> " << item->itemWillSetGeometry << ":" << item->widget()->metaObject()->className(); -#endif } } // 不在上面那里进行show和hide因为这会触发SARibbonPannelLayout的重绘,导致循环绘制,非常影响效率 for (QWidget* w : qAsConst(showWidgets)) { - w->show(); + if (!w->isVisible()) + w->show(); } for (QWidget* w : qAsConst(hideWidgets)) { - w->hide(); + if (w->isVisible()) + w->hide(); } -#if SA_DEBUG_PRINT_SIZE_HINT - if (SARibbonPannel* pannel = qobject_cast< SARibbonPannel* >(parentWidget())) { - qDebug() << "SARibbonPannelLayout layoutActions,pannel name = " << pannel->pannelName(); - } -#endif } /** @@ -380,9 +373,6 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) return; } -#if SARibbonPannelLayout_DEBUG_PRINT - qDebug() << "SARibbonPannelLayout::updateGeomArray(" << setrect << "),pannel name = " << pannel->pannelName(); -#endif int height = setrect.height(); const QMargins& mag = pannelContentsMargins(); const int spacing = this->spacing(); @@ -415,13 +405,9 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) int itemCount = m_items.count(); -#if SARibbonPannelLayout_DEBUG_PRINT - qDebug() << "\r\n\r\n=============================================" - << "\r\nSARibbonPannelLayout::updateGeomArray()" - << " setrect:" << setrect << "\r\npannel name:" << pannel->windowTitle() - << "\r\n largeHeight:" << largeHeight << "\r\n smallHeight:" << smallHeight << "\r\n rowCount:" << rowCount; +#if SA_DEBUG_PRINT_SIZE_HINT + QString debug_print__log__; #endif - // 本列第一、二行占比 SARibbonPannelItem::RowProportion thisColumnRP0 = SARibbonPannelItem::None; SARibbonPannelItem* lastGeomItem = nullptr; // 记录最后一个设置位置的item @@ -437,8 +423,12 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) QSize hint = item->sizeHint(); #if SA_DEBUG_PRINT_SIZE_HINT if (SARibbonToolButton* tb = qobject_cast< SARibbonToolButton* >(item->widget())) { - qDebug() << "SARibbonPannelItem sizeHint=" << hint << " SARibbonToolButton::sizeHint=" << tb->sizeHint() - << " ,name=" << tb->text(); + auto ss__ = tb->sizeHint(); + debug_print__log__ += QString("| | |-[%1]SARibbonToolButton.sizeHint=(%2,%3),ButtonText=%4\n") + .arg(i) + .arg(ss__.width()) + .arg(ss__.height()) + .arg(tb->text()); } #endif Qt::Orientations exp = item->expandingDirections(); @@ -602,11 +592,6 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) break; } lastGeomItem = item; -#if SARibbonPannelLayout_DEBUG_PRINT - qDebug() << item->widget()->metaObject()->className() << " rp:" << rp << " row:" << item->rowIndex - << " col:" << item->columnIndex << " new row:" << row << " new column:" << column - << " itemWillSetGeometry:" << item->itemWillSetGeometry << " sizeHint:" << hint << " x:" << x; -#endif } // 最后一个元素,更新列数 // 2022-06-20 此句本来在循环里面,如果最后一个元素隐藏,会导致无法到达此判断导致异常 @@ -614,13 +599,13 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) if (lastGeomItem->columnIndex != column) { // 说明最后一个元素处于最后位置,触发了换列,此时真实列数需要减1,直接等于column索引 m_columnCount = column; - // 由于最后一个元素触发了换列,x值是新一列的位置,直接作为totalWidth - totalWidth = x + mag.right(); + // 由于最后一个元素触发了换列,x值是新一列的位置,直接作为totalWidth要减去已经加入的spacing + totalWidth = x - spacing + mag.right(); } else { // 说明最后一个元素处于非最后位置,没有触发下一个换列,此时真实列数等于column索引+1 m_columnCount = column + 1; // 由于最后一个元素未触发换列,需要计算totalWidth - totalWidth = x + columMaxWidth + spacing + mag.right(); + totalWidth = x + columMaxWidth + mag.right(); } } // 在有optionButton情况下,的2行模式,需要调整totalWidth @@ -629,21 +614,24 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) totalWidth += pannel->optionActionButtonSize().width(); } } + this->m_sizeHint = QSize(totalWidth, height); // 在设置完所有窗口后,再设置扩展属性的窗口 - if (totalWidth < setrect.width()) { + if (totalWidth < setrect.width() && (setrect.width() - totalWidth) > 10) { // 说明可以设置扩展属性的窗口 recalcExpandGeomArray(setrect); } - this->m_sizeHint = QSize(totalWidth, height); #if SA_DEBUG_PRINT_SIZE_HINT - qDebug() << "SARibbonPannelLayout updateGeomArray,pannel name = " << pannel->pannelName() - << "\n size hint =" << this->m_sizeHint // - << "\n spacing=" << spacing // - << "\n mag=" << mag // - << "\n largeHeight=" << largeHeight // - << "\n smallHeight=" << smallHeight // + qDebug() << "| |-SARibbonPannelLayout updateGeomArray(" << setrect << "),pannel name = " << pannel->pannelName() + << "\n| | |-size hint =" << this->m_sizeHint // + << "\n| | |-totalWidth=" << totalWidth // + << "\n| | |-last x=" << x // + << "\n| | |-columMaxWidth=" << columMaxWidth // + << "\n| | |-spacing=" << spacing // + << "\n| | |-mag=" << mag // + << "\n| | |-largeHeight=" << largeHeight // + << "\n| | |-smallHeight=" << smallHeight // ; - ; + qDebug().noquote() << debug_print__log__; #endif } @@ -729,6 +717,12 @@ void SARibbonPannelLayout::recalcExpandGeomArray(const QRect& setrect) } } } +#if SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "| |-SARibbonPannelLayout recalcExpandGeomArray(" << setrect + << ") pannelName=" << ribbonPannel()->pannelName() // + << ",expandwidth=" << expandwidth // + ; +#endif } /** @@ -782,7 +776,7 @@ void SARibbonPannelLayout::setGeometry(const QRect& rect) return; } #if SA_DEBUG_PRINT_SIZE_HINT - qDebug() << "SARibbonPannelLayout " << ribbonPannel()->pannelName() << " setGeometry=" << rect; + qDebug() << "| |----->SARibbonPannelLayout.setGeometry(" << rect << "(" << ribbonPannel()->pannelName() << ")======="; #endif QLayout::setGeometry(rect); m_dirty = false; diff --git a/src/example/MainWindowExample/main.cpp b/src/example/MainWindowExample/main.cpp index 1af1ec7b..e333935f 100644 --- a/src/example/MainWindowExample/main.cpp +++ b/src/example/MainWindowExample/main.cpp @@ -18,28 +18,24 @@ void log_out_put(QtMsgType type, const QMessageLogContext& context, const QStrin switch (type) { case QtDebugMsg: - fprintf(stdout, "[Debug] %s \n-------------->(%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); + fprintf(stdout, "%s |[Debug] (%s[%u],%s)\n", localMsg.constData(), context.function, context.line, context.file); break; - // case QtInfoMsg: - // fprintf(stdout, "[Info] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, - // context.function); break; - case QtWarningMsg: - fprintf(stdout, "[Warning] %s \n-------------->(%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); + fprintf(stdout, "%s |[Warning] (%s[%u],%s)\n", localMsg.constData(), context.function, context.line, context.file); break; case QtCriticalMsg: - fprintf(stdout, "[Critical] %s \n-------------->(%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); + fprintf(stdout, "%s |[Critical] (%s[%u],%s)\n", localMsg.constData(), context.function, context.line, context.file); break; case QtFatalMsg: - fprintf(stdout, "Fatal: %s \n-------------->(%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); + fprintf(stdout, "%s |[Fatal] (%s[%u],%s)\n", localMsg.constData(), context.function, context.line, context.file); abort(); break; default: - fprintf(stdout, "[Debug] %s \n-------------->(%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); + fprintf(stdout, "%s |[Debug](%s[%u],%s)\n", localMsg.constData(), context.function, context.line, context.file); break; } #ifndef QT_NO_DEBUG_OUTPUT From bc74348b73fa4e561d415d813dda48112c6c9777 Mon Sep 17 00:00:00 2001 From: czyt1988 Date: Mon, 25 Dec 2023 08:48:20 +0800 Subject: [PATCH 14/16] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E6=97=A0=E7=94=A8?= =?UTF-8?q?=E5=8F=98=E9=87=8F=EF=BC=8C=E7=BB=86=E5=BE=AE=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E5=B8=83=E5=B1=80=E6=96=B9=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SARibbonBar/SARibbonBar.cpp | 53 ++++++------- src/SARibbonBar/SARibbonBar.h | 19 +++-- src/SARibbonBar/SARibbonCategory.cpp | 30 +++---- src/SARibbonBar/SARibbonCategory.h | 47 ++++++----- src/SARibbonBar/SARibbonCategoryLayout.cpp | 92 +++++++++++----------- src/SARibbonBar/SARibbonGlobal.h | 10 ++- src/SARibbonBar/SARibbonPannel.cpp | 36 ++++----- src/SARibbonBar/SARibbonPannelItem.h | 6 -- src/SARibbonBar/SARibbonPannelLayout.cpp | 39 ++++----- src/SARibbonBar/SARibbonPannelLayout.h | 32 ++++---- src/SARibbonBar/SARibbonStackedWidget.cpp | 30 +++---- src/SARibbonBar/SARibbonStackedWidget.h | 8 +- src/SARibbonBar/SARibbonToolButton.cpp | 25 +++--- 13 files changed, 206 insertions(+), 221 deletions(-) diff --git a/src/SARibbonBar/SARibbonBar.cpp b/src/SARibbonBar/SARibbonBar.cpp index f726eec5..4610b825 100644 --- a/src/SARibbonBar/SARibbonBar.cpp +++ b/src/SARibbonBar/SARibbonBar.cpp @@ -67,7 +67,6 @@ class SARibbonBar::PrivateData SARibbonButtonGroupWidget* mRightButtonGroup; ///< 在tab bar右边的按钮群 SARibbonQuickAccessBar* mQuickAccessBar; ///< 快速响应栏 SARibbonBar::RibbonStyle mRibbonStyle; ///< ribbon的风格 - SARibbonBar::RibbonStyle mLastShowStyle; ///< ribbon的风格 SARibbonBar::RibbonMode mCurrentRibbonMode; ///< 记录当前模式 QSize mWindowButtonSize; ///< 由SARibbonMainWindow告诉的windowbutton的尺寸 QList< QColor > mContextCategoryColorList; ///< contextCategory的色系 @@ -91,7 +90,6 @@ class SARibbonBar::PrivateData , mMinimumCategoryButtonAction(nullptr) , mRightButtonGroup(nullptr) , mRibbonStyle(SARibbonBar::RibbonStyleLooseThreeRow) - , mLastShowStyle(SARibbonBar::RibbonStyleLooseThreeRow) , mCurrentRibbonMode(SARibbonBar::NormalRibbonMode) , mWindowButtonSize(0, 0) , mContextCategoryColorListIndex(-1) @@ -412,7 +410,7 @@ QList< QColor > SARibbonBar::getDefaultContextCategoryColorList() << QColor(14, 81, 167) // 蓝 << QColor(228, 0, 69) // 红 << QColor(67, 148, 0) // 绿 - ; + ; return res; } @@ -542,7 +540,6 @@ void SARibbonBar::insertCategoryPage(SARibbonCategory* category, int index) tabdata.index = i; d_ptr->mRibbonTabBar->setTabData(i, QVariant::fromValue(tabdata)); d_ptr->mStackedContainerWidget->insertWidget(index, category); - connect(category, &QWidget::windowTitleChanged, this, &SARibbonBar::onCategoryWindowTitleChanged); // 更新index信息 d_ptr->updateTabData(); @@ -970,11 +967,11 @@ void SARibbonBar::showMinimumModeButton(bool isShow) d_ptr->mMinimumCategoryButtonAction = new QAction(this); d_ptr->mMinimumCategoryButtonAction->setIcon( - style()->standardIcon(isMinimumMode() ? QStyle::SP_TitleBarUnshadeButton : QStyle::SP_TitleBarShadeButton, nullptr)); + style()->standardIcon(isMinimumMode() ? QStyle::SP_TitleBarUnshadeButton : QStyle::SP_TitleBarShadeButton, nullptr)); connect(d_ptr->mMinimumCategoryButtonAction, &QAction::triggered, this, [ this ]() { this->setMinimumMode(!isMinimumMode()); this->d_ptr->mMinimumCategoryButtonAction->setIcon( - style()->standardIcon(isMinimumMode() ? QStyle::SP_TitleBarUnshadeButton : QStyle::SP_TitleBarShadeButton, nullptr)); + style()->standardIcon(isMinimumMode() ? QStyle::SP_TitleBarUnshadeButton : QStyle::SP_TitleBarShadeButton, nullptr)); }); d_ptr->mRightButtonGroup->addAction(d_ptr->mMinimumCategoryButtonAction); @@ -989,15 +986,24 @@ void SARibbonBar::showMinimumModeButton(bool isShow) QApplication::sendEvent(this, &resizeEvent); } -/// -/// \brief 是否显示隐藏ribbon按钮 -/// \return -/// +/** + * @brief 是否显示隐藏ribbon按钮 + * @return + */ bool SARibbonBar::haveShowMinimumModeButton() const { return (nullptr != d_ptr->mMinimumCategoryButtonAction); } +/** + @brief 隐藏ribbon对应的action + @return + */ +QAction* SARibbonBar::minimumModeAction() const +{ + return d_ptr->mMinimumCategoryButtonAction; +} + /** @brief tabBar的高度 @return @@ -1307,8 +1313,7 @@ SARibbonQuickAccessBar* SARibbonBar::quickAccessBar() */ void SARibbonBar::setRibbonStyle(SARibbonBar::RibbonStyle v) { - d_ptr->mRibbonStyle = v; - d_ptr->mLastShowStyle = v; + d_ptr->mRibbonStyle = v; d_ptr->mQuickAccessBar->setEnableShowIcon(isOfficeStyle(v)); // 默认情况下2行模式不换行 // 如果想在两行模式换行,在调用SARibbonBar::setRibbonStyle后,再SARibbonToolButton::setEnableWordWrap(true) @@ -1817,7 +1822,7 @@ void SARibbonBar::paintInNormalStyle() titleRegion.setRect(d_ptr->mQuickAccessBar->geometry().right() + 1, border.top(), width() - d_ptr->mIconRightBorderPosition - border.right() - - d_ptr->mWindowButtonSize.width() - d_ptr->mQuickAccessBar->geometry().right() - 1, + - d_ptr->mWindowButtonSize.width() - d_ptr->mQuickAccessBar->geometry().right() - 1, titleBarHeight()); } else { int leftwidth = contextCategoryRegion.x() - d_ptr->mQuickAccessBar->geometry().right() - d_ptr->mIconRightBorderPosition; @@ -1852,7 +1857,6 @@ void SARibbonBar::paintInWpsLiteStyle() //! 显示上下文标签 p.save(); QList< _SAContextCategoryManagerData > contextCategoryDataList = d_ptr->mCurrentShowingContextCategory; - bool isCurrentSelectContextCategoryPage = false; QMargins border = contentsMargins(); for (int i = 0; i < contextCategoryDataList.size(); ++i) { QRect contextTitleRect; @@ -1870,16 +1874,6 @@ void SARibbonBar::paintInWpsLiteStyle() // 绘制 paintContextCategoryTab(p, QString(), contextTitleRect, clr); } - isCurrentSelectContextCategoryPage = indexs.contains(d_ptr->mRibbonTabBar->currentIndex()); - if (isCurrentSelectContextCategoryPage) { - QPen pen; - pen.setColor(clr); - pen.setWidth(1); - p.setPen(pen); - p.setBrush(Qt::NoBrush); - p.drawRect(d_ptr->mStackedContainerWidget->geometry()); - isCurrentSelectContextCategoryPage = false; - } } p.restore(); //! 显示标题等 @@ -1906,10 +1900,11 @@ void SARibbonBar::resizeStackedContainerWidget() { QMargins border = contentsMargins(); const QRect& ribbonTabBarGeometry = d_ptr->mRibbonTabBar->geometry(); - int x = border.left(); - int y = ribbonTabBarGeometry.bottom() + 1; - int w = width() - border.left() - border.right(); - int h = mainBarHeight() - ribbonTabBarGeometry.bottom() - border.bottom() - 1; + + int x = border.left(); + int y = ribbonTabBarGeometry.bottom() + 1; + int w = width() - border.left() - border.right(); + int h = mainBarHeight() - ribbonTabBarGeometry.bottom() - border.bottom() - 1; if (d_ptr->mStackedContainerWidget->isPopupMode()) { // 弹出模式时,位置为全局位置 QPoint absPosition = mapToGlobal(QPoint(x, y)); @@ -2038,7 +2033,7 @@ bool SARibbonBar::event(QEvent* e) { switch (e->type()) { case QEvent::Show: - //第一次显示刷新 + // 第一次显示刷新 updateRibbonGeometry(); break; default: diff --git a/src/SARibbonBar/SARibbonBar.h b/src/SARibbonBar/SARibbonBar.h index e6899d81..31bb8b7f 100644 --- a/src/SARibbonBar/SARibbonBar.h +++ b/src/SARibbonBar/SARibbonBar.h @@ -104,14 +104,14 @@ class SA_RIBBON_EXPORT SARibbonBar : public QMenuBar */ enum RibbonStyle { - RibbonStyleLooseThreeRow = 0x0000, ///< 宽松结构,3行模式 - RibbonStyleCompactThreeRow = 0x0001, ///< 紧凑结构,3行模式 - RibbonStyleLooseTwoRow = 0x0100, ///< 宽松结构,2行模式 - RibbonStyleCompactTwoRow = 0x0101, ///< 紧凑结构,2行模式 - // 以下枚举将组件淘汰 - OfficeStyle = RibbonStyleLooseThreeRow, ///< 类似office 的ribbon风格 - WpsLiteStyle = RibbonStyleCompactThreeRow, ///< 类似wps的紧凑风格 - OfficeStyleTwoRow = RibbonStyleLooseTwoRow, ///< 类似office 的ribbon风格 2行工具栏 三行布局模式,office就是三行布局模式,pannel能布置3行小toolbutton,默认模式 + RibbonStyleLooseThreeRow = 0x0000, ///< 宽松结构,3行模式 + RibbonStyleCompactThreeRow = 0x0001, ///< 紧凑结构,3行模式 + RibbonStyleLooseTwoRow = 0x0100, ///< 宽松结构,2行模式 + RibbonStyleCompactTwoRow = 0x0101, ///< 紧凑结构,2行模式 + // 以下枚举将组件淘汰 + OfficeStyle = RibbonStyleLooseThreeRow, ///< 类似office 的ribbon风格 + WpsLiteStyle = RibbonStyleCompactThreeRow, ///< 类似wps的紧凑风格 + OfficeStyleTwoRow = RibbonStyleLooseTwoRow, ///< 类似office 的ribbon风格 2行工具栏 三行布局模式,office就是三行布局模式,pannel能布置3行小toolbutton,默认模式 WpsLiteStyleTwoRow = RibbonStyleCompactTwoRow ///< 类似wps的紧凑风格 2行工具栏 }; Q_ENUM(RibbonStyle) @@ -227,6 +227,9 @@ class SA_RIBBON_EXPORT SARibbonBar : public QMenuBar // 是否显示隐藏ribbon按钮 bool haveShowMinimumModeButton() const; + // 隐藏ribbon对应的action + QAction* minimumModeAction() const; + // ribbon tab的高度 int tabBarHeight() const; void setTabBarHeight(int h); diff --git a/src/SARibbonBar/SARibbonCategory.cpp b/src/SARibbonBar/SARibbonCategory.cpp index f38cf915..c9edaf27 100644 --- a/src/SARibbonBar/SARibbonCategory.cpp +++ b/src/SARibbonBar/SARibbonCategory.cpp @@ -32,7 +32,6 @@ class SARibbonCategory::PrivateData // 移除Pannel,Category会直接回收SARibbonPannel内存 bool removePannel(SARibbonPannel* pannel); - void setBackgroundBrush(const QBrush& brush); SARibbonCategory* ribbonCategory(); const SARibbonCategory* ribbonCategory() const; void setRibbonPannelLayoutMode(SARibbonPannel::PannelLayoutMode m); @@ -95,7 +94,7 @@ void SARibbonCategory::PrivateData::insertPannel(int index, SARibbonPannel* pann pannel->setPannelLayoutMode(ribbonPannelLayoutMode()); index = qMax(0, index); index = qMin(lay->pannelCount(), index); - lay->addPannel(pannel); + lay->insertPannel(index, pannel); pannel->setVisible(true); } @@ -118,14 +117,6 @@ bool SARibbonCategory::PrivateData::removePannel(SARibbonPannel* pannel) return (false); } -void SARibbonCategory::PrivateData::setBackgroundBrush(const QBrush& brush) -{ - QPalette p = ribbonCategory()->palette(); - - p.setBrush(QPalette::Window, brush); - ribbonCategory()->setPalette(p); -} - QList< SARibbonPannel* > SARibbonCategory::PrivateData::pannelList() { if (SARibbonCategoryLayout* lay = q_ptr->categoryLayout()) { @@ -453,15 +444,6 @@ bool SARibbonCategory::removePannel(int index) return (removePannel(p)); } -/// -/// \brief SARibbonCategory::setBackgroundBrush -/// \param brush -/// -void SARibbonCategory::setBackgroundBrush(const QBrush& brush) -{ - d_ptr->setBackgroundBrush(brush); -} - /** * @brief 返回Category下的所有pannel * @return @@ -524,9 +506,15 @@ void SARibbonCategory::setCanCustomize(bool b) */ SARibbonBar* SARibbonCategory::ribbonBar() const { + // 第一个par是stackwidget if (QWidget* par = parentWidget()) { - if (SARibbonBar* ribbon = qobject_cast< SARibbonBar* >(par->parentWidget())) { - return ribbon; + // 理论此时是ribbonbar + par = par->parentWidget(); + while (par) { + if (SARibbonBar* ribbon = qobject_cast< SARibbonBar* >(par)) { + return ribbon; + } + par = par->parentWidget(); } } return nullptr; diff --git a/src/SARibbonBar/SARibbonCategory.h b/src/SARibbonBar/SARibbonCategory.h index 742b0331..cba1f2b1 100644 --- a/src/SARibbonBar/SARibbonCategory.h +++ b/src/SARibbonBar/SARibbonCategory.h @@ -32,87 +32,84 @@ class SA_RIBBON_EXPORT SARibbonCategory : public QWidget // category的名字 QString categoryName() const; - //设置category名字,等同setWindowTitle + // 设置category名字,等同setWindowTitle void setCategoryName(const QString& title); - //布局模式 + // 布局模式 SARibbonPannel::PannelLayoutMode ribbonPannelLayoutMode() const; - //添加pannel + // 添加pannel SARibbonPannel* addPannel(const QString& title); - //添加pannel + // 添加pannel void addPannel(SARibbonPannel* pannel); // qt designer专用 Q_INVOKABLE void addPannel(QWidget* pannel); - //插入pannel + // 插入pannel SARibbonPannel* insertPannel(const QString& title, int index); - //通过名字查找pannel + // 通过名字查找pannel SARibbonPannel* pannelByName(const QString& title) const; - //通过ObjectName查找pannel + // 通过ObjectName查找pannel SARibbonPannel* pannelByObjectName(const QString& objname) const; - //通过索引找到pannel,如果超过索引范围,会返回nullptr + // 通过索引找到pannel,如果超过索引范围,会返回nullptr SARibbonPannel* pannelByIndex(int index) const; - //查找pannel的index + // 查找pannel的index int pannelIndex(SARibbonPannel* p) const; - //移动一个Pannel从from index到to index + // 移动一个Pannel从from index到to index void movePannel(int from, int to); - //把pannel从Category中移除,不会销毁,此时pannel的所有权归还操作者 + // 把pannel从Category中移除,不会销毁,此时pannel的所有权归还操作者 bool takePannel(SARibbonPannel* pannel); - //移除Pannel,Category会直接回收SARibbonPannel内存 + // 移除Pannel,Category会直接回收SARibbonPannel内存 bool removePannel(SARibbonPannel* pannel); bool removePannel(int index); - //设置背景 - void setBackgroundBrush(const QBrush& brush); - - //返回所有的Pannel + // 返回所有的Pannel QList< SARibbonPannel* > pannelList() const; // QSize sizeHint() const Q_DECL_OVERRIDE; - //如果是ContextCategory,此函数返回true + // 如果是ContextCategory,此函数返回true bool isContextCategory() const; // pannel的个数 int pannelCount() const; - //判断是否可以自定义 + // 判断是否可以自定义 bool isCanCustomize() const; void setCanCustomize(bool b); - //获取对应的ribbonbar,如果没有加入ribbonbar的管理,此值为null + // 获取对应的ribbonbar,如果没有加入ribbonbar的管理,此值为null SARibbonBar* ribbonBar() const; - //刷新category的尺寸布局 + // 刷新category的尺寸布局 void updateItemGeometry(); protected: - //设置pannel的模式 + // 设置pannel的模式 void setRibbonPannelLayoutMode(SARibbonPannel::PannelLayoutMode m); virtual bool event(QEvent* e) Q_DECL_OVERRIDE; - //处理滚轮事件 + // 处理滚轮事件 void wheelEvent(QWheelEvent* event) Q_DECL_OVERRIDE; // void changeEvent(QEvent* event) Q_DECL_OVERRIDE; - //标记这个是上下文标签 + // 标记这个是上下文标签 void markIsContextCategory(bool isContextCategory = true); - //获取SARibbonCategoryLayoutlayout + // 获取SARibbonCategoryLayoutlayout SARibbonCategoryLayout* categoryLayout() const; - //设置Category的对齐方式 + // 设置Category的对齐方式 void setCategoryAlignment(SARibbonAlignment al); SARibbonAlignment getCategoryAlignment() const; }; diff --git a/src/SARibbonBar/SARibbonCategoryLayout.cpp b/src/SARibbonBar/SARibbonCategoryLayout.cpp index da70419b..07c36210 100644 --- a/src/SARibbonBar/SARibbonCategoryLayout.cpp +++ b/src/SARibbonBar/SARibbonCategoryLayout.cpp @@ -7,7 +7,7 @@ #include #ifndef SARibbonCategoryLayout_DEBUG_PRINT -#define SARibbonCategoryLayout_DEBUG_PRINT 0 +#define SARibbonCategoryLayout_DEBUG_PRINT 1 #endif /** * @brief The SARibbonCategoryLayoutPrivate class @@ -17,7 +17,7 @@ class SARibbonCategoryLayout::PrivateData SA_RIBBON_DECLARE_PUBLIC(SARibbonCategoryLayout) public: PrivateData(SARibbonCategoryLayout* p); - //计算所有元素的sizehint总宽度 + // 计算所有元素的sizehint总宽度 int totalSizeHintWidth() const; public: @@ -57,20 +57,20 @@ int SARibbonCategoryLayout::PrivateData::totalSizeHintWidth() const if (!mag.isNull()) { total += (mag.left() + mag.right()); } - //先计算总长 + // 先计算总长 for (SARibbonCategoryLayoutItem* item : qAsConst(mItemList)) { if (item->isEmpty()) { -//如果是hide就直接跳过 -#if SA_DEBUG_PRINT_SIZE_HINT +// 如果是hide就直接跳过 +#if SARibbonCategoryLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT ++debug_i__; debug_totalSizeHintWidth__ += QString(" [%1](%2)is empty skip\n") - .arg(debug_i__) - .arg(item->toPannelWidget()->pannelName()); + .arg(debug_i__) + .arg(item->toPannelWidget()->pannelName()); #endif continue; } - //这里要使用widget()->sizeHint(),因为pannel的标题会影总体布局,此处需要修改 - // TODO + // 这里要使用widget()->sizeHint(),因为pannel的标题会影总体布局,此处需要修改 + // TODO QSize pannelSize = item->widget()->sizeHint(); QSize SeparatorSize(0, 0); if (item->separatorWidget) { @@ -78,18 +78,18 @@ int SARibbonCategoryLayout::PrivateData::totalSizeHintWidth() const } total += pannelSize.width(); total += SeparatorSize.width(); -#if SA_DEBUG_PRINT_SIZE_HINT +#if SARibbonCategoryLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT ++debug_i__; debug_totalSizeHintWidth__ += QString("|-[%1]pannelSize=(%2,%3),SeparatorSize=(%4,%5),name=(%6) \n") - .arg(debug_i__) - .arg(pannelSize.width()) - .arg(pannelSize.height()) - .arg(SeparatorSize.width()) - .arg(SeparatorSize.height()) - .arg(item->toPannelWidget()->pannelName()); + .arg(debug_i__) + .arg(pannelSize.width()) + .arg(pannelSize.height()) + .arg(SeparatorSize.width()) + .arg(SeparatorSize.height()) + .arg(item->toPannelWidget()->pannelName()); #endif } -#if SA_DEBUG_PRINT_SIZE_HINT +#if SARibbonCategoryLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT qDebug() << "SARibbonCategoryLayout.totalSizeHintWidth=" << total; qDebug().noquote() << debug_totalSizeHintWidth__; #endif @@ -225,11 +225,11 @@ void SARibbonCategoryLayout::insertPannel(int index, SARibbonPannel* pannel) index = qMin(d_ptr->mItemList.count(), index); SARibbonCategoryLayoutItem* item = new SARibbonCategoryLayoutItem(pannel); - //分割线 + // 分割线 item->separatorWidget = RibbonSubElementDelegate->createRibbonSeparatorWidget(parentWidget()); - //插入list中 + // 插入list中 d_ptr->mItemList.insert(index, item); - //标记需要重新计算尺寸 + // 标记需要重新计算尺寸 invalidate(); } @@ -303,12 +303,12 @@ void SARibbonCategoryLayout::updateGeometryArr() // total 是总宽,不是x坐标系,x才是坐标系 int total = d_ptr->totalSizeHintWidth(); - //扩展的宽度 + // 扩展的宽度 int expandWidth = 0; -//如果total < categoryWidth,m_d->mXBase可以设置为0 -//判断是否超过总长度 -#if SA_DEBUG_PRINT_SIZE_HINT +// 如果total < categoryWidth,m_d->mXBase可以设置为0 +// 判断是否超过总长度 +#if SARibbonCategoryLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT qDebug() << "SARibbonCategoryLayout::updateGeometryArr" << "\n|-category name=" << category->categoryName() // << "\n|-category height=" << height // @@ -318,29 +318,29 @@ void SARibbonCategoryLayout::updateGeometryArr() << "\n|-mag=" << mag; #endif if (total > categoryWidth) { - //超过总长度,需要显示滚动按钮 + // 超过总长度,需要显示滚动按钮 if (0 == d_ptr->mXBase) { - //已经移动到最左,需要可以向右移动 + // 已经移动到最左,需要可以向右移动 d_ptr->mIsRightScrollBtnShow = true; d_ptr->mIsLeftScrollBtnShow = false; } else if (d_ptr->mXBase <= (categoryWidth - total)) { - //已经移动到最右,需要可以向左移动 + // 已经移动到最右,需要可以向左移动 d_ptr->mIsRightScrollBtnShow = false; d_ptr->mIsLeftScrollBtnShow = true; } else { - //移动到中间两边都可以动 + // 移动到中间两边都可以动 d_ptr->mIsRightScrollBtnShow = true; d_ptr->mIsLeftScrollBtnShow = true; } } else { - //说明total 小于 categoryWidth - //记录可以扩展的数量 + // 说明total 小于 categoryWidth + // 记录可以扩展的数量 int canExpandingCount = 0; d_ptr->mIsRightScrollBtnShow = false; d_ptr->mIsLeftScrollBtnShow = false; - //这个是避免一开始totalWidth > categorySize.width(),通过滚动按钮调整了m_d->mBaseX - //随之调整了窗体尺寸,调整后totalWidth < categorySize.width()导致category在原来位置 - //无法显示,必须这里把mBaseX设置为0 + // 这个是避免一开始totalWidth > categorySize.width(),通过滚动按钮调整了m_d->mBaseX + // 随之调整了窗体尺寸,调整后totalWidth < categorySize.width()导致category在原来位置 + // 无法显示,必须这里把mBaseX设置为0 d_ptr->mXBase = 0; // @@ -353,7 +353,7 @@ void SARibbonCategoryLayout::updateGeometryArr() } } } - //计算可扩展的宽度 + // 计算可扩展的宽度 if (canExpandingCount > 0) { expandWidth = (categoryWidth - total) / canExpandingCount; } else { @@ -362,14 +362,14 @@ void SARibbonCategoryLayout::updateGeometryArr() } int x = d_ptr->mXBase; if ((getCategoryAlignment() == SARibbonAlignment::AlignCenter) && (total < categoryWidth) && (0 == expandWidth)) { - //如果是居中对齐,同时没有伸缩的pannel,同时总宽度没有超过category的宽度 + // 如果是居中对齐,同时没有伸缩的pannel,同时总宽度没有超过category的宽度 x = (categoryWidth - total) / 2; } total = 0; // total重新计算 - //先按照sizeHint设置所有的尺寸 + // 先按照sizeHint设置所有的尺寸 for (SARibbonCategoryLayoutItem* item : qAsConst(d_ptr->mItemList)) { if (item->isEmpty()) { - //如果是hide就直接跳过 + // 如果是hide就直接跳过 if (item->separatorWidget) { // pannel hide分割线也要hide item->separatorWidget->hide(); @@ -390,7 +390,7 @@ void SARibbonCategoryLayout::updateGeometryArr() SeparatorSize = item->separatorWidget->sizeHint(); } if (p->isExpanding()) { - //可扩展,就把pannel扩展到最大 + // 可扩展,就把pannel扩展到最大 pannelSize.setWidth(pannelSize.width() + expandWidth); } int w = pannelSize.width(); @@ -405,7 +405,7 @@ void SARibbonCategoryLayout::updateGeometryArr() d_ptr->mTotalWidth = total; d_ptr->mSizeHint = QSize(d_ptr->mTotalWidth, height); d_ptr->mMinSizeHint = QSize(categoryWidth, height); -#if SA_DEBUG_PRINT_SIZE_HINT +#if SARibbonCategoryLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT qDebug() << "SARibbonCategoryLayout updateGeometryArr,SizeHint=" << d_ptr->mSizeHint << ",Category name=" << category->categoryName(); #endif @@ -420,11 +420,11 @@ void SARibbonCategoryLayout::doLayout() updateGeometryArr(); } SARibbonCategory* category = ribbonCategory(); - //两个滚动按钮的位置永远不变 + // 两个滚动按钮的位置永远不变 d_ptr->mLeftScrollBtn->setGeometry(0, 0, 12, category->height()); d_ptr->mRightScrollBtn->setGeometry(category->width() - 12, 0, 12, category->height()); QList< QWidget* > showWidgets, hideWidgets; -#ifdef SA_DEBUG_PRINT_SIZE_HINT +#if SARibbonCategoryLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT int debug_i__(0); qDebug() << "SARibbonCategoryLayout::doLayout(),name=" << category->categoryName(); #endif @@ -434,7 +434,7 @@ void SARibbonCategoryLayout::doLayout() if (item->separatorWidget) { hideWidgets << item->separatorWidget; } -#ifdef SA_DEBUG_PRINT_SIZE_HINT +#if SARibbonCategoryLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT qDebug() << "|-[" << debug_i__ << "]pannelName(" << item->toPannelWidget()->pannelName() << ",will hide"; ++debug_i__; #endif @@ -447,7 +447,7 @@ void SARibbonCategoryLayout::doLayout() item->separatorWidget->setGeometry(item->mWillSetSeparatorGeometry); showWidgets << item->separatorWidget; } -#ifdef SA_DEBUG_PRINT_SIZE_HINT +#if SARibbonCategoryLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT qDebug() << "|-[" << debug_i__ << "]pannelName(" << item->toPannelWidget()->pannelName() << "),willSetGeometry:" << item->mWillSetGeometry << ",WillSetSeparatorGeometry:" << item->mWillSetSeparatorGeometry; @@ -650,7 +650,7 @@ void SARibbonCategoryLayout::onLeftScrollButtonClicked() { SARibbonCategory* category = qobject_cast< SARibbonCategory* >(parentWidget()); int width = category->width(); - //求总宽 + // 求总宽 int totalWidth = d_ptr->mTotalWidth; if (totalWidth > width) { @@ -669,7 +669,7 @@ void SARibbonCategoryLayout::onRightScrollButtonClicked() { SARibbonCategory* category = qobject_cast< SARibbonCategory* >(parentWidget()); int width = category->width(); - //求总宽 + // 求总宽 int totalWidth = d_ptr->mTotalWidth; if (totalWidth > width) { @@ -690,7 +690,7 @@ void SARibbonCategoryLayout::setGeometry(const QRect& rect) if (old == rect) { return; } -#if SA_DEBUG_PRINT_SIZE_HINT +#if SARibbonCategoryLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT qDebug() << "===========SARibbonCategoryLayout.setGeometry(" << rect << "(" << ribbonCategory()->categoryName() << ")======="; #endif QLayout::setGeometry(rect); diff --git a/src/SARibbonBar/SARibbonGlobal.h b/src/SARibbonBar/SARibbonGlobal.h index 3137071b..c2943370 100644 --- a/src/SARibbonBar/SARibbonGlobal.h +++ b/src/SARibbonBar/SARibbonGlobal.h @@ -9,6 +9,10 @@ @note My native language is not English, and most of the translation of documents is machine translation 版本记录(change log): + - 2023-12-25 -> 1.0.8 + 修正了尺寸刷新的问题,在首次显示不会出现控件跳动的状态 + 调整了创建RibbonButton的方式 + 调整了SARibbonPannel一些接口,使得创建更加规范 - 2023-11-19 -> 1.0.6 添加Office2016主题 @@ -110,7 +114,7 @@ * @def ribbon的数字版本 MAJ.MIN.{PAT} */ #ifndef SA_RIBBON_BAR_VERSION_PAT -#define SA_RIBBON_BAR_VERSION_PAT 7 +#define SA_RIBBON_BAR_VERSION_PAT 8 #endif #ifndef SA_RIBBON_BAR_NO_EXPORT @@ -141,7 +145,7 @@ #define SA_RIBBON_DECLARE_PUBLIC(classname) \ friend class classname; \ classname* q_ptr { nullptr }; \ - PrivateData(const PrivateData&) = delete; \ + PrivateData(const PrivateData&) = delete; \ PrivateData& operator=(const PrivateData&) = delete; #endif @@ -185,7 +189,7 @@ enum class SARibbonAlignment 仅用于调试 */ -#define SA_DEBUG_PRINT_SIZE_HINT 1 +#define SA_DEBUG_PRINT_SIZE_HINT 0 #endif #ifndef SA_DEBUG_PRINT_EVENT /** diff --git a/src/SARibbonBar/SARibbonPannel.cpp b/src/SARibbonBar/SARibbonPannel.cpp index 1af94d8a..67913c8c 100644 --- a/src/SARibbonBar/SARibbonPannel.cpp +++ b/src/SARibbonBar/SARibbonPannel.cpp @@ -578,7 +578,7 @@ QSize SARibbonPannel::optionActionButtonSize() const int SARibbonPannel::actionIndex(QAction* act) const { if (SARibbonPannelLayout* lay = pannelLayout()) { - return (lay->indexOf(act)); + return (lay->indexByAction(act)); } return (-1); } @@ -705,7 +705,7 @@ SARibbonBar* SARibbonPannel::ribbonBar() const void SARibbonPannel::resetLayout(PannelLayoutMode newmode) { Q_UNUSED(newmode); -#if SA_DEBUG_PRINT_SIZE_HINT +#if SARibbonPannel_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT qDebug() << "SARibbonPannel resetLayout,pannelName=" << pannelName(); #endif if (ribbonBar()) { @@ -758,7 +758,7 @@ void SARibbonPannel::resizeEvent(QResizeEvent* e) if (ThreeRowMode == pannelLayoutMode()) { d_ptr->m_optionActionButton->move(width() - d_ptr->m_optionActionButton->width() - 2, height() - titleHeight() - + (titleHeight() - d_ptr->m_optionActionButton->height()) / 2); + + (titleHeight() - d_ptr->m_optionActionButton->height()) / 2); } else { d_ptr->m_optionActionButton->move(width() - d_ptr->m_optionActionButton->width(), height() - d_ptr->m_optionActionButton->height()); @@ -801,7 +801,7 @@ void SARibbonPannel::actionEvent(QActionEvent* e) int index = layout()->count(); if (e->before()) { // 说明是插入 - index = lay->indexOf(e->before()); + index = lay->indexByAction(e->before()); if (-1 == index) { index = layout()->count(); // 找不到的时候就插入到最后 } @@ -825,26 +825,26 @@ void SARibbonPannel::actionEvent(QActionEvent* e) if (QLayout* pl = parw->layout()) { pl->invalidate(); } - // //! 强制发送一个resizeevent,让Category能重绘,如果没有这个函数,发现Category的layout虽然设置了invalidate(标记缓存失效) - // //! 但并没有按顺序在pannel尺寸更新后更新Category的尺寸,导致有些pannel的尺寸识别出现异常 - // //! 重打印信息上看,pannel的尺寸有进行更新,category的尺寸也进行了更新,但更新的次数和调用invalidate的次数不一样,需要手动触发ResizeEvent - // //! 尝试过调用QEvent::LayoutRequest没有效果: - // //! @code - // //! QEvent* el = new QEvent(QEvent::LayoutRequest); - // //! QApplication::postEvent(parw, el); - // //! @endcode - // //! - // //! 调用parw->updateGeometry();也没有效果,目前看使用resizeevent是最有效果的 - // //! - // QResizeEvent* ersize = new QResizeEvent(parw->size(), QSize()); - // QApplication::postEvent(parw, ersize); + //! 强制发送一个resizeevent,让Category能重绘,如果没有这个函数,发现Category的layout虽然设置了invalidate(标记缓存失效) + //! 但并没有按顺序在pannel尺寸更新后更新Category的尺寸,导致有些pannel的尺寸识别出现异常 + //! 重打印信息上看,pannel的尺寸有进行更新,category的尺寸也进行了更新,但更新的次数和调用invalidate的次数不一样,需要手动触发ResizeEvent + //! 尝试过调用QEvent::LayoutRequest没有效果: + //! @code + //! QEvent* el = new QEvent(QEvent::LayoutRequest); + //! QApplication::postEvent(parw, el); + //! @endcode + //! + //! 调用parw->updateGeometry();也没有效果,目前看使用resizeevent是最有效果的 + //! + QResizeEvent* ersize = new QResizeEvent(parw->size(), QSize()); + QApplication::postEvent(parw, ersize); } } break; case QEvent::ActionRemoved: { SARibbonPannelLayout* lay = pannelLayout(); action->disconnect(this); - int index = lay->indexOf(action); + int index = lay->indexByAction(action); if (index != -1) { QLayoutItem* item = lay->takeAt(index); delete item; diff --git a/src/SARibbonBar/SARibbonPannelItem.h b/src/SARibbonBar/SARibbonPannelItem.h index 99af5115..663b76e0 100644 --- a/src/SARibbonBar/SARibbonPannelItem.h +++ b/src/SARibbonBar/SARibbonPannelItem.h @@ -48,10 +48,4 @@ class SA_RIBBON_EXPORT SARibbonPannelItem : public QWidgetItem #ifndef SA_ActionPropertyName_SeparatorBottom #define SA_ActionPropertyName_SeparatorBottom "_sa_SeparatorBottom" #endif -#ifndef SA_ActionPropertyName_IsActionMenu -#define SA_ActionPropertyName_IsActionMenu "_sa_IsActionMenu" -#endif -#ifndef SA_ActionPropertyName_MenuPointer -#define SA_ActionPropertyName_MenuPointer "_sa_MenuPointer" -#endif #endif // SARIBBONPANNELITEM_H diff --git a/src/SARibbonBar/SARibbonPannelLayout.cpp b/src/SARibbonBar/SARibbonPannelLayout.cpp index 29d03b84..ea8db933 100644 --- a/src/SARibbonBar/SARibbonPannelLayout.cpp +++ b/src/SARibbonBar/SARibbonPannelLayout.cpp @@ -6,7 +6,7 @@ #include #include "SARibbonPannel.h" #include "SARibbonPannelItem.h" -#define SARibbonPannelLayout_DEBUG_PRINT 0 +#define SARibbonPannelLayout_DEBUG_PRINT 1 #define HELP_DRAW_RECT(p, rect) \ do { \ p.save(); \ @@ -50,7 +50,7 @@ SARibbonPannelLayout::~SARibbonPannelLayout() * @param action * @return 没有查到返回-1 */ -int SARibbonPannelLayout::indexOf(QAction* action) const +int SARibbonPannelLayout::indexByAction(QAction* action) const { for (int i = 0; i < m_items.count(); ++i) { if (m_items.at(i)->action == action) { @@ -152,6 +152,11 @@ QSize SARibbonPannelLayout::minimumSize() const QSize SARibbonPannelLayout::sizeHint() const { +#if SARibbonPannelLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT + if (SARibbonPannel* pannel = ribbonPannel()) { + qDebug() << "| |-SARibbonPannelLayout sizeHint,sizeHint = " << m_sizeHint; + } +#endif return (m_sizeHint); } @@ -162,7 +167,7 @@ QSize SARibbonPannelLayout::sizeHint() const */ SARibbonPannelItem* SARibbonPannelLayout::pannelItem(QAction* action) const { - int index = indexOf(action); + int index = indexByAction(action); if (index >= 0) { return (m_items[ index ]); @@ -267,8 +272,8 @@ void SARibbonPannelLayout::setPannelContentsMargins(const QMargins& m) */ void SARibbonPannelLayout::layoutActions() { -#if SA_DEBUG_PRINT_SIZE_HINT - if (SARibbonPannel* pannel = qobject_cast< SARibbonPannel* >(parentWidget())) { +#if SARibbonPannelLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT + if (SARibbonPannel* pannel = ribbonPannel()) { qDebug() << "| |-SARibbonPannelLayout layoutActions,pannel name = " << pannel->pannelName(); } #endif @@ -282,8 +287,6 @@ void SARibbonPannelLayout::layoutActions() hideWidgets << item->widget(); } else { item->setGeometry(item->itemWillSetGeometry); - // item->widget()->setFixedSize(item->itemWillSetGeometry.size()); - // item->widget()->move(item->itemWillSetGeometry.topLeft()); showWidgets << item->widget(); } } @@ -405,7 +408,7 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) int itemCount = m_items.count(); -#if SA_DEBUG_PRINT_SIZE_HINT +#if SARibbonPannelLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT QString debug_print__log__; #endif // 本列第一、二行占比 @@ -421,14 +424,14 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) } QSize hint = item->sizeHint(); -#if SA_DEBUG_PRINT_SIZE_HINT +#if SARibbonPannelLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT if (SARibbonToolButton* tb = qobject_cast< SARibbonToolButton* >(item->widget())) { auto ss__ = tb->sizeHint(); debug_print__log__ += QString("| | |-[%1]SARibbonToolButton.sizeHint=(%2,%3),ButtonText=%4\n") - .arg(i) - .arg(ss__.width()) - .arg(ss__.height()) - .arg(tb->text()); + .arg(i) + .arg(ss__.width()) + .arg(ss__.height()) + .arg(tb->text()); } #endif Qt::Orientations exp = item->expandingDirections(); @@ -620,7 +623,7 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) // 说明可以设置扩展属性的窗口 recalcExpandGeomArray(setrect); } -#if SA_DEBUG_PRINT_SIZE_HINT +#if SARibbonPannelLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT qDebug() << "| |-SARibbonPannelLayout updateGeomArray(" << setrect << "),pannel name = " << pannel->pannelName() << "\n| | |-size hint =" << this->m_sizeHint // << "\n| | |-totalWidth=" << totalWidth // @@ -630,7 +633,7 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) << "\n| | |-mag=" << mag // << "\n| | |-largeHeight=" << largeHeight // << "\n| | |-smallHeight=" << smallHeight // - ; + ; qDebug().noquote() << debug_print__log__; #endif } @@ -717,11 +720,11 @@ void SARibbonPannelLayout::recalcExpandGeomArray(const QRect& setrect) } } } -#if SA_DEBUG_PRINT_SIZE_HINT +#if SARibbonPannelLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT qDebug() << "| |-SARibbonPannelLayout recalcExpandGeomArray(" << setrect << ") pannelName=" << ribbonPannel()->pannelName() // << ",expandwidth=" << expandwidth // - ; + ; #endif } @@ -775,7 +778,7 @@ void SARibbonPannelLayout::setGeometry(const QRect& rect) if (old == rect) { return; } -#if SA_DEBUG_PRINT_SIZE_HINT +#if SARibbonPannelLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT qDebug() << "| |----->SARibbonPannelLayout.setGeometry(" << rect << "(" << ribbonPannel()->pannelName() << ")======="; #endif QLayout::setGeometry(rect); diff --git a/src/SARibbonBar/SARibbonPannelLayout.h b/src/SARibbonBar/SARibbonPannelLayout.h index b9348eed..8d4c7bc2 100644 --- a/src/SARibbonBar/SARibbonPannelLayout.h +++ b/src/SARibbonBar/SARibbonPannelLayout.h @@ -22,9 +22,9 @@ class SA_RIBBON_EXPORT SARibbonPannelLayout : public QLayout public: SARibbonPannelLayout(QWidget* p = 0); ~SARibbonPannelLayout(); - virtual int indexOf(QAction* action) const; + int indexByAction(QAction* action) const; - //获取ribbonpannel + // 获取ribbonpannel SARibbonPannel* ribbonPannel() const; // SARibbonPannelLayout additem 无效 @@ -46,45 +46,45 @@ class SA_RIBBON_EXPORT SARibbonPannelLayout : public QLayout QSize minimumSize() const Q_DECL_OVERRIDE; QSize sizeHint() const Q_DECL_OVERRIDE; - //通过action获取SARibbonPannelItem + // 通过action获取SARibbonPannelItem SARibbonPannelItem* pannelItem(QAction* action) const; - //获取最后一个添加的item + // 获取最后一个添加的item SARibbonPannelItem* lastItem() const; - //获取最后生成的窗口 + // 获取最后生成的窗口 QWidget* lastWidget() const; - //移动两个item + // 移动两个item void move(int from, int to); - //判断是否需要重新布局 + // 判断是否需要重新布局 bool isDirty() const; - //计算大图标的高度 + // 计算大图标的高度 static int calcLargeHeight(const QRect& setrect, const SARibbonPannel* pannel); public: - //全局的contentsMargins + // 全局的contentsMargins static const QMargins& pannelContentsMargins(); static void setPannelContentsMargins(const QMargins& m); protected: - //布局action + // 布局action void layoutActions(); - //把action转换为item,对于纯Action,此函数会创建SARibbonToolButton, - // rp用于告诉Layout生成什么样的窗口,详细见SARibbonPannelItem::RowProportion + // 把action转换为item,对于纯Action,此函数会创建SARibbonToolButton, + // rp用于告诉Layout生成什么样的窗口,详细见SARibbonPannelItem::RowProportion SARibbonPannelItem* createItem(QAction* action, SARibbonPannelItem::RowProportion rp = SARibbonPannelItem::None); void updateGeomArray(const QRect& setrect); - //重新计算扩展条码,此函数必须在updateGeomArray函数之后调用 + // 重新计算扩展条码,此函数必须在updateGeomArray函数之后调用 void recalcExpandGeomArray(const QRect& setrect); private: - //返回所有列的区域 - // QMap columnsGeometry() const; - //根据列数,计算窗口的宽度,以及最大宽度 + // 返回所有列的区域 + // QMap columnsGeometry() const; + // 根据列数,计算窗口的宽度,以及最大宽度 void columnWidthInfo(int colindex, int& width, int& maximum) const; private: diff --git a/src/SARibbonBar/SARibbonStackedWidget.cpp b/src/SARibbonBar/SARibbonStackedWidget.cpp index 4cf70830..47c6fee4 100644 --- a/src/SARibbonBar/SARibbonStackedWidget.cpp +++ b/src/SARibbonBar/SARibbonStackedWidget.cpp @@ -1,5 +1,6 @@ #include "SARibbonStackedWidget.h" #include +#include #include #include #include @@ -12,7 +13,6 @@ class SARibbonStackedWidget::PrivateData SA_RIBBON_DECLARE_PUBLIC(SARibbonStackedWidget) public: QEventLoop* eventLoop { nullptr }; - bool isAutoResize { true }; public: PrivateData(SARibbonStackedWidget* p) : q_ptr(p) @@ -81,22 +81,6 @@ void SARibbonStackedWidget::exec() d_ptr->eventLoop = nullptr; } -/** - * @brief 设置stacked管理的窗口会随着stacked的大小变化而变化大小 - * - * 默认为true - * @param autoresize - */ -void SARibbonStackedWidget::setAutoResize(bool autoresize) -{ - d_ptr->isAutoResize = autoresize; -} - -bool SARibbonStackedWidget::isAutoResize() const -{ - return (d_ptr->isAutoResize); -} - /** * @brief 类似tabbar的moveTab函数,交换两个窗口的index * @param from @@ -123,3 +107,15 @@ void SARibbonStackedWidget::hideEvent(QHideEvent* e) QStackedWidget::hideEvent(e); } + +void SARibbonStackedWidget::resizeEvent(QResizeEvent* e) +{ + QStackedWidget::resizeEvent(e); + for (int i = 0; i < count(); ++i) { + if (i == currentIndex()) { + continue; + } + QEvent* layE = new QEvent(QEvent::LayoutRequest); + QApplication::postEvent(widget(i), layE); + } +} diff --git a/src/SARibbonBar/SARibbonStackedWidget.h b/src/SARibbonBar/SARibbonStackedWidget.h index 305a044a..739fd6fa 100644 --- a/src/SARibbonBar/SARibbonStackedWidget.h +++ b/src/SARibbonBar/SARibbonStackedWidget.h @@ -21,15 +21,17 @@ class SA_RIBBON_EXPORT SARibbonStackedWidget : public QStackedWidget bool isNormalMode() const; void exec(); - //设置stacked管理的窗口会随着stacked的大小变化而变化大小 + // 设置stacked管理的窗口会随着stacked的大小变化而变化大小 + // 就算不激活也调整大小 void setAutoResize(bool autoresize); bool isAutoResize() const; + // 移动窗口 void moveWidget(int from, int to); protected: // void mouseReleaseEvent(QMouseEvent *e); - void hideEvent(QHideEvent* e) override; - + void hideEvent(QHideEvent* e) Q_DECL_OVERRIDE; + virtual void resizeEvent(QResizeEvent* e) Q_DECL_OVERRIDE; signals: /** * @brief hidWindow diff --git a/src/SARibbonBar/SARibbonToolButton.cpp b/src/SARibbonBar/SARibbonToolButton.cpp index 42dbf958..1cd3b0d5 100644 --- a/src/SARibbonBar/SARibbonToolButton.cpp +++ b/src/SARibbonBar/SARibbonToolButton.cpp @@ -269,7 +269,7 @@ void SARibbonToolButton::PrivateData::calcSmallButtonDrawRects(const QStyleOptio case Qt::ToolButtonIconOnly: { if (hasIndicator(opt)) { // 在仅有图标的小模式显示时,预留一个下拉箭头位置 - iconRect = opt.rect.adjusted(spacing, spacing, -indicatorLen - spacing, -spacing); + iconRect = opt.rect.adjusted(spacing, spacing, -indicatorLen - spacing, -spacing); indicatorArrowRect = QRect(opt.rect.right() - indicatorLen - spacing, iconRect.y(), indicatorLen, iconRect.height()); } else { iconRect = opt.rect.adjusted(spacing, spacing, -spacing, -spacing); @@ -281,7 +281,7 @@ void SARibbonToolButton::PrivateData::calcSmallButtonDrawRects(const QStyleOptio case Qt::ToolButtonTextOnly: { if (hasIndicator(opt)) { // 在仅有图标的小模式显示时,预留一个下拉箭头位置 - textRect = opt.rect.adjusted(spacing, spacing, -indicatorLen - spacing, -spacing); + textRect = opt.rect.adjusted(spacing, spacing, -indicatorLen - spacing, -spacing); indicatorArrowRect = QRect(opt.rect.right() - indicatorLen - spacing, spacing, indicatorLen, textRect.height()); } else { textRect = opt.rect.adjusted(spacing, spacing, -spacing, -spacing); @@ -490,9 +490,6 @@ QSize SARibbonToolButton::PrivateData::calcLargeButtonSizeHint(const QStyleOptio h = pannel->largeHeight(); } int textHeight = calcTextDrawRectHeight(opt); - if (mDrawIconRect.isValid()) { - minW = qMax(mDrawIconRect.width(), h - textHeight); - } // 估算字体的宽度作为宽度 w = estimateLargeButtonTextWidth(h, textHeight, opt.text, opt.fontMetrics); w += (2 * mSpacing); @@ -501,9 +498,15 @@ QSize SARibbonToolButton::PrivateData::calcLargeButtonSizeHint(const QStyleOptio w += mIndicatorLen; } - // if (w < minW) { - // w = minW; - // } +#if SA_RIBBON_TOOLBUTTON_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "| | |-SARibbonToolButton::PrivateData::calcLargeButtonSizeHint,text=" << opt.text + << "\n| | | |-lineSpacing*4.5=" << opt.fontMetrics.lineSpacing() * 4.5 // + << "\n| | | |-textHeight=" << textHeight // + << "\n| | | |-mDrawIconRect=" << mDrawIconRect // + << "\n| | | |-minW=" << minW // + << "\n| | | |-w=" << w // + ; +#endif //! Qt6.4 取消了QApplication::globalStrut return QSize(w, h).expandedTo(QSize(minW, textHeight)); } @@ -759,9 +762,6 @@ bool SARibbonToolButton::hitButton(const QPoint& pos) const */ void SARibbonToolButton::resizeEvent(QResizeEvent* e) { -#if SA_RIBBON_TOOLBUTTON_DEBUG_PRINT - qDebug() << "SARibbonToolButton::resizeEvent, text=" << text() << " obj=" << objectName() << " size=" << e->size(); -#endif // 在resizeevent计算绘图所需的尺寸,避免在绘图过程中实时绘制提高效率 QToolButton::resizeEvent(e); updateRect(); @@ -779,6 +779,9 @@ QSize SARibbonToolButton::sizeHint() const // initStyleOption(&opt); // d_ptr->updateSizeHint(opt); // } +#if SA_RIBBON_TOOLBUTTON_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "| | |-SARibbonToolButton::sizeHint"; +#endif QStyleOptionToolButton opt; initStyleOption(&opt); d_ptr->updateSizeHint(opt); From a0acfc98ffe60369bea98ed4a23b2afd16541376 Mon Sep 17 00:00:00 2001 From: czyt1988 Date: Mon, 25 Dec 2023 15:23:48 +0800 Subject: [PATCH 15/16] =?UTF-8?q?=E8=B0=83=E6=95=B4actionMenu=E7=9A=84?= =?UTF-8?q?=E7=BB=98=E5=88=B6=E6=96=B9=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit toolbutton在actionMenu在点击后,文本域不会显示边框 --- src/SARibbonBar/SARibbonToolButton.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/SARibbonBar/SARibbonToolButton.cpp b/src/SARibbonBar/SARibbonToolButton.cpp index 1cd3b0d5..8227b05b 100644 --- a/src/SARibbonBar/SARibbonToolButton.cpp +++ b/src/SARibbonBar/SARibbonToolButton.cpp @@ -846,14 +846,17 @@ void SARibbonToolButton::paintButton(QPainter& p, const QStyleOptionToolButton& } } else { // 鼠标在图标区,把文字显示为正常 - tool.state |= (QStyle::State_Raised); // 把图标区域显示为正常 - tool.state &= ~QStyle::State_MouseOver; - // 文字和Indicator都显示正常 - tool.rect = d_ptr->mDrawTextRect.united(d_ptr->mDrawIndicatorArrowRect); - if (autoRaise) { - style()->drawPrimitive(QStyle::PE_PanelButtonTool, &tool, &p, this); - } else { - style()->drawPrimitive(QStyle::PE_PanelButtonBevel, &tool, &p, this); + if (!tool.state.testFlag(QStyle::State_Sunken)) { + // State_Sunken说明此按钮正在按下,这时候,文本区域不需要绘制,只有在非按下状态才需要绘制 + tool.state |= (QStyle::State_Raised); // 把图标区域显示为正常 + tool.state &= ~QStyle::State_MouseOver; + // 文字和Indicator都显示正常 + tool.rect = d_ptr->mDrawTextRect.united(d_ptr->mDrawIndicatorArrowRect); + if (autoRaise) { + style()->drawPrimitive(QStyle::PE_PanelButtonTool, &tool, &p, this); + } else { + style()->drawPrimitive(QStyle::PE_PanelButtonBevel, &tool, &p, this); + } } } } else { // 小按钮模式 From f708dd45c9ad91392da0d6a0b6676eb2a1f23cca Mon Sep 17 00:00:00 2001 From: czyt1988 Date: Mon, 25 Dec 2023 16:23:40 +0800 Subject: [PATCH 16/16] v1.1.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -修正了尺寸刷新的问题,在首次显示不会出现控件跳动的状态 -修正了一些问题 -调整了创建RibbonButton的方式 -调整了SARibbonPannel一些接口,使得创建更加规范 -调整了ToolButton的渲染方式 --- src/SARibbon.cpp | 1878 +++++++++-------- src/SARibbon.h | 320 ++- src/SARibbonBar/SARibbonGlobal.h | 11 +- tools/amalgamate/SARibbonAmalgamTemplate.cpp | 2 - .../SARibbonAmalgamTemplatePublicHeaders.h | 2 - 5 files changed, 1112 insertions(+), 1101 deletions(-) diff --git a/src/SARibbon.cpp b/src/SARibbon.cpp index 89537779..687d8f22 100644 --- a/src/SARibbon.cpp +++ b/src/SARibbon.cpp @@ -2200,9 +2200,9 @@ class SAWindowButtonGroup::PrivateData } buttonMinimize = new SAWindowToolButton(par); buttonMinimize->setObjectName(QStringLiteral("SAMinimizeWindowButton")); - buttonMinimize->setFixedSize(30, RibbonSubElementStyleOpt.titleBarHeight() - 2); + buttonMinimize->setFixedSize(30, par->height() - 2); buttonMinimize->setFocusPolicy(Qt::NoFocus); // 避免铺抓到 - buttonMinimize->setIconSize(buttonMinimize->size() * mIconscale); + // buttonMinimize->setIconSize(buttonMinimize->size() * mIconscale); buttonMinimize->show(); par->connect(buttonMinimize, &QAbstractButton::clicked, par, &SAWindowButtonGroup::minimizeWindow); } else { @@ -2225,10 +2225,10 @@ class SAWindowButtonGroup::PrivateData } buttonMaximize = new SAWindowToolButton(par); buttonMaximize->setObjectName(QStringLiteral("SAMaximizeWindowButton")); - buttonMaximize->setFixedSize(30, RibbonSubElementStyleOpt.titleBarHeight() - 2); + buttonMaximize->setFixedSize(30, par->height() - 2); buttonMaximize->setCheckable(true); buttonMaximize->setFocusPolicy(Qt::NoFocus); // 避免铺抓到 - buttonMaximize->setIconSize(buttonMaximize->size() * mIconscale); + // buttonMaximize->setIconSize(buttonMaximize->size() * mIconscale); buttonMaximize->show(); par->connect(buttonMaximize, &QAbstractButton::clicked, par, &SAWindowButtonGroup::maximizeWindow); } else { @@ -2251,11 +2251,11 @@ class SAWindowButtonGroup::PrivateData } buttonClose = new SAWindowToolButton(par); buttonClose->setObjectName(QStringLiteral("SACloseWindowButton")); - buttonClose->setFixedSize(40, RibbonSubElementStyleOpt.titleBarHeight() - 2); + buttonClose->setFixedSize(40, par->height() - 2); buttonClose->setFocusPolicy(Qt::NoFocus); // 避免铺抓到 // buttonClose->setFlat(true); par->connect(buttonClose, &QAbstractButton::clicked, par, &SAWindowButtonGroup::closeWindow); - buttonClose->setIconSize(buttonClose->size() * mIconscale); + // buttonClose->setIconSize(buttonClose->size() * mIconscale); buttonClose->show(); } else { if (buttonClose) { @@ -2270,22 +2270,6 @@ class SAWindowButtonGroup::PrivateData { q_ptr->setFixedSize(sizeHint()); resize(q_ptr->size()); - // int span = 0; - - // if (buttonClose) { - // buttonClose->move(q_d->width()-buttonClose->width() - // , q_d->y()); - // span = buttonClose->width(); - // } - // if (buttonMaximize) { - // buttonMaximize->move(q_d->width()-buttonMaximize->width()-span - // , q_d->y()); - // span += buttonMaximize->width(); - // } - // if (buttonMinimize) { - // buttonMinimize->move(q_d->width()-buttonMinimize->width()-span - // , q_d->y()); - // } } void resize(QSize size) @@ -2333,7 +2317,7 @@ class SAWindowButtonGroup::PrivateData QSize sizeHint() const { int width = 0; - int height = RibbonSubElementStyleOpt.titleBarHeight(); + int height = 30; if (buttonClose) { width += 40; @@ -2355,7 +2339,9 @@ SAWindowToolButton::SAWindowToolButton(QWidget* p) : QPushButton(p) { setFlat(true); } - +//=================================================== +// SAWindowButtonGroup +//=================================================== SAWindowButtonGroup::SAWindowButtonGroup(QWidget* parent) : QWidget(parent), d_ptr(new SAWindowButtonGroup::PrivateData(this)) { @@ -2523,7 +2509,15 @@ bool SAWindowButtonGroup::eventFilter(QObject* watched, QEvent* e) void SAWindowButtonGroup::parentResize() { QWidget* par = parentWidget(); - + if (SARibbonMainWindow* rb = qobject_cast< SARibbonMainWindow* >(par)) { + if (SARibbonBar* bar = rb->ribbonBar()) { + // 先看看titlebar多高 + if (height() != bar->titleBarHeight()) { + setFixedHeight(bar->titleBarHeight()); + } + d_ptr->resize(QSize(width(), height())); + } + } if (par) { QSize parSize = par->size(); move(parSize.width() - width() - 1, 0); @@ -2575,6 +2569,8 @@ void SAWindowButtonGroup::maximizeWindow() #include #include #include +#include +#include /** * @def 定义文字换行时2行文本的矩形高度系数,此系数决定文字区域的高度 * @@ -3047,26 +3043,31 @@ QSize SARibbonToolButton::PrivateData::calcLargeButtonSizeHint(const QStyleOptio int w = 0; int h = opt.fontMetrics.lineSpacing() * 4.5; // 3*1.5 int minW = h * 0.75; // 最小宽度,在pannel里面的按钮,最小宽度要和icon适应 - if (mDrawIconRect.isValid()) { - minW = mDrawIconRect.height(); - } + if (SARibbonPannel* pannel = qobject_cast< SARibbonPannel* >(q_ptr->parent())) { // 对于建立在SARibbonPannel的基础上的大按钮,把高度设置为SARibbonPannel计算的大按钮高度 h = pannel->largeHeight(); } + int textHeight = calcTextDrawRectHeight(opt); // 估算字体的宽度作为宽度 - w = estimateLargeButtonTextWidth(h, calcTextDrawRectHeight(opt), opt.text, opt.fontMetrics); + w = estimateLargeButtonTextWidth(h, textHeight, opt.text, opt.fontMetrics); w += (2 * mSpacing); // 判断是否需要加上indicator if (isEnableWordWrap() && isTextNeedWrap()) { w += mIndicatorLen; } - if (w < minW) { - w = minW; - } +#if SA_RIBBON_TOOLBUTTON_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "| | |-SARibbonToolButton::PrivateData::calcLargeButtonSizeHint,text=" << opt.text + << "\n| | | |-lineSpacing*4.5=" << opt.fontMetrics.lineSpacing() * 4.5 // + << "\n| | | |-textHeight=" << textHeight // + << "\n| | | |-mDrawIconRect=" << mDrawIconRect // + << "\n| | | |-minW=" << minW // + << "\n| | | |-w=" << w // + ; +#endif //! Qt6.4 取消了QApplication::globalStrut - return QSize(w, h).expandedTo(QSize(2, 2)); + return QSize(w, h).expandedTo(QSize(minW, textHeight)); } /** @@ -3103,7 +3104,6 @@ int SARibbonToolButton::PrivateData::estimateLargeButtonTextWidth(int buttonHeig float widthHeightRatio, int maxTrycount) { - QSize textSize; int space = SA_FONTMETRICS_WIDTH(fm, (QLatin1Char(' '))) * 2; int hintMaxWidth = buttonHeight * widthHeightRatio; ///< 建议的宽度 @@ -3186,7 +3186,9 @@ QPixmap SARibbonToolButton::PrivateData::createIconPixmap(const QStyleOptionTool } else { mode = QIcon::Normal; } - return (opt.icon.pixmap(iconsize - QSize(2, 2), mode, state)); + // 添加高分屏支持 + QSize pxiampSize = iconsize - QSize(2, 2); + return opt.icon.pixmap(pxiampSize, mode, state); } int SARibbonToolButton::PrivateData::getTextAlignment() const @@ -3319,9 +3321,6 @@ bool SARibbonToolButton::hitButton(const QPoint& pos) const */ void SARibbonToolButton::resizeEvent(QResizeEvent* e) { -#if SA_RIBBON_TOOLBUTTON_DEBUG_PRINT - qDebug() << "SARibbonToolButton::resizeEvent, text=" << text() << " obj=" << objectName() << " size=" << e->size(); -#endif // 在resizeevent计算绘图所需的尺寸,避免在绘图过程中实时绘制提高效率 QToolButton::resizeEvent(e); updateRect(); @@ -3334,11 +3333,14 @@ void SARibbonToolButton::resizeEvent(QResizeEvent* e) */ QSize SARibbonToolButton::sizeHint() const { - // if (!d_ptr->mSizeHint.isValid() || d_ptr->mSizeHint.width() <= 22) { // 22是给与sizehint的最小值,如果小于这个值,重新计算一下 + // if (!d_ptr->mSizeHint.isValid()) { // 22是给与sizehint的最小值,如果小于这个值,重新计算一下 // QStyleOptionToolButton opt; // initStyleOption(&opt); // d_ptr->updateSizeHint(opt); // } +#if SA_RIBBON_TOOLBUTTON_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "| | |-SARibbonToolButton::sizeHint"; +#endif QStyleOptionToolButton opt; initStyleOption(&opt); d_ptr->updateSizeHint(opt); @@ -3403,14 +3405,17 @@ void SARibbonToolButton::paintButton(QPainter& p, const QStyleOptionToolButton& } } else { // 鼠标在图标区,把文字显示为正常 - tool.state |= (QStyle::State_Raised); // 把图标区域显示为正常 - tool.state &= ~QStyle::State_MouseOver; - // 文字和Indicator都显示正常 - tool.rect = d_ptr->mDrawTextRect.united(d_ptr->mDrawIndicatorArrowRect); - if (autoRaise) { - style()->drawPrimitive(QStyle::PE_PanelButtonTool, &tool, &p, this); - } else { - style()->drawPrimitive(QStyle::PE_PanelButtonBevel, &tool, &p, this); + if (!tool.state.testFlag(QStyle::State_Sunken)) { + // State_Sunken说明此按钮正在按下,这时候,文本区域不需要绘制,只有在非按下状态才需要绘制 + tool.state |= (QStyle::State_Raised); // 把图标区域显示为正常 + tool.state &= ~QStyle::State_MouseOver; + // 文字和Indicator都显示正常 + tool.rect = d_ptr->mDrawTextRect.united(d_ptr->mDrawIndicatorArrowRect); + if (autoRaise) { + style()->drawPrimitive(QStyle::PE_PanelButtonTool, &tool, &p, this); + } else { + style()->drawPrimitive(QStyle::PE_PanelButtonBevel, &tool, &p, this); + } } } } else { // 小按钮模式 @@ -3485,9 +3490,23 @@ void SARibbonToolButton::paintText(QPainter& p, const QStyleOptionToolButton& op text = opt.text; } } - - style()->drawItemText(&p, textDrawRect, alignment, opt.palette, opt.state & QStyle::State_Enabled, text, QPalette::ButtonText); - + //! 以下内容参考QCommonStyle.cpp + //! void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,QPainter *p, const QWidget *widget) const + //! case CC_ToolButton: + QStyle::State bflags = opt.state & ~QStyle::State_Sunken; + if (bflags & QStyle::State_AutoRaise) { + if (!(bflags & QStyle::State_MouseOver) || !(bflags & QStyle::State_Enabled)) { + bflags &= ~QStyle::State_Raised; + } + } + if (opt.state & QStyle::State_Sunken) { + if (opt.activeSubControls & QStyle::SC_ToolButton) { + bflags |= QStyle::State_Sunken; + } + } + QStyleOptionToolButton label = opt; + label.state = bflags; + style()->drawItemText(&p, textDrawRect, alignment, label.palette, label.state & QStyle::State_Enabled, text, QPalette::ButtonText); SARIBBONTOOLBUTTON_DEBUG_DRAW_RECT(p, textDrawRect); } @@ -3614,17 +3633,12 @@ void SARibbonToolButton::updateRect() { QStyleOptionToolButton opt; initStyleOption(&opt); - // d_ptr->updateSizeHint(opt); d_ptr->updateDrawRect(opt); } /** * @brief 设置在lite模式下是否允许文字换行,如果允许,则图标相对比较小,默认不允许 * @param on - * @note 此函数的调用最好在ribbonbar布局之前设置,且调用之后需要调用@sa SARibbonStyleOption::recalc 刷新 - * @code - * RibbonSubElementStyleOpt.recalc(); - * @endcode */ void SARibbonToolButton::setEnableWordWrap(bool on) { @@ -3722,9 +3736,11 @@ QPixmap SARibbonColorToolButton::PrivateData::createIconPixmap(const QStyleOptio QPainter painter(&res); int xpixmap = (res.width() - pixmap.width()) / 2; int ypixmap = (res.height() - c_ribbonbutton_color_height - 2 - pixmap.height()) / 2; // 这里要减去2而不是1,这样奇数偶数都不会影响 - QRect rpixmap = QRect(xpixmap, ypixmap, pixmap.width(), pixmap.height()); + int w = pixmap.width(); + int h = pixmap.height(); + QRect rpixmap = QRect(xpixmap, ypixmap, w, h); painter.drawPixmap(rpixmap, pixmap); - QRect colorRect = rpixmap.adjusted(0, pixmap.height() + 1, 0, c_ribbonbutton_color_height + 1); + QRect colorRect = rpixmap.adjusted(0, h + 1, 0, c_ribbonbutton_color_height + 1); if (mColor.isValid()) { painter.fillRect(colorRect, mColor); } else { @@ -4558,109 +4574,6 @@ void SARibbonActionsManagerModel::onActionTagChanged(int tag, bool isdelete) /*** End of inlined file: SARibbonActionsManager.cpp ***/ -/*** Start of inlined file: SARibbonDrawHelper.cpp ***/ -SARibbonDrawHelper::SARibbonDrawHelper() -{ -} - -QPixmap SARibbonDrawHelper::iconToPixmap(const QIcon& icon, QWidget* widget, const QStyleOption* opt, const QSize& icoSize) -{ - QIcon::Mode mode; - QIcon::State state; - - if (!(opt->state & QStyle::State_Enabled)) { - mode = QIcon::Disabled; - } else if ((opt->state & QStyle::State_MouseOver) && (opt->state & QStyle::State_AutoRaise)) { - mode = QIcon::Active; - } else { - mode = QIcon::Normal; - } - - if (opt->state & QStyle::State_Selected || opt->state & QStyle::State_On) { - state = QIcon::On; - } else { - state = QIcon::Off; - } - return (icon.pixmap(icoSize, mode, state)); -} - -void SARibbonDrawHelper::drawIcon(const QIcon& icon, QPainter* painter, const QStyleOption* opt, int x, int y, int width, int height) -{ - QIcon::Mode mode; - QIcon::State state; - - if (!(opt->state & QStyle::State_Enabled)) { - mode = QIcon::Disabled; - } else if ((opt->state & QStyle::State_MouseOver) && (opt->state & QStyle::State_AutoRaise)) { - mode = QIcon::Active; - } else { - mode = QIcon::Normal; - } - - if (opt->state & QStyle::State_Selected || opt->state & QStyle::State_On) { - state = QIcon::On; - } else { - state = QIcon::Off; - } - - icon.paint(painter, x, y, width, height, Qt::AlignCenter, mode, state); -} - -void SARibbonDrawHelper::drawIcon(const QIcon& icon, QPainter* painter, const QStyleOption* opt, const QRect& rect) -{ - QIcon::Mode mode; - QIcon::State state; - - if (!(opt->state & QStyle::State_Enabled)) { - mode = QIcon::Disabled; - } else if ((opt->state & QStyle::State_MouseOver) && (opt->state & QStyle::State_AutoRaise)) { - mode = QIcon::Active; - } else { - mode = QIcon::Normal; - } - - if (opt->state & QStyle::State_Selected || opt->state & QStyle::State_On) { - state = QIcon::On; - } else { - state = QIcon::Off; - } - - icon.paint(painter, rect, Qt::AlignCenter, mode, state); -} - -QSize SARibbonDrawHelper::iconActualSize(const QIcon& icon, const QStyleOption* opt, const QSize& iconSize) -{ - QIcon::Mode mode; - QIcon::State state; - - if (!(opt->state & QStyle::State_Enabled)) { - mode = QIcon::Disabled; - } else if ((opt->state & QStyle::State_MouseOver) && (opt->state & QStyle::State_AutoRaise)) { - mode = QIcon::Active; - } else { - mode = QIcon::Normal; - } - - if (opt->state & QStyle::State_Selected || opt->state & QStyle::State_On) { - state = QIcon::On; - } else { - state = QIcon::Off; - } - return (icon.actualSize(iconSize, mode, state)); -} - -void SARibbonDrawHelper::drawText(const QString& text, QStylePainter* painter, const QStyleOption* opt, Qt::Alignment al, int x, int y, int width, int height) -{ - painter->drawItemText(QRect(x, y, width, height), al, opt->palette, opt->state & QStyle::State_Enabled, text); -} - -void SARibbonDrawHelper::drawText(const QString& text, QStylePainter* painter, const QStyleOption* opt, Qt::Alignment al, const QRect& rect) -{ - painter->drawItemText(rect, al, opt->palette, opt->state & QStyle::State_Enabled, text); -} - -/*** End of inlined file: SARibbonDrawHelper.cpp ***/ - /*** Start of inlined file: SARibbonLineEdit.cpp ***/ #include @@ -4910,14 +4823,12 @@ void SARibbonButtonGroupWidget::actionEvent(QActionEvent* e) } layout()->addWidget(item.widget); d_ptr->mItems.append(item); - layout()->invalidate(); updateGeometry(); } break; case QEvent::ActionChanged: { // 让布局重新绘制 layout()->invalidate(); - updateGeometry(); } break; case QEvent::ActionRemoved: { @@ -4935,7 +4846,6 @@ void SARibbonButtonGroupWidget::actionEvent(QActionEvent* e) i = d_ptr->mItems.erase(i); } layout()->invalidate(); - updateGeometry(); } break; default: @@ -4948,6 +4858,7 @@ void SARibbonButtonGroupWidget::actionEvent(QActionEvent* e) /*** Start of inlined file: SARibbonStackedWidget.cpp ***/ #include +#include #include #include #include @@ -4960,7 +4871,6 @@ class SARibbonStackedWidget::PrivateData SA_RIBBON_DECLARE_PUBLIC(SARibbonStackedWidget) public: QEventLoop* eventLoop { nullptr }; - bool isAutoResize { true }; public: PrivateData(SARibbonStackedWidget* p) : q_ptr(p) @@ -5029,22 +4939,6 @@ void SARibbonStackedWidget::exec() d_ptr->eventLoop = nullptr; } -/** - * @brief 设置stacked管理的窗口会随着stacked的大小变化而变化大小 - * - * 默认为true - * @param autoresize - */ -void SARibbonStackedWidget::setAutoResize(bool autoresize) -{ - d_ptr->isAutoResize = autoresize; -} - -bool SARibbonStackedWidget::isAutoResize() const -{ - return (d_ptr->isAutoResize); -} - /** * @brief 类似tabbar的moveTab函数,交换两个窗口的index * @param from @@ -5072,6 +4966,18 @@ void SARibbonStackedWidget::hideEvent(QHideEvent* e) QStackedWidget::hideEvent(e); } +void SARibbonStackedWidget::resizeEvent(QResizeEvent* e) +{ + QStackedWidget::resizeEvent(e); + for (int i = 0; i < count(); ++i) { + if (i == currentIndex()) { + continue; + } + QEvent* layE = new QEvent(QEvent::LayoutRequest); + QApplication::postEvent(widget(i), layE); + } +} + /*** End of inlined file: SARibbonStackedWidget.cpp ***/ /*** Start of inlined file: SARibbonSeparatorWidget.cpp ***/ @@ -5127,7 +5033,8 @@ void SARibbonSeparatorWidget::paintEvent(QPaintEvent* event) #include #include #include - +#include +#include /** * @brief The SARibbonCtrlContainerPrivate class */ @@ -5238,8 +5145,14 @@ bool SARibbonCtrlContainer::hasContainerWidget() const */ void SARibbonCtrlContainer::setIcon(const QIcon& i) { - d_ptr->icon = i; - d_ptr->labelPixmap->setPixmap(i.pixmap(d_ptr->iconSize)); + d_ptr->icon = i; + QPixmap pixmap = i.pixmap(d_ptr->iconSize); + d_ptr->labelPixmap->setPixmap(pixmap); +} + +void SARibbonCtrlContainer::setIcon(const QPixmap& pixmap) +{ + d_ptr->labelPixmap->setPixmap(pixmap); } /** @@ -5466,7 +5379,7 @@ SARibbonPannelItem::SARibbonPannelItem(QWidget* widget) bool SARibbonPannelItem::isEmpty() const { - return (action == 0 || !action->isVisible()); + return (action == nullptr || !action->isVisible()); } /*** End of inlined file: SARibbonPannelItem.cpp ***/ @@ -5474,9 +5387,8 @@ bool SARibbonPannelItem::isEmpty() const /*** Start of inlined file: SARibbonPannelLayout.cpp ***/ #include #include -#include -#define SARibbonPannelLayout_DEBUG_PRINT 0 +#define SARibbonPannelLayout_DEBUG_PRINT 1 #define HELP_DRAW_RECT(p, rect) \ do { \ p.save(); \ @@ -5503,6 +5415,7 @@ SARibbonPannelLayout::SARibbonPannelLayout(QWidget* p) SARibbonPannelLayout::~SARibbonPannelLayout() { + // 参考QToolBarLayout while (!m_items.isEmpty()) { SARibbonPannelItem* item = m_items.takeFirst(); if (QWidgetAction* widgetAction = qobject_cast< QWidgetAction* >(item->action)) { @@ -5519,7 +5432,7 @@ SARibbonPannelLayout::~SARibbonPannelLayout() * @param action * @return 没有查到返回-1 */ -int SARibbonPannelLayout::indexOf(QAction* action) const +int SARibbonPannelLayout::indexByAction(QAction* action) const { for (int i = 0; i < m_items.count(); ++i) { if (m_items.at(i)->action == action) { @@ -5529,6 +5442,15 @@ int SARibbonPannelLayout::indexOf(QAction* action) const return (-1); } +/** + * @brief 获取ribbonpannel + * @return + */ +SARibbonPannel* SARibbonPannelLayout::ribbonPannel() const +{ + return qobject_cast< SARibbonPannel* >(parentWidget()); +} + void SARibbonPannelLayout::addItem(QLayoutItem* item) { Q_UNUSED(item); @@ -5590,6 +5512,7 @@ int SARibbonPannelLayout::count() const bool SARibbonPannelLayout::isEmpty() const { + return (m_items.isEmpty()); } @@ -5611,6 +5534,11 @@ QSize SARibbonPannelLayout::minimumSize() const QSize SARibbonPannelLayout::sizeHint() const { +#if SARibbonPannelLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT + if (SARibbonPannel* pannel = ribbonPannel()) { + qDebug() << "| |-SARibbonPannelLayout sizeHint,sizeHint = " << m_sizeHint; + } +#endif return (m_sizeHint); } @@ -5621,7 +5549,7 @@ QSize SARibbonPannelLayout::sizeHint() const */ SARibbonPannelItem* SARibbonPannelLayout::pannelItem(QAction* action) const { - int index = indexOf(action); + int index = indexByAction(action); if (index >= 0) { return (m_items[ index ]); @@ -5682,6 +5610,8 @@ void SARibbonPannelLayout::move(int from, int to) */ bool SARibbonPannelLayout::isDirty() const { + SARibbonPannelLayout* that = const_cast< SARibbonPannelLayout* >(this); + that->updateGeomArray(QRect()); return (m_dirty); } @@ -5712,8 +5642,6 @@ const QMargins& SARibbonPannelLayout::pannelContentsMargins() /** * @brief 全局的contentsMargins - * @note SARibbonStyleOption会用到此函数,调用设置函数后需要手动重新计算SARibbonStyleOption的内容,@sa SARibbonStyleOption::recalc - * @sa SARibbonStyleOption * @param m */ void SARibbonPannelLayout::setPannelContentsMargins(const QMargins& m) @@ -5726,37 +5654,33 @@ void SARibbonPannelLayout::setPannelContentsMargins(const QMargins& m) */ void SARibbonPannelLayout::layoutActions() { +#if SARibbonPannelLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT + if (SARibbonPannel* pannel = ribbonPannel()) { + qDebug() << "| |-SARibbonPannelLayout layoutActions,pannel name = " << pannel->pannelName(); + } +#endif if (m_dirty) { updateGeomArray(geometry()); } QList< QWidget* > showWidgets, hideWidgets; -#if SARibbonPannelLayout_DEBUG_PRINT - qDebug() << "\r\n\r\n ==============================================" - "\r\n SARibbonPannelLayout::layoutActions" - << " \r\n name:" << parentWidget()->windowTitle() << " sizehint:" << this->sizeHint(); -#endif for (SARibbonPannelItem* item : qAsConst(m_items)) { if (item->isEmpty()) { hideWidgets << item->widget(); } else { item->setGeometry(item->itemWillSetGeometry); - // item->widget()->setFixedSize(item->itemWillSetGeometry.size()); - // item->widget()->move(item->itemWillSetGeometry.topLeft()); showWidgets << item->widget(); -#if SARibbonPannelLayout_DEBUG_PRINT - qDebug() << "[" << item->rowIndex << "," << item->columnIndex << "]" - << " -> " << item->itemWillSetGeometry << ":" << item->widget()->metaObject()->className(); -#endif } } // 不在上面那里进行show和hide因为这会触发SARibbonPannelLayout的重绘,导致循环绘制,非常影响效率 for (QWidget* w : qAsConst(showWidgets)) { - w->show(); + if (!w->isVisible()) + w->show(); } for (QWidget* w : qAsConst(hideWidgets)) { - w->hide(); + if (w->isVisible()) + w->hide(); } } @@ -5792,6 +5716,9 @@ SARibbonPannelItem* SARibbonPannelLayout::createItem(QAction* action, SARibbonPa } else if (action->isSeparator()) { SARibbonSeparatorWidget* sep = RibbonSubElementDelegate->createRibbonSeparatorWidget(pannel); widget = sep; + auto t = action->property(SA_ActionPropertyName_SeparatorTop).toInt(); + auto b = action->property(SA_ActionPropertyName_SeparatorBottom).toInt(); + sep->setTopBottomMargins(t, b); } // 不是widget,自动生成SARibbonToolbutton if (!widget) { @@ -5802,6 +5729,9 @@ SARibbonPannelItem* SARibbonPannelLayout::createItem(QAction* action, SARibbonPa button->setFocusPolicy(Qt::NoFocus); button->setButtonType(buttonType); button->setDefaultAction(action); + // 属性设置 + QToolButton::ToolButtonPopupMode popMode = SARibbonPannel::getActionToolButtonPopupModeProperty(action); + button->setPopupMode(popMode); // 根据QAction的属性设置按钮的大小 QObject::connect(button, &SARibbonToolButton::triggered, pannel, &SARibbonPannel::actionTriggered); @@ -5828,9 +5758,6 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) return; } -#if SARibbonPannelLayout_DEBUG_PRINT - qDebug() << "SARibbonPannelLayout::updateGeomArray(" << setrect << "),pannel name = " << pannel->pannelName(); -#endif int height = setrect.height(); const QMargins& mag = pannelContentsMargins(); const int spacing = this->spacing(); @@ -5863,13 +5790,9 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) int itemCount = m_items.count(); -#if SARibbonPannelLayout_DEBUG_PRINT - qDebug() << "\r\n\r\n=============================================" - << "\r\nSARibbonPannelLayout::updateGeomArray()" - << " setrect:" << setrect << "\r\npannel name:" << pannel->windowTitle() - << "\r\n largeHeight:" << largeHeight << "\r\n smallHeight:" << smallHeight << "\r\n rowCount:" << rowCount; +#if SARibbonPannelLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT + QString debug_print__log__; #endif - // 本列第一、二行占比 SARibbonPannelItem::RowProportion thisColumnRP0 = SARibbonPannelItem::None; SARibbonPannelItem* lastGeomItem = nullptr; // 记录最后一个设置位置的item @@ -5877,17 +5800,22 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) SARibbonPannelItem* item = m_items.at(i); if (item->isEmpty()) { // 如果是hide就直接跳过 -#if SARibbonPannelLayout_DEBUG_PRINT - qDebug() << item->widget()->metaObject()->className() << "is hide" - << " row:" << row << " col:" << column; -#endif item->rowIndex = -1; item->columnIndex = -1; continue; } QSize hint = item->sizeHint(); - +#if SARibbonPannelLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT + if (SARibbonToolButton* tb = qobject_cast< SARibbonToolButton* >(item->widget())) { + auto ss__ = tb->sizeHint(); + debug_print__log__ += QString("| | |-[%1]SARibbonToolButton.sizeHint=(%2,%3),ButtonText=%4\n") + .arg(i) + .arg(ss__.width()) + .arg(ss__.height()) + .arg(tb->text()); + } +#endif Qt::Orientations exp = item->expandingDirections(); if (item->widget()) { // 有窗口是水平扩展,则标记为扩展 @@ -5912,8 +5840,6 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) if (row != 0) { x += (columMaxWidth + spacing); ++column; - row = 0; - columMaxWidth = 0; } // item->rowIndex = 0; @@ -6051,11 +5977,6 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) break; } lastGeomItem = item; -#if SARibbonPannelLayout_DEBUG_PRINT - qDebug() << item->widget()->metaObject()->className() << " rp:" << rp << " row:" << item->rowIndex - << " col:" << item->columnIndex << " new row:" << row << " new column:" << column - << " itemWillSetGeometry:" << item->itemWillSetGeometry << " sizeHint:" << hint << " x:" << x; -#endif } // 最后一个元素,更新列数 // 2022-06-20 此句本来在循环里面,如果最后一个元素隐藏,会导致无法到达此判断导致异常 @@ -6063,13 +5984,13 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) if (lastGeomItem->columnIndex != column) { // 说明最后一个元素处于最后位置,触发了换列,此时真实列数需要减1,直接等于column索引 m_columnCount = column; - // 由于最后一个元素触发了换列,x值是新一列的位置,直接作为totalWidth - totalWidth = x + mag.right(); + // 由于最后一个元素触发了换列,x值是新一列的位置,直接作为totalWidth要减去已经加入的spacing + totalWidth = x - spacing + mag.right(); } else { // 说明最后一个元素处于非最后位置,没有触发下一个换列,此时真实列数等于column索引+1 m_columnCount = column + 1; // 由于最后一个元素未触发换列,需要计算totalWidth - totalWidth = x + columMaxWidth + spacing + mag.right(); + totalWidth = x + columMaxWidth + mag.right(); } } // 在有optionButton情况下,的2行模式,需要调整totalWidth @@ -6078,14 +5999,24 @@ void SARibbonPannelLayout::updateGeomArray(const QRect& setrect) totalWidth += pannel->optionActionButtonSize().width(); } } + this->m_sizeHint = QSize(totalWidth, height); // 在设置完所有窗口后,再设置扩展属性的窗口 - if (totalWidth < setrect.width()) { + if (totalWidth < setrect.width() && (setrect.width() - totalWidth) > 10) { // 说明可以设置扩展属性的窗口 recalcExpandGeomArray(setrect); } - this->m_sizeHint = QSize(totalWidth, height); -#if SARibbonPannelLayout_DEBUG_PRINT - qDebug() << "SARibbonPannelLayout::updateGeomArray,m_sizeHint=" << m_sizeHint; +#if SARibbonPannelLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "| |-SARibbonPannelLayout updateGeomArray(" << setrect << "),pannel name = " << pannel->pannelName() + << "\n| | |-size hint =" << this->m_sizeHint // + << "\n| | |-totalWidth=" << totalWidth // + << "\n| | |-last x=" << x // + << "\n| | |-columMaxWidth=" << columMaxWidth // + << "\n| | |-spacing=" << spacing // + << "\n| | |-mag=" << mag // + << "\n| | |-largeHeight=" << largeHeight // + << "\n| | |-smallHeight=" << smallHeight // + ; + qDebug().noquote() << debug_print__log__; #endif } @@ -6171,6 +6102,12 @@ void SARibbonPannelLayout::recalcExpandGeomArray(const QRect& setrect) } } } +#if SARibbonPannelLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "| |-SARibbonPannelLayout recalcExpandGeomArray(" << setrect + << ") pannelName=" << ribbonPannel()->pannelName() // + << ",expandwidth=" << expandwidth // + ; +#endif } /** @@ -6219,9 +6156,16 @@ void SARibbonPannelLayout::columnWidthInfo(int colindex, int& width, int& maximu void SARibbonPannelLayout::setGeometry(const QRect& rect) { + QRect old = geometry(); + if (old == rect) { + return; + } +#if SARibbonPannelLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "| |----->SARibbonPannelLayout.setGeometry(" << rect << "(" << ribbonPannel()->pannelName() << ")======="; +#endif + QLayout::setGeometry(rect); m_dirty = false; updateGeomArray(rect); - QLayout::setGeometry(rect); layoutActions(); } @@ -6339,10 +6283,8 @@ SARibbonPannel::~SARibbonPannel() */ void SARibbonPannel::setActionRowProportionProperty(QAction* action, SARibbonPannelItem::RowProportion rp) { - if (action == nullptr) { - return; - } - action->setProperty(SARibbonPannelItemRowProportionPropertyName, int(rp)); + Q_CHECK_PTR(action); + action->setProperty(SA_ActionPropertyName_RowProportion, static_cast< int >(rp)); } /** @@ -6353,7 +6295,7 @@ void SARibbonPannel::setActionRowProportionProperty(QAction* action, SARibbonPan SARibbonPannelItem::RowProportion SARibbonPannel::getActionRowProportionProperty(QAction* action) { bool isok = false; - int r = action->property(SARibbonPannelItemRowProportionPropertyName).toInt(&isok); + int r = action->property(SA_ActionPropertyName_RowProportion).toInt(&isok); if (isok) { return (static_cast< SARibbonPannelItem::RowProportion >(r)); @@ -6362,93 +6304,109 @@ SARibbonPannelItem::RowProportion SARibbonPannel::getActionRowProportionProperty } /** - * @brief 设置action的行行为,行属性决定了ribbon pannel的显示方式 - * @param action 需要设置的action,此action必须已经被pannel添加过 - * @param rp 行为 + * @brief 设置action的ToolButtonPopupMode属性 + * @param action + * @param popMode */ -void SARibbonPannel::setActionRowProportion(QAction* action, SARibbonPannelItem::RowProportion rp) +void SARibbonPannel::setActionToolButtonPopupModeProperty(QAction* action, QToolButton::ToolButtonPopupMode popMode) { - if (action == nullptr) { - return; - } - setActionRowProportionProperty(action, rp); - if (SARibbonPannelLayout* lay = pannelLayout()) { - SARibbonPannelItem* it = lay->pannelItem(action); - if (it) { - it->rowProportion = rp; - lay->invalidate(); - } + Q_CHECK_PTR(action); + action->setProperty(SA_ActionPropertyName_ToolButtonPopupMode, static_cast< int >(popMode)); +} + +/** + * @brief 获取action的ToolButtonPopupMode属性 + * @param action + * @return + */ +QToolButton::ToolButtonPopupMode SARibbonPannel::getActionToolButtonPopupModeProperty(QAction* action) +{ + bool isok = false; + int r = action->property(SA_ActionPropertyName_ToolButtonPopupMode).toInt(&isok); + + if (isok) { + return (static_cast< QToolButton::ToolButtonPopupMode >(r)); } + return (QToolButton::InstantPopup); } /** * @brief 添加action - * @param action action + * + * action实际对应了一个toolbutton,如果想找到对应的toolbutton,使用@ref actionToRibbonToolButton + * @param action * @param rp 指定action的行占比 - * @return 返回对应的SARibbonToolButton,如果是窗口,返回的toolbutton为nullptr + * @param popMode 菜单弹出样式 */ -SARibbonToolButton* SARibbonPannel::addAction(QAction* action, SARibbonPannelItem::RowProportion rp) +void SARibbonPannel::addAction(QAction* action, SARibbonPannelItem::RowProportion rp) { - if (action == nullptr) { - return nullptr; - } + Q_CHECK_PTR(action); setActionRowProportionProperty(action, rp); addAction(action); - - return (d_ptr->lastAddActionButton()); } /** - * @brief 添加大图标 - * - * @param action - * @sa 如果想获取actiom对应的SARibbonToolButton,可以使用@ref actionToRibbonToolButton 函数 + * @brief 添加一个action + * @param act + * @param popMode 按钮的样式 + * @param rp action在pannel中的占位情况,默认是大图标 */ -SARibbonToolButton* SARibbonPannel::addLargeAction(QAction* action) +void SARibbonPannel::addAction(QAction* act, QToolButton::ToolButtonPopupMode popMode, SARibbonPannelItem::RowProportion rp) { - return (addAction(action, SARibbonPannelItem::Large)); + Q_CHECK_PTR(act); + setActionRowProportionProperty(act, rp); + setActionToolButtonPopupModeProperty(act, popMode); + addAction(act); } /** - * @brief 在三栏模式下,强制加为2栏action - * @note 在两行模式下,Medium和Small等价 - * 主要应用在ThreeRowMode下 - * @param action - * @sa 如果想获取actiom对应的SARibbonToolButton,可以使用@ref actionToRibbonToolButton 函数 + @brief 添加大图标 + + action实际对应了一个toolbutton,如果想找到对应的toolbutton,使用@ref actionToRibbonToolButton + @param action */ -SARibbonToolButton* SARibbonPannel::addMediumAction(QAction* action) +void SARibbonPannel::addLargeAction(QAction* action) { - return (addAction(action, SARibbonPannelItem::Medium)); + addAction(action, SARibbonPannelItem::Large); } /** - * @brief 添加小图标 - * @param action - * @sa 如果想获取actiom对应的SARibbonToolButton,可以使用@ref actionToRibbonToolButton 函数 + @brief 在三栏模式下,强制加为2栏action + @note 在两行模式下,Medium和Small等价 + 主要应用在ThreeRowMode下 + + action实际对应了一个toolbutton,如果想找到对应的toolbutton,使用@ref actionToRibbonToolButton + @param action */ -SARibbonToolButton* SARibbonPannel::addSmallAction(QAction* action) +void SARibbonPannel::addMediumAction(QAction* action) { - return (addAction(action, SARibbonPannelItem::Small)); + addAction(action, SARibbonPannelItem::Medium); } /** - * @brief 添加一个action - * @param act - * @param popMode 按钮的样式 - * @param rp action在pannel中的占位情况,默认是大图标 + @brief 添加小图标 + + action实际对应了一个toolbutton,如果想找到对应的toolbutton,使用@ref actionToRibbonToolButton + @param action */ -void SARibbonPannel::addAction(QAction* act, QToolButton::ToolButtonPopupMode popMode, SARibbonPannelItem::RowProportion rp) +void SARibbonPannel::addSmallAction(QAction* action) { - if (act == nullptr) { - return; - } - setActionRowProportionProperty(act, rp); - addAction(act); - SARibbonToolButton* btn = d_ptr->lastAddActionButton(); + addAction(action, SARibbonPannelItem::Small); +} - if (btn) { - btn->setPopupMode(popMode); - } +void SARibbonPannel::addSmallAction(QAction* action, QToolButton::ToolButtonPopupMode popMode) +{ + addAction(action, popMode, SARibbonPannelItem::Small); +} + +void SARibbonPannel::addLargeAction(QAction* action, QToolButton::ToolButtonPopupMode popMode) +{ + addAction(action, popMode, SARibbonPannelItem::Large); +} + +void SARibbonPannel::addMediumAction(QAction* action, QToolButton::ToolButtonPopupMode popMode) +{ + addAction(action, popMode, SARibbonPannelItem::Medium); } /** @@ -6479,57 +6437,21 @@ QAction* SARibbonPannel::addAction(const QString& text, const QIcon& icon, QTool * @param popMode,菜单弹出模式,默认InstantPopup模式 * @return */ -SARibbonToolButton* SARibbonPannel::addMenu(QMenu* menu, SARibbonPannelItem::RowProportion rp, QToolButton::ToolButtonPopupMode popMode) +void SARibbonPannel::addMenu(QMenu* menu, SARibbonPannelItem::RowProportion rp, QToolButton::ToolButtonPopupMode popMode) { - if (menu == nullptr) { - return nullptr; - } + Q_CHECK_PTR(menu); QAction* action = menu->menuAction(); - - addAction(action, rp); - SARibbonToolButton* btn = d_ptr->lastAddActionButton(); - - btn->setPopupMode(popMode); - return (btn); -} - -/** - * @brief 添加一个ActionMenu - * @param action - * @param menu - * @param rp - * @return - */ -SARibbonToolButton* SARibbonPannel::addActionMenu(QAction* action, QMenu* menu, SARibbonPannelItem::RowProportion rp) -{ - SARibbonToolButton* btn = addAction(action, rp); - if (nullptr == btn) { - return nullptr; - } - btn->setMenu(menu); - btn->setPopupMode(QToolButton::MenuButtonPopup); - return (btn); -} - -/** - * @brief 添加action menu,action menu是一个特殊的menu,即可点击触发action,也可弹出菜单 - * @param action 点击触发的action,在pannel中,图标以此action的图标为准 - * @param menu 需要弹出的menu - * @return 返回 - */ -SARibbonToolButton* SARibbonPannel::addLargeActionMenu(QAction* action, QMenu* menu) -{ - return (addActionMenu(action, menu, SARibbonPannelItem::Large)); + addAction(action, popMode, rp); } -SARibbonToolButton* SARibbonPannel::addLargeMenu(QMenu* menu, QToolButton::ToolButtonPopupMode popMode) +void SARibbonPannel::addLargeMenu(QMenu* menu, QToolButton::ToolButtonPopupMode popMode) { - return (addMenu(menu, SARibbonPannelItem::Large, popMode)); + addMenu(menu, SARibbonPannelItem::Large, popMode); } -SARibbonToolButton* SARibbonPannel::addSmallMenu(QMenu* menu, QToolButton::ToolButtonPopupMode popMode) +void SARibbonPannel::addSmallMenu(QMenu* menu, QToolButton::ToolButtonPopupMode popMode) { - return (addMenu(menu, SARibbonPannelItem::Small, popMode)); + addMenu(menu, SARibbonPannelItem::Small, popMode); } /** @@ -6586,13 +6508,14 @@ QAction* SARibbonPannel::addLargeWidget(QWidget* w) * @return * @note SARibbonPannel将拥有SARibbonGallery的管理权 */ -SARibbonGallery* SARibbonPannel::addGallery() +SARibbonGallery* SARibbonPannel::addGallery(bool expanding) { SARibbonGallery* gallery = RibbonSubElementDelegate->createRibbonGallery(this); addWidget(gallery, SARibbonPannelItem::Large); - - setExpanding(); + if (expanding) { + setExpanding(expanding); + } return (gallery); } @@ -6607,14 +6530,9 @@ QAction* SARibbonPannel::addSeparator(int top, int bottom) action->setSeparator(true); setActionRowProportionProperty(action, SARibbonPannelItem::Large); + action->setProperty(SA_ActionPropertyName_SeparatorTop, top); + action->setProperty(SA_ActionPropertyName_SeparatorBottom, bottom); addAction(action); - if (SARibbonPannelLayout* lay = pannelLayout()) { - QWidget* w = lay->lastWidget(); - SARibbonSeparatorWidget* sep = qobject_cast< SARibbonSeparatorWidget* >(w); - if (sep) { - sep->setTopBottomMargins(top, bottom); - } - } return (action); } @@ -6625,18 +6543,31 @@ QAction* SARibbonPannel::addSeparator(int top, int bottom) */ SARibbonToolButton* SARibbonPannel::actionToRibbonToolButton(QAction* action) { - SARibbonPannelLayout* lay = qobject_cast< SARibbonPannelLayout* >(layout()); - - if (lay) { - int index = lay->indexOf(action); - if (index == -1) { - return (nullptr); +#if 0 + SARibbonPannelLayout* lay = qobject_cast< SARibbonPannelLayout* >(layout()); + + if (lay) { + int index = lay->indexOf(action); + if (index == -1) { + return (nullptr); + } + QLayoutItem* item = lay->takeAt(index); + SARibbonToolButton* btn = qobject_cast< SARibbonToolButton* >(item ? item->widget() : nullptr); + return (btn); + } + return (nullptr); +#else + for (auto obj : qAsConst(children())) { + if (obj->isWidgetType()) { + if (SARibbonToolButton* btn = qobject_cast< SARibbonToolButton* >(obj)) { + if (btn->defaultAction() == action) { + return btn; + } + } } - QLayoutItem* item = lay->takeAt(index); - SARibbonToolButton* btn = qobject_cast< SARibbonToolButton* >(item ? item->widget() : nullptr); - return (btn); } return (nullptr); +#endif } /** @@ -6663,13 +6594,12 @@ QList< SARibbonToolButton* > SARibbonPannel::ribbonToolButtons() const */ void SARibbonPannel::setPannelLayoutMode(SARibbonPannel::PannelLayoutMode mode) { - // 不做相同判断,这样可以进行强制布局 - // if (d_ptr->m_pannelLayoutMode == mode) { - // return; - // } + if (d_ptr->m_pannelLayoutMode == mode) { + return; + } d_ptr->m_pannelLayoutMode = mode; - resetLayout(mode); resetLargeToolButtonStyle(); + resetLayout(mode); } SARibbonPannel::PannelLayoutMode SARibbonPannel::pannelLayoutMode() const @@ -6711,7 +6641,7 @@ bool SARibbonPannel::isHaveOptionAction() const return (d_ptr->m_optionActionButton != nullptr); } -void SARibbonPannel::paintEvent(QPaintEvent* event) +void SARibbonPannel::paintEvent(QPaintEvent* e) { QPainter p(this); @@ -6739,25 +6669,29 @@ void SARibbonPannel::paintEvent(QPaintEvent* event) } } - QWidget::paintEvent(event); + QWidget::paintEvent(e); } QSize SARibbonPannel::sizeHint() const { - QSize laySize = layout()->sizeHint(); - int maxWidth = laySize.width() + 2; - - if (ThreeRowMode == pannelLayoutMode()) { - // 三行模式 - QFontMetrics fm = fontMetrics(); - QSize titleSize = fm.size(Qt::TextShowMnemonic, pannelName()); - if (d_ptr->m_optionActionButton) { - // optionActionButton的宽度需要预留 - titleSize.setWidth(titleSize.width() + d_ptr->m_optionActionButton->width() + 4); + int shWidth = 500; + int shHeight = 80; + if (QLayout* lay = layout()) { + QSize laySize = layout()->sizeHint(); + shWidth = laySize.width(); + shHeight = laySize.height(); + if (ThreeRowMode == pannelLayoutMode()) { + // 三行模式 + QFontMetrics fm = fontMetrics(); + QSize titleSize = fm.size(Qt::TextShowMnemonic, pannelName()); + if (d_ptr->m_optionActionButton) { + // optionActionButton的宽度需要预留 + titleSize.setWidth(titleSize.width() + d_ptr->m_optionActionButton->width() + 4); + } + shWidth = qMax(shWidth, titleSize.width()); } - maxWidth = qMax(maxWidth, titleSize.width()); } - return (QSize(maxWidth, laySize.height())); + return QSize(shWidth, shHeight); } QSize SARibbonPannel::minimumSizeHint() const @@ -6811,7 +6745,7 @@ QSize SARibbonPannel::optionActionButtonSize() const int SARibbonPannel::actionIndex(QAction* act) const { if (SARibbonPannelLayout* lay = pannelLayout()) { - return (lay->indexOf(act)); + return (lay->indexByAction(act)); } return (-1); } @@ -6885,8 +6819,6 @@ int SARibbonPannel::pannelTitleHeight() /** * @brief 设置pannel的全局高度,此函数是个全局的影响 - * @note SARibbonStyleOption会用到此函数,调用设置函数后需要手动重新计算SARibbonStyleOption的内容,@sa SARibbonStyleOption::recalc - * @sa SARibbonStyleOption * @param h */ void SARibbonPannel::setPannelTitleHeight(int h) @@ -6908,21 +6840,46 @@ SARibbonPannelLayout* SARibbonPannel::pannelLayout() const */ void SARibbonPannel::updateItemGeometry() { +#if SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "SARibbonPannel updateItemGeometry,pannelName=" << pannelName(); +#endif if (QLayout* lay = layout()) { lay->invalidate(); } - updateGeometry(); - QResizeEvent* e = new QResizeEvent(size(), QSize()); - QApplication::postEvent(this, e); +} + +/** + @brief 获取category指针,如果没有parent,或者不在category管理,返回nullptr + @return + */ +SARibbonCategory* SARibbonPannel::category() const +{ + return qobject_cast< SARibbonCategory* >(parent()); +} + +/** + @brief 获取ribbonBar指针,如果没有返回nullptr + @return + */ +SARibbonBar* SARibbonPannel::ribbonBar() const +{ + if (SARibbonCategory* c = category()) { + return c->ribbonBar(); + } + return nullptr; } void SARibbonPannel::resetLayout(PannelLayoutMode newmode) { Q_UNUSED(newmode); - if (QLayout* ly = layout()) { - ly->invalidate(); - layout()->setSpacing(TwoRowMode == newmode ? 4 : 2); - updateGeometry(); // 通知layout进行重新布局 +#if SARibbonPannel_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "SARibbonPannel resetLayout,pannelName=" << pannelName(); +#endif + if (ribbonBar()) { + if (QLayout* ly = layout()) { + layout()->setSpacing(TwoRowMode == newmode ? 4 : 2); + ly->invalidate(); + } } } @@ -6938,11 +6895,30 @@ void SARibbonPannel::resetLargeToolButtonStyle() continue; } b->updateRect(); - b->repaint(); } } -void SARibbonPannel::resizeEvent(QResizeEvent* event) +bool SARibbonPannel::event(QEvent* e) +{ +#if SA_DEBUG_PRINT_EVENT + if (e->type() != QEvent::Paint) { + qDebug() << "SARibbonPannel event(" << e->type() << "),name=" << pannelName(); + } +#endif + // if (SARibbonPannelLayout* lay = pannelLayout()) { + // if (lay->isDirty() && e->type() == QEvent::LayoutRequest) { + // if (QWidget* parw = parentWidget()) { + // if (QLayout* pl = parw->layout()) { + // pl->invalidate(); + // } + // } + // lay->m_dirty = false; + // } + // } + return QWidget::event(e); +} + +void SARibbonPannel::resizeEvent(QResizeEvent* e) { //! 1.移动操作按钮到角落 if (d_ptr->m_optionActionButton) { @@ -6957,7 +6933,7 @@ void SARibbonPannel::resizeEvent(QResizeEvent* event) } //! 2.resize后,重新设置分割线的高度 //! 由于分割线在布局中,只要分割线足够高就可以,不需要重新设置 - return (QWidget::resizeEvent(event)); + return (QWidget::resizeEvent(e)); } /** @@ -6992,32 +6968,27 @@ void SARibbonPannel::actionEvent(QActionEvent* e) int index = layout()->count(); if (e->before()) { // 说明是插入 - index = lay->indexOf(action); + index = lay->indexByAction(e->before()); if (-1 == index) { index = layout()->count(); // 找不到的时候就插入到最后 } } lay->insertAction(index, action, getActionRowProportionProperty(action)); // 由于pannel的尺寸发生变化,需要让category也调整 - if (QWidget* parw = parentWidget()) { - if (QLayout* pl = parw->layout()) { - pl->invalidate(); - } - } + // if (QWidget* parw = parentWidget()) { + // if (QLayout* pl = parw->layout()) { + // pl->invalidate(); + // } + // } } break; case QEvent::ActionChanged: { // 让布局重新绘制 layout()->invalidate(); - updateGeometry(); + + // updateGeometry(); // 由于pannel的尺寸发生变化,需要让category也调整 if (QWidget* parw = parentWidget()) { -#if SARibbonPannel_DEBUG_PRINT - if (SARibbonCategory* category = qobject_cast< SARibbonCategory* >(parw)) { - qDebug() << "pannel (" << pannelName() << ") action(" << action->text() << ") Changed,at category" - << category->categoryName(); - } -#endif if (QLayout* pl = parw->layout()) { pl->invalidate(); } @@ -7026,32 +6997,31 @@ void SARibbonPannel::actionEvent(QActionEvent* e) //! 重打印信息上看,pannel的尺寸有进行更新,category的尺寸也进行了更新,但更新的次数和调用invalidate的次数不一样,需要手动触发ResizeEvent //! 尝试过调用QEvent::LayoutRequest没有效果: //! @code - //! QEvent* e = new QEvent(QEvent::LayoutRequest); - //! QApplication::postEvent(parw, e); + //! QEvent* el = new QEvent(QEvent::LayoutRequest); + //! QApplication::postEvent(parw, el); //! @endcode //! //! 调用parw->updateGeometry();也没有效果,目前看使用resizeevent是最有效果的 //! - parw->updateGeometry(); - QResizeEvent* e = new QResizeEvent(parw->size(), QSize()); - QApplication::postEvent(parw, e); + QResizeEvent* ersize = new QResizeEvent(parw->size(), QSize()); + QApplication::postEvent(parw, ersize); } } break; case QEvent::ActionRemoved: { SARibbonPannelLayout* lay = pannelLayout(); action->disconnect(this); - int index = lay->indexOf(action); + int index = lay->indexByAction(action); if (index != -1) { QLayoutItem* item = lay->takeAt(index); delete item; } // 由于pannel的尺寸发生变化,需要让category也调整 - if (QWidget* parw = parentWidget()) { - if (QLayout* pl = parw->layout()) { - pl->invalidate(); - } - } + // if (QWidget* parw = parentWidget()) { + // if (QLayout* pl = parw->layout()) { + // pl->invalidate(); + // } + // } } break; default: @@ -7077,8 +7047,8 @@ void SARibbonPannel::changeEvent(QEvent* e) if (QLayout* lay = layout()) { lay->invalidate(); } - QWidget::changeEvent(e); } + QWidget::changeEvent(e); } /** @@ -7099,7 +7069,6 @@ const QList< SARibbonPannelItem* >& SARibbonPannel::ribbonPannelItem() const #include #include #include - #include #include #include @@ -7125,7 +7094,6 @@ class SARibbonCategory::PrivateData // 移除Pannel,Category会直接回收SARibbonPannel内存 bool removePannel(SARibbonPannel* pannel); - void setBackgroundBrush(const QBrush& brush); SARibbonCategory* ribbonCategory(); const SARibbonCategory* ribbonCategory() const; void setRibbonPannelLayoutMode(SARibbonPannel::PannelLayoutMode m); @@ -7143,7 +7111,6 @@ class SARibbonCategory::PrivateData bool mIsContextCategory { false }; ///< 标记是否是上下文标签 bool mIsCanCustomize { true }; ///< 标记是否可以自定义 SARibbonPannel::PannelLayoutMode mDefaultPannelLayoutMode { SARibbonPannel::ThreeRowMode }; - SARibbonBar* mBar { nullptr }; }; SARibbonCategory::PrivateData::PrivateData(SARibbonCategory* p) : q_ptr(p) { @@ -7187,10 +7154,9 @@ void SARibbonCategory::PrivateData::insertPannel(int index, SARibbonPannel* pann pannel->setParent(q_ptr); } pannel->setPannelLayoutMode(ribbonPannelLayoutMode()); - pannel->installEventFilter(q_ptr); index = qMax(0, index); index = qMin(lay->pannelCount(), index); - lay->addPannel(pannel); + lay->insertPannel(index, pannel); pannel->setVisible(true); } @@ -7213,14 +7179,6 @@ bool SARibbonCategory::PrivateData::removePannel(SARibbonPannel* pannel) return (false); } -void SARibbonCategory::PrivateData::setBackgroundBrush(const QBrush& brush) -{ - QPalette p = ribbonCategory()->palette(); - - p.setBrush(QPalette::Window, brush); - ribbonCategory()->setPalette(p); -} - QList< SARibbonPannel* > SARibbonCategory::PrivateData::pannelList() { if (SARibbonCategoryLayout* lay = q_ptr->categoryLayout()) { @@ -7251,10 +7209,10 @@ const SARibbonCategory* SARibbonCategory::PrivateData::ribbonCategory() const */ void SARibbonCategory::PrivateData::setRibbonPannelLayoutMode(SARibbonPannel::PannelLayoutMode m) { - // 不做相同判断,这样可以通过此函数强制重新布局 - // if (mDefaultPannelLayoutMode == m) { - // return; - // } + if (mDefaultPannelLayoutMode == m) { + return; + } + mDefaultPannelLayoutMode = m; QList< SARibbonPannel* > ps = pannelList(); @@ -7271,9 +7229,11 @@ SARibbonPannel::PannelLayoutMode SARibbonCategory::PrivateData::ribbonPannelLayo void SARibbonCategory::PrivateData::updateItemGeometry() { +#if SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "SARibbonCategory::PrivateData::updateItemGeometry,categoryName=" << q_ptr->categoryName(); +#endif if (SARibbonCategoryLayout* lay = qobject_cast< SARibbonCategoryLayout* >(q_ptr->layout())) { lay->invalidate(); - lay->doLayout(); } return; } @@ -7321,12 +7281,14 @@ void SARibbonCategory::PrivateData::doWheelEvent(QWheelEvent* event) SARibbonCategory::SARibbonCategory(QWidget* p) : QWidget(p), d_ptr(new SARibbonCategory::PrivateData(this)) { + setAttribute(Qt::WA_StyledBackground); setLayout(new SARibbonCategoryLayout(this)); } SARibbonCategory::SARibbonCategory(const QString& name, QWidget* p) : QWidget(p), d_ptr(new SARibbonCategory::PrivateData(this)) { + setAttribute(Qt::WA_StyledBackground); setLayout(new SARibbonCategoryLayout(this)); setCategoryName(name); } @@ -7365,6 +7327,16 @@ void SARibbonCategory::setRibbonPannelLayoutMode(SARibbonPannel::PannelLayoutMod d_ptr->setRibbonPannelLayoutMode(m); } +bool SARibbonCategory::event(QEvent* e) +{ +#if SA_DEBUG_PRINT_EVENT + if (e->type() != QEvent::Paint) { + qDebug() << "SARibbonCategory event(" << e->type() << "),name=" << categoryName(); + } +#endif + return QWidget::event(e); +} + SARibbonPannel::PannelLayoutMode SARibbonCategory::ribbonPannelLayoutMode() const { return (d_ptr->ribbonPannelLayoutMode()); @@ -7534,15 +7506,6 @@ bool SARibbonCategory::removePannel(int index) return (removePannel(p)); } -/// -/// \brief SARibbonCategory::setBackgroundBrush -/// \param brush -/// -void SARibbonCategory::setBackgroundBrush(const QBrush& brush) -{ - d_ptr->setBackgroundBrush(brush); -} - /** * @brief 返回Category下的所有pannel * @return @@ -7554,10 +7517,10 @@ QList< SARibbonPannel* > SARibbonCategory::pannelList() const QSize SARibbonCategory::sizeHint() const { - if (QLayout* lay = layout()) { + if (SARibbonCategoryLayout* lay = categoryLayout()) { return lay->sizeHint(); } - return QSize(500, 200); + return QSize(1000, 100); } /** @@ -7605,7 +7568,18 @@ void SARibbonCategory::setCanCustomize(bool b) */ SARibbonBar* SARibbonCategory::ribbonBar() const { - return (d_ptr->mBar); + // 第一个par是stackwidget + if (QWidget* par = parentWidget()) { + // 理论此时是ribbonbar + par = par->parentWidget(); + while (par) { + if (SARibbonBar* ribbon = qobject_cast< SARibbonBar* >(par)) { + return ribbon; + } + par = par->parentWidget(); + } + } + return nullptr; } /** @@ -7613,16 +7587,10 @@ SARibbonBar* SARibbonCategory::ribbonBar() const */ void SARibbonCategory::updateItemGeometry() { - QList< SARibbonPannel* > pannels = pannelList(); - for (SARibbonPannel* p : qAsConst(pannels)) { - p->updateItemGeometry(); - } - if (QLayout* lay = layout()) { - lay->invalidate(); - updateGeometry(); - QResizeEvent* e = new QResizeEvent(size(), QSize()); - QApplication::postEvent(this, e); - } +#if SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "SARibbonCategory name=" << categoryName() << " updateItemGeometry"; +#endif + d_ptr->updateItemGeometry(); } /** @@ -7650,32 +7618,6 @@ SARibbonAlignment SARibbonCategory::getCategoryAlignment() const return SARibbonAlignment::AlignLeft; } -bool SARibbonCategory::eventFilter(QObject* watched, QEvent* event) -{ - if (nullptr == watched) { - return (false); - } - SARibbonPannel* pannel = qobject_cast< SARibbonPannel* >(watched); - - if (pannel) { - switch (event->type()) { - case QEvent::HideToParent: { - // 隐藏和显示都要重新布局 - layout()->invalidate(); - } break; - - case QEvent::ShowToParent: { - // 隐藏和显示都要重新布局 - layout()->invalidate(); - } break; - - default: - break; - } - } - return (false); -} - /** * @brief 在超出边界情况下,滚轮可滚动pannel * @param event @@ -7685,6 +7627,35 @@ void SARibbonCategory::wheelEvent(QWheelEvent* event) d_ptr->doWheelEvent(event); } +void SARibbonCategory::changeEvent(QEvent* event) +{ + switch (event->type()) { + case QEvent::StyleChange: { + if (layout()) { +#if SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "SARibbonCategory changeEvent(StyleChange),categoryName=" << categoryName(); +#endif + layout()->invalidate(); + } + } break; + case QEvent::FontChange: { +#if SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "SARibbonCategory changeEvent(FontChange),categoryName=" << categoryName(); +#endif + QList< SARibbonPannel* > pannels = pannelList(); + for (SARibbonPannel* p : qAsConst(pannels)) { + p->setFont(font()); + } + if (layout()) { + layout()->invalidate(); + } + } break; + default: + break; + }; + return QWidget::changeEvent(event); +} + /** * @brief 标记这个是上下文标签 * @param isContextCategory @@ -7703,15 +7674,6 @@ SARibbonCategoryLayout* SARibbonCategory::categoryLayout() const return qobject_cast< SARibbonCategoryLayout* >(layout()); } -/** - * @brief 设置ribbonbar,此函数仅提供给ribbonbar调用 - * @param bar ribbonbar指针 - */ -void SARibbonCategory::setRibbonBar(SARibbonBar* bar) -{ - d_ptr->mBar = bar; -} - //=================================================== // SARibbonCategoryScrollButton //=================================================== @@ -7729,7 +7691,7 @@ SARibbonCategoryScrollButton::SARibbonCategoryScrollButton(Qt::ArrowType arr, QW #include #ifndef SARibbonCategoryLayout_DEBUG_PRINT -#define SARibbonCategoryLayout_DEBUG_PRINT 0 +#define SARibbonCategoryLayout_DEBUG_PRINT 1 #endif /** * @brief The SARibbonCategoryLayoutPrivate class @@ -7750,7 +7712,8 @@ class SARibbonCategoryLayout::PrivateData SARibbonCategoryScrollButton* mRightScrollBtn { nullptr }; ///< 在区域无法显示时显示的按钮 int mTotalWidth { 0 }; int mXBase { 0 }; - QSize mSizeHint { 50, 50 }; + QSize mSizeHint; + QSize mMinSizeHint; QList< SARibbonCategoryLayoutItem* > mItemList; SARibbonAlignment mCategoryAlignment { SARibbonAlignment::AlignLeft }; ///< 对齐方式 }; @@ -7771,16 +7734,27 @@ int SARibbonCategoryLayout::PrivateData::totalSizeHintWidth() const { int total = 0; QMargins mag = q_ptr->contentsMargins(); - +#if SA_DEBUG_PRINT_SIZE_HINT + int debug_i__ = 0; + QString debug_totalSizeHintWidth__; +#endif if (!mag.isNull()) { total += (mag.left() + mag.right()); } // 先计算总长 for (SARibbonCategoryLayoutItem* item : qAsConst(mItemList)) { if (item->isEmpty()) { - // 如果是hide就直接跳过 +// 如果是hide就直接跳过 +#if SARibbonCategoryLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT + ++debug_i__; + debug_totalSizeHintWidth__ += QString(" [%1](%2)is empty skip\n") + .arg(debug_i__) + .arg(item->toPannelWidget()->pannelName()); +#endif continue; } + // 这里要使用widget()->sizeHint(),因为pannel的标题会影总体布局,此处需要修改 + // TODO QSize pannelSize = item->widget()->sizeHint(); QSize SeparatorSize(0, 0); if (item->separatorWidget) { @@ -7788,7 +7762,21 @@ int SARibbonCategoryLayout::PrivateData::totalSizeHintWidth() const } total += pannelSize.width(); total += SeparatorSize.width(); +#if SARibbonCategoryLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT + ++debug_i__; + debug_totalSizeHintWidth__ += QString("|-[%1]pannelSize=(%2,%3),SeparatorSize=(%4,%5),name=(%6) \n") + .arg(debug_i__) + .arg(pannelSize.width()) + .arg(pannelSize.height()) + .arg(SeparatorSize.width()) + .arg(SeparatorSize.height()) + .arg(item->toPannelWidget()->pannelName()); +#endif } +#if SARibbonCategoryLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "SARibbonCategoryLayout.totalSizeHintWidth=" << total; + qDebug().noquote() << debug_totalSizeHintWidth__; +#endif return (total); } @@ -7810,7 +7798,7 @@ SARibbonCategoryLayout::SARibbonCategoryLayout(SARibbonCategory* parent) SARibbonCategoryLayout::~SARibbonCategoryLayout() { - while (QLayoutItem* item = takeAt(0)) { + while (auto item = takePannelItem(0)) { delete item; } } @@ -7847,13 +7835,14 @@ QLayoutItem* SARibbonCategoryLayout::itemAt(int index) const */ QLayoutItem* SARibbonCategoryLayout::takeAt(int index) { - return (takePannelItem(index)); + QLayoutItem* r = takePannelItem(index); + invalidate(); + return r; } SARibbonCategoryLayoutItem* SARibbonCategoryLayout::takePannelItem(int index) { if ((index >= 0) && (index < d_ptr->mItemList.size())) { - invalidate(); SARibbonCategoryLayoutItem* item = d_ptr->mItemList.takeAt(index); if (item->widget()) { item->widget()->hide(); @@ -7891,6 +7880,7 @@ bool SARibbonCategoryLayout::takePannel(SARibbonPannel* pannel) sp->deleteLater(); } delete i; + invalidate(); return true; } return false; @@ -7929,12 +7919,20 @@ void SARibbonCategoryLayout::insertPannel(int index, SARibbonPannel* pannel) QSize SARibbonCategoryLayout::sizeHint() const { + if (d_ptr->mSizeHint.isNull()) { + SARibbonCategoryLayout* that = const_cast< SARibbonCategoryLayout* >(this); + that->updateGeometryArr(); + } return (d_ptr->mSizeHint); } QSize SARibbonCategoryLayout::minimumSize() const { - return (d_ptr->mSizeHint); + if (d_ptr->mMinSizeHint.isNull()) { + SARibbonCategoryLayout* that = const_cast< SARibbonCategoryLayout* >(this); + that->updateGeometryArr(); + } + return (d_ptr->mMinSizeHint); } /** @@ -7972,11 +7970,10 @@ QSize SARibbonCategoryLayout::categoryContentSize() const */ void SARibbonCategoryLayout::updateGeometryArr() { - SARibbonCategory* category = qobject_cast< SARibbonCategory* >(parentWidget()); + SARibbonCategory* category = ribbonCategory(); if (nullptr == category) { return; } - int categoryWidth = category->width(); QMargins mag = contentsMargins(); int height = category->height(); @@ -7995,11 +7992,14 @@ void SARibbonCategoryLayout::updateGeometryArr() // 如果total < categoryWidth,m_d->mXBase可以设置为0 // 判断是否超过总长度 -#if SARibbonCategoryLayout_DEBUG_PRINT - qDebug() << "\r\n\r\n==========================(" << category->categoryName() << ")=======" - << "\r\nSARibbonCategoryLayout::updateGeometryArr" - << "\r\npannel name:" << category->windowTitle() << "\r\n height:" << height - << "\r\n first total:" << total << "\r\n y:" << y << "\r\n expandWidth:" << expandWidth; +#if SARibbonCategoryLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "SARibbonCategoryLayout::updateGeometryArr" + << "\n|-category name=" << category->categoryName() // + << "\n|-category height=" << height // + << "\n|-totalSizeHintWidth=" << total // + << "\n|-y=" << y // + << "\n|-expandWidth:" << expandWidth // + << "\n|-mag=" << mag; #endif if (total > categoryWidth) { // 超过总长度,需要显示滚动按钮 @@ -8067,7 +8067,7 @@ void SARibbonCategoryLayout::updateGeometryArr() qDebug() << "unknow widget in SARibbonCategoryLayout"; continue; } - p->layout()->update(); + // p->layout()->update(); QSize pannelSize = p->sizeHint(); QSize SeparatorSize(0, 0); if (item->separatorWidget) { @@ -8086,20 +8086,13 @@ void SARibbonCategoryLayout::updateGeometryArr() x += w; total += w; } - d_ptr->mTotalWidth = total; - QWidget* cp = category->parentWidget(); - int parentHeight = (nullptr == cp) ? height : cp->height(); - int parentWidth = (nullptr == cp) ? total : cp->width(); -#if SARibbonCategoryLayout_DEBUG_PRINT - qDebug() << "\r\n mSizeHint:[ " << parentHeight << "," << parentWidth << "]"; - for (int i = 0; i < d_ptr->mItemList.size(); ++i) { - qDebug() << "\r\n [ " << i << "] (pannel name=" << d_ptr->mItemList[ i ]->toPannelWidget()->pannelName() - << "),sizeHint=" << d_ptr->mItemList[ i ]->toPannelWidget()->sizeHint() - << "\r\n geo:" << d_ptr->mItemList[ i ]->mWillSetGeometry - << ", Separator geo:" << d_ptr->mItemList[ i ]->mWillSetSeparatorGeometry; - } + d_ptr->mTotalWidth = total; + d_ptr->mSizeHint = QSize(d_ptr->mTotalWidth, height); + d_ptr->mMinSizeHint = QSize(categoryWidth, height); +#if SARibbonCategoryLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "SARibbonCategoryLayout updateGeometryArr,SizeHint=" << d_ptr->mSizeHint + << ",Category name=" << category->categoryName(); #endif - d_ptr->mSizeHint = QSize(parentWidth, parentHeight); } /** @@ -8110,18 +8103,25 @@ void SARibbonCategoryLayout::doLayout() if (d_ptr->mDirty) { updateGeometryArr(); } - SARibbonCategory* category = qobject_cast< SARibbonCategory* >(parentWidget()); + SARibbonCategory* category = ribbonCategory(); // 两个滚动按钮的位置永远不变 d_ptr->mLeftScrollBtn->setGeometry(0, 0, 12, category->height()); d_ptr->mRightScrollBtn->setGeometry(category->width() - 12, 0, 12, category->height()); QList< QWidget* > showWidgets, hideWidgets; - +#if SARibbonCategoryLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT + int debug_i__(0); + qDebug() << "SARibbonCategoryLayout::doLayout(),name=" << category->categoryName(); +#endif for (SARibbonCategoryLayoutItem* item : qAsConst(d_ptr->mItemList)) { if (item->isEmpty()) { hideWidgets << item->widget(); if (item->separatorWidget) { hideWidgets << item->separatorWidget; } +#if SARibbonCategoryLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "|-[" << debug_i__ << "]pannelName(" << item->toPannelWidget()->pannelName() << ",will hide"; + ++debug_i__; +#endif } else { item->widget()->setFixedSize(item->mWillSetGeometry.size()); item->widget()->move(item->mWillSetGeometry.topLeft()); @@ -8131,10 +8131,11 @@ void SARibbonCategoryLayout::doLayout() item->separatorWidget->setGeometry(item->mWillSetSeparatorGeometry); showWidgets << item->separatorWidget; } -#ifdef SA_RIBBON_DEBUG_HELP_DRAW - qDebug() << "SARibbonCategoryLayout::doLayout() ="; - qDebug() << "\r\n pannel:" << item->widget()->windowTitle() << "\r\n pannel geo:" << item->mWillSetGeometry - << "\r\n sep geo:" << item->mWillSetSeparatorGeometry; +#if SARibbonCategoryLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "|-[" << debug_i__ << "]pannelName(" << item->toPannelWidget()->pannelName() + << "),willSetGeometry:" << item->mWillSetGeometry + << ",WillSetSeparatorGeometry:" << item->mWillSetSeparatorGeometry; + ++debug_i__; #endif } } @@ -8149,10 +8150,14 @@ void SARibbonCategoryLayout::doLayout() } // 不在上面那里进行show和hide因为这会触发SARibbonPannelLayout的重绘,导致循环绘制,非常影响效率 for (QWidget* w : qAsConst(showWidgets)) { - w->show(); + if (!w->isVisible()) { + w->show(); + } } for (QWidget* w : qAsConst(hideWidgets)) { - w->hide(); + if (w->isVisible()) { + w->hide(); + } } } @@ -8365,9 +8370,16 @@ void SARibbonCategoryLayout::onRightScrollButtonClicked() void SARibbonCategoryLayout::setGeometry(const QRect& rect) { + QRect old = geometry(); + if (old == rect) { + return; + } +#if SARibbonCategoryLayout_DEBUG_PRINT && SA_DEBUG_PRINT_SIZE_HINT + qDebug() << "===========SARibbonCategoryLayout.setGeometry(" << rect << "(" << ribbonCategory()->categoryName() << ")======="; +#endif + QLayout::setGeometry(rect); d_ptr->mDirty = false; updateGeometryArr(); - QLayout::setGeometry(rect); doLayout(); } //============================================================= @@ -9728,15 +9740,14 @@ class SARibbonBar::PrivateData QList< SARibbonContextCategory* > mContextCategoryList; ///< 存放所有的上下文标签 QList< _SARibbonTabData > mHidedCategory; int mIconRightBorderPosition; ///< 标题栏x值得最小值,在有图标和快捷启动按钮,此值都需要变化 - SARibbonControlButton* mMinimumCategoryButton; ///< 隐藏面板按钮 - SARibbonButtonGroupWidget* mRightButtonGroup; ///< 在tab bar右边的按钮群 - SARibbonQuickAccessBar* mQuickAccessBar; ///< 快速响应栏 - SARibbonBar::RibbonStyle mRibbonStyle; ///< ribbon的风格 - SARibbonBar::RibbonStyle mLastShowStyle; ///< ribbon的风格 - SARibbonBar::RibbonMode mCurrentRibbonMode; ///< 记录当前模式 - QSize mWindowButtonSize; ///< 由SARibbonMainWindow告诉的windowbutton的尺寸 - QList< QColor > mContextCategoryColorList; ///< contextCategory的色系 - int mContextCategoryColorListIndex; ///< 记录contextCategory色系索引 + QAction* mMinimumCategoryButtonAction; ///< 隐藏面板按钮action + SARibbonButtonGroupWidget* mRightButtonGroup; ///< 在tab bar右边的按钮群 + SARibbonQuickAccessBar* mQuickAccessBar; ///< 快速响应栏 + SARibbonBar::RibbonStyle mRibbonStyle; ///< ribbon的风格 + SARibbonBar::RibbonMode mCurrentRibbonMode; ///< 记录当前模式 + QSize mWindowButtonSize; ///< 由SARibbonMainWindow告诉的windowbutton的尺寸 + QList< QColor > mContextCategoryColorList; ///< contextCategory的色系 + int mContextCategoryColorListIndex; ///< 记录contextCategory色系索引 QColor mTitleTextColor; ///< 标题文字颜色,默认无效,无效的情况下和SARibbonBar的qss:color属性一致 QColor mTabBarBaseLineColor; ///< tabbar 底部会绘制一条线条,定义线条颜色 Qt::Alignment mTitleAligment; ///< 标题对齐方式 @@ -9744,6 +9755,8 @@ class SARibbonBar::PrivateData bool mEnableUserDefineAccessBarIconSize; ///< 允许用户自定义AccessBar的IconSize bool mEnableUserDefineRightBarIconSize; ///< 允许用户自定义RightBar的IconSize SARibbonAlignment mRibbonAlignment; ///< 对齐方式 + int mTitleBarHeight; ///< 标题栏高度 + int mMainBarHeight; ///< 固定高度 public: PrivateData(SARibbonBar* par) : q_ptr(par) @@ -9751,10 +9764,9 @@ class SARibbonBar::PrivateData , mRibbonTabBar(nullptr) , mStackedContainerWidget(nullptr) , mIconRightBorderPosition(1) - , mMinimumCategoryButton(nullptr) + , mMinimumCategoryButtonAction(nullptr) , mRightButtonGroup(nullptr) , mRibbonStyle(SARibbonBar::RibbonStyleLooseThreeRow) - , mLastShowStyle(SARibbonBar::RibbonStyleLooseThreeRow) , mCurrentRibbonMode(SARibbonBar::NormalRibbonMode) , mWindowButtonSize(0, 0) , mContextCategoryColorListIndex(-1) @@ -9764,137 +9776,245 @@ class SARibbonBar::PrivateData , mEnableUserDefineAccessBarIconSize(false) , mEnableUserDefineRightBarIconSize(false) , mRibbonAlignment(SARibbonAlignment::AlignLeft) + , mTitleBarHeight(30) + , mMainBarHeight(200) { mContextCategoryColorList = SARibbonBar::getDefaultContextCategoryColorList(); } - void init() - { - mApplicationButton = RibbonSubElementDelegate->createRibbonApplicationButton(q_ptr); - q_ptr->connect(mApplicationButton, &QAbstractButton::clicked, q_ptr, &SARibbonBar::applicationButtonClicked); - mRibbonTabBar = RibbonSubElementDelegate->createRibbonTabBar(q_ptr); - mRibbonTabBar->setObjectName(QStringLiteral("objSARibbonTabBar")); - mRibbonTabBar->setDrawBase(false); - q_ptr->connect(mRibbonTabBar, &QTabBar::currentChanged, q_ptr, &SARibbonBar::onCurrentRibbonTabChanged); - q_ptr->connect(mRibbonTabBar, &QTabBar::tabBarClicked, q_ptr, &SARibbonBar::onCurrentRibbonTabClicked); - q_ptr->connect(mRibbonTabBar, &QTabBar::tabBarDoubleClicked, q_ptr, &SARibbonBar::onCurrentRibbonTabDoubleClicked); - q_ptr->connect(mRibbonTabBar, &QTabBar::tabMoved, q_ptr, &SARibbonBar::onTabMoved); - // - mStackedContainerWidget = RibbonSubElementDelegate->createRibbonStackedWidget(q_ptr); - mStackedContainerWidget->setObjectName(QStringLiteral("objSAStackedContainerWidget")); - mStackedContainerWidget->connect(mStackedContainerWidget, &SARibbonStackedWidget::hidWindow, q_ptr, &SARibbonBar::onStackWidgetHided); - mStackedContainerWidget->installEventFilter(q_ptr); - setNormalMode(); - // - mQuickAccessBar = RibbonSubElementDelegate->createQuickAccessBar(q_ptr); - mQuickAccessBar->setObjectName(QStringLiteral("objSARibbonQuickAccessBar")); - mQuickAccessBar->setIcon(q_ptr->windowIcon()); - // - mRightButtonGroup = RibbonSubElementDelegate->craeteButtonGroupWidget(q_ptr); - mRightButtonGroup->setFrameShape(QFrame::NoFrame); + // 计算tabbar高度 + int calcTabBarHeight(const QFontMetrics& fm); + // 根据字体信息计算标题栏高度 + int calcTitleBarHeight(const QFontMetrics& fm); + // 计算tabbar高度 + int calcMainBarHeight(SARibbonBar::RibbonStyle s, const QFontMetrics& fm, int tabH, int titleH); + // + int calcMinimumModeMainBarHeight() const; + + void resetSize(); + + void init(); + + void setApplicationButton(QAbstractButton* btn); + + bool isContainContextCategoryInList(SARibbonContextCategory* contextCategory); + + void setHideMode(); + + void setNormalMode(); + + QColor getContextCategoryColor(); + + void updateTabData(); + /** + * @brief 通过输入高度计算iconSize + * @param h + * @return + */ + static QSize calcIconSizeByHeight(int h); +}; + +int SARibbonBar::PrivateData::calcTabBarHeight(const QFontMetrics& fm) +{ + int r = fm.height() * 1.5; + if (r < 20) { + r = 20; } + return r; +} - void setApplicationButton(QAbstractButton* btn) - { - if (mApplicationButton) { - delete mApplicationButton; - } - if (btn) { - if (btn->parent() != q_ptr) { - btn->setParent(q_ptr); - } - btn->move(0, q_ptr->titleBarHeight()); - q_ptr->connect(btn, &QAbstractButton::clicked, q_ptr, &SARibbonBar::applicationButtonClicked); +int SARibbonBar::PrivateData::calcTitleBarHeight(const QFontMetrics& fm) +{ + int r = fm.height() * 1.8; + if (r < 20) { + r = 20; + } + return r; +} + +int SARibbonBar::PrivateData::calcMainBarHeight(SARibbonBar::RibbonStyle s, const QFontMetrics& fm, int tabH, int titleH) +{ + int textH = fm.height(); + int pannelTitleHeight = SARibbonPannel::pannelTitleHeight(); + QMargins pannelMargins = SARibbonPannelLayout::pannelContentsMargins(); + int pannelHPadding = pannelMargins.bottom() + pannelMargins.top(); + int mainbarH = 200; + switch (s) { + case SARibbonBar::RibbonStyleLooseThreeRow: { + mainbarH = tabH + titleH + (textH * 1.5) * 3 + pannelTitleHeight + pannelHPadding; + } break; + case SARibbonBar::RibbonStyleCompactThreeRow: { + // 标题栏是存在,只是把bar画在标题栏上,相当于没有bar + mainbarH = titleH + (textH * 1.5) * 3 + pannelTitleHeight + pannelHPadding; + } break; + case SARibbonBar::RibbonStyleLooseTwoRow: { + mainbarH = tabH + titleH + (textH * 1.5) * 2 + pannelTitleHeight + pannelHPadding; + } break; + case SARibbonBar::RibbonStyleCompactTwoRow: { + mainbarH = titleH + (textH * 1.5) * 2 + pannelTitleHeight + pannelHPadding; + } break; + default: { + qWarning() << "unknow SARibbonBar::RibbonStyle:" << s; + } + } + return mainbarH; +} + +int SARibbonBar::PrivateData::calcMinimumModeMainBarHeight() const +{ + switch (mRibbonStyle) { + case RibbonStyleLooseThreeRow: + case RibbonStyleLooseTwoRow: { + return mTitleBarHeight + mRibbonTabBar->height(); + } + case RibbonStyleCompactThreeRow: + case RibbonStyleCompactTwoRow: { + return mTitleBarHeight; + } + default: + break; + } + return mTitleBarHeight + mRibbonTabBar->height(); +} + +void SARibbonBar::PrivateData::resetSize() +{ + auto fm = q_ptr->fontMetrics(); + mTitleBarHeight = calcTitleBarHeight(fm); + int tabH = calcTabBarHeight(fm); + mRibbonTabBar->setFixedHeight(tabH); + mMainBarHeight = calcMainBarHeight(q_ptr->currentRibbonStyle(), fm, tabH, mTitleBarHeight); + if (MinimumRibbonMode == mCurrentRibbonMode) { + // 处于最小模式下时,bar的高度为tabbar的bottom,这个调整必须在resize event之后 + q_ptr->setFixedHeight(calcMinimumModeMainBarHeight()); + } else { + q_ptr->setFixedHeight(mMainBarHeight); + } +} + +void SARibbonBar::PrivateData::init() +{ + mApplicationButton = RibbonSubElementDelegate->createRibbonApplicationButton(q_ptr); + q_ptr->connect(mApplicationButton, &QAbstractButton::clicked, q_ptr, &SARibbonBar::applicationButtonClicked); + mRibbonTabBar = RibbonSubElementDelegate->createRibbonTabBar(q_ptr); + mRibbonTabBar->setObjectName(QStringLiteral("objSARibbonTabBar")); + mRibbonTabBar->setDrawBase(false); + q_ptr->connect(mRibbonTabBar, &QTabBar::currentChanged, q_ptr, &SARibbonBar::onCurrentRibbonTabChanged); + q_ptr->connect(mRibbonTabBar, &QTabBar::tabBarClicked, q_ptr, &SARibbonBar::onCurrentRibbonTabClicked); + q_ptr->connect(mRibbonTabBar, &QTabBar::tabBarDoubleClicked, q_ptr, &SARibbonBar::onCurrentRibbonTabDoubleClicked); + q_ptr->connect(mRibbonTabBar, &QTabBar::tabMoved, q_ptr, &SARibbonBar::onTabMoved); + // + mStackedContainerWidget = RibbonSubElementDelegate->createRibbonStackedWidget(q_ptr); + mStackedContainerWidget->setObjectName(QStringLiteral("objSAStackedContainerWidget")); + mStackedContainerWidget->connect(mStackedContainerWidget, &SARibbonStackedWidget::hidWindow, q_ptr, &SARibbonBar::onStackWidgetHided); + mStackedContainerWidget->installEventFilter(q_ptr); + // + mQuickAccessBar = RibbonSubElementDelegate->createQuickAccessBar(q_ptr); + mQuickAccessBar->setObjectName(QStringLiteral("objSARibbonQuickAccessBar")); + mQuickAccessBar->setIcon(q_ptr->windowIcon()); + // + mRightButtonGroup = RibbonSubElementDelegate->craeteButtonGroupWidget(q_ptr); + // + setNormalMode(); +} + +void SARibbonBar::PrivateData::setApplicationButton(QAbstractButton* btn) +{ + if (mApplicationButton) { + delete mApplicationButton; + } + if (btn) { + if (btn->parent() != q_ptr) { + btn->setParent(q_ptr); } - mApplicationButton = btn; + btn->move(0, q_ptr->titleBarHeight()); + q_ptr->connect(btn, &QAbstractButton::clicked, q_ptr, &SARibbonBar::applicationButtonClicked); } + mApplicationButton = btn; +} - bool isContainContextCategoryInList(SARibbonContextCategory* contextCategory) - { - for (int i = 0; i < mCurrentShowingContextCategory.size(); ++i) { - if (mCurrentShowingContextCategory[ i ] == contextCategory) { - return (true); - } +bool SARibbonBar::PrivateData::isContainContextCategoryInList(SARibbonContextCategory* contextCategory) +{ + for (int i = 0; i < mCurrentShowingContextCategory.size(); ++i) { + if (mCurrentShowingContextCategory[ i ] == contextCategory) { + return (true); } - return (false); } + return (false); +} - void setHideMode() - { - mCurrentRibbonMode = SARibbonBar::MinimumRibbonMode; - this->mStackedContainerWidget->setPopupMode(); - this->mStackedContainerWidget->setFocusPolicy(Qt::NoFocus); - this->mStackedContainerWidget->clearFocus(); - this->mRibbonTabBar->setFocus(); - this->mStackedContainerWidget->hide(); - q_ptr->setFixedHeight(mRibbonTabBar->geometry().bottom()); - } +void SARibbonBar::PrivateData::setHideMode() +{ + mCurrentRibbonMode = SARibbonBar::MinimumRibbonMode; + this->mStackedContainerWidget->setPopupMode(); + this->mStackedContainerWidget->setFocusPolicy(Qt::NoFocus); + this->mStackedContainerWidget->clearFocus(); + this->mRibbonTabBar->setFocus(); + this->mStackedContainerWidget->hide(); + resetSize(); +} - void setNormalMode() - { - mCurrentRibbonMode = SARibbonBar::NormalRibbonMode; - this->mStackedContainerWidget->setNormalMode(); - this->mStackedContainerWidget->setFocus(); - this->mStackedContainerWidget->show(); - } +void SARibbonBar::PrivateData::setNormalMode() +{ + mCurrentRibbonMode = SARibbonBar::NormalRibbonMode; + this->mStackedContainerWidget->setNormalMode(); + this->mStackedContainerWidget->setFocus(); + this->mStackedContainerWidget->show(); + resetSize(); +} - QColor getContextCategoryColor() - { - if (mContextCategoryColorList.isEmpty()) { - mContextCategoryColorListIndex = -1; - return (QColor()); - } - ++mContextCategoryColorListIndex; - if ((mContextCategoryColorListIndex >= mContextCategoryColorList.size()) || (mContextCategoryColorListIndex < 0)) { - mContextCategoryColorListIndex = 0; - } - return (mContextCategoryColorList.at(mContextCategoryColorListIndex)); +QColor SARibbonBar::PrivateData::getContextCategoryColor() +{ + if (mContextCategoryColorList.isEmpty()) { + mContextCategoryColorListIndex = -1; + return (QColor()); + } + ++mContextCategoryColorListIndex; + if ((mContextCategoryColorListIndex >= mContextCategoryColorList.size()) || (mContextCategoryColorListIndex < 0)) { + mContextCategoryColorListIndex = 0; } + return (mContextCategoryColorList.at(mContextCategoryColorListIndex)); +} - void updateTabData() - { - int tabcount = mRibbonTabBar->count(); +void SARibbonBar::PrivateData::updateTabData() +{ + int tabcount = mRibbonTabBar->count(); - for (int i = 0; i < tabcount; ++i) { - QVariant var = mRibbonTabBar->tabData(i); - if (var.isValid()) { - _SARibbonTabData p = var.value< _SARibbonTabData >(); - p.index = i; - mRibbonTabBar->setTabData(i, QVariant::fromValue(p)); - } + for (int i = 0; i < tabcount; ++i) { + QVariant var = mRibbonTabBar->tabData(i); + if (var.isValid()) { + _SARibbonTabData p = var.value< _SARibbonTabData >(); + p.index = i; + mRibbonTabBar->setTabData(i, QVariant::fromValue(p)); } - // 刷新完tabdata信息也要接着刷新ContextCategory信息 - for (_SAContextCategoryManagerData& cd : mCurrentShowingContextCategory) { - cd.tabPageIndex.clear(); - for (int i = 0; i < cd.contextCategory->categoryCount(); ++i) { - SARibbonCategory* category = cd.contextCategory->categoryPage(i); - for (int t = 0; t < tabcount; ++t) { - QVariant v = mRibbonTabBar->tabData(t); - if (v.isValid()) { - _SARibbonTabData d = v.value< _SARibbonTabData >(); - if (d.category == category) { - cd.tabPageIndex.append(t); - } - } else { - cd.tabPageIndex.append(-1); + } + // 刷新完tabdata信息也要接着刷新ContextCategory信息 + for (_SAContextCategoryManagerData& cd : mCurrentShowingContextCategory) { + cd.tabPageIndex.clear(); + for (int i = 0; i < cd.contextCategory->categoryCount(); ++i) { + SARibbonCategory* category = cd.contextCategory->categoryPage(i); + for (int t = 0; t < tabcount; ++t) { + QVariant v = mRibbonTabBar->tabData(t); + if (v.isValid()) { + _SARibbonTabData d = v.value< _SARibbonTabData >(); + if (d.category == category) { + cd.tabPageIndex.append(t); } + } else { + cd.tabPageIndex.append(-1); } } } } - /** - * @brief 通过输入高度计算iconSize - * @param h - * @return - */ - static QSize calcIconSizeByHeight(int h) - { - if (h - 8 >= 20) { - return QSize(h - 8, h - 8); - } - return QSize(h - 4, h - 4); +} + +QSize SARibbonBar::PrivateData::calcIconSizeByHeight(int h) +{ + if (h - 8 >= 20) { + return QSize(h - 8, h - 8); } -}; + return QSize(h - 4, h - 4); +} //=================================================== // SARibbonBar @@ -9907,6 +10027,7 @@ class SARibbonBar::PrivateData SARibbonBar::SARibbonBar(QWidget* parent) : QMenuBar(parent), d_ptr(new SARibbonBar::PrivateData(this)) { d_ptr->init(); + ensurePolished(); setNativeMenuBar(false); // #ifdef Q_OS_MACOS // setNativeMenuBar(false); @@ -10046,7 +10167,6 @@ void SARibbonBar::addCategoryPage(SARibbonCategory* category) tabdata.category = category; tabdata.index = index; - category->setRibbonBar(this); d_ptr->mRibbonTabBar->setTabData(index, QVariant::fromValue(tabdata)); d_ptr->mStackedContainerWidget->insertWidget(index, category); @@ -10097,7 +10217,6 @@ void SARibbonBar::insertCategoryPage(SARibbonCategory* category, int index) tabdata.index = i; d_ptr->mRibbonTabBar->setTabData(i, QVariant::fromValue(tabdata)); d_ptr->mStackedContainerWidget->insertWidget(index, category); - connect(category, &QWidget::windowTitleChanged, this, &SARibbonBar::onCategoryWindowTitleChanged); // 更新index信息 d_ptr->updateTabData(); @@ -10522,28 +10641,21 @@ void SARibbonBar::showMinimumModeButton(bool isShow) { if (isShow) { activeRightButtonGroup(); - if (nullptr == d_ptr->mMinimumCategoryButton) { - d_ptr->mMinimumCategoryButton = RibbonSubElementDelegate->createHidePannelButton(this); - d_ptr->mMinimumCategoryButton->ensurePolished(); // 载入样式图标 - QAction* action = new QAction(d_ptr->mMinimumCategoryButton); - action->setIcon(style()->standardIcon(isMinimumMode() ? QStyle::SP_TitleBarUnshadeButton : QStyle::SP_TitleBarShadeButton, - 0, - d_ptr->mMinimumCategoryButton)); - connect(action, &QAction::triggered, this, [ = ]() { - this->setMinimumMode(!isMinimumMode()); - action->setIcon(style()->standardIcon(isMinimumMode() ? QStyle::SP_TitleBarUnshadeButton : QStyle::SP_TitleBarShadeButton, - 0, - d_ptr->mMinimumCategoryButton)); - }); - d_ptr->mMinimumCategoryButton->setDefaultAction(action); - d_ptr->mRightButtonGroup->addWidget(d_ptr->mMinimumCategoryButton); - update(); - } + + d_ptr->mMinimumCategoryButtonAction = new QAction(this); + d_ptr->mMinimumCategoryButtonAction->setIcon( + style()->standardIcon(isMinimumMode() ? QStyle::SP_TitleBarUnshadeButton : QStyle::SP_TitleBarShadeButton, nullptr)); + connect(d_ptr->mMinimumCategoryButtonAction, &QAction::triggered, this, [ this ]() { + this->setMinimumMode(!isMinimumMode()); + this->d_ptr->mMinimumCategoryButtonAction->setIcon( + style()->standardIcon(isMinimumMode() ? QStyle::SP_TitleBarUnshadeButton : QStyle::SP_TitleBarShadeButton, nullptr)); + }); + d_ptr->mRightButtonGroup->addAction(d_ptr->mMinimumCategoryButtonAction); + } else { - if (nullptr != d_ptr->mMinimumCategoryButton) { - d_ptr->mMinimumCategoryButton->hide(); - d_ptr->mMinimumCategoryButton->deleteLater(); - d_ptr->mMinimumCategoryButton = nullptr; + if (nullptr != d_ptr->mMinimumCategoryButtonAction) { + d_ptr->mMinimumCategoryButtonAction->deleteLater(); + d_ptr->mMinimumCategoryButtonAction = nullptr; } } QResizeEvent resizeEvent(size(), size()); @@ -10551,23 +10663,67 @@ void SARibbonBar::showMinimumModeButton(bool isShow) QApplication::sendEvent(this, &resizeEvent); } -/// -/// \brief 是否显示隐藏ribbon按钮 -/// \return -/// +/** + * @brief 是否显示隐藏ribbon按钮 + * @return + */ bool SARibbonBar::haveShowMinimumModeButton() const { - return (nullptr != d_ptr->mMinimumCategoryButton); + return (nullptr != d_ptr->mMinimumCategoryButtonAction); +} + +/** + @brief 隐藏ribbon对应的action + @return + */ +QAction* SARibbonBar::minimumModeAction() const +{ + return d_ptr->mMinimumCategoryButtonAction; } +/** + @brief tabBar的高度 + @return + */ int SARibbonBar::tabBarHeight() const { - return (RibbonSubElementStyleOpt.tabBarHeight()); + return d_ptr->mRibbonTabBar->height(); +} + +/** + @brief 设置tabbar的高度 + @param h + */ +void SARibbonBar::setTabBarHeight(int h) +{ + d_ptr->mRibbonTabBar->setFixedHeight(h); } +/** + @brief 返回标题栏高度 + @sa setTitleBarHeight + @return + */ int SARibbonBar::titleBarHeight() const { - return (RibbonSubElementStyleOpt.titleBarHeight()); + return d_ptr->mTitleBarHeight; +} + +/** + @brief 设置标题栏的高度 + @sa titleBarHeight + @note 此操作会发射@ref titleBarHeightChanged 信号 + @param h + */ +void SARibbonBar::setTitleBarHeight(int h) +{ + if (d_ptr->mTitleBarHeight == h) { + return; + } + int oldHeight = d_ptr->mTitleBarHeight; + d_ptr->mTitleBarHeight = h; + updateRibbonGeometry(); + emit titleBarHeightChanged(oldHeight, h); } void SARibbonBar::onWindowTitleChanged(const QString& title) @@ -10775,11 +10931,6 @@ void SARibbonBar::synchronousCategoryLayoutMode(bool autoUpdate) c->setRibbonPannelLayoutMode(SARibbonBar::isTwoRowStyle(currentRibbonStyle()) ? SARibbonPannel::TwoRowMode : SARibbonPannel::ThreeRowMode); } - - // 根据样式调整bar的高度 - if (NormalRibbonMode == currentRibbonState()) { - setFixedHeight(mainBarHeight()); - } //! 直接给一个resizeevent,让所有刷新 if (autoUpdate) { QResizeEvent* e = new QResizeEvent(size(), QSize()); @@ -10787,19 +10938,41 @@ void SARibbonBar::synchronousCategoryLayoutMode(bool autoUpdate) } } -void SARibbonBar::activeRightButtonGroup() +/** + @brief 激活tabbar右边的按钮群 + @return 返回右边的按钮群指针 + */ +SARibbonButtonGroupWidget* SARibbonBar::activeRightButtonGroup() { if (nullptr == d_ptr->mRightButtonGroup) { d_ptr->mRightButtonGroup = RibbonSubElementDelegate->craeteButtonGroupWidget(this); - d_ptr->mRightButtonGroup->setFrameShape(QFrame::NoFrame); } d_ptr->mRightButtonGroup->show(); + return d_ptr->mRightButtonGroup; } +/** + @brief 返回右边的按钮群指针 + @return 如果没有创建,返回nullptr + */ SARibbonButtonGroupWidget* SARibbonBar::rightButtonGroup() { - activeRightButtonGroup(); - return (d_ptr->mRightButtonGroup); + return d_ptr->mRightButtonGroup; +} + +/** + @brief 激活QuickAccessBar + @return + */ +SARibbonQuickAccessBar* SARibbonBar::activeQuickAccessBar() +{ + if (nullptr == d_ptr->mQuickAccessBar) { + d_ptr->mQuickAccessBar = RibbonSubElementDelegate->createQuickAccessBar(this); + d_ptr->mQuickAccessBar->setObjectName(QStringLiteral("objSARibbonQuickAccessBar")); + d_ptr->mQuickAccessBar->setIcon(windowIcon()); + } + d_ptr->mQuickAccessBar->show(); + return d_ptr->mQuickAccessBar; } SARibbonQuickAccessBar* SARibbonBar::quickAccessBar() @@ -10817,13 +10990,18 @@ SARibbonQuickAccessBar* SARibbonBar::quickAccessBar() */ void SARibbonBar::setRibbonStyle(SARibbonBar::RibbonStyle v) { - d_ptr->mRibbonStyle = v; - d_ptr->mLastShowStyle = v; + d_ptr->mRibbonStyle = v; d_ptr->mQuickAccessBar->setEnableShowIcon(isOfficeStyle(v)); // 默认情况下2行模式不换行 // 如果想在两行模式换行,在调用SARibbonBar::setRibbonStyle后,再SARibbonToolButton::setEnableWordWrap(true) SARibbonToolButton::setEnableWordWrap(!isTwoRowStyle(v)); - + d_ptr->resetSize(); + if (MinimumRibbonMode == currentRibbonState()) { + // 处于最小模式下时,bar的高度为tabbar的bottom,这个调整必须在resize event之后 + setFixedHeight(minimumModeMainBarHeight()); + } else { + setFixedHeight(mainBarHeight()); + } synchronousCategoryLayoutMode(false); // 这里不急着刷新,下面会继续刷新 QSize oldSize = size(); @@ -10831,10 +11009,7 @@ void SARibbonBar::setRibbonStyle(SARibbonBar::RibbonStyle v) QResizeEvent es(newSize, oldSize); QApplication::sendEvent(this, &es); - if (MinimumRibbonMode == currentRibbonState()) { - // 处于最小模式下时,bar的高度为tabbar的bottom,这个调整必须在resize event之后 - setFixedHeight(d_ptr->mRibbonTabBar->geometry().bottom()); - } + emit ribbonStyleChanged(d_ptr->mRibbonStyle); } @@ -10960,26 +11135,9 @@ QColor SARibbonBar::tabBarBaseLineColor() const */ void SARibbonBar::updateRibbonGeometry() { - // updateRibbonElementGeometry(); - // QList< SARibbonCategory* > categorys = categoryPages(); - // for (SARibbonCategory* c : qAsConst(categorys)) { - // c->updateItemGeometry(); - // } - // //重新调整尺寸 - // resizeAll(); - // - // auto fnUpdate = [](QWidget* w) { - // if (w) { - // if (w->layout()) { - // w->layout()->invalidate(); - // } - // w->updateGeometry(); - // w->adjustSize(); - // } - // }; - // fnUpdate(d_ptr->mQuickAccessBar); - // fnUpdate(d_ptr->mRightButtonGroup); updateGeometry(); + d_ptr->resetSize(); + QList< SARibbonCategory* > categorys = categoryPages(); for (SARibbonCategory* c : qAsConst(categorys)) { c->updateItemGeometry(); @@ -11067,6 +11225,13 @@ bool SARibbonBar::isTitleVisible() const void SARibbonBar::setEnableUserDefineAccessBarIconSize(bool on) { d_ptr->mEnableUserDefineAccessBarIconSize = on; + if (!(d_ptr->mEnableUserDefineAccessBarIconSize)) { // 允许用户自定义AccessBar的IconSize就不进入此条件重置大小 + // 变更iconsize + QSize btnIconSize = PrivateData::calcIconSizeByHeight(titleBarHeight()); + if (btnIconSize != d_ptr->mQuickAccessBar->iconSize()) { + d_ptr->mQuickAccessBar->setIconSize(btnIconSize); + } + } } /** @@ -11090,6 +11255,13 @@ bool SARibbonBar::isEnableUserDefineAccessBarIconSize() const void SARibbonBar::setEnableUserDefineRightBarIconSize(bool on) { d_ptr->mEnableUserDefineRightBarIconSize = on; + // 变更iconsize + if (!(d_ptr->mEnableUserDefineRightBarIconSize)) { + QSize btnIconSize = PrivateData::calcIconSizeByHeight(titleBarHeight()); + if (btnIconSize != d_ptr->mRightButtonGroup->iconSize()) { + d_ptr->mRightButtonGroup->setIconSize(btnIconSize); + } + } } /** @@ -11212,7 +11384,25 @@ int SARibbonBar::calcMinTabBarWidth() const */ int SARibbonBar::mainBarHeight() const { - return RibbonSubElementStyleOpt.ribbonBarHeight(currentRibbonStyle()); + return d_ptr->mMainBarHeight; +} + +/** + @brief 设置mainBar高度 + @param m + */ +void SARibbonBar::setMainBarHeight(int m) +{ + d_ptr->mMainBarHeight = m; +} + +/** + @brief 最小模式下的高度 + @return + */ +int SARibbonBar::minimumModeMainBarHeight() const +{ + return d_ptr->calcMinimumModeMainBarHeight(); } /** @@ -11233,6 +11423,7 @@ void SARibbonBar::updateCategoryTitleToTabName() } } } + repaint(); } void SARibbonBar::paintEvent(QPaintEvent* e) @@ -11256,11 +11447,11 @@ void SARibbonBar::paintInNormalStyle() QPainter p(this); //! - paintBackground(p); + paintTabbarBaseLine(p); //! 显示上下文标签 p.save(); QList< _SAContextCategoryManagerData > contextCategoryDataList = d_ptr->mCurrentShowingContextCategory; - bool isCurrentSelectContextCategoryPage = false; + // bool isCurrentSelectContextCategoryPage = false; QPoint contextCategoryRegion(width(), -1); QMargins border = contentsMargins(); @@ -11287,16 +11478,16 @@ void SARibbonBar::paintInNormalStyle() contextCategoryRegion.setY(contextTitleRect.right()); } } - isCurrentSelectContextCategoryPage = indexs.contains(d_ptr->mRibbonTabBar->currentIndex()); - if (isCurrentSelectContextCategoryPage) { - QPen pen; - pen.setColor(clr); - pen.setWidth(1); - p.setPen(pen); - p.setBrush(Qt::NoBrush); - p.drawRect(d_ptr->mStackedContainerWidget->geometry()); - isCurrentSelectContextCategoryPage = false; - } + // isCurrentSelectContextCategoryPage = indexs.contains(d_ptr->mRibbonTabBar->currentIndex()); + // if (isCurrentSelectContextCategoryPage) { + // QPen pen; + // pen.setColor(clr); + // pen.setWidth(1); + // p.setPen(pen); + // p.setBrush(Qt::NoBrush); + // p.drawRect(d_ptr->mStackedContainerWidget->geometry()); + // isCurrentSelectContextCategoryPage = false; + // } } p.restore(); //! 显示标题等 @@ -11339,11 +11530,10 @@ void SARibbonBar::paintInWpsLiteStyle() { QPainter p(this); //! - paintBackground(p); + paintTabbarBaseLine(p); //! 显示上下文标签 p.save(); QList< _SAContextCategoryManagerData > contextCategoryDataList = d_ptr->mCurrentShowingContextCategory; - bool isCurrentSelectContextCategoryPage = false; QMargins border = contentsMargins(); for (int i = 0; i < contextCategoryDataList.size(); ++i) { QRect contextTitleRect; @@ -11361,16 +11551,6 @@ void SARibbonBar::paintInWpsLiteStyle() // 绘制 paintContextCategoryTab(p, QString(), contextTitleRect, clr); } - isCurrentSelectContextCategoryPage = indexs.contains(d_ptr->mRibbonTabBar->currentIndex()); - if (isCurrentSelectContextCategoryPage) { - QPen pen; - pen.setColor(clr); - pen.setWidth(1); - p.setPen(pen); - p.setBrush(Qt::NoBrush); - p.drawRect(d_ptr->mStackedContainerWidget->geometry()); - isCurrentSelectContextCategoryPage = false; - } } p.restore(); //! 显示标题等 @@ -11397,10 +11577,11 @@ void SARibbonBar::resizeStackedContainerWidget() { QMargins border = contentsMargins(); const QRect& ribbonTabBarGeometry = d_ptr->mRibbonTabBar->geometry(); - int x = border.left(); - int y = ribbonTabBarGeometry.bottom() + 1; - int w = width() - border.left() - border.right(); - int h = mainBarHeight() - ribbonTabBarGeometry.bottom() - border.bottom() - 1; + + int x = border.left(); + int y = ribbonTabBarGeometry.bottom() + 1; + int w = width() - border.left() - border.right(); + int h = mainBarHeight() - ribbonTabBarGeometry.bottom() - border.bottom() - 1; if (d_ptr->mStackedContainerWidget->isPopupMode()) { // 弹出模式时,位置为全局位置 QPoint absPosition = mapToGlobal(QPoint(x, y)); @@ -11525,6 +11706,19 @@ void SARibbonBar::changeEvent(QEvent* e) QMenuBar::changeEvent(e); } +bool SARibbonBar::event(QEvent* e) +{ + switch (e->type()) { + case QEvent::Show: + // 第一次显示刷新 + updateRibbonGeometry(); + break; + default: + break; + } + return QMenuBar::event(e); +} + void SARibbonBar::resizeInOfficeStyle() { synchronousCategoryLayoutMode(false); @@ -11557,14 +11751,7 @@ void SARibbonBar::resizeInOfficeStyle() } QSize quickAccessBarSize = d_ptr->mQuickAccessBar->sizeHint(); // 上下留1px的边线 - d_ptr->mQuickAccessBar->setGeometry(x, y + 1, quickAccessBarSize.width(), validTitleBarHeight - 2); - if (!(d_ptr->mEnableUserDefineAccessBarIconSize)) { // 允许用户自定义AccessBar的IconSize就不进入此条件重置大小 - // 变更iconsize - QSize btnIconSize = PrivateData::calcIconSizeByHeight(validTitleBarHeight - 2); - if (btnIconSize != d_ptr->mQuickAccessBar->iconSize()) { - d_ptr->mQuickAccessBar->setIconSize(btnIconSize); - } - } + d_ptr->mQuickAccessBar->setGeometry(x, y + 1, quickAccessBarSize.width(), validTitleBarHeight); } } // 第二行,开始布局applicationButton,tabbar,tabBarRightSizeButtonGroupWidget,TopRightCorner @@ -11605,13 +11792,6 @@ void SARibbonBar::resizeInOfficeStyle() endX -= wSize.width(); // 上下留1px的边线 d_ptr->mRightButtonGroup->setGeometry(endX, y + 1, wSize.width(), tabH - 2); - // 变更iconsize - if (!(d_ptr->mEnableUserDefineRightBarIconSize)) { - QSize btnIconSize = PrivateData::calcIconSizeByHeight(tabH - 2); - if (btnIconSize != d_ptr->mRightButtonGroup->iconSize()) { - d_ptr->mRightButtonGroup->setIconSize(btnIconSize); - } - } } // 最后确定tabbar宽度 int tabBarAllowedWidth = endX - x; @@ -11666,13 +11846,6 @@ void SARibbonBar::resizeInWpsLiteStyle() endX -= wSize.width(); // 上下留1px的边线 d_ptr->mRightButtonGroup->setGeometry(endX, y + 1, wSize.width(), validTitleBarHeight - 2); - // 变更iconsize - if (!(d_ptr->mEnableUserDefineRightBarIconSize)) { - QSize btnIconSize = PrivateData::calcIconSizeByHeight(validTitleBarHeight - 2); - if (btnIconSize != d_ptr->mRightButtonGroup->iconSize()) { - d_ptr->mRightButtonGroup->setIconSize(btnIconSize); - } - } } // quick access bar定位 if (d_ptr->mQuickAccessBar) { @@ -11681,13 +11854,6 @@ void SARibbonBar::resizeInWpsLiteStyle() endX -= quickAccessBarSize.width(); // 上下留1px的边线 d_ptr->mQuickAccessBar->setGeometry(endX, y + 1, quickAccessBarSize.width(), validTitleBarHeight - 2); - // 变更iconsize - if (!(d_ptr->mEnableUserDefineAccessBarIconSize)) { // 允许用户自定义AccessBar的IconSize就不进入此条件重置大小 - QSize btnIconSize = PrivateData::calcIconSizeByHeight(validTitleBarHeight - 2); - if (btnIconSize != d_ptr->mQuickAccessBar->iconSize()) { - d_ptr->mQuickAccessBar->setIconSize(btnIconSize); - } - } } } // cornerWidget - TopLeftCorner @@ -11749,7 +11915,7 @@ void SARibbonBar::resizeInWpsLiteStyle() resizeStackedContainerWidget(); } -void SARibbonBar::paintBackground(QPainter& painter) +void SARibbonBar::paintTabbarBaseLine(QPainter& painter) { painter.save(); // 在tabbar下绘制一条线 @@ -11787,125 +11953,11 @@ void SARibbonBar::paintWindowTitle(QPainter& painter, const QString& title, cons /*** End of inlined file: SARibbonBar.cpp ***/ -/*** Start of inlined file: SARibbonStyleOption.cpp ***/ -#include -#include -SARibbonStyleOption::SARibbonStyleOption() -{ - init(); -} - -SARibbonStyleOption::~SARibbonStyleOption() -{ -} - -int SARibbonStyleOption::ribbonBarHeight(SARibbonBar::RibbonStyle s) const -{ - switch (s) { - case SARibbonBar::RibbonStyleLooseThreeRow: - return m_ribbonbarHeightOfficeStyleThreeRow; - case SARibbonBar::RibbonStyleLooseTwoRow: - return m_ribbonbarHeightOfficeStyleTwoRow; - case SARibbonBar::RibbonStyleCompactThreeRow: - return m_ribbonbarHeightWPSStyleThreeRow; - case SARibbonBar::RibbonStyleCompactTwoRow: - return m_ribbonbarHeightWPSStyleTwoRow; - default: - break; - } - return m_ribbonbarHeightOfficeStyleThreeRow; -} - -/** - * @brief 标题栏高度 - * @return - */ -int SARibbonStyleOption::titleBarHeight() const -{ - return m_titleBarHeight; -} - -int SARibbonStyleOption::tabBarHeight() const -{ - return m_tabBarHeight; -} - -void SARibbonStyleOption::recalc() -{ - updateMainbarHeight(); -} - -/** - * @brief 计算ribbon的高度 - * - * @note 调用此函数之前必须调用 - * @param s - * @return - */ -int SARibbonStyleOption::calcMainbarHeight(SARibbonBar::RibbonStyle s) const -{ - switch (s) { - case SARibbonBar::RibbonStyleCompactThreeRow: - // 不是减去m_titleBarHeight原因是绘制wps的样式时,标题栏是存在,只是把bar画在标题栏上,相当于没有bar - return m_ribbonbarHeightOfficeStyleThreeRow - m_tabBarHeight; - case SARibbonBar::RibbonStyleCompactTwoRow: - // 两行模式把标题栏去掉 - return m_ribbonbarHeightOfficeStyleThreeRow * 0.9 - m_tabBarHeight - SARibbonPannel::pannelTitleHeight(); - case SARibbonBar::RibbonStyleLooseTwoRow: - return m_ribbonbarHeightOfficeStyleThreeRow * 0.9 - SARibbonPannel::pannelTitleHeight(); - default: - break; - } - return m_ribbonbarHeightOfficeStyleThreeRow; -} - -void SARibbonStyleOption::init() -{ - QFontMetrics fm = QApplication::fontMetrics(); - int lineSpacing = fm.lineSpacing(); - - m_titleBarHeight = lineSpacing * 1.8; - m_tabBarHeight = lineSpacing * 1.5; - m_ribbonbarHeightOfficeStyleThreeRow = m_titleBarHeight + m_tabBarHeight + (lineSpacing * 1.5) * 3 - + SARibbonPannel::pannelTitleHeight() - + SARibbonPannelLayout::pannelContentsMargins().bottom() - + SARibbonPannelLayout::pannelContentsMargins().top(); - updateMainbarHeight(); -} - -void SARibbonStyleOption::updateMainbarHeight() -{ - m_ribbonbarHeightWPSStyleThreeRow = calcMainbarHeight(SARibbonBar::RibbonStyleCompactThreeRow); - m_ribbonbarHeightOfficeStyleTwoRow = calcMainbarHeight(SARibbonBar::RibbonStyleLooseTwoRow); - m_ribbonbarHeightWPSStyleTwoRow = calcMainbarHeight(SARibbonBar::RibbonStyleCompactTwoRow); -} - -/** - * @brief 对SARibbonStyleOption输出 - * @param debug - * @param c - * @return - */ -QDebug operator<<(QDebug debug, const SARibbonStyleOption& c) -{ - QDebugStateSaver saver(debug); - Q_UNUSED(saver); - debug.nospace() << "fontMetrics.lineSpacing=" << QApplication::fontMetrics().lineSpacing() - << ",SARibbonStyleOption(titleBarHeight=" << c.titleBarHeight() << ",tabBarHeight=" << c.tabBarHeight() - << "\n,ribbonBarHeight(OfficeStyle)=" << c.ribbonBarHeight(SARibbonBar::RibbonStyleLooseThreeRow) - << "\n,ribbonBarHeight(OfficeStyleTwoRow)=" << c.ribbonBarHeight(SARibbonBar::RibbonStyleLooseTwoRow) - << "\n,ribbonBarHeight(WpsLiteStyle)=" << c.ribbonBarHeight(SARibbonBar::RibbonStyleCompactThreeRow) - << "\n,ribbonBarHeight(WpsLiteStyleTwoRow)=" << c.ribbonBarHeight(SARibbonBar::RibbonStyleCompactTwoRow); - return debug; -} - -/*** End of inlined file: SARibbonStyleOption.cpp ***/ - /*** Start of inlined file: SARibbonElementFactory.cpp ***/ #include #include -SARibbonElementFactory::SARibbonElementFactory() : mStyleOption(new SARibbonStyleOption()) +SARibbonElementFactory::SARibbonElementFactory() { } @@ -11973,17 +12025,6 @@ SARibbonStackedWidget* SARibbonElementFactory::createRibbonStackedWidget(SARibbo return (new SARibbonStackedWidget(parent)); } -SARibbonControlButton* SARibbonElementFactory::createHidePannelButton(SARibbonBar* parent) -{ - SARibbonControlButton* btn = new SARibbonControlButton(parent); - - btn->setAutoRaise(false); - btn->setObjectName(QStringLiteral("SARibbonBarHidePannelButton")); - btn->setToolButtonStyle(Qt::ToolButtonIconOnly); - btn->setFixedSize(parent->tabBarHeight() - 4, parent->tabBarHeight() - 4); - return (btn); -} - SARibbonButtonGroupWidget* SARibbonElementFactory::craeteButtonGroupWidget(QWidget* parent) { return (new SARibbonButtonGroupWidget(parent)); @@ -11994,20 +12035,6 @@ SARibbonQuickAccessBar* SARibbonElementFactory::createQuickAccessBar(QWidget* pa return (new SARibbonQuickAccessBar(parent)); } -SARibbonStyleOption& SARibbonElementFactory::getRibbonStyleOption() -{ - return (*mStyleOption); -} - -/** - * @brief 设置style配置 - * @param opt - */ -void SARibbonElementFactory::setRibbonStyleOption(SARibbonStyleOption* opt) -{ - mStyleOption.reset(opt); -} - /** * @brief 创建SARibbonPannelOptionButton * @param pannel 附属的pannel @@ -14397,7 +14424,8 @@ SARibbonMainWindow::SARibbonMainWindow(QWidget* parent, bool useRibbon, const Qt if (useRibbon) { installRibbonBar(createRibbonBar()); setRibbonTheme(ribbonTheme()); - qDebug() << RibbonSubElementStyleOpt; + } else { + setupNormalWindow(); } } @@ -14440,6 +14468,11 @@ bool SARibbonMainWindow::eventFilter(QObject* obj, QEvent* e) } return (QMainWindow::eventFilter(obj, e)); } +#else +FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessWidgetsHelper*) SARibbonMainWindow::framelessHelper() +{ + return FramelessWidgetsHelper::get(this); +} #endif /** * @brief 此函数仅用于控制最小最大化和关闭按钮的显示 @@ -14524,6 +14557,15 @@ bool SARibbonMainWindow::isUseRibbon() const return (nullptr != ribbonBar()); } +/** + @brief 获取左上角按钮组(最大化,最小化,关闭) + @return + */ +SAWindowButtonGroup* SARibbonMainWindow::windowButtonGroup() const +{ + return d_ptr->mWindowButtonGroup; +} + /** * @brief 创建ribbonbar的工厂函数 * @return @@ -14582,9 +14624,6 @@ void SARibbonMainWindow::installRibbonBar(SARibbonBar* bar) if (nullptr == d_ptr->mWindowButtonGroup) { d_ptr->mWindowButtonGroup = new SAWindowButtonGroup(this); } - QSize s = d_ptr->mWindowButtonGroup->sizeHint(); - s.setHeight(bar->titleBarHeight()); - d_ptr->mWindowButtonGroup->setFixedSize(s); d_ptr->mWindowButtonGroup->setWindowStates(windowState()); d_ptr->mWindowButtonGroup->show(); helper->setHitTestVisible(d_ptr->mWindowButtonGroup); // IMPORTANT! @@ -14593,7 +14632,6 @@ void SARibbonMainWindow::installRibbonBar(SARibbonBar* bar) helper->setHitTestVisible(bar->applicationButton()); // IMPORTANT! helper->setHitTestVisible(bar->quickAccessBar()); // IMPORTANT! helper->setHitTestVisible(bar->ribbonStackedWidget()); // IMPORTANT! - #else QMainWindow::setMenuWidget(bar); @@ -14616,6 +14654,22 @@ void SARibbonMainWindow::installRibbonBar(SARibbonBar* bar) #endif } +/** + @brief 构建为普通窗口 + */ +void SARibbonMainWindow::setupNormalWindow() +{ +#if SARIBBON_USE_3RDPARTY_FRAMELESSHELPER + auto helper = FramelessWidgetsHelper::get(this); + // 设置window按钮 + if (nullptr == d_ptr->mWindowButtonGroup) { + d_ptr->mWindowButtonGroup = new SAWindowButtonGroup(this); + } + d_ptr->mWindowButtonGroup->setWindowStates(windowState()); + d_ptr->mWindowButtonGroup->show(); +#endif +} + void sa_set_ribbon_theme(QWidget* w, SARibbonMainWindow::RibbonTheme theme) { QFile file; @@ -14642,7 +14696,9 @@ void sa_set_ribbon_theme(QWidget* w, SARibbonMainWindow::RibbonTheme theme) if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return; } - w->setStyleSheet(file.readAll()); + // 有反馈用qstring接住文件内容,再设置进去才能生效(qt5.7版本) + QString qss = file.readAll(); + w->setStyleSheet(qss); } /*** End of inlined file: SARibbonMainWindow.cpp ***/ diff --git a/src/SARibbon.h b/src/SARibbon.h index 21899561..84e93603 100644 --- a/src/SARibbon.h +++ b/src/SARibbon.h @@ -87,6 +87,15 @@ 版本记录(change log): + - 2023-12-25 -> 1.1.0 + 修正了尺寸刷新的问题,在首次显示不会出现控件跳动的状态 + 修正了一些问题 + 调整了创建RibbonButton的方式 + 调整了SARibbonPannel一些接口,使得创建更加规范 + 调整了ToolButton的渲染方式 + + ------------------------ + - 2023-11-19 -> 1.0.6 添加Office2016主题 Category可以居中对齐 @@ -181,22 +190,13 @@ * @def ribbon的数字版本 MAJ.{MIN}.PAT */ #ifndef SA_RIBBON_BAR_VERSION_MIN -#define SA_RIBBON_BAR_VERSION_MIN 0 +#define SA_RIBBON_BAR_VERSION_MIN 1 #endif /** * @def ribbon的数字版本 MAJ.MIN.{PAT} */ #ifndef SA_RIBBON_BAR_VERSION_PAT -#define SA_RIBBON_BAR_VERSION_PAT 6 -#endif - -/** - * @def 属性,用于标记是否可以进行自定义,用于动态设置到@ref SARibbonCategory 和@ref SARibbonPannel - * 值为bool,在为true时,可以通过@ref SARibbonCustomizeWidget 改变这个SARibbonCategory和SARibbonPannel的布局, - * 默认不会有此属性,仅在有此属性且为true时才会在SARibbonCustomizeWidget中能显示为可设置 - */ -#ifndef SA_RIBBON_BAR_PROP_CAN_CUSTOMIZE -#define SA_RIBBON_BAR_PROP_CAN_CUSTOMIZE "_sa_isCanCustomize" +#define SA_RIBBON_BAR_VERSION_PAT 0 #endif #ifndef SA_RIBBON_BAR_NO_EXPORT @@ -240,12 +240,47 @@ enum class SARibbonAlignment AlignCenter ///< 居中对其,tab栏居中对齐,同时category也是居中对齐 }; +/** + * @def 属性,用于标记是否可以进行自定义,用于动态设置到@ref SARibbonCategory 和@ref SARibbonPannel + * 值为bool,在为true时,可以通过@ref SARibbonCustomizeWidget 改变这个SARibbonCategory和SARibbonPannel的布局, + * 默认不会有此属性,仅在有此属性且为true时才会在SARibbonCustomizeWidget中能显示为可设置 + */ +#ifndef SA_RIBBON_BAR_PROP_CAN_CUSTOMIZE +#define SA_RIBBON_BAR_PROP_CAN_CUSTOMIZE "_sa_isCanCustomize" +#endif + /** * @def 定义此宏用第三方的frameless作为无边框方案 * 此宏在qmake或在cmake中定义,不需要在此显示定义 */ // #define SARIBBON_USE_3RDPARTY_FRAMELESSHELPER 0 +#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)) +#ifndef SA_FONTMETRICS_WIDTH +#define SA_FONTMETRICS_WIDTH(fm, str) fm.horizontalAdvance(str) +#endif +#else +#ifndef SA_FONTMETRICS_WIDTH +#define SA_FONTMETRICS_WIDTH(fm, str) fm.width(str) +#endif +#endif + +#ifndef SA_DEBUG_PRINT_SIZE_HINT +/** + @def 定义此宏,将打印和尺寸刷新相关的信息 + + 仅用于调试 + */ +#define SA_DEBUG_PRINT_SIZE_HINT 0 +#endif +#ifndef SA_DEBUG_PRINT_EVENT +/** + @def 定义此宏,将打印事件 + + 仅用于调试 + */ +#define SA_DEBUG_PRINT_EVENT 0 +#endif #endif // SARIBBONGLOBAL_H /*** End of inlined file: SARibbonGlobal.h ***/ @@ -733,6 +768,8 @@ class SA_RIBBON_EXPORT SARibbonToolButton : public QToolButton // 更新尺寸 void updateRect(); + virtual QSize sizeHint() const Q_DECL_OVERRIDE; + public: // 在lite模式下是否允许文字换行 static void setEnableWordWrap(bool on); @@ -747,7 +784,6 @@ class SA_RIBBON_EXPORT SARibbonToolButton : public QToolButton virtual void focusOutEvent(QFocusEvent* e) Q_DECL_OVERRIDE; virtual void leaveEvent(QEvent* e) Q_DECL_OVERRIDE; virtual bool hitButton(const QPoint& pos) const Q_DECL_OVERRIDE; - virtual QSize sizeHint() const Q_DECL_OVERRIDE; virtual bool event(QEvent* e) Q_DECL_OVERRIDE; // 事件改变 - 主要为了捕获字体的改变 virtual void changeEvent(QEvent* e) Q_DECL_OVERRIDE; @@ -1037,47 +1073,6 @@ private slots: /*** End of inlined file: SARibbonActionsManager.h ***/ -/*** Start of inlined file: SARibbonDrawHelper.h ***/ -#ifndef SARIBBONDRAWHELPER_H -#define SARIBBONDRAWHELPER_H -#include -#include -#include -#include - -/** - * @def QFontMetrics::horizontalAdvance(str)/QFontMetrics::width(str) 为了兼容5.11以下的qt版本,定义的兼容宏 - */ -#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)) -#ifndef SA_FONTMETRICS_WIDTH -#define SA_FONTMETRICS_WIDTH(fm, str) fm.horizontalAdvance(str) -#endif -#else -#ifndef SA_FONTMETRICS_WIDTH -#define SA_FONTMETRICS_WIDTH(fm, str) fm.width(str) -#endif -#endif - -/// -/// \brief 绘图辅助 -/// -class SA_RIBBON_EXPORT SARibbonDrawHelper -{ -public: - SARibbonDrawHelper(); - static QPixmap iconToPixmap(const QIcon& icon, QWidget* widget, const QStyleOption* opt, const QSize& icoSize); - static void drawIcon(const QIcon& icon, QPainter* painter, const QStyleOption* opt, int x, int y, int width, int height); - static void drawIcon(const QIcon& icon, QPainter* painter, const QStyleOption* opt, const QRect& rect); - static QSize iconActualSize(const QIcon& icon, const QStyleOption* opt, const QSize& iconSize); - - static void drawText(const QString& text, QStylePainter* painter, const QStyleOption* opt, Qt::Alignment al, int x, int y, int width, int height); - static void drawText(const QString& text, QStylePainter* painter, const QStyleOption* opt, Qt::Alignment al, const QRect& rect); -}; - -#endif // SARIBBONDRAWHELPER_H - -/*** End of inlined file: SARibbonDrawHelper.h ***/ - /*** Start of inlined file: SARibbonLineEdit.h ***/ #ifndef SARIBBONLINEEDIT_H #define SARIBBONLINEEDIT_H @@ -1211,14 +1206,16 @@ class SA_RIBBON_EXPORT SARibbonStackedWidget : public QStackedWidget void exec(); // 设置stacked管理的窗口会随着stacked的大小变化而变化大小 + // 就算不激活也调整大小 void setAutoResize(bool autoresize); bool isAutoResize() const; + // 移动窗口 void moveWidget(int from, int to); protected: // void mouseReleaseEvent(QMouseEvent *e); - void hideEvent(QHideEvent* e) override; - + void hideEvent(QHideEvent* e) Q_DECL_OVERRIDE; + virtual void resizeEvent(QResizeEvent* e) Q_DECL_OVERRIDE; signals: /** * @brief hidWindow @@ -1292,6 +1289,7 @@ class SA_RIBBON_EXPORT SARibbonCtrlContainer : public QWidget bool hasContainerWidget() const; // 图标 void setIcon(const QIcon& i); + void setIcon(const QPixmap& pixmap); QIcon getIcon() const; // 图标 void setText(const QString& t); @@ -1448,7 +1446,6 @@ class SA_RIBBON_EXPORT SARibbonPannelOptionButton : public QToolButton #include #include -#include class SARibbonToolButton; /** * @brief 是对pannel所有子窗口的抽象,参考qt的toolbar @@ -1482,8 +1479,17 @@ class SA_RIBBON_EXPORT SARibbonPannelItem : public QWidgetItem bool customWidget; ///< 对于没有窗口的action,实际也会有一个SARibbonToolButton,在销毁时要delete掉 SARibbonPannelItem::RowProportion rowProportion; ///< 行的占比,ribbon中有large,media和small三种占比,见@ref RowProportion }; -#ifndef SARibbonPannelItemRowProportionPropertyName -#define SARibbonPannelItemRowProportionPropertyName "SARibbonPannelItem_RowProportion" +#ifndef SA_ActionPropertyName_RowProportion +#define SA_ActionPropertyName_RowProportion "_sa_RowProportion" +#endif +#ifndef SA_ActionPropertyName_ToolButtonPopupMode +#define SA_ActionPropertyName_ToolButtonPopupMode "_sa_ToolButtonPopupMode" +#endif +#ifndef SA_ActionPropertyName_SeparatorTop +#define SA_ActionPropertyName_SeparatorTop "_sa_SeparatorTop" +#endif +#ifndef SA_ActionPropertyName_SeparatorBottom +#define SA_ActionPropertyName_SeparatorBottom "_sa_SeparatorBottom" #endif #endif // SARIBBONPANNELITEM_H @@ -1514,7 +1520,10 @@ class SA_RIBBON_EXPORT SARibbonPannelLayout : public QLayout public: SARibbonPannelLayout(QWidget* p = 0); ~SARibbonPannelLayout(); - virtual int indexOf(QAction* action) const; + int indexByAction(QAction* action) const; + + // 获取ribbonpannel + SARibbonPannel* ribbonPannel() const; // SARibbonPannelLayout additem 无效 void addItem(QLayoutItem* item) Q_DECL_OVERRIDE; @@ -1604,7 +1613,8 @@ class SARibbonGallery; class QGridLayout; class SARibbonPannelOptionButton; class SARibbonPannelLayout; - +class SARibbonCategory; +class SARibbonBar; /** * @brief pannel页窗口,pannel是ribbon的面板用于承放控件 * @@ -1624,6 +1634,7 @@ class SA_RIBBON_EXPORT SARibbonPannel : public QWidget friend class SARibbonCategory; friend class SARibbonCategoryPrivate; friend class SARibbonCustomizeWidgetPrivate; + friend class SARibbonPannelLayout; Q_PROPERTY(bool isCanCustomize READ isCanCustomize WRITE setCanCustomize) Q_PROPERTY(bool isExpanding READ isExpanding WRITE setExpanding) Q_PROPERTY(QString pannelName READ pannelName WRITE setPannelName) @@ -1639,29 +1650,23 @@ class SA_RIBBON_EXPORT SARibbonPannel : public QWidget TwoRowMode ///< 两行布局模式,wps的后续布局模式就是两行布局模式,pannel能布置2行小toolbutton }; - // 把action的行属性设置进action中,action自身携带了行属性 - static void setActionRowProportionProperty(QAction* action, SARibbonPannelItem::RowProportion rp); - - // 获取action的行属性 - static SARibbonPannelItem::RowProportion getActionRowProportionProperty(QAction* action); - - // 设置action的行行为,行属性决定了ribbon pannel的显示方式 - void setActionRowProportion(QAction* action, SARibbonPannelItem::RowProportion rp); - // 把action加入到pannel - SARibbonToolButton* addAction(QAction* action, SARibbonPannelItem::RowProportion rp); - + void addAction(QAction* action, SARibbonPannelItem::RowProportion rp); + // 生成并添加一个action + void addAction(QAction* act, QToolButton::ToolButtonPopupMode popMode, SARibbonPannelItem::RowProportion rp = SARibbonPannelItem::Large); // 把action加入到pannel,并以大图标显示 - SARibbonToolButton* addLargeAction(QAction* action); - + void addLargeAction(QAction* action); // 把action加入到pannel,在三行模式下会以中图标显示 - SARibbonToolButton* addMediumAction(QAction* action); - + void addMediumAction(QAction* action); // 把action加入到pannel,并以小图标显示 - SARibbonToolButton* addSmallAction(QAction* action); + void addSmallAction(QAction* action); - // 生成并添加一个action - void addAction(QAction* act, QToolButton::ToolButtonPopupMode popMode, SARibbonPannelItem::RowProportion rp = SARibbonPannelItem::Large); + // 把action加入到pannel,并以小图标显示 + void addSmallAction(QAction* action, QToolButton::ToolButtonPopupMode popMode); + // 把action加入到pannel,并以大图标显示 + void addLargeAction(QAction* action, QToolButton::ToolButtonPopupMode popMode); + // 把action加入到pannel,在三行模式下会以中图标显示 + void addMediumAction(QAction* action, QToolButton::ToolButtonPopupMode popMode); QAction* addAction(const QString& text, const QIcon& icon, @@ -1669,21 +1674,13 @@ class SA_RIBBON_EXPORT SARibbonPannel : public QWidget SARibbonPannelItem::RowProportion rp = SARibbonPannelItem::Large); // 添加menu - SARibbonToolButton* addMenu(QMenu* menu, - SARibbonPannelItem::RowProportion rp, - QToolButton::ToolButtonPopupMode popMode = QToolButton::InstantPopup); - - // 添加action menu - SARibbonToolButton* addActionMenu(QAction* action, QMenu* menu, SARibbonPannelItem::RowProportion rp); - - // action menu,action menu是一个特殊的menu,即可点击触发action,也可弹出菜单 - SARibbonToolButton* addLargeActionMenu(QAction* action, QMenu* menu); + void addMenu(QMenu* menu, SARibbonPannelItem::RowProportion rp, QToolButton::ToolButtonPopupMode popMode = QToolButton::InstantPopup); // 添加普通大菜单 - SARibbonToolButton* addLargeMenu(QMenu* menu, QToolButton::ToolButtonPopupMode popMode = QToolButton::InstantPopup); + void addLargeMenu(QMenu* menu, QToolButton::ToolButtonPopupMode popMode = QToolButton::InstantPopup); // 添加普通小按钮菜单 - SARibbonToolButton* addSmallMenu(QMenu* menu, QToolButton::ToolButtonPopupMode popMode = QToolButton::InstantPopup); + void addSmallMenu(QMenu* menu, QToolButton::ToolButtonPopupMode popMode = QToolButton::InstantPopup); // 添加窗口 QAction* addWidget(QWidget* w, SARibbonPannelItem::RowProportion rp); @@ -1698,7 +1695,7 @@ class SA_RIBBON_EXPORT SARibbonPannel : public QWidget QAction* addLargeWidget(QWidget* w); // 添加一个Gallery - SARibbonGallery* addGallery(); + SARibbonGallery* addGallery(bool expanding = true); // 添加分割线 QAction* addSeparator(int top = 6, int bottom = 6); @@ -1764,6 +1761,10 @@ class SA_RIBBON_EXPORT SARibbonPannel : public QWidget SARibbonPannelLayout* pannelLayout() const; // 更新布局 void updateItemGeometry(); + // 获取category指针,如果没有parent,或者不在category管理,返回nullptr + SARibbonCategory* category() const; + // 获取ribbonBar指针,如果没有返回nullptr + SARibbonBar* ribbonBar() const; signals: /** @@ -1772,6 +1773,16 @@ class SA_RIBBON_EXPORT SARibbonPannel : public QWidget */ void actionTriggered(QAction* action); +public: + // 把action的行属性设置进action中,action自身携带了行属性 + static void setActionRowProportionProperty(QAction* action, SARibbonPannelItem::RowProportion rp); + // 获取action的行属性 + static SARibbonPannelItem::RowProportion getActionRowProportionProperty(QAction* action); + // 把action的行属性设置进action中,action自身携带了行属性 + static void setActionToolButtonPopupModeProperty(QAction* action, QToolButton::ToolButtonPopupMode popMode); + // 获取action的行属性 + static QToolButton::ToolButtonPopupMode getActionToolButtonPopupModeProperty(QAction* action); + protected: // 设置PannelLayoutMode,此函数设置为protect避免误调用 void setPannelLayoutMode(PannelLayoutMode mode); @@ -1779,8 +1790,9 @@ class SA_RIBBON_EXPORT SARibbonPannel : public QWidget void resetLargeToolButtonStyle(); protected: - virtual void paintEvent(QPaintEvent* event) Q_DECL_OVERRIDE; - virtual void resizeEvent(QResizeEvent* event) Q_DECL_OVERRIDE; + virtual bool event(QEvent* e) Q_DECL_OVERRIDE; + virtual void paintEvent(QPaintEvent* e) Q_DECL_OVERRIDE; + virtual void resizeEvent(QResizeEvent* e) Q_DECL_OVERRIDE; virtual void actionEvent(QActionEvent* e) Q_DECL_OVERRIDE; virtual void changeEvent(QEvent* e) Q_DECL_OVERRIDE; }; @@ -1864,9 +1876,6 @@ class SA_RIBBON_EXPORT SARibbonCategory : public QWidget bool removePannel(SARibbonPannel* pannel); bool removePannel(int index); - // 设置背景 - void setBackgroundBrush(const QBrush& brush); - // 返回所有的Pannel QList< SARibbonPannel* > pannelList() const; @@ -1892,10 +1901,11 @@ class SA_RIBBON_EXPORT SARibbonCategory : public QWidget protected: // 设置pannel的模式 void setRibbonPannelLayoutMode(SARibbonPannel::PannelLayoutMode m); - bool eventFilter(QObject* watched, QEvent* event) Q_DECL_OVERRIDE; - + virtual bool event(QEvent* e) Q_DECL_OVERRIDE; // 处理滚轮事件 void wheelEvent(QWheelEvent* event) Q_DECL_OVERRIDE; + // + void changeEvent(QEvent* event) Q_DECL_OVERRIDE; // 标记这个是上下文标签 void markIsContextCategory(bool isContextCategory = true); @@ -1906,9 +1916,6 @@ class SA_RIBBON_EXPORT SARibbonCategory : public QWidget // 设置Category的对齐方式 void setCategoryAlignment(SARibbonAlignment al); SARibbonAlignment getCategoryAlignment() const; - -private: - void setRibbonBar(SARibbonBar* bar); }; /** @@ -2659,18 +2666,26 @@ class SA_RIBBON_EXPORT SARibbonBar : public QMenuBar // 是否显示隐藏ribbon按钮 bool haveShowMinimumModeButton() const; + // 隐藏ribbon对应的action + QAction* minimumModeAction() const; + // ribbon tab的高度 int tabBarHeight() const; - + void setTabBarHeight(int h); // 标题栏的高度 int titleBarHeight() const; - + void setTitleBarHeight(int h); + // 获取mainBar的高度 + int mainBarHeight() const; + void setMainBarHeight(int m); + // 最小模式下的MainBar高度 + int minimumModeMainBarHeight() const; // 激活tabbar右边的按钮群 - void activeRightButtonGroup(); - + SARibbonButtonGroupWidget* activeRightButtonGroup(); // 右侧按钮群 SARibbonButtonGroupWidget* rightButtonGroup(); - + // 激活QuickAccessBar + SARibbonQuickAccessBar* activeQuickAccessBar(); // 快速响应栏 SARibbonQuickAccessBar* quickAccessBar(); @@ -2759,14 +2774,18 @@ class SA_RIBBON_EXPORT SARibbonBar : public QMenuBar */ void ribbonStyleChanged(SARibbonBar::RibbonStyle nowStyle); + /** + @brief 标题栏高度发生了变化的信号 + @param oldHeight + @param newHeight + */ + void titleBarHeightChanged(int oldHeight, int newHeight); + protected: bool eventFilter(QObject* obj, QEvent* e) override; // 根据情况重置tabbar的宽度,主要针对wps模式 int calcMinTabBarWidth() const; - - // 根据currentRibbonStyle计算mainBar的高度 - virtual int mainBarHeight() const; // 更新 void updateCategoryTitleToTabName(); protected slots: @@ -2799,7 +2818,8 @@ protected slots: virtual void resizeEvent(QResizeEvent* e) Q_DECL_OVERRIDE; virtual void moveEvent(QMoveEvent* e) Q_DECL_OVERRIDE; virtual void changeEvent(QEvent* e) Q_DECL_OVERRIDE; - virtual void paintBackground(QPainter& painter); + virtual bool event(QEvent* e) Q_DECL_OVERRIDE; + virtual void paintTabbarBaseLine(QPainter& painter); virtual void paintWindowTitle(QPainter& painter, const QString& title, const QRect& titleRegion); virtual void paintContextCategoryTab(QPainter& painter, const QString& title, QRect contextRect, const QColor& color); }; @@ -2808,68 +2828,6 @@ protected slots: /*** End of inlined file: SARibbonBar.h ***/ -/*** Start of inlined file: SARibbonStyleOption.h ***/ -#ifndef SARIBBONSTYLEOPTION_H -#define SARIBBONSTYLEOPTION_H - -#include -/** - * @brief 定义了saribbon所有尺寸相关信息,saribbon的建立都基于此类的尺寸,如果想调整, - * 可以通过 @ref SARibbonElementCreateDelegate(通过SARibbonElementManager单例管理) 的 @ref setRibbonStyleOption 函数设置自己的SARibbonStyleOption - * - * @sa SARibbonElementManager - * - * 一般SARibbonElementCreateDelegate::setRibbonStyleOption函数最好在ribbonbar构建之前调用 - * - * @note 此类定义了ribbonbar和pannel的高度信息,并通过字体提前计算好一些布局信息 - * - * @todo 后续开发通过配置文件定义ribbon的尺寸布局 - */ -class SA_RIBBON_EXPORT SARibbonStyleOption -{ -public: - SARibbonStyleOption(); - virtual ~SARibbonStyleOption(); - -public: - // ribbonBar的高度 - virtual int ribbonBarHeight(SARibbonBar::RibbonStyle s) const; - - // 标题栏的高度,对于wps模式,此参数没有用 - virtual int titleBarHeight() const; - - // 标签栏高度 - virtual int tabBarHeight() const; - - // 在改变了参数后对需要计算的变量从新计算 - virtual void recalc(); - -protected: - // 通过已有参数计算pannel的高度 - // int calcPannelHeight(SARibbonPannel::PannelLayoutMode lm) const; - // 计算ribbon的高度 - int calcMainbarHeight(SARibbonBar::RibbonStyle s) const; - -private: - // 初始化 - void init(); - // 计算pannel的高度 - void updateMainbarHeight(); - -private: - int m_tabBarHeight; ///< ribbon tab 的高度 - int m_titleBarHeight; ///< 标题栏高度 - int m_ribbonbarHeightOfficeStyleThreeRow; ///< office样式的3行高度 - int m_ribbonbarHeightWPSStyleThreeRow; ///< wps样式3行的高度 - int m_ribbonbarHeightWPSStyleTwoRow; ///< wps样式2行的高度 - int m_ribbonbarHeightOfficeStyleTwoRow; ///< office样式2行的高度 -}; - -SA_RIBBON_EXPORT QDebug operator<<(QDebug debug, const SARibbonStyleOption& c); -#endif // SARIBBONSTYLEOPTION_H - -/*** End of inlined file: SARibbonStyleOption.h ***/ - /*** Start of inlined file: SARibbonElementFactory.h ***/ #ifndef SARIBBONELEMENTFACTORY_H #define SARIBBONELEMENTFACTORY_H @@ -2919,21 +2877,10 @@ class SA_RIBBON_EXPORT SARibbonElementFactory virtual SARibbonToolButton* createRibbonToolButton(QWidget* parent); virtual SARibbonControlButton* createRibbonControlButton(QWidget* parent); virtual SARibbonStackedWidget* createRibbonStackedWidget(SARibbonBar* parent); - - // 创建隐藏ribbon的按钮代理函数 - virtual SARibbonControlButton* createHidePannelButton(SARibbonBar* parent); virtual SARibbonButtonGroupWidget* craeteButtonGroupWidget(QWidget* parent); virtual SARibbonQuickAccessBar* createQuickAccessBar(QWidget* parent); - - // SARibbonStyleOption可以进行继承,此函数无需设置为虚函数 - SARibbonStyleOption& getRibbonStyleOption(); - void setRibbonStyleOption(SARibbonStyleOption* opt); - // 创建SARibbonPannelOptionButton virtual SARibbonPannelOptionButton* createRibbonPannelOptionButton(SARibbonPannel* pannel); - -private: - QScopedPointer< SARibbonStyleOption > mStyleOption; }; #endif // SARIBBONELEMENTCREATEDELEGATE_H @@ -3381,13 +3328,14 @@ class SA_RIBBON_EXPORT SARibbonCustomizeDialog : public QDialog #include "FramelessHelper/Widgets/framelessmainwindow.h" FRAMELESSHELPER_BEGIN_NAMESPACE class StandardTitleBar; +class FramelessWidgetsHelper; FRAMELESSHELPER_END_NAMESPACE #else class SAFramelessHelper; #endif class SARibbonBar; - +class SAWindowButtonGroup; /** * @brief 如果要使用SARibbonBar,必须使用此类代替QMainWindow * @@ -3448,6 +3396,8 @@ class SA_RIBBON_EXPORT SARibbonMainWindow : public QMainWindow SAFramelessHelper* framelessHelper(); // 把ribbonbar的事件传递到frameless virtual bool eventFilter(QObject* obj, QEvent* e) Q_DECL_OVERRIDE; +#else + FRAMELESSHELPER_PREPEND_NAMESPACE(FramelessWidgetsHelper*) framelessHelper(); #endif // 此函数仅用于控制最小最大化和关闭按钮的显示 void updateWindowFlag(Qt::WindowFlags flags); @@ -3457,6 +3407,8 @@ class SA_RIBBON_EXPORT SARibbonMainWindow : public QMainWindow RibbonTheme ribbonTheme() const; // 判断当前是否使用ribbon模式 bool isUseRibbon() const; + // 获取左上角按钮组(最大化,最小化,关闭) + SAWindowButtonGroup* windowButtonGroup() const; protected: // 创建ribbonbar的工厂函数 @@ -3467,6 +3419,8 @@ class SA_RIBBON_EXPORT SARibbonMainWindow : public QMainWindow private: // 安装ribbon void installRibbonBar(SARibbonBar* bar); + // 构建为普通窗口 + void setupNormalWindow(); }; /** diff --git a/src/SARibbonBar/SARibbonGlobal.h b/src/SARibbonBar/SARibbonGlobal.h index c2943370..51715a3a 100644 --- a/src/SARibbonBar/SARibbonGlobal.h +++ b/src/SARibbonBar/SARibbonGlobal.h @@ -9,10 +9,15 @@ @note My native language is not English, and most of the translation of documents is machine translation 版本记录(change log): - - 2023-12-25 -> 1.0.8 + + - 2023-12-25 -> 1.1.0 修正了尺寸刷新的问题,在首次显示不会出现控件跳动的状态 + 修正了一些问题 调整了创建RibbonButton的方式 调整了SARibbonPannel一些接口,使得创建更加规范 + 调整了ToolButton的渲染方式 + + ------------------------ - 2023-11-19 -> 1.0.6 添加Office2016主题 @@ -108,13 +113,13 @@ * @def ribbon的数字版本 MAJ.{MIN}.PAT */ #ifndef SA_RIBBON_BAR_VERSION_MIN -#define SA_RIBBON_BAR_VERSION_MIN 0 +#define SA_RIBBON_BAR_VERSION_MIN 1 #endif /** * @def ribbon的数字版本 MAJ.MIN.{PAT} */ #ifndef SA_RIBBON_BAR_VERSION_PAT -#define SA_RIBBON_BAR_VERSION_PAT 8 +#define SA_RIBBON_BAR_VERSION_PAT 0 #endif #ifndef SA_RIBBON_BAR_NO_EXPORT diff --git a/tools/amalgamate/SARibbonAmalgamTemplate.cpp b/tools/amalgamate/SARibbonAmalgamTemplate.cpp index fd043e5a..dac47b62 100644 --- a/tools/amalgamate/SARibbonAmalgamTemplate.cpp +++ b/tools/amalgamate/SARibbonAmalgamTemplate.cpp @@ -32,7 +32,6 @@ #include "../../src/SARibbonBar/SARibbonColorToolButton.cpp" #include "../../src/SARibbonBar/SARibbonLineWidgetContainer.cpp" #include "../../src/SARibbonBar/SARibbonActionsManager.cpp" -#include "../../src/SARibbonBar/SARibbonDrawHelper.cpp" #include "../../src/SARibbonBar/SARibbonLineEdit.cpp" #include "../../src/SARibbonBar/SARibbonCheckBox.cpp" #include "../../src/SARibbonBar/SARibbonComboBox.cpp" @@ -56,7 +55,6 @@ #include "../../src/SARibbonBar/SARibbonGalleryGroup.cpp" #include "../../src/SARibbonBar/SARibbonGallery.cpp" #include "../../src/SARibbonBar/SARibbonBar.cpp" -#include "../../src/SARibbonBar/SARibbonStyleOption.cpp" #include "../../src/SARibbonBar/SARibbonElementFactory.cpp" #include "../../src/SARibbonBar/SARibbonElementManager.cpp" #include "../../src/SARibbonBar/SARibbonCustomizeData.cpp" diff --git a/tools/amalgamate/SARibbonAmalgamTemplatePublicHeaders.h b/tools/amalgamate/SARibbonAmalgamTemplatePublicHeaders.h index ca04a188..f3342282 100644 --- a/tools/amalgamate/SARibbonAmalgamTemplatePublicHeaders.h +++ b/tools/amalgamate/SARibbonAmalgamTemplatePublicHeaders.h @@ -14,7 +14,6 @@ #include "../../src/SARibbonBar/SARibbonColorToolButton.h" #include "../../src/SARibbonBar/SARibbonLineWidgetContainer.h" #include "../../src/SARibbonBar/SARibbonActionsManager.h" -#include "../../src/SARibbonBar/SARibbonDrawHelper.h" #include "../../src/SARibbonBar/SARibbonLineEdit.h" #include "../../src/SARibbonBar/SARibbonCheckBox.h" #include "../../src/SARibbonBar/SARibbonComboBox.h" @@ -38,7 +37,6 @@ #include "../../src/SARibbonBar/SARibbonGalleryGroup.h" #include "../../src/SARibbonBar/SARibbonGallery.h" #include "../../src/SARibbonBar/SARibbonBar.h" -#include "../../src/SARibbonBar/SARibbonStyleOption.h" #include "../../src/SARibbonBar/SARibbonElementFactory.h" #include "../../src/SARibbonBar/SARibbonElementManager.h" #include "../../src/SARibbonBar/SARibbonCustomizeData.h"