amuse/Editor/ProjectModel.hpp

185 lines
6.0 KiB
C++
Raw Normal View History

#ifndef AMUSE_PROJECT_MODEL_HPP
#define AMUSE_PROJECT_MODEL_HPP
#include <QAbstractItemModel>
#include <QDir>
2018-07-17 04:48:38 +00:00
#include <QIcon>
#include <map>
2018-07-17 04:48:38 +00:00
#include "Common.hpp"
#include "amuse/AudioGroup.hpp"
#include "amuse/AudioGroupData.hpp"
#include "amuse/AudioGroupProject.hpp"
#include "amuse/AudioGroupPool.hpp"
#include "amuse/AudioGroupSampleDirectory.hpp"
class ProjectModel : public QAbstractItemModel
{
Q_OBJECT
public:
enum class ImportMode
{
Original,
WAVs,
Both
};
2018-07-17 04:48:38 +00:00
private:
QDir m_dir;
amuse::ProjectDatabase m_projectDatabase;
std::map<QString, amuse::AudioGroupDatabase> m_groups;
2018-07-18 07:39:26 +00:00
public:
2018-07-17 04:48:38 +00:00
class INode
{
2018-07-18 07:39:26 +00:00
public:
2018-07-17 04:48:38 +00:00
enum class Type
{
2018-07-18 07:39:26 +00:00
Root,
2018-07-17 04:48:38 +00:00
Group, // Top-level group
SongGroup,
2018-07-18 07:39:26 +00:00
SoundGroup,
2018-07-17 04:48:38 +00:00
Collection, // Classified object collection, one of the following:
SoundMacro,
ADSR,
Curve,
Keymap,
Layer
};
2018-07-18 07:39:26 +00:00
private:
2018-07-17 04:48:38 +00:00
INode* m_parent;
std::vector<std::unique_ptr<INode>> m_children;
int m_row;
public:
virtual ~INode() = default;
INode(INode* parent, int row) : m_parent(parent), m_row(row) {}
int childCount() const { return int(m_children.size()); }
INode* child(int row) const { return m_children[row].get(); }
INode* parent() const { return m_parent; }
int row() const { return m_row; }
void reserve(size_t sz) { m_children.reserve(sz); }
template<class T, class... _Args>
T& makeChild(_Args&&... args)
2018-07-15 06:10:50 +00:00
{
2018-07-17 04:48:38 +00:00
m_children.push_back(std::make_unique<T>(this, m_children.size(), std::forward<_Args>(args)...));
return static_cast<T&>(*m_children.back());
2018-07-15 06:10:50 +00:00
}
2018-07-17 04:48:38 +00:00
2018-07-18 07:39:26 +00:00
virtual Type type() const = 0;
2018-07-17 04:48:38 +00:00
virtual QString text() const = 0;
virtual QIcon icon() const = 0;
};
2018-07-17 04:48:38 +00:00
struct RootNode : INode
{
RootNode() : INode(nullptr, 0) {}
2018-07-18 07:39:26 +00:00
Type type() const { return Type::Root; }
2018-07-17 04:48:38 +00:00
QString text() const { return {}; }
QIcon icon() const { return {}; }
};
struct GroupNode : INode
{
std::map<QString, amuse::AudioGroupDatabase>::iterator m_it;
GroupNode(INode* parent, int row, std::map<QString, amuse::AudioGroupDatabase>::iterator it)
: INode(parent, row), m_it(it) {}
2018-07-17 04:48:38 +00:00
static QIcon Icon;
2018-07-18 07:39:26 +00:00
Type type() const { return Type::Group; }
2018-07-17 04:48:38 +00:00
QString text() const { return m_it->first; }
QIcon icon() const { return Icon; }
};
struct SongGroupNode : INode
{
amuse::GroupId m_id;
QString m_name;
amuse::SongGroupIndex& m_index;
SongGroupNode(INode* parent, int row, amuse::GroupId id, amuse::SongGroupIndex& index)
: INode(parent, row), m_id(id), m_name(amuse::GroupId::CurNameDB->resolveNameFromId(id).data()), m_index(index) {}
static QIcon Icon;
2018-07-18 07:39:26 +00:00
Type type() const { return Type::SongGroup; }
2018-07-17 04:48:38 +00:00
QString text() const { return m_name; }
QIcon icon() const { return Icon; }
};
struct SoundGroupNode : INode
{
amuse::GroupId m_id;
QString m_name;
amuse::SFXGroupIndex& m_index;
SoundGroupNode(INode* parent, int row, amuse::GroupId id, amuse::SFXGroupIndex& index)
: INode(parent, row), m_id(id), m_name(amuse::GroupId::CurNameDB->resolveNameFromId(id).data()), m_index(index) {}
static QIcon Icon;
2018-07-18 07:39:26 +00:00
Type type() const { return Type::SoundGroup; }
2018-07-17 04:48:38 +00:00
QString text() const { return m_name; }
QIcon icon() const { return Icon; }
};
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) {}
2018-07-18 07:39:26 +00:00
Type type() const { return Type::Collection; }
2018-07-17 04:48:38 +00:00
QString text() const { return m_name; }
QIcon icon() const { return m_icon; }
};
2018-07-18 07:39:26 +00:00
template <class ID, class T, INode::Type TP>
2018-07-17 04:48:38 +00:00
struct PoolObjectNode : INode
2018-07-15 06:10:50 +00:00
{
2018-07-17 04:48:38 +00:00
ID m_id;
QString m_name;
T& m_obj;
PoolObjectNode(INode* parent, int row, ID id, T& obj)
: INode(parent, row), m_id(id), m_name(ID::CurNameDB->resolveNameFromId(id).data()), m_obj(obj) {}
2018-07-18 07:39:26 +00:00
Type type() const { return TP; }
2018-07-17 04:48:38 +00:00
QString text() const { return m_name; }
QIcon icon() const { return {}; }
};
2018-07-18 07:39:26 +00:00
using SoundMacroNode = PoolObjectNode<amuse::SoundMacroId, amuse::SoundMacro, INode::Type::SoundMacro>;
using ADSRNode = PoolObjectNode<amuse::TableId, amuse::ITable, INode::Type::ADSR>;
using CurveNode = PoolObjectNode<amuse::TableId, amuse::Curve, INode::Type::Curve>;
using KeymapNode = PoolObjectNode<amuse::KeymapId, amuse::Keymap, INode::Type::Keymap>;
using LayersNode = PoolObjectNode<amuse::LayersId, std::vector<amuse::LayerMapping>, INode::Type::Layer>;
2018-07-17 04:48:38 +00:00
std::unique_ptr<RootNode> m_root;
bool m_needsReset = false;
void _resetModelData();
2018-07-15 06:10:50 +00:00
public:
explicit ProjectModel(const QString& path, QObject* parent = Q_NULLPTR);
2018-07-18 07:39:26 +00:00
bool clearProjectData();
bool openGroupData(const QString& groupName, UIMessenger& messenger);
2018-07-17 04:48:38 +00:00
bool importGroupData(const QString& groupName, const amuse::AudioGroupData& data,
ImportMode mode, UIMessenger& messenger);
bool saveToFile(UIMessenger& messenger);
void ensureModelData();
QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) 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;
2018-07-17 04:48:38 +00:00
Qt::ItemFlags flags(const QModelIndex& index) const;
2018-07-18 07:39:26 +00:00
INode* node(const QModelIndex& index) const;
QString path() const { return m_dir.path(); }
bool canDelete() const;
public slots:
void del();
signals:
void canDeleteChanged(bool canDelete);
};
#endif //AMUSE_PROJECT_MODEL_HPP