From 846d04cec8d946c28ddbeecc79c63553e0891736 Mon Sep 17 00:00:00 2001 From: Joni Poikelin Date: Thu, 10 Mar 2016 08:28:35 +0200 Subject: RangeModel: Emit min/max and value changes after component is complete Prevent extra value changed signal to be fired in case when Slider with minimum > 0 and value > minimum are set. Change-Id: I86824c403a7c0296f782d2eec7ed30acfc13b304 Reviewed-by: Mitch Curtis --- src/controls/Private/qquickrangemodel.cpp | 33 ++++++++++++++-- src/controls/Private/qquickrangemodel_p.h | 7 +++- src/controls/Private/qquickrangemodel_p_p.h | 3 ++ tests/auto/controls/data/rangemodel/init.qml | 56 ++++++++++++++++++++++++++++ tests/auto/controls/data/tst_rangemodel.qml | 10 ++++- 5 files changed, 103 insertions(+), 6 deletions(-) create mode 100644 tests/auto/controls/data/rangemodel/init.qml diff --git a/src/controls/Private/qquickrangemodel.cpp b/src/controls/Private/qquickrangemodel.cpp index 02ce0e57..36d7dd34 100644 --- a/src/controls/Private/qquickrangemodel.cpp +++ b/src/controls/Private/qquickrangemodel.cpp @@ -69,6 +69,9 @@ void QQuickRangeModelPrivate::init() posatmin = 0; posatmax = 0; inverted = false; + isComplete = false; + positionChanged = false; + valueChanged = false; } /*! @@ -155,10 +158,16 @@ void QQuickRangeModelPrivate::emitValueAndPositionIfChanged(const qreal oldValue // unchanged. This will be the case when operating with values outside range: const qreal newValue = q->value(); const qreal newPosition = q->position(); - if (!qFuzzyCompare(newValue, oldValue)) - emit q->valueChanged(newValue); - if (!qFuzzyCompare(newPosition, oldPosition)) - emit q->positionChanged(newPosition); + + if (isComplete) { + if (!qFuzzyCompare(newValue, oldValue)) + emit q->valueChanged(newValue); + if (!qFuzzyCompare(newPosition, oldPosition)) + emit q->positionChanged(newPosition); + } else { + positionChanged |= qFuzzyCompare(oldPosition, newPosition); + valueChanged |= !qFuzzyCompare(oldValue, newValue); + } } /*! @@ -346,6 +355,22 @@ qreal QQuickRangeModel::positionForValue(qreal value) const return d->publicPosition(unconstrainedPosition); } +void QQuickRangeModel::classBegin() +{ +} + +void QQuickRangeModel::componentComplete() +{ + Q_D(QQuickRangeModel); + d->isComplete = true; + emit minimumChanged(minimum()); + emit maximumChanged(maximum()); + if (d->valueChanged) + emit valueChanged(value()); + if (d->positionChanged) + emit positionChanged(position()); +} + /*! \property QQuickRangeModel::position \brief the current position of the model diff --git a/src/controls/Private/qquickrangemodel_p.h b/src/controls/Private/qquickrangemodel_p.h index 06d00202..47376ded 100644 --- a/src/controls/Private/qquickrangemodel_p.h +++ b/src/controls/Private/qquickrangemodel_p.h @@ -44,7 +44,7 @@ QT_BEGIN_NAMESPACE class QQuickRangeModelPrivate; -class QQuickRangeModel : public QObject +class QQuickRangeModel : public QObject, public QQmlParserStatus { Q_OBJECT Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged USER true) @@ -56,6 +56,8 @@ class QQuickRangeModel : public QObject Q_PROPERTY(qreal positionAtMaximum READ positionAtMaximum WRITE setPositionAtMaximum NOTIFY positionAtMaximumChanged) Q_PROPERTY(bool inverted READ inverted WRITE setInverted NOTIFY invertedChanged) + Q_INTERFACES(QQmlParserStatus) + public: QQuickRangeModel(QObject *parent = 0); virtual ~QQuickRangeModel(); @@ -87,6 +89,9 @@ public: Q_INVOKABLE qreal valueForPosition(qreal position) const; Q_INVOKABLE qreal positionForValue(qreal value) const; + void classBegin(); + void componentComplete(); + public Q_SLOTS: void toMinimum(); void toMaximum(); diff --git a/src/controls/Private/qquickrangemodel_p_p.h b/src/controls/Private/qquickrangemodel_p_p.h index 235ba069..6097ff3d 100644 --- a/src/controls/Private/qquickrangemodel_p_p.h +++ b/src/controls/Private/qquickrangemodel_p_p.h @@ -67,6 +67,9 @@ public: uint inverted : 1; QQuickRangeModel *q_ptr; + bool isComplete; + bool positionChanged; + bool valueChanged; inline qreal effectivePosAtMin() const { return inverted ? posatmax : posatmin; diff --git a/tests/auto/controls/data/rangemodel/init.qml b/tests/auto/controls/data/rangemodel/init.qml new file mode 100644 index 00000000..9d050143 --- /dev/null +++ b/tests/auto/controls/data/rangemodel/init.qml @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Private 1.0 +import QtTest 1.0 + +RangeModel { + id: rangemodel + positionAtMinimum: 0 + positionAtMaximum: 100 + stepSize: 1 + + property QtObject spy: SignalSpy { + target: rangemodel + signalName: "valueChanged" + } +} diff --git a/tests/auto/controls/data/tst_rangemodel.qml b/tests/auto/controls/data/tst_rangemodel.qml index db3aceb7..6d95f279 100644 --- a/tests/auto/controls/data/tst_rangemodel.qml +++ b/tests/auto/controls/data/tst_rangemodel.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2016 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -68,6 +68,14 @@ TestCase { spy.clear() } + function test_delayedinit() { + var component = Qt.createComponent("rangemodel/init.qml"); + compare(component.status, Component.Ready) + var r = component.createObject(testCase, {minimumValue: 40, maximumValue: 90, value: 80}); + compare(r.value, 80) + compare(r.spy.count, 1) + } + function test_setminimumvalue() { spy.signalName = "minimumChanged" compare(spy.count, 0) -- cgit v1.2.1