#pragma once #include "EditorWidget.hpp" #include #include #include "amuse/Voice.hpp" class SFXObjectDelegate : public BaseObjectDelegate { Q_OBJECT protected: ProjectModel::INode* getNode(const QAbstractItemModel* model, const QModelIndex& index) const; public: explicit SFXObjectDelegate(QObject* parent = Q_NULLPTR); QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const; void setEditorData(QWidget* editor, const QModelIndex& index) const; void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const; private slots: void objIndexChanged(); }; class SFXModel : public QAbstractTableModel { Q_OBJECT friend class SoundGroupEditor; friend class SFXObjectDelegate; friend class SFXTableView; amuse::ObjToken m_node; struct Iterator { using ItTp = std::unordered_map::iterator; ItTp m_it; Iterator(ItTp it) : m_it(it) {} ItTp::pointer operator->() const { return m_it.operator->(); } bool operator<(const Iterator& other) const { return amuse::SFXId::CurNameDB->resolveNameFromId(m_it->first) < amuse::SFXId::CurNameDB->resolveNameFromId(other.m_it->first); } bool operator<(amuse::SongId other) const { return amuse::SFXId::CurNameDB->resolveNameFromId(m_it->first) < amuse::SFXId::CurNameDB->resolveNameFromId(other); } bool operator<(const std::string& name) const { return amuse::SFXId::CurNameDB->resolveNameFromId(m_it->first) < name; } }; std::vector m_sorted; std::unordered_map& _getMap() const; void _buildSortedList(); QModelIndex _indexOfSFX(amuse::SFXId sfx) const; int _hypotheticalIndexOfSFX(const std::string& sfxName) const; public: explicit SFXModel(QObject* parent = Q_NULLPTR); void loadData(ProjectModel::SoundGroupNode* node); void unloadData(); int rowCount(const QModelIndex& parent = QModelIndex()) const; int columnCount(const QModelIndex& parent = QModelIndex()) const; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; Qt::ItemFlags flags(const QModelIndex& index) const; int _insertRow(const std::tuple& data); std::tuple _removeRow(amuse::SFXId sfx); }; class SFXTableView : public QTableView { Q_OBJECT SFXObjectDelegate m_sfxDelegate; RangedValueFactory<0, 127> m_127Factory; RangedValueFactory<0, 255> m_255Factory; QStyledItemDelegate m_127Delegate, m_255Delegate; public: explicit SFXTableView(QWidget* parent = Q_NULLPTR); void setModel(QAbstractItemModel* model); void deleteSelection(); }; class SFXPlayerWidget : public QWidget { Q_OBJECT QAction m_playAction; QToolButton m_button; QModelIndex m_index; amuse::GroupId m_groupId; amuse::SFXId m_sfxId; amuse::ObjToken m_vox; public: explicit SFXPlayerWidget(QModelIndex index, amuse::GroupId gid, amuse::SFXId id, QWidget* parent = Q_NULLPTR); ~SFXPlayerWidget(); amuse::SongId sfxId() const { return m_sfxId; } amuse::Voice* voice() const { return m_vox.get(); } void stopped(); void resizeEvent(QResizeEvent* event); void mouseDoubleClickEvent(QMouseEvent* event); void mousePressEvent(QMouseEvent* event); void mouseReleaseEvent(QMouseEvent* event) { event->ignore(); } public slots: void clicked(); }; class SoundGroupEditor : public EditorWidget { Q_OBJECT SFXModel m_sfxs; SFXTableView* m_sfxTable; AddRemoveButtons m_addRemoveButtons; public: explicit SoundGroupEditor(QWidget* parent = Q_NULLPTR); bool loadData(ProjectModel::SoundGroupNode* node); void unloadData(); ProjectModel::INode* currentNode() const; void setEditorEnabled(bool en) {} void resizeEvent(QResizeEvent* ev); QTableView* getSFXListView() const { return m_sfxTable; } AmuseItemEditFlags itemEditFlags() const; private slots: void rowsInserted(const QModelIndex& parent, int first, int last); void rowsMoved(const QModelIndex& parent, int start, int end, const QModelIndex& destination, int row); void doAdd(); void doSelectionChanged(); void sfxDataChanged(); void itemDeleteAction(); };