forked from quickshell/quickshell
all: replace list properties with ObjectModels
This commit is contained in:
parent
6326f60ce2
commit
5016dbf0d4
|
@ -26,6 +26,7 @@ qt_add_library(quickshell-core STATIC
|
||||||
imageprovider.cpp
|
imageprovider.cpp
|
||||||
transformwatcher.cpp
|
transformwatcher.cpp
|
||||||
boundcomponent.cpp
|
boundcomponent.cpp
|
||||||
|
model.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set_source_files_properties(main.cpp PROPERTIES COMPILE_DEFINITIONS GIT_REVISION="${GIT_REVISION}")
|
set_source_files_properties(main.cpp PROPERTIES COMPILE_DEFINITIONS GIT_REVISION="${GIT_REVISION}")
|
||||||
|
|
|
@ -10,5 +10,8 @@
|
||||||
#define QSDOC_ELEMENT
|
#define QSDOC_ELEMENT
|
||||||
#define QSDOC_NAMED_ELEMENT(name)
|
#define QSDOC_NAMED_ELEMENT(name)
|
||||||
|
|
||||||
|
// change the cname used for this type
|
||||||
|
#define QSDOC_CNAME(name)
|
||||||
|
|
||||||
// overridden properties
|
// overridden properties
|
||||||
#define QSDOC_PROPERTY_OVERRIDE(...)
|
#define QSDOC_PROPERTY_OVERRIDE(...)
|
||||||
|
|
67
src/core/model.cpp
Normal file
67
src/core/model.cpp
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
#include "model.hpp"
|
||||||
|
|
||||||
|
#include <qabstractitemmodel.h>
|
||||||
|
#include <qhash.h>
|
||||||
|
#include <qobject.h>
|
||||||
|
#include <qqmllist.h>
|
||||||
|
#include <qtmetamacros.h>
|
||||||
|
#include <qtypes.h>
|
||||||
|
#include <qvariant.h>
|
||||||
|
|
||||||
|
qint32 UntypedObjectModel::rowCount(const QModelIndex& parent) const {
|
||||||
|
if (parent != QModelIndex()) return 0;
|
||||||
|
return static_cast<qint32>(this->valuesList.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant UntypedObjectModel::data(const QModelIndex& index, qint32 role) const {
|
||||||
|
if (role != 0) return QVariant();
|
||||||
|
return QVariant::fromValue(this->valuesList.at(index.row()));
|
||||||
|
}
|
||||||
|
|
||||||
|
QHash<int, QByteArray> UntypedObjectModel::roleNames() const { return {{0, "modelData"}}; }
|
||||||
|
|
||||||
|
QQmlListProperty<QObject> UntypedObjectModel::values() {
|
||||||
|
return QQmlListProperty<QObject>(
|
||||||
|
this,
|
||||||
|
nullptr,
|
||||||
|
&UntypedObjectModel::valuesCount,
|
||||||
|
&UntypedObjectModel::valueAt
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
qsizetype UntypedObjectModel::valuesCount(QQmlListProperty<QObject>* property) {
|
||||||
|
return static_cast<UntypedObjectModel*>(property->object)->valuesList.count(); // NOLINT
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject* UntypedObjectModel::valueAt(QQmlListProperty<QObject>* property, qsizetype index) {
|
||||||
|
return static_cast<UntypedObjectModel*>(property->object)->valuesList.at(index); // NOLINT
|
||||||
|
}
|
||||||
|
|
||||||
|
void UntypedObjectModel::insertObject(QObject* object, qsizetype index) {
|
||||||
|
auto iindex = index == -1 ? this->valuesList.length() : index;
|
||||||
|
auto intIndex = static_cast<qint32>(iindex);
|
||||||
|
|
||||||
|
this->beginInsertRows(QModelIndex(), intIndex, intIndex);
|
||||||
|
this->valuesList.insert(iindex, object);
|
||||||
|
this->endInsertRows();
|
||||||
|
emit this->valuesChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UntypedObjectModel::removeAt(qsizetype index) {
|
||||||
|
auto intIndex = static_cast<qint32>(index);
|
||||||
|
|
||||||
|
this->beginRemoveRows(QModelIndex(), intIndex, intIndex);
|
||||||
|
this->valuesList.removeAt(index);
|
||||||
|
this->endRemoveRows();
|
||||||
|
emit this->valuesChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UntypedObjectModel::removeObject(const QObject* object) {
|
||||||
|
auto index = this->valuesList.indexOf(object);
|
||||||
|
if (index == -1) return false;
|
||||||
|
|
||||||
|
this->removeAt(index);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
qsizetype UntypedObjectModel::indexOf(QObject* object) { return this->valuesList.indexOf(object); }
|
86
src/core/model.hpp
Normal file
86
src/core/model.hpp
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <qabstractitemmodel.h>
|
||||||
|
#include <qcontainerfwd.h>
|
||||||
|
#include <qobject.h>
|
||||||
|
#include <qqmlintegration.h>
|
||||||
|
#include <qqmllist.h>
|
||||||
|
#include <qtmetamacros.h>
|
||||||
|
#include <qtypes.h>
|
||||||
|
#include <qvariant.h>
|
||||||
|
|
||||||
|
#include "doc.hpp"
|
||||||
|
|
||||||
|
///! View into a list of objets
|
||||||
|
/// Typed view into a list of objects.
|
||||||
|
///
|
||||||
|
/// An ObjectModel works as a QML [Data Model], allowing efficient interaction with
|
||||||
|
/// components that act on models. It has a single role named `modelData`, to match the
|
||||||
|
/// behavior of lists.
|
||||||
|
/// The same information contained in the list model is available as a normal list
|
||||||
|
/// via the `values` property.
|
||||||
|
///
|
||||||
|
/// #### Differences from a list
|
||||||
|
/// Unlike with a list, the following property binding will never be updated when `model[3]` changes.
|
||||||
|
/// ```qml
|
||||||
|
/// // will not update reactively
|
||||||
|
/// property var foo: model[3]
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// You can work around this limitation using the `values` property of the model to view it as a list.
|
||||||
|
/// ```qml
|
||||||
|
/// // will update reactively
|
||||||
|
/// property var foo: model.values[3]
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// [Data Model]: https://doc.qt.io/qt-6/qtquick-modelviewsdata-modelview.html#qml-data-models
|
||||||
|
class UntypedObjectModel: public QAbstractListModel {
|
||||||
|
QSDOC_CNAME(ObjectModel);
|
||||||
|
Q_OBJECT;
|
||||||
|
/// The content of the object model, as a QML list.
|
||||||
|
/// The values of this property will always be of the type of the model.
|
||||||
|
Q_PROPERTY(QQmlListProperty<QObject> values READ values NOTIFY valuesChanged);
|
||||||
|
QML_NAMED_ELEMENT(ObjectModel);
|
||||||
|
QML_UNCREATABLE("ObjectModels cannot be created directly.");
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit UntypedObjectModel(QObject* parent): QAbstractListModel(parent) {}
|
||||||
|
|
||||||
|
[[nodiscard]] qint32 rowCount(const QModelIndex& parent) const override;
|
||||||
|
[[nodiscard]] QVariant data(const QModelIndex& index, qint32 role) const override;
|
||||||
|
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
|
[[nodiscard]] QQmlListProperty<QObject> values();
|
||||||
|
void removeAt(qsizetype index);
|
||||||
|
|
||||||
|
Q_INVOKABLE qsizetype indexOf(QObject* object);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void valuesChanged();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void insertObject(QObject* object, qsizetype index = -1);
|
||||||
|
bool removeObject(const QObject* object);
|
||||||
|
|
||||||
|
QVector<QObject*> valuesList;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static qsizetype valuesCount(QQmlListProperty<QObject>* property);
|
||||||
|
static QObject* valueAt(QQmlListProperty<QObject>* property, qsizetype index);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class ObjectModel: public UntypedObjectModel {
|
||||||
|
public:
|
||||||
|
explicit ObjectModel(QObject* parent): UntypedObjectModel(parent) {}
|
||||||
|
|
||||||
|
[[nodiscard]] const QVector<T*>& valueList() const {
|
||||||
|
return *reinterpret_cast<const QVector<T*>*>(&this->valuesList); // NOLINT
|
||||||
|
}
|
||||||
|
|
||||||
|
void insertObject(T* object, qsizetype index = -1) {
|
||||||
|
this->UntypedObjectModel::insertObject(object, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeObject(const T* object) { this->UntypedObjectModel::removeObject(object); }
|
||||||
|
};
|
|
@ -18,5 +18,6 @@ headers = [
|
||||||
"easingcurve.hpp",
|
"easingcurve.hpp",
|
||||||
"transformwatcher.hpp",
|
"transformwatcher.hpp",
|
||||||
"boundcomponent.hpp",
|
"boundcomponent.hpp",
|
||||||
|
"model.hpp",
|
||||||
]
|
]
|
||||||
-----
|
-----
|
||||||
|
|
|
@ -4,14 +4,12 @@
|
||||||
#include <qdbusconnection.h>
|
#include <qdbusconnection.h>
|
||||||
#include <qdbusconnectioninterface.h>
|
#include <qdbusconnectioninterface.h>
|
||||||
#include <qdbusservicewatcher.h>
|
#include <qdbusservicewatcher.h>
|
||||||
#include <qlist.h>
|
|
||||||
#include <qlogging.h>
|
#include <qlogging.h>
|
||||||
#include <qloggingcategory.h>
|
#include <qloggingcategory.h>
|
||||||
#include <qobject.h>
|
#include <qobject.h>
|
||||||
#include <qqmllist.h>
|
#include <qqmllist.h>
|
||||||
#include <qtmetamacros.h>
|
|
||||||
#include <qtypes.h>
|
|
||||||
|
|
||||||
|
#include "../../core/model.hpp"
|
||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
|
|
||||||
namespace qs::service::mpris {
|
namespace qs::service::mpris {
|
||||||
|
@ -74,34 +72,15 @@ void MprisWatcher::onServiceUnregistered(const QString& service) {
|
||||||
|
|
||||||
void MprisWatcher::onPlayerReady() {
|
void MprisWatcher::onPlayerReady() {
|
||||||
auto* player = qobject_cast<MprisPlayer*>(this->sender());
|
auto* player = qobject_cast<MprisPlayer*>(this->sender());
|
||||||
this->readyPlayers.push_back(player);
|
this->readyPlayers.insertObject(player);
|
||||||
emit this->playersChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MprisWatcher::onPlayerDestroyed(QObject* object) {
|
void MprisWatcher::onPlayerDestroyed(QObject* object) {
|
||||||
auto* player = static_cast<MprisPlayer*>(object); // NOLINT
|
auto* player = static_cast<MprisPlayer*>(object); // NOLINT
|
||||||
|
this->readyPlayers.removeObject(player);
|
||||||
if (this->readyPlayers.removeOne(player)) {
|
|
||||||
emit this->playersChanged();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QQmlListProperty<MprisPlayer> MprisWatcher::players() {
|
ObjectModel<MprisPlayer>* MprisWatcher::players() { return &this->readyPlayers; }
|
||||||
return QQmlListProperty<MprisPlayer>(
|
|
||||||
this,
|
|
||||||
nullptr,
|
|
||||||
&MprisWatcher::playersCount,
|
|
||||||
&MprisWatcher::playerAt
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
qsizetype MprisWatcher::playersCount(QQmlListProperty<MprisPlayer>* property) {
|
|
||||||
return static_cast<MprisWatcher*>(property->object)->readyPlayers.count(); // NOLINT
|
|
||||||
}
|
|
||||||
|
|
||||||
MprisPlayer* MprisWatcher::playerAt(QQmlListProperty<MprisPlayer>* property, qsizetype index) {
|
|
||||||
return static_cast<MprisWatcher*>(property->object)->readyPlayers.at(index); // NOLINT
|
|
||||||
}
|
|
||||||
|
|
||||||
void MprisWatcher::registerPlayer(const QString& address) {
|
void MprisWatcher::registerPlayer(const QString& address) {
|
||||||
if (this->mPlayers.contains(address)) {
|
if (this->mPlayers.contains(address)) {
|
||||||
|
|
|
@ -4,14 +4,13 @@
|
||||||
#include <qdbusinterface.h>
|
#include <qdbusinterface.h>
|
||||||
#include <qdbusservicewatcher.h>
|
#include <qdbusservicewatcher.h>
|
||||||
#include <qhash.h>
|
#include <qhash.h>
|
||||||
#include <qlist.h>
|
|
||||||
#include <qloggingcategory.h>
|
#include <qloggingcategory.h>
|
||||||
#include <qobject.h>
|
#include <qobject.h>
|
||||||
#include <qqmlintegration.h>
|
#include <qqmlintegration.h>
|
||||||
#include <qqmllist.h>
|
#include <qqmllist.h>
|
||||||
#include <qtmetamacros.h>
|
#include <qtmetamacros.h>
|
||||||
#include <qtypes.h>
|
|
||||||
|
|
||||||
|
#include "../../core/model.hpp"
|
||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
|
|
||||||
namespace qs::service::mpris {
|
namespace qs::service::mpris {
|
||||||
|
@ -22,15 +21,12 @@ class MprisWatcher: public QObject {
|
||||||
QML_NAMED_ELEMENT(Mpris);
|
QML_NAMED_ELEMENT(Mpris);
|
||||||
QML_SINGLETON;
|
QML_SINGLETON;
|
||||||
/// All connected MPRIS players.
|
/// All connected MPRIS players.
|
||||||
Q_PROPERTY(QQmlListProperty<MprisPlayer> players READ players NOTIFY playersChanged);
|
Q_PROPERTY(ObjectModel<MprisPlayer>* players READ players CONSTANT);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MprisWatcher(QObject* parent = nullptr);
|
explicit MprisWatcher(QObject* parent = nullptr);
|
||||||
|
|
||||||
[[nodiscard]] QQmlListProperty<MprisPlayer> players();
|
[[nodiscard]] ObjectModel<MprisPlayer>* players();
|
||||||
|
|
||||||
signals:
|
|
||||||
void playersChanged();
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onServiceRegistered(const QString& service);
|
void onServiceRegistered(const QString& service);
|
||||||
|
@ -39,15 +35,12 @@ private slots:
|
||||||
void onPlayerDestroyed(QObject* object);
|
void onPlayerDestroyed(QObject* object);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static qsizetype playersCount(QQmlListProperty<MprisPlayer>* property);
|
|
||||||
static MprisPlayer* playerAt(QQmlListProperty<MprisPlayer>* property, qsizetype index);
|
|
||||||
|
|
||||||
void registerExisting();
|
void registerExisting();
|
||||||
void registerPlayer(const QString& address);
|
void registerPlayer(const QString& address);
|
||||||
|
|
||||||
QDBusServiceWatcher serviceWatcher;
|
QDBusServiceWatcher serviceWatcher;
|
||||||
QHash<QString, MprisPlayer*> mPlayers;
|
QHash<QString, MprisPlayer*> mPlayers;
|
||||||
QList<MprisPlayer*> readyPlayers;
|
ObjectModel<MprisPlayer> readyPlayers {this};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace qs::service::mpris
|
} // namespace qs::service::mpris
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <qtypes.h>
|
#include <qtypes.h>
|
||||||
#include <qvariant.h>
|
#include <qvariant.h>
|
||||||
|
|
||||||
|
#include "../../core/model.hpp"
|
||||||
#include "connection.hpp"
|
#include "connection.hpp"
|
||||||
#include "link.hpp"
|
#include "link.hpp"
|
||||||
#include "metadata.hpp"
|
#include "metadata.hpp"
|
||||||
|
@ -65,88 +66,43 @@ Pipewire::Pipewire(QObject* parent): QObject(parent) {
|
||||||
// clang-format on
|
// clang-format on
|
||||||
}
|
}
|
||||||
|
|
||||||
QQmlListProperty<PwNodeIface> Pipewire::nodes() {
|
ObjectModel<PwNodeIface>* Pipewire::nodes() { return &this->mNodes; }
|
||||||
return QQmlListProperty<PwNodeIface>(this, nullptr, &Pipewire::nodesCount, &Pipewire::nodeAt);
|
|
||||||
}
|
|
||||||
|
|
||||||
qsizetype Pipewire::nodesCount(QQmlListProperty<PwNodeIface>* property) {
|
|
||||||
return static_cast<Pipewire*>(property->object)->mNodes.count(); // NOLINT
|
|
||||||
}
|
|
||||||
|
|
||||||
PwNodeIface* Pipewire::nodeAt(QQmlListProperty<PwNodeIface>* property, qsizetype index) {
|
|
||||||
return static_cast<Pipewire*>(property->object)->mNodes.at(index); // NOLINT
|
|
||||||
}
|
|
||||||
|
|
||||||
void Pipewire::onNodeAdded(PwNode* node) {
|
void Pipewire::onNodeAdded(PwNode* node) {
|
||||||
auto* iface = PwNodeIface::instance(node);
|
auto* iface = PwNodeIface::instance(node);
|
||||||
QObject::connect(iface, &QObject::destroyed, this, &Pipewire::onNodeRemoved);
|
QObject::connect(iface, &QObject::destroyed, this, &Pipewire::onNodeRemoved);
|
||||||
|
this->mNodes.insertObject(iface);
|
||||||
this->mNodes.push_back(iface);
|
|
||||||
emit this->nodesChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pipewire::onNodeRemoved(QObject* object) {
|
void Pipewire::onNodeRemoved(QObject* object) {
|
||||||
auto* iface = static_cast<PwNodeIface*>(object); // NOLINT
|
auto* iface = static_cast<PwNodeIface*>(object); // NOLINT
|
||||||
this->mNodes.removeOne(iface);
|
this->mNodes.removeObject(iface);
|
||||||
emit this->nodesChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QQmlListProperty<PwLinkIface> Pipewire::links() {
|
ObjectModel<PwLinkIface>* Pipewire::links() { return &this->mLinks; }
|
||||||
return QQmlListProperty<PwLinkIface>(this, nullptr, &Pipewire::linksCount, &Pipewire::linkAt);
|
|
||||||
}
|
|
||||||
|
|
||||||
qsizetype Pipewire::linksCount(QQmlListProperty<PwLinkIface>* property) {
|
|
||||||
return static_cast<Pipewire*>(property->object)->mLinks.count(); // NOLINT
|
|
||||||
}
|
|
||||||
|
|
||||||
PwLinkIface* Pipewire::linkAt(QQmlListProperty<PwLinkIface>* property, qsizetype index) {
|
|
||||||
return static_cast<Pipewire*>(property->object)->mLinks.at(index); // NOLINT
|
|
||||||
}
|
|
||||||
|
|
||||||
void Pipewire::onLinkAdded(PwLink* link) {
|
void Pipewire::onLinkAdded(PwLink* link) {
|
||||||
auto* iface = PwLinkIface::instance(link);
|
auto* iface = PwLinkIface::instance(link);
|
||||||
QObject::connect(iface, &QObject::destroyed, this, &Pipewire::onLinkRemoved);
|
QObject::connect(iface, &QObject::destroyed, this, &Pipewire::onLinkRemoved);
|
||||||
|
this->mLinks.insertObject(iface);
|
||||||
this->mLinks.push_back(iface);
|
|
||||||
emit this->linksChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pipewire::onLinkRemoved(QObject* object) {
|
void Pipewire::onLinkRemoved(QObject* object) {
|
||||||
auto* iface = static_cast<PwLinkIface*>(object); // NOLINT
|
auto* iface = static_cast<PwLinkIface*>(object); // NOLINT
|
||||||
this->mLinks.removeOne(iface);
|
this->mLinks.removeObject(iface);
|
||||||
emit this->linksChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QQmlListProperty<PwLinkGroupIface> Pipewire::linkGroups() {
|
ObjectModel<PwLinkGroupIface>* Pipewire::linkGroups() { return &this->mLinkGroups; }
|
||||||
return QQmlListProperty<PwLinkGroupIface>(
|
|
||||||
this,
|
|
||||||
nullptr,
|
|
||||||
&Pipewire::linkGroupsCount,
|
|
||||||
&Pipewire::linkGroupAt
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
qsizetype Pipewire::linkGroupsCount(QQmlListProperty<PwLinkGroupIface>* property) {
|
|
||||||
return static_cast<Pipewire*>(property->object)->mLinkGroups.count(); // NOLINT
|
|
||||||
}
|
|
||||||
|
|
||||||
PwLinkGroupIface*
|
|
||||||
Pipewire::linkGroupAt(QQmlListProperty<PwLinkGroupIface>* property, qsizetype index) {
|
|
||||||
return static_cast<Pipewire*>(property->object)->mLinkGroups.at(index); // NOLINT
|
|
||||||
}
|
|
||||||
|
|
||||||
void Pipewire::onLinkGroupAdded(PwLinkGroup* linkGroup) {
|
void Pipewire::onLinkGroupAdded(PwLinkGroup* linkGroup) {
|
||||||
auto* iface = PwLinkGroupIface::instance(linkGroup);
|
auto* iface = PwLinkGroupIface::instance(linkGroup);
|
||||||
QObject::connect(iface, &QObject::destroyed, this, &Pipewire::onLinkGroupRemoved);
|
QObject::connect(iface, &QObject::destroyed, this, &Pipewire::onLinkGroupRemoved);
|
||||||
|
this->mLinkGroups.insertObject(iface);
|
||||||
this->mLinkGroups.push_back(iface);
|
|
||||||
emit this->linkGroupsChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pipewire::onLinkGroupRemoved(QObject* object) {
|
void Pipewire::onLinkGroupRemoved(QObject* object) {
|
||||||
auto* iface = static_cast<PwLinkGroupIface*>(object); // NOLINT
|
auto* iface = static_cast<PwLinkGroupIface*>(object); // NOLINT
|
||||||
this->mLinkGroups.removeOne(iface);
|
this->mLinkGroups.removeObject(iface);
|
||||||
emit this->linkGroupsChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PwNodeIface* Pipewire::defaultAudioSink() const { // NOLINT
|
PwNodeIface* Pipewire::defaultAudioSink() const { // NOLINT
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <qtmetamacros.h>
|
#include <qtmetamacros.h>
|
||||||
#include <qtypes.h>
|
#include <qtypes.h>
|
||||||
|
|
||||||
|
#include "../../core/model.hpp"
|
||||||
#include "link.hpp"
|
#include "link.hpp"
|
||||||
#include "node.hpp"
|
#include "node.hpp"
|
||||||
#include "registry.hpp"
|
#include "registry.hpp"
|
||||||
|
@ -52,11 +53,11 @@ class Pipewire: public QObject {
|
||||||
Q_OBJECT;
|
Q_OBJECT;
|
||||||
// clang-format off
|
// clang-format off
|
||||||
/// All pipewire nodes.
|
/// All pipewire nodes.
|
||||||
Q_PROPERTY(QQmlListProperty<PwNodeIface> nodes READ nodes NOTIFY nodesChanged);
|
Q_PROPERTY(ObjectModel<PwNodeIface>* nodes READ nodes CONSTANT);
|
||||||
/// All pipewire links.
|
/// All pipewire links.
|
||||||
Q_PROPERTY(QQmlListProperty<PwLinkIface> links READ links NOTIFY linksChanged);
|
Q_PROPERTY(ObjectModel<PwLinkIface>* links READ links CONSTANT);
|
||||||
/// All pipewire link groups.
|
/// All pipewire link groups.
|
||||||
Q_PROPERTY(QQmlListProperty<PwLinkGroupIface> linkGroups READ linkGroups NOTIFY linkGroupsChanged);
|
Q_PROPERTY(ObjectModel<PwLinkGroupIface>* linkGroups READ linkGroups CONSTANT);
|
||||||
/// The default audio sink or `null`.
|
/// The default audio sink or `null`.
|
||||||
Q_PROPERTY(PwNodeIface* defaultAudioSink READ defaultAudioSink NOTIFY defaultAudioSinkChanged);
|
Q_PROPERTY(PwNodeIface* defaultAudioSink READ defaultAudioSink NOTIFY defaultAudioSinkChanged);
|
||||||
/// The default audio source or `null`.
|
/// The default audio source or `null`.
|
||||||
|
@ -68,16 +69,13 @@ class Pipewire: public QObject {
|
||||||
public:
|
public:
|
||||||
explicit Pipewire(QObject* parent = nullptr);
|
explicit Pipewire(QObject* parent = nullptr);
|
||||||
|
|
||||||
[[nodiscard]] QQmlListProperty<PwNodeIface> nodes();
|
[[nodiscard]] ObjectModel<PwNodeIface>* nodes();
|
||||||
[[nodiscard]] QQmlListProperty<PwLinkIface> links();
|
[[nodiscard]] ObjectModel<PwLinkIface>* links();
|
||||||
[[nodiscard]] QQmlListProperty<PwLinkGroupIface> linkGroups();
|
[[nodiscard]] ObjectModel<PwLinkGroupIface>* linkGroups();
|
||||||
[[nodiscard]] PwNodeIface* defaultAudioSink() const;
|
[[nodiscard]] PwNodeIface* defaultAudioSink() const;
|
||||||
[[nodiscard]] PwNodeIface* defaultAudioSource() const;
|
[[nodiscard]] PwNodeIface* defaultAudioSource() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void nodesChanged();
|
|
||||||
void linksChanged();
|
|
||||||
void linkGroupsChanged();
|
|
||||||
void defaultAudioSinkChanged();
|
void defaultAudioSinkChanged();
|
||||||
void defaultAudioSourceChanged();
|
void defaultAudioSourceChanged();
|
||||||
|
|
||||||
|
@ -90,17 +88,9 @@ private slots:
|
||||||
void onLinkGroupRemoved(QObject* object);
|
void onLinkGroupRemoved(QObject* object);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static qsizetype nodesCount(QQmlListProperty<PwNodeIface>* property);
|
ObjectModel<PwNodeIface> mNodes {this};
|
||||||
static PwNodeIface* nodeAt(QQmlListProperty<PwNodeIface>* property, qsizetype index);
|
ObjectModel<PwLinkIface> mLinks {this};
|
||||||
static qsizetype linksCount(QQmlListProperty<PwLinkIface>* property);
|
ObjectModel<PwLinkGroupIface> mLinkGroups {this};
|
||||||
static PwLinkIface* linkAt(QQmlListProperty<PwLinkIface>* property, qsizetype index);
|
|
||||||
static qsizetype linkGroupsCount(QQmlListProperty<PwLinkGroupIface>* property);
|
|
||||||
static PwLinkGroupIface*
|
|
||||||
linkGroupAt(QQmlListProperty<PwLinkGroupIface>* property, qsizetype index);
|
|
||||||
|
|
||||||
QVector<PwNodeIface*> mNodes;
|
|
||||||
QVector<PwLinkIface*> mLinks;
|
|
||||||
QVector<PwLinkGroupIface*> mLinkGroups;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
///! Tracks all link connections to a given node.
|
///! Tracks all link connections to a given node.
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <qtmetamacros.h>
|
#include <qtmetamacros.h>
|
||||||
#include <qtypes.h>
|
#include <qtypes.h>
|
||||||
|
|
||||||
|
#include "../../core/model.hpp"
|
||||||
#include "../../dbus/dbusmenu/dbusmenu.hpp"
|
#include "../../dbus/dbusmenu/dbusmenu.hpp"
|
||||||
#include "../../dbus/properties.hpp"
|
#include "../../dbus/properties.hpp"
|
||||||
#include "host.hpp"
|
#include "host.hpp"
|
||||||
|
@ -106,46 +107,25 @@ SystemTray::SystemTray(QObject* parent): QObject(parent) {
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
for (auto* item: host->items()) {
|
for (auto* item: host->items()) {
|
||||||
this->mItems.push_back(new SystemTrayItem(item, this));
|
this->mItems.insertObject(new SystemTrayItem(item, this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemTray::onItemRegistered(StatusNotifierItem* item) {
|
void SystemTray::onItemRegistered(StatusNotifierItem* item) {
|
||||||
this->mItems.push_back(new SystemTrayItem(item, this));
|
this->mItems.insertObject(new SystemTrayItem(item, this));
|
||||||
emit this->itemsChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemTray::onItemUnregistered(StatusNotifierItem* item) {
|
void SystemTray::onItemUnregistered(StatusNotifierItem* item) {
|
||||||
SystemTrayItem* trayItem = nullptr;
|
for (const auto* storedItem: this->mItems.valueList()) {
|
||||||
|
if (storedItem->item == item) {
|
||||||
this->mItems.removeIf([item, &trayItem](SystemTrayItem* testItem) {
|
this->mItems.removeObject(storedItem);
|
||||||
if (testItem->item == item) {
|
delete storedItem;
|
||||||
trayItem = testItem;
|
break;
|
||||||
return true;
|
}
|
||||||
} else return false;
|
}
|
||||||
});
|
|
||||||
|
|
||||||
emit this->itemsChanged();
|
|
||||||
|
|
||||||
delete trayItem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QQmlListProperty<SystemTrayItem> SystemTray::items() {
|
ObjectModel<SystemTrayItem>* SystemTray::items() { return &this->mItems; }
|
||||||
return QQmlListProperty<SystemTrayItem>(
|
|
||||||
this,
|
|
||||||
nullptr,
|
|
||||||
&SystemTray::itemsCount,
|
|
||||||
&SystemTray::itemAt
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
qsizetype SystemTray::itemsCount(QQmlListProperty<SystemTrayItem>* property) {
|
|
||||||
return reinterpret_cast<SystemTray*>(property->object)->mItems.count(); // NOLINT
|
|
||||||
}
|
|
||||||
|
|
||||||
SystemTrayItem* SystemTray::itemAt(QQmlListProperty<SystemTrayItem>* property, qsizetype index) {
|
|
||||||
return reinterpret_cast<SystemTray*>(property->object)->mItems.at(index); // NOLINT
|
|
||||||
}
|
|
||||||
|
|
||||||
SystemTrayItem* SystemTrayMenuWatcher::trayItem() const { return this->item; }
|
SystemTrayItem* SystemTrayMenuWatcher::trayItem() const { return this->item; }
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,9 @@
|
||||||
|
|
||||||
#include <qobject.h>
|
#include <qobject.h>
|
||||||
#include <qqmlintegration.h>
|
#include <qqmlintegration.h>
|
||||||
#include <qqmllist.h>
|
|
||||||
#include <qtmetamacros.h>
|
#include <qtmetamacros.h>
|
||||||
#include <qtypes.h>
|
|
||||||
|
|
||||||
|
#include "../../core/model.hpp"
|
||||||
#include "item.hpp"
|
#include "item.hpp"
|
||||||
|
|
||||||
namespace SystemTrayStatus { // NOLINT
|
namespace SystemTrayStatus { // NOLINT
|
||||||
|
@ -108,27 +107,21 @@ signals:
|
||||||
class SystemTray: public QObject {
|
class SystemTray: public QObject {
|
||||||
Q_OBJECT;
|
Q_OBJECT;
|
||||||
/// List of all system tray icons.
|
/// List of all system tray icons.
|
||||||
Q_PROPERTY(QQmlListProperty<SystemTrayItem> items READ items NOTIFY itemsChanged);
|
Q_PROPERTY(ObjectModel<SystemTrayItem>* items READ items CONSTANT);
|
||||||
QML_ELEMENT;
|
QML_ELEMENT;
|
||||||
QML_SINGLETON;
|
QML_SINGLETON;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit SystemTray(QObject* parent = nullptr);
|
explicit SystemTray(QObject* parent = nullptr);
|
||||||
|
|
||||||
[[nodiscard]] QQmlListProperty<SystemTrayItem> items();
|
[[nodiscard]] ObjectModel<SystemTrayItem>* items();
|
||||||
|
|
||||||
signals:
|
|
||||||
void itemsChanged();
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onItemRegistered(qs::service::sni::StatusNotifierItem* item);
|
void onItemRegistered(qs::service::sni::StatusNotifierItem* item);
|
||||||
void onItemUnregistered(qs::service::sni::StatusNotifierItem* item);
|
void onItemUnregistered(qs::service::sni::StatusNotifierItem* item);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static qsizetype itemsCount(QQmlListProperty<SystemTrayItem>* property);
|
ObjectModel<SystemTrayItem> mItems {this};
|
||||||
static SystemTrayItem* itemAt(QQmlListProperty<SystemTrayItem>* property, qsizetype index);
|
|
||||||
|
|
||||||
QList<SystemTrayItem*> mItems;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
///! Accessor for SystemTrayItem menus.
|
///! Accessor for SystemTrayItem menus.
|
||||||
|
|
Loading…
Reference in a new issue