core/region: use QList over QQmlListProperty for child regions

This commit is contained in:
outfoxxed 2025-07-12 20:00:13 -07:00
parent 49a3752b9d
commit 0c9c5be8dd
Signed by untrusted user: outfoxxed
GPG key ID: 4C88A185FB89301E
2 changed files with 33 additions and 79 deletions

View file

@ -1,13 +1,13 @@
#include "region.hpp" #include "region.hpp"
#include <cmath> #include <cmath>
#include <qlist.h>
#include <qobject.h> #include <qobject.h>
#include <qpoint.h> #include <qpoint.h>
#include <qqmllist.h> #include <qqmllist.h>
#include <qquickitem.h> #include <qquickitem.h>
#include <qregion.h> #include <qregion.h>
#include <qtmetamacros.h> #include <qtmetamacros.h>
#include <qtypes.h>
#include <qvectornd.h> #include <qvectornd.h>
PendingRegion::PendingRegion(QObject* parent): QObject(parent) { 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::widthChanged, this, &PendingRegion::changed);
QObject::connect(this, &PendingRegion::heightChanged, this, &PendingRegion::changed); QObject::connect(this, &PendingRegion::heightChanged, this, &PendingRegion::changed);
QObject::connect(this, &PendingRegion::childrenChanged, this, &PendingRegion::changed); QObject::connect(this, &PendingRegion::childrenChanged, this, &PendingRegion::changed);
QObject::connect(this, &PendingRegion::regionsChanged, this, &PendingRegion::childrenChanged);
} }
void PendingRegion::setItem(QQuickItem* item) { void PendingRegion::setItem(QQuickItem* item) {
if (item == this->mItem) return;
if (this->mItem != nullptr) { if (this->mItem != nullptr) {
QObject::disconnect(this->mItem, nullptr, this, nullptr); QObject::disconnect(this->mItem, nullptr, this, nullptr);
} }
@ -39,21 +42,33 @@ void PendingRegion::setItem(QQuickItem* item) {
emit this->itemChanged(); 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> PendingRegion::regions() { const QList<PendingRegion*>& PendingRegion::regions() const { return this->mRegions; }
return QQmlListProperty<PendingRegion>(
this, void PendingRegion::setRegions(const QList<PendingRegion*>& regions) {
nullptr, if (regions == this->mRegions) return;
&PendingRegion::regionsAppend,
&PendingRegion::regionsCount, for (auto* region: this->mRegions) {
&PendingRegion::regionAt, QObject::disconnect(region, nullptr, this, nullptr);
&PendingRegion::regionsClear, }
&PendingRegion::regionsReplace,
&PendingRegion::regionsRemoveLast 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 { bool PendingRegion::empty() const {
@ -115,58 +130,3 @@ QRegion PendingRegion::applyTo(const QRect& rect) const {
return this->applyTo(baseRegion); return this->applyTo(baseRegion);
} }
} }
void PendingRegion::regionsAppend(QQmlListProperty<PendingRegion>* prop, PendingRegion* region) {
auto* self = static_cast<PendingRegion*>(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<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();
}

View file

@ -82,7 +82,7 @@ class PendingRegion: public QObject {
/// } /// }
/// } /// }
/// ``` /// ```
Q_PROPERTY(QQmlListProperty<PendingRegion> regions READ regions); Q_PROPERTY(QList<PendingRegion*> regions READ regions WRITE setRegions NOTIFY regionsChanged);
Q_CLASSINFO("DefaultProperty", "regions"); Q_CLASSINFO("DefaultProperty", "regions");
QML_NAMED_ELEMENT(Region); QML_NAMED_ELEMENT(Region);
@ -91,7 +91,8 @@ public:
void setItem(QQuickItem* item); void setItem(QQuickItem* item);
QQmlListProperty<PendingRegion> regions(); [[nodiscard]] const QList<PendingRegion*>& regions() const;
void setRegions(const QList<PendingRegion*>& regions);
[[nodiscard]] bool empty() const; [[nodiscard]] bool empty() const;
[[nodiscard]] QRegion build() const; [[nodiscard]] QRegion build() const;
@ -109,6 +110,7 @@ signals:
void yChanged(); void yChanged();
void widthChanged(); void widthChanged();
void heightChanged(); void heightChanged();
void regionsChanged();
void childrenChanged(); void childrenChanged();
/// Triggered when the region's geometry changes. /// Triggered when the region's geometry changes.
@ -122,14 +124,6 @@ private slots:
void onChildDestroyed(); void onChildDestroyed();
private: 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; QQuickItem* mItem = nullptr;
qint32 mX = 0; qint32 mX = 0;