diff options
14 files changed, 69 insertions, 13 deletions
diff --git a/src/imports/nativestyle/items/qquickstyleitem.cpp b/src/imports/nativestyle/items/qquickstyleitem.cpp index be1e9316..1034459d 100644 --- a/src/imports/nativestyle/items/qquickstyleitem.cpp +++ b/src/imports/nativestyle/items/qquickstyleitem.cpp @@ -114,27 +114,44 @@ QSGNode *QQuickStyleItem::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePa if (!node) node = window()->createNinePatchNode(); - QRectF bounds = boundingRect(); auto texture = window()->createTextureFromImage(m_paintedImage, QQuickWindow::TextureCanUseAtlas); - QSize padding = m_useNinePatchImage ? m_styleItemGeometry.minimumSize / 2 : QSize(0, 0); - if (boundingRect().width() < m_styleItemGeometry.minimumSize.width()) - padding.setWidth(0); - if (boundingRect().height() < m_styleItemGeometry.minimumSize.height()) - padding.setHeight(0); + QRectF bounds = boundingRect(); + const qreal scale = window()->devicePixelRatio(); + const QSizeF ninePatchImageSize = m_paintedImage.rect().size() / scale; #ifdef QT_DEBUG if (m_debugFlags.testFlag(ShowUnscaled)) { - const qreal scale = window()->devicePixelRatio(); - const QSizeF ninePatchImageSize = m_paintedImage.rect().size() / scale; bounds = QRectF(QPointF(), ninePatchImageSize); qqc2Debug() << "Setting paint node bounds to size of image:" << bounds; } #endif + QMargins padding = m_useNinePatchImage ? m_styleItemGeometry.ninePatchMargins : QMargins(0, 0, 0, 0); + if (padding.right() == -1) { + // Special case: a right padding of -1 means that + // the image should not scale horizontally. + bounds.setWidth(ninePatchImageSize.width()); + padding.setLeft(0); + padding.setRight(0); + } else if (boundingRect().width() < m_styleItemGeometry.minimumSize.width()) { + // If the item size is smaller that the image, using nine-patch scaling + // ends up wrapping it. In that case we scale the whole image instead. + padding.setLeft(0); + padding.setRight(0); + } + if (padding.bottom() == -1) { + bounds.setHeight(ninePatchImageSize.height()); + padding.setTop(0); + padding.setBottom(0); + } else if (boundingRect().height() < m_styleItemGeometry.minimumSize.height()) { + padding.setTop(0); + padding.setBottom(0); + } + node->setBounds(bounds); node->setTexture(texture); node->setDevicePixelRatio(window()->devicePixelRatio()); - node->setPadding(padding.width(), padding.height(), padding.width(), padding.height()); + node->setPadding(padding.left(), padding.top(), padding.right(), padding.bottom()); node->update(); return node; @@ -259,9 +276,17 @@ void QQuickStyleItem::paintControlToImage() painter.drawLine(p.x() - offset, p.y() - offset, p.x() - offset, p.y() + m_contentSize.height()); } if (m_debugFlags.testFlag(ShowUnscaled)) { - const QPoint center = m_paintedImage.rect().center() / scale; - painter.drawLine(center.x(), 0, center.x(), m_paintedImage.rect().height()); - painter.drawLine(0, center.y(), m_paintedImage.rect().width(), center.y()); + const QMargins m = m_styleItemGeometry.ninePatchMargins; + const int w = int(m_paintedImage.rect().width() / scale); + const int h = int(m_paintedImage.rect().height() / scale); + if (m.right() != -1) { + painter.drawLine(m.left(), 0, m.left(), h); + painter.drawLine(w - m.right(), 0, w - m.right(), h); + } + if (m.bottom() != -1) { + painter.drawLine(0, m.top(), w, m.top()); + painter.drawLine(0, h - m.bottom(), w, h - m.bottom()); + } } } #endif diff --git a/src/imports/nativestyle/items/qquickstyleitem.h b/src/imports/nativestyle/items/qquickstyleitem.h index bab038ce..47247e15 100644 --- a/src/imports/nativestyle/items/qquickstyleitem.h +++ b/src/imports/nativestyle/items/qquickstyleitem.h @@ -144,6 +144,7 @@ struct StyleItemGeometry QSize implicitSize; QRect contentRect; QRect layoutRect; + QMargins ninePatchMargins; }; QDebug operator<<(QDebug debug, const StyleItemGeometry &cg); diff --git a/src/imports/nativestyle/items/qquickstyleitembutton.cpp b/src/imports/nativestyle/items/qquickstyleitembutton.cpp index 4d5d32e0..6f3fbfec 100644 --- a/src/imports/nativestyle/items/qquickstyleitembutton.cpp +++ b/src/imports/nativestyle/items/qquickstyleitembutton.cpp @@ -59,6 +59,7 @@ StyleItemGeometry QQuickStyleItemButton::calculateGeometry() styleOption.rect = QRect(QPoint(0, 0), geometry.implicitSize); geometry.contentRect = style()->subElementRect(QStyle::SE_PushButtonContents, &styleOption); geometry.layoutRect = style()->subElementRect(QStyle::SE_PushButtonLayoutItem, &styleOption); + geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CE_PushButtonBevel, &styleOption, geometry.minimumSize); return geometry; } diff --git a/src/imports/nativestyle/items/qquickstyleitemcheckbox.cpp b/src/imports/nativestyle/items/qquickstyleitemcheckbox.cpp index e97f7d94..e5ee9133 100644 --- a/src/imports/nativestyle/items/qquickstyleitemcheckbox.cpp +++ b/src/imports/nativestyle/items/qquickstyleitemcheckbox.cpp @@ -60,6 +60,7 @@ StyleItemGeometry QQuickStyleItemCheckBox::calculateGeometry() styleOption.rect = QRect(QPoint(0, 0), geometry.implicitSize); geometry.contentRect = style()->subElementRect(QStyle::SE_CheckBoxContents, &styleOption); geometry.layoutRect = style()->subElementRect(QStyle::SE_CheckBoxLayoutItem, &styleOption); + geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CE_CheckBox, &styleOption, geometry.minimumSize); // Spacing seems to already be baked into SE_CheckBoxContents, so ignore until needed //const int space = style()->pixelMetric(QStyle::PM_CheckBoxLabelSpacing, &styleOption); diff --git a/src/imports/nativestyle/items/qquickstyleitemframe.cpp b/src/imports/nativestyle/items/qquickstyleitemframe.cpp index fe5d1370..42a6c231 100644 --- a/src/imports/nativestyle/items/qquickstyleitemframe.cpp +++ b/src/imports/nativestyle/items/qquickstyleitemframe.cpp @@ -40,12 +40,14 @@ StyleItemGeometry QQuickStyleItemFrame::calculateGeometry() { QStyleOptionFrame styleOption; initStyleOption(styleOption); - StyleItemGeometry geometry; + geometry.minimumSize = style()->sizeFromContents(QStyle::CT_Frame, &styleOption, QSize(0, 0)); geometry.implicitSize = contentSize(); styleOption.rect = QRect(QPoint(0, 0), geometry.implicitSize); geometry.contentRect = style()->subElementRect(QStyle::SE_FrameContents, &styleOption); + geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CE_ShapedFrame, &styleOption, geometry.minimumSize); + return geometry; } diff --git a/src/imports/nativestyle/items/qquickstyleitemgroupbox.cpp b/src/imports/nativestyle/items/qquickstyleitemgroupbox.cpp index fab8fb3a..2b4154d2 100644 --- a/src/imports/nativestyle/items/qquickstyleitemgroupbox.cpp +++ b/src/imports/nativestyle/items/qquickstyleitemgroupbox.cpp @@ -60,6 +60,7 @@ StyleItemGeometry QQuickStyleItemGroupBox::calculateGeometry() styleOption.rect.setSize(geometry.implicitSize); geometry.contentRect = style()->subControlRect(QStyle::CC_GroupBox, &styleOption, QStyle::SC_GroupBoxContents); geometry.layoutRect = style()->subElementRect(QStyle::SE_GroupBoxLayoutItem, &styleOption); + geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CC_GroupBox, &styleOption, geometry.minimumSize); const QQuickStyleMargins oldGroupBoxPadding = m_groupBoxPadding; const QRect frame = style()->subControlRect(QStyle::CC_GroupBox, &styleOption, QStyle::SC_GroupBoxFrame); diff --git a/src/imports/nativestyle/items/qquickstyleitemradiobutton.cpp b/src/imports/nativestyle/items/qquickstyleitemradiobutton.cpp index 5561184c..c8bb251f 100644 --- a/src/imports/nativestyle/items/qquickstyleitemradiobutton.cpp +++ b/src/imports/nativestyle/items/qquickstyleitemradiobutton.cpp @@ -60,6 +60,7 @@ StyleItemGeometry QQuickStyleItemRadioButton::calculateGeometry() styleOption.rect = QRect(QPoint(0, 0), geometry.implicitSize); geometry.contentRect = style()->subElementRect(QStyle::SE_RadioButtonContents, &styleOption); geometry.layoutRect = style()->subElementRect(QStyle::SE_RadioButtonLayoutItem, &styleOption); + geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CE_RadioButton, &styleOption, geometry.minimumSize); return geometry; } diff --git a/src/imports/nativestyle/items/qquickstyleitemslider.cpp b/src/imports/nativestyle/items/qquickstyleitemslider.cpp index 99b0e312..5ca282cc 100644 --- a/src/imports/nativestyle/items/qquickstyleitemslider.cpp +++ b/src/imports/nativestyle/items/qquickstyleitemslider.cpp @@ -63,6 +63,7 @@ StyleItemGeometry QQuickStyleItemSlider::calculateGeometry() geometry.minimumSize = style()->sizeFromContents(QStyle::CT_Slider, &styleOption, QSize(0, 0)); geometry.implicitSize = geometry.minimumSize; geometry.layoutRect = style()->subElementRect(QStyle::SE_SliderLayoutItem, &styleOption); + geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CC_Slider, &styleOption, geometry.minimumSize); return geometry; } diff --git a/src/imports/nativestyle/items/qquickstyleitemspinbox.cpp b/src/imports/nativestyle/items/qquickstyleitemspinbox.cpp index 9ebc62b1..a2c4f1d1 100644 --- a/src/imports/nativestyle/items/qquickstyleitemspinbox.cpp +++ b/src/imports/nativestyle/items/qquickstyleitemspinbox.cpp @@ -62,6 +62,7 @@ StyleItemGeometry QQuickStyleItemSpinBox::calculateGeometry() styleOption.rect = QRect(QPoint(0, 0), geometry.implicitSize); geometry.contentRect = style()->subControlRect(QStyle::CC_SpinBox, &styleOption, QStyle::SC_SpinBoxEditField); geometry.layoutRect = style()->subElementRect(QStyle::SE_SpinBoxLayoutItem, &styleOption); + geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CC_SpinBox, &styleOption, geometry.minimumSize); } else { geometry.implicitSize = geometry.minimumSize; } diff --git a/src/imports/nativestyle/items/qquickstyleitemtextarea.cpp b/src/imports/nativestyle/items/qquickstyleitemtextarea.cpp index 88dbf065..c149444b 100644 --- a/src/imports/nativestyle/items/qquickstyleitemtextarea.cpp +++ b/src/imports/nativestyle/items/qquickstyleitemtextarea.cpp @@ -60,6 +60,7 @@ StyleItemGeometry QQuickStyleItemTextArea::calculateGeometry() geometry.implicitSize = style()->sizeFromContents(QStyle::CT_LineEdit, &styleOption, contentSize()); styleOption.rect = QRect(QPoint(0, 0), geometry.implicitSize); geometry.contentRect = style()->subElementRect(QStyle::SE_LineEditContents, &styleOption); + geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CE_ShapedFrame, &styleOption, geometry.minimumSize); return geometry; } diff --git a/src/imports/nativestyle/items/qquickstyleitemtextfield.cpp b/src/imports/nativestyle/items/qquickstyleitemtextfield.cpp index ed8aaf46..1a262033 100644 --- a/src/imports/nativestyle/items/qquickstyleitemtextfield.cpp +++ b/src/imports/nativestyle/items/qquickstyleitemtextfield.cpp @@ -59,6 +59,7 @@ StyleItemGeometry QQuickStyleItemTextField::calculateGeometry() geometry.implicitSize = style()->sizeFromContents(QStyle::CT_LineEdit, &styleOption, contentSize()); styleOption.rect = QRect(QPoint(0, 0), geometry.implicitSize); geometry.contentRect = style()->subElementRect(QStyle::SE_LineEditContents, &styleOption); + geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CE_ShapedFrame, &styleOption, geometry.minimumSize); return geometry; } diff --git a/src/imports/nativestyle/qstyle/qquickcommonstyle.cpp b/src/imports/nativestyle/qstyle/qquickcommonstyle.cpp index 0cb8e848..e8dadb9e 100644 --- a/src/imports/nativestyle/qstyle/qquickcommonstyle.cpp +++ b/src/imports/nativestyle/qstyle/qquickcommonstyle.cpp @@ -4694,6 +4694,22 @@ QFont QCommonStyle::font(QStyle::ControlElement element, const QStyle::State sta return QGuiApplication::font(); } +QMargins QCommonStyle::ninePatchMargins(QStyle::ControlElement ce, const QStyleOption *opt, const QSize &imageSize) const +{ + // By default, we just divide the image at the center + int w = imageSize.width() / 2; + int h = imageSize.height() / 2; + return QMargins(w, h, w, h); +} + +QMargins QCommonStyle::ninePatchMargins(QStyle::ComplexControl cc, const QStyleOptionComplex *opt, const QSize &imageSize) const +{ + // By default, we just divide the image at the center + int w = imageSize.width() / 2; + int h = imageSize.height() / 2; + return QMargins(w, h, w, h); +} + int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, QStyleHintReturn *hret) const { int ret = 0; diff --git a/src/imports/nativestyle/qstyle/qquickcommonstyle.h b/src/imports/nativestyle/qstyle/qquickcommonstyle.h index 77626843..894194a0 100644 --- a/src/imports/nativestyle/qstyle/qquickcommonstyle.h +++ b/src/imports/nativestyle/qstyle/qquickcommonstyle.h @@ -62,6 +62,8 @@ public: QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize) const override; QFont font(ControlElement element, const QStyle::State state) const override; + QMargins ninePatchMargins(ControlElement ce, const QStyleOption *opt, const QSize &imageSize) const override; + QMargins ninePatchMargins(ComplexControl cc, const QStyleOptionComplex *opt, const QSize &imageSize) const override; int pixelMetric(PixelMetric m, const QStyleOption *opt = nullptr) const override; int styleHint(StyleHint sh, const QStyleOption *opt = nullptr, QStyleHintReturn *shret = nullptr) const override; diff --git a/src/imports/nativestyle/qstyle/qquickstyle.h b/src/imports/nativestyle/qstyle/qquickstyle.h index 91e09f4b..bc0cccf7 100644 --- a/src/imports/nativestyle/qstyle/qquickstyle.h +++ b/src/imports/nativestyle/qstyle/qquickstyle.h @@ -782,6 +782,8 @@ public: virtual QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize) const = 0; virtual QFont font(ControlElement element, const QStyle::State state) const = 0; + virtual QMargins ninePatchMargins(ControlElement ce, const QStyleOption *opt, const QSize &imageSize) const = 0; + virtual QMargins ninePatchMargins(ComplexControl cc, const QStyleOptionComplex *opt, const QSize &imageSize) const = 0; virtual SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, const QPoint &pt) const = 0; |