2018-07-09 18:05:31 +00:00
|
|
|
#ifndef AMUSE_MAINWINDOW_HPP
|
|
|
|
#define AMUSE_MAINWINDOW_HPP
|
2018-03-15 00:25:29 +00:00
|
|
|
|
2018-07-09 18:05:31 +00:00
|
|
|
#include <QMainWindow>
|
2018-07-14 06:06:33 +00:00
|
|
|
#include <QUndoStack>
|
2018-07-17 04:48:38 +00:00
|
|
|
#include <QProgressDialog>
|
|
|
|
#include <QThread>
|
2018-07-18 07:39:26 +00:00
|
|
|
#include <QStyledItemDelegate>
|
2018-08-11 06:31:10 +00:00
|
|
|
#include <QSortFilterProxyModel>
|
2018-07-14 06:06:33 +00:00
|
|
|
#include "ui_MainWindow.h"
|
|
|
|
#include "amuse/Engine.hpp"
|
|
|
|
#include "amuse/BooBackend.hpp"
|
|
|
|
#include "boo/audiodev/IAudioVoiceEngine.hpp"
|
|
|
|
#include "ProjectModel.hpp"
|
2018-07-18 07:39:26 +00:00
|
|
|
#include "EditorWidget.hpp"
|
2018-07-28 04:34:29 +00:00
|
|
|
#include "MIDIReader.hpp"
|
|
|
|
|
|
|
|
#define MaxRecentFiles 4
|
2018-07-14 06:06:33 +00:00
|
|
|
|
2018-07-09 18:05:31 +00:00
|
|
|
namespace Ui {
|
|
|
|
class MainWindow;
|
|
|
|
}
|
2018-03-15 00:25:29 +00:00
|
|
|
|
2018-07-18 07:39:26 +00:00
|
|
|
class MainWindow;
|
2018-07-26 03:41:48 +00:00
|
|
|
class SongGroupEditor;
|
|
|
|
class SoundGroupEditor;
|
|
|
|
class SoundMacroEditor;
|
|
|
|
class ADSREditor;
|
|
|
|
class CurveEditor;
|
|
|
|
class KeymapEditor;
|
|
|
|
class LayersEditor;
|
2018-07-29 03:37:06 +00:00
|
|
|
class SampleEditor;
|
2018-07-14 06:06:33 +00:00
|
|
|
|
2018-07-17 04:48:38 +00:00
|
|
|
class BackgroundTask : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
std::function<void(BackgroundTask&)> m_task;
|
|
|
|
UIMessenger m_threadMessenger;
|
|
|
|
bool m_cancelled = false;
|
|
|
|
public:
|
|
|
|
explicit BackgroundTask(std::function<void(BackgroundTask&)>&& task)
|
|
|
|
: m_task(std::move(task)), m_threadMessenger(this) {}
|
|
|
|
bool isCanceled() const { QCoreApplication::processEvents(); return m_cancelled; }
|
|
|
|
UIMessenger& uiMessenger() { return m_threadMessenger; }
|
|
|
|
|
|
|
|
signals:
|
|
|
|
void setMinimum(int minimum);
|
|
|
|
void setMaximum(int maximum);
|
|
|
|
void setValue(int value);
|
|
|
|
void setLabelText(const QString& text);
|
|
|
|
void finished();
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
void run() { m_task(*this); emit finished(); }
|
|
|
|
void cancel() { m_cancelled = true; }
|
|
|
|
};
|
|
|
|
|
2018-07-18 07:39:26 +00:00
|
|
|
class TreeDelegate : public QStyledItemDelegate
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
MainWindow& m_window;
|
|
|
|
public:
|
|
|
|
explicit TreeDelegate(MainWindow& window, QObject* parent = Q_NULLPTR)
|
|
|
|
: QStyledItemDelegate(parent), m_window(window) {}
|
|
|
|
|
|
|
|
bool editorEvent(QEvent *event,
|
|
|
|
QAbstractItemModel *model,
|
|
|
|
const QStyleOptionViewItem &option,
|
|
|
|
const QModelIndex &index);
|
|
|
|
};
|
|
|
|
|
2018-07-09 18:05:31 +00:00
|
|
|
class MainWindow : public QMainWindow
|
2018-03-15 00:25:29 +00:00
|
|
|
{
|
2018-07-28 04:34:29 +00:00
|
|
|
friend class MIDIReader;
|
2018-07-09 18:05:31 +00:00
|
|
|
Q_OBJECT
|
2018-07-14 06:06:33 +00:00
|
|
|
Ui::MainWindow m_ui;
|
2018-07-28 04:34:29 +00:00
|
|
|
QAction* m_clearRecentFileAct;
|
|
|
|
QAction* m_recentFileActs[MaxRecentFiles];
|
2018-07-18 07:39:26 +00:00
|
|
|
TreeDelegate m_treeDelegate;
|
2018-07-17 04:48:38 +00:00
|
|
|
UIMessenger m_mainMessenger;
|
2018-07-14 06:06:33 +00:00
|
|
|
ProjectModel* m_projectModel = nullptr;
|
2018-08-11 06:31:10 +00:00
|
|
|
QSortFilterProxyModel m_filterProjectModel;
|
2018-07-18 07:39:26 +00:00
|
|
|
QWidget* m_faceSvg;
|
2018-07-26 03:41:48 +00:00
|
|
|
SongGroupEditor* m_songGroupEditor = nullptr;
|
|
|
|
SoundGroupEditor* m_soundGroupEditor = nullptr;
|
|
|
|
SoundMacroEditor* m_soundMacroEditor = nullptr;
|
|
|
|
ADSREditor* m_adsrEditor = nullptr;
|
|
|
|
CurveEditor* m_curveEditor = nullptr;
|
|
|
|
KeymapEditor* m_keymapEditor = nullptr;
|
|
|
|
LayersEditor* m_layersEditor = nullptr;
|
2018-07-29 03:37:06 +00:00
|
|
|
SampleEditor* m_sampleEditor = nullptr;
|
2018-07-14 06:06:33 +00:00
|
|
|
|
|
|
|
std::unique_ptr<boo::IAudioVoiceEngine> m_voxEngine;
|
2018-07-28 04:34:29 +00:00
|
|
|
std::unique_ptr<VoiceAllocator> m_voxAllocator;
|
2018-07-14 06:06:33 +00:00
|
|
|
std::unique_ptr<amuse::Engine> m_engine;
|
2018-07-29 03:37:06 +00:00
|
|
|
amuse::ObjToken<amuse::Voice> m_lastSound;
|
2018-07-28 04:34:29 +00:00
|
|
|
int m_velocity = 90;
|
|
|
|
float m_pitch = 0.f;
|
2018-07-29 03:37:06 +00:00
|
|
|
int8_t m_ctrlVals[128] = {};
|
2018-07-28 04:34:29 +00:00
|
|
|
bool m_uiDisabled = false;
|
2018-07-14 06:06:33 +00:00
|
|
|
|
|
|
|
QUndoStack* m_undoStack;
|
|
|
|
|
|
|
|
QMetaObject::Connection m_cutConn;
|
|
|
|
QMetaObject::Connection m_copyConn;
|
|
|
|
QMetaObject::Connection m_pasteConn;
|
|
|
|
QMetaObject::Connection m_deleteConn;
|
|
|
|
QMetaObject::Connection m_canEditConn;
|
|
|
|
|
2018-07-17 04:48:38 +00:00
|
|
|
BackgroundTask* m_backgroundTask = nullptr;
|
|
|
|
QProgressDialog* m_backgroundDialog = nullptr;
|
|
|
|
QThread m_backgroundThread;
|
|
|
|
|
|
|
|
void connectMessenger(UIMessenger* messenger, Qt::ConnectionType type);
|
|
|
|
|
2018-07-29 03:37:06 +00:00
|
|
|
void updateWindowTitle();
|
2018-07-28 04:34:29 +00:00
|
|
|
void updateRecentFileActions();
|
2018-07-14 06:06:33 +00:00
|
|
|
bool setProjectPath(const QString& path);
|
|
|
|
void refreshAudioIO();
|
|
|
|
void refreshMIDIIO();
|
2018-07-28 04:34:29 +00:00
|
|
|
void timerEvent(QTimerEvent* ev);
|
|
|
|
void setSustain(bool sustain);
|
|
|
|
void keyPressEvent(QKeyEvent* ev);
|
|
|
|
void keyReleaseEvent(QKeyEvent* ev);
|
2018-07-14 06:06:33 +00:00
|
|
|
|
2018-07-17 04:48:38 +00:00
|
|
|
void startBackgroundTask(const QString& windowTitle, const QString& label,
|
|
|
|
std::function<void(BackgroundTask&)>&& task);
|
|
|
|
|
2018-07-18 07:39:26 +00:00
|
|
|
bool _setEditor(EditorWidget* widget);
|
|
|
|
|
2018-07-09 18:05:31 +00:00
|
|
|
public:
|
|
|
|
explicit MainWindow(QWidget* parent = Q_NULLPTR);
|
2018-07-14 06:06:33 +00:00
|
|
|
~MainWindow();
|
|
|
|
|
2018-07-28 04:34:29 +00:00
|
|
|
bool openProject(const QString& path);
|
|
|
|
|
2018-07-18 07:39:26 +00:00
|
|
|
bool openEditor(ProjectModel::SongGroupNode* node);
|
|
|
|
bool openEditor(ProjectModel::SoundGroupNode* node);
|
|
|
|
bool openEditor(ProjectModel::SoundMacroNode* node);
|
|
|
|
bool openEditor(ProjectModel::ADSRNode* node);
|
|
|
|
bool openEditor(ProjectModel::CurveNode* node);
|
|
|
|
bool openEditor(ProjectModel::KeymapNode* node);
|
|
|
|
bool openEditor(ProjectModel::LayersNode* node);
|
2018-07-29 03:37:06 +00:00
|
|
|
bool openEditor(ProjectModel::SampleNode* node);
|
2018-07-18 07:39:26 +00:00
|
|
|
bool openEditor(ProjectModel::INode* node);
|
|
|
|
void closeEditor();
|
|
|
|
|
2018-07-28 04:34:29 +00:00
|
|
|
ProjectModel::INode* getEditorNode() const;
|
2018-08-03 03:45:48 +00:00
|
|
|
EditorWidget* getEditorWidget() const;
|
2018-07-31 08:04:43 +00:00
|
|
|
amuse::ObjToken<amuse::Voice> startEditorVoice(uint8_t key, uint8_t vel);
|
2018-08-10 06:19:23 +00:00
|
|
|
amuse::ObjToken<amuse::Voice> startSFX(amuse::GroupId groupId, amuse::SFXId sfxId);
|
|
|
|
amuse::ObjToken<amuse::Sequencer> startSong(amuse::GroupId groupId, amuse::SongId songId,
|
|
|
|
const unsigned char* arrData);
|
2018-07-26 03:41:48 +00:00
|
|
|
void pushUndoCommand(QUndoCommand* cmd);
|
2018-08-07 07:09:23 +00:00
|
|
|
void updateFocus();
|
2018-07-28 04:34:29 +00:00
|
|
|
void aboutToDeleteNode(ProjectModel::INode* node);
|
|
|
|
|
2018-08-10 06:19:23 +00:00
|
|
|
QString getGroupName(ProjectModel::GroupNode* group) const;
|
|
|
|
ProjectModel::GroupNode* getSelectedGroupNode() const;
|
|
|
|
QString getSelectedGroupName() const;
|
2018-08-11 06:31:10 +00:00
|
|
|
void _recursiveExpandOutline(const QModelIndex& filterIndex) const;
|
2018-08-10 06:19:23 +00:00
|
|
|
void recursiveExpandAndSelectOutline(const QModelIndex& index) const;
|
|
|
|
|
2018-07-28 04:34:29 +00:00
|
|
|
ProjectModel* projectModel() const { return m_projectModel; }
|
2018-08-11 06:31:10 +00:00
|
|
|
UIMessenger& uiMessenger() { return m_mainMessenger; }
|
2018-07-26 03:41:48 +00:00
|
|
|
|
2018-07-14 06:06:33 +00:00
|
|
|
public slots:
|
|
|
|
void newAction();
|
|
|
|
void openAction();
|
2018-07-28 04:34:29 +00:00
|
|
|
void openRecentFileAction();
|
|
|
|
void clearRecentFilesAction();
|
|
|
|
void saveAction();
|
|
|
|
void revertAction();
|
2018-07-29 03:37:06 +00:00
|
|
|
void reloadSampleDataAction();
|
2018-07-14 06:06:33 +00:00
|
|
|
void importAction();
|
2018-08-10 08:11:08 +00:00
|
|
|
void importSongsAction();
|
2018-07-14 06:06:33 +00:00
|
|
|
void exportAction();
|
|
|
|
|
2018-07-18 07:39:26 +00:00
|
|
|
void newSubprojectAction();
|
2018-07-14 06:06:33 +00:00
|
|
|
void newSFXGroupAction();
|
|
|
|
void newSongGroupAction();
|
|
|
|
void newSoundMacroAction();
|
2018-07-18 07:39:26 +00:00
|
|
|
void newADSRAction();
|
|
|
|
void newCurveAction();
|
2018-07-14 06:06:33 +00:00
|
|
|
void newKeymapAction();
|
|
|
|
void newLayersAction();
|
|
|
|
|
|
|
|
void aboutToShowAudioIOMenu();
|
|
|
|
void aboutToShowMIDIIOMenu();
|
|
|
|
|
|
|
|
void setAudioIO();
|
|
|
|
void setMIDIIO();
|
|
|
|
|
2018-07-28 04:34:29 +00:00
|
|
|
void notePressed(int key);
|
|
|
|
void noteReleased();
|
|
|
|
void velocityChanged(int vel);
|
|
|
|
void modulationChanged(int mod);
|
|
|
|
void pitchChanged(int pitch);
|
|
|
|
void killSounds();
|
|
|
|
|
|
|
|
void outlineCutAction();
|
|
|
|
void outlineCopyAction();
|
|
|
|
void outlinePasteAction();
|
|
|
|
void outlineDeleteAction();
|
|
|
|
|
2018-07-14 06:06:33 +00:00
|
|
|
void onFocusChanged(QWidget* old, QWidget* now);
|
2018-08-09 07:42:17 +00:00
|
|
|
void outlineItemActivated(const QModelIndex& index);
|
2018-08-07 07:09:23 +00:00
|
|
|
void setItemEditEnabled(bool enabled);
|
2018-08-10 06:19:23 +00:00
|
|
|
void setItemNewEnabled(bool enabled);
|
2018-07-28 04:34:29 +00:00
|
|
|
bool canEditOutline();
|
|
|
|
void onOutlineSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
|
2018-07-14 06:06:33 +00:00
|
|
|
void onTextSelect();
|
|
|
|
void onTextDelete();
|
|
|
|
|
2018-07-17 04:48:38 +00:00
|
|
|
void onBackgroundTaskFinished();
|
|
|
|
|
|
|
|
QMessageBox::StandardButton msgInformation(const QString &title,
|
|
|
|
const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::Ok,
|
|
|
|
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
|
|
|
|
QMessageBox::StandardButton msgQuestion(const QString &title,
|
|
|
|
const QString &text, QMessageBox::StandardButtons buttons =
|
|
|
|
QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::No),
|
|
|
|
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
|
|
|
|
QMessageBox::StandardButton msgWarning(const QString &title,
|
|
|
|
const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::Ok,
|
|
|
|
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
|
|
|
|
QMessageBox::StandardButton msgCritical(const QString &title,
|
|
|
|
const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::Ok,
|
|
|
|
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
|
|
|
|
|
2018-03-15 00:25:29 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2018-07-09 18:05:31 +00:00
|
|
|
#endif //AMUSE_MAINWINDOW_HPP
|