Editor/KeyboardWidget: Make use of std::array where applicable

Makes the types of the lookup tables and widget arrays strongly typed.
This also makes it a little more straightforward to dehardcode some
magic values related to the array sizes.
This commit is contained in:
Lioncash 2019-08-27 23:44:19 -04:00
parent 1604cbeb70
commit e6af69f882
3 changed files with 80 additions and 47 deletions

View File

@ -10,44 +10,66 @@
#include "Common.hpp" #include "Common.hpp"
#include "StatusBarWidget.hpp" #include "StatusBarWidget.hpp"
const QString NaturalKeyNames[] = {QStringLiteral("C"), QStringLiteral("D"), QStringLiteral("E"), QStringLiteral("F"), const std::array<QString, 7> NaturalKeyNames{
QStringLiteral("G"), QStringLiteral("A"), QStringLiteral("B")}; QStringLiteral("C"), QStringLiteral("D"), QStringLiteral("E"), QStringLiteral("F"),
QStringLiteral("G"), QStringLiteral("A"), QStringLiteral("B"),
};
const QString SharpKeyNames[] = {QStringLiteral("Cs"), QStringLiteral("Ds"), QStringLiteral("Fs"), QStringLiteral("Gs"), const std::array<QString, 5> SharpKeyNames{
QStringLiteral("As")}; QStringLiteral("Cs"), QStringLiteral("Ds"), QStringLiteral("Fs"), QStringLiteral("Gs"), QStringLiteral("As"),
};
const QString KeyStrings[] = {QStringLiteral("C"), QStringLiteral("C#"), QStringLiteral("D"), QStringLiteral("D#"), const std::array<QString, 12> KeyStrings{
QStringLiteral("E"), QStringLiteral("F"), QStringLiteral("F#"), QStringLiteral("G"), QStringLiteral("C"), QStringLiteral("C#"), QStringLiteral("D"), QStringLiteral("D#"),
QStringLiteral("G#"), QStringLiteral("A"), QStringLiteral("A#"), QStringLiteral("B")}; QStringLiteral("E"), QStringLiteral("F"), QStringLiteral("F#"), QStringLiteral("G"),
QStringLiteral("G#"), QStringLiteral("A"), QStringLiteral("A#"), QStringLiteral("B"),
};
const int NaturalKeyNumbers[] = {0, 2, 4, 5, 7, 9, 11}; const std::array<int, 7> NaturalKeyNumbers{
0, 2, 4, 5, 7, 9, 11,
};
const int SharpKeyNumbers[] = {1, 3, 6, 8, 10}; const std::array<int, 5> SharpKeyNumbers{
1, 3, 6, 8, 10,
};
KeyboardOctave::KeyboardOctave(int octave, const QString& svgPath, QWidget* parent) KeyboardOctave::KeyboardOctave(int octave, const QString& svgPath, QWidget* parent)
: QSvgWidget(svgPath, parent), m_octave(octave) { : QSvgWidget(svgPath, parent), m_octave(octave) {
for (int i = 0; i < 7; ++i) for (size_t i = 0; i < NaturalKeyNames.size(); ++i) {
if (renderer()->elementExists(NaturalKeyNames[i])) const auto& naturalKeyName = NaturalKeyNames[i];
m_natural[i] =
renderer()->matrixForElement(NaturalKeyNames[i]).mapRect(renderer()->boundsOnElement(NaturalKeyNames[i]));
for (int i = 0; i < 5; ++i) if (renderer()->elementExists(naturalKeyName)) {
if (renderer()->elementExists(SharpKeyNames[i])) m_natural[i] = renderer()->matrixForElement(naturalKeyName).mapRect(renderer()->boundsOnElement(naturalKeyName));
m_sharp[i] = }
renderer()->matrixForElement(SharpKeyNames[i]).mapRect(renderer()->boundsOnElement(SharpKeyNames[i])); }
for (size_t i = 0; i < SharpKeyNames.size(); ++i) {
const auto& sharpKeyName = SharpKeyNames[i];
if (renderer()->elementExists(sharpKeyName)) {
m_sharp[i] = renderer()->matrixForElement(sharpKeyName).mapRect(renderer()->boundsOnElement(sharpKeyName));
}
}
/* The parent keyboard manages all mouse events */ /* The parent keyboard manages all mouse events */
setAttribute(Qt::WA_TransparentForMouseEvents); setAttribute(Qt::WA_TransparentForMouseEvents);
} }
int KeyboardOctave::getKey(const QPoint& localPos) const { int KeyboardOctave::getKey(const QPoint& localPos) const {
QPointF localPoint = m_widgetToSvg.map(localPos); const QPointF localPoint = m_widgetToSvg.map(localPos);
for (int i = 0; i < 5; ++i)
if (m_sharp[i].contains(localPoint)) for (size_t i = 0; i < m_sharp.size(); ++i) {
if (m_sharp[i].contains(localPoint)) {
return SharpKeyNumbers[i]; return SharpKeyNumbers[i];
for (int i = 0; i < 7; ++i) }
if (m_natural[i].contains(localPoint)) }
for (size_t i = 0; i < m_natural.size(); ++i) {
if (m_natural[i].contains(localPoint)) {
return NaturalKeyNumbers[i]; return NaturalKeyNumbers[i];
}
}
return -1; return -1;
} }
@ -58,8 +80,8 @@ KeyboardWidget::KeyboardWidget(QWidget* parent) : QWidget(parent) {
layout->setContentsMargins(QMargins()); layout->setContentsMargins(QMargins());
layout->setSpacing(0); layout->setSpacing(0);
for (int i = 0; i < 10; ++i) { for (size_t i = 0; i < m_widgets.size() - 1; ++i) {
m_widgets[i] = new KeyboardOctave(i, QStringLiteral(":/bg/keyboard.svg"), this); m_widgets[i] = new KeyboardOctave(int(i), QStringLiteral(":/bg/keyboard.svg"), this);
m_widgets[i]->setGeometry(QRect(0, 0, 141, 50)); m_widgets[i]->setGeometry(QRect(0, 0, 141, 50));
m_widgets[i]->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred)); m_widgets[i]->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred));
layout->addWidget(m_widgets[i]); layout->addWidget(m_widgets[i]);
@ -90,14 +112,19 @@ void KeyboardWidget::_startKey(int octave, int key) { emit notePressed(octave *
void KeyboardWidget::_stopKey() { emit noteReleased(); } void KeyboardWidget::_stopKey() { emit noteReleased(); }
void KeyboardWidget::_moveOnKey(int octave, int key) { void KeyboardWidget::_moveOnKey(int octave, int key) {
if (m_lastOctave != octave || m_lastKey != key) { if (m_lastOctave == octave && m_lastKey == key) {
m_lastOctave = octave; return;
m_lastKey = key; }
if (m_statusFocus)
m_statusFocus->setMessage( m_lastOctave = octave;
QStringLiteral("%1%2 (%3)").arg(KeyStrings[key]).arg(octave - 1).arg(octave * 12 + key)); m_lastKey = key;
if (m_holding)
_startKey(octave, key); if (m_statusFocus) {
m_statusFocus->setMessage(QStringLiteral("%1%2 (%3)").arg(KeyStrings[key]).arg(octave - 1).arg(octave * 12 + key));
}
if (m_holding) {
_startKey(octave, key);
} }
} }

View File

@ -1,16 +1,18 @@
#pragma once #pragma once
#include <array>
#include <QSlider> #include <QSlider>
#include <QString> #include <QString>
#include <QSvgWidget> #include <QSvgWidget>
#include <QWheelEvent> #include <QWheelEvent>
#include <QWidget> #include <QWidget>
extern const QString NaturalKeyNames[7]; extern const std::array<QString, 7> NaturalKeyNames;
extern const QString SharpKeyNames[5]; extern const std::array<QString, 5> SharpKeyNames;
extern const QString KeyStrings[12]; extern const std::array<QString, 12> KeyStrings;
extern const int NaturalKeyNumbers[7]; extern const std::array<int, 7> NaturalKeyNumbers;
extern const int SharpKeyNumbers[5]; extern const std::array<int, 5> SharpKeyNumbers;
class KeyboardWidget; class KeyboardWidget;
class StatusBarFocus; class StatusBarFocus;
@ -18,8 +20,8 @@ class StatusBarFocus;
class KeyboardOctave : public QSvgWidget { class KeyboardOctave : public QSvgWidget {
Q_OBJECT Q_OBJECT
int m_octave; int m_octave;
QRectF m_natural[7]; std::array<QRectF, 7> m_natural;
QRectF m_sharp[5]; std::array<QRectF, 5> m_sharp;
QTransform m_widgetToSvg; QTransform m_widgetToSvg;
public: public:
@ -31,7 +33,7 @@ public:
class KeyboardWidget : public QWidget { class KeyboardWidget : public QWidget {
Q_OBJECT Q_OBJECT
KeyboardOctave* m_widgets[11]; std::array<KeyboardOctave*, 11> m_widgets{};
StatusBarFocus* m_statusFocus = nullptr; StatusBarFocus* m_statusFocus = nullptr;
int m_lastOctave = -1; int m_lastOctave = -1;
int m_lastKey = -1; int m_lastKey = -1;

View File

@ -160,7 +160,7 @@ KeymapView::KeymapView(QWidget* parent)
size_t k = 0; size_t k = 0;
for (size_t i = 0; i < 11; ++i) { for (size_t i = 0; i < 11; ++i) {
for (size_t j = 0; j < 12 && k < m_keyTexts.size(); ++j) { for (size_t j = 0; j < KeyStrings.size() && k < m_keyTexts.size(); ++j) {
m_keyTexts[k++].setText(QStringLiteral("%1%2").arg(KeyStrings[j]).arg(i - 1)); m_keyTexts[k++].setText(QStringLiteral("%1%2").arg(KeyStrings[j]).arg(i - 1));
} }
} }
@ -169,16 +169,20 @@ KeymapView::KeymapView(QWidget* parent)
m_keyPalettes.fill(-1); m_keyPalettes.fill(-1);
for (size_t i = 0; i < m_natural.size(); ++i) { for (size_t i = 0; i < m_natural.size(); ++i) {
if (m_octaveRenderer.elementExists(NaturalKeyNames[i])) { const auto& naturalKeyName = NaturalKeyNames[i];
m_natural[i] = m_octaveRenderer.matrixForElement(NaturalKeyNames[i])
.mapRect(m_octaveRenderer.boundsOnElement(NaturalKeyNames[i])); if (m_octaveRenderer.elementExists(naturalKeyName)) {
m_natural[i] =
m_octaveRenderer.matrixForElement(naturalKeyName).mapRect(m_octaveRenderer.boundsOnElement(naturalKeyName));
} }
} }
for (size_t i = 0; i < m_sharp.size(); ++i) { for (size_t i = 0; i < m_sharp.size(); ++i) {
if (m_octaveRenderer.elementExists(SharpKeyNames[i])) { const auto& sharpKeyName = SharpKeyNames[i];
m_sharp[i] = m_octaveRenderer.matrixForElement(SharpKeyNames[i])
.mapRect(m_octaveRenderer.boundsOnElement(SharpKeyNames[i])); if (m_octaveRenderer.elementExists(sharpKeyName)) {
m_sharp[i] =
m_octaveRenderer.matrixForElement(sharpKeyName).mapRect(m_octaveRenderer.boundsOnElement(sharpKeyName));
} }
} }