blob: df1953abfcc7fb22724bbd897a1d222b27927901 (
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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
|
// SPDX-FileCopyrightText: Nheko Contributors
//
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <QAbstractItemModel>
#include <QQmlComponent>
#include <QQmlIncubator>
#include <QQmlListProperty>
#include <QQuickItem>
#include <QtCore/QObject>
#include <QtCore/QVariant>
#include "TimelineModel.h"
class EventDelegateChooserAttachedType : public QObject
{
Q_OBJECT
Q_PROPERTY(bool keepAspectRatio READ keepAspectRatio WRITE setKeepAspectRatio NOTIFY
keepAspectRatioChanged)
Q_PROPERTY(double aspectRatio READ aspectRatio WRITE setAspectRatio NOTIFY aspectRatioChanged)
Q_PROPERTY(int maxWidth READ maxWidth WRITE setMaxWidth NOTIFY maxWidthChanged)
Q_PROPERTY(int maxHeight READ maxHeight WRITE setMaxHeight NOTIFY maxHeightChanged)
Q_PROPERTY(bool isReply READ isReply WRITE setIsReply NOTIFY isReplyChanged)
QML_ANONYMOUS
public:
EventDelegateChooserAttachedType(QObject *parent)
: QObject(parent)
{
}
bool keepAspectRatio() const { return keepAspectRatio_; }
void setKeepAspectRatio(bool fill)
{
if (fill != keepAspectRatio_) {
keepAspectRatio_ = fill;
emit keepAspectRatioChanged();
polishChooser();
}
}
double aspectRatio() const { return aspectRatio_; }
void setAspectRatio(double fill)
{
aspectRatio_ = fill;
emit aspectRatioChanged();
polishChooser();
}
int maxWidth() const { return maxWidth_; }
void setMaxWidth(int fill)
{
maxWidth_ = fill;
emit maxWidthChanged();
polishChooser();
}
int maxHeight() const { return maxHeight_; }
void setMaxHeight(int fill)
{
maxHeight_ = fill;
emit maxHeightChanged();
}
bool isReply() const { return isReply_; }
void setIsReply(bool fill)
{
if (fill != isReply_) {
isReply_ = fill;
emit isReplyChanged();
polishChooser();
}
}
signals:
void keepAspectRatioChanged();
void aspectRatioChanged();
void maxWidthChanged();
void maxHeightChanged();
void isReplyChanged();
private:
void polishChooser();
double aspectRatio_ = 1.;
int maxWidth_ = -1;
int maxHeight_ = -1;
bool keepAspectRatio_ = false;
bool isReply_ = false;
};
class EventDelegateChoice : public QObject
{
Q_OBJECT
QML_ELEMENT
Q_CLASSINFO("DefaultProperty", "delegate")
public:
Q_PROPERTY(QList<int> roleValues READ roleValues WRITE setRoleValues NOTIFY roleValuesChanged
REQUIRED FINAL)
Q_PROPERTY(
QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged REQUIRED FINAL)
[[nodiscard]] QQmlComponent *delegate() const;
void setDelegate(QQmlComponent *delegate);
[[nodiscard]] QList<int> roleValues() const;
void setRoleValues(const QList<int> &value);
signals:
void delegateChanged();
void roleValuesChanged();
void changed();
private:
QList<int> roleValues_;
QQmlComponent *delegate_ = nullptr;
};
class EventDelegateChooser : public QQuickItem
{
Q_OBJECT
QML_ELEMENT
Q_CLASSINFO("DefaultProperty", "choices")
QML_ATTACHED(EventDelegateChooserAttachedType)
Q_PROPERTY(QQmlListProperty<EventDelegateChoice> choices READ choices CONSTANT FINAL)
Q_PROPERTY(QQuickItem *main READ main NOTIFY mainChanged FINAL)
Q_PROPERTY(QQuickItem *reply READ reply NOTIFY replyChanged FINAL)
Q_PROPERTY(QString eventId READ eventId WRITE setEventId NOTIFY eventIdChanged REQUIRED FINAL)
Q_PROPERTY(QString replyTo READ replyTo WRITE setReplyTo NOTIFY replyToChanged REQUIRED FINAL)
Q_PROPERTY(TimelineModel *room READ room WRITE setRoom NOTIFY roomChanged REQUIRED FINAL)
Q_PROPERTY(bool sameWidth READ sameWidth WRITE setSameWidth NOTIFY sameWidthChanged)
Q_PROPERTY(int maxWidth READ maxWidth WRITE setMaxWidth NOTIFY maxWidthChanged)
Q_PROPERTY(int replyInset READ replyInset WRITE setReplyInset NOTIFY replyInsetChanged)
Q_PROPERTY(int mainInset READ mainInset WRITE setMainInset NOTIFY mainInsetChanged)
public:
QQmlListProperty<EventDelegateChoice> choices();
[[nodiscard]] QQuickItem *main() const
{
return qobject_cast<QQuickItem *>(eventIncubator.object());
}
[[nodiscard]] QQuickItem *reply() const
{
return qobject_cast<QQuickItem *>(replyIncubator.object());
}
bool sameWidth() const { return sameWidth_; }
void setSameWidth(bool width)
{
sameWidth_ = width;
emit sameWidthChanged();
}
int maxWidth() const { return maxWidth_; }
void setMaxWidth(int width)
{
maxWidth_ = width;
emit maxWidthChanged();
polish();
}
int replyInset() const { return replyInset_; }
void setReplyInset(int width)
{
replyInset_ = width;
emit replyInsetChanged();
polish();
}
int mainInset() const { return mainInset_; }
void setMainInset(int width)
{
mainInset_ = width;
emit mainInsetChanged();
polish();
}
void setRoom(TimelineModel *m)
{
if (m != room_) {
room_ = m;
emit roomChanged();
if (isComponentComplete()) {
eventIncubator.reset(eventId_);
replyIncubator.reset(replyId);
}
}
}
[[nodiscard]] TimelineModel *room() { return room_; }
void setEventId(QString idx)
{
eventId_ = idx;
emit eventIdChanged();
if (isComponentComplete())
eventIncubator.reset(eventId_);
}
[[nodiscard]] QString eventId() const { return eventId_; }
void setReplyTo(QString id)
{
replyId = id;
emit replyToChanged();
if (isComponentComplete())
replyIncubator.reset(replyId);
}
[[nodiscard]] QString replyTo() const { return replyId; }
void componentComplete() override;
static EventDelegateChooserAttachedType *qmlAttachedProperties(QObject *object)
{
return new EventDelegateChooserAttachedType(object);
}
void updatePolish() override;
signals:
void mainChanged();
void replyChanged();
void roomChanged();
void eventIdChanged();
void replyToChanged();
void sameWidthChanged();
void maxWidthChanged();
void replyInsetChanged();
void mainInsetChanged();
private:
struct DelegateIncubator final : public QQmlIncubator
{
DelegateIncubator(EventDelegateChooser &parent, bool forReply)
: QQmlIncubator(QQmlIncubator::AsynchronousIfNested)
, chooser(parent)
, forReply(forReply)
{
}
void setInitialState(QObject *object) override;
void statusChanged(QQmlIncubator::Status status) override;
void reset(QString id);
EventDelegateChooser &chooser;
bool forReply;
QString currentId;
QString instantiatedId;
int instantiatedRole = -1;
QAbstractItemModel *instantiatedModel = nullptr;
int oldType = -1;
};
QVariant roleValue_;
QList<EventDelegateChoice *> choices_;
DelegateIncubator eventIncubator{*this, false};
DelegateIncubator replyIncubator{*this, true};
TimelineModel *room_{nullptr};
QString eventId_;
QString replyId;
bool sameWidth_ = false;
int maxWidth_ = 400;
int replyInset_ = 0;
int mainInset_ = 0;
static void appendChoice(QQmlListProperty<EventDelegateChoice> *, EventDelegateChoice *);
static qsizetype choiceCount(QQmlListProperty<EventDelegateChoice> *);
static EventDelegateChoice *choice(QQmlListProperty<EventDelegateChoice> *, qsizetype index);
static void clearChoices(QQmlListProperty<EventDelegateChoice> *);
};
|