aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicknativestyle/items
diff options
context:
space:
mode:
Diffstat (limited to 'src/quicknativestyle/items')
-rw-r--r--src/quicknativestyle/items/items.pri36
-rw-r--r--src/quicknativestyle/items/qquickstyleitem.cpp563
-rw-r--r--src/quicknativestyle/items/qquickstyleitem.h311
-rw-r--r--src/quicknativestyle/items/qquickstyleitembutton.cpp88
-rw-r--r--src/quicknativestyle/items/qquickstyleitembutton.h60
-rw-r--r--src/quicknativestyle/items/qquickstyleitemcheckbox.cpp89
-rw-r--r--src/quicknativestyle/items/qquickstyleitemcheckbox.h60
-rw-r--r--src/quicknativestyle/items/qquickstyleitemcombobox.cpp89
-rw-r--r--src/quicknativestyle/items/qquickstyleitemcombobox.h60
-rw-r--r--src/quicknativestyle/items/qquickstyleitemdial.cpp111
-rw-r--r--src/quicknativestyle/items/qquickstyleitemdial.h60
-rw-r--r--src/quicknativestyle/items/qquickstyleitemframe.cpp67
-rw-r--r--src/quicknativestyle/items/qquickstyleitemframe.h56
-rw-r--r--src/quicknativestyle/items/qquickstyleitemgroupbox.cpp100
-rw-r--r--src/quicknativestyle/items/qquickstyleitemgroupbox.h70
-rw-r--r--src/quicknativestyle/items/qquickstyleitemprogressbar.cpp114
-rw-r--r--src/quicknativestyle/items/qquickstyleitemprogressbar.h61
-rw-r--r--src/quicknativestyle/items/qquickstyleitemradiobutton.cpp83
-rw-r--r--src/quicknativestyle/items/qquickstyleitemradiobutton.h60
-rw-r--r--src/quicknativestyle/items/qquickstyleitemscrollbar.cpp151
-rw-r--r--src/quicknativestyle/items/qquickstyleitemscrollbar.h74
-rw-r--r--src/quicknativestyle/items/qquickstyleitemscrollviewcorner.cpp119
-rw-r--r--src/quicknativestyle/items/qquickstyleitemscrollviewcorner.h56
-rw-r--r--src/quicknativestyle/items/qquickstyleitemslider.cpp123
-rw-r--r--src/quicknativestyle/items/qquickstyleitemslider.h72
-rw-r--r--src/quicknativestyle/items/qquickstyleitemspinbox.cpp110
-rw-r--r--src/quicknativestyle/items/qquickstyleitemspinbox.h73
-rw-r--r--src/quicknativestyle/items/qquickstyleitemtextfield.cpp86
-rw-r--r--src/quicknativestyle/items/qquickstyleitemtextfield.h60
29 files changed, 3062 insertions, 0 deletions
diff --git a/src/quicknativestyle/items/items.pri b/src/quicknativestyle/items/items.pri
new file mode 100644
index 0000000000..5b6d9251a2
--- /dev/null
+++ b/src/quicknativestyle/items/items.pri
@@ -0,0 +1,36 @@
+INCLUDEPATH += $$PWD
+
+HEADERS += \
+ $$PWD/qquickstyleitem.h \
+ $$PWD/qquickstyleitembutton.h \
+ $$PWD/qquickstyleitemgroupbox.h \
+ $$PWD/qquickstyleitemcheckbox.h \
+ $$PWD/qquickstyleitemradiobutton.h \
+ $$PWD/qquickstyleitemslider.h \
+ $$PWD/qquickstyleitemspinbox.h \
+ $$PWD/qquickstyleitemtextfield.h \
+ $$PWD/qquickstyleitemframe.h \
+ $$PWD/qquickstyleitemcombobox.h \
+ $$PWD/qquickstyleitemscrollbar.h \
+ $$PWD/qquickstyleitemprogressbar.h \
+ $$PWD/qquickstyleitemdial.h \
+
+SOURCES += \
+ $$PWD/qquickstyleitem.cpp \
+ $$PWD/qquickstyleitembutton.cpp \
+ $$PWD/qquickstyleitemgroupbox.cpp \
+ $$PWD/qquickstyleitemcheckbox.cpp \
+ $$PWD/qquickstyleitemradiobutton.cpp \
+ $$PWD/qquickstyleitemslider.cpp \
+ $$PWD/qquickstyleitemspinbox.cpp \
+ $$PWD/qquickstyleitemtextfield.cpp \
+ $$PWD/qquickstyleitemframe.cpp \
+ $$PWD/qquickstyleitemcombobox.cpp \
+ $$PWD/qquickstyleitemscrollbar.cpp \
+ $$PWD/qquickstyleitemprogressbar.cpp \
+ $$PWD/qquickstyleitemdial.cpp \
+
+macos {
+ HEADERS += $$PWD/qquickstyleitemscrollviewcorner.h
+ SOURCES += $$PWD/qquickstyleitemscrollviewcorner.cpp
+}
diff --git a/src/quicknativestyle/items/qquickstyleitem.cpp b/src/quicknativestyle/items/qquickstyleitem.cpp
new file mode 100644
index 0000000000..ec041d01e0
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitem.cpp
@@ -0,0 +1,563 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickstyleitem.h"
+
+#include <QtCore/qscopedvaluerollback.h>
+#include <QtCore/qdir.h>
+
+#include <QtQuick/qsgninepatchnode.h>
+#include <QtQuick/private/qquickwindow_p.h>
+#include <QtQuick/qquickwindow.h>
+
+#include <QtQuickTemplates2/private/qquickcontrol_p.h>
+#include <QtQuickTemplates2/private/qquickbutton_p.h>
+
+#include <QtQml/qqml.h>
+
+#include "qquickstyleitembutton.h"
+#include "qquickstylehelper_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QDebug operator<<(QDebug debug, const QQuickStyleMargins &padding)
+{
+ QDebugStateSaver saver(debug);
+ debug.nospace();
+ debug << "StyleMargins(";
+ debug << padding.left() << ", ";
+ debug << padding.top() << ", ";
+ debug << padding.right() << ", ";
+ debug << padding.bottom();
+ debug << ')';
+ return debug;
+}
+
+QDebug operator<<(QDebug debug, const StyleItemGeometry &cg)
+{
+ QDebugStateSaver saver(debug);
+ debug.nospace();
+ debug << "StyleItemGeometry(";
+ debug << "implicitSize:" << cg.implicitSize << ", ";
+ debug << "contentRect:" << cg.contentRect << ", ";
+ debug << "layoutRect:" << cg.layoutRect << ", ";
+ debug << "minimumSize:" << cg.minimumSize << ", ";
+ debug << "9patchMargins:" << cg.ninePatchMargins;
+ debug << ')';
+ return debug;
+}
+
+int QQuickStyleItem::dprAlignedSize(const int size) const
+{
+ // Return the first value equal to or bigger than size
+ // that is a whole number when multiplied with the dpr.
+ static int multiplier = [&]() {
+ const qreal dpr = window()->devicePixelRatio();
+ for (int m = 1; m <= 10; ++m) {
+ const qreal v = m * dpr;
+ if (v == int(v))
+ return m;
+ }
+
+ qWarning() << "The current dpr (" << dpr << ") is not supported"
+ << "by the style and might result in drawing artifacts";
+ return 1;
+ }();
+
+ return int(qCeil(qreal(size) / qreal(multiplier)) * multiplier);
+}
+
+QQuickStyleItem::QQuickStyleItem(QQuickItem *parent)
+ : QQuickItem(parent)
+{
+ setFlag(QQuickItem::ItemHasContents);
+}
+
+QQuickStyleItem::~QQuickStyleItem()
+{
+}
+
+void QQuickStyleItem::connectToControl() const
+{
+ connect(m_control, &QQuickStyleItem::enabledChanged, this, &QQuickStyleItem::markImageDirty);
+ connect(m_control, &QQuickItem::activeFocusChanged, this, &QQuickStyleItem::markImageDirty);
+
+ if (QQuickWindow *win = window()) {
+ connect(win, &QQuickWindow::activeChanged, this, &QQuickStyleItem::markImageDirty);
+ m_connectedWindow = win;
+ }
+}
+
+void QQuickStyleItem::markImageDirty()
+{
+ m_dirty.setFlag(DirtyFlag::Image);
+ if (isComponentComplete())
+ polish();
+}
+
+void QQuickStyleItem::markGeometryDirty()
+{
+ m_dirty.setFlag(DirtyFlag::Geometry);
+ if (isComponentComplete())
+ polish();
+}
+
+QSGNode *QQuickStyleItem::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
+{
+ QSGNinePatchNode *node = static_cast<QSGNinePatchNode *>(oldNode);
+ if (!node)
+ node = window()->createNinePatchNode();
+ if (m_paintedImage.isNull())
+ return node;
+
+ const auto texture = window()->createTextureFromImage(m_paintedImage, QQuickWindow::TextureCanUseAtlas);
+
+ QRectF bounds = boundingRect();
+ const qreal dpr = window()->devicePixelRatio();
+ const QSizeF unscaledImageSize = QSizeF(m_paintedImage.size()) / dpr;
+
+ // We can scale the image up with a nine patch node, but should
+ // avoid to scale it down. Otherwise the nine patch image will look
+ // wrapped (or look truncated, in case of no padding). So if the
+ // item is smaller that the image, don't scale.
+ if (bounds.width() < unscaledImageSize.width())
+ bounds.setWidth(unscaledImageSize.width());
+ if (bounds.height() < unscaledImageSize.height())
+ bounds.setHeight(unscaledImageSize.height());
+
+#ifdef QT_DEBUG
+ if (m_debugFlags.testFlag(Unscaled)) {
+ bounds.setSize(unscaledImageSize);
+ qqc2Info() << "Setting qsg node size to the unscaled size of m_paintedImage:" << bounds;
+ }
+#endif
+
+ if (m_useNinePatchImage) {
+ QMargins padding = m_styleItemGeometry.ninePatchMargins;
+ if (padding.right() == -1) {
+ // Special case: a padding of -1 means that
+ // the image shouldn't scale in the given direction.
+ padding.setLeft(0);
+ padding.setRight(0);
+ }
+ if (padding.bottom() == -1) {
+ padding.setTop(0);
+ padding.setBottom(0);
+ }
+ node->setPadding(padding.left(), padding.top(), padding.right(), padding.bottom());
+ }
+
+ node->setBounds(bounds);
+ node->setTexture(texture);
+ node->setDevicePixelRatio(dpr);
+ node->update();
+
+ return node;
+}
+
+QStyle::State QQuickStyleItem::controlSize(QQuickItem *item)
+{
+ // TODO: add proper API for small and mini
+ if (item->metaObject()->indexOfProperty("qqc2_style_small") != -1)
+ return QStyle::State_Small;
+ if (item->metaObject()->indexOfProperty("qqc2_style_mini") != -1)
+ return QStyle::State_Mini;
+ return QStyle::State_None;
+}
+
+void QQuickStyleItem::initStyleOptionBase(QStyleOption &styleOption) const
+{
+ Q_ASSERT(m_control);
+
+ styleOption.control = const_cast<QQuickItem *>(control<QQuickItem>());
+ styleOption.window = window();
+ styleOption.palette = QQuickItemPrivate::get(m_control)->palette()->toQPalette();
+ styleOption.rect = QRect(QPoint(0, 0), imageSize());
+
+ styleOption.state = QStyle::State_None;
+ styleOption.state |= controlSize(styleOption.control);
+
+ // Note: not all controls inherit from QQuickControl (e.g QQuickTextField)
+ if (const auto quickControl = dynamic_cast<QQuickControl *>(m_control.data()))
+ styleOption.direction = quickControl->isMirrored() ? Qt::RightToLeft : Qt::LeftToRight;
+
+ if (window()) {
+ if (styleOption.window->isActive())
+ styleOption.state |= QStyle::State_Active;
+ if (m_control->isEnabled())
+ styleOption.state |= QStyle::State_Enabled;
+ if (m_control->hasActiveFocus())
+ styleOption.state |= QStyle::State_HasFocus;
+ if (m_control->isUnderMouse())
+ styleOption.state |= QStyle::State_MouseOver;
+ // Should this depend on the focusReason (e.g. only TabFocus) ?
+ styleOption.state |= QStyle::State_KeyboardFocusChange;
+ }
+
+ if (m_overrideState != None) {
+ // In Button.qml we fade between two versions of
+ // the handle, depending on if it's hovered or not
+ if (m_overrideState & AlwaysHovered)
+ styleOption.state |= QStyle::State_MouseOver;
+ else if (m_overrideState & NeverHovered)
+ styleOption.state &= ~QStyle::State_MouseOver;
+ }
+
+ qqc2Info() << styleOption;
+}
+
+void QQuickStyleItem::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ QQuickItem::geometryChange(newGeometry, oldGeometry);
+
+ // Ensure that we only schedule a new geometry update
+ // and polish if this geometry change was caused by
+ // something else than us already updating geometry.
+ if (!m_polishing)
+ markGeometryDirty();
+}
+
+void QQuickStyleItem::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
+{
+ QQuickItem::itemChange(change, data);
+
+ switch (change) {
+ case QQuickItem::ItemVisibleHasChanged:
+ if (data.boolValue)
+ markImageDirty();
+ break;
+ case QQuickItem::ItemSceneChange: {
+ markImageDirty();
+ QQuickWindow *win = data.window;
+ if (m_connectedWindow)
+ disconnect(m_connectedWindow, &QQuickWindow::activeChanged, this, &QQuickStyleItem::markImageDirty);
+ if (win)
+ connect(win, &QQuickWindow::activeChanged, this, &QQuickStyleItem::markImageDirty);
+ m_connectedWindow = win;
+ break;}
+ default:
+ break;
+ }
+}
+
+void QQuickStyleItem::updateGeometry()
+{
+ qqc2InfoHeading("GEOMETRY");
+ m_dirty.setFlag(DirtyFlag::Geometry, false);
+
+ const QQuickStyleMargins oldContentPadding = contentPadding();
+ const QQuickStyleMargins oldLayoutMargins = layoutMargins();
+ const QSize oldMinimumSize = minimumSize();
+
+ m_styleItemGeometry = calculateGeometry();
+
+#ifdef QT_DEBUG
+ if (m_styleItemGeometry.minimumSize.isEmpty())
+ qmlWarning(this) << "minimumSize is empty!";
+#endif
+
+ if (m_styleItemGeometry.implicitSize.isEmpty()) {
+ // If the item has no contents (or its size is
+ // empty), we just use the minimum size as implicit size.
+ m_styleItemGeometry.implicitSize = m_styleItemGeometry.minimumSize;
+ qqc2Info() << "implicitSize is empty, using minimumSize instead";
+ }
+
+ if (contentPadding() != oldContentPadding)
+ emit contentPaddingChanged();
+ if (layoutMargins() != oldLayoutMargins)
+ emit layoutMarginsChanged();
+ if (minimumSize() != oldMinimumSize)
+ emit minimumSizeChanged();
+
+ setImplicitSize(m_styleItemGeometry.implicitSize.width(), m_styleItemGeometry.implicitSize.height());
+
+ qqc2Info() << m_styleItemGeometry
+ << "bounding rect:" << boundingRect()
+ << "layout margins:" << layoutMargins()
+ << "content padding:" << contentPadding()
+ << "input content size:" << m_contentSize;
+}
+
+void QQuickStyleItem::paintControlToImage()
+{
+ qqc2InfoHeading("PAINT");
+ const QSize imgSize = imageSize();
+ if (imgSize.isEmpty())
+ return;
+
+ m_dirty.setFlag(DirtyFlag::Image, false);
+
+ // The size of m_paintedImage should normally be imgSize * dpr. The problem is
+ // that the dpr can be e.g 1.25, which means that the size can end up having a
+ // fraction. But an image cannot have a size with a fraction, so it would need
+ // to be rounded. But on the flip side, rounding the size means that the size
+ // of the scene graph node (which is, when the texture is not scaled,
+ // m_paintedImage.size() / dpr), will end up with a fraction instead. And this
+ // causes rendering artifacts in the scene graph when the texture is mapped
+ // to physical screen coordinates. So for that reason we calculate an image size
+ // that might be slightly larger than imgSize, so that imgSize * dpr lands on a
+ // whole number. The result is that neither the image size, nor the scene graph
+ // node, ends up with a size that has a fraction.
+ const qreal dpr = window()->devicePixelRatio();
+ const int alignedW = int(dprAlignedSize(imgSize.width()) * dpr);
+ const int alignedH = int(dprAlignedSize(imgSize.height()) * dpr);
+ const QSize alignedSize = QSize(alignedW, alignedH);
+
+ if (m_paintedImage.size() != alignedSize) {
+ m_paintedImage = QImage(alignedSize, QImage::Format_ARGB32_Premultiplied);
+ m_paintedImage.setDevicePixelRatio(dpr);
+ qqc2Info() << "created image with dpr aligned size:" << alignedSize;
+ }
+
+ m_paintedImage.fill(Qt::transparent);
+
+ QPainter painter(&m_paintedImage);
+ paintEvent(&painter);
+
+#ifdef QT_DEBUG
+ if (m_debugFlags != NoDebug) {
+ painter.setPen(QColor(255, 0, 0, 255));
+ if (m_debugFlags.testFlag(ImageRect))
+ painter.drawRect(QRect(QPoint(0, 0), alignedSize / dpr));
+ if (m_debugFlags.testFlag(LayoutRect)) {
+ const auto m = layoutMargins();
+ QRect rect = QRect(QPoint(0, 0), imgSize);
+ rect.adjust(m.left(), m.top(), -m.right(), -m.bottom());
+ painter.drawRect(rect);
+ }
+ if (m_debugFlags.testFlag(ContentRect)) {
+ const auto p = contentPadding();
+ QRect rect = QRect(QPoint(0, 0), imgSize);
+ rect.adjust(p.left(), p.top(), -p.right(), -p.bottom());
+ painter.drawRect(rect);
+ }
+ if (m_debugFlags.testFlag(InputContentSize)) {
+ const int offset = 2;
+ const QPoint p = m_styleItemGeometry.contentRect.topLeft();
+ painter.drawLine(p.x() - offset, p.y() - offset, p.x() + m_contentSize.width(), p.y() - offset);
+ painter.drawLine(p.x() - offset, p.y() - offset, p.x() - offset, p.y() + m_contentSize.height());
+ }
+ if (m_debugFlags.testFlag(NinePatchMargins)) {
+ const QMargins m = m_styleItemGeometry.ninePatchMargins;
+ if (m.right() != -1) {
+ painter.drawLine(m.left(), 0, m.left(), imgSize.height());
+ painter.drawLine(imgSize.width() - m.right(), 0, imgSize.width() - m.right(), imgSize.height());
+ }
+ if (m.bottom() != -1) {
+ painter.drawLine(0, m.top(), imgSize.width(), m.top());
+ painter.drawLine(0, imgSize.height() - m.bottom(), imgSize.width(), imgSize.height() - m.bottom());
+ }
+ }
+ if (m_debugFlags.testFlag(SaveImage)) {
+ static int nr = -1;
+ ++nr;
+ static QString filename = QStringLiteral("styleitem_saveimage_");
+ const QString path = QDir::current().absoluteFilePath(filename);
+ const QString name = path + QString::number(nr) + QStringLiteral(".png");
+ m_paintedImage.save(name);
+ qDebug() << "image saved to:" << name;
+ }
+ }
+#endif
+
+ update();
+}
+
+void QQuickStyleItem::updatePolish()
+{
+ QScopedValueRollback<bool> guard(m_polishing, true);
+
+ const bool dirtyGeometry = m_dirty & DirtyFlag::Geometry;
+ const bool dirtyImage = isVisible() && ((m_dirty & DirtyFlag::Image) || (!m_useNinePatchImage && dirtyGeometry));
+
+ if (dirtyGeometry)
+ updateGeometry();
+ if (dirtyImage)
+ paintControlToImage();
+}
+
+#ifdef QT_DEBUG
+void QQuickStyleItem::addDebugInfo()
+{
+ // Example debug strings:
+ // "QQC2_NATIVESTYLE_DEBUG="myButton output contentRect"
+ // "QQC2_NATIVESTYLE_DEBUG="ComboBox ninepatchmargins"
+ // "QQC2_NATIVESTYLE_DEBUG="All layoutrect"
+
+ static const auto debugString = qEnvironmentVariable("QQC2_NATIVESTYLE_DEBUG");
+ static const auto matchAll = debugString.startsWith(QLatin1String("All "));
+ static const auto prefix = QStringLiteral("QQuickStyleItem");
+ if (debugString.isEmpty())
+ return;
+
+ const auto objectName = m_control->objectName();
+ const auto typeName = QString::fromUtf8(metaObject()->className()).remove(prefix);
+ const bool matchName = !objectName.isEmpty() && debugString.startsWith(objectName);
+ const bool matchType = debugString.startsWith(typeName);
+
+ if (!(matchAll || matchName || matchType))
+ return;
+
+#define QQC2_DEBUG_FLAG(FLAG) \
+ if (debugString.contains(QLatin1String(#FLAG), Qt::CaseInsensitive)) m_debugFlags |= FLAG
+
+ QQC2_DEBUG_FLAG(Info);
+ QQC2_DEBUG_FLAG(ImageRect);
+ QQC2_DEBUG_FLAG(ContentRect);
+ QQC2_DEBUG_FLAG(LayoutRect);
+ QQC2_DEBUG_FLAG(InputContentSize);
+ QQC2_DEBUG_FLAG(DontUseNinePatchImage);
+ QQC2_DEBUG_FLAG(NinePatchMargins);
+ QQC2_DEBUG_FLAG(Unscaled);
+ QQC2_DEBUG_FLAG(Debug);
+ QQC2_DEBUG_FLAG(SaveImage);
+
+ if (m_debugFlags & (DontUseNinePatchImage
+ | InputContentSize
+ | ContentRect
+ | LayoutRect
+ | NinePatchMargins)) {
+ // Some rects will not fit inside the drawn image unless
+ // we switch off (nine patch) image scaling.
+ m_debugFlags |= DontUseNinePatchImage;
+ m_useNinePatchImage = false;
+ }
+
+ if (m_debugFlags != NoDebug)
+ qDebug() << "debug options set for" << typeName << "(" << objectName << "):" << m_debugFlags;
+ else
+ qDebug() << "available debug options:" << DebugFlags(0xFFFF);
+}
+#endif
+
+void QQuickStyleItem::componentComplete()
+{
+ Q_ASSERT_X(m_control, Q_FUNC_INFO, "You need to assign a value to property 'control'");
+#ifdef QT_DEBUG
+ addDebugInfo();
+#endif
+ QQuickItem::componentComplete();
+ connectToControl();
+ polish();
+}
+
+qreal QQuickStyleItem::contentWidth()
+{
+ return m_contentSize.width();
+}
+
+void QQuickStyleItem::setContentWidth(qreal contentWidth)
+{
+ if (qFuzzyCompare(m_contentSize.width(), contentWidth))
+ return;
+
+ m_contentSize.setWidth(contentWidth);
+ markGeometryDirty();
+}
+
+qreal QQuickStyleItem::contentHeight()
+{
+ return m_contentSize.height();
+}
+
+void QQuickStyleItem::setContentHeight(qreal contentHeight)
+{
+ if (qFuzzyCompare(m_contentSize.height(), contentHeight))
+ return;
+
+ m_contentSize.setHeight(contentHeight);
+ markGeometryDirty();
+}
+
+QQuickStyleMargins QQuickStyleItem::contentPadding() const
+{
+ const QRect outerRect(QPoint(0, 0), m_styleItemGeometry.implicitSize);
+ return QQuickStyleMargins(outerRect, m_styleItemGeometry.contentRect);
+}
+
+QQuickStyleMargins QQuickStyleItem::layoutMargins() const
+{
+ // ### TODO: layoutRect is currently not being used for anything. But
+ // eventually this information will be needed by layouts to align the controls
+ // correctly. This because the images drawn by QStyle are usually a bit bigger
+ // than the control(frame) itself, to e.g make room for shadow effects
+ // or focus rects/glow. And this will differ from control to control. The
+ // layoutRect will then inform where the frame of the control is.
+ QQuickStyleMargins margins;
+ if (m_styleItemGeometry.layoutRect.isValid()) {
+ const QRect outerRect(QPoint(0, 0), m_styleItemGeometry.implicitSize);
+ margins = QQuickStyleMargins(outerRect, m_styleItemGeometry.layoutRect);
+ }
+ return margins;
+}
+
+QSize QQuickStyleItem::minimumSize() const
+{
+ // The style item should not be scaled below this size.
+ // Otherwise the image will be truncated.
+ return m_styleItemGeometry.minimumSize;
+}
+
+QSize QQuickStyleItem::imageSize() const
+{
+ // Returns the size of the QImage (unscaled) that
+ // is used to draw the control from QStyle.
+ return m_useNinePatchImage ? m_styleItemGeometry.minimumSize : size().toSize();
+}
+
+qreal QQuickStyleItem::focusFrameRadius() const
+{
+ return m_styleItemGeometry.focusFrameRadius;
+}
+
+QFont QQuickStyleItem::styleFont(QQuickItem *control) const
+{
+ Q_ASSERT(control);
+ // Note: This function should be treated as if it was static
+ // (meaning, don't assume anything in this object to be initialized).
+ // Resolving the font/font size should be done early on from QML, before we get
+ // around to calculate geometry and paint. Otherwise we typically need to do it
+ // all over again when/if the font changes. In practice this means that other
+ // items in QML that uses a style font, and at the same time, affects our input
+ // contentSize, cannot wait for this item to be fully constructed before it
+ // gets the font. So we need to resolve it here and now, even if this
+ // object might be in a half initialized state (hence also the control
+ // argument, instead of relying on m_control to be set).
+ return QGuiApplication::font();
+}
+
+QT_END_NAMESPACE
diff --git a/src/quicknativestyle/items/qquickstyleitem.h b/src/quicknativestyle/items/qquickstyleitem.h
new file mode 100644
index 0000000000..3b87faf60c
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitem.h
@@ -0,0 +1,311 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKSTYLEITEM_H
+#define QQUICKSTYLEITEM_H
+
+#include <QtCore/qdebug.h>
+#include <QtQml/qqml.h>
+#include <QtQml/qqmlinfo.h>
+#include <QtQuick/private/qquickitem_p.h>
+#include <QtQuickTemplates2/private/qquickcontrol_p.h>
+
+#include "qquicknativestyle.h"
+#include "qquickstyle.h"
+#include "qquickstyleoption.h"
+
+// Work-around for now, to avoid creator getting confused
+// about missing macros. Should eventually be defined
+// in qt declarative somewhere I assume.
+#ifndef QML_NAMED_ELEMENT
+#define QML_NAMED_ELEMENT(NAME)
+#define QML_UNCREATABLE(NAME)
+#endif
+
+#ifdef QT_DEBUG
+#define qqc2Debug() if (m_debugFlags.testFlag(Debug)) qDebug() << __FUNCTION__ << ":"
+#define qqc2Info() if (m_debugFlags.testFlag(Info)) qDebug() << __FUNCTION__ << ":"
+#define qqc2InfoHeading(HEADING) if (m_debugFlags.testFlag(Info)) qDebug() << "--------" << HEADING << "--------"
+#else
+#define qqc2Debug() if (false) qDebug()
+#define qqc2Info() if (false) qDebug()
+#define qqc2InfoHeading(HEADING) if (false) qDebug()
+#endif
+
+QT_BEGIN_NAMESPACE
+
+using namespace QQC2;
+
+class QQuickStyleMargins
+{
+ Q_GADGET
+
+ Q_PROPERTY(int left READ left())
+ Q_PROPERTY(int top READ top())
+ Q_PROPERTY(int right READ right())
+ Q_PROPERTY(int bottom READ bottom())
+
+ QML_NAMED_ELEMENT(stylemargins)
+ QML_UNCREATABLE("")
+
+public:
+ QQuickStyleMargins() {}
+ QQuickStyleMargins(const QQuickStyleMargins &other) : m_margins(other.m_margins) {}
+ QQuickStyleMargins(const QMargins &margins) : m_margins(margins) {}
+ QQuickStyleMargins(const QRect &outer, const QRect &inner)
+ {
+ const int left = inner.left() - outer.left();
+ const int top = inner.top() - outer.top();
+ const int right = outer.right() - inner.right();
+ const int bottom = outer.bottom() - inner.bottom();
+ m_margins = QMargins(left, top, right, bottom);
+ }
+
+ inline void operator=(const QQuickStyleMargins &other) { m_margins = other.m_margins; }
+ inline bool operator==(const QQuickStyleMargins &other) const { return other.m_margins == m_margins; }
+ inline bool operator!=(const QQuickStyleMargins &other) const { return other.m_margins != m_margins; }
+
+ inline int left() const { return m_margins.left(); }
+ inline int right() const { return m_margins.right(); }
+ inline int top() const { return m_margins.top(); }
+ inline int bottom() const { return m_margins.bottom(); }
+
+ QMargins m_margins;
+};
+
+QDebug operator<<(QDebug debug, const QQuickStyleMargins &padding);
+
+struct StyleItemGeometry
+{
+ /*
+ A QQuickStyleItem is responsible for drawing a control, or a part of it.
+
+ 'minimumSize' should be the minimum possible size that the item can
+ have _without_ taking content size into consideration (and still render
+ correctly). This will also be the size of the image that the item is drawn
+ to, unless QQuickStyleItem::useNinePatchImage is set to false. In that
+ case, the size of the image will be set to the size of the item instead
+ (which is set from QML, and will typically be the same as the size of the control).
+ The default way to calculate minimumSize is to call style()->sizeFromContents()
+ with an empty content size. This is not always well supported by the legacy QStyle
+ implementation, which means that you might e.g get an empty size in return.
+ For those cases, the correct solution is to go into the specific platform style
+ and change it so that it returns a valid size also for this special case.
+
+ 'implicitSize' should reflect the preferred size of the item, taking the
+ given content size (as set from QML) into account. But not all controls
+ have contents (slider), and for many controls, the content/label is instead
+ placed outside the item/background image (radiobutton). In both cases, the
+ size of the item will not include the content size, and implicitSize can
+ usually be set equal to minimumSize instead.
+
+ 'contentRect' should be the free space where the contents can be placed. Note that
+ this rect doesn't need to have the same size as the contentSize provided as input
+ to the style item. Instead, QStyle can typically calculate a rect that is bigger, to
+ e.g center the contents inside the control.
+
+ 'layoutRect' can be set to shift the position of the whole control so
+ that aligns correctly with the other controls. This is important for
+ controls that draws e.g shadows or focus rings. Such adornments should
+ be painted, but not be included when aligning the controls.
+ */
+
+ QSize minimumSize;
+ QSize implicitSize;
+ QRect contentRect;
+ QRect layoutRect; // If invalid, there are no layout margins!
+ QMargins ninePatchMargins;
+ qreal focusFrameRadius;
+};
+
+QDebug operator<<(QDebug debug, const StyleItemGeometry &cg);
+
+class QQuickStyleItem : public QQuickItem
+{
+ Q_OBJECT
+
+ // Input
+ Q_PROPERTY(QQuickItem *control MEMBER m_control NOTIFY controlChanged)
+ Q_PROPERTY(qreal contentWidth READ contentWidth WRITE setContentWidth)
+ Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight)
+ Q_PROPERTY(bool useNinePatchImage MEMBER m_useNinePatchImage)
+ Q_PROPERTY(OverrideState overrideState MEMBER m_overrideState)
+
+ // Output
+ Q_PROPERTY(QQuickStyleMargins contentPadding READ contentPadding() NOTIFY contentPaddingChanged)
+ Q_PROPERTY(QQuickStyleMargins layoutMargins READ layoutMargins() NOTIFY layoutMarginsChanged)
+ Q_PROPERTY(QSize minimumSize READ minimumSize() NOTIFY minimumSizeChanged)
+ Q_PROPERTY(int transitionDuration MEMBER m_transitionDuration CONSTANT)
+
+ QML_NAMED_ELEMENT(StyleItem)
+ QML_UNCREATABLE("StyleItem is an abstract base class.")
+
+public:
+ enum DirtyFlag {
+ Nothing = 0,
+ Geometry,
+ Image,
+ Everything = 255
+ };
+ Q_DECLARE_FLAGS(DirtyFlags, DirtyFlag)
+
+ enum OverrideState {
+ None = 0,
+ AlwaysHovered,
+ NeverHovered,
+ AlwaysSunken
+ };
+ Q_ENUM(OverrideState)
+
+
+#ifdef QT_DEBUG
+ enum DebugFlag {
+ NoDebug = 0x000,
+ Debug = 0x001,
+ Info = 0x002,
+ ImageRect = 0x004,
+ ContentRect = 0x008,
+ LayoutRect = 0x010,
+ Unscaled = 0x020,
+ InputContentSize = 0x040,
+ DontUseNinePatchImage = 0x080,
+ NinePatchMargins = 0x100,
+ SaveImage = 0x200,
+ };
+ Q_FLAG(DebugFlag)
+ Q_DECLARE_FLAGS(DebugFlags, DebugFlag)
+#endif
+
+ explicit QQuickStyleItem(QQuickItem *parent = nullptr);
+ ~QQuickStyleItem() override;
+
+ qreal contentWidth();
+ void setContentWidth(qreal contentWidth);
+ qreal contentHeight();
+ void setContentHeight(qreal contentHeight);
+
+ QQuickStyleMargins contentPadding() const;
+ QQuickStyleMargins layoutMargins() const;
+ QSize minimumSize() const;
+ QSize imageSize() const;
+ qreal focusFrameRadius() const;
+
+ Q_INVOKABLE virtual QFont styleFont(QQuickItem *control) const;
+
+ void markGeometryDirty();
+ void markImageDirty();
+
+signals:
+ void controlChanged();
+ void contentPaddingChanged();
+ void layoutMarginsChanged();
+ void fontChanged();
+ void minimumSizeChanged();
+
+protected:
+ void componentComplete() override;
+ QSGNode *updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *updatePaintNodeData) override;
+ void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+ void itemChange(ItemChange change, const ItemChangeData &data) override;
+ void updatePolish() override;
+
+ virtual void connectToControl() const;
+ virtual void paintEvent(QPainter *painter) const = 0;
+ virtual StyleItemGeometry calculateGeometry() = 0;
+
+ static QStyle::State controlSize(QQuickItem *item);
+ void initStyleOptionBase(QStyleOption &styleOption) const;
+
+ inline QSize contentSize() const { return QSize(qCeil(m_contentSize.width()), qCeil(m_contentSize.height())); }
+ inline static QStyle *style() { return QQuickNativeStyle::style(); }
+
+ template <class T> inline const T* control() const {
+#ifdef QT_DEBUG
+ if (!dynamic_cast<T *>(m_control.data())) {
+ qmlWarning(this) << "control property is not of correct type";
+ Q_UNREACHABLE();
+ }
+#endif
+ return static_cast<T *>(m_control.data());
+ }
+
+#ifdef QT_DEBUG
+ DebugFlags m_debugFlags = NoDebug;
+#endif
+ OverrideState m_overrideState = None;
+
+private:
+ inline void updateGeometry();
+ inline void paintControlToImage();
+
+ int dprAlignedSize(const int size) const;
+
+#ifdef QT_DEBUG
+ void addDebugInfo();
+#endif
+
+private:
+ QPointer<QQuickItem> m_control;
+ QImage m_paintedImage;
+ StyleItemGeometry m_styleItemGeometry;
+ QSizeF m_contentSize;
+
+ DirtyFlags m_dirty = Everything;
+ bool m_useNinePatchImage = true;
+ bool m_polishing = false;
+ mutable QQuickWindow *m_connectedWindow = nullptr;
+
+#ifdef Q_OS_MACOS
+ int m_transitionDuration = 150;
+#else
+ int m_transitionDuration = 400;
+#endif
+
+private:
+ friend class QtQuickControls2MacOSStylePlugin;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickStyleItem::DirtyFlags)
+
+#ifdef QT_DEBUG
+Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickStyleItem::DebugFlags)
+#endif
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickStyleItem)
+
+#endif // QQUICKSTYLEITEM_H
diff --git a/src/quicknativestyle/items/qquickstyleitembutton.cpp b/src/quicknativestyle/items/qquickstyleitembutton.cpp
new file mode 100644
index 0000000000..5dfe060fad
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitembutton.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickstyleitembutton.h"
+
+QFont QQuickStyleItemButton::styleFont(QQuickItem *control) const
+{
+ return style()->font(QStyle::CE_PushButtonLabel, controlSize(control));
+}
+
+void QQuickStyleItemButton::connectToControl() const
+{
+ QQuickStyleItem::connectToControl();
+ auto button = control<QQuickButton>();
+ connect(button, &QQuickButton::downChanged, this, &QQuickStyleItem::markImageDirty);
+}
+
+StyleItemGeometry QQuickStyleItemButton::calculateGeometry()
+{
+ QStyleOptionButton styleOption;
+ initStyleOption(styleOption);
+ StyleItemGeometry geometry;
+
+ geometry.minimumSize = style()->sizeFromContents(QStyle::CT_PushButton, &styleOption, QSize(0, 0));
+ geometry.implicitSize = style()->sizeFromContents(QStyle::CT_PushButton, &styleOption, contentSize());
+ 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);
+ geometry.focusFrameRadius = style()->pixelMetric(QStyle::PM_PushButtonFocusFrameRadius, &styleOption);
+
+ return geometry;
+}
+
+void QQuickStyleItemButton::paintEvent(QPainter *painter) const
+{
+ QStyleOptionButton styleOption;
+ initStyleOption(styleOption);
+ style()->drawControl(QStyle::CE_PushButtonBevel, &styleOption, painter);
+}
+
+void QQuickStyleItemButton::initStyleOption(QStyleOptionButton &styleOption) const
+{
+ initStyleOptionBase(styleOption);
+ auto button = control<QQuickButton>();
+
+ if (button->isDown())
+ styleOption.state |= QStyle::State_Sunken;
+ if (!button->isFlat() && !button->isDown())
+ styleOption.state |= QStyle::State_Raised;
+ if (button->isHighlighted() || button->isChecked())
+ styleOption.state |= QStyle::State_On;
+ if (button->isFlat())
+ styleOption.features |= QStyleOptionButton::Flat;
+}
diff --git a/src/quicknativestyle/items/qquickstyleitembutton.h b/src/quicknativestyle/items/qquickstyleitembutton.h
new file mode 100644
index 0000000000..41ca0cf176
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitembutton.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKSTYLEITEMBUTTON_H
+#define QQUICKSTYLEITEMBUTTON_H
+
+#include "qquickstyleitem.h"
+#include <QtQuickTemplates2/private/qquickbutton_p.h>
+
+class QQuickStyleItemButton : public QQuickStyleItem
+{
+ Q_OBJECT
+ QML_NAMED_ELEMENT(Button)
+
+public:
+ QFont styleFont(QQuickItem *control) const override;
+
+protected:
+ void connectToControl() const override;
+ void paintEvent(QPainter *painter) const override;
+ StyleItemGeometry calculateGeometry() override;
+
+private:
+ void initStyleOption(QStyleOptionButton &styleOption) const;
+};
+
+#endif // QQUICKSTYLEITEMBUTTON_H
diff --git a/src/quicknativestyle/items/qquickstyleitemcheckbox.cpp b/src/quicknativestyle/items/qquickstyleitemcheckbox.cpp
new file mode 100644
index 0000000000..6c4ac8ea30
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemcheckbox.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickstyleitemcheckbox.h"
+
+QFont QQuickStyleItemCheckBox::styleFont(QQuickItem *control) const
+{
+ return style()->font(QStyle::CE_RadioButtonLabel, controlSize(control));
+}
+
+void QQuickStyleItemCheckBox::connectToControl() const
+{
+ QQuickStyleItem::connectToControl();
+ auto checkbox = control<QQuickCheckBox>();
+ connect(checkbox, &QQuickCheckBox::downChanged, this, &QQuickStyleItem::markImageDirty);
+ connect(checkbox, &QQuickCheckBox::checkStateChanged, this, &QQuickStyleItem::markImageDirty);
+}
+
+StyleItemGeometry QQuickStyleItemCheckBox::calculateGeometry()
+{
+ QStyleOptionButton styleOption;
+ initStyleOption(styleOption);
+ StyleItemGeometry geometry;
+
+ geometry.minimumSize = style()->sizeFromContents(QStyle::CT_CheckBox, &styleOption, QSize(0, 0));
+ geometry.implicitSize = geometry.minimumSize;
+ 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);
+ geometry.focusFrameRadius = style()->pixelMetric(QStyle::PM_CheckBoxFocusFrameRadius, &styleOption);
+
+ // Spacing seems to already be baked into SE_CheckBoxContents, so ignore until needed
+ //const int space = style()->pixelMetric(QStyle::PM_CheckBoxLabelSpacing, &styleOption);
+
+ return geometry;
+}
+
+void QQuickStyleItemCheckBox::paintEvent(QPainter *painter) const
+{
+ QStyleOptionButton styleOption;
+ initStyleOption(styleOption);
+ style()->drawControl(QStyle::CE_CheckBox, &styleOption, painter);
+}
+
+void QQuickStyleItemCheckBox::initStyleOption(QStyleOptionButton &styleOption) const
+{
+ initStyleOptionBase(styleOption);
+ auto checkbox = control<QQuickCheckBox>();
+
+ styleOption.state |= checkbox->isDown() ? QStyle::State_Sunken : QStyle::State_Raised;
+ if (checkbox->isTristate() && checkbox->checkState() == Qt::PartiallyChecked)
+ styleOption.state |= QStyle::State_NoChange;
+ else
+ styleOption.state |= checkbox->isChecked() ? QStyle::State_On : QStyle::State_Off;
+}
diff --git a/src/quicknativestyle/items/qquickstyleitemcheckbox.h b/src/quicknativestyle/items/qquickstyleitemcheckbox.h
new file mode 100644
index 0000000000..03bf34b933
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemcheckbox.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKSTYLEITEMCHECKBOX_H
+#define QQUICKSTYLEITEMCHECKBOX_H
+
+#include "qquickstyleitem.h"
+#include <QtQuickTemplates2/private/qquickcheckbox_p.h>
+
+class QQuickStyleItemCheckBox : public QQuickStyleItem
+{
+ Q_OBJECT
+ QML_NAMED_ELEMENT(CheckBox)
+
+public:
+ QFont styleFont(QQuickItem *control) const override;
+
+protected:
+ void connectToControl() const override;
+ void paintEvent(QPainter *painter) const override;
+ StyleItemGeometry calculateGeometry() override;
+
+private:
+ void initStyleOption(QStyleOptionButton &styleOption) const;
+};
+
+#endif // QQUICKSTYLEITEMCHECKBOX_H
diff --git a/src/quicknativestyle/items/qquickstyleitemcombobox.cpp b/src/quicknativestyle/items/qquickstyleitemcombobox.cpp
new file mode 100644
index 0000000000..0ac3756e4e
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemcombobox.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickstyleitemcombobox.h"
+
+QFont QQuickStyleItemComboBox::styleFont(QQuickItem *control) const
+{
+ return style()->font(QStyle::CE_PushButtonLabel, controlSize(control));
+}
+
+void QQuickStyleItemComboBox::connectToControl() const
+{
+ QQuickStyleItem::connectToControl();
+ auto comboBox = control<QQuickComboBox>();
+ connect(comboBox, &QQuickComboBox::downChanged, this, &QQuickStyleItem::markImageDirty);
+}
+
+StyleItemGeometry QQuickStyleItemComboBox::calculateGeometry()
+{
+ QStyleOptionComboBox styleOption;
+ initStyleOption(styleOption);
+ StyleItemGeometry geometry;
+
+ geometry.minimumSize = style()->sizeFromContents(QStyle::CT_ComboBox, &styleOption, QSize(0, 0));
+ geometry.implicitSize = style()->sizeFromContents(QStyle::CT_ComboBox, &styleOption, contentSize());
+ styleOption.rect = QRect(QPoint(0, 0), geometry.implicitSize);
+ geometry.contentRect = style()->subControlRect(QStyle::CC_ComboBox, &styleOption, QStyle::SC_ComboBoxEditField);
+ geometry.layoutRect = style()->subElementRect(QStyle::SE_ComboBoxLayoutItem, &styleOption);
+ geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CC_ComboBox, &styleOption, geometry.minimumSize);
+ geometry.focusFrameRadius = style()->pixelMetric(QStyle::PM_ComboBoxFocusFrameRadius, &styleOption);
+
+ return geometry;
+}
+
+void QQuickStyleItemComboBox::paintEvent(QPainter *painter) const
+{
+ QStyleOptionComboBox styleOption;
+ initStyleOption(styleOption);
+ style()->drawComplexControl(QStyle::CC_ComboBox, &styleOption, painter);
+}
+
+void QQuickStyleItemComboBox::initStyleOption(QStyleOptionComboBox &styleOption) const
+{
+ initStyleOptionBase(styleOption);
+ auto comboBox = control<QQuickComboBox>();
+
+ styleOption.subControls = QStyle::SC_ComboBoxArrow | QStyle::SC_ComboBoxFrame | QStyle::SC_ComboBoxEditField;
+ styleOption.frame = true;
+ styleOption.state |= QStyle::State_Selected;
+ styleOption.editable = comboBox->isEditable();
+
+ if (comboBox->isDown())
+ styleOption.state |= QStyle::State_Sunken;
+ if (!comboBox->isFlat() && !comboBox->isDown())
+ styleOption.state |= QStyle::State_Raised;
+}
diff --git a/src/quicknativestyle/items/qquickstyleitemcombobox.h b/src/quicknativestyle/items/qquickstyleitemcombobox.h
new file mode 100644
index 0000000000..79f1995ed3
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemcombobox.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKSTYLEITEMCOMBOBOX_H
+#define QQUICKSTYLEITEMCOMBOBOX_H
+
+#include "qquickstyleitem.h"
+#include <QtQuickTemplates2/private/qquickcombobox_p.h>
+
+class QQuickStyleItemComboBox : public QQuickStyleItem
+{
+ Q_OBJECT
+ QML_NAMED_ELEMENT(ComboBox)
+
+public:
+ QFont styleFont(QQuickItem *control) const override;
+
+protected:
+ void connectToControl() const override;
+ void paintEvent(QPainter *painter) const override;
+ StyleItemGeometry calculateGeometry() override;
+
+private:
+ void initStyleOption(QStyleOptionComboBox &styleOption) const;
+};
+
+#endif // QQUICKSTYLEITEMCOMBOBOX_H
diff --git a/src/quicknativestyle/items/qquickstyleitemdial.cpp b/src/quicknativestyle/items/qquickstyleitemdial.cpp
new file mode 100644
index 0000000000..bf5784e1b5
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemdial.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickstyleitemdial.h"
+
+QFont QQuickStyleItemDial::styleFont(QQuickItem *control) const
+{
+ return style()->font(QStyle::CE_ProgressBarLabel, controlSize(control));
+}
+
+void QQuickStyleItemDial::connectToControl() const
+{
+ QQuickStyleItem::connectToControl();
+ auto dial = control<QQuickDial>();
+ connect(dial, &QQuickDial::fromChanged, this, &QQuickStyleItem::markImageDirty);
+ connect(dial, &QQuickDial::toChanged, this, &QQuickStyleItem::markImageDirty);
+ connect(dial, &QQuickDial::positionChanged, this, &QQuickStyleItem::markImageDirty);
+ connect(dial, &QQuickDial::valueChanged, this, &QQuickStyleItem::markImageDirty);
+ connect(dial, &QQuickDial::stepSizeChanged, this, &QQuickStyleItem::markImageDirty);
+ connect(dial, &QQuickDial::pressedChanged, this, &QQuickStyleItem::markImageDirty);
+}
+
+StyleItemGeometry QQuickStyleItemDial::calculateGeometry()
+{
+ QStyleOptionSlider styleOption;
+ initStyleOption(styleOption);
+
+ StyleItemGeometry geometry;
+ geometry.minimumSize = style()->sizeFromContents(QStyle::CT_Dial, &styleOption, QSize(0, 0));
+ geometry.implicitSize = geometry.minimumSize;
+ geometry.layoutRect = style()->subElementRect(QStyle::SE_SliderLayoutItem, &styleOption);
+ geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CC_Dial, &styleOption, geometry.minimumSize);
+ geometry.focusFrameRadius = style()->pixelMetric(QStyle::PM_DialFocusFrameRadius, &styleOption);
+
+ return geometry;
+}
+
+void QQuickStyleItemDial::paintEvent(QPainter *painter) const
+{
+ QStyleOptionSlider styleOption;
+ initStyleOption(styleOption);
+ style()->drawComplexControl(QStyle::CC_Dial, &styleOption, painter);
+}
+
+void QQuickStyleItemDial::initStyleOption(QStyleOptionSlider &styleOption) const
+{
+ initStyleOptionBase(styleOption);
+ auto dial = control<QQuickDial>();
+
+ styleOption.subControls = QStyle::SC_SliderGroove | QStyle::SC_SliderHandle;
+ styleOption.activeSubControls = QStyle::SC_None;
+ styleOption.tickInterval = dial->stepSize();
+ styleOption.dialWrapping = dial->wrap();
+ styleOption.upsideDown = true;
+
+ if (dial->isPressed())
+ styleOption.state |= QStyle::State_Sunken;
+
+ if (dial->stepSize() == 0) {
+ styleOption.minimum = 0;
+ styleOption.maximum = 10000;
+ styleOption.sliderPosition = dial->position() * styleOption.maximum;
+ } else {
+ styleOption.minimum = dial->from();
+ styleOption.maximum = dial->to();
+ styleOption.sliderPosition = dial->value();
+ }
+
+ // TODO: add proper API for tickmarks
+ const int index = dial->metaObject()->indexOfProperty("qqc2_style_tickPosition");
+ if (index != -1) {
+ const int tickPosition = dial->metaObject()->property(index).read(dial).toInt();
+ styleOption.tickPosition = QStyleOptionSlider::TickPosition(tickPosition);
+ if (styleOption.tickPosition != QStyleOptionSlider::NoTicks)
+ styleOption.subControls |= QStyle::SC_DialTickmarks;
+ }
+
+}
diff --git a/src/quicknativestyle/items/qquickstyleitemdial.h b/src/quicknativestyle/items/qquickstyleitemdial.h
new file mode 100644
index 0000000000..569820fea2
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemdial.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKSTYLEITEMDIAL_H
+#define QQUICKSTYLEITEMDIAL_H
+
+#include "qquickstyleitem.h"
+#include <QtQuickTemplates2/private/qquickdial_p.h>
+
+class QQuickStyleItemDial : public QQuickStyleItem
+{
+ Q_OBJECT
+ QML_NAMED_ELEMENT(Dial)
+
+public:
+ QFont styleFont(QQuickItem *control) const override;
+
+protected:
+ void connectToControl() const override;
+ void paintEvent(QPainter *painter) const override;
+ StyleItemGeometry calculateGeometry() override;
+
+private:
+ void initStyleOption(QStyleOptionSlider &styleOption) const;
+};
+
+#endif // QQUICKSTYLEITEMDIAL_H
diff --git a/src/quicknativestyle/items/qquickstyleitemframe.cpp b/src/quicknativestyle/items/qquickstyleitemframe.cpp
new file mode 100644
index 0000000000..cf0604927e
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemframe.cpp
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickstyleitemframe.h"
+
+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;
+}
+
+void QQuickStyleItemFrame::paintEvent(QPainter *painter) const
+{
+ QStyleOptionFrame styleOption;
+ initStyleOption(styleOption);
+ style()->drawControl(QStyle::CE_ShapedFrame, &styleOption, painter);
+}
+
+void QQuickStyleItemFrame::initStyleOption(QStyleOptionFrame &styleOption) const
+{
+ initStyleOptionBase(styleOption);
+ styleOption.lineWidth = 1;
+ styleOption.frameShape = QStyleOptionFrame::StyledPanel;
+ styleOption.features = QStyleOptionFrame::Flat;
+}
diff --git a/src/quicknativestyle/items/qquickstyleitemframe.h b/src/quicknativestyle/items/qquickstyleitemframe.h
new file mode 100644
index 0000000000..8e8da68b35
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemframe.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKSTYLEITEMFRAME_H
+#define QQUICKSTYLEITEMFRAME_H
+
+#include "qquickstyleitem.h"
+#include <QtQuickTemplates2/private/qquickframe_p.h>
+
+class QQuickStyleItemFrame : public QQuickStyleItem
+{
+ Q_OBJECT
+ QML_NAMED_ELEMENT(Frame)
+
+protected:
+ void paintEvent(QPainter *painter) const override;
+ StyleItemGeometry calculateGeometry() override;
+
+private:
+ void initStyleOption(QStyleOptionFrame &styleOption) const;
+};
+
+#endif // QQUICKSTYLEITEMFRAME_H
diff --git a/src/quicknativestyle/items/qquickstyleitemgroupbox.cpp b/src/quicknativestyle/items/qquickstyleitemgroupbox.cpp
new file mode 100644
index 0000000000..a828160d75
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemgroupbox.cpp
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickstyleitemgroupbox.h"
+
+QFont QQuickStyleItemGroupBox::styleFont(QQuickItem *control) const
+{
+ return style()->font(QStyle::CE_HeaderLabel, controlSize(control));
+}
+
+StyleItemGeometry QQuickStyleItemGroupBox::calculateGeometry()
+{
+ QStyleOptionGroupBox styleOption;
+ initStyleOption(styleOption);
+
+ StyleItemGeometry geometry;
+ geometry.minimumSize = style()->sizeFromContents(QStyle::CT_GroupBox, &styleOption, QSize(0, 0));
+
+ if (!control<QQuickGroupBox>()->title().isEmpty()) {
+ // We don't draw the title, but we need to take
+ // it into calculation for the control size
+ styleOption.text = QStringLiteral(" ");
+ styleOption.subControls |= QStyle::SC_GroupBoxLabel;
+ }
+
+ geometry.implicitSize = style()->sizeFromContents(QStyle::CT_GroupBox, &styleOption, contentSize());
+ 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);
+ m_groupBoxPadding = QQuickStyleMargins(QRect(QPoint(), geometry.implicitSize), frame);
+ if (m_groupBoxPadding != oldGroupBoxPadding)
+ emit groupBoxPaddingChanged();
+
+ const QPointF oldLabelPos = m_labelPos;
+ m_labelPos = style()->subControlRect(QStyle::CC_GroupBox, &styleOption, QStyle::SC_GroupBoxLabel).topLeft();
+ if (m_labelPos != oldLabelPos)
+ emit labelPosChanged();
+ return geometry;
+}
+
+void QQuickStyleItemGroupBox::paintEvent(QPainter *painter) const
+{
+ QStyleOptionGroupBox styleOption;
+ initStyleOption(styleOption);
+ style()->drawComplexControl(QStyle::CC_GroupBox, &styleOption, painter);
+}
+
+void QQuickStyleItemGroupBox::initStyleOption(QStyleOptionGroupBox &styleOption) const
+{
+ initStyleOptionBase(styleOption);
+ styleOption.subControls = QStyle::SC_GroupBoxFrame;
+ styleOption.lineWidth = 1;
+}
+
+QQuickStyleMargins QQuickStyleItemGroupBox::groupBoxPadding() const
+{
+ return m_groupBoxPadding;
+}
+
+QPointF QQuickStyleItemGroupBox::labelPos() const
+{
+ return m_labelPos;
+}
diff --git a/src/quicknativestyle/items/qquickstyleitemgroupbox.h b/src/quicknativestyle/items/qquickstyleitemgroupbox.h
new file mode 100644
index 0000000000..2b07287f03
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemgroupbox.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKSTYLEITEMGROUPBOX_H
+#define QQUICKSTYLEITEMGROUPBOX_H
+
+#include "qquickstyleitem.h"
+#include <QtQuickTemplates2/private/qquickgroupbox_p.h>
+
+class QQuickStyleItemGroupBox : public QQuickStyleItem
+{
+ Q_OBJECT
+ Q_PROPERTY(QQuickStyleMargins groupBoxPadding READ groupBoxPadding NOTIFY groupBoxPaddingChanged)
+ Q_PROPERTY(QPointF labelPos READ labelPos NOTIFY labelPosChanged)
+ QML_NAMED_ELEMENT(GroupBox)
+
+public:
+ QQuickStyleMargins groupBoxPadding() const;
+ QPointF labelPos() const;
+ QFont styleFont(QQuickItem *control) const override;
+
+signals:
+ void groupBoxPaddingChanged();
+ void labelPosChanged();
+
+protected:
+ void paintEvent(QPainter *painter) const override;
+ StyleItemGeometry calculateGeometry() override;
+
+private:
+ QQuickStyleMargins m_groupBoxPadding;
+ QPointF m_labelPos;
+
+ void initStyleOption(QStyleOptionGroupBox &styleOption) const;
+};
+
+#endif // QQUICKSTYLEITEMGROUPBOX_H
diff --git a/src/quicknativestyle/items/qquickstyleitemprogressbar.cpp b/src/quicknativestyle/items/qquickstyleitemprogressbar.cpp
new file mode 100644
index 0000000000..480e8981b5
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemprogressbar.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickstyleitemprogressbar.h"
+
+QFont QQuickStyleItemProgressBar::styleFont(QQuickItem *control) const
+{
+ return style()->font(QStyle::CE_ProgressBarLabel, controlSize(control));
+}
+
+void QQuickStyleItemProgressBar::connectToControl() const
+{
+ QQuickStyleItem::connectToControl();
+ auto progressBar = control<QQuickProgressBar>();
+ connect(progressBar, &QQuickProgressBar::fromChanged, this, &QQuickStyleItem::markImageDirty);
+ connect(progressBar, &QQuickProgressBar::toChanged, this, &QQuickStyleItem::markImageDirty);
+ connect(progressBar, &QQuickProgressBar::positionChanged, this, &QQuickStyleItem::markImageDirty);
+}
+
+StyleItemGeometry QQuickStyleItemProgressBar::calculateGeometry()
+{
+ QStyleOptionProgressBar styleOption;
+ initStyleOption(styleOption);
+
+ StyleItemGeometry geometry;
+ geometry.minimumSize = style()->sizeFromContents(QStyle::CT_ProgressBar, &styleOption, QSize(0, 0));
+
+ // From qprogressbar.cpp in qtbase:
+ const int cw = style()->pixelMetric(QStyle::PM_ProgressBarChunkWidth, &styleOption);
+ QFontMetrics fm(control<QQuickProgressBar>()->font());
+ QSize size = QSize(qMax(9, cw) * 7 + fm.horizontalAdvance(QLatin1Char('0')) * 4, fm.height() + 8);
+ if (!(styleOption.state & QStyle::State_Horizontal))
+ size = size.transposed();
+
+ geometry.implicitSize = style()->sizeFromContents(QStyle::CT_ProgressBar, &styleOption, size);
+ styleOption.rect = QRect(QPoint(0, 0), geometry.implicitSize);
+ geometry.contentRect = style()->subElementRect(QStyle::SE_ProgressBarContents, &styleOption);
+ geometry.layoutRect = style()->subElementRect(QStyle::SE_ProgressBarLayoutItem, &styleOption);
+ geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CE_ProgressBar, &styleOption, geometry.minimumSize);
+
+ return geometry;
+}
+
+void QQuickStyleItemProgressBar::paintEvent(QPainter *painter) const
+{
+ QStyleOptionProgressBar styleOption;
+ initStyleOption(styleOption);
+#ifndef Q_OS_MACOS
+ const QRect r = styleOption.rect;
+#endif
+ // Note: on macOS, the groove will paint both the background and the contents
+ styleOption.rect = style()->subElementRect(QStyle::SE_ProgressBarGroove, &styleOption);
+ style()->drawControl(QStyle::CE_ProgressBarGroove, &styleOption, painter);
+#ifndef Q_OS_MACOS
+ styleOption.rect = r;
+ styleOption.rect = style()->subElementRect(QStyle::SE_ProgressBarContents, &styleOption);
+ style()->drawControl(QStyle::CE_ProgressBarContents, &styleOption, painter);
+#endif
+}
+
+void QQuickStyleItemProgressBar::initStyleOption(QStyleOptionProgressBar &styleOption) const
+{
+ initStyleOptionBase(styleOption);
+ auto progressBar = control<QQuickProgressBar>();
+
+ styleOption.state = QStyle::State_Horizontal;
+
+ if (progressBar->isIndeterminate()) {
+ styleOption.minimum = 0;
+ styleOption.maximum = 0;
+ } else if (progressBar->to() - progressBar->from() < 100) {
+ // Add some range to support float numbers
+ styleOption.minimum = 0;
+ styleOption.maximum = (progressBar->to() - progressBar->from()) * 100;
+ styleOption.progress = (progressBar->value() - progressBar->from()) * 100;
+ } else {
+ styleOption.minimum = progressBar->from();
+ styleOption.maximum = progressBar->to();
+ styleOption.progress = progressBar->value();
+ }
+}
diff --git a/src/quicknativestyle/items/qquickstyleitemprogressbar.h b/src/quicknativestyle/items/qquickstyleitemprogressbar.h
new file mode 100644
index 0000000000..53692dbe32
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemprogressbar.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKSTYLEITEMPROGRESSBAR_H
+#define QQUICKSTYLEITEMPROGRESSBAR_H
+
+#include "qquickstyleitem.h"
+#include <QtQuickTemplates2/private/qquickprogressbar_p.h>
+
+class QQuickStyleItemProgressBar : public QQuickStyleItem
+{
+ Q_OBJECT
+
+ QML_NAMED_ELEMENT(ProgressBar)
+
+public:
+ QFont styleFont(QQuickItem *control) const override;
+
+protected:
+ void connectToControl() const override;
+ void paintEvent(QPainter *painter) const override;
+ StyleItemGeometry calculateGeometry() override;
+
+private:
+ void initStyleOption(QStyleOptionProgressBar &styleOption) const;
+};
+
+#endif // QQUICKSTYLEITEMPROGRESSBAR_H
diff --git a/src/quicknativestyle/items/qquickstyleitemradiobutton.cpp b/src/quicknativestyle/items/qquickstyleitemradiobutton.cpp
new file mode 100644
index 0000000000..655bb0b63b
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemradiobutton.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickstyleitemradiobutton.h"
+
+QFont QQuickStyleItemRadioButton::styleFont(QQuickItem *control) const
+{
+ return style()->font(QStyle::CE_RadioButtonLabel, controlSize(control));
+}
+
+void QQuickStyleItemRadioButton::connectToControl() const
+{
+ QQuickStyleItem::connectToControl();
+ auto checkbox = control<QQuickRadioButton>();
+ connect(checkbox, &QQuickRadioButton::downChanged, this, &QQuickStyleItem::markImageDirty);
+ connect(checkbox, &QQuickRadioButton::checkedChanged, this, &QQuickStyleItem::markImageDirty);
+}
+
+StyleItemGeometry QQuickStyleItemRadioButton::calculateGeometry()
+{
+ QStyleOptionButton styleOption;
+ initStyleOption(styleOption);
+ StyleItemGeometry geometry;
+
+ geometry.minimumSize = style()->sizeFromContents(QStyle::CT_RadioButton, &styleOption, QSize(0, 0));
+ geometry.implicitSize = geometry.minimumSize;
+ 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);
+ geometry.focusFrameRadius = style()->pixelMetric(QStyle::PM_RadioButtonFocusFrameRadius, &styleOption);
+
+ return geometry;
+}
+
+void QQuickStyleItemRadioButton::paintEvent(QPainter *painter) const
+{
+ QStyleOptionButton styleOption;
+ initStyleOption(styleOption);
+ style()->drawControl(QStyle::CE_RadioButton, &styleOption, painter);
+}
+
+void QQuickStyleItemRadioButton::initStyleOption(QStyleOptionButton &styleOption) const
+{
+ initStyleOptionBase(styleOption);
+ auto checkbox = control<QQuickRadioButton>();
+
+ styleOption.state |= checkbox->isDown() ? QStyle::State_Sunken : QStyle::State_Raised;
+ styleOption.state |= checkbox->isChecked() ? QStyle::State_On : QStyle::State_Off;
+}
diff --git a/src/quicknativestyle/items/qquickstyleitemradiobutton.h b/src/quicknativestyle/items/qquickstyleitemradiobutton.h
new file mode 100644
index 0000000000..56073d8f49
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemradiobutton.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKSTYLEITEMRADIOBUTTON_H
+#define QQUICKSTYLEITEMRADIOBUTTON_H
+
+#include "qquickstyleitem.h"
+#include <QtQuickTemplates2/private/qquickradiobutton_p.h>
+
+class QQuickStyleItemRadioButton : public QQuickStyleItem
+{
+ Q_OBJECT
+ QML_NAMED_ELEMENT(RadioButton)
+
+public:
+ QFont styleFont(QQuickItem *control) const override;
+
+protected:
+ void connectToControl() const override;
+ void paintEvent(QPainter *painter) const override;
+ StyleItemGeometry calculateGeometry() override;
+
+private:
+ void initStyleOption(QStyleOptionButton &styleOption) const;
+};
+
+#endif // QQUICKSTYLEITEMRADIOBUTTON_H
diff --git a/src/quicknativestyle/items/qquickstyleitemscrollbar.cpp b/src/quicknativestyle/items/qquickstyleitemscrollbar.cpp
new file mode 100644
index 0000000000..d6d41d969b
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemscrollbar.cpp
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickstyleitemscrollbar.h"
+
+QFont QQuickStyleItemScrollBar::styleFont(QQuickItem *control) const
+{
+ return style()->font(QStyle::CE_ProgressBarLabel, controlSize(control));
+}
+
+void QQuickStyleItemScrollBar::connectToControl() const
+{
+ QQuickStyleItem::connectToControl();
+ auto scrollBar = control<QQuickScrollBar>();
+ connect(scrollBar, &QQuickScrollBar::orientationChanged, this, &QQuickStyleItem::markImageDirty);
+ connect(scrollBar, &QQuickScrollBar::pressedChanged, this, &QQuickStyleItem::markImageDirty);
+}
+
+StyleItemGeometry QQuickStyleItemScrollBar::calculateGeometry()
+{
+ QStyleOptionSlider styleOption;
+ initStyleOption(styleOption);
+
+ StyleItemGeometry geometry;
+ geometry.minimumSize = style()->sizeFromContents(QStyle::CT_ScrollBar, &styleOption, QSize(0, 0));
+ if (m_subControl == SubLine || m_subControl == AddLine) {
+ // So far, we know that only the windows style uses these subcontrols,
+ // so we can use hardcoded sizes...
+ QSize sz(16, 17);
+ if (styleOption.orientation == Qt::Vertical)
+ sz.transpose();
+ geometry.minimumSize = sz;
+ }
+ geometry.implicitSize = geometry.minimumSize;
+ styleOption.rect = QRect(QPoint(0, 0), geometry.implicitSize);
+ geometry.layoutRect = style()->subElementRect(QStyle::SE_ScrollBarLayoutItem, &styleOption);
+ geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CC_ScrollBar, &styleOption, geometry.minimumSize);
+
+ return geometry;
+}
+
+void QQuickStyleItemScrollBar::paintEvent(QPainter *painter) const
+{
+ QStyleOptionSlider styleOption;
+ initStyleOption(styleOption);
+ if (m_subControl == SubLine || m_subControl == AddLine) {
+ QStyle::SubControl sc = m_subControl == SubLine ? QStyle::SC_ScrollBarSubLine : QStyle::SC_ScrollBarAddLine;
+ QStyleOptionSlider opt = styleOption;
+ opt.subControls = QStyle::SC_ScrollBarAddLine
+ | QStyle::SC_ScrollBarSubLine
+ | QStyle::SC_ScrollBarGroove;
+
+ const qreal scale = window()->devicePixelRatio();
+ const QSize scrollBarMinSize = style()->sizeFromContents(QStyle::CT_ScrollBar, &opt, QSize(0, 0));
+ const QSize sz = scrollBarMinSize * scale;
+ QImage scrollBarImage(sz, QImage::Format_ARGB32_Premultiplied);
+ scrollBarImage.setDevicePixelRatio(scale);
+ QPainter p(&scrollBarImage);
+ opt.rect = QRect(QPoint(0, 0), scrollBarMinSize);
+ style()->drawComplexControl(QStyle::CC_ScrollBar, &opt, &p);
+ QRect sourceImageRect = style()->subControlRect(QStyle::CC_ScrollBar, &opt, sc);
+ sourceImageRect = QRect(sourceImageRect.topLeft() * scale, sourceImageRect.size() * scale);
+ painter->drawImage(QPoint(0, 0), scrollBarImage, sourceImageRect);
+ } else {
+ style()->drawComplexControl(QStyle::CC_ScrollBar, &styleOption, painter);
+ }
+}
+
+void QQuickStyleItemScrollBar::initStyleOption(QStyleOptionSlider &styleOption) const
+{
+ initStyleOptionBase(styleOption);
+ auto scrollBar = control<QQuickScrollBar>();
+
+ switch (m_subControl) {
+ case Groove:
+ styleOption.subControls = QStyle::SC_ScrollBarGroove | QStyle::SC_ScrollBarAddLine | QStyle::SC_ScrollBarSubLine;
+ break;
+ case Handle:
+ styleOption.subControls = QStyle::SC_ScrollBarSlider;
+ break;
+ case AddLine:
+ styleOption.subControls = QStyle::SC_ScrollBarAddLine;
+ break;
+ case SubLine:
+ styleOption.subControls = QStyle::SC_ScrollBarSubLine;
+ break;
+ }
+
+ styleOption.activeSubControls = QStyle::SC_None;
+ styleOption.orientation = scrollBar->orientation();
+ if (styleOption.orientation == Qt::Horizontal)
+ styleOption.state |= QStyle::State_Horizontal;
+
+ if (scrollBar->isPressed())
+ styleOption.state |= QStyle::State_Sunken;
+
+ if (m_overrideState != None) {
+ // In ScrollBar.qml we fade between two versions of
+ // the handle, depending on if it's hovered or not
+
+ if (m_overrideState == AlwaysHovered) {
+ styleOption.activeSubControls = (styleOption.subControls & (QStyle::SC_ScrollBarSlider | QStyle::SC_ScrollBarGroove | QStyle::SC_ScrollBarAddLine | QStyle::SC_ScrollBarSubLine));
+ } else if (m_overrideState == NeverHovered) {
+ styleOption.activeSubControls &= ~(styleOption.subControls & (QStyle::SC_ScrollBarSlider | QStyle::SC_ScrollBarGroove | QStyle::SC_ScrollBarAddLine | QStyle::SC_ScrollBarSubLine));
+ } else if (m_overrideState == AlwaysSunken) {
+ styleOption.state |= QStyle::State_Sunken;
+ styleOption.activeSubControls = (styleOption.subControls & (QStyle::SC_ScrollBarSlider | QStyle::SC_ScrollBarGroove | QStyle::SC_ScrollBarAddLine | QStyle::SC_ScrollBarSubLine));
+ }
+ }
+
+ // The following values will let the handle fill 100% of the
+ // groove / imageSize. But when the handle is resized by
+ // QQuickScrollBar, it will end up with the correct size visually.
+ styleOption.pageStep = 1000;
+ styleOption.minimum = 0;
+ styleOption.maximum = 1;
+ styleOption.sliderValue = 0;
+}
diff --git a/src/quicknativestyle/items/qquickstyleitemscrollbar.h b/src/quicknativestyle/items/qquickstyleitemscrollbar.h
new file mode 100644
index 0000000000..f89d8d3ec3
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemscrollbar.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKSTYLEITEMSCROLLBAR_H
+#define QQUICKSTYLEITEMSCROLLBAR_H
+
+#include "qquickstyleitem.h"
+#include <QtQuickTemplates2/private/qquickscrollbar_p.h>
+
+class QQuickStyleItemScrollBar : public QQuickStyleItem
+{
+ Q_OBJECT
+
+ Q_PROPERTY(SubControl subControl MEMBER m_subControl)
+
+ QML_NAMED_ELEMENT(ScrollBar)
+
+public:
+ enum SubControl {
+ Groove = 1,
+ Handle,
+ AddLine,
+ SubLine
+ };
+ Q_ENUM(SubControl)
+
+ QFont styleFont(QQuickItem *control) const override;
+
+protected:
+ void connectToControl() const override;
+ void paintEvent(QPainter *painter) const override;
+ StyleItemGeometry calculateGeometry() override;
+
+private:
+ void initStyleOption(QStyleOptionSlider &styleOption) const;
+
+private:
+ SubControl m_subControl = Groove;
+};
+
+#endif // QQUICKSTYLEITEMSCROLLBAR_H
diff --git a/src/quicknativestyle/items/qquickstyleitemscrollviewcorner.cpp b/src/quicknativestyle/items/qquickstyleitemscrollviewcorner.cpp
new file mode 100644
index 0000000000..3a992f2d9b
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemscrollviewcorner.cpp
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickstyleitemscrollviewcorner.h"
+
+StyleItemGeometry QQuickStyleItemScrollViewCorner::calculateGeometry()
+{
+ QStyleOptionSlider styleOption;
+ initStyleOption(styleOption);
+
+ StyleItemGeometry geometry;
+
+ // The size of the corner should be the width of the vertical
+ // scrollbar and the height of the horizontal scrollbar.
+ styleOption.orientation = Qt::Vertical;
+ const auto vScrollBarWidth = style()->sizeFromContents(QStyle::CT_ScrollBar, &styleOption, QSize(0, 0)).width();
+ styleOption.orientation = Qt::Horizontal;
+ const auto hScrollBarHeight = style()->sizeFromContents(QStyle::CT_ScrollBar, &styleOption, QSize(0, 0)).height();
+
+ geometry.minimumSize = QSize(vScrollBarWidth, hScrollBarHeight);
+ geometry.implicitSize = geometry.minimumSize;
+
+ return geometry;
+}
+
+void QQuickStyleItemScrollViewCorner::paintEvent(QPainter *painter) const
+{
+ QStyleOptionSlider styleOption;
+ initStyleOption(styleOption);
+
+ // Grab a center piece of a vertical scrollbar groove onto a QImage, and use this
+ // image to draw a corner. We draw the corner by first drawing the piece as it is, and
+ // then rotate it 90 degrees, clip it into a triangle, and draw it once more on top.
+ // The result is that we end up with one vertical and one horizontal triangle that
+ // together form a filled corner rectangle.
+
+ styleOption.orientation = Qt::Vertical;
+
+ const qreal scale = window()->devicePixelRatio();
+ const int grooveWidth = minimumSize().width();
+ const int grooveHeight = minimumSize().height();
+ const QSize scrollBarMinSize = style()->sizeFromContents(QStyle::CT_ScrollBar, &styleOption, QSize(0, 0));
+ const QSize scrollBarSize = scrollBarMinSize + QSize(0, grooveHeight);
+ const int hStart = scrollBarMinSize.height() / 2;
+ const QRect targetImageRect(0, hStart * scale, grooveWidth * scale, grooveHeight * scale);
+
+ QImage scrollBarImage(scrollBarSize * scale, QImage::Format_ARGB32_Premultiplied);
+ scrollBarImage.setDevicePixelRatio(scale);
+ scrollBarImage.fill(Qt::transparent);
+ QPainter scrollBarPainter(&scrollBarImage);
+ styleOption.rect = QRect(QPoint(0, 0), scrollBarSize);
+ style()->drawComplexControl(QStyle::CC_ScrollBar, &styleOption, &scrollBarPainter);
+
+ // Draw vertical groove
+ painter->drawImage(QPoint(0, 0), scrollBarImage, targetImageRect);
+
+ QPainterPath path;
+ path.moveTo(0, 0);
+ path.lineTo(0, grooveHeight);
+ path.lineTo(grooveWidth, grooveHeight);
+ path.closeSubpath();
+
+ QTransform transform;
+ transform.translate(grooveWidth, 0);
+ transform.rotate(90);
+
+ painter->save();
+ painter->setCompositionMode(QPainter::CompositionMode_Source);
+ painter->setClipPath(path);
+ painter->setTransform(transform);
+ // Draw horizontal groove, clipped to a triangle
+ painter->drawImage(QPoint(0, 0), scrollBarImage, targetImageRect);
+ painter->restore();
+}
+
+void QQuickStyleItemScrollViewCorner::initStyleOption(QStyleOptionSlider &styleOption) const
+{
+ initStyleOptionBase(styleOption);
+
+ styleOption.subControls = QStyle::SC_ScrollBarGroove;
+ styleOption.activeSubControls = QStyle::SC_None;
+ styleOption.pageStep = 1000;
+ styleOption.minimum = 0;
+ styleOption.maximum = 1;
+ styleOption.sliderValue = 0;
+}
diff --git a/src/quicknativestyle/items/qquickstyleitemscrollviewcorner.h b/src/quicknativestyle/items/qquickstyleitemscrollviewcorner.h
new file mode 100644
index 0000000000..637a8ea821
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemscrollviewcorner.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKSTYLEITEMSCROLLVIEWCORNER_H
+#define QQUICKSTYLEITEMSCROLLVIEWCORNER_H
+
+#include "qquickstyleitem.h"
+#include <QtQuickTemplates2/private/qquickscrollbar_p.h>
+
+class QQuickStyleItemScrollViewCorner : public QQuickStyleItem
+{
+ Q_OBJECT
+ QML_NAMED_ELEMENT(ScrollViewCorner)
+
+protected:
+ void paintEvent(QPainter *painter) const override;
+ StyleItemGeometry calculateGeometry() override;
+
+private:
+ void initStyleOption(QStyleOptionSlider &styleOption) const;
+};
+
+#endif // QQUICKSTYLEITEMSCROLLVIEWCORNER_H
diff --git a/src/quicknativestyle/items/qquickstyleitemslider.cpp b/src/quicknativestyle/items/qquickstyleitemslider.cpp
new file mode 100644
index 0000000000..67161ad3da
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemslider.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickstyleitemslider.h"
+
+QFont QQuickStyleItemSlider::styleFont(QQuickItem *control) const
+{
+ return style()->font(QStyle::CE_ProgressBarLabel, controlSize(control));
+}
+
+void QQuickStyleItemSlider::connectToControl() const
+{
+ QQuickStyleItem::connectToControl();
+ auto slider = control<QQuickSlider>();
+ connect(slider, &QQuickSlider::fromChanged, this, &QQuickStyleItem::markImageDirty);
+ connect(slider, &QQuickSlider::toChanged, this, &QQuickStyleItem::markImageDirty);
+ connect(slider, &QQuickSlider::positionChanged, this, &QQuickStyleItem::markImageDirty);
+ connect(slider, &QQuickSlider::valueChanged, this, &QQuickStyleItem::markImageDirty);
+ connect(slider, &QQuickSlider::stepSizeChanged, this, &QQuickStyleItem::markImageDirty);
+ connect(slider, &QQuickSlider::pressedChanged, this, &QQuickStyleItem::markImageDirty);
+ connect(slider, &QQuickSlider::orientationChanged, this, &QQuickStyleItem::markImageDirty);
+}
+
+StyleItemGeometry QQuickStyleItemSlider::calculateGeometry()
+{
+ QStyleOptionSlider styleOption;
+ initStyleOption(styleOption);
+
+ StyleItemGeometry geometry;
+ geometry.minimumSize = style()->sizeFromContents(QStyle::CT_Slider, &styleOption, QSize(0, 0));
+ geometry.implicitSize = geometry.minimumSize;
+ styleOption.rect = QRect(QPoint(0, 0), geometry.implicitSize);
+ geometry.layoutRect = style()->subElementRect(QStyle::SE_SliderLayoutItem, &styleOption);
+ geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CC_Slider, &styleOption, geometry.minimumSize);
+ geometry.focusFrameRadius = style()->pixelMetric(QStyle::PM_SliderFocusFrameRadius, &styleOption);
+
+ return geometry;
+}
+
+void QQuickStyleItemSlider::paintEvent(QPainter *painter) const
+{
+ QStyleOptionSlider styleOption;
+ initStyleOption(styleOption);
+ style()->drawComplexControl(QStyle::CC_Slider, &styleOption, painter);
+}
+
+void QQuickStyleItemSlider::initStyleOption(QStyleOptionSlider &styleOption) const
+{
+ initStyleOptionBase(styleOption);
+ auto slider = control<QQuickSlider>();
+
+ styleOption.subControls = QStyle::SC_None;
+ if (m_subControl & Groove)
+ styleOption.subControls |= QStyle::SC_SliderGroove;
+ if (m_subControl & Handle)
+ styleOption.subControls |= QStyle::SC_SliderHandle;
+ styleOption.activeSubControls = QStyle::SC_None;
+ styleOption.orientation = slider->orientation();
+
+ if (slider->isPressed())
+ styleOption.state |= QStyle::State_Sunken;
+
+ qreal min = 0;
+ qreal max = 1;
+ if (!qFuzzyIsNull(slider->stepSize())) {
+ min = slider->from();
+ max = slider->to();
+
+ // TODO: add proper API for tickmarks
+ const int index = slider->metaObject()->indexOfProperty("qqc2_style_tickPosition");
+ if (index != -1) {
+ const int tickPosition = slider->metaObject()->property(index).read(slider).toInt();
+ styleOption.tickPosition = QStyleOptionSlider::TickPosition(tickPosition);
+ if (styleOption.tickPosition != QStyleOptionSlider::NoTicks)
+ styleOption.subControls |= QStyle::SC_SliderTickmarks;
+ }
+ }
+
+ // Since the [from, to] interval in QQuickSlider is floating point, users can
+ // specify very small ranges and step sizes, (e.g. [0.., 0.25], step size 0.05).
+ // Since the style operates on ints, we cannot pass these values directly to the style,
+ // so we normalize all values to the range [0, 10000]
+ static const qreal Scale = 10000;
+ const qreal normalizeMultiplier = Scale/(max - min);
+ styleOption.tickInterval = int(slider->stepSize() * normalizeMultiplier);
+ styleOption.minimum = 0;
+ styleOption.maximum = int(Scale);
+ styleOption.sliderValue = int((slider->value() - min) * normalizeMultiplier);
+ styleOption.sliderPosition = int(slider->position() * styleOption.maximum);
+}
diff --git a/src/quicknativestyle/items/qquickstyleitemslider.h b/src/quicknativestyle/items/qquickstyleitemslider.h
new file mode 100644
index 0000000000..9a5142072b
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemslider.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKSTYLEITEMSLIDER_H
+#define QQUICKSTYLEITEMSLIDER_H
+
+#include "qquickstyleitem.h"
+#include <QtQuickTemplates2/private/qquickslider_p.h>
+
+class QQuickStyleItemSlider : public QQuickStyleItem
+{
+ Q_OBJECT
+
+ Q_PROPERTY(SubControl subControl MEMBER m_subControl)
+
+ QML_NAMED_ELEMENT(Slider)
+
+public:
+ enum SubControl {
+ Groove = 1,
+ Handle,
+ };
+ Q_ENUM(SubControl)
+
+ QFont styleFont(QQuickItem *control) const override;
+
+protected:
+ void connectToControl() const override;
+ void paintEvent(QPainter *painter) const override;
+ StyleItemGeometry calculateGeometry() override;
+
+private:
+ void initStyleOption(QStyleOptionSlider &styleOption) const;
+
+private:
+ SubControl m_subControl = Groove;
+};
+
+#endif // QQUICKSTYLEITEMSLIDER_H
diff --git a/src/quicknativestyle/items/qquickstyleitemspinbox.cpp b/src/quicknativestyle/items/qquickstyleitemspinbox.cpp
new file mode 100644
index 0000000000..2a232b8a39
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemspinbox.cpp
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickstyleitemspinbox.h"
+#include <QtQuickTemplates2/private/qquickindicatorbutton_p.h>
+
+QFont QQuickStyleItemSpinBox::styleFont(QQuickItem *control) const
+{
+ return style()->font(QStyle::CE_ComboBoxLabel, controlSize(control));
+}
+
+void QQuickStyleItemSpinBox::connectToControl() const
+{
+ QQuickStyleItem::connectToControl();
+ auto spinbox = control<QQuickSpinBox>();
+ connect(spinbox->up(), &QQuickIndicatorButton::pressedChanged, this, &QQuickStyleItem::markImageDirty);
+ connect(spinbox->down(), &QQuickIndicatorButton::pressedChanged, this, &QQuickStyleItem::markImageDirty);
+}
+
+StyleItemGeometry QQuickStyleItemSpinBox::calculateGeometry()
+{
+ QStyleOptionSpinBox styleOption;
+ initStyleOption(styleOption);
+ StyleItemGeometry geometry;
+
+ geometry.minimumSize = style()->sizeFromContents(QStyle::CT_SpinBox, &styleOption, QSize(0, 0));
+
+ if (styleOption.subControls == QStyle::SC_SpinBoxFrame) {
+ geometry.implicitSize = style()->sizeFromContents(QStyle::CT_SpinBox, &styleOption, contentSize());
+ 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);
+ geometry.focusFrameRadius = style()->pixelMetric(QStyle::PM_SpinBoxFocusFrameRadius, &styleOption);
+ } else {
+ geometry.implicitSize = geometry.minimumSize;
+ }
+
+ return geometry;
+}
+
+void QQuickStyleItemSpinBox::paintEvent(QPainter *painter) const
+{
+ QStyleOptionSpinBox styleOption;
+ initStyleOption(styleOption);
+ style()->drawComplexControl(QStyle::CC_SpinBox, &styleOption, painter);
+}
+
+void QQuickStyleItemSpinBox::initStyleOption(QStyleOptionSpinBox &styleOption) const
+{
+ initStyleOptionBase(styleOption);
+ auto spinbox = control<QQuickSpinBox>();
+
+ switch (m_subControl) {
+ case Frame:
+ styleOption.subControls = QStyle::SC_SpinBoxFrame;
+ styleOption.frame = true;
+ break;
+ case Up:
+ styleOption.subControls = (QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown);
+ break;
+ case Down:
+ styleOption.subControls = QStyle::SC_SpinBoxDown;
+ break;
+ }
+
+ if (spinbox->up()->isPressed()) {
+ styleOption.activeSubControls = QStyle::SC_SpinBoxUp;
+ styleOption.state |= QStyle::State_Sunken;
+ } else if (spinbox->down()->isPressed()) {
+ styleOption.activeSubControls = QStyle::SC_SpinBoxDown;
+ styleOption.state |= QStyle::State_Sunken;
+ }
+
+ styleOption.buttonSymbols = QStyleOptionSpinBox::UpDownArrows;
+ styleOption.stepEnabled = QStyleOptionSpinBox::StepEnabled;
+}
diff --git a/src/quicknativestyle/items/qquickstyleitemspinbox.h b/src/quicknativestyle/items/qquickstyleitemspinbox.h
new file mode 100644
index 0000000000..d4b9f9fa6c
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemspinbox.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKSTYLEITEMSPINBOX_H
+#define QQUICKSTYLEITEMSPINBOX_H
+
+#include "qquickstyleitem.h"
+#include <QtQuickTemplates2/private/qquickspinbox_p.h>
+
+class QQuickStyleItemSpinBox : public QQuickStyleItem
+{
+ Q_OBJECT
+
+ Q_PROPERTY(SubControl subControl MEMBER m_subControl)
+
+ QML_NAMED_ELEMENT(SpinBox)
+
+public:
+ enum SubControl {
+ Frame = 1,
+ Up,
+ Down,
+ };
+ Q_ENUM(SubControl)
+
+ QFont styleFont(QQuickItem *control) const override;
+
+protected:
+ void connectToControl() const override;
+ void paintEvent(QPainter *painter) const override;
+ StyleItemGeometry calculateGeometry() override;
+
+private:
+ void initStyleOption(QStyleOptionSpinBox &styleOption) const;
+
+private:
+ SubControl m_subControl = Frame;
+};
+
+#endif // QQUICKSTYLEITEMSPINBOX_H
diff --git a/src/quicknativestyle/items/qquickstyleitemtextfield.cpp b/src/quicknativestyle/items/qquickstyleitemtextfield.cpp
new file mode 100644
index 0000000000..cd7d35aa67
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemtextfield.cpp
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickstyleitemtextfield.h"
+
+QFont QQuickStyleItemTextField::styleFont(QQuickItem *control) const
+{
+ return style()->font(QStyle::CE_ComboBoxLabel, controlSize(control));
+}
+
+void QQuickStyleItemTextField::connectToControl() const
+{
+ QQuickStyleItem::connectToControl();
+ auto textField = control<QQuickTextField>();
+ connect(textField, &QQuickTextField::readOnlyChanged, this, &QQuickStyleItem::markImageDirty);
+ connect(textField, &QQuickTextField::focusChanged, this, &QQuickStyleItem::markImageDirty);
+}
+
+StyleItemGeometry QQuickStyleItemTextField::calculateGeometry()
+{
+ QStyleOptionFrame styleOption;
+ initStyleOption(styleOption);
+ StyleItemGeometry geometry;
+
+ geometry.minimumSize = style()->sizeFromContents(QStyle::CT_LineEdit, &styleOption, QSize(0, 0));
+ geometry.implicitSize = style()->sizeFromContents(QStyle::CT_LineEdit, &styleOption, contentSize());
+ styleOption.rect = QRect(QPoint(0, 0), geometry.implicitSize);
+ geometry.layoutRect = styleOption.rect;
+ geometry.contentRect = style()->subElementRect(QStyle::SE_LineEditContents, &styleOption);
+ geometry.ninePatchMargins = style()->ninePatchMargins(QStyle::CE_ShapedFrame, &styleOption, geometry.minimumSize);
+ geometry.focusFrameRadius = style()->pixelMetric(QStyle::PM_TextFieldFocusFrameRadius, &styleOption);
+
+ return geometry;
+}
+
+void QQuickStyleItemTextField::paintEvent(QPainter *painter) const
+{
+ QStyleOptionFrame styleOption;
+ initStyleOption(styleOption);
+ style()->drawPrimitive(QStyle::PE_PanelLineEdit, &styleOption, painter);
+}
+
+void QQuickStyleItemTextField::initStyleOption(QStyleOptionFrame &styleOption) const
+{
+ initStyleOptionBase(styleOption);
+ auto textField = control<QQuickTextField>();
+
+ styleOption.lineWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, &styleOption);
+ styleOption.midLineWidth = 0;
+ styleOption.state |= QStyle::State_Sunken;
+ if (textField->isReadOnly())
+ styleOption.state |= QStyle::State_ReadOnly;
+}
diff --git a/src/quicknativestyle/items/qquickstyleitemtextfield.h b/src/quicknativestyle/items/qquickstyleitemtextfield.h
new file mode 100644
index 0000000000..35aaf753b5
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemtextfield.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKSTYLEITEMTEXTFIELD_H
+#define QQUICKSTYLEITEMTEXTFIELD_H
+
+#include "qquickstyleitem.h"
+#include <QtQuickTemplates2/private/qquicktextfield_p.h>
+
+class QQuickStyleItemTextField : public QQuickStyleItem
+{
+ Q_OBJECT
+ QML_NAMED_ELEMENT(TextField)
+
+public:
+ QFont styleFont(QQuickItem *control) const override;
+
+protected:
+ void connectToControl() const override;
+ void paintEvent(QPainter *painter) const override;
+ StyleItemGeometry calculateGeometry() override;
+
+private:
+ void initStyleOption(QStyleOptionFrame &styleOption) const;
+};
+
+#endif // QQUICKSTYLEITEMTEXTFIELD_H