Skip to content

Commit

Permalink
QML: Add EffectManager proxy and visibleEffectModel
Browse files Browse the repository at this point in the history
This allows accessing the visible effect list from QML.
  • Loading branch information
Holzhaus committed Jun 15, 2021
1 parent c85564a commit 8cab623
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -736,9 +736,11 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL
src/skin/qml/asyncimageprovider.cpp
src/skin/qml/qmlcontrolproxy.cpp
src/skin/qml/qmlconfigproxy.cpp
src/skin/qml/qmleffectsmanagerproxy.cpp
src/skin/qml/qmlplayermanagerproxy.cpp
src/skin/qml/qmlplayerproxy.cpp
src/skin/qml/qmlskin.cpp
src/skin/qml/qmlvisibleeffectsmodel.cpp
src/skin/qml/qmlwaveformoverview.cpp
src/skin/legacy/skincontext.cpp
src/skin/legacy/tooltips.cpp
Expand Down
21 changes: 21 additions & 0 deletions src/skin/qml/qmleffectsmanagerproxy.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include "skin/qml/qmleffectsmanagerproxy.h"

#include <memory>

#include "skin/qml/qmlvisibleeffectsmodel.h"

namespace mixxx {
namespace skin {
namespace qml {

QmlEffectsManagerProxy::QmlEffectsManagerProxy(
std::shared_ptr<EffectsManager> pEffectsManager, QObject* parent)
: QObject(parent),
m_pEffectsManager(pEffectsManager),
m_pVisibleEffectsModel(
new QmlVisibleEffectsModel(pEffectsManager, this)) {
}

} // namespace qml
} // namespace skin
} // namespace mixxx
31 changes: 31 additions & 0 deletions src/skin/qml/qmleffectsmanagerproxy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once
#include <QObject>

#include "effects/effectsmanager.h"

QT_FORWARD_DECLARE_CLASS(QAbstractListModel);

namespace mixxx {
namespace skin {
namespace qml {

class QmlVisibleEffectsModel;

class QmlEffectsManagerProxy : public QObject {
Q_OBJECT
Q_PROPERTY(mixxx::skin::qml::QmlVisibleEffectsModel* visibleEffectsModel
MEMBER m_pVisibleEffectsModel CONSTANT);

public:
explicit QmlEffectsManagerProxy(
std::shared_ptr<EffectsManager> pEffectsManager,
QObject* parent = nullptr);

private:
const std::shared_ptr<EffectsManager> m_pEffectsManager;
QmlVisibleEffectsModel* m_pVisibleEffectsModel;
};

} // namespace qml
} // namespace skin
} // namespace mixxx
26 changes: 25 additions & 1 deletion src/skin/qml/qmlskin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
#include "skin/qml/asyncimageprovider.h"
#include "skin/qml/qmlconfigproxy.h"
#include "skin/qml/qmlcontrolproxy.h"
#include "skin/qml/qmleffectsmanagerproxy.h"
#include "skin/qml/qmlplayermanagerproxy.h"
#include "skin/qml/qmlplayerproxy.h"
#include "skin/qml/qmlvisibleeffectsmodel.h"
#include "skin/qml/qmlwaveformoverview.h"
#include "util/assert.h"

Expand Down Expand Up @@ -128,6 +130,28 @@ QWidget* QmlSkin::loadSkin(QWidget* pParent,
qmlRegisterType<QmlControlProxy>("Mixxx", 0, 1, "ControlProxy");
qmlRegisterType<QmlWaveformOverview>("Mixxx", 0, 1, "WaveformOverview");

qmlRegisterSingletonType<QmlEffectsManagerProxy>("Mixxx",
0,
1,
"EffectsManager",
lambda_to_singleton_type_factory_ptr(
[pCoreServices](QQmlEngine* pEngine,
QJSEngine* pScriptEngine) -> QObject* {
Q_UNUSED(pScriptEngine);

QmlEffectsManagerProxy* pEffectsManagerProxy =
new QmlEffectsManagerProxy(
pCoreServices->getEffectsManager(),
pEngine);
return pEffectsManagerProxy;
}));
qmlRegisterUncreatableType<QmlVisibleEffectsModel>("Mixxx",
0,
1,
"VisibleEffectsModel",
"VisibleEffectsModel objects can't be created directly, please use "
"Mixxx.EffectsManager.visibleEffectsModel");

qmlRegisterSingletonType<QmlPlayerManagerProxy>("Mixxx",
0,
1,
Expand All @@ -150,7 +174,7 @@ QWidget* QmlSkin::loadSkin(QWidget* pParent,
"Player objects can't be created directly, please use "
"Mixxx.PlayerManager.getPlayer(group)");

qmlRegisterSingletonType<QmlPlayerManagerProxy>("Mixxx",
qmlRegisterSingletonType<QmlConfigProxy>("Mixxx",
0,
1,
"Config",
Expand Down
85 changes: 85 additions & 0 deletions src/skin/qml/qmlvisibleeffectsmodel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#include "skin/qml/qmlvisibleeffectsmodel.h"

#include <QModelIndex>

#include "effects/effectmanifest.h"
#include "effects/effectsmanager.h"

namespace mixxx {
namespace skin {
namespace qml {
namespace {
const QHash<int, QByteArray> kRoleNames = {
{Qt::DisplayRole, "display"},
{Qt::ToolTipRole, "tooltip"},
{QmlVisibleEffectsModel::EffectIdRole, "effectId"},
};
}

QmlVisibleEffectsModel::QmlVisibleEffectsModel(
std::shared_ptr<EffectsManager> pEffectsManager,
QObject* parent)
: QAbstractListModel(parent), m_pEffectsManager(pEffectsManager) {
m_visibleEffectManifests = m_pEffectsManager->getVisibleEffectManifests();
connect(m_pEffectsManager.get(),
&EffectsManager::visibleEffectsUpdated,
this,
&QmlVisibleEffectsModel::slotVisibleEffectsUpdated);
}

void QmlVisibleEffectsModel::slotVisibleEffectsUpdated() {
const QList<EffectManifestPointer> visibleEffectManifests =
m_pEffectsManager->getVisibleEffectManifests();
const auto firstMismatch = std::mismatch(visibleEffectManifests.begin(),
visibleEffectManifests.end(),
m_visibleEffectManifests.begin(),
[](const auto a, const auto b) { return a->id() == b->id(); });
Q_UNUSED(firstMismatch);
qWarning() << "first mismatched elements";
}

QVariant QmlVisibleEffectsModel::data(const QModelIndex& index, int role) const {
if (index.row() == 0) {
switch (role) {
case Qt::DisplayRole:
return EffectsManager::kNoEffectString;
case Qt::ToolTipRole:
return tr("No effect loaded.");
default:
return QVariant();
}
}

if (index.row() > m_visibleEffectManifests.size()) {
return QVariant();
}

const EffectManifestPointer pManifest = m_visibleEffectManifests.at(index.row() - 1);
switch (role) {
case Qt::DisplayRole:
return pManifest->displayName();
case Qt::ToolTipRole:
return pManifest->description();
case QmlVisibleEffectsModel::EffectIdRole:
return pManifest->id();
default:
return QVariant();
}
}

int QmlVisibleEffectsModel::rowCount(const QModelIndex& parent) const {
if (parent.isValid()) {
return 0;
}

// Add +1 because we also include "no effect" in the model
return m_visibleEffectManifests.size() + 1;
}

QHash<int, QByteArray> QmlVisibleEffectsModel::roleNames() const {
return kRoleNames;
}

} // namespace qml
} // namespace skin
} // namespace mixxx
37 changes: 37 additions & 0 deletions src/skin/qml/qmlvisibleeffectsmodel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#pragma once
#include <QAbstractListModel>
#include <memory>

#include "effects/effectsmanager.h"

namespace mixxx {
namespace skin {
namespace qml {

class QmlVisibleEffectsModel : public QAbstractListModel {
Q_OBJECT
public:
enum Roles {
EffectIdRole = Qt::UserRole + 1,
};
Q_ENUM(Roles)

explicit QmlVisibleEffectsModel(
std::shared_ptr<EffectsManager> pEffectsManager,
QObject* parent = nullptr);

QVariant data(const QModelIndex& index, int role) const override;
int rowCount(const QModelIndex& parent) const override;
QHash<int, QByteArray> roleNames() const override;

private slots:
void slotVisibleEffectsUpdated();

private:
const std::shared_ptr<EffectsManager> m_pEffectsManager;
QList<EffectManifestPointer> m_visibleEffectManifests;
};

} // namespace qml
} // namespace skin
} // namespace mixxx

0 comments on commit 8cab623

Please sign in to comment.