Compare commits
2 commits
8e25c1cee0
...
4eb5dc5593
Author | SHA1 | Date | |
---|---|---|---|
4eb5dc5593 | |||
f09f591e6a |
4 changed files with 94 additions and 15 deletions
|
@ -7,6 +7,7 @@
|
|||
#include <qquickitem.h>
|
||||
#include <qregion.h>
|
||||
#include <qtmetamacros.h>
|
||||
#include <qtypes.h>
|
||||
|
||||
PendingRegion::PendingRegion(QObject* parent): QObject(parent) {
|
||||
QObject::connect(this, &PendingRegion::shapeChanged, this, &PendingRegion::changed);
|
||||
|
@ -27,6 +28,7 @@ void PendingRegion::setItem(QQuickItem* item) {
|
|||
this->mItem = item;
|
||||
|
||||
if (item != nullptr) {
|
||||
QObject::connect(this->mItem, &QObject::destroyed, this, &PendingRegion::onItemDestroyed);
|
||||
QObject::connect(this->mItem, &QQuickItem::xChanged, this, &PendingRegion::itemChanged);
|
||||
QObject::connect(this->mItem, &QQuickItem::yChanged, this, &PendingRegion::itemChanged);
|
||||
QObject::connect(this->mItem, &QQuickItem::widthChanged, this, &PendingRegion::itemChanged);
|
||||
|
@ -38,16 +40,18 @@ void PendingRegion::setItem(QQuickItem* item) {
|
|||
|
||||
void PendingRegion::onItemDestroyed() { this->mItem = nullptr; }
|
||||
|
||||
void PendingRegion::onChildDestroyed() { this->mRegions.removeAll(this->sender()); }
|
||||
|
||||
QQmlListProperty<PendingRegion> PendingRegion::regions() {
|
||||
return QQmlListProperty<PendingRegion>(
|
||||
this,
|
||||
nullptr,
|
||||
PendingRegion::regionsAppend,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr
|
||||
&PendingRegion::regionsAppend,
|
||||
&PendingRegion::regionsCount,
|
||||
&PendingRegion::regionAt,
|
||||
&PendingRegion::regionsClear,
|
||||
&PendingRegion::regionsReplace,
|
||||
&PendingRegion::regionsRemoveLast
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -103,9 +107,54 @@ QRegion PendingRegion::applyTo(QRegion& region) const {
|
|||
|
||||
void PendingRegion::regionsAppend(QQmlListProperty<PendingRegion>* prop, PendingRegion* region) {
|
||||
auto* self = static_cast<PendingRegion*>(prop->object); // NOLINT
|
||||
region->setParent(self);
|
||||
|
||||
QObject::connect(region, &QObject::destroyed, self, &PendingRegion::onChildDestroyed);
|
||||
QObject::connect(region, &PendingRegion::changed, self, &PendingRegion::childrenChanged);
|
||||
|
||||
self->mRegions.append(region);
|
||||
|
||||
QObject::connect(region, &PendingRegion::changed, self, &PendingRegion::childrenChanged);
|
||||
emit self->childrenChanged();
|
||||
}
|
||||
|
||||
PendingRegion* PendingRegion::regionAt(QQmlListProperty<PendingRegion>* prop, qsizetype i) {
|
||||
return static_cast<PendingRegion*>(prop->object)->mRegions.at(i); // NOLINT
|
||||
}
|
||||
|
||||
void PendingRegion::regionsClear(QQmlListProperty<PendingRegion>* prop) {
|
||||
auto* self = static_cast<PendingRegion*>(prop->object); // NOLINT
|
||||
|
||||
for (auto* region: self->mRegions) {
|
||||
QObject::disconnect(region, nullptr, self, nullptr);
|
||||
}
|
||||
|
||||
self->mRegions.clear(); // NOLINT
|
||||
emit self->childrenChanged();
|
||||
}
|
||||
|
||||
qsizetype PendingRegion::regionsCount(QQmlListProperty<PendingRegion>* prop) {
|
||||
return static_cast<PendingRegion*>(prop->object)->mRegions.length(); // NOLINT
|
||||
}
|
||||
|
||||
void PendingRegion::regionsRemoveLast(QQmlListProperty<PendingRegion>* prop) {
|
||||
auto* self = static_cast<PendingRegion*>(prop->object); // NOLINT
|
||||
|
||||
auto* last = self->mRegions.last();
|
||||
if (last != nullptr) QObject::disconnect(last, nullptr, self, nullptr);
|
||||
|
||||
self->mRegions.removeLast();
|
||||
emit self->childrenChanged();
|
||||
}
|
||||
|
||||
void PendingRegion::regionsReplace(
|
||||
QQmlListProperty<PendingRegion>* prop,
|
||||
qsizetype i,
|
||||
PendingRegion* region
|
||||
) {
|
||||
auto* self = static_cast<PendingRegion*>(prop->object); // NOLINT
|
||||
|
||||
auto* old = self->mRegions.at(i);
|
||||
if (old != nullptr) QObject::disconnect(old, nullptr, self, nullptr);
|
||||
|
||||
self->mRegions.replace(i, region);
|
||||
emit self->childrenChanged();
|
||||
}
|
||||
|
|
|
@ -110,9 +110,16 @@ signals:
|
|||
|
||||
private slots:
|
||||
void onItemDestroyed();
|
||||
void onChildDestroyed();
|
||||
|
||||
private:
|
||||
static void regionsAppend(QQmlListProperty<PendingRegion>* prop, PendingRegion* region);
|
||||
static PendingRegion* regionAt(QQmlListProperty<PendingRegion>* prop, qsizetype i);
|
||||
static void regionsClear(QQmlListProperty<PendingRegion>* prop);
|
||||
static qsizetype regionsCount(QQmlListProperty<PendingRegion>* prop);
|
||||
static void regionsRemoveLast(QQmlListProperty<PendingRegion>* prop);
|
||||
static void
|
||||
regionsReplace(QQmlListProperty<PendingRegion>* prop, qsizetype i, PendingRegion* region);
|
||||
|
||||
QQuickItem* mItem = nullptr;
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <qqmlengine.h>
|
||||
#include <qqmllist.h>
|
||||
#include <qtmetamacros.h>
|
||||
#include <qtypes.h>
|
||||
#include <qvariant.h>
|
||||
|
||||
#include "reload.hpp"
|
||||
|
@ -15,10 +16,10 @@
|
|||
void Variants::onReload(QObject* oldInstance) {
|
||||
auto* old = qobject_cast<Variants*>(oldInstance);
|
||||
|
||||
for (auto& [variant, instanceObj]: this->instances.values) {
|
||||
for (auto& [variant, instanceObj]: this->mInstances.values) {
|
||||
QObject* oldInstance = nullptr;
|
||||
if (old != nullptr) {
|
||||
auto& values = old->instances.values;
|
||||
auto& values = old->mInstances.values;
|
||||
|
||||
if (variant.canConvert<QVariantMap>()) {
|
||||
auto variantMap = variant.value<QVariantMap>();
|
||||
|
@ -96,6 +97,19 @@ void Variants::setModel(const QVariant& model) {
|
|||
|
||||
this->updateVariants();
|
||||
emit this->modelChanged();
|
||||
emit this->instancesChanged();
|
||||
}
|
||||
|
||||
QQmlListProperty<QObject> Variants::instances() {
|
||||
return QQmlListProperty<QObject>(this, nullptr, &Variants::instanceCount, &Variants::instanceAt);
|
||||
}
|
||||
|
||||
qsizetype Variants::instanceCount(QQmlListProperty<QObject>* prop) {
|
||||
return static_cast<Variants*>(prop->object)->mInstances.values.length(); // NOLINT
|
||||
}
|
||||
|
||||
QObject* Variants::instanceAt(QQmlListProperty<QObject>* prop, qsizetype i) {
|
||||
return static_cast<Variants*>(prop->object)->mInstances.values.at(i).second; // NOLINT
|
||||
}
|
||||
|
||||
void Variants::componentComplete() {
|
||||
|
@ -110,12 +124,12 @@ void Variants::updateVariants() {
|
|||
}
|
||||
|
||||
// clean up removed entries
|
||||
for (auto iter = this->instances.values.begin(); iter < this->instances.values.end();) {
|
||||
for (auto iter = this->mInstances.values.begin(); iter < this->mInstances.values.end();) {
|
||||
if (this->mModel.contains(iter->first)) {
|
||||
iter++;
|
||||
} else {
|
||||
iter->second->deleteLater();
|
||||
iter = this->instances.values.erase(iter);
|
||||
iter = this->mInstances.values.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,7 +144,7 @@ void Variants::updateVariants() {
|
|||
}
|
||||
|
||||
{
|
||||
if (this->instances.contains(variant)) {
|
||||
if (this->mInstances.contains(variant)) {
|
||||
continue; // we dont need to recreate this one
|
||||
}
|
||||
|
||||
|
@ -151,7 +165,7 @@ void Variants::updateVariants() {
|
|||
QQmlEngine::setObjectOwnership(instance, QQmlEngine::CppOwnership);
|
||||
|
||||
instance->setParent(this);
|
||||
this->instances.insert(variant, instance);
|
||||
this->mInstances.insert(variant, instance);
|
||||
|
||||
if (this->loaded) {
|
||||
if (auto* reloadable = qobject_cast<Reloadable*>(instance)) reloadable->onReload(nullptr);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <qmap.h>
|
||||
#include <qobject.h>
|
||||
#include <qqmlcomponent.h>
|
||||
#include <qqmllist.h>
|
||||
#include <qqmlparserstatus.h>
|
||||
#include <qtmetamacros.h>
|
||||
#include <qvariant.h>
|
||||
|
@ -52,6 +53,8 @@ class Variants: public Reloadable {
|
|||
/// Each set creates an instance of the component, which are updated when the input sets update.
|
||||
QSDOC_PROPERTY_OVERRIDE(QList<QVariant> model READ model WRITE setModel NOTIFY modelChanged);
|
||||
QSDOC_HIDE Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged);
|
||||
/// Current instances of the delegate.
|
||||
Q_PROPERTY(QQmlListProperty<QObject> instances READ instances NOTIFY instancesChanged);
|
||||
Q_CLASSINFO("DefaultProperty", "delegate");
|
||||
QML_ELEMENT;
|
||||
|
||||
|
@ -64,14 +67,20 @@ public:
|
|||
[[nodiscard]] QVariant model() const;
|
||||
void setModel(const QVariant& model);
|
||||
|
||||
QQmlListProperty<QObject> instances();
|
||||
|
||||
signals:
|
||||
void modelChanged();
|
||||
void instancesChanged();
|
||||
|
||||
private:
|
||||
static qsizetype instanceCount(QQmlListProperty<QObject>* prop);
|
||||
static QObject* instanceAt(QQmlListProperty<QObject>* prop, qsizetype i);
|
||||
|
||||
void updateVariants();
|
||||
|
||||
QQmlComponent* mDelegate = nullptr;
|
||||
QVariantList mModel;
|
||||
AwfulMap<QVariant, QObject*> instances;
|
||||
AwfulMap<QVariant, QObject*> mInstances;
|
||||
bool loaded = false;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue