mirror of
https://github.com/AxioDL/amuse.git
synced 2025-12-09 05:27:57 +00:00
Implement amuse playback
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#define AMUSE_PROJECT_MODEL_HPP
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QIdentityProxyModel>
|
||||
#include <QDir>
|
||||
#include <QIcon>
|
||||
#include <map>
|
||||
@@ -12,6 +13,20 @@
|
||||
#include "amuse/AudioGroupPool.hpp"
|
||||
#include "amuse/AudioGroupSampleDirectory.hpp"
|
||||
|
||||
class ProjectModel;
|
||||
|
||||
class NullItemProxyModel : public QIdentityProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit NullItemProxyModel(ProjectModel* source);
|
||||
QModelIndex mapFromSource(const QModelIndex& sourceIndex) const;
|
||||
QModelIndex mapToSource(const QModelIndex& proxyIndex) const;
|
||||
int rowCount(const QModelIndex& parent) const;
|
||||
QModelIndex index(int row, int column, const QModelIndex& parent) const;
|
||||
QVariant data(const QModelIndex& proxyIndex, int role) const;
|
||||
};
|
||||
|
||||
class ProjectModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -25,6 +40,7 @@ public:
|
||||
|
||||
private:
|
||||
QDir m_dir;
|
||||
NullItemProxyModel m_nullProxy;
|
||||
|
||||
amuse::ProjectDatabase m_projectDatabase;
|
||||
std::map<QString, amuse::AudioGroupDatabase> m_groups;
|
||||
@@ -35,6 +51,7 @@ public:
|
||||
public:
|
||||
enum class Type
|
||||
{
|
||||
Null,
|
||||
Root,
|
||||
Group, // Top-level group
|
||||
SongGroup,
|
||||
@@ -46,30 +63,79 @@ public:
|
||||
Keymap,
|
||||
Layer
|
||||
};
|
||||
private:
|
||||
protected:
|
||||
INode* m_parent;
|
||||
std::vector<std::shared_ptr<INode>> m_children;
|
||||
std::unique_ptr<INode> m_nullChild;
|
||||
int m_row;
|
||||
public:
|
||||
virtual ~INode() = default;
|
||||
INode(INode* parent, int row) : m_parent(parent), m_row(row) {}
|
||||
INode(INode* parent) : m_parent(parent), m_row(0)
|
||||
{
|
||||
/* ONLY USED BY NULL NODE! */
|
||||
}
|
||||
INode(INode* parent, int row);
|
||||
|
||||
int childCount() const { return int(m_children.size()); }
|
||||
INode* child(int row) const { return m_children[row].get(); }
|
||||
INode* child(int row) const
|
||||
{
|
||||
if (row == m_children.size())
|
||||
return nullChild();
|
||||
return m_children[row].get();
|
||||
}
|
||||
INode* nullChild() const { return m_nullChild.get(); }
|
||||
INode* parent() const { return m_parent; }
|
||||
int row() const { return m_row; }
|
||||
|
||||
void reindexRows(int row)
|
||||
{
|
||||
for (auto it = m_children.begin() + row; it != m_children.end(); ++it)
|
||||
(*it)->m_row = row++;
|
||||
m_nullChild->m_row = row;
|
||||
}
|
||||
|
||||
void insertChild(int row, std::shared_ptr<INode>&& n)
|
||||
{
|
||||
m_children.insert(m_children.begin() + row, std::move(n));
|
||||
reindexRows(row);
|
||||
}
|
||||
std::shared_ptr<INode> removeChild(int row)
|
||||
{
|
||||
std::shared_ptr<INode> ret = std::move(m_children[row]);
|
||||
m_children.erase(m_children.begin() + row);
|
||||
reindexRows(row);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void reserve(size_t sz) { m_children.reserve(sz); }
|
||||
template<class T, class... _Args>
|
||||
T& makeChild(_Args&&... args)
|
||||
{
|
||||
m_children.push_back(std::make_shared<T>(this, m_children.size(), std::forward<_Args>(args)...));
|
||||
m_nullChild->m_row = int(m_children.size());
|
||||
return static_cast<T&>(*m_children.back());
|
||||
}
|
||||
|
||||
bool depthTraverse(const std::function<bool(INode* node)>& func)
|
||||
{
|
||||
for (auto& n : m_children)
|
||||
if (!n->depthTraverse(func))
|
||||
break;
|
||||
return func(this);
|
||||
}
|
||||
|
||||
virtual Type type() const = 0;
|
||||
virtual QString text() const = 0;
|
||||
virtual QIcon icon() const = 0;
|
||||
virtual Qt::ItemFlags flags() const { return Qt::ItemIsEnabled | Qt::ItemIsSelectable; }
|
||||
};
|
||||
struct NullNode : INode
|
||||
{
|
||||
NullNode(INode* parent) : INode(parent) {}
|
||||
|
||||
Type type() const { return Type::Null; }
|
||||
QString text() const { return {}; }
|
||||
QIcon icon() const { return {}; }
|
||||
};
|
||||
struct RootNode : INode
|
||||
{
|
||||
@@ -78,7 +144,9 @@ public:
|
||||
Type type() const { return Type::Root; }
|
||||
QString text() const { return {}; }
|
||||
QIcon icon() const { return {}; }
|
||||
Qt::ItemFlags flags() const { return Qt::ItemIsEnabled; }
|
||||
};
|
||||
struct CollectionNode;
|
||||
struct GroupNode : INode
|
||||
{
|
||||
std::map<QString, amuse::AudioGroupDatabase>::iterator m_it;
|
||||
@@ -90,6 +158,9 @@ public:
|
||||
QString text() const { return m_it->first; }
|
||||
QIcon icon() const { return Icon; }
|
||||
|
||||
CollectionNode* getCollectionOfType(Type tp) const;
|
||||
amuse::AudioGroupDatabase* getAudioGroup() const { return &m_it->second; }
|
||||
|
||||
std::shared_ptr<GroupNode> shared_from_this()
|
||||
{ return std::static_pointer_cast<GroupNode>(INode::shared_from_this()); }
|
||||
};
|
||||
@@ -125,28 +196,42 @@ public:
|
||||
std::shared_ptr<SoundGroupNode> shared_from_this()
|
||||
{ return std::static_pointer_cast<SoundGroupNode>(INode::shared_from_this()); }
|
||||
};
|
||||
struct BasePoolObjectNode;
|
||||
struct CollectionNode : INode
|
||||
{
|
||||
QString m_name;
|
||||
QIcon m_icon;
|
||||
CollectionNode(INode* parent, int row, const QString& name, const QIcon& icon)
|
||||
: INode(parent, row), m_name(name), m_icon(icon) {}
|
||||
Type m_collectionType;
|
||||
CollectionNode(INode* parent, int row, const QString& name, const QIcon& icon, Type collectionType)
|
||||
: INode(parent, row), m_name(name), m_icon(icon), m_collectionType(collectionType) {}
|
||||
|
||||
Type type() const { return Type::Collection; }
|
||||
QString text() const { return m_name; }
|
||||
QIcon icon() const { return m_icon; }
|
||||
Qt::ItemFlags flags() const { return Qt::ItemIsEnabled; }
|
||||
|
||||
Type collectionType() const { return m_collectionType; }
|
||||
int indexOfId(amuse::ObjectId id) const;
|
||||
amuse::ObjectId idOfIndex(int idx) const;
|
||||
BasePoolObjectNode* nodeOfIndex(int idx) const;
|
||||
|
||||
std::shared_ptr<CollectionNode> shared_from_this()
|
||||
{ return std::static_pointer_cast<CollectionNode>(INode::shared_from_this()); }
|
||||
};
|
||||
template <class ID, class T, INode::Type TP>
|
||||
struct PoolObjectNode : INode
|
||||
struct BasePoolObjectNode : INode
|
||||
{
|
||||
amuse::ObjectId m_id;
|
||||
BasePoolObjectNode(INode* parent, int row, amuse::ObjectId id)
|
||||
: INode(parent, row), m_id(id) {}
|
||||
amuse::ObjectId id() const { return m_id; }
|
||||
};
|
||||
template <class ID, class T, INode::Type TP>
|
||||
struct PoolObjectNode : BasePoolObjectNode
|
||||
{
|
||||
ID m_id;
|
||||
QString m_name;
|
||||
std::shared_ptr<T> m_obj;
|
||||
PoolObjectNode(INode* parent, int row, ID id, std::shared_ptr<T> obj)
|
||||
: INode(parent, row), m_id(id), m_name(ID::CurNameDB->resolveNameFromId(id).data()), m_obj(obj) {}
|
||||
: BasePoolObjectNode(parent, row, id), m_name(ID::CurNameDB->resolveNameFromId(id).data()), m_obj(obj) {}
|
||||
|
||||
Type type() const { return TP; }
|
||||
QString text() const { return m_name; }
|
||||
@@ -177,22 +262,23 @@ public:
|
||||
|
||||
void ensureModelData();
|
||||
|
||||
QModelIndex proxyCreateIndex(int arow, int acolumn, void *adata) const;
|
||||
QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const;
|
||||
QModelIndex index(INode* node) const;
|
||||
QModelIndex parent(const QModelIndex& child) const;
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex& parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
|
||||
Qt::ItemFlags flags(const QModelIndex& index) const;
|
||||
INode* node(const QModelIndex& index) const;
|
||||
GroupNode* getGroupNode(INode* node) const;
|
||||
bool canEdit(const QModelIndex& index) const;
|
||||
void _undoDel(const QModelIndex& index, std::shared_ptr<ProjectModel::INode>&& node);
|
||||
std::shared_ptr<ProjectModel::INode> _redoDel(const QModelIndex& index);
|
||||
void del(const QModelIndex& index);
|
||||
|
||||
QString path() const { return m_dir.path(); }
|
||||
bool canDelete() const;
|
||||
|
||||
public slots:
|
||||
void del();
|
||||
|
||||
signals:
|
||||
void canDeleteChanged(bool canDelete);
|
||||
NullItemProxyModel* getNullProxy() { return &m_nullProxy; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user