Incubate delegates asynchronously

This commit is contained in:
Nicolas Werner 2019-10-25 13:20:05 +02:00
parent c8f97216fa
commit 3d6f502bcc
3 changed files with 42 additions and 10 deletions

View file

@ -29,7 +29,7 @@ Rectangle {
ListView {
id: chat
cacheBuffer: parent.height
cacheBuffer: 2000
visible: timelineManager.timeline != null
anchors.fill: parent

View file

@ -95,17 +95,11 @@ DelegateChooser::recalcChild()
auto choiceValue = choice->roleValue();
if (!roleValue_.isValid() || !choiceValue.isValid() || choiceValue == roleValue_) {
if (child) {
// delete child;
child->setParentItem(nullptr);
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());
choice->delegate()->create(incubator, QQmlEngine::contextForObject(this));
return;
}
}
@ -118,3 +112,28 @@ DelegateChooser::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!");
delete chooser.child;
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());
}
}

View file

@ -5,6 +5,7 @@
#pragma once
#include <QQmlComponent>
#include <QQmlIncubator>
#include <QQmlListProperty>
#include <QQuickItem>
#include <QtCore/QObject>
@ -59,9 +60,21 @@ signals:
void roleValueChanged();
private:
struct DelegateIncubator : public QQmlIncubator
{
DelegateIncubator(DelegateChooser &parent)
: QQmlIncubator(QQmlIncubator::AsynchronousIfNested)
, chooser(parent)
{}
void statusChanged(QQmlIncubator::Status status) override;
DelegateChooser &chooser;
};
QVariant roleValue_;
QList<DelegateChoice *> choices_;
QQuickItem *child;
QQuickItem *child = nullptr;
DelegateIncubator incubator{*this};
static void appendChoice(QQmlListProperty<DelegateChoice> *, DelegateChoice *);
static int choiceCount(QQmlListProperty<DelegateChoice> *);