From bfa0560938eab328a12fabc57316304580cccf67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Arve=20S=C3=A6ther?= Date: Mon, 19 Oct 2020 13:57:11 +0200 Subject: Native style/Slider: Fix tickmarks and groove for fractional numbers In QQuickSlider, this was very noticeable for very short ranges (e.g. a range less than 1). It also caused wrong rendering of the groove on macOS style. Change-Id: I8a88b2e107e543f5b0cef5a7093b94b08ebeb398 Reviewed-by: Richard Moe Gustavsen --- .../nativestyle/items/qquickstyleitemslider.cpp | 19 +++++++++++++------ tests/manual/nativestyle/Sliders.qml | 11 +++++++++++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/imports/nativestyle/items/qquickstyleitemslider.cpp b/src/imports/nativestyle/items/qquickstyleitemslider.cpp index 4f64b3ba..bc986522 100644 --- a/src/imports/nativestyle/items/qquickstyleitemslider.cpp +++ b/src/imports/nativestyle/items/qquickstyleitemslider.cpp @@ -85,14 +85,13 @@ void QQuickStyleItemSlider::initStyleOption(QStyleOptionSlider &styleOption) styleOption.subControls = m_subControl == Groove ? QStyle::SC_SliderGroove : QStyle::SC_SliderHandle; styleOption.activeSubControls = QStyle::SC_None; styleOption.orientation = slider->orientation(); - styleOption.tickInterval = int(slider->stepSize()); if (slider->isPressed()) styleOption.state |= QStyle::State_Sunken; qreal min = 0; - qreal max = 10000; + qreal max = 1; if (!qFuzzyIsNull(slider->stepSize())) { min = slider->from(); max = slider->to(); @@ -106,8 +105,16 @@ void QQuickStyleItemSlider::initStyleOption(QStyleOptionSlider &styleOption) styleOption.subControls |= QStyle::SC_SliderTickmarks; } } - styleOption.minimum = int(min); - styleOption.maximum = int(max); - styleOption.sliderValue = int(slider->value()); - styleOption.sliderPosition = int(slider->position() * (max - min)); + + // 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() - min) * normalizeMultiplier); } diff --git a/tests/manual/nativestyle/Sliders.qml b/tests/manual/nativestyle/Sliders.qml index dcc6c79c..84822549 100644 --- a/tests/manual/nativestyle/Sliders.qml +++ b/tests/manual/nativestyle/Sliders.qml @@ -84,6 +84,17 @@ ControlContainer { property int qqc2_style_tickPosition: 2 } + + Slider { + // Should show 9 tickmarks + width: sliderWidth + from: 3.3 + to: 3.7 + stepSize: 0.05 + value: 3.5 + property int qqc2_style_tickPosition: 2 + } + } Row { -- cgit v1.2.3