diff options
Diffstat (limited to 'src/widgets/styles')
37 files changed, 250 insertions, 113 deletions
diff --git a/src/widgets/styles/images/titlebar-contexthelp-16.png b/src/widgets/styles/images/titlebar-contexthelp-16.png Binary files differnew file mode 100644 index 0000000000..2cead19910 --- /dev/null +++ b/src/widgets/styles/images/titlebar-contexthelp-16.png diff --git a/src/widgets/styles/images/titlebar-contexthelp-32.png b/src/widgets/styles/images/titlebar-contexthelp-32.png Binary files differnew file mode 100644 index 0000000000..1cd4843d5e --- /dev/null +++ b/src/widgets/styles/images/titlebar-contexthelp-32.png diff --git a/src/widgets/styles/images/titlebar-contexthelp-48.png b/src/widgets/styles/images/titlebar-contexthelp-48.png Binary files differnew file mode 100644 index 0000000000..9b170687be --- /dev/null +++ b/src/widgets/styles/images/titlebar-contexthelp-48.png diff --git a/src/widgets/styles/images/titlebar-max-16.png b/src/widgets/styles/images/titlebar-max-16.png Binary files differnew file mode 100644 index 0000000000..101a7eac2b --- /dev/null +++ b/src/widgets/styles/images/titlebar-max-16.png diff --git a/src/widgets/styles/images/titlebar-max-32.png b/src/widgets/styles/images/titlebar-max-32.png Binary files differnew file mode 100644 index 0000000000..529c54f61d --- /dev/null +++ b/src/widgets/styles/images/titlebar-max-32.png diff --git a/src/widgets/styles/images/titlebar-max-48.png b/src/widgets/styles/images/titlebar-max-48.png Binary files differnew file mode 100644 index 0000000000..cfa0b67edf --- /dev/null +++ b/src/widgets/styles/images/titlebar-max-48.png diff --git a/src/widgets/styles/images/titlebar-min-16.png b/src/widgets/styles/images/titlebar-min-16.png Binary files differnew file mode 100644 index 0000000000..95e714b522 --- /dev/null +++ b/src/widgets/styles/images/titlebar-min-16.png diff --git a/src/widgets/styles/images/titlebar-min-32.png b/src/widgets/styles/images/titlebar-min-32.png Binary files differnew file mode 100644 index 0000000000..0b9afedecf --- /dev/null +++ b/src/widgets/styles/images/titlebar-min-32.png diff --git a/src/widgets/styles/images/titlebar-min-48.png b/src/widgets/styles/images/titlebar-min-48.png Binary files differnew file mode 100644 index 0000000000..b59a336d36 --- /dev/null +++ b/src/widgets/styles/images/titlebar-min-48.png diff --git a/src/widgets/styles/images/titlebar-shade-16.png b/src/widgets/styles/images/titlebar-shade-16.png Binary files differnew file mode 100644 index 0000000000..cc870a1e5c --- /dev/null +++ b/src/widgets/styles/images/titlebar-shade-16.png diff --git a/src/widgets/styles/images/titlebar-shade-32.png b/src/widgets/styles/images/titlebar-shade-32.png Binary files differnew file mode 100644 index 0000000000..b785b8e216 --- /dev/null +++ b/src/widgets/styles/images/titlebar-shade-32.png diff --git a/src/widgets/styles/images/titlebar-shade-48.png b/src/widgets/styles/images/titlebar-shade-48.png Binary files differnew file mode 100644 index 0000000000..42b75b4a0c --- /dev/null +++ b/src/widgets/styles/images/titlebar-shade-48.png diff --git a/src/widgets/styles/images/titlebar-unshade-16.png b/src/widgets/styles/images/titlebar-unshade-16.png Binary files differnew file mode 100644 index 0000000000..ef19de6c2f --- /dev/null +++ b/src/widgets/styles/images/titlebar-unshade-16.png diff --git a/src/widgets/styles/images/titlebar-unshade-32.png b/src/widgets/styles/images/titlebar-unshade-32.png Binary files differnew file mode 100644 index 0000000000..9f74bb0ac7 --- /dev/null +++ b/src/widgets/styles/images/titlebar-unshade-32.png diff --git a/src/widgets/styles/images/titlebar-unshade-48.png b/src/widgets/styles/images/titlebar-unshade-48.png Binary files differnew file mode 100644 index 0000000000..bd17c3cf48 --- /dev/null +++ b/src/widgets/styles/images/titlebar-unshade-48.png diff --git a/src/widgets/styles/images/toolbar-ext-h-16.png b/src/widgets/styles/images/toolbar-ext-h-16.png Binary files differnew file mode 100644 index 0000000000..c6bd1b1784 --- /dev/null +++ b/src/widgets/styles/images/toolbar-ext-h-16.png diff --git a/src/widgets/styles/images/toolbar-ext-h-32.png b/src/widgets/styles/images/toolbar-ext-h-32.png Binary files differnew file mode 100644 index 0000000000..99c62698f2 --- /dev/null +++ b/src/widgets/styles/images/toolbar-ext-h-32.png diff --git a/src/widgets/styles/images/toolbar-ext-h-8.png b/src/widgets/styles/images/toolbar-ext-h-8.png Binary files differnew file mode 100644 index 0000000000..340a374bce --- /dev/null +++ b/src/widgets/styles/images/toolbar-ext-h-8.png diff --git a/src/widgets/styles/images/toolbar-ext-h-rtl-16.png b/src/widgets/styles/images/toolbar-ext-h-rtl-16.png Binary files differnew file mode 100644 index 0000000000..31c72892b4 --- /dev/null +++ b/src/widgets/styles/images/toolbar-ext-h-rtl-16.png diff --git a/src/widgets/styles/images/toolbar-ext-h-rtl-32.png b/src/widgets/styles/images/toolbar-ext-h-rtl-32.png Binary files differnew file mode 100644 index 0000000000..bfc333daac --- /dev/null +++ b/src/widgets/styles/images/toolbar-ext-h-rtl-32.png diff --git a/src/widgets/styles/images/toolbar-ext-h-rtl-8.png b/src/widgets/styles/images/toolbar-ext-h-rtl-8.png Binary files differnew file mode 100644 index 0000000000..538e408310 --- /dev/null +++ b/src/widgets/styles/images/toolbar-ext-h-rtl-8.png diff --git a/src/widgets/styles/images/toolbar-ext.png b/src/widgets/styles/images/toolbar-ext-macstyle.png Binary files differindex 37bd403ff8..37bd403ff8 100644 --- a/src/widgets/styles/images/toolbar-ext.png +++ b/src/widgets/styles/images/toolbar-ext-macstyle.png diff --git a/src/widgets/styles/images/toolbar-ext@2x.png b/src/widgets/styles/images/toolbar-ext-macstyle@2x.png Binary files differindex 6fc729efb0..6fc729efb0 100644 --- a/src/widgets/styles/images/toolbar-ext@2x.png +++ b/src/widgets/styles/images/toolbar-ext-macstyle@2x.png diff --git a/src/widgets/styles/images/toolbar-ext-v-10.png b/src/widgets/styles/images/toolbar-ext-v-10.png Binary files differnew file mode 100644 index 0000000000..2a6d0e4c70 --- /dev/null +++ b/src/widgets/styles/images/toolbar-ext-v-10.png diff --git a/src/widgets/styles/images/toolbar-ext-v-20.png b/src/widgets/styles/images/toolbar-ext-v-20.png Binary files differnew file mode 100644 index 0000000000..adc27f52b5 --- /dev/null +++ b/src/widgets/styles/images/toolbar-ext-v-20.png diff --git a/src/widgets/styles/images/toolbar-ext-v-5.png b/src/widgets/styles/images/toolbar-ext-v-5.png Binary files differnew file mode 100644 index 0000000000..21c670446c --- /dev/null +++ b/src/widgets/styles/images/toolbar-ext-v-5.png diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 735ae6b080..66f5f4876e 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -938,55 +938,53 @@ void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewIt viewItemTextLayout(textLayout, textRect.width()); - QString elidedText; - qreal height = 0; - qreal width = 0; - int elidedIndex = -1; - const int lineCount = textLayout.lineCount(); - for (int j = 0; j < lineCount; ++j) { - const QTextLine line = textLayout.lineAt(j); - if (j + 1 <= lineCount - 1) { - const QTextLine nextLine = textLayout.lineAt(j + 1); - if ((nextLine.y() + nextLine.height()) > textRect.height()) { - int start = line.textStart(); - int length = line.textLength() + nextLine.textLength(); - const QStackTextEngine engine(textLayout.text().mid(start, length), option->font); - elidedText = engine.elidedText(option->textElideMode, textRect.width()); - height += line.height(); - width = textRect.width(); - elidedIndex = j; - break; - } - } - if (line.naturalTextWidth() > textRect.width()) { - int start = line.textStart(); - int length = line.textLength(); - const QStackTextEngine engine(textLayout.text().mid(start, length), option->font); - elidedText = engine.elidedText(option->textElideMode, textRect.width()); - height += line.height(); - width = textRect.width(); - elidedIndex = j; - break; - } - width = qMax<qreal>(width, line.width()); - height += line.height(); - } - + const QRectF boundingRect = textLayout.boundingRect(); const QRect layoutRect = QStyle::alignedRect(option->direction, option->displayAlignment, - QSize(int(width), int(height)), textRect); + boundingRect.size().toSize(), textRect); const QPointF position = layoutRect.topLeft(); + const int lineCount = textLayout.lineCount(); + + qreal height = 0; for (int i = 0; i < lineCount; ++i) { const QTextLine line = textLayout.lineAt(i); - if (i == elidedIndex) { - qreal x = position.x() + line.x(); - qreal y = position.y() + line.y() + line.ascent(); + height += line.height(); + + // above visible rect + if (height + layoutRect.top() <= textRect.top()) + continue; + + const int start = line.textStart(); + const int length = line.textLength(); + + const bool drawElided = line.naturalTextWidth() > textRect.width(); + bool elideLastVisibleLine = false; + if (!drawElided && i + 1 < lineCount) { + const QTextLine nextLine = textLayout.lineAt(i + 1); + const int nextHeight = height + nextLine.height() / 2; + // elide when less than the next half line is visible + if (nextHeight + layoutRect.top() > textRect.height() + textRect.top()) + elideLastVisibleLine = true; + } + + if (drawElided || elideLastVisibleLine) { + QString text = textLayout.text().mid(start, length); + if (elideLastVisibleLine) + text += QChar(0x2026); + const QStackTextEngine engine(text, option->font); + const QString elidedText = engine.elidedText(option->textElideMode, textRect.width()); + const QPointF pos(position.x() + line.x(), + position.y() + line.y() + line.ascent()); p->save(); p->setFont(option->font); - p->drawText(QPointF(x, y), elidedText); + p->drawText(pos, elidedText); p->restore(); - break; + } else { + line.draw(p, position); } - line.draw(p, position); + + // below visible text, can stop + if (height + layoutRect.top() >= textRect.bottom()) + break; } } @@ -1675,8 +1673,9 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, alignment |= Qt::AlignLeft | Qt::AlignVCenter; } tr.translate(shiftX, shiftY); + const QString text = toolbutton->fontMetrics.elidedText(toolbutton->text, Qt::ElideMiddle, tr.width()); proxy()->drawItemText(p, QStyle::visualRect(opt->direction, rect, tr), alignment, toolbutton->palette, - toolbutton->state & State_Enabled, toolbutton->text, + toolbutton->state & State_Enabled, text, QPalette::ButtonText); } else { rect.translate(shiftX, shiftY); @@ -2863,8 +2862,8 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt, case SE_TabBarScrollLeftButton: { const bool vertical = opt->rect.width() < opt->rect.height(); const Qt::LayoutDirection ld = widget->layoutDirection(); - const int buttonWidth = qMax(pixelMetric(QStyle::PM_TabBarScrollButtonWidth, 0, widget), QApplication::globalStrut().width()); - const int buttonOverlap = pixelMetric(QStyle::PM_TabBar_ScrollButtonOverlap, 0, widget); + const int buttonWidth = qMax(proxy()->pixelMetric(QStyle::PM_TabBarScrollButtonWidth, 0, widget), QApplication::globalStrut().width()); + const int buttonOverlap = proxy()->pixelMetric(QStyle::PM_TabBar_ScrollButtonOverlap, 0, widget); r = vertical ? QRect(0, opt->rect.height() - (buttonWidth * 2) + buttonOverlap, opt->rect.width(), buttonWidth) : QStyle::visualRect(ld, opt->rect, QRect(opt->rect.width() - (buttonWidth * 2) + buttonOverlap, 0, buttonWidth, opt->rect.height())); @@ -2872,7 +2871,7 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt, case SE_TabBarScrollRightButton: { const bool vertical = opt->rect.width() < opt->rect.height(); const Qt::LayoutDirection ld = widget->layoutDirection(); - const int buttonWidth = qMax(pixelMetric(QStyle::PM_TabBarScrollButtonWidth, 0, widget), QApplication::globalStrut().width()); + const int buttonWidth = qMax(proxy()->pixelMetric(QStyle::PM_TabBarScrollButtonWidth, 0, widget), QApplication::globalStrut().width()); r = vertical ? QRect(0, opt->rect.height() - buttonWidth, opt->rect.width(), buttonWidth) : QStyle::visualRect(ld, opt->rect, QRect(opt->rect.width() - buttonWidth, 0, buttonWidth, opt->rect.height())); @@ -3087,7 +3086,7 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt, //have all the information we need (ie. the layout's margin) const QToolBar *tb = qobject_cast<const QToolBar*>(widget); const int margin = tb && tb->layout() ? tb->layout()->margin() : 2; - const int handleExtent = pixelMetric(QStyle::PM_ToolBarHandleExtent, opt, tb); + const int handleExtent = proxy()->pixelMetric(QStyle::PM_ToolBarHandleExtent, opt, tb); if (tbopt->state & QStyle::State_Horizontal) { r = QRect(margin, margin, handleExtent, tbopt->rect.height() - 2*margin); r = QStyle::visualRect(tbopt->direction, tbopt->rect, r); @@ -4942,8 +4941,8 @@ QSize QCommonStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, case CT_SpinBox: if (const QStyleOptionSpinBox *vopt = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) { // Add button + frame widths - int buttonWidth = 20; - int fw = vopt->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, vopt, widget) : 0; + const int buttonWidth = (vopt->subControls & (QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown)) != 0 ? 20 : 0; + const int fw = vopt->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, vopt, widget) : 0; sz += QSize(buttonWidth + 2*fw, 2*fw); } break; @@ -5312,6 +5311,9 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget case SH_SpinBox_ButtonsInsideFrame: ret = true; break; + case SH_SpinBox_StepModifier: + ret = Qt::ControlModifier; + break; default: ret = 0; break; @@ -5724,14 +5726,14 @@ static inline QString iconPngSuffix() { return QStringLiteral(".png"); } static void addIconFiles(const QString &prefix, const int sizes[], size_t count, QIcon &icon) { - for (size_t i = 0; i < count; ++i) { - const int size = sizes[i]; - icon.addFile(prefix + QString::number(size) + iconPngSuffix(), QSize(size, size)); - } + for (size_t i = 0; i < count; ++i) + icon.addFile(prefix + QString::number(sizes[i]) + iconPngSuffix()); } static const int dockTitleIconSizes[] = {10, 16, 20, 32, 48, 64}; - +static const int titleBarSizes[] = {16, 32, 48}; +static const int toolBarExtHSizes[] = {8, 16, 32}; +static const int toolBarExtVSizes[] = {5, 10, 20}; #endif // imageformat_png /*! @@ -6046,6 +6048,27 @@ QIcon QCommonStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption switch (standardIcon) { #ifndef QT_NO_IMAGEFORMAT_PNG + case SP_TitleBarMinButton: + addIconFiles(iconResourcePrefix() + QStringLiteral("titlebar-min-"), + titleBarSizes, sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon); + break; + case SP_TitleBarMaxButton: + addIconFiles(iconResourcePrefix() + QStringLiteral("titlebar-max-"), + titleBarSizes, sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon); + break; + case SP_TitleBarShadeButton: + addIconFiles(iconResourcePrefix() + QStringLiteral("titlebar-shade-"), + titleBarSizes, sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon); + + break; + case SP_TitleBarUnshadeButton: + addIconFiles(iconResourcePrefix() + QStringLiteral("titlebar-unshade-"), + titleBarSizes, sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon); + break; + case SP_TitleBarContextHelpButton: + addIconFiles(iconResourcePrefix() + QStringLiteral("titlebar-contexthelp-"), + titleBarSizes, sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon); + break; case SP_FileDialogNewFolder: icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/newdirectory-16.png"), QSize(16, 16)); icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/newdirectory-32.png"), QSize(32, 32)); @@ -6254,6 +6277,17 @@ QIcon QCommonStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption addIconFiles(iconResourcePrefix() + QStringLiteral("normalizedockup-"), dockTitleIconSizes, sizeof(dockTitleIconSizes)/sizeof(dockTitleIconSizes[0]), icon); break; + case SP_ToolBarHorizontalExtensionButton: { + QString prefix = iconResourcePrefix() + QStringLiteral("toolbar-ext-h-"); + if (rtl) + prefix += QStringLiteral("rtl-"); + addIconFiles(prefix, toolBarExtHSizes, sizeof(toolBarExtHSizes)/sizeof(toolBarExtHSizes[0]), icon); + } + break; + case SP_ToolBarVerticalExtensionButton: + addIconFiles(iconResourcePrefix() + QStringLiteral("toolbar-ext-v-"), + toolBarExtVSizes, sizeof(toolBarExtVSizes)/sizeof(toolBarExtVSizes[0]), icon); + break; #endif // QT_NO_IMAGEFORMAT_PNG default: icon.addPixmap(proxy()->standardPixmap(standardIcon, option, widget)); diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp index 73a6554f1a..8006be8c27 100644 --- a/src/widgets/styles/qstyle.cpp +++ b/src/widgets/styles/qstyle.cpp @@ -2001,6 +2001,13 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, Determnines if the spin box buttons are inside the line edit frame. This enum value has been introduced in Qt 5.11. + \value SH_SpinBox_StepModifier + Determines which Qt::KeyboardModifier increases the step rate of + QAbstractSpinBox. Possible values are Qt::NoModifier, + Qt::ControlModifier (default) or Qt::ShiftModifier. Qt::NoModifier + disables this feature. + This enum value has been introduced in Qt 5.12. + \sa styleHint() */ diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h index cef569d514..9192dae864 100644 --- a/src/widgets/styles/qstyle.h +++ b/src/widgets/styles/qstyle.h @@ -741,6 +741,7 @@ public: SH_Widget_Animation_Duration, SH_ComboBox_AllowWheelScrolling, SH_SpinBox_ButtonsInsideFrame, + SH_SpinBox_StepModifier, // Add new style hint values here SH_CustomBase = 0xf0000000 diff --git a/src/widgets/styles/qstyle.qrc b/src/widgets/styles/qstyle.qrc index 2dc3207e6d..d3511ee754 100644 --- a/src/widgets/styles/qstyle.qrc +++ b/src/widgets/styles/qstyle.qrc @@ -140,13 +140,37 @@ <file>images/normalizedockup-32.png</file> <file>images/normalizedockup-48.png</file> <file>images/normalizedockup-64.png</file> + <file>images/toolbar-ext-h-8.png</file> + <file>images/toolbar-ext-h-16.png</file> + <file>images/toolbar-ext-h-32.png</file> + <file>images/toolbar-ext-h-rtl-8.png</file> + <file>images/toolbar-ext-h-rtl-16.png</file> + <file>images/toolbar-ext-h-rtl-32.png</file> + <file>images/toolbar-ext-v-5.png</file> + <file>images/toolbar-ext-v-10.png</file> + <file>images/toolbar-ext-v-20.png</file> + <file>images/titlebar-contexthelp-16.png</file> + <file>images/titlebar-contexthelp-32.png</file> + <file>images/titlebar-contexthelp-48.png</file> + <file>images/titlebar-max-16.png</file> + <file>images/titlebar-max-32.png</file> + <file>images/titlebar-max-48.png</file> + <file>images/titlebar-min-16.png</file> + <file>images/titlebar-min-32.png</file> + <file>images/titlebar-min-48.png</file> + <file>images/titlebar-shade-16.png</file> + <file>images/titlebar-shade-32.png</file> + <file>images/titlebar-shade-48.png</file> + <file>images/titlebar-unshade-16.png</file> + <file>images/titlebar-unshade-32.png</file> + <file>images/titlebar-unshade-48.png</file> </qresource> <qresource prefix="/qt-project.org/styles/macstyle"> <file alias="images/closedock-16.png">images/closedock-macstyle-16.png</file> <file alias="images/closedock-down-16.png">images/closedock-down-macstyle-16.png</file> <file alias="images/dockdock-16.png">images/dockdock-macstyle-16.png</file> <file alias="images/dockdock-down-16.png">images/dockdock-down-macstyle-16.png</file> - <file>images/toolbar-ext.png</file> - <file>images/toolbar-ext@2x.png</file> + <file alias="images/toolbar-ext.png">images/toolbar-ext-macstyle.png</file> + <file alias="images/toolbar-ext@2x.png">images/toolbar-ext-macstyle@2x.png</file> </qresource> </RCC> diff --git a/src/widgets/styles/qstylehelper.cpp b/src/widgets/styles/qstylehelper.cpp index 8679d96eda..0b910d46df 100644 --- a/src/widgets/styles/qstylehelper.cpp +++ b/src/widgets/styles/qstylehelper.cpp @@ -403,14 +403,6 @@ QColor backgroundColor(const QPalette &pal, const QWidget* widget) return pal.color(QPalette::Base); } -QWindow *styleObjectWindow(QObject *so) -{ - if (so) - return so->property("_q_styleObjectWindow").value<QWindow *>(); - - return 0; -} - WidgetSizePolicy widgetSizePolicy(const QWidget *widget, const QStyleOption *opt) { while (widget) { diff --git a/src/widgets/styles/qstylehelper_p.h b/src/widgets/styles/qstylehelper_p.h index 260860bf4d..d79dfe4288 100644 --- a/src/widgets/styles/qstylehelper_p.h +++ b/src/widgets/styles/qstylehelper_p.h @@ -90,7 +90,6 @@ namespace QStyleHelper Q_WIDGETS_EXPORT bool hasAncestor(QObject *obj, QAccessible::Role role); #endif Q_WIDGETS_EXPORT QColor backgroundColor(const QPalette &pal, const QWidget* widget = 0); - Q_WIDGETS_EXPORT QWindow *styleObjectWindow(QObject *so); enum WidgetSizePolicy { SizeLarge = 0, SizeSmall = 1, SizeMini = 2, SizeDefault = -1 }; diff --git a/src/widgets/styles/qstyleoption.cpp b/src/widgets/styles/qstyleoption.cpp index e7fa26e2d4..97631a5841 100644 --- a/src/widgets/styles/qstyleoption.cpp +++ b/src/widgets/styles/qstyleoption.cpp @@ -1842,10 +1842,12 @@ QStyleOptionMenuItem::QStyleOptionMenuItem(int version) /*! \variable QStyleOptionMenuItem::tabWidth - \brief the tab width for the menu item + \brief the reserved width for the menu item's shortcut - The tab width is the distance between the text of the menu item - and the shortcut. The default value is 0. + QMenu sets it to the width occupied by the widest shortcut among + all visible items within the menu. + + The default value is 0. */ diff --git a/src/widgets/styles/qstyleoption.h b/src/widgets/styles/qstyleoption.h index 9fbaf34a86..8ae07efc81 100644 --- a/src/widgets/styles/qstyleoption.h +++ b/src/widgets/styles/qstyleoption.h @@ -366,7 +366,7 @@ public: QString text; QIcon icon; int maxIconWidth; - int tabWidth; + int tabWidth; // ### Qt 6: rename to reservedShortcutWidth QFont font; QStyleOptionMenuItem(); diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index ceede9e72f..71c7f5449a 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -117,6 +117,8 @@ #include <QtWidgets/qtoolbar.h> #endif +#include <QtGui/qscreen.h> + QT_BEGIN_NAMESPACE using namespace QCss; @@ -532,6 +534,8 @@ public: const QStyleSheetGeometryData *geometry() const { return geo; } const QStyleSheetPositionData *position() const { return p; } + bool hasModification() const; + bool hasPalette() const { return pal != 0; } bool hasBackground() const { return bg != 0 && (!bg->pixmap.isNull() || bg->brush.style() != Qt::NoBrush); } bool hasGradientBackground() const { return bg && bg->brush.style() >= Qt::LinearGradientPattern @@ -952,8 +956,10 @@ QRenderRule::QRenderRule(const QVector<Declaration> &declarations, const QObject Attachment attachment = Attachment_Scroll; origin = Origin_Padding; Origin clip = Origin_Border; - if (v.extractBackground(&brush, &uri, &repeat, &alignment, &origin, &attachment, &clip)) - bg = new QStyleSheetBackgroundData(brush, QPixmap(uri), repeat, alignment, origin, attachment, clip); + if (v.extractBackground(&brush, &uri, &repeat, &alignment, &origin, &attachment, &clip)) { + bg = new QStyleSheetBackgroundData(brush, QStyleSheetStyle::loadPixmap(uri, object), + repeat, alignment, origin, attachment, clip); + } QBrush sfg, fg; QBrush sbg, abg; @@ -992,7 +998,7 @@ QRenderRule::QRenderRule(const QVector<Declaration> &declarations, const QObject bd->bi = new QStyleSheetBorderImageData; QStyleSheetBorderImageData *bi = bd->bi; - bi->pixmap = QPixmap(uri); + bi->pixmap = QStyleSheetStyle::loadPixmap(uri, object); for (int i = 0; i < 4; i++) bi->cuts[i] = cuts[i]; bi->horizStretch = horizStretch; @@ -1043,7 +1049,7 @@ QRenderRule::QRenderRule(const QVector<Declaration> &declarations, const QObject if (const QWidget *widget = qobject_cast<const QWidget *>(object)) { QStyleSheetStyle *style = const_cast<QStyleSheetStyle *>(globalStyleSheetStyle); if (!style) - style = qobject_cast<QStyleSheetStyle *>(widget->style()); + style = qt_styleSheet(widget->style()); if (style) fixupBorder(style->nativeFrameWidth(widget)); } @@ -1215,30 +1221,33 @@ void QRenderRule::drawBackgroundImage(QPainter *p, const QRect &rect, QPoint off if (background()->attachment == Attachment_Fixed) off = QPoint(0, 0); + QSize bgpSize = bgp.size() / bgp.devicePixelRatio(); + int bgpHeight = bgpSize.height(); + int bgpWidth = bgpSize.width(); QRect r = originRect(rect, background()->origin); - QRect aligned = QStyle::alignedRect(Qt::LeftToRight, background()->position, bgp.size(), r); + QRect aligned = QStyle::alignedRect(Qt::LeftToRight, background()->position, bgpSize, r); QRect inter = aligned.translated(-off).intersected(r); switch (background()->repeat) { case Repeat_Y: p->drawTiledPixmap(inter.x(), r.y(), inter.width(), r.height(), bgp, inter.x() - aligned.x() + off.x(), - bgp.height() - int(aligned.y() - r.y()) % bgp.height() + off.y()); + bgpHeight - int(aligned.y() - r.y()) % bgpHeight + off.y()); break; case Repeat_X: p->drawTiledPixmap(r.x(), inter.y(), r.width(), inter.height(), bgp, - bgp.width() - int(aligned.x() - r.x())%bgp.width() + off.x(), + bgpWidth - int(aligned.x() - r.x())%bgpWidth + off.x(), inter.y() - aligned.y() + off.y()); break; case Repeat_XY: p->drawTiledPixmap(r, bgp, - QPoint(bgp.width() - int(aligned.x() - r.x())% bgp.width() + off.x(), - bgp.height() - int(aligned.y() - r.y())%bgp.height() + off.y())); + QPoint(bgpWidth - int(aligned.x() - r.x())% bgpWidth + off.x(), + bgpHeight - int(aligned.y() - r.y())%bgpHeight + off.y())); break; case Repeat_None: default: p->drawPixmap(inter.x(), inter.y(), bgp, inter.x() - aligned.x() + off.x(), - inter.y() - aligned.y() + off.y(), inter.width(), inter.height()); + inter.y() - aligned.y() + off.y(), bgp.width() , bgp.height()); break; } @@ -1446,6 +1455,21 @@ void QRenderRule::configurePalette(QPalette *p, QPalette::ColorGroup cg, const Q p->setBrush(cg, QPalette::AlternateBase, pal->alternateBackground); } +bool QRenderRule::hasModification() const +{ + return hasPalette() || + hasBackground() || + hasGradientBackground() || + !hasNativeBorder() || + !hasNativeOutline() || + hasBox() || + hasPosition() || + hasGeometry() || + hasImage() || + hasFont || + !styleHints.isEmpty(); +} + /////////////////////////////////////////////////////////////////////////////// // Style rules #define OBJECT_PTR(x) (static_cast<QObject *>(x.ptr)) @@ -1504,7 +1528,7 @@ public: return className; } else if (name == QLatin1String("style")) { QWidget *w = qobject_cast<QWidget *>(obj); - QStyleSheetStyle *proxy = w ? qobject_cast<QStyleSheetStyle *>(w->style()) : 0; + QStyleSheetStyle *proxy = w ? qt_styleSheet(w->style()) : 0; if (proxy) { QString styleName = QString::fromLatin1(proxy->baseStyle()->metaObject()->className()); cache[name] = styleName; @@ -1925,11 +1949,11 @@ QRenderRule QStyleSheetStyle::renderRule(const QObject *obj, const QStyleOption break; case QTabBar::RoundedEast: case QTabBar::TriangularEast: - extraClass |= PseudoClass_Left; + extraClass |= PseudoClass_Right; break; case QTabBar::RoundedWest: case QTabBar::TriangularWest: - extraClass |= PseudoClass_Right; + extraClass |= PseudoClass_Left; break; default: break; @@ -1962,11 +1986,11 @@ QRenderRule QStyleSheetStyle::renderRule(const QObject *obj, const QStyleOption break; case QTabBar::RoundedEast: case QTabBar::TriangularEast: - extraClass |= PseudoClass_Left; + extraClass |= PseudoClass_Right; break; case QTabBar::RoundedWest: case QTabBar::TriangularWest: - extraClass |= PseudoClass_Right; + extraClass |= PseudoClass_Left; break; default: break; @@ -2736,7 +2760,7 @@ QStyle *QStyleSheetStyle::baseStyle() const { if (base) return base; - if (QStyleSheetStyle *me = qobject_cast<QStyleSheetStyle *>(QApplication::style())) + if (QStyleSheetStyle *me = qt_styleSheet(QApplication::style())) return me->base; return QApplication::style(); } @@ -2825,6 +2849,9 @@ void QStyleSheetStyle::polish(QWidget *w) #endif QRenderRule rule = renderRule(w, PseudoElement_None, PseudoClass_Any); + + w->setAttribute(Qt::WA_StyleSheetTarget, rule.hasModification()); + if (rule.hasDrawable() || rule.hasBox()) { if (w->metaObject() == &QWidget::staticMetaObject #if QT_CONFIG(itemviews) @@ -2908,6 +2935,7 @@ void QStyleSheetStyle::unpolish(QWidget *w) styleSheetCaches->styleSheetCache.remove(w); unsetPalette(w); setGeometry(w); + w->setAttribute(Qt::WA_StyleSheetTarget, false); w->setAttribute(Qt::WA_StyleSheet, false); QObject::disconnect(w, 0, this, 0); #if QT_CONFIG(scrollarea) @@ -3672,6 +3700,17 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q bool dis = !(opt->state & QStyle::State_Enabled), act = opt->state & QStyle::State_Selected; + int checkableOffset = 0; + if (checkable) { + QRenderRule subSubRule = renderRule(w, opt, PseudoElement_MenuCheckMark); + QStyleOptionMenuItem newMi = mi; + newMi.rect = positionRect(w, subRule, subSubRule, PseudoElement_MenuCheckMark, opt->rect, opt->direction); + checkableOffset = newMi.rect.width(); + if (subSubRule.hasDrawable() || checked) + drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, w); + } + + int iconOffset = 0; if (!mi.icon.isNull()) { QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal; if (act && !dis) @@ -3691,20 +3730,22 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q iconRule.geo->height = pixh; } QRect iconRect = positionRect(w, subRule, iconRule, PseudoElement_MenuIcon, opt->rect, opt->direction); + if (opt->direction == Qt::LeftToRight) + iconRect.moveLeft(iconRect.left() + checkableOffset); + else + iconRect.moveRight(iconRect.right() - checkableOffset); iconRule.drawRule(p, iconRect); QRect pmr(0, 0, pixw, pixh); pmr.moveCenter(iconRect.center()); p->drawPixmap(pmr.topLeft(), pixmap); - } else if (checkable) { - QRenderRule subSubRule = renderRule(w, opt, PseudoElement_MenuCheckMark); - if (subSubRule.hasDrawable() || checked) { - QStyleOptionMenuItem newMi = mi; - newMi.rect = positionRect(w, subRule, subSubRule, PseudoElement_MenuCheckMark, opt->rect, opt->direction); - drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, w); - } + iconOffset = iconRule.geo->width; } QRect textRect = subRule.contentsRect(opt->rect); + if (opt->direction == Qt::LeftToRight) + textRect.setLeft(textRect.left() + checkableOffset + iconOffset); + else + textRect.setRight(textRect.right() - checkableOffset - iconOffset); textRect.setWidth(textRect.width() - mi.tabWidth); QStringRef s(&mi.text); p->setPen(mi.palette.buttonText().color()); @@ -3838,17 +3879,10 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q if(hasStyleRule(w, PseudoElement_HeaderViewSection)) { QRenderRule subRule = renderRule(w, opt, PseudoElement_HeaderViewSection); if (!subRule.hasNativeBorder() || !subRule.baseStyleCanDraw() - || subRule.hasBackground() || subRule.hasPalette() || subRule.hasFont) { + || subRule.hasBackground() || subRule.hasPalette() || subRule.hasFont || subRule.hasBorder()) { ParentStyle::drawControl(ce, opt, p, w); return; } - if (subRule.hasFont) { - const QFont oldFont = p->font(); - p->setFont(subRule.font.resolve(p->font())); - baseStyle()->drawControl(ce, opt, p, w); - p->setFont(oldFont); - return; - } } break; case CE_HeaderSection: @@ -4821,13 +4855,12 @@ int QStyleSheetStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const return 0; break; - case PM_TabBarScrollButtonWidth: { + case PM_TabBarScrollButtonWidth: subRule = renderRule(w, opt, PseudoElement_TabBarScroller); if (subRule.hasContentsSize()) { QSize sz = subRule.size(); - return sz.width() != -1 ? sz.width() : sz.height(); + return (sz.width() != -1 ? sz.width() : sz.height()) / 2; } - } break; case PM_TabBarTabShiftHorizontal: @@ -5050,6 +5083,16 @@ QSize QStyleSheetStyle::sizeFromContents(ContentsType ct, const QStyleOption *op int width = csz.width(); if (mi->text.contains(QLatin1Char('\t'))) width += 12; //as in QCommonStyle + bool checkable = mi->checkType != QStyleOptionMenuItem::NotCheckable; + if (checkable) { + QRenderRule subSubRule = renderRule(w, opt, PseudoElement_MenuCheckMark); + QRect checkmarkRect = positionRect(w, subRule, subSubRule, PseudoElement_MenuCheckMark, opt->rect, opt->direction); + width += checkmarkRect.width(); + } + if (!mi->icon.isNull()) { + QPixmap pixmap = mi->icon.pixmap(pixelMetric(PM_SmallIconSize)); + width += pixmap.width(); + } return subRule.boxSize(subRule.adjustSize(QSize(width, csz.height()))); } } @@ -5200,7 +5243,7 @@ static QLatin1String propertyNameForStandardPixmap(QStyle::StandardPixmap sp) case QStyle::SP_DialogCloseButton: return QLatin1String("dialog-close-icon"); case QStyle::SP_DialogApplyButton: return QLatin1String("dialog-apply-icon"); case QStyle::SP_DialogResetButton: return QLatin1String("dialog-reset-icon"); - case QStyle::SP_DialogDiscardButton: return QLatin1String("discard-icon"); + case QStyle::SP_DialogDiscardButton: return QLatin1String("dialog-discard-icon"); case QStyle::SP_DialogYesButton: return QLatin1String("dialog-yes-icon"); case QStyle::SP_DialogNoButton: return QLatin1String("dialog-no-icon"); case QStyle::SP_ArrowUp: return QLatin1String("uparrow-icon"); @@ -5876,6 +5919,12 @@ QRect QStyleSheetStyle::subElementRect(SubElement se, const QStyleOption *opt, c } break; + case SE_TabBarScrollLeftButton: + case SE_TabBarScrollRightButton: + if (hasStyleRule(w, PseudoElement_TabBarScroller)) + return ParentStyle::subElementRect(se, opt, w); + break; + case SE_TabBarTearIndicator: { QRenderRule subRule = renderRule(w, opt, PseudoElement_TabBarTear); if (subRule.hasContentsSize()) { @@ -6067,6 +6116,28 @@ bool QStyleSheetStyle::isNaturalChild(const QObject *obj) return false; } +QPixmap QStyleSheetStyle::loadPixmap(const QString &fileName, const QObject *context) +{ + qreal ratio = -1.0; + if (const QWidget *widget = qobject_cast<const QWidget *>(context)) { + if (QScreen *screen = QApplication::screenAt(widget->mapToGlobal(QPoint(0, 0)))) + ratio = screen->devicePixelRatio(); + } + + if (ratio < 0) { + if (const QApplication *app = qApp) + ratio = app->devicePixelRatio(); + else + ratio = 1.0; + } + + qreal sourceDevicePixelRatio = 1.0; + QString resolvedFileName = qt_findAtNxFile(fileName, ratio, &sourceDevicePixelRatio); + QPixmap pixmap(resolvedFileName); + pixmap.setDevicePixelRatio(sourceDevicePixelRatio); + return pixmap; +} + QT_END_NAMESPACE #include "moc_qstylesheetstyle_p.cpp" diff --git a/src/widgets/styles/qstylesheetstyle_p.h b/src/widgets/styles/qstylesheetstyle_p.h index 042abf5c22..d4edb83525 100644 --- a/src/widgets/styles/qstylesheetstyle_p.h +++ b/src/widgets/styles/qstylesheetstyle_p.h @@ -167,6 +167,7 @@ private: static Qt::Alignment resolveAlignment(Qt::LayoutDirection, Qt::Alignment); static bool isNaturalChild(const QObject *obj); + static QPixmap loadPixmap(const QString &fileName, const QObject *context); bool initObject(const QObject *obj) const; public: static int numinstances; @@ -215,6 +216,13 @@ template <typename T> class QTypeInfo<QStyleSheetStyleCaches::Tampered<T>> : QTypeInfoMerger<QStyleSheetStyleCaches::Tampered<T>, T> {}; + +// Returns a QStyleSheet from the given style. +inline QStyleSheetStyle* qt_styleSheet(QStyle *style) +{ + return qobject_cast<QStyleSheetStyle *>(style); +} + QT_END_NAMESPACE #endif // QT_NO_STYLE_STYLESHEET #endif // QSTYLESHEETSTYLE_P_H diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp index 80ce8419f8..12ca5201c1 100644 --- a/src/widgets/styles/qwindowsstyle.cpp +++ b/src/widgets/styles/qwindowsstyle.cpp @@ -842,17 +842,19 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, : opt->palette.text().color()); if (opt->state & State_NoChange) p->setBrush(opt->palette.brush(QPalette::Button)); - p->drawRect(opt->rect.x() + 1, opt->rect.y() + 1, 11, 11); + p->drawRect(opt->rect.x() + 1, opt->rect.y() + 1, opt->rect.width() - 2, opt->rect.height() - 2); } #endif // QT_CONFIG(itemviews) if (!(opt->state & State_Off)) { QPointF points[6]; - points[0] = { opt->rect.x() + QStyleHelper::dpiScaled(3.5), opt->rect.y() + QStyleHelper::dpiScaled(5.5) }; - points[1] = { points[0].x(), points[0].y() + QStyleHelper::dpiScaled(2) }; - points[2] = { points[1].x() + QStyleHelper::dpiScaled(2), points[1].y() + QStyleHelper::dpiScaled(2) }; - points[3] = { points[2].x() + QStyleHelper::dpiScaled(4), points[2].y() - QStyleHelper::dpiScaled(4) }; - points[4] = { points[3].x(), points[3].y() - QStyleHelper::dpiScaled(2) }; - points[5] = { points[4].x() - QStyleHelper::dpiScaled(4), points[4].y() + QStyleHelper::dpiScaled(4) }; + qreal scaleh = opt->rect.width() / 12.0; + qreal scalev = opt->rect.height() / 12.0; + points[0] = { opt->rect.x() + 3.5 * scaleh, opt->rect.y() + 5.5 * scalev }; + points[1] = { points[0].x(), points[0].y() + 2 * scalev }; + points[2] = { points[1].x() + 2 * scaleh, points[1].y() + 2 * scalev }; + points[3] = { points[2].x() + 4 * scaleh, points[2].y() - 4 * scalev }; + points[4] = { points[3].x(), points[3].y() - 2 * scalev }; + points[5] = { points[4].x() - 4 * scaleh, points[4].y() + 4 * scalev }; p->setPen(QPen(opt->palette.text().color(), 0)); p->setBrush(opt->palette.text().color()); p->drawPolygon(points, 6); @@ -1150,9 +1152,6 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, opt, widget), mode); const int pixw = pixmap.width() / pixmap.devicePixelRatio(); const int pixh = pixmap.height() / pixmap.devicePixelRatio(); - if (act && !dis && !checked) - qDrawShadePanel(p, vCheckRect, menuitem->palette, false, 1, - &menuitem->palette.brush(QPalette::Button)); QRect pmr(0, 0, pixw, pixh); pmr.moveCenter(vCheckRect.center()); p->setPen(menuitem->palette.text().color()); |