diff options
Diffstat (limited to 'src/timeline/DelegateChooser.cpp')
-rw-r--r-- | src/timeline/DelegateChooser.cpp | 138 |
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()); + } +} |