]> cloud.milkyroute.net Git - dolphin.git/blob - src/panels/information/pixmapviewer.cpp
Center align pixmaps in a high DPR friendly way
[dolphin.git] / src / panels / information / pixmapviewer.cpp
1 /***************************************************************************
2 * Copyright (C) 2006 by Peter Penz <peter.penz19@gmail.com> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
18 ***************************************************************************/
19
20 #include "pixmapviewer.h"
21
22 #include <KIconLoader>
23
24 #include <QPainter>
25 #include <QPixmap>
26 #include <QStyle>
27
28 PixmapViewer::PixmapViewer(QWidget* parent, Transition transition) :
29 QWidget(parent),
30 m_transition(transition),
31 m_animationStep(0),
32 m_sizeHint()
33 {
34 setMinimumWidth(KIconLoader::SizeEnormous);
35 setMinimumHeight(KIconLoader::SizeEnormous);
36
37 m_animation.setDuration(150);
38 m_animation.setCurveShape(QTimeLine::LinearCurve);
39
40 if (m_transition != NoTransition) {
41 connect(&m_animation, &QTimeLine::valueChanged, this, static_cast<void(PixmapViewer::*)()>(&PixmapViewer::update));
42 connect(&m_animation, &QTimeLine::finished, this, &PixmapViewer::checkPendingPixmaps);
43 }
44 }
45
46 PixmapViewer::~PixmapViewer()
47 {
48 }
49
50 void PixmapViewer::setPixmap(const QPixmap& pixmap)
51 {
52 if (pixmap.isNull()) {
53 return;
54 }
55
56 if ((m_transition != NoTransition) && (m_animation.state() == QTimeLine::Running)) {
57 m_pendingPixmaps.enqueue(pixmap);
58 if (m_pendingPixmaps.count() > 5) {
59 // don't queue more than 5 pixmaps
60 m_pendingPixmaps.takeFirst();
61 }
62 return;
63 }
64
65 m_oldPixmap = m_pixmap.isNull() ? pixmap : m_pixmap;
66 m_pixmap = pixmap;
67 update();
68
69 const bool animate = (m_transition != NoTransition) &&
70 (m_pixmap.size() != m_oldPixmap.size());
71 if (animate) {
72 m_animation.start();
73 }
74 }
75
76 void PixmapViewer::setSizeHint(const QSize& size)
77 {
78 m_sizeHint = size;
79 updateGeometry();
80 }
81
82 QSize PixmapViewer::sizeHint() const
83 {
84 return m_sizeHint;
85 }
86
87 void PixmapViewer::paintEvent(QPaintEvent* event)
88 {
89 QWidget::paintEvent(event);
90
91 QPainter painter(this);
92
93 if (m_transition != NoTransition) {
94 const float value = m_animation.currentValue();
95 const int scaledWidth = static_cast<int>((m_oldPixmap.width() * (1.0 - value)) + (m_pixmap.width() * value));
96 const int scaledHeight = static_cast<int>((m_oldPixmap.height() * (1.0 - value)) + (m_pixmap.height() * value));
97
98 const bool useOldPixmap = (m_transition == SizeTransition) &&
99 (m_oldPixmap.width() > m_pixmap.width());
100 const QPixmap& largePixmap = useOldPixmap ? m_oldPixmap : m_pixmap;
101 if (!largePixmap.isNull()) {
102 const QPixmap scaledPixmap = largePixmap.scaled(scaledWidth,
103 scaledHeight,
104 Qt::IgnoreAspectRatio,
105 Qt::FastTransformation);
106
107 style()->drawItemPixmap(&painter, rect(), Qt::AlignCenter, scaledPixmap);
108 }
109 } else {
110 style()->drawItemPixmap(&painter, rect(), Qt::AlignCenter, m_pixmap);
111 }
112 }
113
114 void PixmapViewer::checkPendingPixmaps()
115 {
116 if (m_pendingPixmaps.count() > 0) {
117 QPixmap pixmap = m_pendingPixmaps.dequeue();
118 m_oldPixmap = m_pixmap.isNull() ? pixmap : m_pixmap;
119 m_pixmap = pixmap;
120 update();
121 m_animation.start();
122 } else {
123 m_oldPixmap = m_pixmap;
124 }
125 }
126