From 4d8b8c3b816528ece6274bac97d30905f77aabfb Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Thu, 22 Jun 2023 19:54:17 +0200 Subject: Create an EventDelegateChooser --- src/timeline/EventDelegateChooser.h | 136 ++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 src/timeline/EventDelegateChooser.h (limited to 'src/timeline/EventDelegateChooser.h') diff --git a/src/timeline/EventDelegateChooser.h b/src/timeline/EventDelegateChooser.h new file mode 100644 index 00000000..ce22ca3a --- /dev/null +++ b/src/timeline/EventDelegateChooser.h @@ -0,0 +1,136 @@ +// SPDX-FileCopyrightText: Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +// 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 +#include +#include +#include +#include +#include +#include + +#include "TimelineModel.h" + +class EventDelegateChoice : public QObject +{ + Q_OBJECT + QML_ELEMENT + Q_CLASSINFO("DefaultProperty", "delegate") + +public: + Q_PROPERTY(QList 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 roleValues() const; + void setRoleValues(const QList &value); + +signals: + void delegateChanged(); + void roleValuesChanged(); + void changed(); + +private: + QList roleValues_; + QQmlComponent *delegate_ = nullptr; +}; + +class EventDelegateChooser : public QQuickItem +{ + Q_OBJECT + QML_ELEMENT + Q_CLASSINFO("DefaultProperty", "choices") + +public: + Q_PROPERTY(QQmlListProperty choices READ choices CONSTANT FINAL) + Q_PROPERTY(QQuickItem *main READ main NOTIFY mainChanged FINAL) + Q_PROPERTY(TimelineModel *room READ room WRITE setRoom NOTIFY roomChanged REQUIRED 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) + + QQmlListProperty choices(); + + [[nodiscard]] QQuickItem *main() const + { + return qobject_cast(eventIncubator.object()); + } + + void setRoom(TimelineModel *m) + { + if (m != room_) { + room_ = m; + eventIncubator.reset(eventId_); + replyIncubator.reset(replyId); + emit roomChanged(); + } + } + [[nodiscard]] TimelineModel *room() { return room_; } + + void setEventId(QString idx) + { + eventId_ = idx; + emit eventIdChanged(); + } + [[nodiscard]] QString eventId() const { return eventId_; } + void setReplyTo(QString id) + { + replyId = id; + emit replyToChanged(); + } + [[nodiscard]] QString replyTo() const { return replyId; } + + void componentComplete() override; + +signals: + void mainChanged(); + void replyChanged(); + void roomChanged(); + void eventIdChanged(); + void replyToChanged(); + +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; + }; + + QVariant roleValue_; + QList choices_; + DelegateIncubator eventIncubator{*this, false}; + DelegateIncubator replyIncubator{*this, true}; + TimelineModel *room_{nullptr}; + QString eventId_; + QString replyId; + + static void appendChoice(QQmlListProperty *, EventDelegateChoice *); + static qsizetype choiceCount(QQmlListProperty *); + static EventDelegateChoice *choice(QQmlListProperty *, qsizetype index); + static void clearChoices(QQmlListProperty *); +}; -- cgit 1.4.1