fix: remove dead list view anim code

This commit is contained in:
2 * r + 2 * t 2026-04-09 22:06:46 +10:00
parent e3b3a66877
commit 9145f83639
3 changed files with 1 additions and 344 deletions

View file

@ -26,21 +26,7 @@ LazyListView {
useCustomViewport: true
viewport: Qt.rect(0, container.contentY, width, container.height)
addDuration: Appearance.anim.durations.expressiveDefaultSpatial
addCurve.type: Easing.BezierSpline
addCurve.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial
addFromOpacity: 0
addFromScale: 0
removeDuration: Appearance.anim.durations.normal
removeCurve.type: Easing.BezierSpline
removeCurve.bezierCurve: Appearance.anim.curves.standard
removeToOpacity: 0
removeToScale: 0.6
moveDuration: Appearance.anim.durations.expressiveDefaultSpatial
moveCurve.type: Easing.BezierSpline
moveCurve.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial
model: ScriptModel {
values: {

View file

@ -1,7 +1,6 @@
#include "lazylistview.hpp"
#include <algorithm>
#include <qpropertyanimation.h>
#include <qtimer.h>
namespace {
@ -268,52 +267,6 @@ qreal LazyListView::delegateVisibleHeight(QQuickItem* item) {
return item->implicitHeight();
}
// --- Add Animation ---
int LazyListView::addDuration() const {
return m_addDuration;
}
void LazyListView::setAddDuration(int duration) {
if (m_addDuration == duration)
return;
m_addDuration = duration;
emit addDurationChanged();
}
QEasingCurve LazyListView::addCurve() const {
return m_addCurve;
}
void LazyListView::setAddCurve(const QEasingCurve& curve) {
if (m_addCurve == curve)
return;
m_addCurve = curve;
emit addCurveChanged();
}
qreal LazyListView::addFromOpacity() const {
return m_addFromOpacity;
}
void LazyListView::setAddFromOpacity(qreal opacity) {
if (qFuzzyCompare(m_addFromOpacity, opacity))
return;
m_addFromOpacity = opacity;
emit addFromOpacityChanged();
}
qreal LazyListView::addFromScale() const {
return m_addFromScale;
}
void LazyListView::setAddFromScale(qreal scale) {
if (qFuzzyCompare(m_addFromScale, scale))
return;
m_addFromScale = scale;
emit addFromScaleChanged();
}
// --- Remove Animation ---
int LazyListView::removeDuration() const {
@ -327,73 +280,12 @@ void LazyListView::setRemoveDuration(int duration) {
emit removeDurationChanged();
}
QEasingCurve LazyListView::removeCurve() const {
return m_removeCurve;
}
void LazyListView::setRemoveCurve(const QEasingCurve& curve) {
if (m_removeCurve == curve)
return;
m_removeCurve = curve;
emit removeCurveChanged();
}
qreal LazyListView::removeToOpacity() const {
return m_removeToOpacity;
}
void LazyListView::setRemoveToOpacity(qreal opacity) {
if (qFuzzyCompare(m_removeToOpacity, opacity))
return;
m_removeToOpacity = opacity;
emit removeToOpacityChanged();
}
qreal LazyListView::removeToScale() const {
return m_removeToScale;
}
void LazyListView::setRemoveToScale(qreal scale) {
if (qFuzzyCompare(m_removeToScale, scale))
return;
m_removeToScale = scale;
emit removeToScaleChanged();
}
// --- Move Animation ---
int LazyListView::moveDuration() const {
return m_moveDuration;
}
void LazyListView::setMoveDuration(int duration) {
if (m_moveDuration == duration)
return;
m_moveDuration = duration;
emit moveDurationChanged();
}
QEasingCurve LazyListView::moveCurve() const {
return m_moveCurve;
}
void LazyListView::setMoveCurve(const QEasingCurve& curve) {
if (m_moveCurve == curve)
return;
m_moveCurve = curve;
emit moveCurveChanged();
}
// --- State ---
int LazyListView::count() const {
return m_model ? m_model->rowCount() : 0;
}
bool LazyListView::settled() const {
return m_activeAnimations == 0;
}
// --- QQuickItem Overrides ---
void LazyListView::componentComplete() {
@ -589,7 +481,7 @@ void LazyListView::syncDelegates() {
const auto vp = effectiveViewport();
QList<int> toRemove;
for (auto it = m_delegates.begin(); it != m_delegates.end(); ++it) {
if (visibleIndices.contains(it.key()) || it->animation)
if (visibleIndices.contains(it.key()))
continue;
if (!it->item) {
toRemove.append(it.key());
@ -806,15 +698,6 @@ LazyListView::DelegateEntry LazyListView::createDelegate(int modelIndex) {
}
void LazyListView::destroyDelegate(DelegateEntry& entry) {
if (entry.animation) {
// Disconnect before stopping to prevent re-entrant onAnimationFinished
disconnect(entry.animation, &QAbstractAnimation::finished, this, &LazyListView::onAnimationFinished);
entry.animation->stop();
entry.animation = nullptr;
--m_activeAnimations;
if (m_activeAnimations == 0)
emit settledChanged();
}
if (entry.attachedConnection)
disconnect(entry.attachedConnection);
if (entry.item) {
@ -908,15 +791,9 @@ void LazyListView::resetContent() {
destroyDelegate(entry);
m_dyingDelegates.clear();
if (m_activeAnimations != 0) {
m_activeAnimations = 0;
emit settledChanged();
}
// Reset pending state
m_knownHeightSum = 0;
m_knownHeightCount = 0;
m_pendingAddAnimations.clear();
// Rebuild layout from model
m_layout.clear();
@ -955,10 +832,6 @@ void LazyListView::onRowsInserted(const QModelIndex& parent, int first, int last
}
m_delegates = std::move(shifted);
// Queue add animations and mark displacement
for (int i = first; i <= last; ++i)
m_pendingAddAnimations.insert(i);
emit countChanged();
polish();
}
@ -975,7 +848,6 @@ void LazyListView::onRowsAboutToBeRemoved(const QModelIndex& parent, int first,
if (entry.item)
m_itemToIndex.remove(entry.item);
entry.pendingRemoval = true;
stopAnimation(entry);
if (m_removeDuration > 0 && entry.item) {
auto* attached =
@ -1129,129 +1001,4 @@ void LazyListView::onModelReset() {
resetContent();
}
// --- Animation ---
void LazyListView::startAddAnimation(DelegateEntry& entry) {
if (!entry.item || m_addDuration <= 0)
return;
stopAnimation(entry);
auto* group = new QParallelAnimationGroup(this);
if (!qFuzzyCompare(m_addFromOpacity, 1.0)) {
auto* opacityAnim = new QPropertyAnimation(entry.item, "opacity");
opacityAnim->setDuration(m_addDuration);
opacityAnim->setEasingCurve(m_addCurve);
opacityAnim->setStartValue(m_addFromOpacity);
opacityAnim->setEndValue(1.0);
group->addAnimation(opacityAnim);
entry.item->setOpacity(m_addFromOpacity);
}
if (!qFuzzyCompare(m_addFromScale, 1.0)) {
auto* scaleAnim = new QPropertyAnimation(entry.item, "scale");
scaleAnim->setDuration(m_addDuration);
scaleAnim->setEasingCurve(m_addCurve);
scaleAnim->setStartValue(m_addFromScale);
scaleAnim->setEndValue(1.0);
group->addAnimation(scaleAnim);
entry.item->setScale(m_addFromScale);
}
if (group->animationCount() == 0) {
delete group;
return;
}
entry.animation = group;
++m_activeAnimations;
if (m_activeAnimations == 1)
emit settledChanged();
connect(group, &QAbstractAnimation::finished, this, &LazyListView::onAnimationFinished);
group->start(QAbstractAnimation::DeleteWhenStopped);
}
void LazyListView::startRemoveAnimation(DelegateEntry& entry) {
if (!entry.item || m_removeDuration <= 0)
return;
stopAnimation(entry);
auto* group = new QParallelAnimationGroup(this);
if (!qFuzzyCompare(m_removeToOpacity, 1.0)) {
auto* opacityAnim = new QPropertyAnimation(entry.item, "opacity");
opacityAnim->setDuration(m_removeDuration);
opacityAnim->setEasingCurve(m_removeCurve);
opacityAnim->setStartValue(entry.item->opacity());
opacityAnim->setEndValue(m_removeToOpacity);
group->addAnimation(opacityAnim);
}
if (!qFuzzyCompare(m_removeToScale, 1.0)) {
auto* scaleAnim = new QPropertyAnimation(entry.item, "scale");
scaleAnim->setDuration(m_removeDuration);
scaleAnim->setEasingCurve(m_removeCurve);
scaleAnim->setStartValue(entry.item->scale());
scaleAnim->setEndValue(m_removeToScale);
group->addAnimation(scaleAnim);
}
if (group->animationCount() == 0) {
delete group;
return;
}
entry.animation = group;
++m_activeAnimations;
if (m_activeAnimations == 1)
emit settledChanged();
connect(group, &QAbstractAnimation::finished, this, &LazyListView::onAnimationFinished);
group->start(QAbstractAnimation::DeleteWhenStopped);
}
void LazyListView::stopAnimation(DelegateEntry& entry) {
if (!entry.animation)
return;
entry.animation->stop();
entry.animation = nullptr;
--m_activeAnimations;
if (m_activeAnimations == 0)
emit settledChanged();
}
void LazyListView::onAnimationFinished() {
auto* group = qobject_cast<QParallelAnimationGroup*>(sender());
// Clear animation pointer from live delegates
for (auto& entry : m_delegates) {
if (entry.animation == group)
entry.animation = nullptr;
}
// Clean up dying delegates whose animation finished
m_dyingDelegates.erase(std::remove_if(m_dyingDelegates.begin(), m_dyingDelegates.end(),
[this, group](DelegateEntry& entry) {
if (entry.animation == group) {
entry.animation = nullptr;
destroyDelegate(entry);
return true;
}
return false;
}),
m_dyingDelegates.end());
--m_activeAnimations;
if (m_activeAnimations == 0)
emit settledChanged();
// Re-sync in case viewport changed during animation
polish();
}
} // namespace caelestia::components

View file

@ -1,10 +1,8 @@
#pragma once
#include <qabstractitemmodel.h>
#include <qeasingcurve.h>
#include <qhash.h>
#include <qobject.h>
#include <qparallelanimationgroup.h>
#include <qqmlcomponent.h>
#include <qqmlcontext.h>
#include <qqmlintegration.h>
@ -82,25 +80,11 @@ class LazyListView : public QQuickItem {
// Async
Q_PROPERTY(bool asynchronous READ asynchronous WRITE setAsynchronous NOTIFY asynchronousChanged)
// Add Animation
Q_PROPERTY(int addDuration READ addDuration WRITE setAddDuration NOTIFY addDurationChanged)
Q_PROPERTY(QEasingCurve addCurve READ addCurve WRITE setAddCurve NOTIFY addCurveChanged)
Q_PROPERTY(qreal addFromOpacity READ addFromOpacity WRITE setAddFromOpacity NOTIFY addFromOpacityChanged)
Q_PROPERTY(qreal addFromScale READ addFromScale WRITE setAddFromScale NOTIFY addFromScaleChanged)
// Remove Animation
Q_PROPERTY(int removeDuration READ removeDuration WRITE setRemoveDuration NOTIFY removeDurationChanged)
Q_PROPERTY(QEasingCurve removeCurve READ removeCurve WRITE setRemoveCurve NOTIFY removeCurveChanged)
Q_PROPERTY(qreal removeToOpacity READ removeToOpacity WRITE setRemoveToOpacity NOTIFY removeToOpacityChanged)
Q_PROPERTY(qreal removeToScale READ removeToScale WRITE setRemoveToScale NOTIFY removeToScaleChanged)
// Move/Displaced Animation
Q_PROPERTY(int moveDuration READ moveDuration WRITE setMoveDuration NOTIFY moveDurationChanged)
Q_PROPERTY(QEasingCurve moveCurve READ moveCurve WRITE setMoveCurve NOTIFY moveCurveChanged)
// State
Q_PROPERTY(int count READ count NOTIFY countChanged)
Q_PROPERTY(bool settled READ settled NOTIFY settledChanged)
public:
explicit LazyListView(QQuickItem* parent = nullptr);
@ -143,43 +127,12 @@ public:
[[nodiscard]] bool asynchronous() const;
void setAsynchronous(bool async);
// Add Animation
[[nodiscard]] int addDuration() const;
void setAddDuration(int duration);
[[nodiscard]] QEasingCurve addCurve() const;
void setAddCurve(const QEasingCurve& curve);
[[nodiscard]] qreal addFromOpacity() const;
void setAddFromOpacity(qreal opacity);
[[nodiscard]] qreal addFromScale() const;
void setAddFromScale(qreal scale);
// Remove Animation
[[nodiscard]] int removeDuration() const;
void setRemoveDuration(int duration);
[[nodiscard]] QEasingCurve removeCurve() const;
void setRemoveCurve(const QEasingCurve& curve);
[[nodiscard]] qreal removeToOpacity() const;
void setRemoveToOpacity(qreal opacity);
[[nodiscard]] qreal removeToScale() const;
void setRemoveToScale(qreal scale);
// Move Animation
[[nodiscard]] int moveDuration() const;
void setMoveDuration(int duration);
[[nodiscard]] QEasingCurve moveCurve() const;
void setMoveCurve(const QEasingCurve& curve);
// State
[[nodiscard]] int count() const;
[[nodiscard]] bool settled() const;
signals:
void modelChanged();
void delegateChanged();
@ -192,18 +145,8 @@ signals:
void cacheBufferChanged();
void estimatedHeightChanged();
void asynchronousChanged();
void addDurationChanged();
void addCurveChanged();
void addFromOpacityChanged();
void addFromScaleChanged();
void removeDurationChanged();
void removeCurveChanged();
void removeToOpacityChanged();
void removeToScaleChanged();
void moveDurationChanged();
void moveCurveChanged();
void countChanged();
void settledChanged();
void viewportAdjustNeeded(qreal delta);
protected:
@ -223,7 +166,6 @@ private:
QQuickItem* item = nullptr;
QQmlContext* context = nullptr;
bool pendingRemoval = false;
QParallelAnimationGroup* animation = nullptr;
QMetaObject::Connection attachedConnection;
};
@ -254,11 +196,6 @@ private:
void onDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QList<int>& roles);
void onModelReset();
// Animation
void startAddAnimation(DelegateEntry& entry);
void startRemoveAnimation(DelegateEntry& entry);
void stopAnimation(DelegateEntry& entry);
void onAnimationFinished();
// Members
QAbstractItemModel* m_model = nullptr;
@ -278,28 +215,15 @@ private:
int m_knownHeightCount = 0;
bool m_asynchronous = false;
int m_addDuration = 300;
QEasingCurve m_addCurve;
qreal m_addFromOpacity = 0;
qreal m_addFromScale = 1;
int m_removeDuration = 300;
QEasingCurve m_removeCurve;
qreal m_removeToOpacity = 0;
qreal m_removeToScale = 1;
int m_moveDuration = 300;
QEasingCurve m_moveCurve;
QVector<ItemRecord> m_layout;
QHash<int, DelegateEntry> m_delegates;
QHash<QQuickItem*, int> m_itemToIndex;
QVector<DelegateEntry> m_dyingDelegates;
int m_activeAnimations = 0;
bool m_componentComplete = false;
bool m_relayoutPending = false;
QSet<int> m_pendingAddAnimations;
QList<QMetaObject::Connection> m_modelConnections;
};