File indexing completed on 2024-12-08 03:40:42

0001 /*
0002     This file is part of the KDE project
0003     SPDX-FileCopyrightText: 2007 Fredrik Höglund <fredrik@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #ifndef DELEGATEANIMATIONHANDLER_P_H
0009 #define DELEGATEANIMATIONHANDLER_P_H
0010 
0011 #include <QBasicTimer>
0012 #include <QElapsedTimer>
0013 #include <QMap>
0014 #include <QPersistentModelIndex>
0015 #include <QStyle>
0016 #include <QTime>
0017 #include <QTimeLine>
0018 #include <QTimer>
0019 
0020 class QAbstractItemView;
0021 
0022 namespace KIO
0023 {
0024 class CachedRendering : public QObject
0025 {
0026     Q_OBJECT
0027 public:
0028     CachedRendering(QStyle::State state, const QSize &size, const QModelIndex &validityIndex, qreal devicePixelRatio = 1.0);
0029     bool checkValidity(QStyle::State current) const
0030     {
0031         return state == current && valid;
0032     }
0033 
0034     QStyle::State state;
0035     QPixmap regular;
0036     QPixmap hover;
0037 
0038     bool valid;
0039     QPersistentModelIndex validityIndex;
0040 private Q_SLOTS:
0041     void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
0042     void modelReset();
0043 };
0044 
0045 class AnimationState
0046 {
0047 public:
0048     ~AnimationState();
0049     AnimationState(const AnimationState &) = delete;
0050     AnimationState &operator=(const AnimationState &) = delete;
0051 
0052     // Progress of the mouse hovering animation
0053     qreal hoverProgress() const;
0054     // Progress of the icon fading animation
0055     qreal fadeProgress() const;
0056     // Angle of the painter, to paint the animation for a file job on an item
0057     qreal jobAnimationAngle() const;
0058 
0059     void setJobAnimation(bool value);
0060     bool hasJobAnimation() const;
0061 
0062     CachedRendering *cachedRendering() const
0063     {
0064         return renderCache;
0065     }
0066     // The previous render-cache is deleted, if there was one
0067     void setCachedRendering(CachedRendering *rendering)
0068     {
0069         delete renderCache;
0070         renderCache = rendering;
0071     }
0072 
0073     // Returns current cached rendering, and removes it from this state.
0074     // The caller has the ownership.
0075     CachedRendering *takeCachedRendering()
0076     {
0077         CachedRendering *ret = renderCache;
0078         renderCache = nullptr;
0079         return ret;
0080     }
0081 
0082     CachedRendering *cachedRenderingFadeFrom() const
0083     {
0084         return fadeFromRenderCache;
0085     }
0086     // The previous render-cache is deleted, if there was one
0087     void setCachedRenderingFadeFrom(CachedRendering *rendering)
0088     {
0089         delete fadeFromRenderCache;
0090         fadeFromRenderCache = rendering;
0091         if (rendering) {
0092             m_fadeProgress = 0;
0093         } else {
0094             m_fadeProgress = 1;
0095         }
0096     }
0097 
0098 private:
0099     explicit AnimationState(const QModelIndex &index);
0100     bool update();
0101 
0102     QPersistentModelIndex index;
0103     QTimeLine::Direction direction;
0104     bool animating;
0105     bool jobAnimation;
0106     qreal progress;
0107     qreal m_fadeProgress;
0108     qreal m_jobAnimationAngle;
0109     QElapsedTimer time;
0110     QElapsedTimer creationTime;
0111     CachedRendering *renderCache;
0112     CachedRendering *fadeFromRenderCache;
0113 
0114     friend class DelegateAnimationHandler;
0115 };
0116 
0117 class DelegateAnimationHandler : public QObject
0118 {
0119     Q_OBJECT
0120 
0121     typedef QList<AnimationState *> AnimationList;
0122     typedef QMapIterator<const QAbstractItemView *, AnimationList *> AnimationListsIterator;
0123     typedef QMutableMapIterator<const QAbstractItemView *, AnimationList *> MutableAnimationListsIterator;
0124 
0125 public:
0126     explicit DelegateAnimationHandler(QObject *parent = nullptr);
0127     ~DelegateAnimationHandler() override;
0128 
0129     AnimationState *animationState(const QStyleOption &option, const QModelIndex &index, const QAbstractItemView *view);
0130 
0131     void restartAnimation(AnimationState *state);
0132 
0133     void gotNewIcon(const QModelIndex &index);
0134 
0135 private Q_SLOTS:
0136     void viewDeleted(QObject *view);
0137     void sequenceTimerTimeout();
0138 
0139 private:
0140     void eventuallyStartIteration(const QModelIndex &index);
0141     AnimationState *findAnimationState(const QAbstractItemView *view, const QModelIndex &index) const;
0142     void addAnimationState(AnimationState *state, const QAbstractItemView *view);
0143     void startAnimation(AnimationState *state);
0144     int runAnimations(AnimationList *list, const QAbstractItemView *view);
0145     void timerEvent(QTimerEvent *event) override;
0146     void setSequenceIndex(int arg1);
0147 
0148 private:
0149     QMap<const QAbstractItemView *, AnimationList *> animationLists;
0150     QElapsedTimer fadeInAddTime;
0151     QBasicTimer timer;
0152     // Icon sequence handling:
0153     QPersistentModelIndex sequenceModelIndex;
0154     QTimer iconSequenceTimer;
0155     int currentSequenceIndex;
0156 };
0157 
0158 }
0159 
0160 #endif