X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/7f4c3976c0626657362b6324c0dad2867cc24e9b..efd4a2acb681a0766d59d5cfb0bcbfb7fc389309:/src/panels/information/pixmapviewer.cpp diff --git a/src/panels/information/pixmapviewer.cpp b/src/panels/information/pixmapviewer.cpp index 0053e43f9..b18c9e64e 100644 --- a/src/panels/information/pixmapviewer.cpp +++ b/src/panels/information/pixmapviewer.cpp @@ -1,43 +1,34 @@ -/*************************************************************************** - * Copyright (C) 2006 by Peter Penz * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ +/* + * SPDX-FileCopyrightText: 2006 Peter Penz + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ #include "pixmapviewer.h" #include +#include +#include #include -#include - -PixmapViewer::PixmapViewer(QWidget* parent, Transition transition) : - QWidget(parent), - m_transition(transition), - m_animationStep(0), - m_sizeHint() +#include + +PixmapViewer::PixmapViewer(QWidget *parent, Transition transition) + : QWidget(parent) + , m_animatedImage(nullptr) + , m_transition(transition) + , m_animationStep(0) + , m_sizeHint() + , m_hasAnimatedImage(false) { setMinimumWidth(KIconLoader::SizeEnormous); setMinimumHeight(KIconLoader::SizeEnormous); m_animation.setDuration(150); - m_animation.setCurveShape(QTimeLine::LinearCurve); + m_animation.setEasingCurve(QEasingCurve::Linear); if (m_transition != NoTransition) { - connect(&m_animation, &QTimeLine::valueChanged, this, static_cast(&PixmapViewer::update)); + connect(&m_animation, &QTimeLine::valueChanged, this, QOverload<>::of(&PixmapViewer::update)); connect(&m_animation, &QTimeLine::finished, this, &PixmapViewer::checkPendingPixmaps); } } @@ -46,7 +37,7 @@ PixmapViewer::~PixmapViewer() { } -void PixmapViewer::setPixmap(const QPixmap& pixmap) +void PixmapViewer::setPixmap(const QPixmap &pixmap) { if (pixmap.isNull()) { return; @@ -63,17 +54,32 @@ void PixmapViewer::setPixmap(const QPixmap& pixmap) m_oldPixmap = m_pixmap.isNull() ? pixmap : m_pixmap; m_pixmap = pixmap; + + // Avoid flicker with static pixmap if an animated image is running + if (m_animatedImage && m_animatedImage->state() == QMovie::Running) { + return; + } + update(); - const bool animate = (m_transition != NoTransition) && - (m_pixmap.size() != m_oldPixmap.size()); - if (animate) { + const bool animateTransition = (m_transition != NoTransition) && (m_pixmap.size() != m_oldPixmap.size()); + if (animateTransition) { m_animation.start(); + } else if (m_hasAnimatedImage) { + // If there is no transition animation but an animatedImage + // and it is not already running, start animating now + if (m_animatedImage->state() != QMovie::Running) { + m_animatedImage->start(); + } } } -void PixmapViewer::setSizeHint(const QSize& size) +void PixmapViewer::setSizeHint(const QSize &size) { + if (m_animatedImage && size != m_sizeHint) { + m_animatedImage->stop(); + } + m_sizeHint = size; updateGeometry(); } @@ -83,47 +89,96 @@ QSize PixmapViewer::sizeHint() const return m_sizeHint; } -void PixmapViewer::paintEvent(QPaintEvent* event) +void PixmapViewer::setAnimatedImageFileName(const QString &fileName) +{ + if (!m_animatedImage) { + m_animatedImage = new QMovie(this); + connect(m_animatedImage, &QMovie::frameChanged, this, &PixmapViewer::updateAnimatedImageFrame); + } + + if (m_animatedImage->fileName() != fileName) { + m_animatedImage->setFileName(fileName); + } + + m_hasAnimatedImage = m_animatedImage->isValid() && (m_animatedImage->frameCount() > 1); +} + +QString PixmapViewer::animatedImageFileName() const +{ + if (!m_hasAnimatedImage) { + return QString(); + } + return m_animatedImage->fileName(); +} + +void PixmapViewer::paintEvent(QPaintEvent *event) { QWidget::paintEvent(event); QPainter painter(this); - if (m_transition != NoTransition) { + if (m_transition != NoTransition || (m_hasAnimatedImage && m_animatedImage->state() != QMovie::Running)) { const float value = m_animation.currentValue(); - const int scaledWidth = static_cast((m_oldPixmap.width() * (1.0 - value)) + (m_pixmap.width() * value)); + const int scaledWidth = static_cast((m_oldPixmap.width() * (1.0 - value)) + (m_pixmap.width() * value)); const int scaledHeight = static_cast((m_oldPixmap.height() * (1.0 - value)) + (m_pixmap.height() * value)); - const int x = (width() - scaledWidth ) / 2; - const int y = (height() - scaledHeight) / 2; - - const bool useOldPixmap = (m_transition == SizeTransition) && - (m_oldPixmap.width() > m_pixmap.width()); - const QPixmap& largePixmap = useOldPixmap ? m_oldPixmap : m_pixmap; - if (!largePixmap.isNull()) { - const QPixmap scaledPixmap = largePixmap.scaled(scaledWidth, - scaledHeight, - Qt::IgnoreAspectRatio, - Qt::FastTransformation); - painter.drawPixmap(x, y, scaledPixmap); - } - } else { - const int x = (width() - m_pixmap.width() ) / 2; - const int y = (height() - m_pixmap.height()) / 2; - painter.drawPixmap(x, y, m_pixmap); + const bool useOldPixmap = (m_transition == SizeTransition) && (m_oldPixmap.width() > m_pixmap.width()); + const QPixmap &largePixmap = useOldPixmap ? m_oldPixmap : m_pixmap; + if (!largePixmap.isNull()) { + QPixmap scaledPixmap = largePixmap.scaled(scaledWidth, scaledHeight, Qt::IgnoreAspectRatio, Qt::FastTransformation); + scaledPixmap.setDevicePixelRatio(devicePixelRatioF()); + + style()->drawItemPixmap(&painter, rect(), Qt::AlignCenter, scaledPixmap); + } + } else if (!m_pixmap.isNull()) { + style()->drawItemPixmap(&painter, rect(), Qt::AlignCenter, m_pixmap); } } void PixmapViewer::checkPendingPixmaps() { - if (m_pendingPixmaps.count() > 0) { + if (!m_pendingPixmaps.isEmpty()) { QPixmap pixmap = m_pendingPixmaps.dequeue(); m_oldPixmap = m_pixmap.isNull() ? pixmap : m_pixmap; m_pixmap = pixmap; update(); m_animation.start(); + } else if (m_hasAnimatedImage) { + m_animatedImage->setScaledSize(m_pixmap.size()); + m_animatedImage->start(); } else { m_oldPixmap = m_pixmap; } } +void PixmapViewer::updateAnimatedImageFrame() +{ + Q_ASSERT(m_animatedImage); + + m_pixmap = m_animatedImage->currentPixmap(); + if (m_pixmap.width() > m_sizeHint.width() || m_pixmap.height() > m_sizeHint.height()) { + m_pixmap = m_pixmap.scaled(m_sizeHint, Qt::KeepAspectRatio); + m_animatedImage->setScaledSize(m_pixmap.size()); + } + update(); +} + +void PixmapViewer::stopAnimatedImage() +{ + if (m_hasAnimatedImage) { + m_animatedImage->stop(); + m_hasAnimatedImage = false; + delete m_animatedImage; + m_animatedImage = nullptr; + } +} + +bool PixmapViewer::isAnimatedMimeType(const QString &mimeType) +{ + const QList imageFormats = QImageReader::imageFormatsForMimeType(mimeType.toUtf8()); + return std::any_of(imageFormats.begin(), imageFormats.end(), [](const QByteArray &format) { + return QMovie::supportedFormats().contains(format); + }); +} + +#include "moc_pixmapviewer.cpp"