aboutsummaryrefslogtreecommitdiffstats
path: root/src/kvilib/ext/KviAnimatedPixmap.h
blob: afbc5f3cf947c42710caba7325d8e55f9266f70c (about) (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#ifndef KVI_ANIMATEDPIXMAP_H_
#define KVI_ANIMATEDPIXMAP_H_
//=============================================================================
//
//   File : KviAnimatedPixmap.h
//   Creation date : Wed Jul 30 2008 01:45:21 CEST by Alexey Uzhva
//
//   This file is part of the KVIrc IRC client distribution
//   Copyright (C) 2008 Alexey Uzhva (wizard at opendoor dot ru)
//
//   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.
//
//=============================================================================

#include "kvi_settings.h"
#include "KviAnimatedPixmapCache.h"

#include <QObject>
#include <QString>
#include <QTimer>

class QPixmap;

/**
 * This class should not be here, because we already have QMovie
 * with the same functionality.
 *
 * But QMovie is really stupid, bacause:
 * 	1) It does not support infinitive animation.
 *     It relies on image metadata to determine loop count. So most of pics will
 *     be played only once.
 *
 *  2) It duplicates QPixmap while we calls currentFrame(), that's a very
 *     big overload for us.
 *
 *  3) If we try to scale QMovie by using built-in scale mechanism, it will
 *     manually scale each frame each time, we will call currentFrame().
 *     So if we plan to play movie 10,100,1000 times, it will scale image
 *     10,100,1000 times too:(
 *
 *  4) KviAnimatedPixmap uses internal cache mechanism with KviAnimatedPixmapCache class.
 *     It's managed inside KviAnimatedPixmap and KviAnimatedPixmapCache. No other actions
 *     needed to perform caching.
 *
 * So... Here is my workaround. It's working in this way:
 * You should create new pixmap with constructor KviAnimatedPixmap(QString fileName).
 * It will automagically look at cache and use it, if possible.
 *
 * KviAnimatedPixmap stores animation as a set of QPixmap's, and delays.
 * when started (see start()) it emits frameChanged() events at the frame change.
 *
 * You should use pixmap() methd to access the current frame.
 *
 * This class owns all pixmaps. Do not store links to them.
 */

class KVILIB_API KviAnimatedPixmap : public QObject, public KviAnimatedPixmapInterface
{
	Q_OBJECT
protected:
	QString m_szFileName;
	KviAnimatedPixmapCache::Data * m_pFrameData;

	uint m_uCurrentFrameNumber;
	int m_iStarted;

public:
	/*
	* Creates KviAnimatedPixmap, and loads data from "fileName".
	*/
	KviAnimatedPixmap(QString fileName, int iWidth = 0, int iHeight = 0);

	virtual ~KviAnimatedPixmap();

	/*
	 * Creates new pixmap using "source" as source of images.
	 */
	KviAnimatedPixmap(const KviAnimatedPixmap & source);

	/*
	 * Returns true if animation is started.
	 * Returns false otherways.
	 */
	bool isStarted() const
	{
		return m_iStarted > 0;
	}

	/*
	 * Starts the animation
	 */
	void start();

	/*
	 * Stops the animation
	 */
	void stop();

	/*
	 * Returns true if animation has at least one loaded frame.
	 * Returns false otherways.
	 */
	bool isValid() const
	{
		return (m_pFrameData->count() > 0);
	}

	/*
	 * Returns active frame's pixmap.
	 * Never fails.
	 */

	QPixmap * pixmap()
	{
		if(m_pFrameData->count() > 0)
			return m_pFrameData->at(m_uCurrentFrameNumber).pixmap;
		else
			return KviAnimatedPixmapCache::dummyPixmap();
	}

	/*
	 * Returns active frame number
	 */
	uint activeFrameNumber() const
	{
		return m_uCurrentFrameNumber;
	}

	/*
	 * Returns animation frame count
	 */
	uint framesCount() const
	{
		return m_pFrameData->count();
	}

	/*
	 * Returns current image size
	 */
	const QSize & size() const
	{
		return m_pFrameData->size;
	}

	/*
	 * Resizes all frames to the newSize size, using "ratioMode"
	 * ratio.
	 */
	void resize(QSize newSize, Qt::AspectRatioMode ratioMode);

	/*
	 * Called when the frame changes
	 */
	void nextFrame(bool bEmitSignalAndScheduleNext);

signals:

	/*
	 * Slot, to be connected to m_animationTimer, to receive animation
	 * frame changes.
	 */
	void frameChanged();
};

#endif /* KVI_ANIMATEDPIXMAP_H_ */