From 0c9c5be8dd856b8ed3c1d37be24d96f9b4171c20 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Sat, 12 Jul 2025 20:00:13 -0700 Subject: [PATCH] core/region: use QList over QQmlListProperty for child regions --- src/core/region.cpp | 98 ++++++++++++++------------------------------- src/core/region.hpp | 14 ++----- 2 files changed, 33 insertions(+), 79 deletions(-) diff --git a/src/core/region.cpp b/src/core/region.cpp index 439cfbd2..e36ed7d7 100644 --- a/src/core/region.cpp +++ b/src/core/region.cpp @@ -1,13 +1,13 @@ #include "region.hpp" #include +#include #include #include #include #include #include #include -#include #include PendingRegion::PendingRegion(QObject* parent): QObject(parent) { @@ -19,9 +19,12 @@ PendingRegion::PendingRegion(QObject* parent): QObject(parent) { QObject::connect(this, &PendingRegion::widthChanged, this, &PendingRegion::changed); QObject::connect(this, &PendingRegion::heightChanged, this, &PendingRegion::changed); QObject::connect(this, &PendingRegion::childrenChanged, this, &PendingRegion::changed); + QObject::connect(this, &PendingRegion::regionsChanged, this, &PendingRegion::childrenChanged); } void PendingRegion::setItem(QQuickItem* item) { + if (item == this->mItem) return; + if (this->mItem != nullptr) { QObject::disconnect(this->mItem, nullptr, this, nullptr); } @@ -39,21 +42,33 @@ void PendingRegion::setItem(QQuickItem* item) { emit this->itemChanged(); } -void PendingRegion::onItemDestroyed() { this->mItem = nullptr; } +void PendingRegion::onItemDestroyed() { + this->mItem = nullptr; + emit this->itemChanged(); +} -void PendingRegion::onChildDestroyed() { this->mRegions.removeAll(this->sender()); } +void PendingRegion::onChildDestroyed() { + this->mRegions.removeAll(this->sender()); + emit this->regionsChanged(); +} -QQmlListProperty PendingRegion::regions() { - return QQmlListProperty( - this, - nullptr, - &PendingRegion::regionsAppend, - &PendingRegion::regionsCount, - &PendingRegion::regionAt, - &PendingRegion::regionsClear, - &PendingRegion::regionsReplace, - &PendingRegion::regionsRemoveLast - ); +const QList& PendingRegion::regions() const { return this->mRegions; } + +void PendingRegion::setRegions(const QList& regions) { + if (regions == this->mRegions) return; + + for (auto* region: this->mRegions) { + QObject::disconnect(region, nullptr, this, nullptr); + } + + this->mRegions = regions; + + for (auto* region: regions) { + QObject::connect(region, &QObject::destroyed, this, &PendingRegion::onChildDestroyed); + QObject::connect(region, &PendingRegion::changed, this, &PendingRegion::childrenChanged); + } + + emit this->regionsChanged(); } bool PendingRegion::empty() const { @@ -115,58 +130,3 @@ QRegion PendingRegion::applyTo(const QRect& rect) const { return this->applyTo(baseRegion); } } - -void PendingRegion::regionsAppend(QQmlListProperty* prop, PendingRegion* region) { - auto* self = static_cast(prop->object); // NOLINT - if (!region) return; - - QObject::connect(region, &QObject::destroyed, self, &PendingRegion::onChildDestroyed); - QObject::connect(region, &PendingRegion::changed, self, &PendingRegion::childrenChanged); - - self->mRegions.append(region); - - emit self->childrenChanged(); -} - -PendingRegion* PendingRegion::regionAt(QQmlListProperty* prop, qsizetype i) { - return static_cast(prop->object)->mRegions.at(i); // NOLINT -} - -void PendingRegion::regionsClear(QQmlListProperty* prop) { - auto* self = static_cast(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* prop) { - return static_cast(prop->object)->mRegions.length(); // NOLINT -} - -void PendingRegion::regionsRemoveLast(QQmlListProperty* prop) { - auto* self = static_cast(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* prop, - qsizetype i, - PendingRegion* region -) { - auto* self = static_cast(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(); -} diff --git a/src/core/region.hpp b/src/core/region.hpp index 6637d7bd..0335abbf 100644 --- a/src/core/region.hpp +++ b/src/core/region.hpp @@ -82,7 +82,7 @@ class PendingRegion: public QObject { /// } /// } /// ``` - Q_PROPERTY(QQmlListProperty regions READ regions); + Q_PROPERTY(QList regions READ regions WRITE setRegions NOTIFY regionsChanged); Q_CLASSINFO("DefaultProperty", "regions"); QML_NAMED_ELEMENT(Region); @@ -91,7 +91,8 @@ public: void setItem(QQuickItem* item); - QQmlListProperty regions(); + [[nodiscard]] const QList& regions() const; + void setRegions(const QList& regions); [[nodiscard]] bool empty() const; [[nodiscard]] QRegion build() const; @@ -109,6 +110,7 @@ signals: void yChanged(); void widthChanged(); void heightChanged(); + void regionsChanged(); void childrenChanged(); /// Triggered when the region's geometry changes. @@ -122,14 +124,6 @@ private slots: void onChildDestroyed(); private: - static void regionsAppend(QQmlListProperty* prop, PendingRegion* region); - static PendingRegion* regionAt(QQmlListProperty* prop, qsizetype i); - static void regionsClear(QQmlListProperty* prop); - static qsizetype regionsCount(QQmlListProperty* prop); - static void regionsRemoveLast(QQmlListProperty* prop); - static void - regionsReplace(QQmlListProperty* prop, qsizetype i, PendingRegion* region); - QQuickItem* mItem = nullptr; qint32 mX = 0;