forked from qt-creator/qt-creator
ImageViewer: Fix animation playback replay and loop
This fixes the issue that looped animated images do not automatically loop and that animations can generally not be replayed from start. It introduces the "resume" state to the tool bar icon in order to distinguish between "playing an animation from start" and "resuming the playback of a paused animation". The setting cache mode QMovie::CacheAll was removed because it prevents a looped animation from looping, and also its memory consumption (which depends on animation dimension and frames) does not seem to be positively outweighed by anything else. Fixes: QTCREATORBUG-29606 Change-Id: Iaca8d93766201f5f953784be7ee6d56610e63695 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Eike Ziller <eike.ziller@qt.io> Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
This commit is contained in:
@@ -234,7 +234,7 @@ void ImageViewer::ctor()
|
||||
d->imageView, &ImageView::reset);
|
||||
connect(d->file.data(), &ImageViewerFile::reloadFinished,
|
||||
d->imageView, &ImageView::createScene);
|
||||
connect(d->file.data(), &ImageViewerFile::isPausedChanged,
|
||||
connect(d->file.data(), &ImageViewerFile::movieStateChanged,
|
||||
this, &ImageViewer::updatePauseAction);
|
||||
connect(d->imageView, &ImageView::scaleFactorChanged,
|
||||
this, &ImageViewer::scaleFactorUpdate);
|
||||
@@ -349,19 +349,42 @@ void ImageViewer::togglePlay()
|
||||
|
||||
void ImageViewer::playToggled()
|
||||
{
|
||||
d->file->setPaused(!d->file->isPaused());
|
||||
QMovie *m = d->file->movie();
|
||||
if (!m)
|
||||
return;
|
||||
const QMovie::MovieState state = d->file->movie()->state();
|
||||
switch (state) {
|
||||
case QMovie::NotRunning:
|
||||
m->start();
|
||||
break;
|
||||
case QMovie::Paused:
|
||||
m->setPaused(false);
|
||||
break;
|
||||
case QMovie::Running:
|
||||
m->setPaused(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ImageViewer::updatePauseAction()
|
||||
{
|
||||
bool isMovie = d->file->type() == ImageViewerFile::TypeMovie;
|
||||
if (isMovie && !d->file->isPaused()) {
|
||||
d->actionPlayPause->setToolTipBase(Tr::tr("Pause Animation"));
|
||||
d->actionPlayPause->setIcon(Icons::INTERRUPT_SMALL_TOOLBAR.icon());
|
||||
} else {
|
||||
d->actionPlayPause->setToolTipBase(Tr::tr("Play Animation"));
|
||||
d->actionPlayPause->setIcon(Icons::RUN_SMALL_TOOLBAR.icon());
|
||||
d->actionPlayPause->setEnabled(isMovie);
|
||||
const bool isMovie = d->file->type() == ImageViewerFile::TypeMovie;
|
||||
const QMovie::MovieState state = isMovie ? d->file->movie()->state() : QMovie::NotRunning;
|
||||
CommandAction *a = d->actionPlayPause;
|
||||
switch (state) {
|
||||
case QMovie::NotRunning:
|
||||
a->setToolTipBase(Tr::tr("Play Animation"));
|
||||
a->setIcon(Icons::RUN_SMALL_TOOLBAR.icon());
|
||||
a->setEnabled(isMovie);
|
||||
break;
|
||||
case QMovie::Paused:
|
||||
a->setToolTipBase(Tr::tr("Resume Paused Animation"));
|
||||
a->setIcon(Icons::CONTINUE_SMALL_TOOLBAR.icon());
|
||||
break;
|
||||
case QMovie::Running:
|
||||
a->setToolTipBase(Tr::tr("Pause Animation"));
|
||||
a->setIcon(Icons::INTERRUPT_SMALL_TOOLBAR.icon());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "imageviewerconstants.h"
|
||||
#include "imageviewertr.h"
|
||||
#include "utils/algorithm.h"
|
||||
|
||||
#include <coreplugin/editormanager/documentmodel.h>
|
||||
#include <coreplugin/editormanager/ieditor.h>
|
||||
@@ -115,20 +116,8 @@ Core::IDocument::OpenResult ImageViewerFile::openImpl(QString *errorString,
|
||||
return OpenResult::CannotHandle;
|
||||
}
|
||||
m_type = TypeMovie;
|
||||
m_movie->setCacheMode(QMovie::CacheAll);
|
||||
connect(
|
||||
m_movie,
|
||||
&QMovie::finished,
|
||||
m_movie,
|
||||
[this] {
|
||||
if (m_movie->isValid())
|
||||
m_movie->start();
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
connect(m_movie, &QMovie::resized, this, &ImageViewerFile::imageSizeChanged);
|
||||
m_movie->start();
|
||||
m_isPaused = false; // force update
|
||||
setPaused(true);
|
||||
connect(m_movie, &QMovie::stateChanged, this, &ImageViewerFile::movieStateChanged);
|
||||
} else {
|
||||
m_pixmap = new QPixmap(fileName);
|
||||
if (m_pixmap->isNull()) {
|
||||
@@ -169,18 +158,9 @@ bool ImageViewerFile::reload(QString *errorString,
|
||||
return success;
|
||||
}
|
||||
|
||||
bool ImageViewerFile::isPaused() const
|
||||
QMovie *ImageViewerFile::movie() const
|
||||
{
|
||||
return m_isPaused;
|
||||
}
|
||||
|
||||
void ImageViewerFile::setPaused(bool paused)
|
||||
{
|
||||
if (!m_movie || m_isPaused == paused)
|
||||
return;
|
||||
m_isPaused = paused;
|
||||
m_movie->setPaused(paused);
|
||||
emit isPausedChanged(m_isPaused);
|
||||
return m_movie;
|
||||
}
|
||||
|
||||
QGraphicsItem *ImageViewerFile::createGraphicsItem() const
|
||||
@@ -221,16 +201,13 @@ ImageViewerFile::ImageType ImageViewerFile::type() const
|
||||
|
||||
void ImageViewerFile::updateVisibility()
|
||||
{
|
||||
if (!m_movie || m_isPaused)
|
||||
if (!m_movie || m_movie->state() != QMovie::Running)
|
||||
return;
|
||||
bool visible = false;
|
||||
for (Core::IEditor *editor : Core::DocumentModel::editorsForDocument(this)) {
|
||||
if (editor->widget()->isVisible()) {
|
||||
visible = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_movie->setPaused(!visible);
|
||||
const bool anyVisible = Utils::anyOf(Core::DocumentModel::editorsForDocument(this),
|
||||
[] (Core::IEditor *editor)
|
||||
{ return editor->widget()->isVisible(); });
|
||||
if (!anyVisible)
|
||||
m_movie->setPaused(true);
|
||||
}
|
||||
|
||||
void ImageViewerFile::cleanUp()
|
||||
|
@@ -6,9 +6,10 @@
|
||||
|
||||
#include <coreplugin/idocument.h>
|
||||
|
||||
#include <QMovie>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QGraphicsItem;
|
||||
class QMovie;
|
||||
class QPixmap;
|
||||
|
||||
#ifndef QT_NO_SVG
|
||||
@@ -40,8 +41,7 @@ public:
|
||||
ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const override;
|
||||
bool reload(QString *errorString, ReloadFlag flag, ChangeType type) override;
|
||||
|
||||
bool isPaused() const;
|
||||
void setPaused(bool paused);
|
||||
QMovie *movie() const;
|
||||
|
||||
QGraphicsItem *createGraphicsItem() const;
|
||||
ImageType type() const;
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
signals:
|
||||
void openFinished(bool success);
|
||||
void imageSizeChanged(const QSize &size);
|
||||
void isPausedChanged(bool paused);
|
||||
void movieStateChanged();
|
||||
|
||||
private:
|
||||
void cleanUp();
|
||||
@@ -63,7 +63,6 @@ private:
|
||||
#endif
|
||||
QMovie *m_movie = nullptr;
|
||||
QPixmap *m_pixmap = nullptr;
|
||||
bool m_isPaused = false;
|
||||
};
|
||||
|
||||
} // ImageViewer::Internal
|
||||
|
Reference in New Issue
Block a user