blob: 1f2c0b74603db0b137f0b61f9cd7ac985559dac9 (
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
|
// SPDX-FileCopyrightText: Nheko Contributors
//
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <QBuffer>
#include <QMovie>
#include <QObject>
#include <QQuickItem>
#include "timeline/TimelineModel.h"
// This is an AnimatedImage, that can draw encrypted images
class MxcAnimatedImage : public QQuickItem
{
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(TimelineModel *roomm READ room WRITE setRoom NOTIFY roomChanged REQUIRED)
Q_PROPERTY(QString eventId READ eventId WRITE setEventId NOTIFY eventIdChanged)
Q_PROPERTY(bool animatable READ animatable NOTIFY animatableChanged)
Q_PROPERTY(bool loaded READ loaded NOTIFY loadedChanged)
Q_PROPERTY(bool play READ play WRITE setPlay NOTIFY playChanged)
public:
MxcAnimatedImage(QQuickItem *parent = nullptr)
: QQuickItem(parent)
{
connect(this, &MxcAnimatedImage::eventIdChanged, &MxcAnimatedImage::startDownload);
connect(this, &MxcAnimatedImage::roomChanged, &MxcAnimatedImage::startDownload);
connect(&movie, &QMovie::frameChanged, this, &MxcAnimatedImage::newFrame);
setFlag(QQuickItem::ItemHasContents);
setFlag(QQuickItem::ItemObservesViewport);
// setAcceptHoverEvents(true);
}
bool animatable() const { return animatable_; }
bool loaded() const { return buffer.size() > 0; }
bool play() const { return play_; }
QString eventId() const { return eventId_; }
TimelineModel *room() const { return room_; }
void setEventId(QString newEventId)
{
if (eventId_ != newEventId) {
eventId_ = newEventId;
emit eventIdChanged();
}
}
void setRoom(TimelineModel *room)
{
if (room_ != room) {
room_ = room;
emit roomChanged();
}
}
void setPlay(bool newPlay)
{
if (play_ != newPlay) {
play_ = newPlay;
if (movie.frameCount() > 1)
movie.setPaused(!play_);
else {
movie.jumpToFrame(0);
movie.setPaused(true);
}
emit playChanged();
}
}
void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
QSGNode *updatePaintNode(QSGNode *oldNode,
QQuickItem::UpdatePaintNodeData *updatePaintNodeData) override;
signals:
void roomChanged();
void eventIdChanged();
void animatableChanged();
void loadedChanged();
void playChanged();
private slots:
void startDownload();
void newFrame(int frame)
{
currentFrame = frame;
imageDirty = true;
if (!clipRect().isEmpty())
update();
}
private:
TimelineModel *room_ = nullptr;
QString eventId_;
QString filename_;
bool animatable_ = false;
QBuffer buffer;
QMovie movie;
int currentFrame = 0;
bool imageDirty = true;
bool play_ = true;
};
|