diff options
author | Jan Arve Sæther <jan-arve.saether@qt.io> | 2020-10-29 17:01:27 +0100 |
---|---|---|
committer | Jan Arve Sæther <jan-arve.saether@qt.io> | 2020-12-10 16:21:21 +0100 |
commit | 64fd0b53b378ef91725d4950720c3bdfaee11498 (patch) | |
tree | 4860bf008c3437a41575e9a05dda8eba96f05848 /src/imports/nativestyle | |
parent | 8d061f542181cfe0ac9052948c869d87ce80589b (diff) |
Add support for ScrollBar arrow buttons
In order to achieve this, it separates out QQuickSpinButton into a
separate file (and renames it since it's not only purposed for SpinBox
anymore). This allows it to be also used by QQuickScrollBar.
Fixes: QTBUG-88115
Pick-to: 6.0
Change-Id: I2dea42b29750b7bc619031f40a43717fc10c177b
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Diffstat (limited to 'src/imports/nativestyle')
5 files changed, 73 insertions, 19 deletions
diff --git a/src/imports/nativestyle/items/qquickstyleitem.h b/src/imports/nativestyle/items/qquickstyleitem.h index fdfd7012..0a89454b 100644 --- a/src/imports/nativestyle/items/qquickstyleitem.h +++ b/src/imports/nativestyle/items/qquickstyleitem.h @@ -186,6 +186,7 @@ public: None = 0, AlwaysHovered, NeverHovered, + AlwaysSunken }; Q_ENUM(OverrideState) diff --git a/src/imports/nativestyle/items/qquickstyleitemscrollbar.cpp b/src/imports/nativestyle/items/qquickstyleitemscrollbar.cpp index 1b94b22d..d6d41d96 100644 --- a/src/imports/nativestyle/items/qquickstyleitemscrollbar.cpp +++ b/src/imports/nativestyle/items/qquickstyleitemscrollbar.cpp @@ -56,6 +56,14 @@ StyleItemGeometry QQuickStyleItemScrollBar::calculateGeometry() 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); @@ -68,7 +76,27 @@ void QQuickStyleItemScrollBar::paintEvent(QPainter *painter) const { QStyleOptionSlider styleOption; initStyleOption(styleOption); - style()->drawComplexControl(QStyle::CC_ScrollBar, &styleOption, painter); + 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 @@ -76,9 +104,21 @@ void QQuickStyleItemScrollBar::initStyleOption(QStyleOptionSlider &styleOption) initStyleOptionBase(styleOption); auto scrollBar = control<QQuickScrollBar>(); - styleOption.subControls = m_subControl == Groove - ? QStyle::SC_ScrollBarGroove | QStyle::SC_ScrollBarAddLine | QStyle::SC_ScrollBarSubLine - : QStyle::SC_ScrollBarSlider; + 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) @@ -90,12 +130,14 @@ void QQuickStyleItemScrollBar::initStyleOption(QStyleOptionSlider &styleOption) 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) { + + 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)); - } else if (m_overrideState & NeverHovered) { - styleOption.state &= ~QStyle::State_Sunken; - styleOption.activeSubControls &= ~(styleOption.subControls & (QStyle::SC_ScrollBarSlider | QStyle::SC_ScrollBarGroove)); + styleOption.activeSubControls = (styleOption.subControls & (QStyle::SC_ScrollBarSlider | QStyle::SC_ScrollBarGroove | QStyle::SC_ScrollBarAddLine | QStyle::SC_ScrollBarSubLine)); } } diff --git a/src/imports/nativestyle/items/qquickstyleitemscrollbar.h b/src/imports/nativestyle/items/qquickstyleitemscrollbar.h index 9d86cb09..f89d8d3e 100644 --- a/src/imports/nativestyle/items/qquickstyleitemscrollbar.h +++ b/src/imports/nativestyle/items/qquickstyleitemscrollbar.h @@ -52,6 +52,8 @@ public: enum SubControl { Groove = 1, Handle, + AddLine, + SubLine }; Q_ENUM(SubControl) diff --git a/src/imports/nativestyle/items/qquickstyleitemspinbox.cpp b/src/imports/nativestyle/items/qquickstyleitemspinbox.cpp index 46097567..2a232b8a 100644 --- a/src/imports/nativestyle/items/qquickstyleitemspinbox.cpp +++ b/src/imports/nativestyle/items/qquickstyleitemspinbox.cpp @@ -35,6 +35,7 @@ ****************************************************************************/ #include "qquickstyleitemspinbox.h" +#include <QtQuickTemplates2/private/qquickindicatorbutton_p.h> QFont QQuickStyleItemSpinBox::styleFont(QQuickItem *control) const { @@ -45,8 +46,8 @@ void QQuickStyleItemSpinBox::connectToControl() const { QQuickStyleItem::connectToControl(); auto spinbox = control<QQuickSpinBox>(); - connect(spinbox->up(), &QQuickSpinButton::pressedChanged, this, &QQuickStyleItem::markImageDirty); - connect(spinbox->down(), &QQuickSpinButton::pressedChanged, this, &QQuickStyleItem::markImageDirty); + connect(spinbox->up(), &QQuickIndicatorButton::pressedChanged, this, &QQuickStyleItem::markImageDirty); + connect(spinbox->down(), &QQuickIndicatorButton::pressedChanged, this, &QQuickStyleItem::markImageDirty); } StyleItemGeometry QQuickStyleItemSpinBox::calculateGeometry() diff --git a/src/imports/nativestyle/qstyle/windows/qquickwindowsxpstyle.cpp b/src/imports/nativestyle/qstyle/windows/qquickwindowsxpstyle.cpp index 0f07aef0..fd363d62 100644 --- a/src/imports/nativestyle/qstyle/windows/qquickwindowsxpstyle.cpp +++ b/src/imports/nativestyle/qstyle/windows/qquickwindowsxpstyle.cpp @@ -2552,14 +2552,16 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo d->drawBackground(theme); } if (maxedOut) { - theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider); - theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage)); - theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage)); - partId = scrollbar->orientation == Qt::Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT; - stateId = SCRBS_DISABLED; - theme.partId = partId; - theme.stateId = stateId; - d->drawBackground(theme); + if (sub & SC_ScrollBarSlider) { + theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider); + theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage)); + theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage)); + partId = scrollbar->orientation == Qt::Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT; + stateId = SCRBS_DISABLED; + theme.partId = partId; + theme.stateId = stateId; + d->drawBackground(theme); + } } else { if (sub & SC_ScrollBarSubPage) { theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage); @@ -3536,6 +3538,12 @@ QSize QWindowsXPStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt if (slider->subControls & (SC_ScrollBarSlider | SC_ScrollBarGroove)) { szw = qMax(szw, scrollBarSliderMin + 2 * scrollBarHeight); szh = scrollBarHeight; + } else if (slider->subControls & (SC_ScrollBarAddLine| SC_ScrollBarSubLine)) { + // Assume that the AddLine and SubLine buttons have the same size, and just query + // for the size of AddLine + const QSize s = proxy()->subControlRect(CC_ScrollBar, slider, SC_ScrollBarAddLine).size(); + szw = qMax(szw, s.width()); + szh = scrollBarHeight; } } break; |