fix property changed signals firing multiple times
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
#include "carouselview.hpp"
|
||||
|
||||
#include <QSignalBlocker>
|
||||
#include <QQmlContext>
|
||||
#include <QQmlProperty>
|
||||
#include <QMouseEvent>
|
||||
#include <QWheelEvent>
|
||||
|
||||
#include <cmath>
|
||||
#include <qobject.h>
|
||||
|
||||
namespace ZShell::components {
|
||||
|
||||
@@ -81,6 +83,33 @@ void CarouselView::setDelegate(QQmlComponent* c) {
|
||||
relayout();
|
||||
}
|
||||
|
||||
void CarouselView::notifyCurrentIndexChanged() {
|
||||
if (!m_completed) return;
|
||||
emit currentIndexChanged();
|
||||
}
|
||||
|
||||
void CarouselView::notifyCurrentItemChanged() {
|
||||
if (!m_completed) return;
|
||||
emit currentItemChanged();
|
||||
}
|
||||
|
||||
void CarouselView::notifyPreviewIndexChanged(int realIndex) {
|
||||
if (!m_completed || realIndex < 0) return;
|
||||
emit previewIndexChanged(realIndex, m_model.at(realIndex));
|
||||
}
|
||||
|
||||
void CarouselView::classBegin() {}
|
||||
|
||||
void CarouselView::componentComplete() {
|
||||
m_completed = true;
|
||||
emit currentIndexChanged();
|
||||
if (m_currentRealIndex >= 0 && m_currentRealIndex < m_model.size())
|
||||
emit previewIndexChanged(
|
||||
m_currentRealIndex, m_model.at(m_currentRealIndex));
|
||||
|
||||
emit currentItemChanged();
|
||||
}
|
||||
|
||||
bool CarouselView::childMouseEventFilter(QQuickItem* item, QEvent* event) {
|
||||
Q_UNUSED(item);
|
||||
|
||||
@@ -163,7 +192,7 @@ void CarouselView::setModel(const QVariantList& m) {
|
||||
if (newCount == 0) {
|
||||
m_currentRealIndex = -1;
|
||||
m_currentItem = nullptr;
|
||||
emit currentItemChanged();
|
||||
notifyCurrentItemChanged();
|
||||
|
||||
releaseAllItems();
|
||||
rebuildArrangement();
|
||||
@@ -173,19 +202,23 @@ void CarouselView::setModel(const QVariantList& m) {
|
||||
|
||||
if (!m_initializedLayout) {
|
||||
m_centerBlockStart = 0;
|
||||
m_currentVirtualIndex = 0;
|
||||
|
||||
m_contentX = contentXForIndex(0);
|
||||
const int startVirtual =
|
||||
m_pendingCurrentIndex >= 0
|
||||
? qBound(0, m_pendingCurrentIndex, newCount - 1)
|
||||
: 0;
|
||||
|
||||
m_pendingCurrentIndex = -1;
|
||||
|
||||
m_currentVirtualIndex = startVirtual;
|
||||
m_contentX = contentXForIndex(startVirtual);
|
||||
m_currentRealIndex = realIndexOf(m_currentVirtualIndex);
|
||||
|
||||
m_previewRealIndex = m_currentRealIndex;
|
||||
|
||||
m_initializedLayout = true;
|
||||
|
||||
m_layoutCapacity =
|
||||
qMax(m_layoutCapacity, layoutCapacityForWidth(m_maxWidth));
|
||||
|
||||
setImplicitWidth(targetWidthForMaxWidth(m_maxWidth));
|
||||
|
||||
rebuildArrangement();
|
||||
@@ -320,6 +353,22 @@ void CarouselView::setDelegateProperties(const QVariantMap& v) {
|
||||
}
|
||||
|
||||
void CarouselView::setCurrentIndex(int idx) {
|
||||
if (m_model.isEmpty()) {
|
||||
m_pendingCurrentIndex = idx;
|
||||
|
||||
if (m_currentRealIndex != idx) {
|
||||
m_currentRealIndex = idx;
|
||||
notifyCurrentIndexChanged();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_completed) {
|
||||
centerInstantlyOnReal(idx);
|
||||
return;
|
||||
}
|
||||
|
||||
goToIndex(idx);
|
||||
}
|
||||
|
||||
@@ -336,7 +385,7 @@ void CarouselView::updateCurrentItem() {
|
||||
if (item == m_currentItem) return;
|
||||
|
||||
m_currentItem = item;
|
||||
emit currentItemChanged();
|
||||
notifyCurrentItemChanged();
|
||||
}
|
||||
|
||||
void CarouselView::geometryChange(const QRectF& newGeo, const QRectF& oldGeo) {
|
||||
@@ -676,15 +725,12 @@ void CarouselView::updateCurrentIndexFromContentX(bool emitPreview) {
|
||||
if (newReal != m_currentRealIndex) {
|
||||
m_currentRealIndex = newReal;
|
||||
|
||||
emit currentIndexChanged();
|
||||
notifyCurrentIndexChanged();
|
||||
}
|
||||
|
||||
if (emitPreview && newReal != m_previewRealIndex) {
|
||||
m_previewRealIndex = newReal;
|
||||
|
||||
if (newReal >= 0) {
|
||||
emit previewIndexChanged(newReal, m_model.at(newReal));
|
||||
}
|
||||
notifyPreviewIndexChanged(newReal);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1029,13 +1075,14 @@ void CarouselView::glideTo(qreal dest) {
|
||||
|
||||
cancelAnimations();
|
||||
|
||||
m_glideAnim->setDuration(m_glideDuration);
|
||||
{
|
||||
QSignalBlocker blocker(m_glideAnim);
|
||||
|
||||
m_glideAnim->setStartValue(m_contentX);
|
||||
|
||||
m_glideAnim->setEndValue(dest);
|
||||
|
||||
m_glideAnim->start();
|
||||
m_glideAnim->setDuration(m_glideDuration);
|
||||
m_glideAnim->setStartValue(m_contentX);
|
||||
m_glideAnim->setEndValue(dest);
|
||||
m_glideAnim->start();
|
||||
}
|
||||
}
|
||||
|
||||
void CarouselView::snapToNearest() {
|
||||
@@ -1078,10 +1125,6 @@ void CarouselView::decrementCurrentIndex() {
|
||||
glideTo(contentXForIndex(m_currentVirtualIndex - 1));
|
||||
}
|
||||
|
||||
void CarouselView::jumpToIndex(int realIndex) {
|
||||
centerInstantlyOnReal(realIndex);
|
||||
}
|
||||
|
||||
void CarouselView::centerInstantlyOnReal(int realIndex) {
|
||||
const int count = m_model.size();
|
||||
|
||||
@@ -1115,7 +1158,7 @@ void CarouselView::centerInstantlyOnReal(int realIndex) {
|
||||
|
||||
if (changed) emit currentIndexChanged();
|
||||
|
||||
emit previewIndexChanged(realIndex, m_model.at(realIndex));
|
||||
notifyPreviewIndexChanged(realIndex);
|
||||
|
||||
relayout();
|
||||
}
|
||||
@@ -1219,12 +1262,16 @@ void CarouselView::mouseReleaseEvent(QMouseEvent* event) {
|
||||
|
||||
cancelAnimations();
|
||||
|
||||
m_flickAnim->setDuration(
|
||||
static_cast<int>(qBound<qreal>(120, duration, 900)));
|
||||
m_flickAnim->setEasingCurve(QEasingCurve::OutQuad);
|
||||
m_flickAnim->setStartValue(m_contentX);
|
||||
m_flickAnim->setEndValue(dest);
|
||||
m_flickAnim->start();
|
||||
{
|
||||
QSignalBlocker blocker(m_flickAnim);
|
||||
|
||||
m_flickAnim->setDuration(
|
||||
static_cast<int>(qBound<qreal>(120, duration, 900)));
|
||||
m_flickAnim->setEasingCurve(QEasingCurve::OutQuad);
|
||||
m_flickAnim->setStartValue(m_contentX);
|
||||
m_flickAnim->setEndValue(dest);
|
||||
m_flickAnim->start();
|
||||
}
|
||||
|
||||
event->accept();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user