8#include "delegateanimationhandler_p.h"
10#include <QAbstractItemView>
12#include <QPersistentModelIndex>
16#include <QAbstractProxyModel>
19#include "moc_delegateanimationhandler_p.cpp"
28 bool draggingState()
const
42 , regular(
QPixmap(size * devicePixelRatio))
43 , hover(
QPixmap(size * devicePixelRatio))
45 , validityIndex(index)
47 regular.setDevicePixelRatio(devicePixelRatio);
48 hover.setDevicePixelRatio(devicePixelRatio);
53 connect(index.model(), &QAbstractItemModel::dataChanged, this, &CachedRendering::dataChanged);
54 connect(index.model(), &QAbstractItemModel::modelReset, this, &CachedRendering::modelReset);
60 if (validityIndex.row() >= topLeft.
row() && validityIndex.column() >= topLeft.
column() && validityIndex.row() <= bottomRight.
row()
61 && validityIndex.column() <= bottomRight.
column()) {
66void CachedRendering::modelReset()
73AnimationState::AnimationState(
const QModelIndex &index)
80 , m_jobAnimationAngle(0.0)
81 , renderCache(nullptr)
82 , fadeFromRenderCache(nullptr)
87AnimationState::~AnimationState()
90 delete fadeFromRenderCache;
93bool AnimationState::update()
96 const qreal increment = 1000. / runtime / 1000.;
97 const qreal delta = increment * time.restart();
100 progress = qMin(qreal(1.0), progress + delta);
101 animating = (progress < 1.0);
103 progress = qMax(qreal(0.0), progress - delta);
104 animating = (progress > 0.0);
107 if (fadeFromRenderCache) {
109 m_fadeProgress = qMin(qreal(1.0), m_fadeProgress + delta);
110 animating |= (m_fadeProgress < 1.0);
111 if (m_fadeProgress == 1) {
112 setCachedRenderingFadeFrom(
nullptr);
117 m_jobAnimationAngle += 1.0;
118 if (m_jobAnimationAngle == 360) {
119 m_jobAnimationAngle = 0;
136static constexpr double s_mPI2 = 1.57079632679489661923;
138qreal AnimationState::hoverProgress()
const
140 return qRound(255.0 * std::sin(progress * s_mPI2)) / 255.0;
143qreal AnimationState::fadeProgress()
const
145 return qRound(255.0 * std::sin(m_fadeProgress * s_mPI2)) / 255.0;
148qreal AnimationState::jobAnimationAngle()
const
150 return m_jobAnimationAngle;
153bool AnimationState::hasJobAnimation()
const
158void AnimationState::setJobAnimation(
bool value)
160 jobAnimation = value;
165static const int switchIconInterval = 1000;
167DelegateAnimationHandler::DelegateAnimationHandler(
QObject *parent)
170 iconSequenceTimer.setSingleShot(
true);
171 iconSequenceTimer.setInterval(switchIconInterval);
176DelegateAnimationHandler::~DelegateAnimationHandler()
181 while (i.hasNext()) {
183 qDeleteAll(*i.value());
186 animationLists.clear();
189void DelegateAnimationHandler::sequenceTimerTimeout()
204 iconSequenceTimer.start();
208void DelegateAnimationHandler::gotNewIcon(
const QModelIndex &index)
213 if (sequenceModelIndex.isValid() && currentSequenceIndex) {
214 iconSequenceTimer.start();
217 ++currentSequenceIndex;
220void DelegateAnimationHandler::setSequenceIndex(
int sequenceIndex)
224 if (sequenceIndex > 0) {
225 currentSequenceIndex = sequenceIndex;
226 iconSequenceTimer.start();
228 currentSequenceIndex = 0;
229 sequenceTimerTimeout();
230 currentSequenceIndex = 0;
231 iconSequenceTimer.stop();
235void DelegateAnimationHandler::eventuallyStartIteration(
const QModelIndex &index)
240 if (sequenceModelIndex.isValid()) {
245 sequenceModelIndex = index;
255 if (!view ||
static_cast<const ProtectedAccessor *
>(view)->draggingState()) {
259 AnimationState *state = findAnimationState(view, index);
263 if (!state && hover) {
264 state =
new AnimationState(index);
265 addAnimationState(state, view);
267 if (!fadeInAddTime.isValid() || (fadeInAddTime.isValid() && fadeInAddTime.elapsed() > 300)) {
268 startAnimation(state);
270 state->animating =
false;
271 state->progress = 1.0;
275 fadeInAddTime.restart();
277 eventuallyStartIteration(index);
283 if (state->creationTime.elapsed() < 200) {
284 state->progress = 0.0;
287 startAnimation(state);
290 if (index == sequenceModelIndex) {
301 if (!state->animating) {
302 startAnimation(state);
305 eventuallyStartIteration(index);
308 state =
new AnimationState(index);
309 addAnimationState(state, view);
310 startAnimation(state);
311 state->setJobAnimation(
true);
320 const AnimationList *
list = animationLists.
value(view);
323 auto it = std::find_if(
list->
cbegin(),
list->
cend(), [&index](AnimationState *state) {
324 return state->index == index;
334void DelegateAnimationHandler::addAnimationState(AnimationState *state,
const QAbstractItemView *view)
336 AnimationList *
list = animationLists.
value(view);
342 list =
new AnimationList;
343 animationLists.
insert(view, list);
349void DelegateAnimationHandler::restartAnimation(AnimationState *state)
351 startAnimation(state);
354void DelegateAnimationHandler::startAnimation(AnimationState *state)
357 state->animating =
true;
359 if (!timer.isActive()) {
360 timer.start(1000 / 30,
this);
364int DelegateAnimationHandler::runAnimations(AnimationList *list,
const QAbstractItemView *view)
366 int activeAnimations = 0;
370 while (i.hasNext()) {
371 AnimationState *state = i.next();
373 if (!state->animating) {
379 if (state->index.isValid()) {
380 bool finished = state->update();
403 return activeAnimations;
406void DelegateAnimationHandler::viewDeleted(
QObject *view)
413void DelegateAnimationHandler::timerEvent(
QTimerEvent *)
415 int activeAnimations = 0;
417 AnimationListsIterator i(animationLists);
418 while (i.hasNext()) {
423 activeAnimations += runAnimations(list, view);
426 if (activeAnimations == 0 && timer.isActive()) {
433#include "delegateanimationhandler.moc"
A model for a KIO-based directory tree.
@ HasJobRole
returns whether or not there is a job on an item (file/directory). roleName is "hasJob".
void requestSequenceIcon(const QModelIndex &index, int sequenceIndex)
This emits the needSequenceIcon signal, requesting another sequence icon.
A namespace for KIO globals.
KIOCORE_EXPORT QStringList list(const QString &fileClass)
Returns a list of directories associated with this file-class.
virtual QVariant data(const QModelIndex &index, int role) const const=0
State state() const const
void update(const QModelIndex &index)
virtual QRect visualRect(const QModelIndex &index) const const=0
virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const const=0
void append(QList< T > &&value)
const_iterator cbegin() const const
const_iterator cend() const const
iterator insert(const_iterator before, parameter_type value)
T value(qsizetype i) const const
const QAbstractItemModel * model() const const
void destroyed(QObject *obj)
bool isEmpty() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
bool toBool() const const