2018-07-14 06:06:33 +00:00
|
|
|
#ifndef AMUSE_EDITOR_WIDGET_HPP
|
|
|
|
#define AMUSE_EDITOR_WIDGET_HPP
|
|
|
|
|
|
|
|
#include <QWidget>
|
2018-07-26 03:41:48 +00:00
|
|
|
#include <QUndoCommand>
|
|
|
|
#include <QApplication>
|
2018-08-06 04:20:42 +00:00
|
|
|
#include <QSpinBox>
|
|
|
|
#include <QComboBox>
|
|
|
|
#include <QWheelEvent>
|
2018-08-09 07:42:17 +00:00
|
|
|
#include <QItemEditorFactory>
|
2018-08-10 06:19:23 +00:00
|
|
|
#include <QToolButton>
|
|
|
|
#include <QAction>
|
2018-08-16 06:26:44 +00:00
|
|
|
#include <QPushButton>
|
|
|
|
#include <QLabel>
|
2018-08-26 04:57:02 +00:00
|
|
|
#include <QMenu>
|
|
|
|
#include <QStyledItemDelegate>
|
2018-07-18 07:39:26 +00:00
|
|
|
#include "ProjectModel.hpp"
|
2018-07-14 06:06:33 +00:00
|
|
|
|
|
|
|
class EditorWidget : public QWidget
|
|
|
|
{
|
2018-07-26 03:41:48 +00:00
|
|
|
Q_OBJECT
|
2018-07-14 06:06:33 +00:00
|
|
|
public:
|
|
|
|
explicit EditorWidget(QWidget* parent = Q_NULLPTR);
|
2018-07-18 07:39:26 +00:00
|
|
|
virtual bool valid() const { return true; }
|
2018-07-26 03:41:48 +00:00
|
|
|
virtual void unloadData() {}
|
2018-07-28 04:34:29 +00:00
|
|
|
virtual ProjectModel::INode* currentNode() const { return nullptr; }
|
2018-08-10 06:19:23 +00:00
|
|
|
virtual void setEditorEnabled(bool en) { setEnabled(en); }
|
2018-08-25 08:34:04 +00:00
|
|
|
virtual AmuseItemEditFlags itemEditFlags() const { return AmuseItemNone; }
|
2018-08-10 06:19:23 +00:00
|
|
|
public slots:
|
2018-08-07 07:09:23 +00:00
|
|
|
virtual void itemCutAction() {}
|
|
|
|
virtual void itemCopyAction() {}
|
|
|
|
virtual void itemPasteAction() {}
|
|
|
|
virtual void itemDeleteAction() {}
|
2018-07-14 06:06:33 +00:00
|
|
|
};
|
|
|
|
|
2018-07-26 03:41:48 +00:00
|
|
|
class EditorUndoCommand : public QUndoCommand
|
|
|
|
{
|
|
|
|
protected:
|
2018-07-30 06:20:03 +00:00
|
|
|
amuse::ObjToken<ProjectModel::INode> m_node;
|
2018-07-26 03:41:48 +00:00
|
|
|
enum class Id
|
|
|
|
{
|
|
|
|
SMChangeVal,
|
2018-08-03 03:45:48 +00:00
|
|
|
SampLoop,
|
2018-08-04 02:07:34 +00:00
|
|
|
SampPitch,
|
|
|
|
ADSRAttack,
|
|
|
|
ADSRDecay,
|
|
|
|
ADSRSustain,
|
|
|
|
ADSRAttackAndDecay,
|
|
|
|
ADSRDecayAndSustain,
|
|
|
|
ADSRRelease,
|
|
|
|
ADSRDLS,
|
|
|
|
ADSRVelToAttack,
|
2018-08-04 22:05:01 +00:00
|
|
|
ADSRKeyToDecay,
|
|
|
|
CurveEdit
|
2018-07-26 03:41:48 +00:00
|
|
|
};
|
|
|
|
public:
|
2018-07-30 06:20:03 +00:00
|
|
|
EditorUndoCommand(amuse::ObjToken<ProjectModel::INode> node,
|
2018-07-26 03:41:48 +00:00
|
|
|
const QString& text, QUndoCommand* parent = nullptr)
|
|
|
|
: QUndoCommand(text, parent), m_node(node) {}
|
|
|
|
void undo();
|
|
|
|
void redo();
|
|
|
|
};
|
2018-07-14 06:06:33 +00:00
|
|
|
|
2018-08-06 04:20:42 +00:00
|
|
|
class FieldSpinBox : public QSpinBox
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
explicit FieldSpinBox(QWidget* parent = Q_NULLPTR)
|
|
|
|
: QSpinBox(parent) {}
|
|
|
|
|
|
|
|
/* Don't scroll */
|
|
|
|
void wheelEvent(QWheelEvent* event) { event->ignore(); }
|
|
|
|
};
|
|
|
|
|
2018-08-16 06:26:44 +00:00
|
|
|
class FieldSlider : public QWidget
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
QSlider m_slider;
|
|
|
|
QLabel m_value;
|
|
|
|
public:
|
|
|
|
explicit FieldSlider(QWidget* parent = Q_NULLPTR);
|
|
|
|
|
|
|
|
/* Don't scroll */
|
|
|
|
void wheelEvent(QWheelEvent* event) { event->ignore(); }
|
|
|
|
|
|
|
|
int value() const { return m_slider.value(); }
|
|
|
|
void setValue(int value) { m_slider.setValue(value); doValueChanged(value); }
|
|
|
|
void setRange(int min, int max) { m_slider.setRange(min, max); }
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
void doValueChanged(int value);
|
|
|
|
signals:
|
|
|
|
void valueChanged(int value);
|
|
|
|
};
|
|
|
|
|
|
|
|
class FieldDoubleSlider : public QWidget
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
QSlider m_slider;
|
|
|
|
QLabel m_value;
|
|
|
|
double m_min = 0.0;
|
|
|
|
double m_max = 1.0;
|
|
|
|
public:
|
|
|
|
explicit FieldDoubleSlider(QWidget* parent = Q_NULLPTR);
|
|
|
|
|
|
|
|
/* Don't scroll */
|
|
|
|
void wheelEvent(QWheelEvent* event) { event->ignore(); }
|
|
|
|
|
|
|
|
double value() const;
|
|
|
|
void setValue(double value);
|
|
|
|
void setRange(double min, double max);
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
void doValueChanged(int value);
|
|
|
|
signals:
|
|
|
|
void valueChanged(double value);
|
|
|
|
};
|
|
|
|
|
2018-08-06 04:20:42 +00:00
|
|
|
class FieldComboBox : public QComboBox
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
explicit FieldComboBox(QWidget* parent = Q_NULLPTR)
|
|
|
|
: QComboBox(parent) {}
|
|
|
|
|
|
|
|
/* Don't scroll */
|
|
|
|
void wheelEvent(QWheelEvent* event) { event->ignore(); }
|
|
|
|
};
|
|
|
|
|
2018-08-25 08:34:04 +00:00
|
|
|
class FieldProjectNode : public QWidget
|
2018-08-06 04:20:42 +00:00
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
ProjectModel::CollectionNode* m_collection;
|
2018-08-25 08:34:04 +00:00
|
|
|
FieldComboBox m_comboBox;
|
|
|
|
QPushButton m_button;
|
2018-08-06 04:20:42 +00:00
|
|
|
public:
|
|
|
|
explicit FieldProjectNode(ProjectModel::CollectionNode* collection = Q_NULLPTR, QWidget* parent = Q_NULLPTR);
|
|
|
|
void setCollection(ProjectModel::CollectionNode* collection);
|
|
|
|
ProjectModel::CollectionNode* collection() const { return m_collection; }
|
2018-08-25 08:34:04 +00:00
|
|
|
int currentIndex() const { return m_comboBox.currentIndex(); }
|
|
|
|
void setCurrentIndex(int index) { m_comboBox.setCurrentIndex(index); }
|
|
|
|
void showPopup() { m_comboBox.showPopup(); }
|
|
|
|
ProjectModel::BasePoolObjectNode* currentNode() const;
|
|
|
|
bool event(QEvent* ev);
|
|
|
|
private slots:
|
|
|
|
void _currentIndexChanged(int);
|
|
|
|
public slots:
|
|
|
|
void openCurrent();
|
|
|
|
signals:
|
|
|
|
void currentIndexChanged(int);
|
2018-08-06 04:20:42 +00:00
|
|
|
};
|
|
|
|
|
2018-08-25 08:34:04 +00:00
|
|
|
class FieldPageObjectNode : public QWidget
|
2018-08-09 07:42:17 +00:00
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
ProjectModel::GroupNode* m_group;
|
2018-08-25 08:34:04 +00:00
|
|
|
FieldComboBox m_comboBox;
|
|
|
|
QPushButton m_button;
|
2018-08-09 07:42:17 +00:00
|
|
|
public:
|
|
|
|
explicit FieldPageObjectNode(ProjectModel::GroupNode* group = Q_NULLPTR, QWidget* parent = Q_NULLPTR);
|
|
|
|
void setGroup(ProjectModel::GroupNode* group);
|
|
|
|
ProjectModel::GroupNode* group() const { return m_group; }
|
2018-08-25 08:34:04 +00:00
|
|
|
int currentIndex() const { return m_comboBox.currentIndex(); }
|
|
|
|
void setCurrentIndex(int index) { m_comboBox.setCurrentIndex(index); }
|
|
|
|
QModelIndex rootModelIndex() const { return m_comboBox.rootModelIndex(); }
|
|
|
|
void showPopup() { m_comboBox.showPopup(); }
|
|
|
|
ProjectModel::BasePoolObjectNode* currentNode() const;
|
|
|
|
bool event(QEvent* ev);
|
|
|
|
private slots:
|
|
|
|
void _currentIndexChanged(int);
|
|
|
|
public slots:
|
|
|
|
void openCurrent();
|
|
|
|
signals:
|
|
|
|
void currentIndexChanged(int);
|
2018-08-09 07:42:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
class EditorFieldNode : public T
|
|
|
|
{
|
|
|
|
bool m_deferPopupOpen = true;
|
|
|
|
public:
|
|
|
|
using T::T;
|
|
|
|
bool shouldPopupOpen()
|
|
|
|
{
|
|
|
|
bool ret = m_deferPopupOpen;
|
|
|
|
m_deferPopupOpen = false;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
using EditorFieldProjectNode = EditorFieldNode<FieldProjectNode>;
|
|
|
|
using EditorFieldPageObjectNode = EditorFieldNode<FieldPageObjectNode>;
|
|
|
|
|
|
|
|
template <int MIN, int MAX>
|
|
|
|
class RangedValueFactory : public QItemEditorFactory
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
QWidget* createEditor(int userType, QWidget *parent) const
|
|
|
|
{
|
|
|
|
QSpinBox* sb = new QSpinBox(parent);
|
|
|
|
sb->setFrame(false);
|
|
|
|
sb->setMinimum(MIN);
|
|
|
|
sb->setMaximum(MAX);
|
|
|
|
return sb;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-08-10 06:19:23 +00:00
|
|
|
class AddRemoveButtons : public QWidget
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
QAction m_addAction;
|
|
|
|
QToolButton m_addButton;
|
|
|
|
QAction m_removeAction;
|
|
|
|
QToolButton m_removeButton;
|
|
|
|
public:
|
|
|
|
explicit AddRemoveButtons(QWidget* parent = Q_NULLPTR);
|
|
|
|
QAction* addAction() { return &m_addAction; }
|
|
|
|
QAction* removeAction() { return &m_removeAction; }
|
|
|
|
};
|
|
|
|
|
2018-08-16 06:26:44 +00:00
|
|
|
class ListingDeleteButton : public QPushButton
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
explicit ListingDeleteButton(QWidget* parent = Q_NULLPTR);
|
|
|
|
void enterEvent(QEvent* event);
|
|
|
|
void leaveEvent(QEvent* event);
|
|
|
|
};
|
|
|
|
|
2018-08-26 04:57:02 +00:00
|
|
|
class ContextMenu : public QMenu
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
void hideEvent(QHideEvent* ev)
|
|
|
|
{
|
|
|
|
QMenu::hideEvent(ev);
|
|
|
|
deleteLater();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class BaseObjectDelegate : public QStyledItemDelegate
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
protected:
|
|
|
|
virtual ProjectModel::INode* getNode(const QAbstractItemModel* model, const QModelIndex& index) const = 0;
|
|
|
|
public:
|
|
|
|
explicit BaseObjectDelegate(QObject* parent = Q_NULLPTR) : QStyledItemDelegate(parent) {}
|
|
|
|
bool editorEvent(QEvent *event, QAbstractItemModel *model,
|
|
|
|
const QStyleOptionViewItem &option, const QModelIndex &index);
|
|
|
|
private slots:
|
|
|
|
void doOpenEditor();
|
|
|
|
void doFindUsages();
|
|
|
|
};
|
|
|
|
|
2018-07-14 06:06:33 +00:00
|
|
|
#endif //AMUSE_EDITOR_WIDGET_HPP
|