aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2021-05-03 12:21:54 +0200
committerFabian Kosmale <fabian.kosmale@qt.io>2021-05-03 15:09:04 +0200
commit42687caf7bc7496b838995f3fa68194ca8323da3 (patch)
tree574ada990010e90528750e58ac9a7beae3683451 /src
parent344f3435e442827d0365f28d2e81aa5160207773 (diff)
QQuickDial: Keep value integer if everything is integer
If a user uses integer values for stepSize, from and to in a Dial, they most likely want the actual values of the Dial to be integers, too. Detect this condition, and store it in a new boolean member. If the condition is met, we round the value in QQuickDialPrivate::valueAt (which, due to floating point math might not be an exact integer). As a drive-by, reorder the boolean members to introduce no additional space overhead. Pick-to: 6.1 5.15 Fixes: QTBUG-92214 Change-Id: If4633fae1d7d425ca7fb767c7284d6f8ea7ce78c Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/quicktemplates2/qquickdial.cpp34
1 files changed, 31 insertions, 3 deletions
diff --git a/src/quicktemplates2/qquickdial.cpp b/src/quicktemplates2/qquickdial.cpp
index 76e5428d..bd9c864d 100644
--- a/src/quicktemplates2/qquickdial.cpp
+++ b/src/quicktemplates2/qquickdial.cpp
@@ -41,6 +41,8 @@
#include <QtQuick/private/qquickflickable_p.h>
#include <QtQuickTemplates2/private/qquickcontrol_p_p.h>
+#include <cmath>
+
QT_BEGIN_NAMESPACE
/*!
@@ -116,25 +118,37 @@ public:
void cancelHandle();
void executeHandle(bool complete = false);
+ void updateAllValuesAreInteger();
+
qreal from = 0;
qreal to = 1;
qreal value = 0;
qreal position = 0;
qreal angle = startAngle;
qreal stepSize = 0;
- bool pressed = false;
QPointF pressPoint;
qreal positionBeforePress = 0;
QQuickDial::SnapMode snapMode = QQuickDial::NoSnap;
QQuickDial::InputMode inputMode = QQuickDial::Circular;
+ QQuickDeferredPointer<QQuickItem> handle;
bool wrap = false;
bool live = true;
- QQuickDeferredPointer<QQuickItem> handle;
+ bool pressed = false;
+ bool allValuesAreInteger = false;
};
qreal QQuickDialPrivate::valueAt(qreal position) const
{
- return from + (to - from) * position;
+ qreal value = from + (to - from) * position;
+
+ /* play nice with users expecting that integer from, to and stepSize leads to
+ integer values - given that we are using floating point internally (and in
+ the API of value), this does not hold, but it is easy enough to handle
+ */
+ if (allValuesAreInteger)
+ value = qRound(value);
+
+ return value;
}
qreal QQuickDialPrivate::snapPosition(qreal position) const
@@ -308,6 +322,17 @@ void QQuickDialPrivate::executeHandle(bool complete)
quickCompleteDeferred(q, handleName(), handle);
}
+template<typename ...Real>
+static bool areRepresentableAsInteger(Real... numbers) {
+ auto check = [](qreal number) -> bool { return std::nearbyint(number) == number; };
+ return (... && check(numbers));
+}
+
+void QQuickDialPrivate::updateAllValuesAreInteger()
+{
+ allValuesAreInteger = areRepresentableAsInteger(to, from, stepSize) && stepSize != 0.0;
+}
+
QQuickDial::QQuickDial(QQuickItem *parent)
: QQuickControl(*(new QQuickDialPrivate), parent)
{
@@ -342,6 +367,7 @@ void QQuickDial::setFrom(qreal from)
d->from = from;
emit fromChanged();
+ d->updateAllValuesAreInteger();
if (isComponentComplete()) {
setValue(d->value);
d->updatePosition();
@@ -369,6 +395,7 @@ void QQuickDial::setTo(qreal to)
return;
d->to = to;
+ d->updateAllValuesAreInteger();
emit toChanged();
if (isComponentComplete()) {
setValue(d->value);
@@ -468,6 +495,7 @@ void QQuickDial::setStepSize(qreal step)
return;
d->stepSize = step;
+ d->updateAllValuesAreInteger();
emit stepSizeChanged();
}