summary refs log tree commit diff
path: root/src/timeline/EventDelegateChooser.h
diff options
context:
space:
mode:
authorNicolas Werner <nicolas.werner@hotmail.de>2023-06-22 19:54:17 +0200
committerNicolas Werner <nicolas.werner@hotmail.de>2023-08-25 19:03:10 +0200
commit4d8b8c3b816528ece6274bac97d30905f77aabfb (patch)
tree44948aeab0dbab56b46a7205edcfb3003ccad3b8 /src/timeline/EventDelegateChooser.h
parentMerge pull request #1536 from Nheko-Reborn/issue1440 (diff)
downloadnheko-4d8b8c3b816528ece6274bac97d30905f77aabfb.tar.xz
Create an EventDelegateChooser
Diffstat (limited to 'src/timeline/EventDelegateChooser.h')
-rw-r--r--src/timeline/EventDelegateChooser.h136
1 files changed, 136 insertions, 0 deletions
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 <QAbstractItemModel>
+#include <QQmlComponent>
+#include <QQmlIncubator>
+#include <QQmlListProperty>
+#include <QQuickItem>
+#include <QtCore/QObject>
+#include <QtCore/QVariant>
+
+#include "TimelineModel.h"
+
+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")
+
+public:
+    Q_PROPERTY(QQmlListProperty<EventDelegateChoice> 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<EventDelegateChoice> choices();
+
+    [[nodiscard]] QQuickItem *main() const
+    {
+        return qobject_cast<QQuickItem *>(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<EventDelegateChoice *> choices_;
+    DelegateIncubator eventIncubator{*this, false};
+    DelegateIncubator replyIncubator{*this, true};
+    TimelineModel *room_{nullptr};
+    QString eventId_;
+    QString replyId;
+
+    static void appendChoice(QQmlListProperty<EventDelegateChoice> *, EventDelegateChoice *);
+    static qsizetype choiceCount(QQmlListProperty<EventDelegateChoice> *);
+    static EventDelegateChoice *choice(QQmlListProperty<EventDelegateChoice> *, qsizetype index);
+    static void clearChoices(QQmlListProperty<EventDelegateChoice> *);
+};