summary refs log tree commit diff
path: root/src/timeline/DelegateChooser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/timeline/DelegateChooser.cpp')
-rw-r--r--src/timeline/DelegateChooser.cpp138
1 files changed, 138 insertions, 0 deletions
diff --git a/src/timeline/DelegateChooser.cpp b/src/timeline/DelegateChooser.cpp
new file mode 100644
index 00000000..632a2a64
--- /dev/null
+++ b/src/timeline/DelegateChooser.cpp
@@ -0,0 +1,138 @@
+#include "DelegateChooser.h"
+
+#include "Logging.h"
+
+// uses private API, which moved between versions
+#include <QQmlEngine>
+#include <QtGlobal>
+
+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);
+}
+
+void
+DelegateChooser::appendChoice(QQmlListProperty<DelegateChoice> *p, DelegateChoice *c)
+{
+        DelegateChooser *dc = static_cast<DelegateChooser *>(p->object);
+        dc->choices_.append(c);
+}
+
+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_) {
+                        if (child) {
+                                child->setParentItem(nullptr);
+                                child = nullptr;
+                        }
+
+                        choice->delegate()->create(incubator, QQmlEngine::contextForObject(this));
+                        return;
+                }
+        }
+}
+
+void
+DelegateChooser::componentComplete()
+{
+        QQuickItem::componentComplete();
+        recalcChild();
+}
+
+void
+DelegateChooser::DelegateIncubator::statusChanged(QQmlIncubator::Status status)
+{
+        if (status == QQmlIncubator::Ready) {
+                chooser.child = dynamic_cast<QQuickItem *>(object());
+                if (chooser.child == nullptr) {
+                        nhlog::ui()->error("Delegate has to be derived of Item!");
+                        return;
+                }
+
+                chooser.child->setParentItem(&chooser);
+                connect(chooser.child, &QQuickItem::heightChanged, &chooser, [this]() {
+                        chooser.setHeight(chooser.child->height());
+                });
+                chooser.setHeight(chooser.child->height());
+                QQmlEngine::setObjectOwnership(chooser.child,
+                                               QQmlEngine::ObjectOwnership::JavaScriptOwnership);
+
+        } else if (status == QQmlIncubator::Error) {
+                for (const auto &e : errors())
+                        nhlog::ui()->error("Error instantiating delegate: {}",
+                                           e.toString().toStdString());
+        }
+}