forked from mirror/nheko
The interface is taken from Qt/KDE, but the implementation is different, because the Qt implementation depends on some Qt internals.remotes/origin/0.7.0-dev
parent
cff46d97a8
commit
c37495fae2
@ -0,0 +1,52 @@ |
|||||||
|
import QtQuick 2.6 |
||||||
|
import Qt.labs.qmlmodels 1.0 |
||||||
|
import com.github.nheko 1.0 |
||||||
|
|
||||||
|
import "./delegates" |
||||||
|
|
||||||
|
DelegateChooser { |
||||||
|
role: "type" |
||||||
|
width: chat.width |
||||||
|
roleValue: model.type |
||||||
|
|
||||||
|
DelegateChoice { |
||||||
|
roleValue: MtxEvent.TextMessage |
||||||
|
TimelineRow { view: chat; TextMessage { id: kid } } |
||||||
|
} |
||||||
|
DelegateChoice { |
||||||
|
roleValue: MtxEvent.NoticeMessage |
||||||
|
TimelineRow { view: chat; NoticeMessage { id: kid } } |
||||||
|
} |
||||||
|
DelegateChoice { |
||||||
|
roleValue: MtxEvent.EmoteMessage |
||||||
|
TimelineRow { view: chat; TextMessage { id: kid } } |
||||||
|
} |
||||||
|
DelegateChoice { |
||||||
|
roleValue: MtxEvent.ImageMessage |
||||||
|
TimelineRow { view: chat; ImageMessage { id: kid } } |
||||||
|
} |
||||||
|
DelegateChoice { |
||||||
|
roleValue: MtxEvent.Sticker |
||||||
|
TimelineRow { view: chat; ImageMessage { id: kid } } |
||||||
|
} |
||||||
|
DelegateChoice { |
||||||
|
roleValue: MtxEvent.FileMessage |
||||||
|
TimelineRow { view: chat; FileMessage { id: kid } } |
||||||
|
} |
||||||
|
DelegateChoice { |
||||||
|
roleValue: MtxEvent.VideoMessage |
||||||
|
TimelineRow { view: chat; PlayableMediaMessage { id: kid } } |
||||||
|
} |
||||||
|
DelegateChoice { |
||||||
|
roleValue: MtxEvent.AudioMessage |
||||||
|
TimelineRow { view: chat; PlayableMediaMessage { id: kid } } |
||||||
|
} |
||||||
|
DelegateChoice { |
||||||
|
roleValue: MtxEvent.Redacted |
||||||
|
TimelineRow { view: chat; Redacted { id: kid } } |
||||||
|
} |
||||||
|
DelegateChoice { |
||||||
|
//roleValue: MtxEvent.Redacted |
||||||
|
TimelineRow { view: chat; Placeholder { id: kid } } |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,160 @@ |
|||||||
|
#include "DelegateChooser.h" |
||||||
|
|
||||||
|
#include "Logging.h" |
||||||
|
|
||||||
|
// uses private API, which moved between versions
|
||||||
|
#include <QQmlEngine> |
||||||
|
#include <QtGlobal> |
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) |
||||||
|
#include <QtQmlModels/private/qqmladaptormodel_p.h> |
||||||
|
#else |
||||||
|
#include <QtQml/private/qqmladaptormodel_p.h> |
||||||
|
#endif |
||||||
|
|
||||||
|
QQmlComponent * |
||||||
|
DelegateChoice::delegate() const |
||||||
|
{ |
||||||
|
return delegate_; |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
DelegateChoice::setDelegate(QQmlComponent *delegate) |
||||||
|
{ |
||||||
|
if (delegate != delegate_) { |
||||||
|
delegate_ = delegate; |
||||||
|
emit delegateChanged(); |
||||||
|
emit changed(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
QVariant |
||||||
|
DelegateChoice::roleValue() const |
||||||
|
{ |
||||||
|
return roleValue_; |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
DelegateChoice::setRoleValue(const QVariant &value) |
||||||
|
{ |
||||||
|
if (value != roleValue_) { |
||||||
|
roleValue_ = value; |
||||||
|
emit roleValueChanged(); |
||||||
|
emit changed(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
QVariant |
||||||
|
DelegateChooser::roleValue() const |
||||||
|
{ |
||||||
|
return roleValue_; |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
DelegateChooser::setRoleValue(const QVariant &value) |
||||||
|
{ |
||||||
|
if (value != roleValue_) { |
||||||
|
roleValue_ = value; |
||||||
|
recalcChild(); |
||||||
|
emit roleValueChanged(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
QQmlListProperty<DelegateChoice> |
||||||
|
DelegateChooser::choices() |
||||||
|
{ |
||||||
|
return QQmlListProperty<DelegateChoice>(this, |
||||||
|
this, |
||||||
|
&DelegateChooser::appendChoice, |
||||||
|
&DelegateChooser::choiceCount, |
||||||
|
&DelegateChooser::choice, |
||||||
|
&DelegateChooser::clearChoices); |
||||||
|
} |
||||||
|
|
||||||
|
QString |
||||||
|
DelegateChooser::role() const |
||||||
|
{ |
||||||
|
return role_; |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
DelegateChooser::setRole(const QString &role) |
||||||
|
{ |
||||||
|
if (role != role_) { |
||||||
|
role_ = role; |
||||||
|
emit roleChanged(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
QQmlComponent * |
||||||
|
DelegateChooser::delegate(QQmlAdaptorModel *adaptorModel, int row, int column) const |
||||||
|
{ |
||||||
|
auto value = adaptorModel->value(adaptorModel->indexAt(row, column), role_); |
||||||
|
|
||||||
|
for (const auto choice : choices_) { |
||||||
|
auto choiceValue = choice->roleValue(); |
||||||
|
if (!value.isValid() || choiceValue == value) { |
||||||
|
nhlog::ui()->debug("Returned delegate for {}", role_.toStdString()); |
||||||
|
return choice->delegate(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
nhlog::ui()->debug("Returned null delegate"); |
||||||
|
return nullptr; |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
DelegateChooser::appendChoice(QQmlListProperty<DelegateChoice> *p, DelegateChoice *c) |
||||||
|
{ |
||||||
|
DelegateChooser *dc = static_cast<DelegateChooser *>(p->object); |
||||||
|
dc->choices_.append(c); |
||||||
|
// dc->recalcChild();
|
||||||
|
} |
||||||
|
|
||||||
|
int |
||||||
|
DelegateChooser::choiceCount(QQmlListProperty<DelegateChoice> *p) |
||||||
|
{ |
||||||
|
return static_cast<DelegateChooser *>(p->object)->choices_.count(); |
||||||
|
} |
||||||
|
DelegateChoice * |
||||||
|
DelegateChooser::choice(QQmlListProperty<DelegateChoice> *p, int index) |
||||||
|
{ |
||||||
|
return static_cast<DelegateChooser *>(p->object)->choices_.at(index); |
||||||
|
} |
||||||
|
void |
||||||
|
DelegateChooser::clearChoices(QQmlListProperty<DelegateChoice> *p) |
||||||
|
{ |
||||||
|
static_cast<DelegateChooser *>(p->object)->choices_.clear(); |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
DelegateChooser::recalcChild() |
||||||
|
{ |
||||||
|
for (const auto choice : choices_) { |
||||||
|
auto choiceValue = choice->roleValue(); |
||||||
|
if (!roleValue_.isValid() || !choiceValue.isValid() || choiceValue == roleValue_) { |
||||||
|
nhlog::ui()->debug("Returned delegate for {}", role_.toStdString()); |
||||||
|
|
||||||
|
if (child) { |
||||||
|
// delete child;
|
||||||
|
child = nullptr; |
||||||
|
} |
||||||
|
|
||||||
|
child = dynamic_cast<QQuickItem *>( |
||||||
|
choice->delegate()->create(QQmlEngine::contextForObject(this))); |
||||||
|
child->setParentItem(this); |
||||||
|
connect(this->child, &QQuickItem::heightChanged, this, [this]() { |
||||||
|
this->setHeight(this->child->height()); |
||||||
|
}); |
||||||
|
this->setHeight(this->child->height()); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
DelegateChooser::componentComplete() |
||||||
|
{ |
||||||
|
QQuickItem::componentComplete(); |
||||||
|
recalcChild(); |
||||||
|
} |
||||||
|
|
@ -0,0 +1,78 @@ |
|||||||
|
// A DelegateChooser like the one, that was added to Qt5.12 (in labs), but compatible with older Qt versions
|
||||||
|
// see KDE/kquickitemviews
|
||||||
|
// see qtdeclarative/qqmldelagatecomponent
|
||||||
|
|
||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <QQmlComponent> |
||||||
|
#include <QQmlListProperty> |
||||||
|
#include <QQuickItem> |
||||||
|
#include <QtCore/QObject> |
||||||
|
#include <QtCore/QVariant> |
||||||
|
|
||||||
|
class QQmlAdaptorModel; |
||||||
|
|
||||||
|
class DelegateChoice : public QObject |
||||||
|
{ |
||||||
|
Q_OBJECT |
||||||
|
Q_CLASSINFO("DefaultProperty", "delegate") |
||||||
|
|
||||||
|
public: |
||||||
|
Q_PROPERTY(QVariant roleValue READ roleValue WRITE setRoleValue NOTIFY roleValueChanged) |
||||||
|
Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) |
||||||
|
|
||||||
|
QQmlComponent *delegate() const; |
||||||
|
void setDelegate(QQmlComponent *delegate); |
||||||
|
|
||||||
|
QVariant roleValue() const; |
||||||
|
void setRoleValue(const QVariant &value); |
||||||
|
|
||||||
|
signals: |
||||||
|
void delegateChanged(); |
||||||
|
void roleValueChanged(); |
||||||
|
void changed(); |
||||||
|
|
||||||
|
private: |
||||||
|
QVariant roleValue_; |
||||||
|
QQmlComponent *delegate_ = nullptr; |
||||||
|
}; |
||||||
|
|
||||||
|
class DelegateChooser : public QQuickItem |
||||||
|
{ |
||||||
|
Q_OBJECT |
||||||
|
Q_CLASSINFO("DefaultProperty", "choices") |
||||||
|
|
||||||
|
public: |
||||||
|
Q_PROPERTY(QQmlListProperty<DelegateChoice> choices READ choices CONSTANT) |
||||||
|
Q_PROPERTY(QString role READ role WRITE setRole NOTIFY roleChanged) |
||||||
|
Q_PROPERTY(QVariant roleValue READ roleValue WRITE setRoleValue NOTIFY roleValueChanged) |
||||||
|
|
||||||
|
QQmlListProperty<DelegateChoice> choices(); |
||||||
|
|
||||||
|
QString role() const; |
||||||
|
void setRole(const QString &role); |
||||||
|
|
||||||
|
QVariant roleValue() const; |
||||||
|
void setRoleValue(const QVariant &value); |
||||||
|
|
||||||
|
QQmlComponent *delegate(QQmlAdaptorModel *adaptorModel, int row, int column = 0) const; |
||||||
|
|
||||||
|
void recalcChild(); |
||||||
|
void componentComplete() override; |
||||||
|
|
||||||
|
signals: |
||||||
|
void roleChanged(); |
||||||
|
void roleValueChanged(); |
||||||
|
|
||||||
|
private: |
||||||
|
QString role_; |
||||||
|
QVariant roleValue_; |
||||||
|
QList<DelegateChoice *> choices_; |
||||||
|
QQuickItem *child; |
||||||
|
|
||||||
|
static void appendChoice(QQmlListProperty<DelegateChoice> *, DelegateChoice *); |
||||||
|
static int choiceCount(QQmlListProperty<DelegateChoice> *); |
||||||
|
static DelegateChoice *choice(QQmlListProperty<DelegateChoice> *, int index); |
||||||
|
static void clearChoices(QQmlListProperty<DelegateChoice> *); |
||||||
|
}; |
||||||
|
|
Loading…
Reference in new issue