diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9ec3eb023f5..d88175b5873 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -466,6 +466,8 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL
src/preferences/dialog/dlgprefautodjdlg.ui
src/preferences/dialog/dlgprefbeats.cpp
src/preferences/dialog/dlgprefbeatsdlg.ui
+ src/preferences/dialog/dlgprefcolors.cpp
+ src/preferences/dialog/dlgprefcolorsdlg.ui
src/preferences/dialog/dlgprefcrossfader.cpp
src/preferences/dialog/dlgprefcrossfaderdlg.ui
src/preferences/dialog/dlgprefdeck.cpp
@@ -498,6 +500,8 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL
src/preferences/dialog/dlgprefwaveformdlg.ui
src/preferences/dlgpreferencepage.cpp
src/preferences/effectsettingsmodel.cpp
+ src/preferences/colorpaletteeditor.cpp
+ src/preferences/colorpaletteeditormodel.cpp
src/preferences/colorpalettesettings.cpp
src/preferences/replaygainsettings.cpp
src/preferences/settingsmanager.cpp
@@ -562,6 +566,7 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL
src/util/cmdlineargs.cpp
src/util/color/color.cpp
src/util/color/colorpalette.cpp
+ src/util/color/predefinedcolorpalettes.cpp
src/util/console.cpp
src/util/db/dbconnection.cpp
src/util/db/dbconnectionpool.cpp
diff --git a/build/depends.py b/build/depends.py
index e13d2df5b3b..3d6096f2f13 100644
--- a/build/depends.py
+++ b/build/depends.py
@@ -768,6 +768,7 @@ def sources(self, build):
"src/preferences/configobject.cpp",
"src/preferences/dialog/dlgprefautodj.cpp",
"src/preferences/dialog/dlgprefdeck.cpp",
+ "src/preferences/dialog/dlgprefcolors.cpp",
"src/preferences/dialog/dlgprefcrossfader.cpp",
"src/preferences/dialog/dlgprefeffects.cpp",
"src/preferences/dialog/dlgprefeq.cpp",
@@ -790,6 +791,8 @@ def sources(self, build):
"src/preferences/effectsettingsmodel.cpp",
"src/preferences/broadcastprofile.cpp",
"src/preferences/upgrade.cpp",
+ "src/preferences/colorpaletteeditor.cpp",
+ "src/preferences/colorpaletteeditormodel.cpp",
"src/preferences/colorpalettesettings.cpp",
"src/preferences/dlgpreferencepage.cpp",
@@ -1286,6 +1289,7 @@ def sources(self, build):
"src/util/console.cpp",
"src/util/color/color.cpp",
"src/util/color/colorpalette.cpp",
+ "src/util/color/predefinedcolorpalettes.cpp",
"src/util/db/dbconnection.cpp",
"src/util/db/dbconnectionpool.cpp",
"src/util/db/dbconnectionpooler.cpp",
@@ -1347,6 +1351,7 @@ def sources(self, build):
'src/preferences/dialog/dlgprefautodjdlg.ui',
'src/preferences/dialog/dlgprefbeatsdlg.ui',
'src/preferences/dialog/dlgprefdeckdlg.ui',
+ 'src/preferences/dialog/dlgprefcolorsdlg.ui',
'src/preferences/dialog/dlgprefcrossfaderdlg.ui',
'src/preferences/dialog/dlgpreflv2dlg.ui',
'src/preferences/dialog/dlgprefeffectsdlg.ui',
diff --git a/res/images/preferences/ic_preferences_colors.svg b/res/images/preferences/ic_preferences_colors.svg
new file mode 100644
index 00000000000..cb7199750b8
--- /dev/null
+++ b/res/images/preferences/ic_preferences_colors.svg
@@ -0,0 +1,7 @@
+
diff --git a/res/mixxx.qrc b/res/mixxx.qrc
index 545cba1feac..c863791eee5 100644
--- a/res/mixxx.qrc
+++ b/res/mixxx.qrc
@@ -37,6 +37,7 @@
images/preferences/ic_preferences_autodj.svg
images/preferences/ic_preferences_bpmdetect.svg
images/preferences/ic_preferences_broadcast.svg
+ images/preferences/ic_preferences_colors.svg
images/preferences/ic_preferences_controllers.svg
images/preferences/ic_preferences_crossfader.svg
images/preferences/ic_preferences_decks.svg
diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp
index d087506dbc4..ebb89fd413c 100644
--- a/src/engine/controls/cuecontrol.cpp
+++ b/src/engine/controls/cuecontrol.cpp
@@ -11,6 +11,7 @@
#include "engine/enginebuffer.h"
#include "preferences/colorpalettesettings.h"
#include "util/color/color.h"
+#include "util/color/predefinedcolorpalettes.h"
#include "util/sample.h"
#include "vinylcontrol/defs_vinylcontrol.h"
@@ -622,7 +623,7 @@ void CueControl::hotcueSet(HotcueControl* pControl, double v) {
auto hotcueColorPalette = m_colorPaletteSettings.getHotcueColorPalette();
pCue->setColor(hotcueColorPalette.colorForHotcueIndex(hotcue));
} else {
- pCue->setColor(ColorPalette::kDefaultCueColor);
+ pCue->setColor(mixxx::PredefinedColorPalettes::kDefaultCueColor);
}
// TODO(XXX) deal with spurious signals
diff --git a/src/preferences/colorpaletteeditor.cpp b/src/preferences/colorpaletteeditor.cpp
new file mode 100644
index 00000000000..378d6abe576
--- /dev/null
+++ b/src/preferences/colorpaletteeditor.cpp
@@ -0,0 +1,216 @@
+#include "preferences/colorpaletteeditor.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "preferences/colorpalettesettings.h"
+#include "util/color/predefinedcolorpalettes.h"
+
+namespace {
+const QColor kDefaultPaletteColor(0, 0, 0);
+}
+
+ColorPaletteEditor::ColorPaletteEditor(QWidget* parent)
+ : QWidget(parent),
+ m_bPaletteExists(false),
+ m_bPaletteIsReadOnly(false),
+ m_pPaletteNameComboBox(make_parented()),
+ m_pTableView(make_parented()),
+ m_pModel(make_parented(m_pTableView)) {
+ m_pPaletteNameComboBox->setEditable(true);
+
+ QDialogButtonBox* pButtonBox = new QDialogButtonBox();
+ m_pSaveButton = pButtonBox->addButton(QDialogButtonBox::Save);
+ m_pResetButton = pButtonBox->addButton(QDialogButtonBox::Reset);
+ m_pDiscardButton = pButtonBox->addButton(QDialogButtonBox::Discard);
+
+ QHBoxLayout* pTopLayout = new QHBoxLayout();
+ pTopLayout->addWidget(new QLabel("Name:"));
+ pTopLayout->addWidget(m_pPaletteNameComboBox, 1);
+ pTopLayout->addWidget(pButtonBox);
+
+ QVBoxLayout* pLayout = new QVBoxLayout();
+ pLayout->addLayout(pTopLayout);
+ pLayout->addWidget(m_pTableView, 1);
+ setLayout(pLayout);
+ setContentsMargins(0, 0, 0, 0);
+
+ // Set up model
+ m_pModel->setColumnCount(2);
+ m_pModel->setHeaderData(0, Qt::Horizontal, tr("Color"), Qt::DisplayRole);
+ m_pModel->setHeaderData(1, Qt::Horizontal, tr("Assign to Hotcue"), Qt::DisplayRole);
+ connect(m_pModel,
+ &ColorPaletteEditorModel::dirtyChanged,
+ this,
+ &ColorPaletteEditor::slotUpdateButtons);
+ connect(m_pModel,
+ &ColorPaletteEditorModel::emptyChanged,
+ this,
+ &ColorPaletteEditor::slotUpdateButtons);
+
+ // Setup up table view
+ m_pTableView->setShowGrid(false);
+ m_pTableView->setSelectionBehavior(QAbstractItemView::SelectRows);
+ m_pTableView->setSelectionMode(QAbstractItemView::SingleSelection);
+ m_pTableView->setDragDropMode(QAbstractItemView::InternalMove);
+ m_pTableView->setDragDropOverwriteMode(false);
+ m_pTableView->setContextMenuPolicy(Qt::CustomContextMenu);
+ m_pTableView->setModel(m_pModel);
+
+ connect(m_pTableView,
+ &QTableView::doubleClicked,
+ this,
+ &ColorPaletteEditor::slotTableViewDoubleClicked);
+ connect(m_pTableView,
+ &QTableView::customContextMenuRequested,
+ this,
+ &ColorPaletteEditor::slotTableViewContextMenuRequested);
+ connect(m_pPaletteNameComboBox,
+ &QComboBox::editTextChanged,
+ this,
+ &ColorPaletteEditor::slotPaletteNameChanged);
+ connect(m_pDiscardButton,
+ &QPushButton::clicked,
+ this,
+ &ColorPaletteEditor::slotDiscardButtonClicked);
+ connect(m_pSaveButton,
+ &QPushButton::clicked,
+ this,
+ &ColorPaletteEditor::slotSaveButtonClicked);
+}
+
+void ColorPaletteEditor::initialize(UserSettingsPointer pConfig) {
+ DEBUG_ASSERT(!m_pConfig);
+ m_pConfig = pConfig;
+ reset();
+}
+
+void ColorPaletteEditor::reset() {
+ m_pPaletteNameComboBox->clear();
+ for (const ColorPalette& palette : mixxx::PredefinedColorPalettes::kPalettes) {
+ m_pPaletteNameComboBox->addItem(palette.getName());
+ }
+ m_pPaletteNameComboBox->insertSeparator(mixxx::PredefinedColorPalettes::kPalettes.size());
+ ColorPaletteSettings colorPaletteSettings(m_pConfig);
+ for (const QString& paletteName : colorPaletteSettings.getColorPaletteNames()) {
+ m_pPaletteNameComboBox->addItem(paletteName);
+ }
+}
+
+void ColorPaletteEditor::slotUpdateButtons() {
+ bool bDirty = m_pModel->isDirty();
+ bool bEmpty = m_pModel->isEmpty();
+ m_pResetButton->setEnabled(bDirty);
+ m_pSaveButton->setEnabled(!m_bPaletteExists || (!m_bPaletteIsReadOnly && bDirty && !bEmpty));
+ m_pDiscardButton->setEnabled(m_bPaletteExists && !m_bPaletteIsReadOnly);
+}
+
+void ColorPaletteEditor::slotTableViewDoubleClicked(const QModelIndex& index) {
+ if (index.isValid() && index.column() == 0) {
+ QColor color = QColorDialog::getColor();
+ if (color.isValid()) {
+ m_pModel->setColor(index.row(), color);
+ }
+ }
+}
+
+void ColorPaletteEditor::slotTableViewContextMenuRequested(const QPoint& pos) {
+ QMenu menu(this);
+
+ QAction* pAddAction = menu.addAction("Add");
+ QAction* pRemoveAction = menu.addAction("Remove");
+ QAction* pAction = menu.exec(m_pTableView->viewport()->mapToGlobal(pos));
+ if (pAction == pAddAction) {
+ m_pModel->appendRow(kDefaultPaletteColor);
+ } else if (pAction == pRemoveAction) {
+ QModelIndexList selection = m_pTableView->selectionModel()->selectedRows();
+
+ if (selection.count() > 0) {
+ QModelIndex index = selection.at(0);
+
+ //row selected
+ int row = index.row();
+ m_pModel->removeRow(row);
+ }
+ }
+}
+
+void ColorPaletteEditor::slotPaletteNameChanged(const QString& text) {
+ bool bPaletteIsReadOnly = false;
+ bool bPaletteExists = false;
+ for (const ColorPalette& palette : mixxx::PredefinedColorPalettes::kPalettes) {
+ if (text == palette.getName()) {
+ bPaletteExists = true;
+ bPaletteIsReadOnly = true;
+ break;
+ }
+ }
+
+ ColorPaletteSettings colorPaletteSettings(m_pConfig);
+ if (!bPaletteIsReadOnly) {
+ bPaletteExists = colorPaletteSettings.getColorPaletteNames().contains(text);
+ }
+
+ if (bPaletteExists) {
+ if (!m_pModel->isDirty()) {
+ bool bPaletteFound = false;
+ for (const ColorPalette& palette : mixxx::PredefinedColorPalettes::kPalettes) {
+ if (text == palette.getName()) {
+ bPaletteFound = true;
+ m_pModel->setColorPalette(palette);
+ break;
+ }
+ }
+ if (!bPaletteFound) {
+ m_pModel->setColorPalette(colorPaletteSettings.getColorPalette(text, mixxx::PredefinedColorPalettes::kDefaultHotcueColorPalette));
+ }
+ }
+ }
+
+ m_bPaletteExists = bPaletteExists;
+ m_bPaletteIsReadOnly = bPaletteIsReadOnly;
+ slotUpdateButtons();
+}
+
+void ColorPaletteEditor::slotDiscardButtonClicked() {
+ QString paletteName = m_pPaletteNameComboBox->currentText();
+ ColorPaletteSettings colorPaletteSettings(m_pConfig);
+ colorPaletteSettings.removePalette(paletteName);
+ reset();
+ emit paletteRemoved(paletteName);
+}
+
+void ColorPaletteEditor::slotSaveButtonClicked() {
+ QString paletteName = m_pPaletteNameComboBox->currentText();
+ ColorPaletteSettings colorPaletteSettings(m_pConfig);
+ colorPaletteSettings.setColorPalette(paletteName, m_pModel->getColorPalette(paletteName));
+ m_pModel->setDirty(false);
+ reset();
+ m_pPaletteNameComboBox->setCurrentText(paletteName);
+ emit paletteChanged(paletteName);
+}
+
+void ColorPaletteEditor::slotResetButtonClicked() {
+ QString paletteName = m_pPaletteNameComboBox->currentText();
+ ColorPaletteSettings colorPaletteSettings(m_pConfig);
+ bool bPaletteExists = colorPaletteSettings.getColorPaletteNames().contains(paletteName);
+ if (!bPaletteExists) {
+ for (const ColorPalette& palette : mixxx::PredefinedColorPalettes::kPalettes) {
+ if (paletteName == palette.getName()) {
+ bPaletteExists = true;
+ break;
+ }
+ }
+ }
+ m_pModel->setDirty(false);
+ reset();
+ if (bPaletteExists) {
+ m_pPaletteNameComboBox->setCurrentText(paletteName);
+ }
+}
diff --git a/src/preferences/colorpaletteeditor.h b/src/preferences/colorpaletteeditor.h
new file mode 100644
index 00000000000..9786c10b592
--- /dev/null
+++ b/src/preferences/colorpaletteeditor.h
@@ -0,0 +1,45 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+
+#include "preferences/colorpaletteeditormodel.h"
+#include "preferences/usersettings.h"
+#include "util/parented_ptr.h"
+
+// Widget for viewing, adding, editing and removing color palettes that can be
+// used for track/hotcue colors.
+class ColorPaletteEditor : public QWidget {
+ Q_OBJECT
+ public:
+ ColorPaletteEditor(QWidget* parent = nullptr);
+ void initialize(UserSettingsPointer pConfig);
+ void reset();
+
+ signals:
+ void paletteChanged(QString name);
+ void paletteRemoved(QString name);
+
+ private slots:
+ void slotUpdateButtons();
+ void slotTableViewDoubleClicked(const QModelIndex& index);
+ void slotTableViewContextMenuRequested(const QPoint& pos);
+ void slotPaletteNameChanged(const QString& text);
+ void slotDiscardButtonClicked();
+ void slotSaveButtonClicked();
+ void slotResetButtonClicked();
+
+ private:
+ bool m_bPaletteExists;
+ bool m_bPaletteIsReadOnly;
+
+ UserSettingsPointer m_pConfig;
+ parented_ptr m_pPaletteNameComboBox;
+ parented_ptr m_pTableView;
+ parented_ptr m_pModel;
+ QPushButton* m_pSaveButton;
+ QPushButton* m_pDiscardButton;
+ QPushButton* m_pResetButton;
+};
diff --git a/src/preferences/colorpaletteeditormodel.cpp b/src/preferences/colorpaletteeditormodel.cpp
new file mode 100644
index 00000000000..62d958fbe16
--- /dev/null
+++ b/src/preferences/colorpaletteeditormodel.cpp
@@ -0,0 +1,138 @@
+#include "preferences/colorpaletteeditormodel.h"
+
+namespace {
+
+QIcon toQIcon(const QColor& color) {
+ QPixmap pixmap(50, 50);
+ pixmap.fill(color);
+ return QIcon(pixmap);
+}
+
+} // namespace
+
+ColorPaletteEditorModel::ColorPaletteEditorModel(QObject* parent)
+ : QStandardItemModel(parent),
+ m_bEmpty(true),
+ m_bDirty(false) {
+ connect(this,
+ &ColorPaletteEditorModel::rowsRemoved,
+ [this] {
+ if (rowCount() == 0) {
+ m_bEmpty = true;
+ emit emptyChanged(true);
+ }
+ setDirty(true);
+ });
+ connect(this,
+ &ColorPaletteEditorModel::rowsInserted,
+ [this] {
+ if (m_bEmpty && rowCount() != 0) {
+ m_bEmpty = false;
+ emit emptyChanged(true);
+ }
+ setDirty(true);
+ });
+ connect(this,
+ &ColorPaletteEditorModel::rowsMoved,
+ [this] {
+ setDirty(true);
+ });
+}
+
+bool ColorPaletteEditorModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) {
+ // Always move the entire row, and don't allow column "shifting"
+ Q_UNUSED(column);
+ return QStandardItemModel::dropMimeData(data, action, row, 0, parent);
+}
+
+bool ColorPaletteEditorModel::setData(const QModelIndex& modelIndex, const QVariant& value, int role) {
+ setDirty(true);
+ if (modelIndex.isValid() && modelIndex.column() == 1) {
+ bool ok;
+ int hotcueIndex = value.toInt(&ok);
+
+ // Make sure that the value is valid
+ if (!ok || hotcueIndex <= 0 || hotcueIndex > rowCount()) {
+ return QStandardItemModel::setData(modelIndex, QVariant(), role);
+ }
+
+ // Make sure there is no other row with the same hotcue index
+ for (int i = 0; i < rowCount(); i++) {
+ QModelIndex otherModelIndex = index(i, 1);
+ QVariant otherValue = data(otherModelIndex);
+ int otherHotcueIndex = otherValue.toInt(&ok);
+ if (ok && otherHotcueIndex == hotcueIndex) {
+ QStandardItemModel::setData(otherModelIndex, QVariant(), role);
+ }
+ }
+ }
+
+ return QStandardItemModel::setData(modelIndex, value, role);
+}
+
+void ColorPaletteEditorModel::setColor(int row, const QColor& color) {
+ QStandardItem* pItem = item(row, 0);
+ if (pItem) {
+ pItem->setIcon(toQIcon(color));
+ pItem->setText(color.name());
+ }
+ setDirty(true);
+}
+
+void ColorPaletteEditorModel::appendRow(const QColor& color, int hotcueIndex) {
+ QStandardItem* pColorItem = new QStandardItem(toQIcon(color), color.name());
+ pColorItem->setEditable(false);
+ pColorItem->setDropEnabled(false);
+
+ QString hotcueIndexStr;
+ if (hotcueIndex >= 0) {
+ hotcueIndexStr = QString::number(hotcueIndex + 1);
+ }
+
+ QStandardItem* pHotcueIndexItem = new QStandardItem(hotcueIndexStr);
+ pHotcueIndexItem->setEditable(true);
+ pHotcueIndexItem->setDropEnabled(false);
+
+ QStandardItemModel::appendRow(QList{pColorItem, pHotcueIndexItem});
+}
+
+void ColorPaletteEditorModel::setColorPalette(const ColorPalette& palette) {
+ // Remove all rows
+ removeRows(0, rowCount());
+
+ // Make a map of hotcue indices
+ QMap hotcueColorIndicesMap;
+ QList hotcueColorIndices = palette.getHotcueIndices();
+ for (int i = 0; i < hotcueColorIndices.size(); i++) {
+ int colorIndex = hotcueColorIndices.at(i);
+ hotcueColorIndicesMap.insert(colorIndex, i);
+ }
+
+ for (int i = 0; i < palette.size(); i++) {
+ QColor color = mixxx::RgbColor::toQColor(palette.at(i));
+ int colorIndex = hotcueColorIndicesMap.value(i, kNoHotcueIndex);
+ appendRow(color, colorIndex);
+ }
+
+ setDirty(false);
+}
+
+ColorPalette ColorPaletteEditorModel::getColorPalette(const QString& name) const {
+ QList colors;
+ QMap hotcueColorIndices;
+ for (int i = 0; i < rowCount(); i++) {
+ QStandardItem* pColorItem = item(i, 0);
+ QStandardItem* pHotcueIndexItem = item(i, 1);
+ mixxx::RgbColor::optional_t color = mixxx::RgbColor::fromQString(pColorItem->text());
+ if (color) {
+ colors << *color;
+
+ bool ok;
+ int hotcueIndex = pHotcueIndexItem->text().toInt(&ok);
+ if (ok) {
+ hotcueColorIndices.insert(hotcueIndex - 1, colors.size() - 1);
+ }
+ }
+ }
+ return ColorPalette(name, colors, hotcueColorIndices.values());
+}
diff --git a/src/preferences/colorpaletteeditormodel.h b/src/preferences/colorpaletteeditormodel.h
new file mode 100644
index 00000000000..b76c7a0053f
--- /dev/null
+++ b/src/preferences/colorpaletteeditormodel.h
@@ -0,0 +1,48 @@
+#pragma once
+#include
+
+#include "util/color/colorpalette.h"
+
+// Model that is used by the QTableView of the ColorPaletteEditor.
+// Takes of displaying palette colors and provides a getter/setter for
+// ColorPalette instances.
+class ColorPaletteEditorModel : public QStandardItemModel {
+ Q_OBJECT
+ public:
+ static constexpr int kNoHotcueIndex = -1;
+
+ ColorPaletteEditorModel(QObject* parent = nullptr);
+
+ bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) override;
+ bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
+
+ void setColor(int row, const QColor& color);
+ void appendRow(const QColor& color, int hotcueIndex = kNoHotcueIndex);
+
+ void setDirty(bool bDirty) {
+ if (m_bDirty == bDirty) {
+ return;
+ }
+ m_bDirty = bDirty;
+ emit dirtyChanged(m_bDirty);
+ }
+
+ bool isDirty() const {
+ return m_bDirty;
+ }
+
+ bool isEmpty() const {
+ return m_bEmpty;
+ }
+
+ void setColorPalette(const ColorPalette& palette);
+ ColorPalette getColorPalette(const QString& name) const;
+
+ signals:
+ void emptyChanged(bool bIsEmpty);
+ void dirtyChanged(bool bIsDirty);
+
+ private:
+ bool m_bEmpty;
+ bool m_bDirty;
+};
diff --git a/src/preferences/colorpalettesettings.cpp b/src/preferences/colorpalettesettings.cpp
index 63976e4cbdb..fed31b32743 100644
--- a/src/preferences/colorpalettesettings.cpp
+++ b/src/preferences/colorpalettesettings.cpp
@@ -1,11 +1,16 @@
#include "preferences/colorpalettesettings.h"
+#include "util/color/predefinedcolorpalettes.h"
+
namespace {
const mixxx::RgbColor kColorBlack(0x000000);
const QString kColorPaletteConfigGroup = QStringLiteral("[Config]");
const QString kColorPaletteGroupStart = QStringLiteral("[ColorPalette ");
const QString kColorPaletteGroupEnd = QStringLiteral("]");
const QRegExp kColorPaletteGroupNameRegex(QStringLiteral("^\\[ColorPalette (.+)\\]$"));
+const QString kColorPaletteHotcueIndicesConfigItem = QStringLiteral("hotcue_indices");
+const QString kColorPaletteHotcueIndicesConfigSeparator = QStringLiteral(" ");
+const QString kColorPaletteGroup = QStringLiteral("[ColorPalette %1]");
const ConfigKey kHotcueColorPaletteConfigKey(kColorPaletteConfigGroup, QStringLiteral("HotcueColorPalette"));
const ConfigKey kTrackColorPaletteConfigKey(kColorPaletteConfigGroup, QStringLiteral("TrackColorPalette"));
@@ -25,12 +30,35 @@ ConfigKey keyForIndex(const QString& group, int index, int numDigits) {
ColorPalette ColorPaletteSettings::getColorPalette(
const QString& name, const ColorPalette& defaultPalette) const {
- QList colorList;
+ if (name.isEmpty()) {
+ return defaultPalette;
+ }
+ // If we find a predefined palette with this name, return it
+ for (const ColorPalette& palette : mixxx::PredefinedColorPalettes::kPalettes) {
+ if (name == palette.getName()) {
+ return palette;
+ }
+ }
+
+ // Read colors from configuration
const QString group = kColorPaletteGroupStart + name + kColorPaletteGroupEnd;
+ QList colorList;
+ QList hotcueIndices;
for (const ConfigKey& key : m_pConfig->getKeysWithGroup(group)) {
- mixxx::RgbColor color = mixxx::RgbColor(m_pConfig->getValue(key, kColorBlack));
- colorList.append(color);
+ if (key.item == kColorPaletteHotcueIndicesConfigItem) {
+ for (const QString& stringIndex :
+ m_pConfig->getValueString(key).split(kColorPaletteHotcueIndicesConfigSeparator, QString::SkipEmptyParts)) {
+ bool ok;
+ int index = stringIndex.toInt(&ok);
+ if (ok && index >= 0) {
+ hotcueIndices << static_cast(index);
+ }
+ }
+ } else {
+ mixxx::RgbColor color = mixxx::RgbColor(m_pConfig->getValue(key, kColorBlack));
+ colorList.append(color);
+ }
}
// If no palette is defined in the settings, we use the default one.
@@ -38,7 +66,7 @@ ColorPalette ColorPaletteSettings::getColorPalette(
return defaultPalette;
}
- return ColorPalette(name, colorList);
+ return ColorPalette(name, colorList, hotcueIndices);
}
void ColorPaletteSettings::setColorPalette(const QString& name, const ColorPalette& colorPalette) {
@@ -47,6 +75,12 @@ void ColorPaletteSettings::setColorPalette(const QString& name, const ColorPalet
return;
}
+ for (const ColorPalette& palette : mixxx::PredefinedColorPalettes::kPalettes) {
+ if (name == palette.getName()) {
+ qDebug() << "Color Palette" << name << "is a built-in palette, not writing to config!";
+ return;
+ }
+ }
removePalette(name);
const QString group = kColorPaletteGroupStart + name + kColorPaletteGroupEnd;
@@ -55,6 +89,16 @@ void ColorPaletteSettings::setColorPalette(const QString& name, const ColorPalet
mixxx::RgbColor color = colorPalette.at(index);
m_pConfig->setValue(keyForIndex(group, index, numDigits), color);
}
+
+ QStringList stringIndices;
+ for (const unsigned int index : colorPalette.getHotcueIndices()) {
+ stringIndices << QString::number(index);
+ }
+ if (!stringIndices.isEmpty()) {
+ m_pConfig->setValue(
+ ConfigKey(group, kColorPaletteHotcueIndicesConfigItem),
+ stringIndices.join(kColorPaletteHotcueIndicesConfigSeparator));
+ }
}
void ColorPaletteSettings::removePalette(const QString& name) {
@@ -66,10 +110,7 @@ void ColorPaletteSettings::removePalette(const QString& name) {
ColorPalette ColorPaletteSettings::getHotcueColorPalette() const {
QString name = m_pConfig->getValueString(kHotcueColorPaletteConfigKey);
- if (name.isEmpty()) {
- return ColorPalette::mixxxHotcuePalette;
- }
- return getColorPalette(name, ColorPalette::mixxxHotcuePalette);
+ return getColorPalette(name, mixxx::PredefinedColorPalettes::kDefaultHotcueColorPalette);
}
void ColorPaletteSettings::setHotcueColorPalette(const ColorPalette& colorPalette) {
@@ -84,10 +125,7 @@ void ColorPaletteSettings::setHotcueColorPalette(const ColorPalette& colorPalett
ColorPalette ColorPaletteSettings::getTrackColorPalette() const {
QString name = m_pConfig->getValueString(kTrackColorPaletteConfigKey);
- if (name.isEmpty()) {
- return ColorPalette::mixxxHotcuePalette;
- }
- return getColorPalette(name, ColorPalette::mixxxHotcuePalette);
+ return getColorPalette(name, mixxx::PredefinedColorPalettes::kDefaultTrackColorPalette);
}
void ColorPaletteSettings::setTrackColorPalette(const ColorPalette& colorPalette) {
diff --git a/src/preferences/dialog/dlgprefcolors.cpp b/src/preferences/dialog/dlgprefcolors.cpp
new file mode 100644
index 00000000000..6888e8db98b
--- /dev/null
+++ b/src/preferences/dialog/dlgprefcolors.cpp
@@ -0,0 +1,100 @@
+#include "preferences/dialog/dlgprefcolors.h"
+
+#include
+#include
+#include
+
+#include "control/controlobject.h"
+#include "util/color/predefinedcolorpalettes.h"
+
+DlgPrefColors::DlgPrefColors(
+ QWidget* parent, UserSettingsPointer pConfig)
+ : DlgPreferencePage(parent),
+ m_pConfig(pConfig),
+ m_colorPaletteSettings(ColorPaletteSettings(pConfig)) {
+ setupUi(this);
+ colorPaletteEditor->initialize(pConfig);
+
+ loadSettings();
+
+ connect(colorPaletteEditor,
+ &ColorPaletteEditor::paletteChanged,
+ [this] {
+ loadSettings();
+ });
+ connect(colorPaletteEditor,
+ &ColorPaletteEditor::paletteRemoved,
+ [this] {
+ loadSettings();
+ });
+}
+
+DlgPrefColors::~DlgPrefColors() {
+}
+
+// Loads the config keys and sets the widgets in the dialog to match
+void DlgPrefColors::loadSettings() {
+ comboBoxHotcueColors->clear();
+ comboBoxTrackColors->clear();
+ foreach (const ColorPalette& palette, mixxx::PredefinedColorPalettes::kPalettes) {
+ QString paletteName = palette.getName();
+ comboBoxHotcueColors->addItem(paletteName);
+ comboBoxTrackColors->addItem(paletteName);
+ }
+
+ foreach (const QString& paletteName, m_colorPaletteSettings.getColorPaletteNames()) {
+ comboBoxHotcueColors->addItem(paletteName);
+ comboBoxTrackColors->addItem(paletteName);
+ }
+
+ comboBoxHotcueColors->setCurrentText(
+ m_colorPaletteSettings.getHotcueColorPalette().getName());
+ comboBoxTrackColors->setCurrentText(
+ m_colorPaletteSettings.getTrackColorPalette().getName());
+
+ slotApply();
+}
+
+// Set the default values for all the widgets
+void DlgPrefColors::slotResetToDefaults() {
+ comboBoxHotcueColors->setCurrentText(
+ mixxx::PredefinedColorPalettes::kDefaultHotcueColorPalette.getName());
+ comboBoxTrackColors->setCurrentText(
+ mixxx::PredefinedColorPalettes::kDefaultTrackColorPalette.getName());
+ slotApply();
+}
+
+// Apply and save any changes made in the dialog
+void DlgPrefColors::slotApply() {
+ QString hotcueColorPaletteName = comboBoxHotcueColors->currentText();
+ QString trackColorPaletteName = comboBoxTrackColors->currentText();
+ bool bHotcueColorPaletteFound = false;
+ bool bTrackColorPaletteFound = false;
+
+ foreach (const ColorPalette& palette, mixxx::PredefinedColorPalettes::kPalettes) {
+ if (!bHotcueColorPaletteFound && hotcueColorPaletteName == palette.getName()) {
+ m_colorPaletteSettings.setHotcueColorPalette(palette);
+ bHotcueColorPaletteFound = true;
+ }
+ if (!bTrackColorPaletteFound && trackColorPaletteName == palette.getName()) {
+ m_colorPaletteSettings.setTrackColorPalette(palette);
+ bTrackColorPaletteFound = true;
+ }
+ }
+
+ if (!bHotcueColorPaletteFound) {
+ m_colorPaletteSettings.setHotcueColorPalette(
+ m_colorPaletteSettings.getColorPalette(hotcueColorPaletteName,
+ m_colorPaletteSettings.getHotcueColorPalette()));
+ }
+
+ if (!bTrackColorPaletteFound) {
+ m_colorPaletteSettings.setTrackColorPalette(
+ m_colorPaletteSettings.getColorPalette(trackColorPaletteName,
+ m_colorPaletteSettings.getTrackColorPalette()));
+ }
+
+ m_pConfig->setValue(
+ ConfigKey("[Controls]", "auto_hotcue_colors"),
+ checkBoxAssignHotcueColors->isChecked());
+}
diff --git a/src/preferences/dialog/dlgprefcolors.h b/src/preferences/dialog/dlgprefcolors.h
new file mode 100644
index 00000000000..9feb41a873b
--- /dev/null
+++ b/src/preferences/dialog/dlgprefcolors.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include
+
+#include "control/controlproxy.h"
+#include "preferences/colorpalettesettings.h"
+#include "preferences/dialog/ui_dlgprefcolorsdlg.h"
+#include "preferences/dlgpreferencepage.h"
+#include "preferences/usersettings.h"
+
+class DlgPrefColors : public DlgPreferencePage, public Ui::DlgPrefColorsDlg {
+ Q_OBJECT
+ public:
+ DlgPrefColors(QWidget* parent, UserSettingsPointer pConfig);
+ virtual ~DlgPrefColors();
+
+ public slots:
+ // Apply changes to widget
+ void slotApply();
+ void slotResetToDefaults();
+
+ signals:
+ void apply(const QString&);
+
+ private:
+ void loadSettings();
+ void loadPaletteIntoEditor(const ColorPalette& palette);
+
+ const UserSettingsPointer m_pConfig;
+ ColorPaletteSettings m_colorPaletteSettings;
+};
diff --git a/src/preferences/dialog/dlgprefcolorsdlg.ui b/src/preferences/dialog/dlgprefcolorsdlg.ui
new file mode 100644
index 00000000000..08bf006daa6
--- /dev/null
+++ b/src/preferences/dialog/dlgprefcolorsdlg.ui
@@ -0,0 +1,110 @@
+
+
+ DlgPrefColorsDlg
+
+
+
+ 0
+ 0
+ 524
+ 333
+
+
+
+
+ 0
+ 0
+
+
+
+ Color Preferences
+
+
+ -
+
+
+ Colors
+
+
+
-
+
+
+ Hotcues:
+
+
+
+ -
+
+
+ -
+
+
+ Track:
+
+
+
+ -
+
+
+ -
+
+
+ Auto hotcue colors
+
+
+ checkBoxAssignHotcueColors
+
+
+
+ -
+
+
+ Automatically assigns a predefined color to a newly created hotcue point, based on its index.
+
+
+ Assign predefined colors to newly created hotcue points
+
+
+
+
+
+
+ -
+
+
+ Palette Editor
+
+
+
-
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+
+ ColorPaletteEditor
+ QWidget
+ preferences/colorpaletteeditor.h
+ 1
+
+
+
+
+
diff --git a/src/preferences/dialog/dlgprefdeck.cpp b/src/preferences/dialog/dlgprefdeck.cpp
index e6c2ced3be2..1d27be85333 100644
--- a/src/preferences/dialog/dlgprefdeck.cpp
+++ b/src/preferences/dialog/dlgprefdeck.cpp
@@ -206,14 +206,6 @@ DlgPrefDeck::DlgPrefDeck(QWidget * parent, MixxxMainWindow * mixxx,
this,
SLOT(slotCloneDeckOnLoadDoubleTapCheckbox(bool)));
- // Automatically assign a color to new hot cues
- m_bAssignHotcueColors = m_pConfig->getValue(ConfigKey("[Controls]", "auto_hotcue_colors"), false);
- checkBoxAssignHotcueColors->setChecked(m_bAssignHotcueColors);
- connect(checkBoxAssignHotcueColors,
- SIGNAL(toggled(bool)),
- this,
- SLOT(slotAssignHotcueColorsCheckbox(bool)));
-
m_bRateInverted = m_pConfig->getValue(ConfigKey("[Controls]", "RateDir"), false);
setRateDirectionForAllDecks(m_bRateInverted);
checkBoxInvertSpeedSlider->setChecked(m_bRateInverted);
@@ -386,9 +378,6 @@ void DlgPrefDeck::slotUpdate() {
checkBoxCloneDeckOnLoadDoubleTap->setChecked(m_pConfig->getValue(
ConfigKey("[Controls]", "CloneDeckOnLoadDoubleTap"), true));
- checkBoxAssignHotcueColors->setChecked(m_pConfig->getValue(
- ConfigKey("[Controls]", "auto_hotcue_colors"), false));
-
double deck1RateRange = m_rateRangeControls[0]->get();
int index = ComboBoxRateRange->findData(static_cast(deck1RateRange * 100));
if (index == -1) {
@@ -551,10 +540,6 @@ void DlgPrefDeck::slotCloneDeckOnLoadDoubleTapCheckbox(bool checked) {
m_bCloneDeckOnLoadDoubleTap = checked;
}
-void DlgPrefDeck::slotAssignHotcueColorsCheckbox(bool checked) {
- m_bAssignHotcueColors = checked;
-}
-
void DlgPrefDeck::slotSetTrackTimeDisplay(QAbstractButton* b) {
if (b == radioButtonRemaining) {
m_timeDisplayMode = TrackTime::DisplayMode::REMAINING;
@@ -642,7 +627,6 @@ void DlgPrefDeck::slotApply() {
m_pConfig->setValue(ConfigKey("[Controls]", "CueRecall"), static_cast(m_seekOnLoadMode));
m_pConfig->setValue(ConfigKey("[Controls]", "CloneDeckOnLoadDoubleTap"),
m_bCloneDeckOnLoadDoubleTap);
- m_pConfig->setValue(ConfigKey("[Controls]", "auto_hotcue_colors"), m_bAssignHotcueColors);
// Set rate range
setRateRangeForAllDecks(m_iRateRangePercent);
diff --git a/src/preferences/dialog/dlgprefdeck.h b/src/preferences/dialog/dlgprefdeck.h
index cbc3b5b8688..96bc1914401 100644
--- a/src/preferences/dialog/dlgprefdeck.h
+++ b/src/preferences/dialog/dlgprefdeck.h
@@ -80,7 +80,6 @@ class DlgPrefDeck : public DlgPreferencePage, public Ui::DlgPrefDeckDlg {
void slotCueModeCombobox(int);
void slotSetTrackLoadMode(int comboboxIndex);
void slotCloneDeckOnLoadDoubleTapCheckbox(bool);
- void slotAssignHotcueColorsCheckbox(bool);
void slotRateRampingModeLinearButton(bool);
void slotRateRampSensitivitySlider(int);
diff --git a/src/preferences/dialog/dlgprefdeckdlg.ui b/src/preferences/dialog/dlgprefdeckdlg.ui
index e1ca340a60d..927f8aecabf 100644
--- a/src/preferences/dialog/dlgprefdeckdlg.ui
+++ b/src/preferences/dialog/dlgprefdeckdlg.ui
@@ -23,6 +23,16 @@
10
+ -
+
+
+ Playing track protection
+
+
+ checkBoxDisallowLoadToPlayingDeck
+
+
+
-
@@ -36,6 +46,33 @@
+ -
+
+
+ -
+
+
+ When the analyzer places the intro start point automatically,
+it will place it at the main cue point if the main cue point has been set previously.
+This may be helpful for upgrading to Mixxx 2.3 from earlier versions.
+
+If this option is disabled, the intro start point is automatically placed at the first sound.
+
+
+ Set intro start to main cue when analyzing tracks
+
+
+
+ -
+
+
+ Intro start
+
+
+ ComboBoxCueMode
+
+
+
-
@@ -61,27 +98,30 @@ CUP mode:
- -
-
+
-
+
- Intro start
+ Clone deck
- ComboBoxCueMode
+ checkBoxCloneDeckOnLoadDoubleTap
- -
-
-
- When the analyzer places the intro start point automatically,
-it will place it at the main cue point if the main cue point has been set previously.
-This may be helpful for upgrading to Mixxx 2.3 from earlier versions.
-
-If this option is disabled, the intro start point is automatically placed at the first sound.
+
-
+
+
+ Time Format
+
+
+ -
+
+
+ -
+
- Set intro start to main cue when analyzing tracks
+ Track load point
@@ -104,6 +144,13 @@ If this option is disabled, the intro start point is automatically placed at the
+ -
+
+
+ Do not load tracks into playing decks
+
+
+
-
-
@@ -138,74 +185,7 @@ If this option is disabled, the intro start point is automatically placed at the
- -
-
-
- Time Format
-
-
-
- -
-
-
- -
-
-
- Track load point
-
-
-
- -
-
-
- -
-
-
- Auto hotcue colors
-
-
- checkBoxAssignHotcueColors
-
-
-
- -
-
-
- Automatically assigns a predefined color to a newly created hotcue point, based on its index.
-
-
- Assign predefined colors to newly created hotcue points
-
-
-
- -
-
-
- Playing track protection
-
-
- checkBoxDisallowLoadToPlayingDeck
-
-
-
-
-
-
- Do not load tracks into playing decks
-
-
-
- -
-
-
- Clone deck
-
-
- checkBoxCloneDeckOnLoadDoubleTap
-
-
-
- -
Create a playing clone of the first playing deck by double-tapping a Load button on a controller or keyboard.
@@ -822,14 +802,13 @@ You can always drag-and-drop tracks on screen to clone a deck.
-
+
+
false
-
-
diff --git a/src/preferences/dialog/dlgpreferences.cpp b/src/preferences/dialog/dlgpreferences.cpp
index fc34d5a30bb..61b7b1828e6 100644
--- a/src/preferences/dialog/dlgpreferences.cpp
+++ b/src/preferences/dialog/dlgpreferences.cpp
@@ -37,11 +37,12 @@
#include "preferences/dialog/dlgprefnovinyl.h"
#endif
-#include "preferences/dialog/dlgprefinterface.h"
-#include "preferences/dialog/dlgprefwaveform.h"
+#include "preferences/dialog/dlgprefcolors.h"
+#include "preferences/dialog/dlgprefcrossfader.h"
#include "preferences/dialog/dlgprefdeck.h"
#include "preferences/dialog/dlgprefeq.h"
-#include "preferences/dialog/dlgprefcrossfader.h"
+#include "preferences/dialog/dlgprefinterface.h"
+#include "preferences/dialog/dlgprefwaveform.h"
#ifdef __LILV__
#include "preferences/dialog/dlgpreflv2.h"
#endif /* __LILV__ */
@@ -121,6 +122,8 @@ DlgPreferences::DlgPreferences(MixxxMainWindow * mixxx, SkinLoader* pSkinLoader,
addPageWidget(m_waveformPage);
m_deckPage = new DlgPrefDeck(this, mixxx, pPlayerManager, m_pConfig);
addPageWidget(m_deckPage);
+ m_colorsPage = new DlgPrefColors(this, m_pConfig);
+ addPageWidget(m_colorsPage);
m_equalizerPage = new DlgPrefEQ(this, pEffectsManager, m_pConfig);
addPageWidget(m_equalizerPage);
m_crossfaderPage = new DlgPrefCrossfader(this, m_pConfig);
@@ -234,6 +237,12 @@ void DlgPreferences::createIcons() {
m_pDecksButton->setTextAlignment(0, Qt::AlignLeft | Qt::AlignVCenter);
m_pDecksButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+ m_pColorsButton = new QTreeWidgetItem(contentsTreeWidget, QTreeWidgetItem::Type);
+ m_pColorsButton->setIcon(0, QIcon(":/images/preferences/ic_preferences_colors.svg"));
+ m_pColorsButton->setText(0, tr("Colors"));
+ m_pColorsButton->setTextAlignment(0, Qt::AlignLeft | Qt::AlignVCenter);
+ m_pColorsButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+
m_pEqButton = new QTreeWidgetItem(contentsTreeWidget, QTreeWidgetItem::Type);
m_pEqButton->setIcon(0, QIcon(":/images/preferences/ic_preferences_equalizers.svg"));
m_pEqButton->setText(0, tr("Equalizers"));
@@ -334,6 +343,8 @@ void DlgPreferences::changePage(QTreeWidgetItem* current, QTreeWidgetItem* previ
switchToPage(m_waveformPage);
} else if (current == m_pDecksButton) {
switchToPage(m_deckPage);
+ } else if (current == m_pColorsButton) {
+ switchToPage(m_colorsPage);
} else if (current == m_pEqButton) {
switchToPage(m_equalizerPage);
} else if (current == m_pCrossfaderButton) {
diff --git a/src/preferences/dialog/dlgpreferences.h b/src/preferences/dialog/dlgpreferences.h
index a33b504249a..aa1972f4bd9 100644
--- a/src/preferences/dialog/dlgpreferences.h
+++ b/src/preferences/dialog/dlgpreferences.h
@@ -40,6 +40,7 @@ class DlgPrefNoVinyl;
class DlgPrefInterface;
class DlgPrefWaveform;
class DlgPrefDeck;
+class DlgPrefColors;
class DlgPrefEQ;
class DlgPrefEffects;
class DlgPrefCrossfader;
@@ -66,11 +67,16 @@ class DlgPrefModplug;
class DlgPreferences : public QDialog, public Ui::DlgPreferencesDlg {
Q_OBJECT
public:
- DlgPreferences(MixxxMainWindow* mixxx, SkinLoader* pSkinLoader, SoundManager* soundman,
- PlayerManager* pPlayerManager, ControllerManager* controllers,
- VinylControlManager* pVCManager, LV2Backend* pLV2Backend,
- EffectsManager* pEffectsManager,
- SettingsManager* pSettingsManager, Library *pLibrary);
+ DlgPreferences(MixxxMainWindow* mixxx,
+ SkinLoader* pSkinLoader,
+ SoundManager* soundman,
+ PlayerManager* pPlayerManager,
+ ControllerManager* controllers,
+ VinylControlManager* pVCManager,
+ LV2Backend* pLV2Backend,
+ EffectsManager* pEffectsManager,
+ SettingsManager* pSettingsManager,
+ Library* pLibrary);
virtual ~DlgPreferences();
void addPageWidget(DlgPreferencePage* pWidget);
@@ -115,6 +121,7 @@ class DlgPreferences : public QDialog, public Ui::DlgPreferencesDlg {
DlgPrefInterface* m_interfacePage;
DlgPrefWaveform* m_waveformPage;
DlgPrefDeck* m_deckPage;
+ DlgPrefColors* m_colorsPage;
DlgPrefEQ* m_equalizerPage;
DlgPrefCrossfader* m_crossfaderPage;
DlgPrefEffects* m_effectsPage;
@@ -138,6 +145,7 @@ class DlgPreferences : public QDialog, public Ui::DlgPreferencesDlg {
QTreeWidgetItem* m_pInterfaceButton;
QTreeWidgetItem* m_pWaveformButton;
QTreeWidgetItem* m_pDecksButton;
+ QTreeWidgetItem* m_pColorsButton;
QTreeWidgetItem* m_pEqButton;
#ifdef __LILV__
QTreeWidgetItem* m_pLV2Button;
diff --git a/src/test/colorconfig_test.cpp b/src/test/colorconfig_test.cpp
index 58a17f706a2..5ed387161b0 100644
--- a/src/test/colorconfig_test.cpp
+++ b/src/test/colorconfig_test.cpp
@@ -3,6 +3,7 @@
#include "preferences/colorpalettesettings.h"
#include "test/mixxxtest.h"
#include "util/color/colorpalette.h"
+#include "util/color/predefinedcolorpalettes.h"
#include "util/color/rgbcolor.h"
class ColorConfigTest : public MixxxTest {};
@@ -99,7 +100,8 @@ TEST_F(ColorConfigTest, LoadSavePalettes) {
TEST_F(ColorConfigTest, DefaultColorPalette) {
ColorPaletteSettings colorPaletteSettings(config());
- ColorPalette colorPaletteFromConfig =
- colorPaletteSettings.getHotcueColorPalette();
- ASSERT_EQ(ColorPalette::mixxxHotcuePalette, colorPaletteFromConfig);
+ ASSERT_EQ(mixxx::PredefinedColorPalettes::kDefaultHotcueColorPalette,
+ colorPaletteSettings.getHotcueColorPalette());
+ ASSERT_EQ(mixxx::PredefinedColorPalettes::kDefaultTrackColorPalette,
+ colorPaletteSettings.getTrackColorPalette());
}
diff --git a/src/test/colorpalette_test.cpp b/src/test/colorpalette_test.cpp
index 77b13d731de..f601259a68c 100644
--- a/src/test/colorpalette_test.cpp
+++ b/src/test/colorpalette_test.cpp
@@ -3,25 +3,26 @@
#include
#include "test/mixxxtest.h"
+#include "util/color/predefinedcolorpalettes.h"
class ColorPaletteTest : public MixxxTest {};
TEST_F(ColorPaletteTest, NextColor) {
- const ColorPalette palette = ColorPalette::mixxxHotcuePalette;
+ const ColorPalette palette = mixxx::PredefinedColorPalettes::kDefaultHotcueColorPalette;
ASSERT_TRUE(palette.size() >= 1);
ASSERT_EQ(palette.nextColor(palette.at(0)), palette.at(1));
ASSERT_EQ(palette.nextColor(palette.at(palette.size() - 1)), palette.at(0));
}
TEST_F(ColorPaletteTest, PreviousColor) {
- const ColorPalette palette = ColorPalette::mixxxHotcuePalette;
+ const ColorPalette palette = mixxx::PredefinedColorPalettes::kDefaultHotcueColorPalette;
ASSERT_TRUE(palette.size() >= 1);
ASSERT_EQ(palette.previousColor(palette.at(1)), palette.at(0));
ASSERT_EQ(palette.previousColor(palette.at(0)), palette.at(palette.size() - 1));
}
TEST_F(ColorPaletteTest, NextAndPreviousColorRoundtrip) {
- const ColorPalette palette = ColorPalette::mixxxHotcuePalette;
+ const ColorPalette palette = mixxx::PredefinedColorPalettes::kDefaultHotcueColorPalette;
ASSERT_TRUE(palette.size() >= 1);
ASSERT_EQ(palette.nextColor(palette.previousColor(palette.at(0))), palette.at(0));
ASSERT_EQ(palette.nextColor(palette.previousColor(palette.at(palette.size() - 1))), palette.at(palette.size() - 1));
diff --git a/src/track/cue.cpp b/src/track/cue.cpp
index a923ab7a941..7ba0ad99251 100644
--- a/src/track/cue.cpp
+++ b/src/track/cue.cpp
@@ -9,7 +9,7 @@
#include "engine/engine.h"
#include "util/assert.h"
#include "util/color/color.h"
-#include "util/color/colorpalette.h"
+#include "util/color/predefinedcolorpalettes.h"
namespace {
@@ -54,7 +54,7 @@ Cue::Cue()
m_sampleStartPosition(Cue::kNoPosition),
m_sampleEndPosition(Cue::kNoPosition),
m_iHotCue(Cue::kNoHotCue),
- m_color(ColorPalette::kDefaultCueColor) {
+ m_color(mixxx::PredefinedColorPalettes::kDefaultCueColor) {
}
Cue::Cue(
@@ -101,7 +101,7 @@ Cue::Cue(
sampleRate)),
m_iHotCue(cueInfo.getHotCueNumber() ? *cueInfo.getHotCueNumber() : kNoHotCue),
m_label(cueInfo.getLabel()),
- m_color(cueInfo.getColor().value_or(ColorPalette::kDefaultCueColor)) {
+ m_color(cueInfo.getColor().value_or(mixxx::PredefinedColorPalettes::kDefaultCueColor)) {
}
mixxx::CueInfo Cue::getCueInfo(
diff --git a/src/util/color/colorpalette.cpp b/src/util/color/colorpalette.cpp
index a606f8e73b4..f5ff71be249 100644
--- a/src/util/color/colorpalette.cpp
+++ b/src/util/color/colorpalette.cpp
@@ -1,38 +1,5 @@
#include "colorpalette.h"
-namespace {
-
-constexpr mixxx::RgbColor kColorMixxxRed(0xC50A08);
-constexpr mixxx::RgbColor kColorMixxxYellow(0x32BE44);
-constexpr mixxx::RgbColor kColorMixxxGreen(0x42D4F4);
-constexpr mixxx::RgbColor kColorMixxxCeleste(0xF8D200);
-constexpr mixxx::RgbColor kColorMixxxBlue(0x0044FF);
-constexpr mixxx::RgbColor kColorMixxxPurple(0xAF00CC);
-constexpr mixxx::RgbColor kColorMixxxPink(0xFCA6D7);
-constexpr mixxx::RgbColor kColorMixxxWhite(0xF2F2FF);
-
-// Replaces "no color" values and is used for new cues if auto_hotcue_colors is
-// disabled
-constexpr mixxx::RgbColor kSchemaMigrationReplacementColor(0xFF8C00);
-
-} // anonymous namespace
-
-const ColorPalette ColorPalette::mixxxHotcuePalette =
- ColorPalette(
- QStringLiteral("Mixxx Hotcue Colors"),
- QList{
- kColorMixxxRed,
- kColorMixxxYellow,
- kColorMixxxGreen,
- kColorMixxxCeleste,
- kColorMixxxBlue,
- kColorMixxxPurple,
- kColorMixxxPink,
- kColorMixxxWhite,
- });
-
-const mixxx::RgbColor ColorPalette::kDefaultCueColor = kSchemaMigrationReplacementColor;
-
mixxx::RgbColor ColorPalette::nextColor(mixxx::RgbColor color) const {
// Return first color if color not in palette ((-1 + 1) % size)
return at((indexOf(color) + 1) % size());
@@ -49,7 +16,14 @@ mixxx::RgbColor ColorPalette::previousColor(mixxx::RgbColor color) const {
return at(iIndex);
}
-mixxx::RgbColor ColorPalette::colorForHotcueIndex(unsigned int index) const {
- // For hotcue n, get nth color from palette
- return at(index % size());
+mixxx::RgbColor ColorPalette::colorForHotcueIndex(unsigned int hotcueIndex) const {
+ int colorIndex;
+ if (m_hotcueColorIndices.isEmpty()) {
+ // For hotcue n, get nth color from palette
+ colorIndex = hotcueIndex;
+ } else {
+ // For hotcue n, get nth color from palette
+ colorIndex = m_hotcueColorIndices.at(hotcueIndex % m_hotcueColorIndices.size());
+ }
+ return at(colorIndex % size());
}
diff --git a/src/util/color/colorpalette.h b/src/util/color/colorpalette.h
index 1f0165a8b39..1354df10af7 100644
--- a/src/util/color/colorpalette.h
+++ b/src/util/color/colorpalette.h
@@ -6,9 +6,10 @@
class ColorPalette final {
public:
- explicit ColorPalette(QString name, QList colorList)
+ explicit ColorPalette(QString name, QList colorList, QList hotcueColorIndices = {})
: m_name(name),
- m_colorList(colorList) {
+ m_colorList(colorList),
+ m_hotcueColorIndices(hotcueColorIndices) {
DEBUG_ASSERT(m_colorList.size() != 0);
}
@@ -44,16 +45,18 @@ class ColorPalette final {
m_name = name;
}
- static const ColorPalette mixxxHotcuePalette;
- static const mixxx::RgbColor kDefaultCueColor;
-
const QList& getColorList() const {
return m_colorList;
}
+ QList getHotcueIndices() const {
+ return m_hotcueColorIndices;
+ }
+
private:
QString m_name;
QList m_colorList;
+ QList m_hotcueColorIndices;
};
inline bool operator==(
diff --git a/src/util/color/predefinedcolorpalettes.cpp b/src/util/color/predefinedcolorpalettes.cpp
new file mode 100644
index 00000000000..db6deb0ed7b
--- /dev/null
+++ b/src/util/color/predefinedcolorpalettes.cpp
@@ -0,0 +1,265 @@
+#include "predefinedcolorpalettes.h"
+
+namespace {
+
+// Default Mixxx Hotcue Color Palette
+constexpr mixxx::RgbColor kColorMixxxRed(0xC50A08);
+constexpr mixxx::RgbColor kColorMixxxYellow(0x32BE44);
+constexpr mixxx::RgbColor kColorMixxxGreen(0x42D4F4);
+constexpr mixxx::RgbColor kColorMixxxCeleste(0xF8D200);
+constexpr mixxx::RgbColor kColorMixxxBlue(0x0044FF);
+constexpr mixxx::RgbColor kColorMixxxPurple(0xAF00CC);
+constexpr mixxx::RgbColor kColorMixxxPink(0xFCA6D7);
+constexpr mixxx::RgbColor kColorMixxxWhite(0xF2F2FF);
+
+// Rekordbox Track Color Palette
+constexpr mixxx::RgbColor kRekordboxTrackColorPink(0xF870F8);
+constexpr mixxx::RgbColor kRekordboxTrackColorRed(0xF870900);
+constexpr mixxx::RgbColor kRekordboxTrackColorOrange(0xF8A030);
+constexpr mixxx::RgbColor kRekordboxTrackColorYellow(0xF8E331);
+constexpr mixxx::RgbColor kRekordboxTrackColorGreen(0x1EE000);
+constexpr mixxx::RgbColor kRekordboxTrackColorAqua(0x16C0F8);
+constexpr mixxx::RgbColor kRekordboxTrackColorBlue(0x0150F8);
+constexpr mixxx::RgbColor kRekordboxTrackColorPurple(0x9808F8);
+
+// Traktor Track Color Palette
+constexpr mixxx::RgbColor kTraktorProTrackColorRed(0xFA4B35);
+constexpr mixxx::RgbColor kTraktorProTrackColorOrange(0xFF8402);
+constexpr mixxx::RgbColor kTraktorProTrackColorYellow(0xFFF700);
+constexpr mixxx::RgbColor kTraktorProTrackColorGreen(0x00F329);
+constexpr mixxx::RgbColor kTraktorProTrackColorBlue(0x0187FF);
+constexpr mixxx::RgbColor kTraktorProTrackColorViolet(0xA669FF);
+constexpr mixxx::RgbColor kTraktorProTrackColorMagenta(0xFE55EA);
+
+// Serato DJ Intro Hotcue Color Palette
+constexpr mixxx::RgbColor kSeratoDJIntroHotcueColorRed(0xCC0000);
+constexpr mixxx::RgbColor kSeratoDJIntroHotcueColorOrange(0xCC4400);
+constexpr mixxx::RgbColor kSeratoDJIntroHotcueColorBrown(0xCC8800);
+constexpr mixxx::RgbColor kSeratoDJIntroHotcueColorYellow(0xCCCC00);
+constexpr mixxx::RgbColor kSeratoDJIntroHotcueColorEmerald(0x88CC00);
+constexpr mixxx::RgbColor kSeratoDJIntroHotcueColorKelly(0x44CC00);
+constexpr mixxx::RgbColor kSeratoDJIntroHotcueColorGreen(0x00CC00);
+constexpr mixxx::RgbColor kSeratoDJIntroHotcueColorSea(0x00CC44);
+constexpr mixxx::RgbColor kSeratoDJIntroHotcueColorJade(0x00CC88);
+constexpr mixxx::RgbColor kSeratoDJIntroHotcueColorTurquoise(0x00CCCC);
+constexpr mixxx::RgbColor kSeratoDJIntroHotcueColorTeal(0x0088CC);
+constexpr mixxx::RgbColor kSeratoDJIntroHotcueColorBlue(0x0044CC);
+constexpr mixxx::RgbColor kSeratoDJIntroHotcueColorDarkBlue(0x0000CC);
+constexpr mixxx::RgbColor kSeratoDJIntroHotcueColorViolet(0x4400CC);
+constexpr mixxx::RgbColor kSeratoDJIntroHotcueColorPurple(0x8800CC);
+constexpr mixxx::RgbColor kSeratoDJIntroHotcueColorFuchsia(0xCC00CC);
+constexpr mixxx::RgbColor kSeratoDJIntroHotcueColorMagenta(0xCC0088);
+constexpr mixxx::RgbColor kSeratoDJIntroHotcueColorCarmine(0xCC0044);
+
+// Serato DJ Pro Hotcue Color Palette
+constexpr mixxx::RgbColor kSeratoDJProHotcueColorRed1(0xC02626);
+constexpr mixxx::RgbColor kSeratoDJProHotcueColorOrange1(0xDB4E27);
+constexpr mixxx::RgbColor kSeratoDJProHotcueColorOrange2(0xF8821A);
+constexpr mixxx::RgbColor kSeratoDJProHotcueColorYellow(0xFAC313);
+constexpr mixxx::RgbColor kSeratoDJProHotcueColorGreen1(0x4EB648);
+constexpr mixxx::RgbColor kSeratoDJProHotcueColorGreen2(0x006838);
+constexpr mixxx::RgbColor kSeratoDJProHotcueColorGreen3(0x1FAD26);
+constexpr mixxx::RgbColor kSeratoDJProHotcueColorGreen4(0x8DC63F);
+constexpr mixxx::RgbColor kSeratoDJProHotcueColorBlue1(0x2B3673);
+constexpr mixxx::RgbColor kSeratoDJProHotcueColorCyan(0x1DBEBD);
+constexpr mixxx::RgbColor kSeratoDJProHotcueColorBlue2(0x173BA2);
+constexpr mixxx::RgbColor kSeratoDJProHotcueColorDarkBlue1(0x173BA2);
+constexpr mixxx::RgbColor kSeratoDJProHotcueColorDarkBlue2(0x173BA2);
+constexpr mixxx::RgbColor kSeratoDJProHotcueColorViolet1(0x5C3F97);
+constexpr mixxx::RgbColor kSeratoDJProHotcueColorViolet2(0x6823B6);
+constexpr mixxx::RgbColor kSeratoDJProHotcueColorMagenta(0xCE359E);
+constexpr mixxx::RgbColor kSeratoDJProHotcueColorPurple(0xDC1D49);
+constexpr mixxx::RgbColor kSeratoDJProHotcueColorRed2(0xC71136);
+
+// Serato DJ Pro Track Color Palette (as shown in library column)
+constexpr mixxx::RgbColor kSeratoDJProTrackColorGrey1(0x333333);
+constexpr mixxx::RgbColor kSeratoDJProTrackColorGrey2(0x555555);
+constexpr mixxx::RgbColor kSeratoDJProTrackColorPink1(0x993399);
+constexpr mixxx::RgbColor kSeratoDJProTrackColorPink2(0x993377);
+constexpr mixxx::RgbColor kSeratoDJProTrackColorRed1(0x993355);
+constexpr mixxx::RgbColor kSeratoDJProTrackColorRed2(0x993333);
+constexpr mixxx::RgbColor kSeratoDJProTrackColorOrange(0x995533);
+constexpr mixxx::RgbColor kSeratoDJProTrackColorBrown1(0x997733);
+constexpr mixxx::RgbColor kSeratoDJProTrackColorBrown2(0x999933);
+constexpr mixxx::RgbColor kSeratoDJProTrackColorBrown3(0x779933);
+constexpr mixxx::RgbColor kSeratoDJProTrackColorGreen1(0x559933);
+constexpr mixxx::RgbColor kSeratoDJProTrackColorGreen2(0x339933);
+constexpr mixxx::RgbColor kSeratoDJProTrackColorGreen3(0x339955);
+constexpr mixxx::RgbColor kSeratoDJProTrackColorTurquoise1(0x339977);
+constexpr mixxx::RgbColor kSeratoDJProTrackColorTurquoise2(0x339999);
+constexpr mixxx::RgbColor kSeratoDJProTrackColorTurquoise3(0x337799);
+constexpr mixxx::RgbColor kSeratoDJProTrackColorBlue(0x335599);
+constexpr mixxx::RgbColor kSeratoDJProTrackColorPurple1(0x333399);
+constexpr mixxx::RgbColor kSeratoDJProTrackColorPurple2(0x553399);
+constexpr mixxx::RgbColor kSeratoDJProTrackColorPurple3(0x773399);
+
+// VirtualDJ Track Color Palette
+constexpr mixxx::RgbColor kVirtualDJTrackColorRed(0xFF0000);
+constexpr mixxx::RgbColor kVirtualDJTrackColorYellow(0xFFFF00);
+constexpr mixxx::RgbColor kVirtualDJTrackColorGreen(0x00FF00);
+constexpr mixxx::RgbColor kVirtualDJTrackColorCyan(0x00FFFF);
+constexpr mixxx::RgbColor kVirtualDJTrackColorBlue(0x0000FF);
+constexpr mixxx::RgbColor kVirtualDJTrackColorFuchsia(0xFF00FF);
+constexpr mixxx::RgbColor kVirtualDJTrackColorWhite(0xFFFFFF);
+
+// Replaces "no color" values and is used for new cues if auto_hotcue_colors is
+// disabled
+constexpr mixxx::RgbColor kSchemaMigrationReplacementColor(0xFF8000);
+
+} // anonymous namespace
+
+namespace mixxx {
+
+const ColorPalette PredefinedColorPalettes::kMixxxHotcueColorPalette =
+ ColorPalette(
+ QStringLiteral("Mixxx Hotcue Colors"),
+ QList{
+ kColorMixxxRed,
+ kColorMixxxYellow,
+ kColorMixxxGreen,
+ kColorMixxxCeleste,
+ kColorMixxxBlue,
+ kColorMixxxPurple,
+ kColorMixxxPink,
+ kColorMixxxWhite,
+ });
+
+const ColorPalette PredefinedColorPalettes::kSeratoDJIntroHotcueColorPalette =
+ ColorPalette(
+ QStringLiteral("Serato DJ Intro Hotcue Colors"),
+ QList{
+ kSeratoDJIntroHotcueColorRed,
+ kSeratoDJIntroHotcueColorOrange,
+ kSeratoDJIntroHotcueColorBrown,
+ kSeratoDJIntroHotcueColorYellow,
+ kSeratoDJIntroHotcueColorEmerald,
+ kSeratoDJIntroHotcueColorKelly,
+ kSeratoDJIntroHotcueColorGreen,
+ kSeratoDJIntroHotcueColorSea,
+ kSeratoDJIntroHotcueColorJade,
+ kSeratoDJIntroHotcueColorTurquoise,
+ kSeratoDJIntroHotcueColorTeal,
+ kSeratoDJIntroHotcueColorBlue,
+ kSeratoDJIntroHotcueColorDarkBlue,
+ kSeratoDJIntroHotcueColorViolet,
+ kSeratoDJIntroHotcueColorPurple,
+ kSeratoDJIntroHotcueColorFuchsia,
+ kSeratoDJIntroHotcueColorMagenta,
+ kSeratoDJIntroHotcueColorCarmine,
+ },
+ QList{0, 2, 12, 3, 6, 15, 9, 14});
+
+const ColorPalette PredefinedColorPalettes::kSeratoDJProHotcueColorPalette =
+ ColorPalette(
+ QStringLiteral("Serato DJ Pro Hotcue Colors"),
+ QList{
+ kSeratoDJProHotcueColorRed1,
+ kSeratoDJProHotcueColorOrange1,
+ kSeratoDJProHotcueColorOrange2,
+ kSeratoDJProHotcueColorYellow,
+ kSeratoDJProHotcueColorGreen1,
+ kSeratoDJProHotcueColorGreen2,
+ kSeratoDJProHotcueColorGreen3,
+ kSeratoDJProHotcueColorGreen4,
+ kSeratoDJProHotcueColorBlue1,
+ kSeratoDJProHotcueColorCyan,
+ kSeratoDJProHotcueColorBlue2,
+ kSeratoDJProHotcueColorDarkBlue1,
+ kSeratoDJProHotcueColorDarkBlue2,
+ kSeratoDJProHotcueColorViolet1,
+ kSeratoDJProHotcueColorViolet2,
+ kSeratoDJProHotcueColorMagenta,
+ kSeratoDJProHotcueColorPurple,
+ kSeratoDJProHotcueColorRed2,
+ },
+ QList{0, 2, 12, 3, 6, 15, 9, 14});
+
+const ColorPalette PredefinedColorPalettes::kRekordboxTrackColorPalette =
+ ColorPalette(
+ QStringLiteral("Rekordbox Track Colors"),
+ QList{
+ kRekordboxTrackColorPink,
+ kRekordboxTrackColorRed,
+ kRekordboxTrackColorOrange,
+ kRekordboxTrackColorYellow,
+ kRekordboxTrackColorGreen,
+ kRekordboxTrackColorAqua,
+ kRekordboxTrackColorBlue,
+ kRekordboxTrackColorPurple,
+ });
+
+const ColorPalette PredefinedColorPalettes::kSeratoDJProTrackColorPalette =
+ ColorPalette(
+ QStringLiteral("Serato DJ Pro Track Colors"),
+ QList{
+ kSeratoDJProTrackColorGrey1,
+ kSeratoDJProTrackColorGrey2,
+ kSeratoDJProTrackColorPink1,
+ kSeratoDJProTrackColorPink2,
+ kSeratoDJProTrackColorRed1,
+ kSeratoDJProTrackColorRed2,
+ kSeratoDJProTrackColorOrange,
+ kSeratoDJProTrackColorBrown1,
+ kSeratoDJProTrackColorBrown2,
+ kSeratoDJProTrackColorBrown3,
+ kSeratoDJProTrackColorGreen1,
+ kSeratoDJProTrackColorGreen2,
+ kSeratoDJProTrackColorGreen3,
+ kSeratoDJProTrackColorTurquoise1,
+ kSeratoDJProTrackColorTurquoise2,
+ kSeratoDJProTrackColorTurquoise3,
+ kSeratoDJProTrackColorBlue,
+ kSeratoDJProTrackColorPurple1,
+ kSeratoDJProTrackColorPurple2,
+ kSeratoDJProTrackColorPurple3,
+ });
+
+const ColorPalette PredefinedColorPalettes::kTraktorProTrackColorPalette =
+ ColorPalette(
+ QStringLiteral("Traktor Pro Track Colors"),
+ QList{
+ kTraktorProTrackColorRed,
+ kTraktorProTrackColorOrange,
+ kTraktorProTrackColorYellow,
+ kTraktorProTrackColorGreen,
+ kTraktorProTrackColorBlue,
+ kTraktorProTrackColorViolet,
+ kTraktorProTrackColorMagenta,
+ });
+
+const ColorPalette PredefinedColorPalettes::kVirtualDJTrackColorPalette =
+ ColorPalette(
+ QStringLiteral("VirtualDJ Track Colors"),
+ QList{
+ kVirtualDJTrackColorRed,
+ kVirtualDJTrackColorYellow,
+ kVirtualDJTrackColorGreen,
+ kVirtualDJTrackColorCyan,
+ kVirtualDJTrackColorBlue,
+ kVirtualDJTrackColorFuchsia,
+ kVirtualDJTrackColorWhite,
+ });
+
+const ColorPalette PredefinedColorPalettes::kDefaultHotcueColorPalette =
+ mixxx::PredefinedColorPalettes::kMixxxHotcueColorPalette;
+
+const ColorPalette PredefinedColorPalettes::kDefaultTrackColorPalette =
+ mixxx::PredefinedColorPalettes::kMixxxHotcueColorPalette;
+
+const QList PredefinedColorPalettes::kPalettes{
+ // Hotcue Color Palettes
+ mixxx::PredefinedColorPalettes::kMixxxHotcueColorPalette,
+ mixxx::PredefinedColorPalettes::kSeratoDJProHotcueColorPalette,
+ mixxx::PredefinedColorPalettes::kSeratoDJIntroHotcueColorPalette,
+
+ // Track Color Palettes
+ mixxx::PredefinedColorPalettes::kRekordboxTrackColorPalette,
+ mixxx::PredefinedColorPalettes::kSeratoDJProTrackColorPalette,
+ mixxx::PredefinedColorPalettes::kTraktorProTrackColorPalette,
+ mixxx::PredefinedColorPalettes::kVirtualDJTrackColorPalette,
+};
+
+const mixxx::RgbColor PredefinedColorPalettes::kDefaultCueColor =
+ kSchemaMigrationReplacementColor;
+
+} // namespace mixxx
diff --git a/src/util/color/predefinedcolorpalettes.h b/src/util/color/predefinedcolorpalettes.h
new file mode 100644
index 00000000000..a1f910fc3be
--- /dev/null
+++ b/src/util/color/predefinedcolorpalettes.h
@@ -0,0 +1,24 @@
+#pragma once
+#include "util/color/colorpalette.h"
+
+namespace mixxx {
+
+class PredefinedColorPalettes {
+ public:
+ static const ColorPalette kMixxxHotcueColorPalette;
+ static const ColorPalette kSeratoDJIntroHotcueColorPalette;
+ static const ColorPalette kSeratoDJProHotcueColorPalette;
+
+ static const ColorPalette kRekordboxTrackColorPalette;
+ static const ColorPalette kSeratoDJProTrackColorPalette;
+ static const ColorPalette kTraktorProTrackColorPalette;
+ static const ColorPalette kVirtualDJTrackColorPalette;
+
+ static const ColorPalette kDefaultHotcueColorPalette;
+ static const ColorPalette kDefaultTrackColorPalette;
+
+ static const QList kPalettes;
+ static const mixxx::RgbColor kDefaultCueColor;
+};
+
+} // namespace mixxx