diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/quicktemplates2/qquickabstractbutton.cpp | 4 | ||||
-rw-r--r-- | src/quicktemplates2/qquickcombobox.cpp | 119 | ||||
-rw-r--r-- | src/quicktemplates2/qquickcombobox_p.h | 4 | ||||
-rw-r--r-- | src/quicktemplates2/qquickpopup_p_p.h | 2 | ||||
-rw-r--r-- | src/quicktemplates2/qquicktooltip.cpp | 3 | ||||
-rw-r--r-- | src/quicktemplates2/qquicktumbler.cpp | 17 |
6 files changed, 118 insertions, 31 deletions
diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp index 983f2651..2099f2db 100644 --- a/src/quicktemplates2/qquickabstractbutton.cpp +++ b/src/quicktemplates2/qquickabstractbutton.cpp @@ -105,6 +105,7 @@ QT_BEGIN_NAMESPACE \qmlsignal QtQuick.Controls::AbstractButton::pressAndHold() This signal is emitted when the button is interactively pressed and held down by the user via touch or mouse. + It is not emitted when \l autoRepeat is enabled. */ /*! @@ -658,6 +659,9 @@ void QQuickAbstractButton::setAutoExclusive(bool exclusive) This property holds whether the button repeats \l pressed(), \l released() and \l clicked() signals while the button is pressed and held down. + If this property is set to \c true, the \l pressAndHold() signal will not + be emitted. + The default value is \c false. The initial delay and the repetition interval are defined in milliseconds diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp index 60526a0a..21eecfe1 100644 --- a/src/quicktemplates2/qquickcombobox.cpp +++ b/src/quicktemplates2/qquickcombobox.cpp @@ -43,6 +43,7 @@ #include <QtCore/qregularexpression.h> #include <QtCore/qabstractitemmodel.h> +#include <QtCore/qglobal.h> #include <QtGui/qinputmethod.h> #include <QtGui/qguiapplication.h> #include <QtGui/qpa/qplatformtheme.h> @@ -231,6 +232,13 @@ public: void updateEditText(); void updateCurrentText(); void updateCurrentValue(); + void updateCurrentText(bool hasDelegateModelObject); + void updateCurrentValue(bool hasDelegateModelObject); + void updateCurrentTextAndValue(); + + bool isValidIndex(int index) const; + QString fastTextAt(int index) const; + QVariant fastValueAt(int index) const; void acceptInput(); QString tryComplete(const QString &inputText); @@ -433,10 +441,34 @@ void QQuickComboBoxPrivate::updateEditText() q->setEditText(text); } +// We have these two rather than just using default arguments +// because QObjectPrivate::connect() doesn't accept lambdas. void QQuickComboBoxPrivate::updateCurrentText() { + updateCurrentText(false); +} + +void QQuickComboBoxPrivate::updateCurrentValue() +{ + updateCurrentValue(false); +} + +void QQuickComboBoxPrivate::updateCurrentText(bool hasDelegateModelObject) +{ Q_Q(QQuickComboBox); - QString text = q->textAt(currentIndex); + QString text; + // If a delegate model object was passed in, it means the calling code + // has decided to reuse it for several function calls to speed things up. + // So, use the faster (private) version in that case. + // For other cases, we use the version that creates the delegate model object + // itself in order to have neater, more convenient calling code. + if (isValidIndex(currentIndex)) { + if (hasDelegateModelObject) + text = fastTextAt(currentIndex); + else + text = q->textAt(currentIndex); + } + if (currentText != text) { currentText = text; if (!hasDisplayText) @@ -451,10 +483,19 @@ void QQuickComboBoxPrivate::updateCurrentText() q->setEditText(currentText); } -void QQuickComboBoxPrivate::updateCurrentValue() +void QQuickComboBoxPrivate::updateCurrentValue(bool hasDelegateModelObject) { Q_Q(QQuickComboBox); - const QVariant value = q->valueAt(currentIndex); + QVariant value; + // If a delegate model object was passed in, it means the calling code + // has decided to reuse it for several function calls to speed things up. + // So, use the faster (private) version in that case. + if (isValidIndex(currentIndex)) { + if (hasDelegateModelObject) + value = fastValueAt(currentIndex); + else + value = q->valueAt(currentIndex); + } if (currentValue == value) return; @@ -462,6 +503,38 @@ void QQuickComboBoxPrivate::updateCurrentValue() emit q->currentValueChanged(); } +void QQuickComboBoxPrivate::updateCurrentTextAndValue() +{ + QObject *object = nullptr; + // For performance reasons, we reuse the same delegate model object: QTBUG-76029. + if (isValidIndex(currentIndex)) + object = delegateModel->object(currentIndex); + const bool hasDelegateModelObject = object != nullptr; + updateCurrentText(hasDelegateModelObject); + updateCurrentValue(hasDelegateModelObject); + if (object) + delegateModel->release(object); +} + +bool QQuickComboBoxPrivate::isValidIndex(int index) const +{ + return delegateModel && index >= 0 && index < delegateModel->count(); +} + +// For performance reasons (QTBUG-76029), both this and valueAt assume that +// the index is valid and delegateModel->object(index) has been called. +QString QQuickComboBoxPrivate::fastTextAt(int index) const +{ + const QString effectiveTextRole = textRole.isEmpty() ? QStringLiteral("modelData") : textRole; + return delegateModel->stringValue(index, effectiveTextRole); +} + +QVariant QQuickComboBoxPrivate::fastValueAt(int index) const +{ + const QString effectiveValueRole = valueRole.isEmpty() ? QStringLiteral("modelData") : valueRole; + return delegateModel->variantValue(index, effectiveValueRole); +} + void QQuickComboBoxPrivate::acceptInput() { Q_Q(QQuickComboBox); @@ -508,10 +581,8 @@ void QQuickComboBoxPrivate::setCurrentIndex(int index, Activation activate) currentIndex = index; emit q->currentIndexChanged(); - if (componentComplete) { - updateCurrentText(); - updateCurrentValue(); - } + if (componentComplete) + updateCurrentTextAndValue(); if (activate) emit q->activated(index); @@ -832,10 +903,14 @@ void QQuickComboBox::setModel(const QVariant& m) if (d->model == model) return; - if (QAbstractItemModel* aim = qvariant_cast<QAbstractItemModel *>(d->model)) - QObjectPrivate::disconnect(aim, &QAbstractItemModel::dataChanged, d, &QQuickComboBoxPrivate::updateCurrentText); - if (QAbstractItemModel* aim = qvariant_cast<QAbstractItemModel *>(model)) - QObjectPrivate::connect(aim, &QAbstractItemModel::dataChanged, d, &QQuickComboBoxPrivate::updateCurrentText); + if (QAbstractItemModel* aim = qvariant_cast<QAbstractItemModel *>(d->model)) { + QObjectPrivate::disconnect(aim, &QAbstractItemModel::dataChanged, + d, QOverload<>::of(&QQuickComboBoxPrivate::updateCurrentText)); + } + if (QAbstractItemModel* aim = qvariant_cast<QAbstractItemModel *>(model)) { + QObjectPrivate::connect(aim, &QAbstractItemModel::dataChanged, + d, QOverload<>::of(&QQuickComboBoxPrivate::updateCurrentText)); + } d->model = model; d->createDelegateModel(); @@ -1505,15 +1580,13 @@ QVariant QQuickComboBox::currentValue() const QVariant QQuickComboBox::valueAt(int index) const { Q_D(const QQuickComboBox); - if (!d->delegateModel || index < 0 || index >= d->delegateModel->count()) + if (!d->isValidIndex(index)) return QVariant(); - // We use QVariant because the model API uses QVariant. - QVariant value; QObject *object = d->delegateModel->object(index); + QVariant value; if (object) { - const QString role = d->valueRole.isEmpty() ? QStringLiteral("modelData") : d->valueRole; - value = d->delegateModel->variantValue(index, role); + value = d->fastValueAt(index); d->delegateModel->release(object); } return value; @@ -1550,13 +1623,13 @@ int QQuickComboBox::indexOfValue(const QVariant &value) const QString QQuickComboBox::textAt(int index) const { Q_D(const QQuickComboBox); - if (!d->delegateModel || index < 0 || index >= d->delegateModel->count()) + if (!d->isValidIndex(index)) return QString(); - QString text; QObject *object = d->delegateModel->object(index); + QString text; if (object) { - text = d->delegateModel->stringValue(index, d->textRole.isEmpty() ? QStringLiteral("modelData") : d->textRole); + text = d->fastTextAt(index); d->delegateModel->release(object); } return text; @@ -1823,12 +1896,10 @@ void QQuickComboBox::componentComplete() static_cast<QQmlDelegateModel *>(d->delegateModel)->componentComplete(); if (count() > 0) { - if (!d->hasCurrentIndex && d->currentIndex == -1) { + if (!d->hasCurrentIndex && d->currentIndex == -1) setCurrentIndex(0); - } else { - d->updateCurrentText(); - d->updateCurrentValue(); - } + else + d->updateCurrentTextAndValue(); } } diff --git a/src/quicktemplates2/qquickcombobox_p.h b/src/quicktemplates2/qquickcombobox_p.h index a55541d4..c9063d6a 100644 --- a/src/quicktemplates2/qquickcombobox_p.h +++ b/src/quicktemplates2/qquickcombobox_p.h @@ -163,8 +163,8 @@ public: // 2.14 (Qt 5.14) QVariant currentValue() const; - Q_INVOKABLE QVariant valueAt(int index) const; - Q_INVOKABLE int indexOfValue(const QVariant &value) const; + Q_REVISION(14) Q_INVOKABLE QVariant valueAt(int index) const; + Q_REVISION(14) Q_INVOKABLE int indexOfValue(const QVariant &value) const; public Q_SLOTS: void incrementCurrentIndex(); diff --git a/src/quicktemplates2/qquickpopup_p_p.h b/src/quicktemplates2/qquickpopup_p_p.h index e32fdb28..8a85f914 100644 --- a/src/quicktemplates2/qquickpopup_p_p.h +++ b/src/quicktemplates2/qquickpopup_p_p.h @@ -187,7 +187,7 @@ public: QQuickPopup::ClosePolicy closePolicy = DefaultClosePolicy; QQuickItem *parentItem = nullptr; QQuickItem *dimmer = nullptr; - QQuickWindow *window = nullptr; + QPointer<QQuickWindow> window; QQuickTransition *enter = nullptr; QQuickTransition *exit = nullptr; QQuickPopupItem *popupItem = nullptr; diff --git a/src/quicktemplates2/qquicktooltip.cpp b/src/quicktemplates2/qquicktooltip.cpp index c1271dab..0a36e0c7 100644 --- a/src/quicktemplates2/qquicktooltip.cpp +++ b/src/quicktemplates2/qquicktooltip.cpp @@ -238,12 +238,13 @@ void QQuickToolTip::setTimeout(int timeout) if (d->timeout == timeout) return; + d->timeout = timeout; + if (timeout <= 0) d->stopTimeout(); else if (isVisible()) d->startTimeout(); - d->timeout = timeout; emit timeoutChanged(); } diff --git a/src/quicktemplates2/qquicktumbler.cpp b/src/quicktemplates2/qquicktumbler.cpp index 8b702c60..85c70b1b 100644 --- a/src/quicktemplates2/qquicktumbler.cpp +++ b/src/quicktemplates2/qquicktumbler.cpp @@ -949,9 +949,20 @@ void QQuickTumblerAttachedPrivate::calculateDisplacement() const qreal contentY = tumblerPrivate->viewContentY; const qreal delegateH = delegateHeight(tumbler); const qreal preferredHighlightBegin = tumblerPrivate->view->property("preferredHighlightBegin").toReal(); - // Tumbler's displacement goes from negative at the top to positive towards the bottom, so we must switch this around. - const qreal reverseDisplacement = (contentY + preferredHighlightBegin) / delegateH; - displacement = reverseDisplacement - index; + const qreal itemY = qobject_cast<QQuickItem*>(parent)->y(); + qreal currentItemY = 0; + auto currentItem = tumblerPrivate->view->property("currentItem").value<QQuickItem*>(); + if (currentItem) + currentItemY = currentItem->y(); + // Start from the y position of the current item. + const qreal topOfCurrentItemInViewport = currentItemY - contentY; + // Then, calculate the distance between it and the preferredHighlightBegin. + const qreal relativePositionToPreferredHighlightBegin = topOfCurrentItemInViewport - preferredHighlightBegin; + // Next, calculate the distance between us and the current item. + const qreal distanceFromCurrentItem = currentItemY - itemY; + const qreal displacementInPixels = distanceFromCurrentItem - relativePositionToPreferredHighlightBegin; + // Convert it from pixels to a floating point index. + displacement = displacementInPixels / delegateH; } emitIfDisplacementChanged(previousDisplacement, displacement); |