mirror of https://github.com/AxioDL/amuse.git
More work on Amuse Editor
This commit is contained in:
parent
3f265cdb46
commit
f50ee6e8f1
|
@ -0,0 +1,7 @@
|
||||||
|
#include "ADSREditor.hpp"
|
||||||
|
|
||||||
|
ADSREditor::ADSREditor(ProjectModel::ADSRNode* node, QWidget* parent)
|
||||||
|
: EditorWidget(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef AMUSE_ADSR_EDITOR_HPP
|
||||||
|
#define AMUSE_ADSR_EDITOR_HPP
|
||||||
|
|
||||||
|
#include "EditorWidget.hpp"
|
||||||
|
|
||||||
|
class ADSREditor : public EditorWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ADSREditor(ProjectModel::ADSRNode* node, QWidget* parent = Q_NULLPTR);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //AMUSE_ADSR_EDITOR_HPP
|
|
@ -28,15 +28,17 @@ add_executable(amuse-gui WIN32 MACOSX_BUNDLE
|
||||||
Common.hpp Common.cpp
|
Common.hpp Common.cpp
|
||||||
MainWindow.ui MainWindow.hpp MainWindow.cpp
|
MainWindow.ui MainWindow.hpp MainWindow.cpp
|
||||||
KeyboardWidget.hpp KeyboardWidget.cpp
|
KeyboardWidget.hpp KeyboardWidget.cpp
|
||||||
StatusBarWidget.hpp StatusBarWidget.cpp
|
StatusBarWidget.hpp
|
||||||
ProjectModel.hpp ProjectModel.cpp
|
ProjectModel.hpp ProjectModel.cpp
|
||||||
ProjectStatistics.hpp ProjectStatistics.cpp
|
ProjectStatistics.hpp ProjectStatistics.cpp
|
||||||
EditorWidget.hpp EditorWidget.cpp
|
EditorWidget.hpp EditorWidget.cpp
|
||||||
SoundMacroEditor.hpp SoundMacroEditor.cpp
|
SoundMacroEditor.hpp SoundMacroEditor.cpp
|
||||||
|
ADSREditor.hpp ADSREditor.cpp
|
||||||
|
CurveEditor.hpp CurveEditor.cpp
|
||||||
KeymapEditor.hpp KeymapEditor.cpp
|
KeymapEditor.hpp KeymapEditor.cpp
|
||||||
LayersEditor.hpp LayersEditor.cpp
|
LayersEditor.hpp LayersEditor.cpp
|
||||||
SampleEditor.hpp SampleEditor.cpp
|
SampleEditor.hpp SampleEditor.cpp
|
||||||
SFXGroupEditor.hpp SFXGroupEditor.cpp
|
SoundGroupEditor.hpp SoundGroupEditor.cpp
|
||||||
SongGroupEditor.hpp SongGroupEditor.cpp
|
SongGroupEditor.hpp SongGroupEditor.cpp
|
||||||
AudioGroupModel.hpp AudioGroupModel.cpp
|
AudioGroupModel.hpp AudioGroupModel.cpp
|
||||||
resources/resources.qrc qrc_resources.cpp
|
resources/resources.qrc qrc_resources.cpp
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
#include "CurveEditor.hpp"
|
||||||
|
|
||||||
|
CurveEditor::CurveEditor(ProjectModel::CurveNode* node, QWidget* parent)
|
||||||
|
: EditorWidget(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef AMUSE_CURVE_EDITOR_HPP
|
||||||
|
#define AMUSE_CURVE_EDITOR_HPP
|
||||||
|
|
||||||
|
#include "EditorWidget.hpp"
|
||||||
|
|
||||||
|
class CurveEditor : public EditorWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit CurveEditor(ProjectModel::CurveNode* node, QWidget* parent = Q_NULLPTR);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //AMUSE_CURVE_EDITOR_HPP
|
|
@ -2,12 +2,14 @@
|
||||||
#define AMUSE_EDITOR_WIDGET_HPP
|
#define AMUSE_EDITOR_WIDGET_HPP
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
#include "ProjectModel.hpp"
|
||||||
|
|
||||||
class EditorWidget : public QWidget
|
class EditorWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit EditorWidget(QWidget* parent = Q_NULLPTR);
|
explicit EditorWidget(QWidget* parent = Q_NULLPTR);
|
||||||
|
virtual bool valid() const { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,203 @@
|
||||||
#include "KeyboardWidget.hpp"
|
#include "KeyboardWidget.hpp"
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QSvgRenderer>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <QScrollArea>
|
||||||
|
|
||||||
|
/* Used for generating transform matrices to map coordinate space */
|
||||||
|
static QTransform RectToRect(const QRectF& from, const QRectF& to)
|
||||||
|
{
|
||||||
|
QPolygonF orig(from);
|
||||||
|
orig.pop_back();
|
||||||
|
QPolygonF resize(to);
|
||||||
|
resize.pop_back();
|
||||||
|
QTransform ret;
|
||||||
|
QTransform::quadToQuad(orig, resize, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const QString NaturalKeyNames[] =
|
||||||
|
{
|
||||||
|
QStringLiteral("C"),
|
||||||
|
QStringLiteral("D"),
|
||||||
|
QStringLiteral("E"),
|
||||||
|
QStringLiteral("F"),
|
||||||
|
QStringLiteral("G"),
|
||||||
|
QStringLiteral("A"),
|
||||||
|
QStringLiteral("B")
|
||||||
|
};
|
||||||
|
|
||||||
|
static const QString SharpKeyNames[] =
|
||||||
|
{
|
||||||
|
QStringLiteral("Cs"),
|
||||||
|
QStringLiteral("Ds"),
|
||||||
|
QStringLiteral("Fs"),
|
||||||
|
QStringLiteral("Gs"),
|
||||||
|
QStringLiteral("As")
|
||||||
|
};
|
||||||
|
|
||||||
|
static const QString KeyStrings[] =
|
||||||
|
{
|
||||||
|
QStringLiteral("C"),
|
||||||
|
QStringLiteral("C#"),
|
||||||
|
QStringLiteral("D"),
|
||||||
|
QStringLiteral("D#"),
|
||||||
|
QStringLiteral("E"),
|
||||||
|
QStringLiteral("F"),
|
||||||
|
QStringLiteral("F#"),
|
||||||
|
QStringLiteral("G"),
|
||||||
|
QStringLiteral("G#"),
|
||||||
|
QStringLiteral("A"),
|
||||||
|
QStringLiteral("A#"),
|
||||||
|
QStringLiteral("B")
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int NaturalKeyNumbers[] =
|
||||||
|
{
|
||||||
|
0, 2, 4, 5, 7, 9, 11
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int SharpKeyNumbers[] =
|
||||||
|
{
|
||||||
|
1, 3, 6, 8, 10
|
||||||
|
};
|
||||||
|
|
||||||
|
KeyboardOctave::KeyboardOctave(int octave, const QString& svgPath, QWidget* parent)
|
||||||
|
: QSvgWidget(svgPath, parent), m_octave(octave)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 7; ++i)
|
||||||
|
if (renderer()->elementExists(NaturalKeyNames[i]))
|
||||||
|
m_natural[i] = renderer()->matrixForElement(NaturalKeyNames[i]).
|
||||||
|
mapRect(renderer()->boundsOnElement(NaturalKeyNames[i]));
|
||||||
|
|
||||||
|
for (int i = 0; i < 5; ++i)
|
||||||
|
if (renderer()->elementExists(SharpKeyNames[i]))
|
||||||
|
m_sharp[i] = renderer()->matrixForElement(SharpKeyNames[i]).
|
||||||
|
mapRect(renderer()->boundsOnElement(SharpKeyNames[i]));
|
||||||
|
|
||||||
|
/* The parent keyboard manages all mouse events */
|
||||||
|
setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
}
|
||||||
|
|
||||||
|
int KeyboardOctave::getKey(const QPoint& localPos) const
|
||||||
|
{
|
||||||
|
QPointF localPoint = m_widgetToSvg.map(localPos);
|
||||||
|
for (int i = 0; i < 5; ++i)
|
||||||
|
if (m_sharp[i].contains(localPoint))
|
||||||
|
return SharpKeyNumbers[i];
|
||||||
|
for (int i = 0; i < 7; ++i)
|
||||||
|
if (m_natural[i].contains(localPoint))
|
||||||
|
return NaturalKeyNumbers[i];
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardOctave::resizeEvent(QResizeEvent *event)
|
||||||
|
{
|
||||||
|
m_widgetToSvg = RectToRect(rect(), renderer()->viewBoxF());
|
||||||
|
}
|
||||||
|
|
||||||
KeyboardWidget::KeyboardWidget(QWidget* parent)
|
KeyboardWidget::KeyboardWidget(QWidget* parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
{
|
{
|
||||||
|
QHBoxLayout* layout = new QHBoxLayout(this);
|
||||||
|
layout->setContentsMargins(QMargins());
|
||||||
|
layout->setSpacing(0);
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; ++i)
|
||||||
|
{
|
||||||
|
m_widgets[i] = new KeyboardOctave(i, QStringLiteral(":/bg/keyboard.svg"), this);
|
||||||
|
m_widgets[i]->setGeometry(QRect(0, 0, 141, 50));
|
||||||
|
m_widgets[i]->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred));
|
||||||
|
layout->addWidget(m_widgets[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_widgets[10] = new KeyboardOctave(10, QStringLiteral(":/bg/keyboard_last.svg"), this);
|
||||||
|
m_widgets[10]->setGeometry(QRect(0, 0, 101, 50));
|
||||||
|
m_widgets[10]->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred));
|
||||||
|
layout->addWidget(m_widgets[10]);
|
||||||
|
|
||||||
|
setLayout(layout);
|
||||||
|
setMouseTracking(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<int, int> KeyboardWidget::_getOctaveAndKey(QMouseEvent* event) const
|
||||||
|
{
|
||||||
|
for (KeyboardOctave* oct : m_widgets)
|
||||||
|
{
|
||||||
|
QPoint localPos = oct->mapFromParent(event->pos());
|
||||||
|
if (oct->rect().contains(localPos))
|
||||||
|
return {oct->getOctave(), oct->getKey(localPos)};
|
||||||
|
}
|
||||||
|
return {-1, -1};
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardWidget::_startKey(int octave, int key)
|
||||||
|
{
|
||||||
|
printf("START %d %d\n", octave, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardWidget::_stopKey()
|
||||||
|
{
|
||||||
|
printf("STOP\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardWidget::_moveOnKey(int octave, int key)
|
||||||
|
{
|
||||||
|
if (m_lastOctave != octave || m_lastKey != key)
|
||||||
|
{
|
||||||
|
m_lastOctave = octave;
|
||||||
|
m_lastKey = key;
|
||||||
|
if (m_statusFocus)
|
||||||
|
m_statusFocus->setMessage(QStringLiteral("%1%2").arg(KeyStrings[key]).arg(octave - 1));
|
||||||
|
if (m_holding)
|
||||||
|
_startKey(octave, key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardWidget::_pressOnKey(int octave, int key)
|
||||||
|
{
|
||||||
|
_moveOnKey(octave, key);
|
||||||
|
m_holding = true;
|
||||||
|
_startKey(octave, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardWidget::mouseMoveEvent(QMouseEvent* event)
|
||||||
|
{
|
||||||
|
std::pair<int, int> ok = _getOctaveAndKey(event);
|
||||||
|
if (ok.first != -1 && ok.second != -1)
|
||||||
|
_moveOnKey(ok.first, ok.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardWidget::mousePressEvent(QMouseEvent* event)
|
||||||
|
{
|
||||||
|
std::pair<int, int> ok = _getOctaveAndKey(event);
|
||||||
|
if (ok.first != -1 && ok.second != -1)
|
||||||
|
_pressOnKey(ok.first, ok.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardWidget::mouseReleaseEvent(QMouseEvent* event)
|
||||||
|
{
|
||||||
|
_stopKey();
|
||||||
|
m_holding = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardWidget::enterEvent(QEvent* event)
|
||||||
|
{
|
||||||
|
if (m_statusFocus)
|
||||||
|
m_statusFocus->enter();
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardWidget::leaveEvent(QEvent* event)
|
||||||
|
{
|
||||||
|
if (m_statusFocus)
|
||||||
|
m_statusFocus->exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardWidget::showEvent(QShowEvent* event)
|
||||||
|
{
|
||||||
|
if (QScrollArea* scroll = qobject_cast<QScrollArea*>(parentWidget()->parentWidget()))
|
||||||
|
{
|
||||||
|
/* Scroll to C3 */
|
||||||
|
scroll->ensureVisible(141 * 4 + scroll->width(), 0, 0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,50 @@
|
||||||
#define AMUSE_KEYBOARD_WIDGET_HPP
|
#define AMUSE_KEYBOARD_WIDGET_HPP
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
#include <QSvgWidget>
|
||||||
|
#include "StatusBarWidget.hpp"
|
||||||
|
|
||||||
|
class KeyboardWidget;
|
||||||
|
|
||||||
|
class KeyboardOctave : public QSvgWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
int m_octave;
|
||||||
|
QRectF m_natural[7];
|
||||||
|
QRectF m_sharp[5];
|
||||||
|
QTransform m_widgetToSvg;
|
||||||
|
public:
|
||||||
|
explicit KeyboardOctave(int octave, const QString& svgPath, QWidget* parent = Q_NULLPTR);
|
||||||
|
int getOctave() const { return m_octave; }
|
||||||
|
int getKey(const QPoint& localPos) const;
|
||||||
|
void resizeEvent(QResizeEvent *event);
|
||||||
|
};
|
||||||
|
|
||||||
class KeyboardWidget : public QWidget
|
class KeyboardWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
KeyboardOctave* m_widgets[11];
|
||||||
|
StatusBarFocus* m_statusFocus = nullptr;
|
||||||
|
int m_lastOctave = -1;
|
||||||
|
int m_lastKey = -1;
|
||||||
|
bool m_holding = false;
|
||||||
|
|
||||||
|
std::pair<int, int> _getOctaveAndKey(QMouseEvent* event) const;
|
||||||
|
void _startKey(int octave, int key);
|
||||||
|
void _stopKey();
|
||||||
|
void _moveOnKey(int octave, int key);
|
||||||
|
void _pressOnKey(int octave, int key);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit KeyboardWidget(QWidget* parent = Q_NULLPTR);
|
explicit KeyboardWidget(QWidget* parent = Q_NULLPTR);
|
||||||
|
void setStatusFocus(StatusBarFocus* statusFocus) { m_statusFocus = statusFocus; }
|
||||||
|
|
||||||
|
void mouseMoveEvent(QMouseEvent* event);
|
||||||
|
void mousePressEvent(QMouseEvent* event);
|
||||||
|
void mouseReleaseEvent(QMouseEvent* event);
|
||||||
|
void enterEvent(QEvent* event);
|
||||||
|
void leaveEvent(QEvent* event);
|
||||||
|
void showEvent(QShowEvent *event);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "KeymapEditor.hpp"
|
#include "KeymapEditor.hpp"
|
||||||
|
|
||||||
KeymapEditor::KeymapEditor(QWidget* parent)
|
KeymapEditor::KeymapEditor(ProjectModel::KeymapNode* node, QWidget* parent)
|
||||||
: EditorWidget(parent)
|
: EditorWidget(parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ class KeymapEditor : public EditorWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit KeymapEditor(QWidget* parent = Q_NULLPTR);
|
explicit KeymapEditor(ProjectModel::KeymapNode* node, QWidget* parent = Q_NULLPTR);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "LayersEditor.hpp"
|
#include "LayersEditor.hpp"
|
||||||
|
|
||||||
LayersEditor::LayersEditor(QWidget* parent)
|
LayersEditor::LayersEditor(ProjectModel::LayersNode* node, QWidget* parent)
|
||||||
: EditorWidget(parent)
|
: EditorWidget(parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ class LayersEditor : public EditorWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit LayersEditor(QWidget* parent = Q_NULLPTR);
|
explicit LayersEditor(ProjectModel::LayersNode* node, QWidget* parent = Q_NULLPTR);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,18 @@
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <QProgressDialog>
|
#include <QProgressDialog>
|
||||||
|
#include <QMouseEvent>
|
||||||
#include <QtSvg/QtSvg>
|
#include <QtSvg/QtSvg>
|
||||||
#include "amuse/ContainerRegistry.hpp"
|
#include "amuse/ContainerRegistry.hpp"
|
||||||
#include "Common.hpp"
|
#include "Common.hpp"
|
||||||
|
#include "SongGroupEditor.hpp"
|
||||||
|
#include "SoundGroupEditor.hpp"
|
||||||
|
#include "SoundGroupEditor.hpp"
|
||||||
|
#include "SoundMacroEditor.hpp"
|
||||||
|
#include "ADSREditor.hpp"
|
||||||
|
#include "CurveEditor.hpp"
|
||||||
|
#include "KeymapEditor.hpp"
|
||||||
|
#include "LayersEditor.hpp"
|
||||||
|
|
||||||
static void connectMessenger(UIMessenger* messenger, Qt::ConnectionType type)
|
static void connectMessenger(UIMessenger* messenger, Qt::ConnectionType type)
|
||||||
{
|
{
|
||||||
|
@ -15,6 +24,7 @@ static void connectMessenger(UIMessenger* messenger, Qt::ConnectionType type)
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget* parent)
|
MainWindow::MainWindow(QWidget* parent)
|
||||||
: QMainWindow(parent),
|
: QMainWindow(parent),
|
||||||
|
m_treeDelegate(*this, this),
|
||||||
m_mainMessenger(this),
|
m_mainMessenger(this),
|
||||||
m_undoStack(new QUndoStack(this)),
|
m_undoStack(new QUndoStack(this)),
|
||||||
m_backgroundThread(this)
|
m_backgroundThread(this)
|
||||||
|
@ -22,8 +32,11 @@ MainWindow::MainWindow(QWidget* parent)
|
||||||
m_backgroundThread.start();
|
m_backgroundThread.start();
|
||||||
|
|
||||||
m_ui.setupUi(this);
|
m_ui.setupUi(this);
|
||||||
|
m_ui.projectOutline->setItemDelegate(&m_treeDelegate);
|
||||||
connectMessenger(&m_mainMessenger, Qt::DirectConnection);
|
connectMessenger(&m_mainMessenger, Qt::DirectConnection);
|
||||||
|
|
||||||
|
m_ui.keyboardContents->setStatusFocus(new StatusBarFocus(m_ui.statusbar));
|
||||||
|
|
||||||
m_ui.actionNew_Project->setShortcut(QKeySequence::New);
|
m_ui.actionNew_Project->setShortcut(QKeySequence::New);
|
||||||
connect(m_ui.actionNew_Project, SIGNAL(triggered()), this, SLOT(newAction()));
|
connect(m_ui.actionNew_Project, SIGNAL(triggered()), this, SLOT(newAction()));
|
||||||
m_ui.actionOpen_Project->setShortcut(QKeySequence::Open);
|
m_ui.actionOpen_Project->setShortcut(QKeySequence::Open);
|
||||||
|
@ -45,11 +58,21 @@ MainWindow::MainWindow(QWidget* parent)
|
||||||
m_ui.actionDelete->setShortcut(QKeySequence::Delete);
|
m_ui.actionDelete->setShortcut(QKeySequence::Delete);
|
||||||
onFocusChanged(nullptr, this);
|
onFocusChanged(nullptr, this);
|
||||||
|
|
||||||
m_ui.editorSvg->load(QStringLiteral(":/bg/FaceGrey.svg"));
|
QGridLayout* faceLayout = new QGridLayout;
|
||||||
|
QSvgWidget* faceSvg = new QSvgWidget(QStringLiteral(":/bg/FaceGrey.svg"));
|
||||||
|
faceSvg->setGeometry(0, 0, 256, 256);
|
||||||
|
faceSvg->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
|
||||||
|
faceLayout->addWidget(faceSvg);
|
||||||
|
m_faceSvg = new QWidget;
|
||||||
|
m_faceSvg->setLayout(faceLayout);
|
||||||
|
m_ui.editorContents->addWidget(m_faceSvg);
|
||||||
|
|
||||||
|
connect(m_ui.actionNew_Subproject, SIGNAL(triggered()), this, SLOT(newSubprojectAction()));
|
||||||
connect(m_ui.actionNew_SFX_Group, SIGNAL(triggered()), this, SLOT(newSFXGroupAction()));
|
connect(m_ui.actionNew_SFX_Group, SIGNAL(triggered()), this, SLOT(newSFXGroupAction()));
|
||||||
connect(m_ui.actionNew_Song_Group, SIGNAL(triggered()), this, SLOT(newSongGroupAction()));
|
connect(m_ui.actionNew_Song_Group, SIGNAL(triggered()), this, SLOT(newSongGroupAction()));
|
||||||
connect(m_ui.actionNew_Sound_Macro, SIGNAL(triggered()), this, SLOT(newSoundMacroAction()));
|
connect(m_ui.actionNew_Sound_Macro, SIGNAL(triggered()), this, SLOT(newSoundMacroAction()));
|
||||||
|
connect(m_ui.actionNew_ADSR, SIGNAL(triggered()), this, SLOT(newADSRAction()));
|
||||||
|
connect(m_ui.actionNew_Curve, SIGNAL(triggered()), this, SLOT(newCurveAction()));
|
||||||
connect(m_ui.actionNew_Keymap, SIGNAL(triggered()), this, SLOT(newKeymapAction()));
|
connect(m_ui.actionNew_Keymap, SIGNAL(triggered()), this, SLOT(newKeymapAction()));
|
||||||
connect(m_ui.actionNew_Layers, SIGNAL(triggered()), this, SLOT(newLayersAction()));
|
connect(m_ui.actionNew_Layers, SIGNAL(triggered()), this, SLOT(newLayersAction()));
|
||||||
|
|
||||||
|
@ -128,6 +151,9 @@ bool MainWindow::setProjectPath(const QString& path)
|
||||||
m_ui.projectOutline->setModel(m_projectModel);
|
m_ui.projectOutline->setModel(m_projectModel);
|
||||||
m_ui.actionExport_GameCube_Groups->setEnabled(true);
|
m_ui.actionExport_GameCube_Groups->setEnabled(true);
|
||||||
setWindowFilePath(path);
|
setWindowFilePath(path);
|
||||||
|
#ifndef __APPLE__
|
||||||
|
setWindowTitle(QString("Amuse - %1").arg(dir.dirName()));
|
||||||
|
#endif
|
||||||
setFocusAudioGroup(nullptr);
|
setFocusAudioGroup(nullptr);
|
||||||
onFocusChanged(nullptr, focusWidget());
|
onFocusChanged(nullptr, focusWidget());
|
||||||
|
|
||||||
|
@ -217,6 +243,88 @@ void MainWindow::startBackgroundTask(const QString& windowTitle, const QString&
|
||||||
QMetaObject::invokeMethod(m_backgroundTask, "run", Qt::QueuedConnection);
|
QMetaObject::invokeMethod(m_backgroundTask, "run", Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MainWindow::_setEditor(EditorWidget* editor)
|
||||||
|
{
|
||||||
|
while (m_ui.editorContents->currentWidget() != m_faceSvg)
|
||||||
|
{
|
||||||
|
m_ui.editorContents->currentWidget()->deleteLater();
|
||||||
|
m_ui.editorContents->removeWidget(m_ui.editorContents->currentWidget());
|
||||||
|
}
|
||||||
|
if (!editor)
|
||||||
|
return false;
|
||||||
|
if (!editor->valid())
|
||||||
|
{
|
||||||
|
editor->deleteLater();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_ui.editorContents->addWidget(editor);
|
||||||
|
m_ui.editorContents->setCurrentWidget(editor);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::openEditor(ProjectModel::SongGroupNode* node)
|
||||||
|
{
|
||||||
|
return _setEditor(new SongGroupEditor(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::openEditor(ProjectModel::SoundGroupNode* node)
|
||||||
|
{
|
||||||
|
return _setEditor(new SoundGroupEditor(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::openEditor(ProjectModel::SoundMacroNode* node)
|
||||||
|
{
|
||||||
|
return _setEditor(new SoundMacroEditor(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::openEditor(ProjectModel::ADSRNode* node)
|
||||||
|
{
|
||||||
|
return _setEditor(new ADSREditor(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::openEditor(ProjectModel::CurveNode* node)
|
||||||
|
{
|
||||||
|
return _setEditor(new CurveEditor(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::openEditor(ProjectModel::KeymapNode* node)
|
||||||
|
{
|
||||||
|
return _setEditor(new KeymapEditor(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::openEditor(ProjectModel::LayersNode* node)
|
||||||
|
{
|
||||||
|
return _setEditor(new LayersEditor(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::openEditor(ProjectModel::INode* node)
|
||||||
|
{
|
||||||
|
switch (node->type())
|
||||||
|
{
|
||||||
|
case ProjectModel::INode::Type::SongGroup:
|
||||||
|
return openEditor(static_cast<ProjectModel::SongGroupNode*>(node));
|
||||||
|
case ProjectModel::INode::Type::SoundGroup:
|
||||||
|
return openEditor(static_cast<ProjectModel::SoundGroupNode*>(node));
|
||||||
|
case ProjectModel::INode::Type::SoundMacro:
|
||||||
|
return openEditor(static_cast<ProjectModel::SoundMacroNode*>(node));
|
||||||
|
case ProjectModel::INode::Type::ADSR:
|
||||||
|
return openEditor(static_cast<ProjectModel::ADSRNode*>(node));
|
||||||
|
case ProjectModel::INode::Type::Curve:
|
||||||
|
return openEditor(static_cast<ProjectModel::CurveNode*>(node));
|
||||||
|
case ProjectModel::INode::Type::Keymap:
|
||||||
|
return openEditor(static_cast<ProjectModel::KeymapNode*>(node));
|
||||||
|
case ProjectModel::INode::Type::Layer:
|
||||||
|
return openEditor(static_cast<ProjectModel::LayersNode*>(node));
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::closeEditor()
|
||||||
|
{
|
||||||
|
_setEditor(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::newAction()
|
void MainWindow::newAction()
|
||||||
{
|
{
|
||||||
QString path = QFileDialog::getSaveFileName(this, tr("New Project"));
|
QString path = QFileDialog::getSaveFileName(this, tr("New Project"));
|
||||||
|
@ -226,6 +334,9 @@ void MainWindow::newAction()
|
||||||
return;
|
return;
|
||||||
if (!setProjectPath(path))
|
if (!setProjectPath(path))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
m_projectModel->clearProjectData();
|
||||||
|
m_projectModel->ensureModelData();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::openAction()
|
void MainWindow::openAction()
|
||||||
|
@ -233,10 +344,41 @@ void MainWindow::openAction()
|
||||||
QString path = QFileDialog::getExistingDirectory(this, tr("Open Project"));
|
QString path = QFileDialog::getExistingDirectory(this, tr("Open Project"));
|
||||||
if (path.isEmpty())
|
if (path.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
QDir dir(path);
|
||||||
|
if (!dir.exists())
|
||||||
|
{
|
||||||
|
QString msg = QString(tr("The directory at '%1' does not exist.")).arg(path);
|
||||||
|
QMessageBox::critical(this, tr("Bad Directory"), msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (QFileInfo(dir, QStringLiteral("!project.yaml")).exists() &&
|
||||||
|
QFileInfo(dir, QStringLiteral("!pool.yaml")).exists())
|
||||||
|
dir.cdUp();
|
||||||
|
|
||||||
if (!setProjectPath(path))
|
if (!setProjectPath(path))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
ProjectModel* model = m_projectModel;
|
||||||
|
startBackgroundTask(tr("Opening"), tr("Scanning Project"),
|
||||||
|
[dir, model](BackgroundTask& task)
|
||||||
|
{
|
||||||
|
QStringList childDirs = dir.entryList(QDir::Dirs);
|
||||||
|
for (const auto& chDir : childDirs)
|
||||||
|
{
|
||||||
|
if (task.isCanceled())
|
||||||
|
return;
|
||||||
|
QString chPath = dir.filePath(chDir);
|
||||||
|
if (QFileInfo(chPath, QStringLiteral("!project.yaml")).exists() &&
|
||||||
|
QFileInfo(chPath, QStringLiteral("!pool.yaml")).exists())
|
||||||
|
{
|
||||||
|
task.setLabelText(tr("Opening %1").arg(chDir));
|
||||||
|
if (!model->openGroupData(chDir, task.uiMessenger()))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::importAction()
|
void MainWindow::importAction()
|
||||||
|
@ -372,6 +514,33 @@ void MainWindow::exportAction()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TreeDelegate::editorEvent(QEvent* event,
|
||||||
|
QAbstractItemModel* _model,
|
||||||
|
const QStyleOptionViewItem& option,
|
||||||
|
const QModelIndex& index)
|
||||||
|
{
|
||||||
|
ProjectModel* model = static_cast<ProjectModel*>(_model);
|
||||||
|
ProjectModel::INode* node = model->node(index);
|
||||||
|
if (!node)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ((event->type() == QEvent::MouseButtonDblClick &&
|
||||||
|
static_cast<QMouseEvent*>(event)->button() == Qt::LeftButton) ||
|
||||||
|
(event->type() == QEvent::KeyPress &&
|
||||||
|
static_cast<QKeyEvent*>(event)->key() == Qt::Key_Enter))
|
||||||
|
{
|
||||||
|
// Open in editor
|
||||||
|
return m_window.openEditor(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::newSubprojectAction()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::newSFXGroupAction()
|
void MainWindow::newSFXGroupAction()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -387,6 +556,16 @@ void MainWindow::newSoundMacroAction()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::newADSRAction()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::newCurveAction()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::newKeymapAction()
|
void MainWindow::newKeymapAction()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -5,16 +5,19 @@
|
||||||
#include <QUndoStack>
|
#include <QUndoStack>
|
||||||
#include <QProgressDialog>
|
#include <QProgressDialog>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
#include "ui_MainWindow.h"
|
#include "ui_MainWindow.h"
|
||||||
#include "amuse/Engine.hpp"
|
#include "amuse/Engine.hpp"
|
||||||
#include "amuse/BooBackend.hpp"
|
#include "amuse/BooBackend.hpp"
|
||||||
#include "boo/audiodev/IAudioVoiceEngine.hpp"
|
#include "boo/audiodev/IAudioVoiceEngine.hpp"
|
||||||
#include "ProjectModel.hpp"
|
#include "ProjectModel.hpp"
|
||||||
|
#include "EditorWidget.hpp"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class MainWindow;
|
class MainWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MainWindow;
|
||||||
class AudioGroupModel;
|
class AudioGroupModel;
|
||||||
|
|
||||||
class BackgroundTask : public QObject
|
class BackgroundTask : public QObject
|
||||||
|
@ -41,13 +44,29 @@ public slots:
|
||||||
void cancel() { m_cancelled = true; }
|
void cancel() { m_cancelled = true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
|
||||||
class MainWindow : public QMainWindow
|
class MainWindow : public QMainWindow
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Ui::MainWindow m_ui;
|
Ui::MainWindow m_ui;
|
||||||
|
TreeDelegate m_treeDelegate;
|
||||||
UIMessenger m_mainMessenger;
|
UIMessenger m_mainMessenger;
|
||||||
ProjectModel* m_projectModel = nullptr;
|
ProjectModel* m_projectModel = nullptr;
|
||||||
AudioGroupModel* m_focusAudioGroup = nullptr;
|
AudioGroupModel* m_focusAudioGroup = nullptr;
|
||||||
|
QWidget* m_faceSvg;
|
||||||
|
|
||||||
std::unique_ptr<boo::IAudioVoiceEngine> m_voxEngine;
|
std::unique_ptr<boo::IAudioVoiceEngine> m_voxEngine;
|
||||||
std::unique_ptr<amuse::BooBackendVoiceAllocator> m_voxAllocator;
|
std::unique_ptr<amuse::BooBackendVoiceAllocator> m_voxAllocator;
|
||||||
|
@ -79,19 +98,34 @@ class MainWindow : public QMainWindow
|
||||||
void startBackgroundTask(const QString& windowTitle, const QString& label,
|
void startBackgroundTask(const QString& windowTitle, const QString& label,
|
||||||
std::function<void(BackgroundTask&)>&& task);
|
std::function<void(BackgroundTask&)>&& task);
|
||||||
|
|
||||||
|
bool _setEditor(EditorWidget* widget);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MainWindow(QWidget* parent = Q_NULLPTR);
|
explicit MainWindow(QWidget* parent = Q_NULLPTR);
|
||||||
~MainWindow();
|
~MainWindow();
|
||||||
|
|
||||||
|
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);
|
||||||
|
bool openEditor(ProjectModel::INode* node);
|
||||||
|
void closeEditor();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void newAction();
|
void newAction();
|
||||||
void openAction();
|
void openAction();
|
||||||
void importAction();
|
void importAction();
|
||||||
void exportAction();
|
void exportAction();
|
||||||
|
|
||||||
|
void newSubprojectAction();
|
||||||
void newSFXGroupAction();
|
void newSFXGroupAction();
|
||||||
void newSongGroupAction();
|
void newSongGroupAction();
|
||||||
void newSoundMacroAction();
|
void newSoundMacroAction();
|
||||||
|
void newADSRAction();
|
||||||
|
void newCurveAction();
|
||||||
void newKeymapAction();
|
void newKeymapAction();
|
||||||
void newLayersAction();
|
void newLayersAction();
|
||||||
|
|
||||||
|
|
|
@ -35,10 +35,6 @@
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QSplitter" name="leftSplitter">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<widget class="QTreeView" name="projectOutline">
|
<widget class="QTreeView" name="projectOutline">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
@ -52,25 +48,13 @@
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="animated">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
<attribute name="headerVisible">
|
<attribute name="headerVisible">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</attribute>
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QTableView" name="propertyEditor">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>2</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>200</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
<widget class="QSplitter" name="rightSplitter">
|
<widget class="QSplitter" name="rightSplitter">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
@ -109,7 +93,7 @@
|
||||||
<property name="widgetResizable">
|
<property name="widgetResizable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="editorContents">
|
<widget class="QStackedWidget" name="editorContents">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
|
@ -118,24 +102,6 @@
|
||||||
<height>442</height>
|
<height>442</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QSvgWidget" name="editorSvg" native="true">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>256</width>
|
|
||||||
<height>256</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QScrollArea" name="keyboardScrollArea">
|
<widget class="QScrollArea" name="keyboardScrollArea">
|
||||||
|
@ -174,10 +140,22 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>540</width>
|
<width>1501</width>
|
||||||
<height>100</height>
|
<height>85</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>1501</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="maximumSize">
|
<property name="maximumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>16777215</width>
|
<width>16777215</width>
|
||||||
|
@ -213,10 +191,14 @@
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>P&roject</string>
|
<string>P&roject</string>
|
||||||
</property>
|
</property>
|
||||||
|
<addaction name="actionNew_Subproject"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
<addaction name="actionNew_SFX_Group"/>
|
<addaction name="actionNew_SFX_Group"/>
|
||||||
<addaction name="actionNew_Song_Group"/>
|
<addaction name="actionNew_Song_Group"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionNew_Sound_Macro"/>
|
<addaction name="actionNew_Sound_Macro"/>
|
||||||
|
<addaction name="actionNew_ADSR"/>
|
||||||
|
<addaction name="actionNew_Curve"/>
|
||||||
<addaction name="actionNew_Keymap"/>
|
<addaction name="actionNew_Keymap"/>
|
||||||
<addaction name="actionNew_Layers"/>
|
<addaction name="actionNew_Layers"/>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -418,6 +400,42 @@
|
||||||
<string>Ctrl+E</string>
|
<string>Ctrl+E</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionNew_Subproject">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset>
|
||||||
|
<normaloff>:/icons/IconNewGroup.svg</normaloff>:/icons/IconNewGroup.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>N&ew Subproject</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionNew_ADSR">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset>
|
||||||
|
<normaloff>:/icons/IconNewADSR.svg</normaloff>:/icons/IconNewADSR.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Ne&w ADSR</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionNew_Curve">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset>
|
||||||
|
<normaloff>:/icons/IconNewCurve.svg</normaloff>:/icons/IconNewCurve.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>New &Curve</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
@ -431,12 +449,6 @@
|
||||||
<extends>QStatusBar</extends>
|
<extends>QStatusBar</extends>
|
||||||
<header>StatusBarWidget.hpp</header>
|
<header>StatusBarWidget.hpp</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
|
||||||
<class>QSvgWidget</class>
|
|
||||||
<extends>QWidget</extends>
|
|
||||||
<header location="global">QSvgWidget</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
|
|
@ -18,6 +18,25 @@ ProjectModel::ProjectModel(const QString& path, QObject* parent)
|
||||||
SoundGroupNode::Icon = QIcon(":/icons/IconSoundGroup.svg");
|
SoundGroupNode::Icon = QIcon(":/icons/IconSoundGroup.svg");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ProjectModel::clearProjectData()
|
||||||
|
{
|
||||||
|
m_projectDatabase = amuse::ProjectDatabase();
|
||||||
|
m_groups.clear();
|
||||||
|
|
||||||
|
m_needsReset = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProjectModel::openGroupData(const QString& groupName, UIMessenger& messenger)
|
||||||
|
{
|
||||||
|
m_projectDatabase.setIdDatabases();
|
||||||
|
QString path = QFileInfo(m_dir, groupName).filePath();
|
||||||
|
m_groups.insert(std::make_pair(groupName, QStringToSysString(path)));
|
||||||
|
|
||||||
|
m_needsReset = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ProjectModel::importGroupData(const QString& groupName, const amuse::AudioGroupData& data,
|
bool ProjectModel::importGroupData(const QString& groupName, const amuse::AudioGroupData& data,
|
||||||
ImportMode mode, UIMessenger& messenger)
|
ImportMode mode, UIMessenger& messenger)
|
||||||
{
|
{
|
||||||
|
@ -89,12 +108,13 @@ void ProjectModel::_resetModelData()
|
||||||
{
|
{
|
||||||
it->second.setIdDatabases();
|
it->second.setIdDatabases();
|
||||||
GroupNode& gn = m_root->makeChild<GroupNode>(it);
|
GroupNode& gn = m_root->makeChild<GroupNode>(it);
|
||||||
auto& songGroups = it->second.getProj().songGroups();
|
amuse::AudioGroup& group = it->second;
|
||||||
auto& sfxGroups = it->second.getProj().sfxGroups();
|
auto& songGroups = group.getProj().songGroups();
|
||||||
auto& soundMacros = it->second.getPool().soundMacros();
|
auto& sfxGroups = group.getProj().sfxGroups();
|
||||||
auto& tables = it->second.getPool().tables();
|
auto& soundMacros = group.getPool().soundMacros();
|
||||||
auto& keymaps = it->second.getPool().keymaps();
|
auto& tables = group.getPool().tables();
|
||||||
auto& layers = it->second.getPool().layers();
|
auto& keymaps = group.getPool().keymaps();
|
||||||
|
auto& layers = group.getPool().layers();
|
||||||
gn.reserve(songGroups.size() + sfxGroups.size() + 4);
|
gn.reserve(songGroups.size() + sfxGroups.size() + 4);
|
||||||
for (const auto& grp : SortUnorderedMap(songGroups))
|
for (const auto& grp : SortUnorderedMap(songGroups))
|
||||||
gn.makeChild<SongGroupNode>(grp.first, grp.second.get());
|
gn.makeChild<SongGroupNode>(grp.first, grp.second.get());
|
||||||
|
@ -106,7 +126,7 @@ void ProjectModel::_resetModelData()
|
||||||
gn.makeChild<CollectionNode>(tr("Sound Macros"), QIcon(":/icons/IconSoundMacro.svg"));
|
gn.makeChild<CollectionNode>(tr("Sound Macros"), QIcon(":/icons/IconSoundMacro.svg"));
|
||||||
col.reserve(soundMacros.size());
|
col.reserve(soundMacros.size());
|
||||||
for (const auto& macro : SortUnorderedMap(soundMacros))
|
for (const auto& macro : SortUnorderedMap(soundMacros))
|
||||||
col.makeChild<PoolObjectNode<amuse::SoundMacroId, amuse::SoundMacro>>(macro.first, macro.second.get());
|
col.makeChild<SoundMacroNode>(macro.first, macro.second.get());
|
||||||
}
|
}
|
||||||
if (tables.size())
|
if (tables.size())
|
||||||
{
|
{
|
||||||
|
@ -130,7 +150,7 @@ void ProjectModel::_resetModelData()
|
||||||
{
|
{
|
||||||
amuse::ITable::Type tp = t.second.get()->Isa();
|
amuse::ITable::Type tp = t.second.get()->Isa();
|
||||||
if (tp == amuse::ITable::Type::ADSR || tp == amuse::ITable::Type::ADSRDLS)
|
if (tp == amuse::ITable::Type::ADSR || tp == amuse::ITable::Type::ADSRDLS)
|
||||||
col.makeChild<PoolObjectNode<amuse::TableId, amuse::ITable>>(t.first, *t.second.get());
|
col.makeChild<ADSRNode>(t.first, *t.second.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (curveCount)
|
if (curveCount)
|
||||||
|
@ -142,7 +162,7 @@ void ProjectModel::_resetModelData()
|
||||||
{
|
{
|
||||||
amuse::ITable::Type tp = t.second.get()->Isa();
|
amuse::ITable::Type tp = t.second.get()->Isa();
|
||||||
if (tp == amuse::ITable::Type::Curve)
|
if (tp == amuse::ITable::Type::Curve)
|
||||||
col.makeChild<PoolObjectNode<amuse::TableId, amuse::Curve>>(t.first, static_cast<amuse::Curve&>(*t.second.get()));
|
col.makeChild<CurveNode>(t.first, static_cast<amuse::Curve&>(*t.second.get()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,7 +172,7 @@ void ProjectModel::_resetModelData()
|
||||||
gn.makeChild<CollectionNode>(tr("Keymaps"), QIcon(":/icons/IconKeymap.svg"));
|
gn.makeChild<CollectionNode>(tr("Keymaps"), QIcon(":/icons/IconKeymap.svg"));
|
||||||
col.reserve(keymaps.size());
|
col.reserve(keymaps.size());
|
||||||
for (auto& keymap : SortUnorderedMap(keymaps))
|
for (auto& keymap : SortUnorderedMap(keymaps))
|
||||||
col.makeChild<PoolObjectNode<amuse::KeymapId, amuse::Keymap>>(keymap.first, keymap.second.get());
|
col.makeChild<KeymapNode>(keymap.first, keymap.second.get());
|
||||||
}
|
}
|
||||||
if (layers.size())
|
if (layers.size())
|
||||||
{
|
{
|
||||||
|
@ -160,7 +180,7 @@ void ProjectModel::_resetModelData()
|
||||||
gn.makeChild<CollectionNode>(tr("Layers"), QIcon(":/icons/IconLayers.svg"));
|
gn.makeChild<CollectionNode>(tr("Layers"), QIcon(":/icons/IconLayers.svg"));
|
||||||
col.reserve(layers.size());
|
col.reserve(layers.size());
|
||||||
for (auto& keymap : SortUnorderedMap(layers))
|
for (auto& keymap : SortUnorderedMap(layers))
|
||||||
col.makeChild<PoolObjectNode<amuse::LayersId, std::vector<amuse::LayerMapping>>>(keymap.first, keymap.second.get());
|
col.makeChild<LayersNode>(keymap.first, keymap.second.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
endResetModel();
|
endResetModel();
|
||||||
|
@ -250,6 +270,13 @@ Qt::ItemFlags ProjectModel::flags(const QModelIndex& index) const
|
||||||
return QAbstractItemModel::flags(index);
|
return QAbstractItemModel::flags(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProjectModel::INode* ProjectModel::node(const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return nullptr;
|
||||||
|
return static_cast<INode*>(index.internalPointer());
|
||||||
|
}
|
||||||
|
|
||||||
bool ProjectModel::canDelete() const
|
bool ProjectModel::canDelete() const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -29,13 +29,16 @@ private:
|
||||||
amuse::ProjectDatabase m_projectDatabase;
|
amuse::ProjectDatabase m_projectDatabase;
|
||||||
std::map<QString, amuse::AudioGroupDatabase> m_groups;
|
std::map<QString, amuse::AudioGroupDatabase> m_groups;
|
||||||
|
|
||||||
|
public:
|
||||||
class INode
|
class INode
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
enum class Type
|
enum class Type
|
||||||
{
|
{
|
||||||
|
Root,
|
||||||
Group, // Top-level group
|
Group, // Top-level group
|
||||||
SongGroup,
|
SongGroup,
|
||||||
SfxGroup,
|
SoundGroup,
|
||||||
Collection, // Classified object collection, one of the following:
|
Collection, // Classified object collection, one of the following:
|
||||||
SoundMacro,
|
SoundMacro,
|
||||||
ADSR,
|
ADSR,
|
||||||
|
@ -43,6 +46,7 @@ private:
|
||||||
Keymap,
|
Keymap,
|
||||||
Layer
|
Layer
|
||||||
};
|
};
|
||||||
|
private:
|
||||||
INode* m_parent;
|
INode* m_parent;
|
||||||
std::vector<std::unique_ptr<INode>> m_children;
|
std::vector<std::unique_ptr<INode>> m_children;
|
||||||
int m_row;
|
int m_row;
|
||||||
|
@ -63,6 +67,7 @@ private:
|
||||||
return static_cast<T&>(*m_children.back());
|
return static_cast<T&>(*m_children.back());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual Type type() const = 0;
|
||||||
virtual QString text() const = 0;
|
virtual QString text() const = 0;
|
||||||
virtual QIcon icon() const = 0;
|
virtual QIcon icon() const = 0;
|
||||||
};
|
};
|
||||||
|
@ -70,6 +75,7 @@ private:
|
||||||
{
|
{
|
||||||
RootNode() : INode(nullptr, 0) {}
|
RootNode() : INode(nullptr, 0) {}
|
||||||
|
|
||||||
|
Type type() const { return Type::Root; }
|
||||||
QString text() const { return {}; }
|
QString text() const { return {}; }
|
||||||
QIcon icon() const { return {}; }
|
QIcon icon() const { return {}; }
|
||||||
};
|
};
|
||||||
|
@ -80,6 +86,7 @@ private:
|
||||||
: INode(parent, row), m_it(it) {}
|
: INode(parent, row), m_it(it) {}
|
||||||
|
|
||||||
static QIcon Icon;
|
static QIcon Icon;
|
||||||
|
Type type() const { return Type::Group; }
|
||||||
QString text() const { return m_it->first; }
|
QString text() const { return m_it->first; }
|
||||||
QIcon icon() const { return Icon; }
|
QIcon icon() const { return Icon; }
|
||||||
};
|
};
|
||||||
|
@ -92,6 +99,7 @@ private:
|
||||||
: INode(parent, row), m_id(id), m_name(amuse::GroupId::CurNameDB->resolveNameFromId(id).data()), m_index(index) {}
|
: INode(parent, row), m_id(id), m_name(amuse::GroupId::CurNameDB->resolveNameFromId(id).data()), m_index(index) {}
|
||||||
|
|
||||||
static QIcon Icon;
|
static QIcon Icon;
|
||||||
|
Type type() const { return Type::SongGroup; }
|
||||||
QString text() const { return m_name; }
|
QString text() const { return m_name; }
|
||||||
QIcon icon() const { return Icon; }
|
QIcon icon() const { return Icon; }
|
||||||
};
|
};
|
||||||
|
@ -104,6 +112,7 @@ private:
|
||||||
: INode(parent, row), m_id(id), m_name(amuse::GroupId::CurNameDB->resolveNameFromId(id).data()), m_index(index) {}
|
: INode(parent, row), m_id(id), m_name(amuse::GroupId::CurNameDB->resolveNameFromId(id).data()), m_index(index) {}
|
||||||
|
|
||||||
static QIcon Icon;
|
static QIcon Icon;
|
||||||
|
Type type() const { return Type::SoundGroup; }
|
||||||
QString text() const { return m_name; }
|
QString text() const { return m_name; }
|
||||||
QIcon icon() const { return Icon; }
|
QIcon icon() const { return Icon; }
|
||||||
};
|
};
|
||||||
|
@ -114,10 +123,11 @@ private:
|
||||||
CollectionNode(INode* parent, int row, const QString& name, const QIcon& icon)
|
CollectionNode(INode* parent, int row, const QString& name, const QIcon& icon)
|
||||||
: INode(parent, row), m_name(name), m_icon(icon) {}
|
: INode(parent, row), m_name(name), m_icon(icon) {}
|
||||||
|
|
||||||
|
Type type() const { return Type::Collection; }
|
||||||
QString text() const { return m_name; }
|
QString text() const { return m_name; }
|
||||||
QIcon icon() const { return m_icon; }
|
QIcon icon() const { return m_icon; }
|
||||||
};
|
};
|
||||||
template <class ID, class T>
|
template <class ID, class T, INode::Type TP>
|
||||||
struct PoolObjectNode : INode
|
struct PoolObjectNode : INode
|
||||||
{
|
{
|
||||||
ID m_id;
|
ID m_id;
|
||||||
|
@ -126,9 +136,15 @@ private:
|
||||||
PoolObjectNode(INode* parent, int row, ID id, T& 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) {}
|
: INode(parent, row), m_id(id), m_name(ID::CurNameDB->resolveNameFromId(id).data()), m_obj(obj) {}
|
||||||
|
|
||||||
|
Type type() const { return TP; }
|
||||||
QString text() const { return m_name; }
|
QString text() const { return m_name; }
|
||||||
QIcon icon() const { return {}; }
|
QIcon icon() const { return {}; }
|
||||||
};
|
};
|
||||||
|
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>;
|
||||||
|
|
||||||
std::unique_ptr<RootNode> m_root;
|
std::unique_ptr<RootNode> m_root;
|
||||||
|
|
||||||
|
@ -138,6 +154,8 @@ private:
|
||||||
public:
|
public:
|
||||||
explicit ProjectModel(const QString& path, QObject* parent = Q_NULLPTR);
|
explicit ProjectModel(const QString& path, QObject* parent = Q_NULLPTR);
|
||||||
|
|
||||||
|
bool clearProjectData();
|
||||||
|
bool openGroupData(const QString& groupName, UIMessenger& messenger);
|
||||||
bool importGroupData(const QString& groupName, const amuse::AudioGroupData& data,
|
bool importGroupData(const QString& groupName, const amuse::AudioGroupData& data,
|
||||||
ImportMode mode, UIMessenger& messenger);
|
ImportMode mode, UIMessenger& messenger);
|
||||||
bool saveToFile(UIMessenger& messenger);
|
bool saveToFile(UIMessenger& messenger);
|
||||||
|
@ -150,6 +168,7 @@ public:
|
||||||
int columnCount(const QModelIndex& parent = QModelIndex()) const;
|
int columnCount(const QModelIndex& parent = QModelIndex()) const;
|
||||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
|
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
|
||||||
Qt::ItemFlags flags(const QModelIndex& index) const;
|
Qt::ItemFlags flags(const QModelIndex& index) const;
|
||||||
|
INode* node(const QModelIndex& index) const;
|
||||||
|
|
||||||
QString path() const { return m_dir.path(); }
|
QString path() const { return m_dir.path(); }
|
||||||
bool canDelete() const;
|
bool canDelete() const;
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
#include "SFXGroupEditor.hpp"
|
|
||||||
|
|
||||||
SFXGroupEditor::SFXGroupEditor(QWidget* parent)
|
|
||||||
: EditorWidget(parent)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
#ifndef AMUSE_SFX_GROUP_EDITOR_HPP
|
|
||||||
#define AMUSE_SFX_GROUP_EDITOR_HPP
|
|
||||||
|
|
||||||
#include "EditorWidget.hpp"
|
|
||||||
|
|
||||||
class SFXGroupEditor : public EditorWidget
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit SFXGroupEditor(QWidget* parent = Q_NULLPTR);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif //AMUSE_SFX_GROUP_EDITOR_HPP
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "SongGroupEditor.hpp"
|
#include "SongGroupEditor.hpp"
|
||||||
|
|
||||||
SongGroupEditor::SongGroupEditor(QWidget* parent)
|
SongGroupEditor::SongGroupEditor(ProjectModel::SongGroupNode* node, QWidget* parent)
|
||||||
: EditorWidget(parent)
|
: EditorWidget(parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ class SongGroupEditor : public EditorWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit SongGroupEditor(QWidget* parent = Q_NULLPTR);
|
explicit SongGroupEditor(ProjectModel::SongGroupNode* node, QWidget* parent = Q_NULLPTR);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
#include "SoundGroupEditor.hpp"
|
||||||
|
|
||||||
|
SoundGroupEditor::SoundGroupEditor(ProjectModel::SoundGroupNode* node, QWidget* parent)
|
||||||
|
: EditorWidget(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef AMUSE_SOUND_GROUP_EDITOR_HPP
|
||||||
|
#define AMUSE_SOUND_GROUP_EDITOR_HPP
|
||||||
|
|
||||||
|
#include "EditorWidget.hpp"
|
||||||
|
|
||||||
|
class SoundGroupEditor : public EditorWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit SoundGroupEditor(ProjectModel::SoundGroupNode* node, QWidget* parent = Q_NULLPTR);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //AMUSE_SOUND_GROUP_EDITOR_HPP
|
|
@ -1,7 +1,10 @@
|
||||||
#include "SoundMacroEditor.hpp"
|
#include "SoundMacroEditor.hpp"
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
SoundMacroEditor::SoundMacroEditor(QWidget* parent)
|
SoundMacroEditor::SoundMacroEditor(ProjectModel::SoundMacroNode* node, QWidget* parent)
|
||||||
: EditorWidget(parent)
|
: EditorWidget(parent)
|
||||||
{
|
{
|
||||||
|
QLabel* lab = new QLabel;
|
||||||
|
lab->setText(node->m_name);
|
||||||
|
lab->setParent(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ class SoundMacroEditor : public EditorWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit SoundMacroEditor(QWidget* parent = Q_NULLPTR);
|
explicit SoundMacroEditor(ProjectModel::SoundMacroNode* node, QWidget* parent = Q_NULLPTR);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
#include "StatusBarWidget.hpp"
|
|
||||||
|
|
||||||
StatusBarWidget::StatusBarWidget(QWidget* parent)
|
|
||||||
: QStatusBar(parent)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
|
@ -2,13 +2,65 @@
|
||||||
#define AMUSE_STATUSBAR_WIDGET_HPP
|
#define AMUSE_STATUSBAR_WIDGET_HPP
|
||||||
|
|
||||||
#include <QStatusBar>
|
#include <QStatusBar>
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
class StatusBarFocus;
|
||||||
|
|
||||||
class StatusBarWidget : public QStatusBar
|
class StatusBarWidget : public QStatusBar
|
||||||
{
|
{
|
||||||
|
friend class StatusBarFocus;
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
QLabel* m_normalMessage;
|
||||||
|
StatusBarFocus* m_curFocus = nullptr;
|
||||||
public:
|
public:
|
||||||
explicit StatusBarWidget(QWidget* parent = Q_NULLPTR);
|
explicit StatusBarWidget(QWidget* parent = Q_NULLPTR) : QStatusBar(parent) {}
|
||||||
|
void setNormalMessage(const QString& message) { m_normalMessage->setText(message); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class StatusBarFocus : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
QString m_message;
|
||||||
|
public:
|
||||||
|
explicit StatusBarFocus(StatusBarWidget* statusWidget)
|
||||||
|
: QObject(statusWidget) {}
|
||||||
|
~StatusBarFocus() { exit(); }
|
||||||
|
void setMessage(const QString& message)
|
||||||
|
{
|
||||||
|
m_message = message;
|
||||||
|
if (StatusBarWidget* widget = qobject_cast<StatusBarWidget*>(parent()))
|
||||||
|
{
|
||||||
|
if (widget->m_curFocus == this)
|
||||||
|
{
|
||||||
|
if (m_message.isEmpty())
|
||||||
|
widget->clearMessage();
|
||||||
|
else
|
||||||
|
widget->showMessage(m_message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void enter()
|
||||||
|
{
|
||||||
|
if (StatusBarWidget* widget = qobject_cast<StatusBarWidget*>(parent()))
|
||||||
|
{
|
||||||
|
widget->m_curFocus = this;
|
||||||
|
if (m_message.isEmpty())
|
||||||
|
widget->clearMessage();
|
||||||
|
else
|
||||||
|
widget->showMessage(m_message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void exit()
|
||||||
|
{
|
||||||
|
if (StatusBarWidget* widget = qobject_cast<StatusBarWidget*>(parent()))
|
||||||
|
{
|
||||||
|
if (widget->m_curFocus == this)
|
||||||
|
{
|
||||||
|
widget->clearMessage();
|
||||||
|
widget->m_curFocus = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#endif //AMUSE_STATUSBAR_WIDGET_HPP
|
#endif //AMUSE_STATUSBAR_WIDGET_HPP
|
||||||
|
|
|
@ -0,0 +1,239 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="140"
|
||||||
|
height="100"
|
||||||
|
viewBox="0 0 37.041665 26.458336"
|
||||||
|
version="1.1"
|
||||||
|
id="svg8"
|
||||||
|
inkscape:version="0.92.2 2405546, 2018-03-11"
|
||||||
|
sodipodi:docname="keyboard.svg">
|
||||||
|
<defs
|
||||||
|
id="defs2">
|
||||||
|
<linearGradient
|
||||||
|
id="whiteKey">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4540" />
|
||||||
|
<stop
|
||||||
|
id="stop4552"
|
||||||
|
offset="0.67000026"
|
||||||
|
style="stop-color:#cecece;stop-opacity:1;" />
|
||||||
|
<stop
|
||||||
|
id="stop4550"
|
||||||
|
offset="0.68000031"
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop4542" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="blackKey">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#000000;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4528" />
|
||||||
|
<stop
|
||||||
|
id="stop4538"
|
||||||
|
offset="0.33333373"
|
||||||
|
style="stop-color:#000000;stop-opacity:1;" />
|
||||||
|
<stop
|
||||||
|
id="stop4536"
|
||||||
|
offset="0.36666706"
|
||||||
|
style="stop-color:#313131;stop-opacity:1;" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#000000;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop4530" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#blackKey"
|
||||||
|
id="linearGradient4534"
|
||||||
|
x1="2.6458333"
|
||||||
|
y1="286.41666"
|
||||||
|
x2="2.6458333"
|
||||||
|
y2="270.54166"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(0.66145845)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#blackKey"
|
||||||
|
id="linearGradient4534-3"
|
||||||
|
x1="2.645833"
|
||||||
|
y1="286.41663"
|
||||||
|
x2="2.6458333"
|
||||||
|
y2="270.54166"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(6.6145838,1.0903046e-5)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#blackKey"
|
||||||
|
id="linearGradient4534-6"
|
||||||
|
x1="2.6458328"
|
||||||
|
y1="286.41666"
|
||||||
|
x2="2.6458333"
|
||||||
|
y2="270.54166"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(15.875001,7.6333333e-6)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#blackKey"
|
||||||
|
id="linearGradient4534-0"
|
||||||
|
x1="2.645833"
|
||||||
|
y1="286.41663"
|
||||||
|
x2="2.6458333"
|
||||||
|
y2="270.54166"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(21.828126,1.4333333e-5)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#blackKey"
|
||||||
|
id="linearGradient4534-2"
|
||||||
|
x1="2.645833"
|
||||||
|
y1="286.41666"
|
||||||
|
x2="2.6458333"
|
||||||
|
y2="270.54166"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(27.781251,7.7033334e-6)" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#313131"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="3.4618283"
|
||||||
|
inkscape:cx="44.115558"
|
||||||
|
inkscape:cy="71.875845"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
units="px"
|
||||||
|
inkscape:window-width="1286"
|
||||||
|
inkscape:window-height="1176"
|
||||||
|
inkscape:window-x="1170"
|
||||||
|
inkscape:window-y="447"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
fit-margin-top="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid4518"
|
||||||
|
spacingx="0.13229167"
|
||||||
|
spacingy="0.26458333"
|
||||||
|
visible="false"
|
||||||
|
empspacing="5"
|
||||||
|
originx="0.13229165"
|
||||||
|
originy="0.13228834" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(0.13229166,-270.67394)">
|
||||||
|
<path
|
||||||
|
style="fill:#fdfdfd;fill-opacity:1;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 0,270.54165 v 26.45833 H 5.2916666 V 286.41665 H 3.3072917 v -15.875 z"
|
||||||
|
id="C"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="ccccccc"
|
||||||
|
inkscape:label="C" />
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="M 5.2916666,296.99998 H 10.583333 V 286.41665 H 9.2604166 v -15.875 H 7.2760419 v 15.875 H 5.2916666 Z"
|
||||||
|
id="D"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="ccccccccc"
|
||||||
|
inkscape:label="D" />
|
||||||
|
<path
|
||||||
|
style="fill:url(#linearGradient4534);fill-opacity:1;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 3.3072917,270.54165 v 15.875 h 3.9687499 v -15.875 z"
|
||||||
|
id="Cs"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
inkscape:label="Cs" />
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="M 10.583333,296.99998 H 15.875 v -26.45833 h -2.645834 v 15.875 h -2.645833 z"
|
||||||
|
id="E"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
inkscape:label="E" />
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 15.875,296.99998 h 5.291666 v -10.58333 h -2.645833 v -15.875 H 15.875 Z"
|
||||||
|
id="F"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
inkscape:label="F" />
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 21.166666,296.99998 h 5.291667 v -10.58333 h -1.984374 v -15.875 h -1.984376 v 15.875 h -1.322917 z"
|
||||||
|
id="G"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="ccccccccc"
|
||||||
|
inkscape:label="G" />
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="M 26.458333,296.99998 H 31.75 v -10.58333 h -1.322917 v -15.875 h -1.984374 v 15.875 h -1.984376 z"
|
||||||
|
id="A"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="ccccccccc"
|
||||||
|
inkscape:label="A" />
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 31.75,296.99998 h 5.291666 v -10.58333 -15.875 h -2.645833 v 15.875 H 31.75 Z"
|
||||||
|
id="B"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccccccc"
|
||||||
|
inkscape:label="B" />
|
||||||
|
<path
|
||||||
|
style="fill:url(#linearGradient4534-3);fill-opacity:1;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 9.260417,270.54165 v 15.875 h 3.96875 v -15.875 z"
|
||||||
|
id="Ds"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
inkscape:label="Ds" />
|
||||||
|
<path
|
||||||
|
style="fill:url(#linearGradient4534-6);fill-opacity:1;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 18.520834,270.54165 v 15.875 h 3.96875 v -15.875 z"
|
||||||
|
id="Fs"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
inkscape:label="Fs" />
|
||||||
|
<path
|
||||||
|
style="fill:url(#linearGradient4534-0);fill-opacity:1;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 24.473959,270.54165 v 15.875 h 3.96875 v -15.875 z"
|
||||||
|
id="Gs"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
inkscape:label="Gs" />
|
||||||
|
<path
|
||||||
|
style="fill:url(#linearGradient4534-2);fill-opacity:1;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 30.427084,270.54165 v 15.875 h 3.96875 v -15.875 z"
|
||||||
|
id="As"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
inkscape:label="As" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 8.6 KiB |
|
@ -0,0 +1,174 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="101"
|
||||||
|
height="100"
|
||||||
|
viewBox="0 0 26.722915 26.458338"
|
||||||
|
version="1.1"
|
||||||
|
id="svg8"
|
||||||
|
inkscape:version="0.92.2 2405546, 2018-03-11"
|
||||||
|
sodipodi:docname="keyboard_last.svg">
|
||||||
|
<defs
|
||||||
|
id="defs2">
|
||||||
|
<linearGradient
|
||||||
|
id="blackKey">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#000000;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4528" />
|
||||||
|
<stop
|
||||||
|
id="stop4538"
|
||||||
|
offset="0.33333373"
|
||||||
|
style="stop-color:#000000;stop-opacity:1;" />
|
||||||
|
<stop
|
||||||
|
id="stop4536"
|
||||||
|
offset="0.36666706"
|
||||||
|
style="stop-color:#313131;stop-opacity:1;" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#000000;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop4530" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#blackKey"
|
||||||
|
id="linearGradient4534"
|
||||||
|
x1="2.6458333"
|
||||||
|
y1="286.41666"
|
||||||
|
x2="2.6458333"
|
||||||
|
y2="270.54166"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(0.66145845)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#blackKey"
|
||||||
|
id="linearGradient4534-3"
|
||||||
|
x1="2.645833"
|
||||||
|
y1="286.41663"
|
||||||
|
x2="2.6458333"
|
||||||
|
y2="270.54166"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(6.6145838,1.0903046e-5)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#blackKey"
|
||||||
|
id="linearGradient4534-6"
|
||||||
|
x1="2.6458328"
|
||||||
|
y1="286.41666"
|
||||||
|
x2="2.6458333"
|
||||||
|
y2="270.54166"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(15.875001,7.6333333e-6)" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#313131"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="5.25169"
|
||||||
|
inkscape:cx="63.580658"
|
||||||
|
inkscape:cy="56.621412"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
units="px"
|
||||||
|
inkscape:window-width="1424"
|
||||||
|
inkscape:window-height="1104"
|
||||||
|
inkscape:window-x="2192"
|
||||||
|
inkscape:window-y="236"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
fit-margin-top="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid4518"
|
||||||
|
spacingx="0.13229167"
|
||||||
|
spacingy="0.26458333"
|
||||||
|
visible="false"
|
||||||
|
empspacing="5"
|
||||||
|
originx="0.13229164"
|
||||||
|
originy="0.13228669" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(0.13229166,-270.67394)">
|
||||||
|
<path
|
||||||
|
style="fill:#fdfdfd;fill-opacity:1;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 0,270.54165 v 26.45833 H 5.2916666 V 286.41665 H 3.3072917 v -15.875 z"
|
||||||
|
id="C"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="ccccccc"
|
||||||
|
inkscape:label="C" />
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="M 5.2916666,296.99998 H 10.583333 V 286.41665 H 9.2604166 v -15.875 H 7.2760419 v 15.875 H 5.2916666 Z"
|
||||||
|
id="D"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="ccccccccc"
|
||||||
|
inkscape:label="D" />
|
||||||
|
<path
|
||||||
|
style="fill:url(#linearGradient4534);fill-opacity:1;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 3.3072917,270.54165 v 15.875 h 3.9687499 v -15.875 z"
|
||||||
|
id="Cs"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
inkscape:label="Cs" />
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="M 10.583333,296.99998 H 15.875 v -26.45833 h -2.645834 v 15.875 h -2.645833 z"
|
||||||
|
id="E"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
inkscape:label="E" />
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 15.875,296.99998 h 5.291666 v -10.58333 h -2.645833 v -15.875 H 15.875 Z"
|
||||||
|
id="F"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
inkscape:label="F" />
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 21.166666,296.99998 h 5.291667 c 0,0 1e-6,-26.45833 1e-6,-26.45833 h -3.968751 v 15.875 h -1.322917 z"
|
||||||
|
id="G"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="ccccccc"
|
||||||
|
inkscape:label="G" />
|
||||||
|
<path
|
||||||
|
style="fill:url(#linearGradient4534-3);fill-opacity:1;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 9.260417,270.54165 v 15.875 h 3.96875 v -15.875 z"
|
||||||
|
id="Ds"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
inkscape:label="Ds" />
|
||||||
|
<path
|
||||||
|
style="fill:url(#linearGradient4534-6);fill-opacity:1;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 18.520834,270.54165 v 15.875 h 3.96875 v -15.875 z"
|
||||||
|
id="Fs"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
inkscape:label="Fs" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 6.1 KiB |
|
@ -22,5 +22,7 @@
|
||||||
</qresource>
|
</qresource>
|
||||||
<qresource prefix="/bg">
|
<qresource prefix="/bg">
|
||||||
<file>FaceGrey.svg</file>
|
<file>FaceGrey.svg</file>
|
||||||
|
<file>keyboard.svg</file>
|
||||||
|
<file>keyboard_last.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -21,8 +21,12 @@ class AudioGroup
|
||||||
|
|
||||||
public:
|
public:
|
||||||
operator bool() const { return m_valid; }
|
operator bool() const { return m_valid; }
|
||||||
explicit AudioGroup(const AudioGroupData& data);
|
AudioGroup() = default;
|
||||||
explicit AudioGroup(SystemStringView groupPath);
|
explicit AudioGroup(const AudioGroupData& data) { assign(data); }
|
||||||
|
explicit AudioGroup(SystemStringView groupPath) { assign(groupPath); }
|
||||||
|
|
||||||
|
void assign(const AudioGroupData& data);
|
||||||
|
void assign(SystemStringView groupPath);
|
||||||
|
|
||||||
const AudioGroupSampleDirectory::Entry* getSample(SampleId sfxId) const;
|
const AudioGroupSampleDirectory::Entry* getSample(SampleId sfxId) const;
|
||||||
const unsigned char* getSampleData(SampleId sfxId, const AudioGroupSampleDirectory::Entry* sample) const;
|
const unsigned char* getSampleData(SampleId sfxId, const AudioGroupSampleDirectory::Entry* sample) const;
|
||||||
|
@ -43,10 +47,16 @@ class AudioGroupDatabase : public AudioGroup
|
||||||
amuse::NameDB m_layersDb;
|
amuse::NameDB m_layersDb;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
AudioGroupDatabase() = default;
|
||||||
explicit AudioGroupDatabase(const AudioGroupData& data)
|
explicit AudioGroupDatabase(const AudioGroupData& data)
|
||||||
: AudioGroup(data) {}
|
{
|
||||||
|
assign(data);
|
||||||
|
}
|
||||||
explicit AudioGroupDatabase(SystemStringView groupPath)
|
explicit AudioGroupDatabase(SystemStringView groupPath)
|
||||||
: AudioGroup(groupPath) {}
|
{
|
||||||
|
setIdDatabases();
|
||||||
|
assign(groupPath);
|
||||||
|
}
|
||||||
|
|
||||||
void setIdDatabases()
|
void setIdDatabases()
|
||||||
{
|
{
|
||||||
|
|
|
@ -118,6 +118,7 @@ struct SoundMacro
|
||||||
MulVars,
|
MulVars,
|
||||||
DivVars,
|
DivVars,
|
||||||
AddIVars,
|
AddIVars,
|
||||||
|
SetVar,
|
||||||
IfEqual = 0x70,
|
IfEqual = 0x70,
|
||||||
IfLess,
|
IfLess,
|
||||||
Invalid = 0xff
|
Invalid = 0xff
|
||||||
|
@ -926,6 +927,17 @@ struct SoundMacro
|
||||||
bool Do(SoundMacroState& st, Voice& vox) const;
|
bool Do(SoundMacroState& st, Voice& vox) const;
|
||||||
CmdOp Isa() const { return CmdOp::AddIVars; }
|
CmdOp Isa() const { return CmdOp::AddIVars; }
|
||||||
};
|
};
|
||||||
|
struct CmdSetVar : ICmd
|
||||||
|
{
|
||||||
|
AT_DECL_DNA_YAML
|
||||||
|
AT_DECL_DNAV
|
||||||
|
Value<bool> varCtrlA;
|
||||||
|
Value<atInt8> a;
|
||||||
|
Seek<1, athena::Current> pad;
|
||||||
|
Value<atInt16> imm;
|
||||||
|
bool Do(SoundMacroState& st, Voice& vox) const;
|
||||||
|
CmdOp Isa() const { return CmdOp::SetVar; }
|
||||||
|
};
|
||||||
struct CmdIfEqual : ICmd
|
struct CmdIfEqual : ICmd
|
||||||
{
|
{
|
||||||
AT_DECL_DNA_YAML
|
AT_DECL_DNA_YAML
|
||||||
|
@ -1149,10 +1161,10 @@ class AudioGroupPool
|
||||||
std::unordered_map<KeymapId, Keymap> m_keymaps;
|
std::unordered_map<KeymapId, Keymap> m_keymaps;
|
||||||
std::unordered_map<LayersId, std::vector<LayerMapping>> m_layers;
|
std::unordered_map<LayersId, std::vector<LayerMapping>> m_layers;
|
||||||
|
|
||||||
AudioGroupPool() = default;
|
|
||||||
template <athena::Endian DNAE>
|
template <athena::Endian DNAE>
|
||||||
static AudioGroupPool _AudioGroupPool(athena::io::IStreamReader& r);
|
static AudioGroupPool _AudioGroupPool(athena::io::IStreamReader& r);
|
||||||
public:
|
public:
|
||||||
|
AudioGroupPool() = default;
|
||||||
static AudioGroupPool CreateAudioGroupPool(const AudioGroupData& data);
|
static AudioGroupPool CreateAudioGroupPool(const AudioGroupData& data);
|
||||||
static AudioGroupPool CreateAudioGroupPool(SystemStringView groupPath);
|
static AudioGroupPool CreateAudioGroupPool(SystemStringView groupPath);
|
||||||
|
|
||||||
|
|
|
@ -183,7 +183,6 @@ class AudioGroupProject
|
||||||
std::unordered_map<GroupId, SongGroupIndex> m_songGroups;
|
std::unordered_map<GroupId, SongGroupIndex> m_songGroups;
|
||||||
std::unordered_map<GroupId, SFXGroupIndex> m_sfxGroups;
|
std::unordered_map<GroupId, SFXGroupIndex> m_sfxGroups;
|
||||||
|
|
||||||
AudioGroupProject() = default;
|
|
||||||
AudioGroupProject(athena::io::IStreamReader& r, GCNDataTag);
|
AudioGroupProject(athena::io::IStreamReader& r, GCNDataTag);
|
||||||
template <athena::Endian DNAE>
|
template <athena::Endian DNAE>
|
||||||
static AudioGroupProject _AudioGroupProject(athena::io::IStreamReader& r, bool absOffs);
|
static AudioGroupProject _AudioGroupProject(athena::io::IStreamReader& r, bool absOffs);
|
||||||
|
@ -192,6 +191,7 @@ class AudioGroupProject
|
||||||
template <athena::Endian DNAE>
|
template <athena::Endian DNAE>
|
||||||
static void BootstrapObjectIDs(athena::io::IStreamReader& r, bool absOffs);
|
static void BootstrapObjectIDs(athena::io::IStreamReader& r, bool absOffs);
|
||||||
public:
|
public:
|
||||||
|
AudioGroupProject() = default;
|
||||||
static AudioGroupProject CreateAudioGroupProject(const AudioGroupData& data);
|
static AudioGroupProject CreateAudioGroupProject(const AudioGroupData& data);
|
||||||
static AudioGroupProject CreateAudioGroupProject(SystemStringView groupPath);
|
static AudioGroupProject CreateAudioGroupProject(SystemStringView groupPath);
|
||||||
static void BootstrapObjectIDs(const AudioGroupData& data);
|
static void BootstrapObjectIDs(const AudioGroupData& data);
|
||||||
|
|
|
@ -253,9 +253,8 @@ private:
|
||||||
static void _extractCompressed(SampleId id, const Entry& ent, amuse::SystemStringView destDir,
|
static void _extractCompressed(SampleId id, const Entry& ent, amuse::SystemStringView destDir,
|
||||||
const unsigned char* samp);
|
const unsigned char* samp);
|
||||||
|
|
||||||
AudioGroupSampleDirectory() = default;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
AudioGroupSampleDirectory() = default;
|
||||||
AudioGroupSampleDirectory(athena::io::IStreamReader& r, GCNDataTag);
|
AudioGroupSampleDirectory(athena::io::IStreamReader& r, GCNDataTag);
|
||||||
AudioGroupSampleDirectory(athena::io::IStreamReader& r, const unsigned char* sampData, bool absOffs, N64DataTag);
|
AudioGroupSampleDirectory(athena::io::IStreamReader& r, const unsigned char* sampData, bool absOffs, N64DataTag);
|
||||||
AudioGroupSampleDirectory(athena::io::IStreamReader& r, bool absOffs, PCDataTag);
|
AudioGroupSampleDirectory(athena::io::IStreamReader& r, bool absOffs, PCDataTag);
|
||||||
|
|
|
@ -4,19 +4,21 @@
|
||||||
namespace amuse
|
namespace amuse
|
||||||
{
|
{
|
||||||
|
|
||||||
AudioGroup::AudioGroup(const AudioGroupData& data)
|
void AudioGroup::assign(const AudioGroupData& data)
|
||||||
: m_proj(AudioGroupProject::CreateAudioGroupProject(data))
|
{
|
||||||
, m_pool(AudioGroupPool::CreateAudioGroupPool(data))
|
m_proj = AudioGroupProject::CreateAudioGroupProject(data);
|
||||||
, m_sdir(AudioGroupSampleDirectory::CreateAudioGroupSampleDirectory(data))
|
m_pool = AudioGroupPool::CreateAudioGroupPool(data);
|
||||||
, m_samp(data.getSamp())
|
m_sdir = AudioGroupSampleDirectory::CreateAudioGroupSampleDirectory(data);
|
||||||
{}
|
m_samp = data.getSamp();
|
||||||
|
}
|
||||||
AudioGroup::AudioGroup(SystemStringView groupPath)
|
void AudioGroup::assign(SystemStringView groupPath)
|
||||||
: m_proj(AudioGroupProject::CreateAudioGroupProject(groupPath))
|
{
|
||||||
, m_pool(AudioGroupPool::CreateAudioGroupPool(groupPath))
|
/* Reverse order when loading intermediates */
|
||||||
, m_sdir(AudioGroupSampleDirectory::CreateAudioGroupSampleDirectory(groupPath))
|
m_sdir = AudioGroupSampleDirectory::CreateAudioGroupSampleDirectory(groupPath);
|
||||||
, m_groupPath(groupPath)
|
m_pool = AudioGroupPool::CreateAudioGroupPool(groupPath);
|
||||||
{}
|
m_proj = AudioGroupProject::CreateAudioGroupProject(groupPath);
|
||||||
|
m_samp = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
const AudioGroupSampleDirectory::Entry* AudioGroup::getSample(SampleId sfxId) const
|
const AudioGroupSampleDirectory::Entry* AudioGroup::getSample(SampleId sfxId) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -134,7 +134,7 @@ AudioGroupPool AudioGroupPool::CreateAudioGroupPool(SystemStringView groupPath)
|
||||||
if (!fi.hasError())
|
if (!fi.hasError())
|
||||||
{
|
{
|
||||||
athena::io::YAMLDocReader r;
|
athena::io::YAMLDocReader r;
|
||||||
if (r.parse(&fi) && r.ValidateClassType("amuse::Pool"))
|
if (r.parse(&fi) && !r.readString("DNAType").compare("amuse::Pool"))
|
||||||
{
|
{
|
||||||
if (auto __r = r.enterSubRecord("soundMacros"))
|
if (auto __r = r.enterSubRecord("soundMacros"))
|
||||||
{
|
{
|
||||||
|
@ -518,6 +518,8 @@ std::unique_ptr<SoundMacro::ICmd> SoundMacro::MakeCmd(R& r)
|
||||||
cmd = _MakeCmd<CmdDivVars>(r); break;
|
cmd = _MakeCmd<CmdDivVars>(r); break;
|
||||||
case CmdOp::AddIVars:
|
case CmdOp::AddIVars:
|
||||||
cmd = _MakeCmd<CmdAddIVars>(r); break;
|
cmd = _MakeCmd<CmdAddIVars>(r); break;
|
||||||
|
case CmdOp::SetVar:
|
||||||
|
cmd = _MakeCmd<CmdSetVar>(r); break;
|
||||||
case CmdOp::IfEqual:
|
case CmdOp::IfEqual:
|
||||||
cmd = _MakeCmd<CmdIfEqual>(r); break;
|
cmd = _MakeCmd<CmdIfEqual>(r); break;
|
||||||
case CmdOp::IfLess:
|
case CmdOp::IfLess:
|
||||||
|
@ -684,6 +686,8 @@ std::string_view SoundMacro::CmdOpToStr(CmdOp op)
|
||||||
return "DivVars"sv;
|
return "DivVars"sv;
|
||||||
case CmdOp::AddIVars:
|
case CmdOp::AddIVars:
|
||||||
return "AddIVars"sv;
|
return "AddIVars"sv;
|
||||||
|
case CmdOp::SetVar:
|
||||||
|
return "SetVar"sv;
|
||||||
case CmdOp::IfEqual:
|
case CmdOp::IfEqual:
|
||||||
return "IfEqual"sv;
|
return "IfEqual"sv;
|
||||||
case CmdOp::IfLess:
|
case CmdOp::IfLess:
|
||||||
|
@ -845,6 +849,8 @@ SoundMacro::CmdOp SoundMacro::CmdStrToOp(std::string_view op)
|
||||||
return CmdOp::DivVars;
|
return CmdOp::DivVars;
|
||||||
else if (!CompareCaseInsensitive(op.data(), "AddIVars"))
|
else if (!CompareCaseInsensitive(op.data(), "AddIVars"))
|
||||||
return CmdOp::AddIVars;
|
return CmdOp::AddIVars;
|
||||||
|
else if (!CompareCaseInsensitive(op.data(), "SetVar"))
|
||||||
|
return CmdOp::SetVar;
|
||||||
else if (!CompareCaseInsensitive(op.data(), "IfEqual"))
|
else if (!CompareCaseInsensitive(op.data(), "IfEqual"))
|
||||||
return CmdOp::IfEqual;
|
return CmdOp::IfEqual;
|
||||||
else if (!CompareCaseInsensitive(op.data(), "IfLess"))
|
else if (!CompareCaseInsensitive(op.data(), "IfLess"))
|
||||||
|
|
|
@ -229,7 +229,7 @@ AudioGroupProject AudioGroupProject::CreateAudioGroupProject(SystemStringView gr
|
||||||
if (!fi.hasError())
|
if (!fi.hasError())
|
||||||
{
|
{
|
||||||
athena::io::YAMLDocReader r;
|
athena::io::YAMLDocReader r;
|
||||||
if (r.parse(&fi) && r.ValidateClassType("amuse::Project"))
|
if (r.parse(&fi) && !r.readString("DNAType").compare("amuse::Project"))
|
||||||
{
|
{
|
||||||
if (auto __v = r.enterSubRecord("songGroups"))
|
if (auto __v = r.enterSubRecord("songGroups"))
|
||||||
{
|
{
|
||||||
|
@ -289,7 +289,7 @@ AudioGroupProject AudioGroupProject::CreateAudioGroupProject(SystemStringView gr
|
||||||
ret.m_sfxGroups.reserve(r.getCurNode()->m_mapChildren.size());
|
ret.m_sfxGroups.reserve(r.getCurNode()->m_mapChildren.size());
|
||||||
for (const auto& grp : r.getCurNode()->m_mapChildren)
|
for (const auto& grp : r.getCurNode()->m_mapChildren)
|
||||||
{
|
{
|
||||||
if (auto __r = r.enterSubRecord(nullptr))
|
if (auto __r = r.enterSubRecord(grp.first.c_str()))
|
||||||
{
|
{
|
||||||
uint16_t groupId;
|
uint16_t groupId;
|
||||||
std::string groupName = ParseStringSlashId(grp.first, groupId);
|
std::string groupName = ParseStringSlashId(grp.first, groupId);
|
||||||
|
|
|
@ -1024,6 +1024,16 @@ bool SoundMacro::CmdAddIVars::Do(SoundMacroState& st, Voice& vox) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SoundMacro::CmdSetVar::Do(SoundMacroState& st, Voice& vox) const
|
||||||
|
{
|
||||||
|
if (varCtrlA)
|
||||||
|
vox.setCtrlValue(a, imm);
|
||||||
|
else
|
||||||
|
st.m_variables[a] = imm;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool SoundMacro::CmdIfEqual::Do(SoundMacroState& st, Voice& vox) const
|
bool SoundMacro::CmdIfEqual::Do(SoundMacroState& st, Voice& vox) const
|
||||||
{
|
{
|
||||||
int32_t useA, useB;
|
int32_t useA, useB;
|
||||||
|
|
Loading…
Reference in New Issue