From 75e6e2a32a3ff78f12388a50080fcbd0a455eaa1 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sun, 27 Oct 2019 10:31:11 +0100 Subject: [PATCH 001/158] Create HotcueColorPalette class --- build/depends.py | 1 + src/util/color/hotcuecolorpalette.cpp | 20 ++++++++++++++++++++ src/util/color/hotcuecolorpalette.h | 17 +++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 src/util/color/hotcuecolorpalette.cpp create mode 100644 src/util/color/hotcuecolorpalette.h diff --git a/build/depends.py b/build/depends.py index 812fdad8130..655a832b648 100644 --- a/build/depends.py +++ b/build/depends.py @@ -1277,6 +1277,7 @@ def sources(self, build): "src/util/cache.cpp", "src/util/console.cpp", "src/util/color/color.cpp", + "src/util/color/hotcuecolorpalette.cpp", "src/util/db/dbconnection.cpp", "src/util/db/dbconnectionpool.cpp", "src/util/db/dbconnectionpooler.cpp", diff --git a/src/util/color/hotcuecolorpalette.cpp b/src/util/color/hotcuecolorpalette.cpp new file mode 100644 index 00000000000..d0b003ef2d5 --- /dev/null +++ b/src/util/color/hotcuecolorpalette.cpp @@ -0,0 +1,20 @@ +// +// Created by Ferran Pujol Camins on 27/10/2019. +// + +#include "hotcuecolorpalette.h" + +HotcueColorPalette::HotcueColorPalette(QList colorList) + : m_colorList(colorList) { +} + +const HotcueColorPalette HotcueColorPalette::mixxxPalette = + HotcueColorPalette(QList{ + QColor("#c50a08"), + QColor("#32be44"), + QColor("#0044ff"), + QColor("#f8d200"), + QColor("#42d4f4"), + QColor("#af00cc"), + QColor("#fca6d7"), + QColor("#f2f2ff")}); \ No newline at end of file diff --git a/src/util/color/hotcuecolorpalette.h b/src/util/color/hotcuecolorpalette.h new file mode 100644 index 00000000000..2f4a4f579f3 --- /dev/null +++ b/src/util/color/hotcuecolorpalette.h @@ -0,0 +1,17 @@ +// +// Created by Ferran Pujol Camins on 27/10/2019. +// + +#pragma once + +#include +#include "QList" + +class HotcueColorPalette { + public: + HotcueColorPalette(QList); + + static const HotcueColorPalette mixxxPalette; + + QList m_colorList; +}; \ No newline at end of file From 393ac126790ae3fad493c4f2f7bd66b3f088b4fd Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sun, 27 Oct 2019 20:04:03 +0100 Subject: [PATCH 002/158] Add methods to store QColor in the config --- src/preferences/configobject.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/preferences/configobject.cpp b/src/preferences/configobject.cpp index 6eecb2bb991..1819186d9be 100644 --- a/src/preferences/configobject.cpp +++ b/src/preferences/configobject.cpp @@ -270,6 +270,13 @@ void ConfigObject::setValue( set(key, ConfigValue(QString::number(value))); } +template<> +template<> +void ConfigObject::setValue( + const ConfigKey& key, const QColor& value) { + set(key, ConfigValue(value.name(QColor::NameFormat::HexArgb))); +} + template <> template <> bool ConfigObject::getValue( const ConfigKey& key, const bool& default_value) const { @@ -306,6 +313,24 @@ double ConfigObject::getValue( return ok ? result : default_value; } +template<> +template<> +QColor ConfigObject::getValue( + const ConfigKey& key, const QColor& default_value) const { + const ConfigValue value = get(key); + if (value.isNull()) { + return default_value; + } + auto color = QColor(value.value); + return color.isValid() ? color : default_value; +} + +template<> +template<> +QColor ConfigObject::getValue(const ConfigKey& key) const { + return getValue(key, QColor()); +} + // For string literal default template <> QString ConfigObject::getValue( From 42a22b0a8480b04946b69b54b19fe056edb3799a Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sun, 27 Oct 2019 20:04:40 +0100 Subject: [PATCH 003/158] Add class to store HotcueColorPalette in userconfig --- build/depends.py | 1 + src/preferences/configobject.cpp | 12 +++++++ src/preferences/configobject.h | 2 ++ .../hotcuecolorpalettesettings.cpp | 36 +++++++++++++++++++ src/preferences/hotcuecolorpalettesettings.h | 26 ++++++++++++++ 5 files changed, 77 insertions(+) create mode 100644 src/preferences/hotcuecolorpalettesettings.cpp create mode 100644 src/preferences/hotcuecolorpalettesettings.h diff --git a/build/depends.py b/build/depends.py index 655a832b648..221aff9237f 100644 --- a/build/depends.py +++ b/build/depends.py @@ -790,6 +790,7 @@ def sources(self, build): "src/preferences/effectsettingsmodel.cpp", "src/preferences/broadcastprofile.cpp", "src/preferences/upgrade.cpp", + "src/preferences/hotcuecolorpalettesettings.cpp", "src/preferences/dlgpreferencepage.cpp", "src/effects/effectmanifest.cpp", diff --git a/src/preferences/configobject.cpp b/src/preferences/configobject.cpp index 1819186d9be..22900ac4e48 100644 --- a/src/preferences/configobject.cpp +++ b/src/preferences/configobject.cpp @@ -215,6 +215,18 @@ template void ConfigObject::save() { } } +template +QList ConfigObject::getKeysWithGroup(QString group) { + QWriteLocker lock(&m_valuesLock); + QList filteredList; + for (const ConfigKey& key : m_values.uniqueKeys()) { + if (key.group == group) { + filteredList.append(key); + } + } + return filteredList; +} + template ConfigObject::ConfigObject(const QDomNode& node) { if (!node.isNull() && node.isElement()) { QDomNode ctrl = node.firstChild(); diff --git a/src/preferences/configobject.h b/src/preferences/configobject.h index 3e4ba6aa20e..3791de6ecd7 100644 --- a/src/preferences/configobject.h +++ b/src/preferences/configobject.h @@ -187,6 +187,8 @@ template class ConfigObject { return m_settingsPath; } + QList getKeysWithGroup(QString group); + protected: // We use QMap because we want a sorted list in mixxx.cfg QMap m_values; diff --git a/src/preferences/hotcuecolorpalettesettings.cpp b/src/preferences/hotcuecolorpalettesettings.cpp new file mode 100644 index 00000000000..b6a745606c0 --- /dev/null +++ b/src/preferences/hotcuecolorpalettesettings.cpp @@ -0,0 +1,36 @@ +#include "preferences/hotcuecolorpalettesettings.h" + +const QString HotcueColorPaletteSettings::sGroup = "[HotcueColorPalette]"; + +HotcueColorPalette HotcueColorPaletteSettings::getHotcueColorPalette() const { + QList colorList; + for (const ConfigKey& key : m_pConfig->getKeysWithGroup(sGroup)) { + QColor color = m_pConfig->getValue(key); + if (color.isValid()) { + colorList.append(color); + } + } + + // If no palette is defined in the settings, we use the default one. + if (colorList.isEmpty()) { + return HotcueColorPalette::mixxxPalette; + } + + return colorList; +} + +void HotcueColorPaletteSettings::setHotcueColorPalette( + const HotcueColorPalette& colorPalette) { + removePalette(); + + for (int index = 0; index < colorPalette.m_colorList.count(); ++index) { + QColor color = colorPalette.m_colorList[index]; + m_pConfig->setValue(keyForIndex(index), color); + } +} + +void HotcueColorPaletteSettings::removePalette() { + for (const ConfigKey& key : m_pConfig->getKeysWithGroup(sGroup)) { + m_pConfig->remove(key); + } +} \ No newline at end of file diff --git a/src/preferences/hotcuecolorpalettesettings.h b/src/preferences/hotcuecolorpalettesettings.h new file mode 100644 index 00000000000..ad28c5ec807 --- /dev/null +++ b/src/preferences/hotcuecolorpalettesettings.h @@ -0,0 +1,26 @@ +#pragma once + +#include "preferences/usersettings.h" +#include "util/color/hotcuecolorpalette.h" + +class HotcueColorPaletteSettings { + public: + HotcueColorPaletteSettings(UserSettingsPointer pConfig) + : m_pConfig(pConfig) { + } + + HotcueColorPalette getHotcueColorPalette() const; + + void setHotcueColorPalette(const HotcueColorPalette& colorPalette); + + private: + static const QString sGroup; + + void removePalette(); + + ConfigKey keyForIndex(int index) { + return ConfigKey(sGroup, QString::number(index)); + } + + UserSettingsPointer m_pConfig; +}; From 86bda126f3d19fa24936a0ce694357895c40afe2 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Fri, 1 Nov 2019 12:04:54 +0100 Subject: [PATCH 004/158] Add tests for color config methods --- CMakeLists.txt | 1 + src/test/colorconfig_test.cpp | 79 +++++++++++++++++++++++++++++ src/util/color/hotcuecolorpalette.h | 7 ++- 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 src/test/colorconfig_test.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 99c51f3ebdf..fe138a654ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -921,6 +921,7 @@ add_executable(mixxx-test src/test/broadcastsettings_test.cpp src/test/cache_test.cpp src/test/channelhandle_test.cpp + src/test/colorconfig_test.cpp src/test/compatibility_test.cpp src/test/configobject_test.cpp src/test/controller_preset_validation_test.cpp diff --git a/src/test/colorconfig_test.cpp b/src/test/colorconfig_test.cpp new file mode 100644 index 00000000000..fc95fec6573 --- /dev/null +++ b/src/test/colorconfig_test.cpp @@ -0,0 +1,79 @@ +#include +#include + +#include "test/mixxxtest.h" + +#include +#include + +class ColorConfigTest : public MixxxTest {}; + +TEST_F(ColorConfigTest, TestSavingColorWithoutAlpha) { + ConfigKey key("[Color]", "color"); + QColor originalColor("#FF9900"); + config()->setValue(key, originalColor); + saveAndReloadConfig(); + QColor colorFromConfig = config()->getValue(key); + ASSERT_EQ(originalColor, colorFromConfig); +} + +TEST_F(ColorConfigTest, TestSavingColorWithAlpha) { + ConfigKey key("[Color]", "color"); + QColor originalColor("#66FF9900"); + config()->setValue(key, originalColor); + saveAndReloadConfig(); + QColor colorFromConfig = config()->getValue(key); + ASSERT_EQ(originalColor, colorFromConfig); +} + +TEST_F(ColorConfigTest, TestDefaultColorWhenNoStoredColor) { + ConfigKey key("[Color]", "color"); + QColor defaultColor("#66FF9900"); + QColor colorFromConfig = config()->getValue(key, defaultColor); + ASSERT_EQ(defaultColor, colorFromConfig); +} + +TEST_F(ColorConfigTest, TestSaveColorPalette) { + HotcueColorPaletteSettings colorPaletteSettings(config()); + HotcueColorPalette originalColorPalette(QList{ + QColor("#66FF9900"), + QColor("#FF9900"), + QColor("#00000000"), + QColor("#FFFFFF"), + }); + ConfigKey key("[ColorPalette]", "colorPalette"); + colorPaletteSettings.setHotcueColorPalette(originalColorPalette); + saveAndReloadConfig(); + HotcueColorPalette colorPaletteFromConfig = + colorPaletteSettings.getHotcueColorPalette(); + ASSERT_EQ(originalColorPalette, colorPaletteFromConfig); +} + +TEST_F(ColorConfigTest, TestReplaceColorPalette) { + HotcueColorPaletteSettings colorPaletteSettings(config()); + HotcueColorPalette colorPalette1(QList{ + QColor("#66FF9900"), + QColor("#FF9900"), + QColor("#00000000"), + QColor("#FFFFFF"), + }); + HotcueColorPalette colorPalette2(QList{ + QColor("#0000FF"), + QColor("#FF0000"), + }); + ConfigKey key("[ColorPalette]", "colorPalette"); + colorPaletteSettings.setHotcueColorPalette(colorPalette1); + saveAndReloadConfig(); + colorPaletteSettings.setHotcueColorPalette(colorPalette2); + saveAndReloadConfig(); + HotcueColorPalette colorPaletteFromConfig = + colorPaletteSettings.getHotcueColorPalette(); + ASSERT_EQ(colorPalette2, colorPaletteFromConfig); +} + +TEST_F(ColorConfigTest, TestDefaultColorPalette) { + HotcueColorPaletteSettings colorPaletteSettings(config()); + HotcueColorPalette colorPaletteFromConfig = + colorPaletteSettings.getHotcueColorPalette(); + ASSERT_EQ(HotcueColorPalette::mixxxPalette, colorPaletteFromConfig); +} \ No newline at end of file diff --git a/src/util/color/hotcuecolorpalette.h b/src/util/color/hotcuecolorpalette.h index 2f4a4f579f3..a544599f3e0 100644 --- a/src/util/color/hotcuecolorpalette.h +++ b/src/util/color/hotcuecolorpalette.h @@ -14,4 +14,9 @@ class HotcueColorPalette { static const HotcueColorPalette mixxxPalette; QList m_colorList; -}; \ No newline at end of file +}; + +inline bool operator==( + const HotcueColorPalette& lhs, const HotcueColorPalette& rhs) { + return lhs.m_colorList == rhs.m_colorList; +} From 48b2b02f6634c1f5d26bc21ee3065f8bc162d059 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sat, 2 Nov 2019 18:57:42 +0100 Subject: [PATCH 005/158] Make Cue related code use QColor instead of PredefinedColorPointer COs and the database now hold the color hex int representation instead of a color id. --- CMakeLists.txt | 4 +- src/engine/controls/cuecontrol.cpp | 69 +++---- src/engine/controls/cuecontrol.h | 9 +- src/library/dao/cuedao.cpp | 18 +- src/library/dlgtrackinfo.cpp | 54 +++--- src/library/dlgtrackinfo.h | 3 +- src/track/cue.cpp | 16 +- src/track/cue.h | 17 +- src/util/color/hotcuecolorpalette.cpp | 6 +- src/util/color/hotcuecolorpalette.h | 26 ++- src/waveform/renderers/waveformrendermark.cpp | 2 +- src/widget/wcolorpicker.cpp | 170 +++++++++++------- src/widget/wcolorpicker.h | 18 +- src/widget/wcolorpickeraction.cpp | 8 +- src/widget/wcolorpickeraction.h | 5 +- src/widget/wcuemenupopup.cpp | 10 +- src/widget/wcuemenupopup.h | 6 +- src/widget/woverview.cpp | 11 +- src/widget/wtracktableview.cpp | 28 +-- src/widget/wtracktableview.h | 2 +- 20 files changed, 288 insertions(+), 194 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fe138a654ed..24996722a4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -313,7 +313,6 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL src/errordialoghandler.cpp src/library/analysisfeature.cpp src/library/analysislibrarytablemodel.cpp - src/library/trackloader.cpp src/library/autodj/autodjfeature.cpp src/library/autodj/autodjprocessor.cpp src/library/autodj/dlgautodj.cpp @@ -410,6 +409,7 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL src/library/tableitemdelegate.cpp src/library/trackcollection.cpp src/library/trackcollectionmanager.cpp + src/library/trackloader.cpp src/library/traktor/traktorfeature.cpp src/library/treeitem.cpp src/library/treeitemmodel.cpp @@ -473,6 +473,7 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL src/preferences/dialog/dlgprefwaveformdlg.ui src/preferences/dlgpreferencepage.cpp src/preferences/effectsettingsmodel.cpp + src/preferences/hotcuecolorpalettesettings.cpp src/preferences/replaygainsettings.cpp src/preferences/settingsmanager.cpp src/preferences/upgrade.cpp @@ -533,6 +534,7 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL src/util/cache.cpp src/util/cmdlineargs.cpp src/util/color/color.cpp + src/util/color/hotcuecolorpalette.cpp src/util/color/predefinedcolor.cpp src/util/console.cpp src/util/db/dbconnection.cpp diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index 8205ab61e01..830c4f52b84 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -6,12 +6,13 @@ #include "engine/enginebuffer.h" #include "engine/controls/cuecontrol.h" +#include "control/controlindicator.h" #include "control/controlobject.h" #include "control/controlpushbutton.h" -#include "control/controlindicator.h" -#include "vinylcontrol/defs_vinylcontrol.h" -#include "util/sample.h" +#include "preferences/hotcuecolorpalettesettings.h" #include "util/color/color.h" +#include "util/sample.h" +#include "vinylcontrol/defs_vinylcontrol.h" // TODO: Convert these doubles to a standard enum // and convert elseif logic to switch statements @@ -25,6 +26,7 @@ static const double CUE_MODE_CUP = 5.0; CueControl::CueControl(QString group, UserSettingsPointer pConfig) : EngineControl(group, pConfig), + m_pConfig(pConfig), m_bPreviewing(false), // m_pPlay->toBoo() -> engine play state // m_pPlay->set(1.0) -> emulate play button press @@ -597,9 +599,12 @@ void CueControl::hotcueSet(HotcueControl* pControl, double v) { // TODO(XXX) deal with spurious signals attachCue(pCue, pControl); - if (getConfig()->getValue(ConfigKey("[Controls]", "auto_hotcue_colors"), false)) { - const QList predefinedColors = Color::kPredefinedColorsSet.allColors; - pCue->setColor(predefinedColors.at((hotcue % (predefinedColors.count() - 1)) + 1)); + ConfigKey autoHotcueColorsKey("[Controls]", "auto_hotcue_colors"); + if (getConfig()->getValue(autoHotcueColorsKey, false)) { + HotcueColorPaletteSettings colorPaletteSettings(getConfig()); + auto hotcueColorPalette = colorPaletteSettings.getHotcueColorPalette(); + auto colors = hotcueColorPalette.m_colorList; + pCue->setColor(colors.at((hotcue % (colors.count() - 1)) + 1)); }; // If quantize is enabled and we are not playing, jump to the cue point @@ -1684,20 +1689,20 @@ void CueControl::hotcueFocusColorPrev(double v) { return; } - PredefinedColorPointer pColor = pControl->getColor(); - if (!pColor) { - return; - } + QColor color = pControl->getColor(); + DEBUG_ASSERT(color.isValid()); + + HotcueColorPaletteSettings colorPaletteSettings(m_pConfig); + HotcueColorPalette colorPalette = colorPaletteSettings.getHotcueColorPalette(); // Get previous color in color set - int iColorIndex = Color::kPredefinedColorsSet.predefinedColorIndex(pColor) - 1; + int iColorIndex = colorPalette.indexOf(color) - 1; if (iColorIndex <= 0) { - iColorIndex = Color::kPredefinedColorsSet.allColors.size() - 1; + iColorIndex = colorPalette.size() - 1; } - pColor = Color::kPredefinedColorsSet.allColors.at(iColorIndex); - DEBUG_ASSERT(pColor != nullptr); + color = colorPalette.at(iColorIndex); - pControl->setColor(pColor); + pControl->setColor(color); } void CueControl::hotcueFocusColorNext(double v) { @@ -1715,20 +1720,20 @@ void CueControl::hotcueFocusColorNext(double v) { return; } - PredefinedColorPointer pColor = pControl->getColor(); - if (!pColor) { - return; - } + QColor color = pControl->getColor(); + DEBUG_ASSERT(color.isValid()); + + HotcueColorPaletteSettings colorPaletteSettings(m_pConfig); + HotcueColorPalette colorPalette = colorPaletteSettings.getHotcueColorPalette(); - // Get next color in color set - int iColorIndex = Color::kPredefinedColorsSet.predefinedColorIndex(pColor) + 1; - if (iColorIndex >= Color::kPredefinedColorsSet.allColors.size()) { + // Get previous color in color set + int iColorIndex = colorPalette.indexOf(color) + 1; + if (iColorIndex >= colorPalette.size()) { iColorIndex = 0; } - pColor = Color::kPredefinedColorsSet.allColors.at(iColorIndex); - DEBUG_ASSERT(pColor != nullptr); + color = colorPalette.at(iColorIndex); - pControl->setColor(pColor); + pControl->setColor(color); } @@ -1845,9 +1850,9 @@ void HotcueControl::slotHotcuePositionChanged(double newPosition) { emit hotcuePositionChanged(this, newPosition); } -void HotcueControl::slotHotcueColorChanged(double newColorId) { - m_pCue->setColor(Color::kPredefinedColorsSet.predefinedColorFromId(newColorId)); - emit hotcueColorChanged(this, newColorId); +void HotcueControl::slotHotcueColorChanged(double newColor) { + m_pCue->setColor(QColor::fromRgba(newColor)); + emit(hotcueColorChanged(this, newColor)); } double HotcueControl::getPosition() const { @@ -1861,12 +1866,12 @@ void HotcueControl::setCue(CuePointer pCue) { // because we have a null check for valid data else where in the code m_pCue = pCue; } -PredefinedColorPointer HotcueControl::getColor() const { - return Color::kPredefinedColorsSet.predefinedColorFromId(m_hotcueColor->get()); +QColor HotcueControl::getColor() const { + return QColor::fromRgba(m_hotcueColor->get()); } -void HotcueControl::setColor(PredefinedColorPointer newColor) { - m_hotcueColor->set(static_cast(newColor->m_iId)); +void HotcueControl::setColor(const QColor& newColor) { + m_hotcueColor->set(newColor.rgba()); } void HotcueControl::resetCue() { // clear pCue first because we have a null check for valid data else where diff --git a/src/engine/controls/cuecontrol.h b/src/engine/controls/cuecontrol.h index be65fd1a333..e90b344f1e1 100644 --- a/src/engine/controls/cuecontrol.h +++ b/src/engine/controls/cuecontrol.h @@ -50,8 +50,8 @@ class HotcueControl : public QObject { void setCue(CuePointer pCue); void resetCue(); void setPosition(double position); - void setColor(PredefinedColorPointer newColor); - PredefinedColorPointer getColor() const; + void setColor(const QColor& newColor); + QColor getColor() const; // Used for caching the preview state of this hotcue control. inline bool isPreviewing() { @@ -76,7 +76,7 @@ class HotcueControl : public QObject { void slotHotcueActivatePreview(double v); void slotHotcueClear(double v); void slotHotcuePositionChanged(double newPosition); - void slotHotcueColorChanged(double newColorId); + void slotHotcueColorChanged(double newColor); signals: void hotcueSet(HotcueControl* pHotcue, double v); @@ -87,7 +87,7 @@ class HotcueControl : public QObject { void hotcueActivatePreview(HotcueControl* pHotcue, double v); void hotcueClear(HotcueControl* pHotcue, double v); void hotcuePositionChanged(HotcueControl* pHotcue, double newPosition); - void hotcueColorChanged(HotcueControl* pHotcue, double newColorId); + void hotcueColorChanged(HotcueControl* pHotcue, double newColor); void hotcuePlay(double v); private: @@ -193,6 +193,7 @@ class CueControl : public EngineControl { double getQuantizedCurrentPosition(); TrackAt getTrackAt() const; + UserSettingsPointer m_pConfig; bool m_bPreviewing; ControlObject* m_pPlay; ControlObject* m_pStopButton; diff --git a/src/library/dao/cuedao.cpp b/src/library/dao/cuedao.cpp index 5d81c215615..3b8afb9cbe9 100644 --- a/src/library/dao/cuedao.cpp +++ b/src/library/dao/cuedao.cpp @@ -11,7 +11,6 @@ #include "library/queryutil.h" #include "util/assert.h" #include "util/performancetimer.h" -#include "util/color/color.h" #include "util/color/predefinedcolor.h" int CueDAO::cueCount() { @@ -53,9 +52,16 @@ CuePointer CueDAO::cueFromRow(const QSqlQuery& query) const { int length = record.value(record.indexOf("length")).toInt(); int hotcue = record.value(record.indexOf("hotcue")).toInt(); QString label = record.value(record.indexOf("label")).toString(); - int iColorId = record.value(record.indexOf("color")).toInt(); - PredefinedColorPointer color = Color::kPredefinedColorsSet.predefinedColorFromId(iColorId); - CuePointer pCue(new Cue(id, trackId, (Cue::Type)type, position, length, hotcue, label, color)); + uint colorValue = record.value(record.indexOf("color")).toUInt(); + QColor color = QColor::fromRgba(colorValue); + CuePointer pCue(new Cue(id, + trackId, + (Cue::Type)type, + position, + length, + hotcue, + label, + color)); m_cues[id] = pCue; return pCue; } @@ -147,7 +153,7 @@ bool CueDAO::saveCue(Cue* cue) { query.bindValue(":length", cue->getLength()); query.bindValue(":hotcue", cue->getHotCue()); query.bindValue(":label", cue->getLabel()); - query.bindValue(":color", cue->getColor()->m_iId); + query.bindValue(":color", cue->getColor().rgba()); if (query.exec()) { int id = query.lastInsertId().toInt(); @@ -175,7 +181,7 @@ bool CueDAO::saveCue(Cue* cue) { query.bindValue(":length", cue->getLength()); query.bindValue(":hotcue", cue->getHotCue()); query.bindValue(":label", cue->getLabel()); - query.bindValue(":color", cue->getColor()->m_iId); + query.bindValue(":color", cue->getColor().rgba()); if (query.exec()) { cue->setDirty(false); diff --git a/src/library/dlgtrackinfo.cpp b/src/library/dlgtrackinfo.cpp index 64ae4c8b297..1df502769fa 100644 --- a/src/library/dlgtrackinfo.cpp +++ b/src/library/dlgtrackinfo.cpp @@ -1,16 +1,19 @@ +#include #include -#include +#include #include +#include #include "library/coverartcache.h" #include "library/coverartutils.h" #include "library/dlgtrackinfo.h" +#include "preferences/hotcuecolorpalettesettings.h" #include "sources/soundsourceproxy.h" #include "track/beatfactory.h" #include "track/cue.h" #include "track/keyfactory.h" #include "track/keyutils.h" -#include "util/color/color.h" +#include "util/color/hotcuecolorpalette.h" #include "util/compatibility.h" #include "util/desktophelper.h" #include "util/duration.h" @@ -21,11 +24,12 @@ const int kMinBpm = 30; // Maximum allowed interval between beats (calculated from kMinBpm). const mixxx::Duration kMaxInterval = mixxx::Duration::fromMillis(1000.0 * (60.0 / kMinBpm)); -DlgTrackInfo::DlgTrackInfo(QWidget* parent) - : QDialog(parent), - m_pTapFilter(new TapFilter(this, kFilterLength, kMaxInterval)), - m_dLastTapedBpm(-1.), - m_pWCoverArtLabel(new WCoverArtLabel(this)) { +DlgTrackInfo::DlgTrackInfo(UserSettingsPointer pConfig, QWidget* parent) + : QDialog(parent), + m_pTapFilter(new TapFilter(this, kFilterLength, kMaxInterval)), + m_dLastTapedBpm(-1.), + m_pWCoverArtLabel(new WCoverArtLabel(this)), + m_pConfig(pConfig) { init(); } @@ -408,21 +412,22 @@ void DlgTrackInfo::populateCues(TrackPointer pTrack) { // Make the type read only typeItem->setFlags(Qt::NoItemFlags); + HotcueColorPaletteSettings colorPaletteSettings(m_pConfig); + auto colorPalette = colorPaletteSettings.getHotcueColorPalette(); + QList hotcueColorList = + colorPaletteSettings.getHotcueColorPalette().m_colorList; QComboBox* colorComboBox = new QComboBox(); - const QList predefinedColors = Color::kPredefinedColorsSet.allColors; - for (int i = 0; i < predefinedColors.count(); i++) { - PredefinedColorPointer color = predefinedColors.at(i); - QColor defaultRgba = color->m_defaultRgba; - colorComboBox->addItem(color->m_sDisplayName, defaultRgba); - if (*color != *Color::kPredefinedColorsSet.noColor) { - QPixmap pixmap(80, 80); - pixmap.fill(defaultRgba); - QIcon icon(pixmap); - colorComboBox->setItemIcon(i, icon); - } + for (int i = 0; i < hotcueColorList.count(); i++) { + QColor color = hotcueColorList.at(i); + colorComboBox->addItem("", color); + QPixmap pixmap(80, 80); + pixmap.fill(color); + QIcon icon(pixmap); + colorComboBox->setItemIcon(i, icon); } - PredefinedColorPointer cueColor = pCue->getColor(); - colorComboBox->setCurrentIndex(Color::kPredefinedColorsSet.predefinedColorIndex(cueColor)); + QColor cueColor = pCue->getColor(); + int colorIndex = hotcueColorList.indexOf(cueColor); + colorComboBox->setCurrentIndex(math_min(colorIndex, 0)); m_cueMap[row] = pCue; cueTable->insertRow(row); @@ -507,7 +512,14 @@ void DlgTrackInfo::saveTrack() { if (pCue->getType() == Cue::Type::HotCue) { auto colorComboBox = qobject_cast(colorWidget); if (colorComboBox) { - PredefinedColorPointer color = Color::kPredefinedColorsSet.allColors.at(colorComboBox->currentIndex()); + HotcueColorPaletteSettings colorPaletteSettings(m_pConfig); + auto colorPalette = + colorPaletteSettings.getHotcueColorPalette(); + QList hotcueColorList = + colorPaletteSettings.getHotcueColorPalette() + .m_colorList; + QColor color = + hotcueColorList.at(colorComboBox->currentIndex()); pCue->setColor(color); } } diff --git a/src/library/dlgtrackinfo.h b/src/library/dlgtrackinfo.h index 677483ead30..341de08ad08 100644 --- a/src/library/dlgtrackinfo.h +++ b/src/library/dlgtrackinfo.h @@ -18,7 +18,7 @@ class DlgTrackInfo : public QDialog, public Ui::DlgTrackInfo { Q_OBJECT public: - DlgTrackInfo(QWidget* parent); + DlgTrackInfo(UserSettingsPointer pConfig, QWidget* parent); virtual ~DlgTrackInfo(); public slots: @@ -85,6 +85,7 @@ class DlgTrackInfo : public QDialog, public Ui::DlgTrackInfo { CoverInfo m_loadedCoverInfo; WCoverArtLabel* m_pWCoverArtLabel; + UserSettingsPointer m_pConfig; }; #endif /* DLGTRACKINFO_H */ diff --git a/src/track/cue.cpp b/src/track/cue.cpp index d0951a86d91..99ec0f74271 100644 --- a/src/track/cue.cpp +++ b/src/track/cue.cpp @@ -28,12 +28,18 @@ Cue::Cue(TrackId trackId) m_sampleEndPosition(Cue::kNoPosition), m_iHotCue(-1), m_label(kDefaultLabel), - m_color(Color::kPredefinedColorsSet.noColor) { + m_color(QColor()) { DEBUG_ASSERT(!m_label.isNull()); } -Cue::Cue(int id, TrackId trackId, Cue::Type type, double position, double length, - int hotCue, QString label, PredefinedColorPointer color) +Cue::Cue(int id, + TrackId trackId, + Cue::Type type, + double position, + double length, + int hotCue, + QString label, + QColor color) : m_bDirty(false), m_iId(id), m_trackId(trackId), @@ -153,12 +159,12 @@ void Cue::setLabel(const QString label) { emit updated(); } -PredefinedColorPointer Cue::getColor() const { +QColor Cue::getColor() const { QMutexLocker lock(&m_mutex); return m_color; } -void Cue::setColor(const PredefinedColorPointer color) { +void Cue::setColor(const QColor& color) { QMutexLocker lock(&m_mutex); m_color = color; m_bDirty = true; diff --git a/src/track/cue.h b/src/track/cue.h index ffc1c814690..9b6d133766a 100644 --- a/src/track/cue.h +++ b/src/track/cue.h @@ -6,7 +6,6 @@ #include #include "track/trackid.h" -#include "util/color/predefinedcolor.h" #include "util/memory.h" class CuePosition; @@ -54,8 +53,8 @@ class Cue : public QObject { QString getLabel() const; void setLabel(QString label); - PredefinedColorPointer getColor() const; - void setColor(PredefinedColorPointer color); + QColor getColor() const; + void setColor(const QColor& color); double getEndPosition() const; @@ -64,8 +63,14 @@ class Cue : public QObject { private: explicit Cue(TrackId trackId); - Cue(int id, TrackId trackId, Cue::Type type, double position, double length, - int hotCue, QString label, PredefinedColorPointer color); + Cue(int id, + TrackId trackId, + Cue::Type type, + double position, + double length, + int hotCue, + QString label, + QColor color); void setDirty(bool dirty); void setId(int id); void setTrackId(TrackId trackId); @@ -80,7 +85,7 @@ class Cue : public QObject { double m_sampleEndPosition; int m_iHotCue; QString m_label; - PredefinedColorPointer m_color; + QColor m_color; friend class Track; friend class CueDAO; diff --git a/src/util/color/hotcuecolorpalette.cpp b/src/util/color/hotcuecolorpalette.cpp index d0b003ef2d5..ab51fde7a0d 100644 --- a/src/util/color/hotcuecolorpalette.cpp +++ b/src/util/color/hotcuecolorpalette.cpp @@ -4,10 +4,6 @@ #include "hotcuecolorpalette.h" -HotcueColorPalette::HotcueColorPalette(QList colorList) - : m_colorList(colorList) { -} - const HotcueColorPalette HotcueColorPalette::mixxxPalette = HotcueColorPalette(QList{ QColor("#c50a08"), @@ -17,4 +13,4 @@ const HotcueColorPalette HotcueColorPalette::mixxxPalette = QColor("#42d4f4"), QColor("#af00cc"), QColor("#fca6d7"), - QColor("#f2f2ff")}); \ No newline at end of file + QColor("#f2f2ff")}); diff --git a/src/util/color/hotcuecolorpalette.h b/src/util/color/hotcuecolorpalette.h index a544599f3e0..de9f2c33af6 100644 --- a/src/util/color/hotcuecolorpalette.h +++ b/src/util/color/hotcuecolorpalette.h @@ -5,11 +5,33 @@ #pragma once #include -#include "QList" +#include class HotcueColorPalette { public: - HotcueColorPalette(QList); + HotcueColorPalette(QList colorList) + : m_colorList(colorList) { + } + + QColor at(int i) const { + return m_colorList.at(i); + } + + int size() const { + return m_colorList.size(); + } + + int indexOf(QColor color) const { + return m_colorList.indexOf(color); + } + + QList::const_iterator begin() const { + return m_colorList.begin(); + } + + QList::const_iterator end() const { + return m_colorList.end(); + } static const HotcueColorPalette mixxxPalette; diff --git a/src/waveform/renderers/waveformrendermark.cpp b/src/waveform/renderers/waveformrendermark.cpp index 1d338688e08..d22fa1b20ef 100644 --- a/src/waveform/renderers/waveformrendermark.cpp +++ b/src/waveform/renderers/waveformrendermark.cpp @@ -128,7 +128,7 @@ void WaveformRenderMark::slotCuesUpdated() { } QString newLabel = pCue->getLabel(); - QColor newColor = m_predefinedColorsRepresentation.representationFor(pCue->getColor()); + QColor newColor = pCue->getColor(); if (pMark->m_text.isNull() || newLabel != pMark->m_text || !pMark->fillColor().isValid() || newColor != pMark->fillColor()) { pMark->m_text = newLabel; diff --git a/src/widget/wcolorpicker.cpp b/src/widget/wcolorpicker.cpp index c6c94278698..10e2257f764 100644 --- a/src/widget/wcolorpicker.cpp +++ b/src/widget/wcolorpicker.cpp @@ -1,6 +1,5 @@ #include "widget/wcolorpicker.h" -#include #include #include #include @@ -13,7 +12,9 @@ namespace { } WColorPicker::WColorPicker(ColorOption colorOption, QWidget* parent) - : QWidget(parent) { + : QWidget(parent), + m_colorOption(colorOption), + m_palette(HotcueColorPalette::mixxxPalette) { QGridLayout* pLayout = new QGridLayout(); pLayout->setMargin(0); pLayout->setContentsMargins(0, 0, 0, 0); @@ -33,93 +34,130 @@ WColorPicker::WColorPicker(ColorOption colorOption, QWidget* parent) int row = 0; int column = 0; - for (const auto& pColor : Color::kPredefinedColorsSet.allColors) { - if (colorOption != ColorOption::AllowNoColor && - pColor == Color::kPredefinedColorsSet.noColor) { - continue; - } - - parented_ptr pColorButton = make_parented("", this); - if (m_pStyle) { - pColorButton->setStyle(m_pStyle); - } - - if (pColor->m_defaultRgba.isValid()) { - // Set the background color of the button. This can't be overridden in skin stylesheets. - pColorButton->setStyleSheet( - QString("QPushButton { background-color: #%1; }").arg(pColor->m_defaultRgba.rgb(), 6, 16, QChar('0')) - ); - } else { - pColorButton->setProperty("noColor", true); - } - pColorButton->setToolTip(pColor->m_sDisplayName); - pColorButton->setCheckable(true); - m_pColorButtons.insert(pColor, pColorButton); + if (m_colorOption == ColorOption::AllowNoColor) { + addColorButton(QColor(), pLayout, row, column); + column++; + } - pLayout->addWidget(pColorButton, row, column); + for (const auto& color : m_palette) { + addColorButton(color, pLayout, row, column); column++; if (column == kNumColumns) { column = 0; row++; } - - connect(this, - &WColorPicker::colorPicked, - this, - &WColorPicker::slotColorPicked); - connect(pColorButton, - &QPushButton::clicked, - this, - [pColor, this]() { - emit colorPicked(pColor); - }); } +} + +void WColorPicker::addColorButton(const QColor& color, QGridLayout* pLayout, int row, int column) { setLayout(pLayout); + parented_ptr pColorButton = make_parented("", this); + if (m_pStyle) { + pColorButton->setStyle(m_pStyle); + } + + if (color.isValid()) { + // Set the background color of the button. This can't be overridden in skin stylesheets. + pColorButton->setStyleSheet( + QString("QPushButton { background-color: %1; }").arg(color.name())); + } else { + pColorButton->setProperty("noColor", true); + } + + pColorButton->setCheckable(true); + m_colorButtons.append(pColorButton); + + pLayout->addWidget(pColorButton, row, column); + + connect(this, + &WColorPicker::colorPicked, + this, + &WColorPicker::slotColorPicked); + connect(pColorButton, + &QPushButton::clicked, + this, + [color, this]() { + emit colorPicked(color); + }); } -void WColorPicker::setSelectedColor(PredefinedColorPointer pColor) { - if (m_pSelectedColor) { - auto it = m_pColorButtons.constFind(m_pSelectedColor); - if (it != m_pColorButtons.constEnd()) { - it.value()->setChecked(false); - // This is needed to re-apply skin styles (e.g. to show/hide a checkmark icon) - it.value()->style()->unpolish(it.value()); - it.value()->style()->polish(it.value()); +void WColorPicker::resetSelectedColor() { + // Unset currently selected color + int i; + if (m_colorOption == ColorOption::AllowNoColor && !m_selectedColor.isValid()) { + i = 0; + } else { + i = m_palette.indexOf(m_selectedColor); + if (i == -1) { + return; } + if (m_colorOption == ColorOption::AllowNoColor) { + i++; + } + } + + DEBUG_ASSERT(i < m_colorButtons.size()); + + QPushButton* pButton = m_colorButtons.at(i); + VERIFY_OR_DEBUG_ASSERT(pButton != nullptr) { + return; } + pButton->setChecked(false); + // This is needed to re-apply skin styles (e.g. to show/hide a checkmark icon) + pButton->style()->unpolish(pButton); + pButton->style()->polish(pButton); +} + +void WColorPicker::setSelectedColor(const QColor& color) { + resetSelectedColor(); - if (pColor) { - auto it = m_pColorButtons.constFind(pColor); - if (it != m_pColorButtons.constEnd()) { - it.value()->setChecked(true); - // This is needed to re-apply skin styles (e.g. to show/hide a checkmark icon) - it.value()->style()->unpolish(it.value()); - it.value()->style()->polish(it.value()); + m_selectedColor = color; + + int i; + if (m_colorOption == ColorOption::AllowNoColor && !color.isValid()) { + i = 0; + } else { + i = m_palette.indexOf(color); + if (i == -1) { + return; + } + if (m_colorOption == ColorOption::AllowNoColor) { + i++; } } - m_pSelectedColor = pColor; + DEBUG_ASSERT(i < m_colorButtons.size()); + + QPushButton* pButton = m_colorButtons.at(i); + VERIFY_OR_DEBUG_ASSERT(pButton != nullptr) { + return; + } + pButton->setChecked(true); + // This is needed to re-apply skin styles (e.g. to show/hide a checkmark icon) + pButton->style()->unpolish(pButton); + pButton->style()->polish(pButton); } -void WColorPicker::useColorSet(PredefinedColorsRepresentation* pColorRepresentation) { - QMapIterator i(m_pColorButtons); - while (i.hasNext()) { - i.next(); - PredefinedColorPointer pColor = i.key(); - QPushButton* pColorButton = i.value(); - QColor color = (pColorRepresentation == nullptr) ? pColor->m_defaultRgba : pColorRepresentation->representationFor(pColor); +void WColorPicker::useColorSet(const HotcueColorPalette& palette) { + for (int i = 0; i < m_colorButtons.size(); ++i) { + int j = i; + if (m_colorOption == ColorOption::AllowNoColor) { + j++; + } - // Set the background color of the button. This can't be overridden in skin stylesheets. - pColorButton->setStyleSheet( - QString("QPushButton { background-color: #%1; }").arg(color.rgb(), 6, 16, QChar('0')) - ); + if (i >= palette.size() || j >= m_colorButtons.size()) { + return; + } - pColorButton->setToolTip(pColor->m_sDisplayName); + // Set the background color of the button. This can't be overridden in skin stylesheets. + m_colorButtons.at(j)->setStyleSheet( + QString("QPushButton { background-color: %1; }") + .arg(palette.at(i).name())); } } -void WColorPicker::slotColorPicked(PredefinedColorPointer pColor) { - setSelectedColor(pColor); +void WColorPicker::slotColorPicked(const QColor& color) { + setSelectedColor(color); } diff --git a/src/widget/wcolorpicker.h b/src/widget/wcolorpicker.h index e3e10e57096..0e7befac1b7 100644 --- a/src/widget/wcolorpicker.h +++ b/src/widget/wcolorpicker.h @@ -1,11 +1,13 @@ #pragma once +#include #include #include #include #include #include "util/color/color.h" +#include "util/color/hotcuecolorpalette.h" class WColorPicker : public QWidget { Q_OBJECT @@ -17,17 +19,21 @@ class WColorPicker : public QWidget { explicit WColorPicker(ColorOption colorOption, QWidget* parent = nullptr); - void setSelectedColor(PredefinedColorPointer pColor = nullptr); - void useColorSet(PredefinedColorsRepresentation* pColorRepresentation); + void resetSelectedColor(); + void setSelectedColor(const QColor& color); + void useColorSet(const HotcueColorPalette& palette); signals: - void colorPicked(PredefinedColorPointer pColor); + void colorPicked(QColor color); private slots: - void slotColorPicked(PredefinedColorPointer pColor); + void slotColorPicked(const QColor& color); private: - QMap m_pColorButtons; - PredefinedColorPointer m_pSelectedColor; + void addColorButton(const QColor& color, QGridLayout* pLayout, int row, int column); + ColorOption m_colorOption; + QColor m_selectedColor; + HotcueColorPalette m_palette; + QList m_colorButtons; QStyle* m_pStyle; }; diff --git a/src/widget/wcolorpickeraction.cpp b/src/widget/wcolorpickeraction.cpp index db72bc97e95..5270a75a4ba 100644 --- a/src/widget/wcolorpickeraction.cpp +++ b/src/widget/wcolorpickeraction.cpp @@ -13,6 +13,10 @@ WColorPickerAction::WColorPickerAction(WColorPicker::ColorOption colorOption, QW setDefaultWidget(pWidget); } -void WColorPickerAction::setSelectedColor(PredefinedColorPointer pColor) { - m_pColorPicker->setSelectedColor(pColor); +void WColorPickerAction::resetSelectedColor() { + m_pColorPicker->resetSelectedColor(); +} + +void WColorPickerAction::setSelectedColor(QColor color) { + m_pColorPicker->setSelectedColor(color); } diff --git a/src/widget/wcolorpickeraction.h b/src/widget/wcolorpickeraction.h index 48e1012772b..9c9ced435bd 100644 --- a/src/widget/wcolorpickeraction.h +++ b/src/widget/wcolorpickeraction.h @@ -14,10 +14,11 @@ class WColorPickerAction : public QWidgetAction { WColorPicker::ColorOption colorOption, QWidget* parent = nullptr); - void setSelectedColor(PredefinedColorPointer pColor = nullptr); + void resetSelectedColor(); + void setSelectedColor(QColor color = QColor()); signals: - void colorPicked(PredefinedColorPointer pColor); + void colorPicked(QColor color); private: parented_ptr m_pColorPicker; diff --git a/src/widget/wcuemenupopup.cpp b/src/widget/wcuemenupopup.cpp index 6cefca6aef2..97a2cff3ea6 100644 --- a/src/widget/wcuemenupopup.cpp +++ b/src/widget/wcuemenupopup.cpp @@ -97,7 +97,7 @@ void WCueMenuPopup::setTrackAndCue(TrackPointer pTrack, CuePointer pCue) { m_pCueNumber->setText(QString("")); m_pCuePosition->setText(QString("")); m_pEditLabel->setText(QString("")); - m_pColorPicker->setSelectedColor(); + m_pColorPicker->setSelectedColor(QColor()); } } @@ -108,14 +108,12 @@ void WCueMenuPopup::slotEditLabel() { m_pCue->setLabel(m_pEditLabel->text()); } -void WCueMenuPopup::slotChangeCueColor(PredefinedColorPointer pColor) { +void WCueMenuPopup::slotChangeCueColor(const QColor& color) { VERIFY_OR_DEBUG_ASSERT(m_pCue != nullptr) { return; } - VERIFY_OR_DEBUG_ASSERT(pColor != nullptr) { - return; - } - m_pCue->setColor(pColor); + m_pCue->setColor(color); + m_pColorPicker->setSelectedColor(color); hide(); } diff --git a/src/widget/wcuemenupopup.h b/src/widget/wcuemenupopup.h index cac6a9825c1..e9d7a932744 100644 --- a/src/widget/wcuemenupopup.h +++ b/src/widget/wcuemenupopup.h @@ -23,9 +23,9 @@ class WCueMenuPopup : public QWidget { void setTrackAndCue(TrackPointer pTrack, CuePointer pCue); - void useColorSet(PredefinedColorsRepresentation* pColorRepresentation) { + void useColorSet(const HotcueColorPalette& palette) { if (m_pColorPicker != nullptr) { - m_pColorPicker->useColorSet(pColorRepresentation); + m_pColorPicker->useColorSet(palette); } } @@ -54,7 +54,7 @@ class WCueMenuPopup : public QWidget { private slots: void slotEditLabel(); void slotDeleteCue(); - void slotChangeCueColor(PredefinedColorPointer pColor); + void slotChangeCueColor(const QColor& color); private: CuePointer m_pCue; diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index 183e9e08447..40538b7b3c2 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -25,6 +25,7 @@ #include "control/controlproxy.h" #include "engine/engine.h" #include "mixer/playermanager.h" +#include "preferences/hotcuecolorpalettesettings.h" #include "track/track.h" #include "util/color/color.h" #include "util/compatibility.h" @@ -136,7 +137,10 @@ void WOverview::setup(const QDomNode& node, const SkinContext& context) { ? defaultMark->fillColor() : m_signalColors.getAxesColor(); m_predefinedColorsRepresentation = context.getCueColorRepresentation(node, defaultColor); - m_pCueMenuPopup->useColorSet(&m_predefinedColorsRepresentation); + + HotcueColorPaletteSettings colorPaletteSettings(m_pConfig); + auto colorPalette = colorPaletteSettings.getHotcueColorPalette(); + m_pCueMenuPopup->useColorSet(colorPalette); for (const auto& pMark: m_marks) { if (pMark->isValid()) { @@ -349,8 +353,9 @@ void WOverview::updateCues(const QList &loadedCues) { for (CuePointer currentCue: loadedCues) { const WaveformMarkPointer pMark = m_marks.getHotCueMark(currentCue->getHotCue()); - if (pMark != nullptr && pMark->isValid() && pMark->isVisible() && pMark->getSamplePosition() != Cue::kNoPosition) { - QColor newColor = m_predefinedColorsRepresentation.representationFor(currentCue->getColor()); + if (pMark != nullptr && pMark->isValid() && pMark->isVisible() + && pMark->getSamplePosition() != Cue::kNoPosition) { + QColor newColor = currentCue->getColor(); if (newColor != pMark->fillColor() || newColor != pMark->m_textColor) { pMark->setBaseColor(newColor); } diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index aff9ac98e5a..6c9a7b25647 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -753,7 +753,7 @@ void WTrackTableView::showTrackInfo(QModelIndex index) { if (m_pTrackInfo.isNull()) { // Give a NULL parent because otherwise it inherits our style which can // make it unreadable. Bug #673411 - m_pTrackInfo.reset(new DlgTrackInfo(nullptr)); + m_pTrackInfo.reset(new DlgTrackInfo(m_pConfig, nullptr)); connect(m_pTrackInfo.data(), SIGNAL(next()), this, SLOT(slotNextTrackInfo())); @@ -1108,25 +1108,11 @@ void WTrackTableView::contextMenuEvent(QContextMenuEvent* event) { } } - // Get the predefined color of the selected tracks. If they have - // different colors, do not preselect a color (by using nullptr - // instead). - PredefinedColorPointer predefinedTrackColor = nullptr; - - if (trackColor) { - // All tracks have the same color - for (PredefinedColorPointer color : Color::kPredefinedColorsSet.allColors) { - if (mixxx::RgbColor(color->m_defaultRgba.rgb()) == *trackColor) { - predefinedTrackColor = color; - break; - } - } - } else if (!multipleTrackColors) { - // All tracks have no color - predefinedTrackColor = Color::kPredefinedColorsSet.noColor; + if (multipleTrackColors) { + m_pColorPickerAction->resetSelectedColor(); + } else { + m_pColorPickerAction->setSelectedColor(toQColor(trackColor)); } - - m_pColorPickerAction->setSelectedColor(predefinedTrackColor); m_pColorMenu->addAction(m_pColorPickerAction); m_pMenu->addMenu(m_pColorMenu); } @@ -1985,7 +1971,7 @@ void WTrackTableView::lockBpm(bool lock) { } } -void WTrackTableView::slotColorPicked(PredefinedColorPointer pColor) { +void WTrackTableView::slotColorPicked(const QColor& color) { TrackModel* trackModel = getTrackModel(); if (trackModel == nullptr) { return; @@ -1995,7 +1981,7 @@ void WTrackTableView::slotColorPicked(PredefinedColorPointer pColor) { // TODO: This should be done in a thread for large selections for (const auto& index : selectedTrackIndices) { TrackPointer track = trackModel->getTrack(index); - track->setColor(mixxx::RgbColor::fromQColor(pColor->m_defaultRgba)); + track->setColor(mixxx::RgbColor::optional(color)); } m_pMenu->hide(); diff --git a/src/widget/wtracktableview.h b/src/widget/wtracktableview.h index 2c1b90d7c65..895731950fd 100644 --- a/src/widget/wtracktableview.h +++ b/src/widget/wtracktableview.h @@ -81,7 +81,7 @@ class WTrackTableView : public WLibraryTableView { void slotLockBpm(); void slotUnlockBpm(); void slotScaleBpm(int); - void slotColorPicked(PredefinedColorPointer pColor); + void slotColorPicked(const QColor& color); void slotClearBeats(); void slotClearPlayCount(); From fcb4a1deb98dd8f8e7215047be48047e14c23f81 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sat, 2 Nov 2019 19:14:52 +0100 Subject: [PATCH 006/158] Migrate hotcue color id to RGBA in DB --- res/schema.xml | 25 +++++++++++++++++++++++++ src/database/mixxxdb.cpp | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/res/schema.xml b/res/schema.xml index be595aa65e4..648be453ac9 100644 --- a/res/schema.xml +++ b/res/schema.xml @@ -489,4 +489,29 @@ METADATA ALTER TABLE library ADD COLUMN color INTEGER; + + + Convert the PredefinedColor ID to the actual RGBA value. + + + + UPDATE cues SET color=0xFFF2F2FF WHERE color=0; + + UPDATE cues SET color=0xFFC50A08 WHERE color=1; + + UPDATE cues SET color=0xFF32BE44 WHERE color=2; + + UPDATE cues SET color=0xFF0044FF WHERE color=3; + + UPDATE cues SET color=0xFFF8D200 WHERE color=4; + + UPDATE cues SET color=0xFF42D4F4 WHERE color=5; + + UPDATE cues SET color=0xFFAF00CC WHERE color=6; + + UPDATE cues SET color=0xFFFCA6D7 WHERE color=7; + + UPDATE cues SET color=0xFFF2F2FF WHERE color=8; + + diff --git a/src/database/mixxxdb.cpp b/src/database/mixxxdb.cpp index e3a2e70cc7e..ab01999a95a 100644 --- a/src/database/mixxxdb.cpp +++ b/src/database/mixxxdb.cpp @@ -11,7 +11,7 @@ const QString MixxxDb::kDefaultSchemaFile(":/schema.xml"); //static -const int MixxxDb::kRequiredSchemaVersion = 31; +const int MixxxDb::kRequiredSchemaVersion = 32; namespace { From c22b7378ab166ed226b7596c84031529ca02b4a2 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sat, 2 Nov 2019 21:20:23 +0100 Subject: [PATCH 007/158] Remove PredefinedColorRepresentation --- src/skin/skincontext.h | 14 ------- .../color/predefinedcolorsrepresentation.h | 41 ------------------- src/util/color/predefinedcolorsset.h | 16 -------- src/waveform/renderers/waveformrendermark.cpp | 5 --- src/waveform/renderers/waveformrendermark.h | 2 - src/widget/woverview.cpp | 5 --- src/widget/woverview.h | 1 - 7 files changed, 84 deletions(-) delete mode 100644 src/util/color/predefinedcolorsrepresentation.h diff --git a/src/skin/skincontext.h b/src/skin/skincontext.h index 10bba69feff..55e501a32b6 100644 --- a/src/skin/skincontext.h +++ b/src/skin/skincontext.h @@ -258,20 +258,6 @@ class SkinContext { return m_scaleFactor; } - PredefinedColorsRepresentation getCueColorRepresentation(const QDomNode& node, QColor defaultColor) const { - PredefinedColorsRepresentation colorRepresentation = Color::kPredefinedColorsSet.defaultRepresentation(); - for (PredefinedColorPointer color : Color::kPredefinedColorsSet.allColors) { - QString sColorName(color->m_sName); - QColor skinRgba = selectColor(node, "Cue" + sColorName); - if (skinRgba.isValid()) { - PredefinedColorPointer originalColor = Color::kPredefinedColorsSet.predefinedColorFromName(sColorName); - colorRepresentation.setCustomRgba(originalColor, skinRgba); - } - } - colorRepresentation.setCustomRgba(Color::kPredefinedColorsSet.noColor, defaultColor); - return colorRepresentation; - } - private: PixmapSource getPixmapSourceInner(const QString& filename) const; diff --git a/src/util/color/predefinedcolorsrepresentation.h b/src/util/color/predefinedcolorsrepresentation.h deleted file mode 100644 index 83f16405447..00000000000 --- a/src/util/color/predefinedcolorsrepresentation.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef PREDEFINEDCOLORSREPRESENTATION_H -#define PREDEFINEDCOLORSREPRESENTATION_H - -#include -#include - -#include "util/color/predefinedcolor.h" - -// PredefinedColorsRepresentation defines a particular way to render Mixxx PredefinedColors. -// -// PredefinedColorsRepresentation maps a PredefinedColor to a custom Rgba color. -// Initially no color has a custom Rgba set. -// Call setCustomRgba(PredefinedColorPointer, QColor) to add a custom Rgba for a predefined color -// and customize the color map. -// -// This class uses the color's name() property as key, e.g. "#A9A9A9" -// Since QHash has copy-on-write, making a copy of PredefinedColorsRepresentation is fast. -// A deep copy of the QHash will be made when a copy is modified. -class PredefinedColorsRepresentation final { - public: - // Set a custom Rgba for a given color - void setCustomRgba(PredefinedColorPointer color, QColor cutomizedRgba) { - m_colorNameMap[color->m_defaultRgba.name()] = cutomizedRgba.name(); - } - - // Returns the custom Rgba of a color. - // If no custom Rgba is set for color, returns color->m_defaultRgba. - QColor representationFor(PredefinedColorPointer color) const { - QColor defaultRgba = color->m_defaultRgba; - if (m_colorNameMap.contains(defaultRgba.name())) { - return QColor(m_colorNameMap[defaultRgba.name()]); - } - return defaultRgba; - } - - - private: - QHash m_colorNameMap; -}; - -#endif /* PREDEFINEDCOLORSREPRESENTATION_H */ diff --git a/src/util/color/predefinedcolorsset.h b/src/util/color/predefinedcolorsset.h index 5a343913e8f..f8749f2a3fa 100644 --- a/src/util/color/predefinedcolorsset.h +++ b/src/util/color/predefinedcolorsset.h @@ -3,7 +3,6 @@ #include #include -#include "predefinedcolorsrepresentation.h" #include "util/color/predefinedcolor.h" // This class defines a set of predefined colors and provides some handy functions to work with them. @@ -70,13 +69,6 @@ class PredefinedColorsSet final { white, }; - PredefinedColorsSet() - : m_defaultRepresentation() { - for (PredefinedColorPointer color : allColors) { - m_defaultRepresentation.setCustomRgba(color, color->m_defaultRgba); - } - } - // Returns the position of a PredefinedColor in the allColors list. int predefinedColorIndex(PredefinedColorPointer searchedColor) const { for (int position = 0; position < allColors.count(); ++position) { @@ -109,12 +101,4 @@ class PredefinedColorsSet final { } return noColor; }; - - // The default color representation, i.e. maps each predefined color to its default Rgba. - PredefinedColorsRepresentation defaultRepresentation() const { - return m_defaultRepresentation; - }; - - private: - PredefinedColorsRepresentation m_defaultRepresentation; }; diff --git a/src/waveform/renderers/waveformrendermark.cpp b/src/waveform/renderers/waveformrendermark.cpp index d22fa1b20ef..26a840e8974 100644 --- a/src/waveform/renderers/waveformrendermark.cpp +++ b/src/waveform/renderers/waveformrendermark.cpp @@ -27,11 +27,6 @@ WaveformRenderMark::WaveformRenderMark( void WaveformRenderMark::setup(const QDomNode& node, const SkinContext& context) { WaveformSignalColors signalColors = *m_waveformRenderer->getWaveformSignalColors(); m_marks.setup(m_waveformRenderer->getGroup(), node, context, signalColors); - WaveformMarkPointer defaultMark(m_marks.getDefaultMark()); - QColor defaultColor = defaultMark - ? defaultMark->fillColor() - : signalColors.getAxesColor(); - m_predefinedColorsRepresentation = context.getCueColorRepresentation(node, defaultColor); } void WaveformRenderMark::draw(QPainter* painter, QPaintEvent* /*event*/) { diff --git a/src/waveform/renderers/waveformrendermark.h b/src/waveform/renderers/waveformrendermark.h index 693332c8162..dc0fad17c90 100644 --- a/src/waveform/renderers/waveformrendermark.h +++ b/src/waveform/renderers/waveformrendermark.h @@ -35,8 +35,6 @@ class WaveformRenderMark : public QObject, public WaveformRendererAbstract { private: void generateMarkImage(WaveformMarkPointer pMark); - PredefinedColorsRepresentation m_predefinedColorsRepresentation; - WaveformMarkSet m_marks; DISALLOW_COPY_AND_ASSIGN(WaveformRenderMark); }; diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index 40538b7b3c2..4b7a74814c7 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -132,11 +132,6 @@ void WOverview::setup(const QDomNode& node, const SkinContext& context) { // setup hotcues and cue and loop(s) m_marks.setup(m_group, node, context, m_signalColors); - WaveformMarkPointer defaultMark(m_marks.getDefaultMark()); - QColor defaultColor = defaultMark - ? defaultMark->fillColor() - : m_signalColors.getAxesColor(); - m_predefinedColorsRepresentation = context.getCueColorRepresentation(node, defaultColor); HotcueColorPaletteSettings colorPaletteSettings(m_pConfig); auto colorPalette = colorPaletteSettings.getHotcueColorPalette(); diff --git a/src/widget/woverview.h b/src/widget/woverview.h index 4837b89f002..25ce680bd18 100644 --- a/src/widget/woverview.h +++ b/src/widget/woverview.h @@ -169,7 +169,6 @@ class WOverview : public WWidget, public TrackDropTarget { QColor m_labelBackgroundColor; QColor m_endOfTrackColor; - PredefinedColorsRepresentation m_predefinedColorsRepresentation; // All WaveformMarks WaveformMarkSet m_marks; // List of visible WaveformMarks sorted by the order they appear in the track From f017447d841f57ea526101b622c645de9bb36fc9 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sun, 3 Nov 2019 09:43:25 +0100 Subject: [PATCH 008/158] Make UserSettings available in ControllerEngine --- src/controllers/bulk/bulkcontroller.cpp | 14 +++++++------- src/controllers/bulk/bulkcontroller.h | 6 ++++-- src/controllers/bulk/bulkenumerator.cpp | 8 ++++---- src/controllers/bulk/bulkenumerator.h | 3 ++- src/controllers/controller.cpp | 9 +++++---- src/controllers/controller.h | 4 +++- src/controllers/controllerengine.cpp | 4 +++- src/controllers/controllerengine.h | 3 ++- src/controllers/controllermanager.cpp | 8 ++++---- src/controllers/hid/hidcontroller.cpp | 5 +++-- src/controllers/hid/hidcontroller.h | 2 +- src/controllers/hid/hidenumerator.cpp | 5 +++-- src/controllers/hid/hidenumerator.h | 3 ++- src/controllers/midi/hss1394controller.cpp | 8 +++++--- src/controllers/midi/hss1394controller.h | 5 ++++- src/controllers/midi/hss1394enumerator.cpp | 8 +++++--- src/controllers/midi/hss1394enumerator.h | 3 ++- src/controllers/midi/midicontroller.cpp | 4 ++-- src/controllers/midi/midicontroller.h | 2 +- src/controllers/midi/portmidicontroller.cpp | 11 +++++------ src/controllers/midi/portmidicontroller.h | 7 ++++--- src/controllers/midi/portmidienumerator.cpp | 12 ++++++++---- src/controllers/midi/portmidienumerator.h | 3 ++- .../controller_preset_validation_test.cpp | 9 ++++----- src/test/midicontrollertest.cpp | 5 +++-- src/test/portmidicontroller_test.cpp | 19 +++++++++++-------- 26 files changed, 99 insertions(+), 71 deletions(-) diff --git a/src/controllers/bulk/bulkcontroller.cpp b/src/controllers/bulk/bulkcontroller.cpp index 17459ae8d97..49468b1ceab 100644 --- a/src/controllers/bulk/bulkcontroller.cpp +++ b/src/controllers/bulk/bulkcontroller.cpp @@ -69,15 +69,15 @@ static QString get_string(libusb_device_handle *handle, u_int8_t id) { return QString::fromLatin1((char*)buf); } - -BulkController::BulkController(libusb_context* context, - libusb_device_handle *handle, - struct libusb_device_descriptor *desc) - : m_context(context), +BulkController::BulkController(UserSettingsPointer pConfig, + libusb_context* context, + libusb_device_handle* handle, + struct libusb_device_descriptor* desc) + : Controller(pConfig), + m_context(context), m_phandle(handle), in_epaddr(0), - out_epaddr(0) -{ + out_epaddr(0) { vendor_id = desc->idVendor; product_id = desc->idProduct; diff --git a/src/controllers/bulk/bulkcontroller.h b/src/controllers/bulk/bulkcontroller.h index 480aa084a69..9d67c1041ea 100644 --- a/src/controllers/bulk/bulkcontroller.h +++ b/src/controllers/bulk/bulkcontroller.h @@ -42,8 +42,10 @@ class BulkReader : public QThread { class BulkController : public Controller { Q_OBJECT public: - BulkController(libusb_context* context, libusb_device_handle *handle, - struct libusb_device_descriptor *desc); + BulkController(UserSettingsPointer pConfig, + libusb_context* context, + libusb_device_handle* handle, + struct libusb_device_descriptor* desc); ~BulkController() override; QString presetExtension() override; diff --git a/src/controllers/bulk/bulkenumerator.cpp b/src/controllers/bulk/bulkenumerator.cpp index 2942c5b3ac7..27b5eea15d3 100644 --- a/src/controllers/bulk/bulkenumerator.cpp +++ b/src/controllers/bulk/bulkenumerator.cpp @@ -11,9 +11,8 @@ #include "controllers/bulk/bulkenumerator.h" #include "controllers/bulk/bulksupported.h" -BulkEnumerator::BulkEnumerator() - : ControllerEnumerator(), - m_context(NULL) { +BulkEnumerator::BulkEnumerator(UserSettingsPointer pConfig) + : ControllerEnumerator(), m_context(NULL), m_pConfig(pConfig) { libusb_init(&m_context); } @@ -55,7 +54,8 @@ QList BulkEnumerator::queryDevices() { continue; } - BulkController* currentDevice = new BulkController(m_context, handle, &desc); + BulkController* currentDevice = + new BulkController(m_pConfig, m_context, handle, &desc); m_devices.push_back(currentDevice); } } diff --git a/src/controllers/bulk/bulkenumerator.h b/src/controllers/bulk/bulkenumerator.h index 5e16dd67d11..2018a4a1181 100644 --- a/src/controllers/bulk/bulkenumerator.h +++ b/src/controllers/bulk/bulkenumerator.h @@ -14,7 +14,7 @@ struct libusb_context; class BulkEnumerator : public ControllerEnumerator { public: - BulkEnumerator(); + BulkEnumerator(UserSettingsPointer pConfig); virtual ~BulkEnumerator(); QList queryDevices(); @@ -22,6 +22,7 @@ class BulkEnumerator : public ControllerEnumerator { private: QList m_devices; libusb_context* m_context; + UserSettingsPointer m_pConfig; }; #endif diff --git a/src/controllers/controller.cpp b/src/controllers/controller.cpp index e30ff7a5f63..15a1e1dd5ec 100644 --- a/src/controllers/controller.cpp +++ b/src/controllers/controller.cpp @@ -13,14 +13,15 @@ #include "controllers/defs_controllers.h" #include "util/screensaver.h" -Controller::Controller() +Controller::Controller(UserSettingsPointer pConfig) : QObject(), m_pEngine(NULL), m_bIsOutputDevice(false), m_bIsInputDevice(false), m_bIsOpen(false), - m_bLearning(false) { - m_userActivityInhibitTimer.start(); + m_bLearning(false), + m_pConfig(pConfig) { + m_userActivityInhibitTimer.start(); } Controller::~Controller() { @@ -35,7 +36,7 @@ void Controller::startEngine() qWarning() << "Controller: Engine already exists! Restarting:"; stopEngine(); } - m_pEngine = new ControllerEngine(this); + m_pEngine = new ControllerEngine(this, m_pConfig); } void Controller::stopEngine() { diff --git a/src/controllers/controller.h b/src/controllers/controller.h index ec2ad82ceac..387b0640973 100644 --- a/src/controllers/controller.h +++ b/src/controllers/controller.h @@ -23,7 +23,7 @@ class Controller : public QObject, ConstControllerPresetVisitor { Q_OBJECT public: - Controller(); + Controller(UserSettingsPointer pConfig); ~Controller() override; // Subclass should call close() at minimum. // Returns the extension for the controller (type) preset files. This is @@ -162,6 +162,8 @@ class Controller : public QObject, ConstControllerPresetVisitor { bool m_bLearning; QElapsedTimer m_userActivityInhibitTimer; + UserSettingsPointer m_pConfig; + // accesses lots of our stuff, but in the same thread friend class ControllerManager; // For testing diff --git a/src/controllers/controllerengine.cpp b/src/controllers/controllerengine.cpp index 8b272c4e528..fa5fbac8784 100644 --- a/src/controllers/controllerengine.cpp +++ b/src/controllers/controllerengine.cpp @@ -29,9 +29,11 @@ const int kDecks = 16; const int kScratchTimerMs = 1; const double kAlphaBetaDt = kScratchTimerMs / 1000.0; -ControllerEngine::ControllerEngine(Controller* controller) +ControllerEngine::ControllerEngine( + Controller* controller, UserSettingsPointer pConfig) : m_pEngine(nullptr), m_pController(controller), + m_pConfig(pConfig), m_bPopups(false), m_pBaClass(nullptr) { // Handle error dialog buttons diff --git a/src/controllers/controllerengine.h b/src/controllers/controllerengine.h index 2359a0bcbb3..7eafb1763ea 100644 --- a/src/controllers/controllerengine.h +++ b/src/controllers/controllerengine.h @@ -80,7 +80,7 @@ class ScriptConnectionInvokableWrapper : public QObject { class ControllerEngine : public QObject { Q_OBJECT public: - ControllerEngine(Controller* controller); + ControllerEngine(Controller* controller, UserSettingsPointer pConfig); virtual ~ControllerEngine(); bool isReady(); @@ -198,6 +198,7 @@ class ControllerEngine : public QObject { double getDeckRate(const QString& group); Controller* m_pController; + UserSettingsPointer m_pConfig; bool m_bPopups; QList m_scriptFunctionPrefixes; QMap m_scriptErrors; diff --git a/src/controllers/controllermanager.cpp b/src/controllers/controllermanager.cpp index d6d4592bd27..ec74976f7f5 100644 --- a/src/controllers/controllermanager.cpp +++ b/src/controllers/controllermanager.cpp @@ -127,15 +127,15 @@ void ControllerManager::slotInitialize() { // Instantiate all enumerators. Enumerators can take a long time to // construct since they interact with host MIDI APIs. - m_enumerators.append(new PortMidiEnumerator()); + m_enumerators.append(new PortMidiEnumerator(m_pConfig)); #ifdef __HSS1394__ - m_enumerators.append(new Hss1394Enumerator()); + m_enumerators.append(new Hss1394Enumerator(m_pConfig)); #endif #ifdef __BULK__ - m_enumerators.append(new BulkEnumerator()); + m_enumerators.append(new BulkEnumerator(m_pConfig)); #endif #ifdef __HID__ - m_enumerators.append(new HidEnumerator()); + m_enumerators.append(new HidEnumerator(m_pConfig)); #endif } diff --git a/src/controllers/hid/hidcontroller.cpp b/src/controllers/hid/hidcontroller.cpp index c317799155e..32912447f72 100644 --- a/src/controllers/hid/hidcontroller.cpp +++ b/src/controllers/hid/hidcontroller.cpp @@ -16,8 +16,9 @@ #include "controllers/controllerdebug.h" #include "util/time.h" -HidController::HidController(const hid_device_info deviceInfo) - : m_pHidDevice(NULL) { +HidController::HidController(const hid_device_info deviceInfo, UserSettingsPointer pConfig) + : Controller(pConfig), + m_pHidDevice(NULL) { // Copy required variables from deviceInfo, which will be freed after // this class is initialized by caller. hid_vendor_id = deviceInfo.vendor_id; diff --git a/src/controllers/hid/hidcontroller.h b/src/controllers/hid/hidcontroller.h index 4f446c9ae9b..b85b6cdfaf2 100644 --- a/src/controllers/hid/hidcontroller.h +++ b/src/controllers/hid/hidcontroller.h @@ -20,7 +20,7 @@ class HidController final : public Controller { Q_OBJECT public: - HidController(const hid_device_info deviceInfo); + HidController(const hid_device_info deviceInfo, UserSettingsPointer pConfig); ~HidController() override; QString presetExtension() override; diff --git a/src/controllers/hid/hidenumerator.cpp b/src/controllers/hid/hidenumerator.cpp index c1c2dc27834..802459f3c02 100644 --- a/src/controllers/hid/hidenumerator.cpp +++ b/src/controllers/hid/hidenumerator.cpp @@ -11,7 +11,8 @@ #include "controllers/hid/hidenumerator.h" #include "controllers/hid/hidblacklist.h" -HidEnumerator::HidEnumerator() : ControllerEnumerator() { +HidEnumerator::HidEnumerator(UserSettingsPointer pConfig) + : ControllerEnumerator(), m_pConfig(pConfig) { } HidEnumerator::~HidEnumerator() { @@ -98,7 +99,7 @@ QList HidEnumerator::queryDevices() { continue; } - HidController* currentDevice = new HidController(*cur_dev); + HidController* currentDevice = new HidController(*cur_dev, m_pConfig); m_devices.push_back(currentDevice); } hid_free_enumeration(devs); diff --git a/src/controllers/hid/hidenumerator.h b/src/controllers/hid/hidenumerator.h index 351e972beb1..9b39b75c947 100644 --- a/src/controllers/hid/hidenumerator.h +++ b/src/controllers/hid/hidenumerator.h @@ -12,13 +12,14 @@ class HidEnumerator : public ControllerEnumerator { public: - HidEnumerator(); + HidEnumerator(UserSettingsPointer pConfig); virtual ~HidEnumerator(); QList queryDevices(); private: QList m_devices; + UserSettingsPointer m_pConfig; }; #endif diff --git a/src/controllers/midi/hss1394controller.cpp b/src/controllers/midi/hss1394controller.cpp index 7c78a5b4a6a..1b87a4e834e 100644 --- a/src/controllers/midi/hss1394controller.cpp +++ b/src/controllers/midi/hss1394controller.cpp @@ -64,9 +64,11 @@ void DeviceChannelListener::Reconnected() { qDebug() << "HSS1394 device" << m_sName << "re-connected"; } -Hss1394Controller::Hss1394Controller(const hss1394::TNodeInfo deviceInfo, - int deviceIndex) - : MidiController(), +Hss1394Controller::Hss1394Controller( + const hss1394::TNodeInfo deviceInfo, + int deviceIndex, + UserSettingsPointer pConfig) + : MidiController(pConfig), m_deviceInfo(deviceInfo), m_iDeviceIndex(deviceIndex) { // Note: We prepend the input stream's index to the device's name to prevent diff --git a/src/controllers/midi/hss1394controller.h b/src/controllers/midi/hss1394controller.h index ec6e5503093..284d00629fe 100644 --- a/src/controllers/midi/hss1394controller.h +++ b/src/controllers/midi/hss1394controller.h @@ -43,7 +43,10 @@ class DeviceChannelListener : public QObject, public hss1394::ChannelListener { class Hss1394Controller : public MidiController { Q_OBJECT public: - Hss1394Controller(const hss1394::TNodeInfo deviceInfo, int deviceIndex); + Hss1394Controller( + const hss1394::TNodeInfo deviceInfo, + int deviceIndex, + UserSettingsPointer pConfig); ~Hss1394Controller() override; private slots: diff --git a/src/controllers/midi/hss1394enumerator.cpp b/src/controllers/midi/hss1394enumerator.cpp index 8152abd0e36..9c29ac98ee3 100644 --- a/src/controllers/midi/hss1394enumerator.cpp +++ b/src/controllers/midi/hss1394enumerator.cpp @@ -9,7 +9,9 @@ #include "controllers/midi/hss1394controller.h" #include "controllers/midi/hss1394enumerator.h" -Hss1394Enumerator::Hss1394Enumerator() : MidiEnumerator() { +Hss1394Enumerator::Hss1394Enumerator(UserSettingsPointer pConfig) + : MidiEnumerator(), + m_pConfig(pConfig) { } Hss1394Enumerator::~Hss1394Enumerator() { @@ -42,8 +44,8 @@ QList Hss1394Enumerator::queryDevices() { QString("%1").arg(tNodeInfo.uGUID.mu32Low, 0, 16), QString("%1").arg(tNodeInfo.uProtocolVersion, 0, 16)); qDebug() << " " << message; - Hss1394Controller *currentDevice = new Hss1394Controller( - tNodeInfo, i); + Hss1394Controller* currentDevice = new Hss1394Controller( + tNodeInfo, i, m_pConfig); m_devices.push_back(currentDevice); } } diff --git a/src/controllers/midi/hss1394enumerator.h b/src/controllers/midi/hss1394enumerator.h index baa208701fc..78d581425fd 100644 --- a/src/controllers/midi/hss1394enumerator.h +++ b/src/controllers/midi/hss1394enumerator.h @@ -13,12 +13,13 @@ class Hss1394Enumerator : public MidiEnumerator { Q_OBJECT public: - Hss1394Enumerator(); + Hss1394Enumerator(UserSettingsPointer pConfig); virtual ~Hss1394Enumerator(); QList queryDevices(); private: + UserSettingsPointer m_pConfig; QList m_devices; }; diff --git a/src/controllers/midi/midicontroller.cpp b/src/controllers/midi/midicontroller.cpp index 479631b8388..877897f00f1 100644 --- a/src/controllers/midi/midicontroller.cpp +++ b/src/controllers/midi/midicontroller.cpp @@ -17,8 +17,8 @@ #include "util/math.h" #include "util/screensaver.h" -MidiController::MidiController() - : Controller() { +MidiController::MidiController(UserSettingsPointer pConfig) + : Controller(pConfig) { setDeviceCategory(tr("MIDI Controller")); } diff --git a/src/controllers/midi/midicontroller.h b/src/controllers/midi/midicontroller.h index 93d91fdf443..b8ebb8b94b4 100644 --- a/src/controllers/midi/midicontroller.h +++ b/src/controllers/midi/midicontroller.h @@ -23,7 +23,7 @@ class MidiController : public Controller { Q_OBJECT public: - MidiController(); + MidiController(UserSettingsPointer pConfig); ~MidiController() override; QString presetExtension() override; diff --git a/src/controllers/midi/portmidicontroller.cpp b/src/controllers/midi/portmidicontroller.cpp index c4479a1ae68..4be78583c78 100644 --- a/src/controllers/midi/portmidicontroller.cpp +++ b/src/controllers/midi/portmidicontroller.cpp @@ -12,12 +12,11 @@ #include "controllers/controllerdebug.h" PortMidiController::PortMidiController(const PmDeviceInfo* inputDeviceInfo, - const PmDeviceInfo* outputDeviceInfo, - int inputDeviceIndex, - int outputDeviceIndex) - : MidiController(), - m_cReceiveMsg_index(0), - m_bInSysex(false) { + const PmDeviceInfo* outputDeviceInfo, + int inputDeviceIndex, + int outputDeviceIndex, + UserSettingsPointer pConfig) + : MidiController(pConfig), m_cReceiveMsg_index(0), m_bInSysex(false) { for (unsigned int k = 0; k < MIXXX_PORTMIDI_BUFFER_LEN; ++k) { // Can be shortened to `m_midiBuffer[k] = {}` with C++11. m_midiBuffer[k].message = 0; diff --git a/src/controllers/midi/portmidicontroller.h b/src/controllers/midi/portmidicontroller.h index 96da9afce1a..92d2954e18f 100644 --- a/src/controllers/midi/portmidicontroller.h +++ b/src/controllers/midi/portmidicontroller.h @@ -60,9 +60,10 @@ class PortMidiController : public MidiController { Q_OBJECT public: PortMidiController(const PmDeviceInfo* inputDeviceInfo, - const PmDeviceInfo* outputDeviceInfo, - int inputDeviceIndex, - int outputDeviceIndex); + const PmDeviceInfo* outputDeviceInfo, + int inputDeviceIndex, + int outputDeviceIndex, + UserSettingsPointer pConfig); ~PortMidiController() override; private slots: diff --git a/src/controllers/midi/portmidienumerator.cpp b/src/controllers/midi/portmidienumerator.cpp index 47e6a23a829..ba525ddeb73 100644 --- a/src/controllers/midi/portmidienumerator.cpp +++ b/src/controllers/midi/portmidienumerator.cpp @@ -21,7 +21,8 @@ bool shouldBlacklistDevice(const PmDeviceInfo* device) { deviceName.startsWith("Midi Through Port", Qt::CaseInsensitive); } -PortMidiEnumerator::PortMidiEnumerator() : MidiEnumerator() { +PortMidiEnumerator::PortMidiEnumerator(UserSettingsPointer pConfig) + : MidiEnumerator(), m_pConfig(pConfig) { PmError err = Pm_Initialize(); // Based on reading the source, it's not possible for this to fail. if (err != pmNoError) { @@ -257,9 +258,12 @@ QList PortMidiEnumerator::queryDevices() { // device (outputDeviceInfo != NULL). //.... so create our (aggregate) MIDI device! - PortMidiController *currentDevice = new PortMidiController( - inputDeviceInfo, outputDeviceInfo, - inputDevIndex, outputDevIndex); + PortMidiController* currentDevice = + new PortMidiController(inputDeviceInfo, + outputDeviceInfo, + inputDevIndex, + outputDevIndex, + m_pConfig); m_devices.push_back(currentDevice); } diff --git a/src/controllers/midi/portmidienumerator.h b/src/controllers/midi/portmidienumerator.h index 606c4feb4de..9566b54df1b 100644 --- a/src/controllers/midi/portmidienumerator.h +++ b/src/controllers/midi/portmidienumerator.h @@ -13,13 +13,14 @@ class PortMidiEnumerator : public MidiEnumerator { Q_OBJECT public: - PortMidiEnumerator(); + PortMidiEnumerator(UserSettingsPointer pConfig); virtual ~PortMidiEnumerator(); QList queryDevices(); private: QList m_devices; + UserSettingsPointer m_pConfig; }; // For testing. diff --git a/src/test/controller_preset_validation_test.cpp b/src/test/controller_preset_validation_test.cpp index d49ee3e50ba..970cf0158c9 100644 --- a/src/test/controller_preset_validation_test.cpp +++ b/src/test/controller_preset_validation_test.cpp @@ -15,7 +15,7 @@ class FakeController : public Controller { public: - FakeController(); + FakeController(UserSettingsPointer pConfig); ~FakeController() override; QString presetExtension() override { @@ -112,9 +112,8 @@ class FakeController : public Controller { HidControllerPreset m_hidPreset; }; -FakeController::FakeController() - : m_bMidiPreset(false), - m_bHidPreset(false) { +FakeController::FakeController(UserSettingsPointer pConfig) + : Controller(pConfig), m_bMidiPreset(false), m_bHidPreset(false) { } FakeController::~FakeController() { @@ -135,7 +134,7 @@ class ControllerPresetValidationTest : public MixxxTest { return false; } - FakeController controller; + FakeController controller(config()); controller.setDeviceName("Test Controller"); controller.startEngine(); controller.setPreset(*pPreset); diff --git a/src/test/midicontrollertest.cpp b/src/test/midicontrollertest.cpp index 696483c05fd..0d10c4c54a0 100644 --- a/src/test/midicontrollertest.cpp +++ b/src/test/midicontrollertest.cpp @@ -12,7 +12,8 @@ class MockMidiController : public MidiController { public: - MockMidiController() { } + MockMidiController(UserSettingsPointer pConfig) : MidiController(pConfig) { + } ~MockMidiController() override { } MOCK_METHOD0(open, int()); @@ -27,7 +28,7 @@ class MockMidiController : public MidiController { class MidiControllerTest : public MixxxTest { protected: void SetUp() override { - m_pController.reset(new MockMidiController()); + m_pController.reset(new MockMidiController(config())); } void addMapping(MidiInputMapping mapping) { diff --git a/src/test/portmidicontroller_test.cpp b/src/test/portmidicontroller_test.cpp index ad007b79095..9d8fccdaa69 100644 --- a/src/test/portmidicontroller_test.cpp +++ b/src/test/portmidicontroller_test.cpp @@ -16,11 +16,15 @@ using ::testing::SetArrayArgument; class MockPortMidiController : public PortMidiController { public: MockPortMidiController(const PmDeviceInfo* inputDeviceInfo, - const PmDeviceInfo* outputDeviceInfo, - int inputDeviceIndex, - int outputDeviceIndex) : PortMidiController( - inputDeviceInfo, outputDeviceInfo, - inputDeviceIndex, outputDeviceIndex) { + const PmDeviceInfo* outputDeviceInfo, + int inputDeviceIndex, + int outputDeviceIndex, + UserSettingsPointer pConfig) + : PortMidiController(inputDeviceInfo, + outputDeviceInfo, + inputDeviceIndex, + outputDeviceIndex, + pConfig) { } ~MockPortMidiController() override { } @@ -71,9 +75,8 @@ class PortMidiControllerTest : public MixxxTest { m_outputDeviceInfo.output = 1; m_outputDeviceInfo.opened = 0; - m_pController.reset(new MockPortMidiController(&m_inputDeviceInfo, - &m_outputDeviceInfo, - 0, 0)); + m_pController.reset(new MockPortMidiController( + &m_inputDeviceInfo, &m_outputDeviceInfo, 0, 0, config())); m_pController->setPortMidiInputDevice(m_mockInput); m_pController->setPortMidiOutputDevice(m_mockOutput); } From f68f28c554cc09ab373260c6bbeb8047a0942455 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sun, 3 Nov 2019 09:47:13 +0100 Subject: [PATCH 009/158] Remove PredefinedColors from controller scripts ... and use QColor instead. --- src/controllers/colorjsproxy.cpp | 50 +++++++++++++++------------ src/controllers/colorjsproxy.h | 21 ++++++----- src/controllers/controllerengine.cpp | 2 +- src/test/controllerengine_test.cpp | 45 ++++++++++++------------ src/util/color/hotcuecolorpalette.cpp | 3 +- 5 files changed, 65 insertions(+), 56 deletions(-) diff --git a/src/controllers/colorjsproxy.cpp b/src/controllers/colorjsproxy.cpp index 4147cdcc124..8b2f2fd644e 100644 --- a/src/controllers/colorjsproxy.cpp +++ b/src/controllers/colorjsproxy.cpp @@ -1,36 +1,40 @@ #include "controllers/colorjsproxy.h" +#include "preferences/hotcuecolorpalettesettings.h" -ColorJSProxy::ColorJSProxy(QScriptEngine* pScriptEngine) - : m_pScriptEngine(pScriptEngine), - m_predefinedColorsList(makePredefinedColorsList(pScriptEngine)){}; - -ColorJSProxy::~ColorJSProxy() {}; +ColorJSProxy::ColorJSProxy( + QScriptEngine* pScriptEngine, UserSettingsPointer pConfig) + : m_pScriptEngine(pScriptEngine), + m_hotcueColorPalette(makeHotcueColorPalette(pScriptEngine, pConfig)), + m_pConfig(pConfig) { +} -QScriptValue ColorJSProxy::predefinedColorFromId(int iId) { - PredefinedColorPointer color(Color::kPredefinedColorsSet.predefinedColorFromId(iId)); - return jsColorFrom(color); -}; +ColorJSProxy::~ColorJSProxy() = default; -Q_INVOKABLE QScriptValue ColorJSProxy::predefinedColorsList() { - return m_predefinedColorsList; +Q_INVOKABLE QScriptValue ColorJSProxy::hotcueColorPalette() { + return m_hotcueColorPalette; } -QScriptValue ColorJSProxy::jsColorFrom(PredefinedColorPointer predefinedColor) { +QScriptValue ColorJSProxy::colorFromHexCode(uint colorCode) { + QColor color = QColor::fromRgba(colorCode); QScriptValue jsColor = m_pScriptEngine->newObject(); - jsColor.setProperty("red", predefinedColor->m_defaultRgba.red()); - jsColor.setProperty("green", predefinedColor->m_defaultRgba.green()); - jsColor.setProperty("blue", predefinedColor->m_defaultRgba.blue()); - jsColor.setProperty("alpha", predefinedColor->m_defaultRgba.alpha()); - jsColor.setProperty("id", predefinedColor->m_iId); + jsColor.setProperty("red", color.red()); + jsColor.setProperty("green", color.green()); + jsColor.setProperty("blue", color.blue()); + jsColor.setProperty("alpha", color.alpha()); return jsColor; } -QScriptValue ColorJSProxy::makePredefinedColorsList(QScriptEngine* pScriptEngine) { - int numColors = Color::kPredefinedColorsSet.allColors.length(); - QScriptValue colorList = pScriptEngine->newArray(numColors); +QScriptValue ColorJSProxy::makeHotcueColorPalette( + QScriptEngine* pScriptEngine, UserSettingsPointer pConfig) { + // TODO: make sure we get notified when the palette changes + HotcueColorPaletteSettings colorPaletteSettings(pConfig); + QList colorList = + colorPaletteSettings.getHotcueColorPalette().m_colorList; + int numColors = colorList.length(); + QScriptValue jsColorList = pScriptEngine->newArray(numColors); for (int i = 0; i < numColors; ++i) { - PredefinedColorPointer color = Color::kPredefinedColorsSet.allColors.at(i); - colorList.setProperty(i, jsColorFrom(color)); + QColor color = colorList.at(i); + jsColorList.setProperty(i, colorFromHexCode(color.rgba())); } - return colorList; + return jsColorList; } diff --git a/src/controllers/colorjsproxy.h b/src/controllers/colorjsproxy.h index e6ebeda1d9b..61a801b4617 100644 --- a/src/controllers/colorjsproxy.h +++ b/src/controllers/colorjsproxy.h @@ -5,23 +5,28 @@ #include #include +#include "preferences/usersettings.h" #include "util/color/color.h" -class ColorJSProxy: public QObject { +class ColorJSProxy final : public QObject { Q_OBJECT public: - ColorJSProxy(QScriptEngine* pScriptEngine); + ColorJSProxy(QScriptEngine* pScriptEngine, UserSettingsPointer pConfig); - virtual ~ColorJSProxy(); + ~ColorJSProxy() override; - Q_INVOKABLE QScriptValue predefinedColorFromId(int iId); - Q_INVOKABLE QScriptValue predefinedColorsList(); + Q_INVOKABLE QScriptValue hotcueColorPalette(); + // Return a JS object with the red, green, blue and alpha components + // of a color. The parameter is the hexadecimal representation of the color + // i.e. 0xAARRGGBB + Q_INVOKABLE QScriptValue colorFromHexCode(uint colorCode); private: - QScriptValue jsColorFrom(PredefinedColorPointer predefinedColor); - QScriptValue makePredefinedColorsList(QScriptEngine* pScriptEngine); + QScriptValue makeHotcueColorPalette( + QScriptEngine* pScriptEngine, UserSettingsPointer pConfig); QScriptEngine* m_pScriptEngine; - QScriptValue m_predefinedColorsList; + QScriptValue m_hotcueColorPalette; + UserSettingsPointer m_pConfig; }; #endif /* COLORJSPROXY_H */ diff --git a/src/controllers/controllerengine.cpp b/src/controllers/controllerengine.cpp index fa5fbac8784..320a8cfda4a 100644 --- a/src/controllers/controllerengine.cpp +++ b/src/controllers/controllerengine.cpp @@ -215,7 +215,7 @@ void ControllerEngine::initializeScriptEngine() { engineGlobalObject.setProperty("midi", m_pEngine->newQObject(m_pController)); } - m_pColorJSProxy = std::make_unique(m_pEngine); + m_pColorJSProxy = std::make_unique(m_pEngine, m_pConfig); engineGlobalObject.setProperty("color", m_pEngine->newQObject(m_pColorJSProxy.get())); m_pBaClass = new ByteArrayClass(m_pEngine); diff --git a/src/test/controllerengine_test.cpp b/src/test/controllerengine_test.cpp index d84f736a6ff..ccf717dbc8c 100644 --- a/src/test/controllerengine_test.cpp +++ b/src/test/controllerengine_test.cpp @@ -1,13 +1,14 @@ -#include #include +#include #include "control/controlobject.h" #include "control/controlpotmeter.h" -#include "preferences/usersettings.h" -#include "controllers/controllerengine.h" #include "controllers/controllerdebug.h" +#include "controllers/controllerengine.h" #include "controllers/softtakeover.h" +#include "preferences/usersettings.h" #include "test/mixxxtest.h" +#include "util/color/hotcuecolorpalette.h" #include "util/memory.h" #include "util/time.h" @@ -17,7 +18,7 @@ class ControllerEngineTest : public MixxxTest { mixxx::Time::setTestMode(true); mixxx::Time::setTestElapsedTime(mixxx::Duration::fromMillis(10)); QThread::currentThread()->setObjectName("Main"); - cEngine = new ControllerEngine(nullptr); + cEngine = new ControllerEngine(nullptr, config()); pScriptEngine = cEngine->m_pEngine; ControllerDebug::enable(); cEngine->setPopups(false); @@ -618,24 +619,24 @@ TEST_F(ControllerEngineTest, connectionExecutesWithCorrectThisObject) { EXPECT_DOUBLE_EQ(1.0, pass->get()); } -TEST_F(ControllerEngineTest, colorProxy) { - QList allColors = Color::kPredefinedColorsSet.allColors; +TEST_F(ControllerEngineTest, colorProxyTestMixxxPalette) { + QList allColors = HotcueColorPalette::mixxxPalette.m_colorList; for (int i = 0; i < allColors.length(); ++i) { - PredefinedColorPointer color = allColors[i]; - qDebug() << "Testing color " << color->m_sName; - QScriptValue jsColor = pScriptEngine->evaluate("color.predefinedColorFromId(" + QString::number(color->m_iId) + ")"); - EXPECT_EQ(jsColor.property("red").toInt32(), color->m_defaultRgba.red()); - EXPECT_EQ(jsColor.property("green").toInt32(), color->m_defaultRgba.green()); - EXPECT_EQ(jsColor.property("blue").toInt32(), color->m_defaultRgba.blue()); - EXPECT_EQ(jsColor.property("alpha").toInt32(), color->m_defaultRgba.alpha()); - EXPECT_EQ(jsColor.property("id").toInt32(), color->m_iId); - - QScriptValue jsColor2 = pScriptEngine->evaluate("color.predefinedColorsList()[" - + QString::number(i) + "]"); - EXPECT_EQ(jsColor2.property("red").toInt32(), color->m_defaultRgba.red()); - EXPECT_EQ(jsColor2.property("green").toInt32(), color->m_defaultRgba.green()); - EXPECT_EQ(jsColor2.property("blue").toInt32(), color->m_defaultRgba.blue()); - EXPECT_EQ(jsColor2.property("alpha").toInt32(), color->m_defaultRgba.alpha()); - EXPECT_EQ(jsColor2.property("id").toInt32(), color->m_iId); + QColor color = allColors[i]; + qDebug() << "Testing color " << color.name(); + QString colorCode = QString::number(color.rgba()); + QScriptValue jsColor = pScriptEngine->evaluate( + "color.colorFromHexCode(" + colorCode + ")"); + EXPECT_EQ(jsColor.property("red").toInt32(), color.red()); + EXPECT_EQ(jsColor.property("green").toInt32(), color.green()); + EXPECT_EQ(jsColor.property("blue").toInt32(), color.blue()); + EXPECT_EQ(jsColor.property("alpha").toInt32(), color.alpha()); + + QScriptValue jsColor2 = pScriptEngine->evaluate( + "color.hotcueColorPalette()[" + QString::number(i) + "]"); + EXPECT_EQ(jsColor2.property("red").toInt32(), color.red()); + EXPECT_EQ(jsColor2.property("green").toInt32(), color.green()); + EXPECT_EQ(jsColor2.property("blue").toInt32(), color.blue()); + EXPECT_EQ(jsColor2.property("alpha").toInt32(), color.alpha()); } } diff --git a/src/util/color/hotcuecolorpalette.cpp b/src/util/color/hotcuecolorpalette.cpp index ab51fde7a0d..0bac5436bde 100644 --- a/src/util/color/hotcuecolorpalette.cpp +++ b/src/util/color/hotcuecolorpalette.cpp @@ -5,8 +5,7 @@ #include "hotcuecolorpalette.h" const HotcueColorPalette HotcueColorPalette::mixxxPalette = - HotcueColorPalette(QList{ - QColor("#c50a08"), + HotcueColorPalette(QList{QColor("#c50a08"), QColor("#32be44"), QColor("#0044ff"), QColor("#f8d200"), From 66d3ffadfdc2c0d80427db18d115924e12a96934 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sun, 3 Nov 2019 10:10:06 +0100 Subject: [PATCH 010/158] Remove PredefinedColor --- CMakeLists.txt | 1 - build/depends.py | 3 +- src/library/dao/cuedao.cpp | 1 - src/skin/skincontext.h | 1 - src/util/color/color.cpp | 2 - src/util/color/color.h | 4 +- src/util/color/predefinedcolor.cpp | 10 --- src/util/color/predefinedcolor.h | 35 --------- src/util/color/predefinedcolorsset.h | 104 --------------------------- src/widget/wtracktableview.cpp | 1 - 10 files changed, 2 insertions(+), 160 deletions(-) delete mode 100644 src/util/color/predefinedcolor.cpp delete mode 100644 src/util/color/predefinedcolor.h delete mode 100644 src/util/color/predefinedcolorsset.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 24996722a4c..a71a311cea5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -535,7 +535,6 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL src/util/cmdlineargs.cpp src/util/color/color.cpp src/util/color/hotcuecolorpalette.cpp - src/util/color/predefinedcolor.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 221aff9237f..2f8f24d0346 100644 --- a/build/depends.py +++ b/build/depends.py @@ -1305,8 +1305,7 @@ def sources(self, build): "src/util/desktophelper.cpp", "src/util/widgetrendertimer.cpp", "src/util/workerthread.cpp", - "src/util/workerthreadscheduler.cpp", - "src/util/color/predefinedcolor.cpp" + "src/util/workerthreadscheduler.cpp" ] proto_args = { diff --git a/src/library/dao/cuedao.cpp b/src/library/dao/cuedao.cpp index 3b8afb9cbe9..e43859645ee 100644 --- a/src/library/dao/cuedao.cpp +++ b/src/library/dao/cuedao.cpp @@ -11,7 +11,6 @@ #include "library/queryutil.h" #include "util/assert.h" #include "util/performancetimer.h" -#include "util/color/predefinedcolor.h" int CueDAO::cueCount() { qDebug() << "CueDAO::cueCount" << QThread::currentThread() << m_database.connectionName(); diff --git a/src/skin/skincontext.h b/src/skin/skincontext.h index 55e501a32b6..8898b337f35 100644 --- a/src/skin/skincontext.h +++ b/src/skin/skincontext.h @@ -15,7 +15,6 @@ #include "preferences/usersettings.h" #include "skin/pixmapsource.h" #include "util/color/color.h" -#include "util/color/predefinedcolorsrepresentation.h" #include "widget/wsingletoncontainer.h" #include "widget/wpixmapstore.h" diff --git a/src/util/color/color.cpp b/src/util/color/color.cpp index 4627fdf3d9a..92116acb748 100644 --- a/src/util/color/color.cpp +++ b/src/util/color/color.cpp @@ -4,8 +4,6 @@ namespace Color { -const PredefinedColorsSet kPredefinedColorsSet = PredefinedColorsSet(); - // algorithm by http://www.nbdtech.com/Blog/archive/2008/04/27/Calculating-the-Perceived-Brightness-of-a-Color.aspx // NOTE(Swiftb0y): please suggest if I should you use other methods // (like the W3C algorithm) or if this approach is to to performance hungry diff --git a/src/util/color/color.h b/src/util/color/color.h index 13401e05254..e5196a409e7 100644 --- a/src/util/color/color.h +++ b/src/util/color/color.h @@ -1,11 +1,9 @@ #pragma once -#include "util/color/predefinedcolorsset.h" +#include namespace Color { -extern const PredefinedColorsSet kPredefinedColorsSet; - int brightness(int red, int green, int blue); inline int brightness(const QColor& color) { diff --git a/src/util/color/predefinedcolor.cpp b/src/util/color/predefinedcolor.cpp deleted file mode 100644 index 2a5db56e987..00000000000 --- a/src/util/color/predefinedcolor.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "util/color/predefinedcolor.h" - -#include "util/color/color.h" - -PredefinedColor::PredefinedColor(QColor defaultRgba, QString sName, QString sDisplayName, int iId) - : m_defaultRgba(defaultRgba), - m_sName(sName), - m_sDisplayName(sDisplayName), - m_iId(iId) { -} diff --git a/src/util/color/predefinedcolor.h b/src/util/color/predefinedcolor.h deleted file mode 100644 index 4e5745c0883..00000000000 --- a/src/util/color/predefinedcolor.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include - -#include "util/memory.h" - -// The PredefinedColor class is used to represent a Mixxx identificable color. -// A PredefinedColor can be uniquely identified with its m_iId property. -// -// PredefinedColors have a default Rgba value. A PredefinedColorsMap can provide with an alternative -// Rgba value for each PredefinedColor. Thus, a PredefinedColorsMap defines a particular way to render -// the PredefinedColors. -class PredefinedColor final { - public: - PredefinedColor(QColor defaultRgba, QString sName, QString sDisplayName, int iId); - - inline bool operator==(const PredefinedColor& other) const { - return m_iId == other.m_iId; - } - - inline bool operator!=(const PredefinedColor& other) const { - return m_iId != other.m_iId; - } - - // The QColor that is used by default to render this PredefinedColor. - const QColor m_defaultRgba; - // The name of the color used programmatically, e.g. on skin files. - const QString m_sName; - // The name of the color used on UI. - const QString m_sDisplayName; - // An Id uniquely identifying this predefined color. - // This value is used to identify a color on the DB and control objects. - const int m_iId; -}; -typedef std::shared_ptr PredefinedColorPointer; diff --git a/src/util/color/predefinedcolorsset.h b/src/util/color/predefinedcolorsset.h deleted file mode 100644 index f8749f2a3fa..00000000000 --- a/src/util/color/predefinedcolorsset.h +++ /dev/null @@ -1,104 +0,0 @@ -#pragma once - -#include -#include - -#include "util/color/predefinedcolor.h" - -// This class defines a set of predefined colors and provides some handy functions to work with them. -// A single global instance is create in the Color namespace. -// This class is thread-safe because all its methods and public properties are const. -class PredefinedColorsSet final { - public: - const PredefinedColorPointer noColor = std::make_shared( - QColor(), - QLatin1String("No Color"), - QObject::tr("No Color"), - 0); - const PredefinedColorPointer red = std::make_shared( - QColor(0xC50A08), - QLatin1String("Red"), - QObject::tr("Red"), - 1); - const PredefinedColorPointer green = std::make_shared( - QColor(0x32BE44), - QLatin1String("Green"), - QObject::tr("Green"), - 2); - const PredefinedColorPointer blue = std::make_shared( - QColor(0x0044FF), - QLatin1String("Blue"), - QObject::tr("Blue"), - 3); - const PredefinedColorPointer yellow = std::make_shared( - QColor(0xF8D200), - QLatin1String("Yellow"), - QObject::tr("Yellow"), - 4); - const PredefinedColorPointer cyan = std::make_shared( - QColor(0x42D4F4), - QLatin1String("Celeste"), - QObject::tr("Celeste"), - 5); - const PredefinedColorPointer magenta = std::make_shared( - QColor(0xAF00CC), - QLatin1String("Purple"), - QObject::tr("Purple"), - 6); - const PredefinedColorPointer pink = std::make_shared( - QColor(0xFCA6D7), - QLatin1String("Pink"), - QObject::tr("Pink"), - 7); - const PredefinedColorPointer white = std::make_shared( - QColor(0xF2F2FF), - QLatin1String("White"), - QObject::tr("White"), - 8); - - // The list of the predefined colors. - const QList allColors{ - noColor, - red, - green, - yellow, - blue, - cyan, - magenta, - pink, - white, - }; - - // Returns the position of a PredefinedColor in the allColors list. - int predefinedColorIndex(PredefinedColorPointer searchedColor) const { - for (int position = 0; position < allColors.count(); ++position) { - PredefinedColorPointer color(allColors.at(position)); - if (*color == *searchedColor) { - return position; - } - } - return 0; - }; - - // Return a predefined color from its name. - // Return noColor if there's no color with such name. - PredefinedColorPointer predefinedColorFromName(QString name) const { - for (PredefinedColorPointer color : allColors) { - if (color->m_sName == name) { - return color; - } - } - return noColor; - }; - - // Return a predefined color from its id. - // Return noColor if there's no color with iId. - PredefinedColorPointer predefinedColorFromId(int iId) const { - for (PredefinedColorPointer color : allColors) { - if (color->m_iId == iId) { - return color; - } - } - return noColor; - }; -}; diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 6c9a7b25647..d2c2a2e01a5 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -39,7 +39,6 @@ #include "util/assert.h" #include "util/parented_ptr.h" #include "util/desktophelper.h" -#include "util/color/predefinedcolorsset.h" WTrackTableView::WTrackTableView(QWidget * parent, UserSettingsPointer pConfig, From 30b82cf1b4333bbdca4aeced776c4973fbe6b532 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sun, 3 Nov 2019 10:16:50 +0100 Subject: [PATCH 011/158] Update midi-components library and change cue color CO name --- res/controllers/Roland_DJ-505-scripts.js | 12 ++++++------ res/controllers/midi-components-0.0.js | 18 +++++++++--------- res/skins/Deere/hotcue_button.xml | 2 +- res/skins/LateNight/button_hotcue.xml | 2 +- res/skins/Shade/hotcue_button.xml | 2 +- res/skins/Tango/button_hotcue_deck.xml | 2 +- src/engine/controls/cuecontrol.cpp | 2 +- 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/res/controllers/Roland_DJ-505-scripts.js b/res/controllers/Roland_DJ-505-scripts.js index be2ddb4f772..ca091acab03 100644 --- a/res/controllers/Roland_DJ-505-scripts.js +++ b/res/controllers/Roland_DJ-505-scripts.js @@ -1603,7 +1603,7 @@ DJ505.PitchPlayMode = function(deck, offset) { this.number = n + 1; this.on = this.color + DJ505.PadColor.DIM_MODIFIER; this.colors = pitchplayColors; - this.colorIdKey = "hotcue_" + this.number + "_color_id"; + this.colorKey = "hotcue_" + this.number + "_color"; components.Button.call(this); }; this.PerformancePad.prototype = new components.Button({ @@ -1665,8 +1665,8 @@ DJ505.PitchPlayMode = function(deck, offset) { this.outKey = "hotcue_" + this.number + "_enabled"; this.output = function(value, _group, _control) { var outval = this.outValueScale(value); - if (this.colorIdKey !== undefined && outval !== this.off) { - this.outputColor(engine.getValue(this.group, this.colorIdKey)); + if (this.colorKey !== undefined && outval !== this.off) { + this.outputColor(engine.getValue(this.group, this.colorKey)); } else { this.send(DJ505.PadColor.OFF); } @@ -1676,13 +1676,13 @@ DJ505.PitchPlayMode = function(deck, offset) { var previousCuepoint = this.mode.cuepoint; this.mode.cuepoint = this.number; this.mode.pads[previousCuepoint - 1].trigger(); - this.outputColor(engine.getValue(this.group, this.colorIdKey)); + this.outputColor(engine.getValue(this.group, this.colorKey)); } }; this.connect = function() { components.Button.prototype.connect.call(this); // call parent connect - if (undefined !== this.group && this.colorIdKey !== undefined) { - this.connections[1] = engine.makeConnection(this.group, this.colorIdKey, function(id) { + if (undefined !== this.group && this.colorKey !== undefined) { + this.connections[1] = engine.makeConnection(this.group, this.colorKey, function(id) { if (engine.getValue(this.group, this.outKey)) { this.outputColor(id); } diff --git a/res/controllers/midi-components-0.0.js b/res/controllers/midi-components-0.0.js index 2657bb2176e..7db8bd503b6 100644 --- a/res/controllers/midi-components-0.0.js +++ b/res/controllers/midi-components-0.0.js @@ -295,9 +295,9 @@ return; } if (options.colors !== undefined || options.sendRGB !== undefined) { - this.colorIdKey = "hotcue_" + options.number + "_color_id"; + this.colorKey = 'hotcue_' + options.number + '_color'; if (options.colors === undefined) { - options.colors = color.predefinedColorsList(); + options.colors = color.hotcueColorPalette(); } } this.number = options.number; @@ -312,8 +312,8 @@ this.inKey = "hotcue_" + this.number + "_clear"; }, getColor: function() { - if (this.colorIdKey !== undefined) { - return color.predefinedColorFromId(engine.getValue(this.group, this.colorIdKey)); + if (this.colorKey !== undefined) { + return color.colorFromHexCode(engine.getValue(this.group,this.colorKey)); } else { return null; } @@ -324,8 +324,8 @@ // and there is no hotcueColor for turning the LED // off. So the `send()` function is responsible for turning the // actual LED off. - if (this.colorIdKey !== undefined && outval !== this.off) { - this.outputColor(engine.getValue(this.group, this.colorIdKey)); + if (this.colorKey !== undefined && outval !== this.off) { + this.outputColor(engine.getValue(this.group, this.colorKey)); } else { this.send(outval); } @@ -348,9 +348,9 @@ }, connect: function() { Button.prototype.connect.call(this); // call parent connect - if (undefined !== this.group && this.colorIdKey !== undefined) { - this.connections[1] = engine.makeConnection(this.group, this.colorIdKey, function(id) { - if (engine.getValue(this.group, this.outKey)) { + if (undefined !== this.group && this.colorKey !== undefined) { + this.connections[1] = engine.makeConnection(this.group, this.colorKey, function (id) { + if (engine.getValue(this.group,this.outKey)) { this.outputColor(id); } }); diff --git a/res/skins/Deere/hotcue_button.xml b/res/skins/Deere/hotcue_button.xml index b301c6994ed..0cc869e7350 100644 --- a/res/skins/Deere/hotcue_button.xml +++ b/res/skins/Deere/hotcue_button.xml @@ -46,7 +46,7 @@ false - ,hotcue__color_id + ,hotcue__color highlight diff --git a/res/skins/LateNight/button_hotcue.xml b/res/skins/LateNight/button_hotcue.xml index 64765685504..fc9eba27700 100644 --- a/res/skins/LateNight/button_hotcue.xml +++ b/res/skins/LateNight/button_hotcue.xml @@ -37,7 +37,7 @@ false - ,hotcue__color_id + ,hotcue__color highlight diff --git a/res/skins/Shade/hotcue_button.xml b/res/skins/Shade/hotcue_button.xml index cf889c255f9..f31ffdf7b1b 100644 --- a/res/skins/Shade/hotcue_button.xml +++ b/res/skins/Shade/hotcue_button.xml @@ -27,7 +27,7 @@ false - ,hotcue__color_id + ,hotcue__color highlight diff --git a/res/skins/Tango/button_hotcue_deck.xml b/res/skins/Tango/button_hotcue_deck.xml index bb1009dbf42..c858ef7640c 100644 --- a/res/skins/Tango/button_hotcue_deck.xml +++ b/res/skins/Tango/button_hotcue_deck.xml @@ -38,7 +38,7 @@ Variables: false - ,hotcue__color_id + ,hotcue__color highlight diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index 830c4f52b84..66526e30a8b 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -1761,7 +1761,7 @@ HotcueControl::HotcueControl(QString group, int i) m_hotcueEnabled->setReadOnly(); // The id of the predefined color assigned to this color. - m_hotcueColor = new ControlObject(keyForControl(i, "color_id")); + m_hotcueColor = new ControlObject(keyForControl(i, "color")); connect(m_hotcueColor, &ControlObject::valueChanged, this, From 1a3b8aa7ab0c85ff41c70db3c21c49da8922d60b Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sun, 3 Nov 2019 11:04:05 +0100 Subject: [PATCH 012/158] Avoid constructing HotcueColorPaletteSettings every time its used --- src/controllers/colorjsproxy.cpp | 14 +++++++------- src/controllers/colorjsproxy.h | 11 ++++++----- src/controllers/controllerengine.cpp | 3 ++- src/engine/controls/cuecontrol.cpp | 5 +++-- src/engine/controls/cuecontrol.h | 4 +++- src/preferences/hotcuecolorpalettesettings.h | 2 +- 6 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/controllers/colorjsproxy.cpp b/src/controllers/colorjsproxy.cpp index 8b2f2fd644e..bbce727f5c0 100644 --- a/src/controllers/colorjsproxy.cpp +++ b/src/controllers/colorjsproxy.cpp @@ -1,11 +1,12 @@ #include "controllers/colorjsproxy.h" #include "preferences/hotcuecolorpalettesettings.h" -ColorJSProxy::ColorJSProxy( - QScriptEngine* pScriptEngine, UserSettingsPointer pConfig) +ColorJSProxy::ColorJSProxy(QScriptEngine* pScriptEngine, + HotcueColorPaletteSettings colorPaletteSettings) : m_pScriptEngine(pScriptEngine), - m_hotcueColorPalette(makeHotcueColorPalette(pScriptEngine, pConfig)), - m_pConfig(pConfig) { + m_hotcueColorPalette( + makeHotcueColorPalette(pScriptEngine, colorPaletteSettings)), + m_colorPaletteSettings(colorPaletteSettings) { } ColorJSProxy::~ColorJSProxy() = default; @@ -24,10 +25,9 @@ QScriptValue ColorJSProxy::colorFromHexCode(uint colorCode) { return jsColor; } -QScriptValue ColorJSProxy::makeHotcueColorPalette( - QScriptEngine* pScriptEngine, UserSettingsPointer pConfig) { +QScriptValue ColorJSProxy::makeHotcueColorPalette(QScriptEngine* pScriptEngine, + HotcueColorPaletteSettings colorPaletteSettings) { // TODO: make sure we get notified when the palette changes - HotcueColorPaletteSettings colorPaletteSettings(pConfig); QList colorList = colorPaletteSettings.getHotcueColorPalette().m_colorList; int numColors = colorList.length(); diff --git a/src/controllers/colorjsproxy.h b/src/controllers/colorjsproxy.h index 61a801b4617..abeddcf1684 100644 --- a/src/controllers/colorjsproxy.h +++ b/src/controllers/colorjsproxy.h @@ -5,13 +5,14 @@ #include #include -#include "preferences/usersettings.h" +#include "preferences/hotcuecolorpalettesettings.h" #include "util/color/color.h" class ColorJSProxy final : public QObject { Q_OBJECT public: - ColorJSProxy(QScriptEngine* pScriptEngine, UserSettingsPointer pConfig); + ColorJSProxy(QScriptEngine* pScriptEngine, + HotcueColorPaletteSettings colorPaletteSettings); ~ColorJSProxy() override; @@ -22,11 +23,11 @@ class ColorJSProxy final : public QObject { Q_INVOKABLE QScriptValue colorFromHexCode(uint colorCode); private: - QScriptValue makeHotcueColorPalette( - QScriptEngine* pScriptEngine, UserSettingsPointer pConfig); + QScriptValue makeHotcueColorPalette(QScriptEngine* pScriptEngine, + HotcueColorPaletteSettings colorPaletteSettings); QScriptEngine* m_pScriptEngine; QScriptValue m_hotcueColorPalette; - UserSettingsPointer m_pConfig; + HotcueColorPaletteSettings m_colorPaletteSettings; }; #endif /* COLORJSPROXY_H */ diff --git a/src/controllers/controllerengine.cpp b/src/controllers/controllerengine.cpp index 320a8cfda4a..961dbc2a947 100644 --- a/src/controllers/controllerengine.cpp +++ b/src/controllers/controllerengine.cpp @@ -215,7 +215,8 @@ void ControllerEngine::initializeScriptEngine() { engineGlobalObject.setProperty("midi", m_pEngine->newQObject(m_pController)); } - m_pColorJSProxy = std::make_unique(m_pEngine, m_pConfig); + m_pColorJSProxy = std::make_unique( + m_pEngine, HotcueColorPaletteSettings(m_pConfig)); engineGlobalObject.setProperty("color", m_pEngine->newQObject(m_pColorJSProxy.get())); m_pBaClass = new ByteArrayClass(m_pEngine); diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index 66526e30a8b..6d2ff1c3d8d 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -27,6 +27,7 @@ CueControl::CueControl(QString group, UserSettingsPointer pConfig) : EngineControl(group, pConfig), m_pConfig(pConfig), + m_colorPaletteSettings(HotcueColorPaletteSettings(pConfig)), m_bPreviewing(false), // m_pPlay->toBoo() -> engine play state // m_pPlay->set(1.0) -> emulate play button press @@ -601,8 +602,8 @@ void CueControl::hotcueSet(HotcueControl* pControl, double v) { ConfigKey autoHotcueColorsKey("[Controls]", "auto_hotcue_colors"); if (getConfig()->getValue(autoHotcueColorsKey, false)) { - HotcueColorPaletteSettings colorPaletteSettings(getConfig()); - auto hotcueColorPalette = colorPaletteSettings.getHotcueColorPalette(); + auto hotcueColorPalette = + m_colorPaletteSettings.getHotcueColorPalette(); auto colors = hotcueColorPalette.m_colorList; pCue->setColor(colors.at((hotcue % (colors.count() - 1)) + 1)); }; diff --git a/src/engine/controls/cuecontrol.h b/src/engine/controls/cuecontrol.h index e90b344f1e1..414191fdf06 100644 --- a/src/engine/controls/cuecontrol.h +++ b/src/engine/controls/cuecontrol.h @@ -7,9 +7,10 @@ #include #include +#include "control/controlproxy.h" #include "engine/controls/enginecontrol.h" +#include "preferences/hotcuecolorpalettesettings.h" #include "preferences/usersettings.h" -#include "control/controlproxy.h" #include "track/track.h" #define NUM_HOT_CUES 37 @@ -194,6 +195,7 @@ class CueControl : public EngineControl { TrackAt getTrackAt() const; UserSettingsPointer m_pConfig; + HotcueColorPaletteSettings m_colorPaletteSettings; bool m_bPreviewing; ControlObject* m_pPlay; ControlObject* m_pStopButton; diff --git a/src/preferences/hotcuecolorpalettesettings.h b/src/preferences/hotcuecolorpalettesettings.h index ad28c5ec807..fb1891e32c3 100644 --- a/src/preferences/hotcuecolorpalettesettings.h +++ b/src/preferences/hotcuecolorpalettesettings.h @@ -5,7 +5,7 @@ class HotcueColorPaletteSettings { public: - HotcueColorPaletteSettings(UserSettingsPointer pConfig) + explicit HotcueColorPaletteSettings(UserSettingsPointer pConfig) : m_pConfig(pConfig) { } From 7a5d13f08c2dc4e5a69757656c47264bfddca7ed Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Mon, 4 Nov 2019 09:14:37 +0100 Subject: [PATCH 013/158] Change test names --- src/test/colorconfig_test.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/test/colorconfig_test.cpp b/src/test/colorconfig_test.cpp index fc95fec6573..e3fd79c72c2 100644 --- a/src/test/colorconfig_test.cpp +++ b/src/test/colorconfig_test.cpp @@ -8,7 +8,7 @@ class ColorConfigTest : public MixxxTest {}; -TEST_F(ColorConfigTest, TestSavingColorWithoutAlpha) { +TEST_F(ColorConfigTest, SavingColorWithoutAlpha) { ConfigKey key("[Color]", "color"); QColor originalColor("#FF9900"); config()->setValue(key, originalColor); @@ -17,7 +17,7 @@ TEST_F(ColorConfigTest, TestSavingColorWithoutAlpha) { ASSERT_EQ(originalColor, colorFromConfig); } -TEST_F(ColorConfigTest, TestSavingColorWithAlpha) { +TEST_F(ColorConfigTest, SavingColorWithAlpha) { ConfigKey key("[Color]", "color"); QColor originalColor("#66FF9900"); config()->setValue(key, originalColor); @@ -26,14 +26,14 @@ TEST_F(ColorConfigTest, TestSavingColorWithAlpha) { ASSERT_EQ(originalColor, colorFromConfig); } -TEST_F(ColorConfigTest, TestDefaultColorWhenNoStoredColor) { +TEST_F(ColorConfigTest, GetDefaultColorWhenNoStoredColor) { ConfigKey key("[Color]", "color"); QColor defaultColor("#66FF9900"); QColor colorFromConfig = config()->getValue(key, defaultColor); ASSERT_EQ(defaultColor, colorFromConfig); } -TEST_F(ColorConfigTest, TestSaveColorPalette) { +TEST_F(ColorConfigTest, SaveColorPalette) { HotcueColorPaletteSettings colorPaletteSettings(config()); HotcueColorPalette originalColorPalette(QList{ QColor("#66FF9900"), @@ -49,7 +49,7 @@ TEST_F(ColorConfigTest, TestSaveColorPalette) { ASSERT_EQ(originalColorPalette, colorPaletteFromConfig); } -TEST_F(ColorConfigTest, TestReplaceColorPalette) { +TEST_F(ColorConfigTest, ReplaceColorPalette) { HotcueColorPaletteSettings colorPaletteSettings(config()); HotcueColorPalette colorPalette1(QList{ QColor("#66FF9900"), @@ -71,9 +71,9 @@ TEST_F(ColorConfigTest, TestReplaceColorPalette) { ASSERT_EQ(colorPalette2, colorPaletteFromConfig); } -TEST_F(ColorConfigTest, TestDefaultColorPalette) { +TEST_F(ColorConfigTest, DefaultColorPalette) { HotcueColorPaletteSettings colorPaletteSettings(config()); HotcueColorPalette colorPaletteFromConfig = colorPaletteSettings.getHotcueColorPalette(); ASSERT_EQ(HotcueColorPalette::mixxxPalette, colorPaletteFromConfig); -} \ No newline at end of file +} From 23e114f5d25bd354d3b38e63bc22c62f3a2d8b78 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Mon, 4 Nov 2019 09:30:01 +0100 Subject: [PATCH 014/158] Reorder constructor parameters --- src/library/dlgtrackinfo.cpp | 2 +- src/library/dlgtrackinfo.h | 2 +- src/widget/wtracktableview.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/library/dlgtrackinfo.cpp b/src/library/dlgtrackinfo.cpp index 1df502769fa..7844a865bad 100644 --- a/src/library/dlgtrackinfo.cpp +++ b/src/library/dlgtrackinfo.cpp @@ -24,7 +24,7 @@ const int kMinBpm = 30; // Maximum allowed interval between beats (calculated from kMinBpm). const mixxx::Duration kMaxInterval = mixxx::Duration::fromMillis(1000.0 * (60.0 / kMinBpm)); -DlgTrackInfo::DlgTrackInfo(UserSettingsPointer pConfig, QWidget* parent) +DlgTrackInfo::DlgTrackInfo(QWidget* parent, UserSettingsPointer pConfig) : QDialog(parent), m_pTapFilter(new TapFilter(this, kFilterLength, kMaxInterval)), m_dLastTapedBpm(-1.), diff --git a/src/library/dlgtrackinfo.h b/src/library/dlgtrackinfo.h index 341de08ad08..a52904790c6 100644 --- a/src/library/dlgtrackinfo.h +++ b/src/library/dlgtrackinfo.h @@ -18,7 +18,7 @@ class DlgTrackInfo : public QDialog, public Ui::DlgTrackInfo { Q_OBJECT public: - DlgTrackInfo(UserSettingsPointer pConfig, QWidget* parent); + DlgTrackInfo(QWidget* parent, UserSettingsPointer pConfig); virtual ~DlgTrackInfo(); public slots: diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index d2c2a2e01a5..740e8d08258 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -752,7 +752,7 @@ void WTrackTableView::showTrackInfo(QModelIndex index) { if (m_pTrackInfo.isNull()) { // Give a NULL parent because otherwise it inherits our style which can // make it unreadable. Bug #673411 - m_pTrackInfo.reset(new DlgTrackInfo(m_pConfig, nullptr)); + m_pTrackInfo.reset(new DlgTrackInfo(nullptr, m_pConfig)); connect(m_pTrackInfo.data(), SIGNAL(next()), this, SLOT(slotNextTrackInfo())); From 0ef7da41f6a2765e1817c58b4432bf02bf530a31 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Mon, 4 Nov 2019 09:34:13 +0100 Subject: [PATCH 015/158] Rename member variable --- src/controllers/colorjsproxy.cpp | 4 ++-- src/controllers/colorjsproxy.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/controllers/colorjsproxy.cpp b/src/controllers/colorjsproxy.cpp index bbce727f5c0..f7ef331f704 100644 --- a/src/controllers/colorjsproxy.cpp +++ b/src/controllers/colorjsproxy.cpp @@ -4,7 +4,7 @@ ColorJSProxy::ColorJSProxy(QScriptEngine* pScriptEngine, HotcueColorPaletteSettings colorPaletteSettings) : m_pScriptEngine(pScriptEngine), - m_hotcueColorPalette( + m_JsHotcueColorPalette( makeHotcueColorPalette(pScriptEngine, colorPaletteSettings)), m_colorPaletteSettings(colorPaletteSettings) { } @@ -12,7 +12,7 @@ ColorJSProxy::ColorJSProxy(QScriptEngine* pScriptEngine, ColorJSProxy::~ColorJSProxy() = default; Q_INVOKABLE QScriptValue ColorJSProxy::hotcueColorPalette() { - return m_hotcueColorPalette; + return m_JsHotcueColorPalette; } QScriptValue ColorJSProxy::colorFromHexCode(uint colorCode) { diff --git a/src/controllers/colorjsproxy.h b/src/controllers/colorjsproxy.h index abeddcf1684..dda4d693798 100644 --- a/src/controllers/colorjsproxy.h +++ b/src/controllers/colorjsproxy.h @@ -26,7 +26,7 @@ class ColorJSProxy final : public QObject { QScriptValue makeHotcueColorPalette(QScriptEngine* pScriptEngine, HotcueColorPaletteSettings colorPaletteSettings); QScriptEngine* m_pScriptEngine; - QScriptValue m_hotcueColorPalette; + QScriptValue m_JsHotcueColorPalette; HotcueColorPaletteSettings m_colorPaletteSettings; }; From bbc45039679110475e85ce06f0ec61416f0a6d10 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Mon, 4 Nov 2019 09:50:15 +0100 Subject: [PATCH 016/158] Rename some color related classes --- CMakeLists.txt | 2 +- build/depends.py | 2 +- src/engine/controls/cuecontrol.cpp | 6 +-- src/library/dlgtrackinfo.cpp | 2 +- .../hotcuecolorpalettesettings.cpp | 8 ++-- src/preferences/hotcuecolorpalettesettings.h | 6 +-- src/test/colorconfig_test.cpp | 16 ++++---- src/test/controllerengine_test.cpp | 4 +- ...otcuecolorpalette.cpp => colorpalette.cpp} | 10 ++--- src/util/color/colorpalette.h | 40 +++++++++++++++++++ src/widget/wcolorpicker.cpp | 4 +- src/widget/wcolorpicker.h | 6 +-- src/widget/wcuemenupopup.h | 2 +- 13 files changed, 72 insertions(+), 36 deletions(-) rename src/util/color/{hotcuecolorpalette.cpp => colorpalette.cpp} (54%) create mode 100644 src/util/color/colorpalette.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a71a311cea5..af9b88af50c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -534,7 +534,7 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL src/util/cache.cpp src/util/cmdlineargs.cpp src/util/color/color.cpp - src/util/color/hotcuecolorpalette.cpp + src/util/color/colorpalette.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 2f8f24d0346..ac62b65794a 100644 --- a/build/depends.py +++ b/build/depends.py @@ -1278,7 +1278,7 @@ def sources(self, build): "src/util/cache.cpp", "src/util/console.cpp", "src/util/color/color.cpp", - "src/util/color/hotcuecolorpalette.cpp", + "src/util/color/colorpalette.cpp", "src/util/db/dbconnection.cpp", "src/util/db/dbconnectionpool.cpp", "src/util/db/dbconnectionpooler.cpp", diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index 6d2ff1c3d8d..f89718376e1 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -1693,8 +1693,8 @@ void CueControl::hotcueFocusColorPrev(double v) { QColor color = pControl->getColor(); DEBUG_ASSERT(color.isValid()); - HotcueColorPaletteSettings colorPaletteSettings(m_pConfig); - HotcueColorPalette colorPalette = colorPaletteSettings.getHotcueColorPalette(); + HotcueColorPaletteSettings m_colorPaletteSettings(m_pConfig); + ColorPalette colorPalette = m_colorPaletteSettings.getHotcueColorPalette(); // Get previous color in color set int iColorIndex = colorPalette.indexOf(color) - 1; @@ -1725,7 +1725,7 @@ void CueControl::hotcueFocusColorNext(double v) { DEBUG_ASSERT(color.isValid()); HotcueColorPaletteSettings colorPaletteSettings(m_pConfig); - HotcueColorPalette colorPalette = colorPaletteSettings.getHotcueColorPalette(); + ColorPalette colorPalette = colorPaletteSettings.getHotcueColorPalette(); // Get previous color in color set int iColorIndex = colorPalette.indexOf(color) + 1; diff --git a/src/library/dlgtrackinfo.cpp b/src/library/dlgtrackinfo.cpp index 7844a865bad..df5e27a2d21 100644 --- a/src/library/dlgtrackinfo.cpp +++ b/src/library/dlgtrackinfo.cpp @@ -13,7 +13,7 @@ #include "track/cue.h" #include "track/keyfactory.h" #include "track/keyutils.h" -#include "util/color/hotcuecolorpalette.h" +#include "util/color/colorpalette.h" #include "util/compatibility.h" #include "util/desktophelper.h" #include "util/duration.h" diff --git a/src/preferences/hotcuecolorpalettesettings.cpp b/src/preferences/hotcuecolorpalettesettings.cpp index b6a745606c0..4faf0f93086 100644 --- a/src/preferences/hotcuecolorpalettesettings.cpp +++ b/src/preferences/hotcuecolorpalettesettings.cpp @@ -2,7 +2,7 @@ const QString HotcueColorPaletteSettings::sGroup = "[HotcueColorPalette]"; -HotcueColorPalette HotcueColorPaletteSettings::getHotcueColorPalette() const { +ColorPalette HotcueColorPaletteSettings::getHotcueColorPalette() const { QList colorList; for (const ConfigKey& key : m_pConfig->getKeysWithGroup(sGroup)) { QColor color = m_pConfig->getValue(key); @@ -13,14 +13,14 @@ HotcueColorPalette HotcueColorPaletteSettings::getHotcueColorPalette() const { // If no palette is defined in the settings, we use the default one. if (colorList.isEmpty()) { - return HotcueColorPalette::mixxxPalette; + return ColorPalette::mixxxPalette; } return colorList; } void HotcueColorPaletteSettings::setHotcueColorPalette( - const HotcueColorPalette& colorPalette) { + const ColorPalette& colorPalette) { removePalette(); for (int index = 0; index < colorPalette.m_colorList.count(); ++index) { @@ -33,4 +33,4 @@ void HotcueColorPaletteSettings::removePalette() { for (const ConfigKey& key : m_pConfig->getKeysWithGroup(sGroup)) { m_pConfig->remove(key); } -} \ No newline at end of file +} diff --git a/src/preferences/hotcuecolorpalettesettings.h b/src/preferences/hotcuecolorpalettesettings.h index fb1891e32c3..9ed134146a2 100644 --- a/src/preferences/hotcuecolorpalettesettings.h +++ b/src/preferences/hotcuecolorpalettesettings.h @@ -1,7 +1,7 @@ #pragma once #include "preferences/usersettings.h" -#include "util/color/hotcuecolorpalette.h" +#include "util/color/colorpalette.h" class HotcueColorPaletteSettings { public: @@ -9,9 +9,9 @@ class HotcueColorPaletteSettings { : m_pConfig(pConfig) { } - HotcueColorPalette getHotcueColorPalette() const; + ColorPalette getHotcueColorPalette() const; - void setHotcueColorPalette(const HotcueColorPalette& colorPalette); + void setHotcueColorPalette(const ColorPalette& colorPalette); private: static const QString sGroup; diff --git a/src/test/colorconfig_test.cpp b/src/test/colorconfig_test.cpp index e3fd79c72c2..477bab40a52 100644 --- a/src/test/colorconfig_test.cpp +++ b/src/test/colorconfig_test.cpp @@ -4,7 +4,7 @@ #include "test/mixxxtest.h" #include -#include +#include class ColorConfigTest : public MixxxTest {}; @@ -35,7 +35,7 @@ TEST_F(ColorConfigTest, GetDefaultColorWhenNoStoredColor) { TEST_F(ColorConfigTest, SaveColorPalette) { HotcueColorPaletteSettings colorPaletteSettings(config()); - HotcueColorPalette originalColorPalette(QList{ + ColorPalette originalColorPalette(QList{ QColor("#66FF9900"), QColor("#FF9900"), QColor("#00000000"), @@ -44,20 +44,20 @@ TEST_F(ColorConfigTest, SaveColorPalette) { ConfigKey key("[ColorPalette]", "colorPalette"); colorPaletteSettings.setHotcueColorPalette(originalColorPalette); saveAndReloadConfig(); - HotcueColorPalette colorPaletteFromConfig = + ColorPalette colorPaletteFromConfig = colorPaletteSettings.getHotcueColorPalette(); ASSERT_EQ(originalColorPalette, colorPaletteFromConfig); } TEST_F(ColorConfigTest, ReplaceColorPalette) { HotcueColorPaletteSettings colorPaletteSettings(config()); - HotcueColorPalette colorPalette1(QList{ + ColorPalette colorPalette1(QList{ QColor("#66FF9900"), QColor("#FF9900"), QColor("#00000000"), QColor("#FFFFFF"), }); - HotcueColorPalette colorPalette2(QList{ + ColorPalette colorPalette2(QList{ QColor("#0000FF"), QColor("#FF0000"), }); @@ -66,14 +66,14 @@ TEST_F(ColorConfigTest, ReplaceColorPalette) { saveAndReloadConfig(); colorPaletteSettings.setHotcueColorPalette(colorPalette2); saveAndReloadConfig(); - HotcueColorPalette colorPaletteFromConfig = + ColorPalette colorPaletteFromConfig = colorPaletteSettings.getHotcueColorPalette(); ASSERT_EQ(colorPalette2, colorPaletteFromConfig); } TEST_F(ColorConfigTest, DefaultColorPalette) { HotcueColorPaletteSettings colorPaletteSettings(config()); - HotcueColorPalette colorPaletteFromConfig = + ColorPalette colorPaletteFromConfig = colorPaletteSettings.getHotcueColorPalette(); - ASSERT_EQ(HotcueColorPalette::mixxxPalette, colorPaletteFromConfig); + ASSERT_EQ(ColorPalette::mixxxHotcuesPalette, colorPaletteFromConfig); } diff --git a/src/test/controllerengine_test.cpp b/src/test/controllerengine_test.cpp index ccf717dbc8c..ea6a9ad0117 100644 --- a/src/test/controllerengine_test.cpp +++ b/src/test/controllerengine_test.cpp @@ -8,7 +8,7 @@ #include "controllers/softtakeover.h" #include "preferences/usersettings.h" #include "test/mixxxtest.h" -#include "util/color/hotcuecolorpalette.h" +#include "util/color/colorpalette.h" #include "util/memory.h" #include "util/time.h" @@ -620,7 +620,7 @@ TEST_F(ControllerEngineTest, connectionExecutesWithCorrectThisObject) { } TEST_F(ControllerEngineTest, colorProxyTestMixxxPalette) { - QList allColors = HotcueColorPalette::mixxxPalette.m_colorList; + QList allColors = ColorPalette::mixxxPalette.m_colorList; for (int i = 0; i < allColors.length(); ++i) { QColor color = allColors[i]; qDebug() << "Testing color " << color.name(); diff --git a/src/util/color/hotcuecolorpalette.cpp b/src/util/color/colorpalette.cpp similarity index 54% rename from src/util/color/hotcuecolorpalette.cpp rename to src/util/color/colorpalette.cpp index 0bac5436bde..3f16c8f676d 100644 --- a/src/util/color/hotcuecolorpalette.cpp +++ b/src/util/color/colorpalette.cpp @@ -1,11 +1,7 @@ -// -// Created by Ferran Pujol Camins on 27/10/2019. -// +#include "colorpalette.h" -#include "hotcuecolorpalette.h" - -const HotcueColorPalette HotcueColorPalette::mixxxPalette = - HotcueColorPalette(QList{QColor("#c50a08"), +const ColorPalette ColorPalette::mixxxPalette = + ColorPalette(QList{QColor("#c50a08"), QColor("#32be44"), QColor("#0044ff"), QColor("#f8d200"), diff --git a/src/util/color/colorpalette.h b/src/util/color/colorpalette.h new file mode 100644 index 00000000000..5bd2eb836d8 --- /dev/null +++ b/src/util/color/colorpalette.h @@ -0,0 +1,40 @@ +#pragma once + +#include +#include + +class ColorPalette { + public: + ColorPalette(QList colorList) + : m_colorList(colorList) { + } + + QColor at(int i) const { + return m_colorList.at(i); + } + + int size() const { + return m_colorList.size(); + } + + int indexOf(QColor color) const { + return m_colorList.indexOf(color); + } + + QList::const_iterator begin() const { + return m_colorList.begin(); + } + + QList::const_iterator end() const { + return m_colorList.end(); + } + + static const ColorPalette mixxxPalette; + + QList m_colorList; +}; + +inline bool operator==( + const ColorPalette& lhs, const ColorPalette& rhs) { + return lhs.m_colorList == rhs.m_colorList; +} diff --git a/src/widget/wcolorpicker.cpp b/src/widget/wcolorpicker.cpp index 10e2257f764..717ea97a27f 100644 --- a/src/widget/wcolorpicker.cpp +++ b/src/widget/wcolorpicker.cpp @@ -14,7 +14,7 @@ namespace { WColorPicker::WColorPicker(ColorOption colorOption, QWidget* parent) : QWidget(parent), m_colorOption(colorOption), - m_palette(HotcueColorPalette::mixxxPalette) { + m_palette(ColorPalette::mixxxPalette) { QGridLayout* pLayout = new QGridLayout(); pLayout->setMargin(0); pLayout->setContentsMargins(0, 0, 0, 0); @@ -139,7 +139,7 @@ void WColorPicker::setSelectedColor(const QColor& color) { pButton->style()->polish(pButton); } -void WColorPicker::useColorSet(const HotcueColorPalette& palette) { +void WColorPicker::useColorSet(const ColorPalette& palette) { for (int i = 0; i < m_colorButtons.size(); ++i) { int j = i; if (m_colorOption == ColorOption::AllowNoColor) { diff --git a/src/widget/wcolorpicker.h b/src/widget/wcolorpicker.h index 0e7befac1b7..cb3d45e6b32 100644 --- a/src/widget/wcolorpicker.h +++ b/src/widget/wcolorpicker.h @@ -7,7 +7,7 @@ #include #include "util/color/color.h" -#include "util/color/hotcuecolorpalette.h" +#include "util/color/colorpalette.h" class WColorPicker : public QWidget { Q_OBJECT @@ -21,7 +21,7 @@ class WColorPicker : public QWidget { void resetSelectedColor(); void setSelectedColor(const QColor& color); - void useColorSet(const HotcueColorPalette& palette); + void useColorSet(const ColorPalette& palette); signals: void colorPicked(QColor color); @@ -33,7 +33,7 @@ class WColorPicker : public QWidget { void addColorButton(const QColor& color, QGridLayout* pLayout, int row, int column); ColorOption m_colorOption; QColor m_selectedColor; - HotcueColorPalette m_palette; + ColorPalette m_palette; QList m_colorButtons; QStyle* m_pStyle; }; diff --git a/src/widget/wcuemenupopup.h b/src/widget/wcuemenupopup.h index e9d7a932744..1861a82203b 100644 --- a/src/widget/wcuemenupopup.h +++ b/src/widget/wcuemenupopup.h @@ -23,7 +23,7 @@ class WCueMenuPopup : public QWidget { void setTrackAndCue(TrackPointer pTrack, CuePointer pCue); - void useColorSet(const HotcueColorPalette& palette) { + void useColorSet(const ColorPalette& palette) { if (m_pColorPicker != nullptr) { m_pColorPicker->useColorSet(palette); } From 22593219b6444e8c0797d8e763533db4fc14d8c6 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Mon, 4 Nov 2019 10:15:40 +0100 Subject: [PATCH 017/158] Remove cues tab on TrackInfo --- src/library/dlgtrackinfo.cpp | 240 ----------------------------------- src/library/dlgtrackinfo.h | 5 - src/library/dlgtrackinfo.ui | 102 ++------------- 3 files changed, 12 insertions(+), 335 deletions(-) diff --git a/src/library/dlgtrackinfo.cpp b/src/library/dlgtrackinfo.cpp index df5e27a2d21..9a4429be713 100644 --- a/src/library/dlgtrackinfo.cpp +++ b/src/library/dlgtrackinfo.cpp @@ -40,7 +40,6 @@ DlgTrackInfo::~DlgTrackInfo() { void DlgTrackInfo::init() { setupUi(this); - cueTable->hideColumn(0); coverBox->insertWidget(1, m_pWCoverArtLabel); connect(btnNext, &QPushButton::clicked, this, &DlgTrackInfo::slotNext); @@ -93,14 +92,6 @@ void DlgTrackInfo::init() { this, &DlgTrackInfo::slotKeyTextChanged); - connect(btnCueActivate, - &QPushButton::clicked, - this, - &DlgTrackInfo::cueActivate); - connect(btnCueDelete, - &QPushButton::clicked, - this, - &DlgTrackInfo::cueDelete); connect(bpmTap, &QPushButton::pressed, m_pTapFilter.data(), @@ -166,39 +157,6 @@ void DlgTrackInfo::slotPrev() { emit previous(); } -void DlgTrackInfo::cueActivate() { - -} - -void DlgTrackInfo::cueDelete() { - QList selected = cueTable->selectedItems(); - QListIterator item_it(selected); - - QSet rowsToDelete; - while(item_it.hasNext()) { - QTableWidgetItem* item = item_it.next(); - rowsToDelete.insert(item->row()); - } - - // TODO: QList::fromSet(const QSet&) is deprecated and should be - // replaced with QList(set.begin(), set.end()). - // However, the proposed alternative has just been introduced in Qt - // 5.14. Until the minimum required Qt version of Mixx is increased, - // we need a version check here -#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) - QList rowsList = QList(rowsToDelete.begin(), rowsToDelete.end()); -#else - QList rowsList = QList::fromSet(rowsToDelete); -#endif - std::sort(rowsList.begin(), rowsList.end()); - - QListIterator it(rowsList); - it.toBack(); - while (it.hasPrevious()) { - cueTable->removeRow(it.previous()); - } -} - void DlgTrackInfo::populateFields(const Track& track) { setWindowTitle(track.getArtist() % " - " % track.getTitle()); @@ -267,7 +225,6 @@ void DlgTrackInfo::loadTrack(TrackPointer pTrack) { m_pLoadedTrack = pTrack; populateFields(*m_pLoadedTrack); - populateCues(m_pLoadedTrack); m_pWCoverArtLabel->loadTrack(m_pLoadedTrack); // We already listen to changed() so we don't need to listen to individual @@ -319,131 +276,6 @@ void DlgTrackInfo::slotOpenInFileBrowser() { mixxx::DesktopHelper::openInFileBrowser(QStringList(m_pLoadedTrack->getLocation())); } -void DlgTrackInfo::populateCues(TrackPointer pTrack) { - int sampleRate = pTrack->getSampleRate(); - - QList listPoints; - const QList cuePoints = pTrack->getCuePoints(); - QListIterator it(cuePoints); - while (it.hasNext()) { - CuePointer pCue = it.next(); - Cue::Type type = pCue->getType(); - if (type == Cue::Type::HotCue || type == Cue::Type::MainCue || type == Cue::Type::Intro - || type == Cue::Type::Outro) { - listPoints.push_back(pCue); - } - } - it = QListIterator(listPoints); - cueTable->setSortingEnabled(false); - int row = 0; - - while (it.hasNext()) { - CuePointer pCue(it.next()); - - QString rowStr = QString("%1").arg(row); - - // All hotcues are stored in Cue's as 0-indexed, but the GUI presents - // them to the user as 1-indexex. Add 1 here. rryan 9/2010 - int iHotcue = pCue->getHotCue() + 1; - QString hotcue = ""; - hotcue = QString("%1").arg(iHotcue); - double position = pCue->getPosition(); - if (position == -1) { - continue; - } - - double totalSeconds = position / sampleRate / 2.0; - - bool negative = false; - if (totalSeconds < 0) { - totalSeconds *= -1; - negative = true; - } - - int iTotalSeconds = static_cast(totalSeconds); - int fraction = 100 * (totalSeconds - iTotalSeconds); - int seconds = iTotalSeconds % 60; - int mins = iTotalSeconds / 60; - //int hours = mins / 60; //Not going to worry about this for now. :) - - //Construct a nicely formatted duration string now. - QString duration = QString("%1%2:%3.%4").arg( - negative ? QString("-") : QString(), - QString::number(mins), - QString("%1").arg(seconds, 2, 10, QChar('0')), - QString("%1").arg(fraction, 2, 10, QChar('0'))); - - QTableWidgetItem* durationItem = new QTableWidgetItem(duration); - // Make the duration read only - durationItem->setFlags(Qt::NoItemFlags); - - // Decode cue type to display text - QString cueType; - switch (pCue->getType()) { - case Cue::Type::Invalid: - cueType = "?"; - break; - case Cue::Type::HotCue: - cueType = "Hotcue"; - break; - case Cue::Type::MainCue: - cueType = "Main Cue"; - break; - case Cue::Type::Beat: - cueType = "Beat"; - break; - case Cue::Type::Loop: - cueType = "Loop"; - break; - case Cue::Type::Jump: - cueType = "Jump"; - break; - case Cue::Type::Intro: - cueType = "Intro"; - break; - case Cue::Type::Outro: - cueType = "Outro"; - break; - default: - break; - } - - QTableWidgetItem* typeItem = new QTableWidgetItem(cueType); - // Make the type read only - typeItem->setFlags(Qt::NoItemFlags); - - HotcueColorPaletteSettings colorPaletteSettings(m_pConfig); - auto colorPalette = colorPaletteSettings.getHotcueColorPalette(); - QList hotcueColorList = - colorPaletteSettings.getHotcueColorPalette().m_colorList; - QComboBox* colorComboBox = new QComboBox(); - for (int i = 0; i < hotcueColorList.count(); i++) { - QColor color = hotcueColorList.at(i); - colorComboBox->addItem("", color); - QPixmap pixmap(80, 80); - pixmap.fill(color); - QIcon icon(pixmap); - colorComboBox->setItemIcon(i, icon); - } - QColor cueColor = pCue->getColor(); - int colorIndex = hotcueColorList.indexOf(cueColor); - colorComboBox->setCurrentIndex(math_min(colorIndex, 0)); - - m_cueMap[row] = pCue; - cueTable->insertRow(row); - cueTable->setItem(row, 0, new QTableWidgetItem(rowStr)); - cueTable->setItem(row, 1, durationItem); - cueTable->setItem(row, 2, typeItem); - cueTable->setItem(row, 3, new QTableWidgetItem(hotcue)); - cueTable->setCellWidget(row, 4, colorComboBox); - cueTable->setItem(row, 5, new QTableWidgetItem(pCue->getLabel())); - row += 1; - } - cueTable->setSortingEnabled(true); - cueTable->horizontalHeader()->setStretchLastSection(true); - cueTable->horizontalHeader()->setSectionResizeMode(3, QHeaderView::ResizeToContents); -} - void DlgTrackInfo::saveTrack() { if (!m_pLoadedTrack) return; @@ -478,74 +310,6 @@ void DlgTrackInfo::saveTrack() { slotKeyTextChanged(); m_pLoadedTrack->setKeys(m_keysClone); - - QSet updatedRows; - for (int row = 0; row < cueTable->rowCount(); ++row) { - QTableWidgetItem* rowItem = cueTable->item(row, 0); - QTableWidgetItem* hotcueItem = cueTable->item(row, 3); - QWidget* colorWidget = cueTable->cellWidget(row, 4); - QTableWidgetItem* labelItem = cueTable->item(row, 5); - - VERIFY_OR_DEBUG_ASSERT(rowItem && hotcueItem && colorWidget && labelItem) { - qWarning() << "unable to retrieve cells from cueTable row"; - continue; - } - - int oldRow = rowItem->data(Qt::DisplayRole).toInt(); - CuePointer pCue(m_cueMap.value(oldRow, CuePointer())); - if (!pCue) { - continue; - } - updatedRows.insert(oldRow); - - QVariant vHotcue = hotcueItem->data(Qt::DisplayRole); - bool ok; - int iTableHotcue = vHotcue.toInt(&ok); - if (ok) { - // The GUI shows hotcues as 1-indexed, but they are actually - // 0-indexed, so subtract 1 - pCue->setHotCue(iTableHotcue - 1); - } else { - pCue->setHotCue(-1); - } - - if (pCue->getType() == Cue::Type::HotCue) { - auto colorComboBox = qobject_cast(colorWidget); - if (colorComboBox) { - HotcueColorPaletteSettings colorPaletteSettings(m_pConfig); - auto colorPalette = - colorPaletteSettings.getHotcueColorPalette(); - QList hotcueColorList = - colorPaletteSettings.getHotcueColorPalette() - .m_colorList; - QColor color = - hotcueColorList.at(colorComboBox->currentIndex()); - pCue->setColor(color); - } - } - // do nothing for now. - - QString label = labelItem->data(Qt::DisplayRole).toString(); - pCue->setLabel(label); - } - - QMutableHashIterator it(m_cueMap); - // Everything that was not processed above was removed. - while (it.hasNext()) { - it.next(); - int oldRow = it.key(); - - // If cue's old row is not in updatedRows then it must have been - // deleted. - if (updatedRows.contains(oldRow)) { - continue; - } - CuePointer pCue(it.value()); - it.remove(); - qDebug() << "Deleting cue" << pCue->getId() << pCue->getHotCue(); - m_pLoadedTrack->removeCue(pCue); - } - m_pLoadedTrack->setCoverInfo(m_loadedCoverInfo); // Reconnect changed signals now. @@ -597,10 +361,6 @@ void DlgTrackInfo::clear() { txtKey->setText(""); txtReplayGain->setText(""); - m_cueMap.clear(); - cueTable->clearContents(); - cueTable->setRowCount(0); - m_loadedCoverInfo = CoverInfo(); m_pWCoverArtLabel->setCoverArt(m_loadedCoverInfo, QPixmap()); } diff --git a/src/library/dlgtrackinfo.h b/src/library/dlgtrackinfo.h index a52904790c6..51ecc69a184 100644 --- a/src/library/dlgtrackinfo.h +++ b/src/library/dlgtrackinfo.h @@ -39,9 +39,6 @@ class DlgTrackInfo : public QDialog, public Ui::DlgTrackInfo { void cancel(); void trackUpdated(); - void cueActivate(); - void cueDelete(); - void slotBpmDouble(); void slotBpmHalve(); void slotBpmTwoThirds(); @@ -69,12 +66,10 @@ class DlgTrackInfo : public QDialog, public Ui::DlgTrackInfo { private: void populateFields(const Track& track); void reloadTrackBeats(const Track& track); - void populateCues(TrackPointer pTrack); void saveTrack(); void unloadTrack(bool save); void clear(); void init(); - QHash m_cueMap; TrackPointer m_pLoadedTrack; BeatsPointer m_pBeatsClone; Keys m_keysClone; diff --git a/src/library/dlgtrackinfo.ui b/src/library/dlgtrackinfo.ui index 4435134c7a0..caf42ac2c25 100644 --- a/src/library/dlgtrackinfo.ui +++ b/src/library/dlgtrackinfo.ui @@ -7,7 +7,7 @@ 0 0 700 - 588 + 595 @@ -41,7 +41,7 @@ - 0 + 2 @@ -376,7 +376,16 @@ QLayout::SetDefaultConstraint - + + 0 + + + 0 + + + 0 + + 0 @@ -798,90 +807,6 @@ Often results in higher quality beatgrids, but will not do well on tracks that h - - - Cuepoints - - - - - - - Cue Id - - - - - Position - - - - - Type - - - - - Hotcue - - - - - Color - - - - - Label - - - - - - - - - - - 125 - 0 - - - - Delete Cue - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 125 - 0 - - - - Activate Cue - - - - - - - @@ -1030,9 +955,6 @@ Often results in higher quality beatgrids, but will not do well on tracks that h bpmThreeFourth bpmThreeHalves bpmFourThirds - cueTable - btnCueDelete - btnCueActivate From e1f92ec3367972c4512f4b318f3c87e563bf9bb6 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Mon, 11 Nov 2019 15:41:34 +0100 Subject: [PATCH 018/158] Set hotcue color to the first predefined color --- src/engine/controls/cuecontrol.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index f89718376e1..3aa2d3f68fb 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -597,17 +597,19 @@ void CueControl::hotcueSet(HotcueControl* pControl, double v) { pCue->setHotCue(hotcue); pCue->setLabel(""); pCue->setType(Cue::Type::HotCue); - // TODO(XXX) deal with spurious signals - attachCue(pCue, pControl); + auto hotcueColorPalette = m_colorPaletteSettings.getHotcueColorPalette(); ConfigKey autoHotcueColorsKey("[Controls]", "auto_hotcue_colors"); if (getConfig()->getValue(autoHotcueColorsKey, false)) { - auto hotcueColorPalette = - m_colorPaletteSettings.getHotcueColorPalette(); auto colors = hotcueColorPalette.m_colorList; pCue->setColor(colors.at((hotcue % (colors.count() - 1)) + 1)); + } else { + pCue->setColor(hotcueColorPalette.m_colorList.first()); }; + // TODO(XXX) deal with spurious signals + attachCue(pCue, pControl); + // If quantize is enabled and we are not playing, jump to the cue point // since it's not necessarily where we currently are. TODO(XXX) is this // potentially invalid for vinyl control? @@ -1761,7 +1763,7 @@ HotcueControl::HotcueControl(QString group, int i) m_hotcueEnabled = new ControlObject(keyForControl(i, "enabled")); m_hotcueEnabled->setReadOnly(); - // The id of the predefined color assigned to this color. + // The rgba value of the color assigned to this color. m_hotcueColor = new ControlObject(keyForControl(i, "color")); connect(m_hotcueColor, &ControlObject::valueChanged, From 413c17cae97b518dc2681711a2fbb2bdaee327f5 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Mon, 11 Nov 2019 15:44:43 +0100 Subject: [PATCH 019/158] Set hotcue color CO to -1 when no hotcue is loaded --- src/engine/controls/cuecontrol.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index 3aa2d3f68fb..5f45195c0f7 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -317,6 +317,8 @@ void CueControl::detachCue(HotcueControl* pControl) { } disconnect(pCue.get(), 0, this, 0); pControl->resetCue(); + // Reset the color CO to -1 + pControl->setColor(QColor()); } void CueControl::trackLoaded(TrackPointer pNewTrack) { @@ -1765,6 +1767,7 @@ HotcueControl::HotcueControl(QString group, int i) // The rgba value of the color assigned to this color. m_hotcueColor = new ControlObject(keyForControl(i, "color")); + m_hotcueColor->set(-1); connect(m_hotcueColor, &ControlObject::valueChanged, this, @@ -1874,7 +1877,11 @@ QColor HotcueControl::getColor() const { } void HotcueControl::setColor(const QColor& newColor) { - m_hotcueColor->set(newColor.rgba()); + if (newColor.isValid()) { + m_hotcueColor->set(newColor.rgba()); + } else { + m_hotcueColor->set(-1); + } } void HotcueControl::resetCue() { // clear pCue first because we have a null check for valid data else where From 74b098c4c211465844e0c6d17504fc2404a966f0 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Mon, 11 Nov 2019 19:10:45 +0100 Subject: [PATCH 020/158] Make hotcue skin buttons use the cue color Shade still does not work --- res/skins/Deere/hotcue_button.xml | 2 +- res/skins/Deere/style.qss | 124 ------------------------ res/skins/LateNight/button_hotcue.xml | 2 +- res/skins/LateNight/style.qss | 38 -------- res/skins/Shade/hotcue_button.xml | 2 +- res/skins/Shade/style.qss | 45 --------- res/skins/Shade/style_dark.qss | 5 - res/skins/Shade/style_summer_sunset.qss | 10 +- res/skins/Tango/button_hotcue_deck.xml | 2 +- res/skins/Tango/style.qss | 59 ----------- src/widget/wwidget.cpp | 24 +++++ src/widget/wwidget.h | 7 ++ 12 files changed, 41 insertions(+), 279 deletions(-) diff --git a/res/skins/Deere/hotcue_button.xml b/res/skins/Deere/hotcue_button.xml index 0cc869e7350..2712d6eb0f0 100644 --- a/res/skins/Deere/hotcue_button.xml +++ b/res/skins/Deere/hotcue_button.xml @@ -47,7 +47,7 @@ ,hotcue__color - highlight + backgroundColorRgba diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index 4cdd6ac8e17..89bb8e9418a 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -1559,130 +1559,6 @@ WPushButton[value="2"]:hover { border: 1px solid #0080BE; } -/* Hotcue Color: No Color */ -#HotcueButton[value="1"][highlight="0"], -#HotcueButton[value="2"][highlight="0"] { - background-color: #006596; -} - -#HotcueButton[value="1"][highlight="0"]:hover, -#HotcueButton[value="2"][highlight="0"]:hover { - background-color: #0080BE; -} - -/* Hotcue Color: Red */ -#HotcueButton[value="1"][highlight="1"], -#HotcueButton[value="2"][highlight="1"] { - background-color: #c50a08; -} - -#HotcueButton[value="1"][highlight="1"]:hover, -#HotcueButton[value="2"][highlight="1"]:hover { - background-color: #e50c08; -} - -/* Hotcue Color: Green */ -#HotcueButton[value="1"][highlight="2"], -#HotcueButton[value="2"][highlight="2"] { - background-color: #32be44; -} - -#HotcueButton[value="1"][highlight="2"]:hover, -#HotcueButton[value="2"][highlight="2"]:hover { - background-color: #52de64; -} - -/* Hotcue Color: Blue */ -#HotcueButton[value="1"][highlight="3"], -#HotcueButton[value="2"][highlight="3"] { - background-color: #0044ff; -} - -#HotcueButton[value="1"][highlight="3"]:hover, -#HotcueButton[value="2"][highlight="3"]:hover { - background-color: #0064ff; -} - -/* Hotcue Color: Yellow */ -#HotcueButton[value="1"][highlight="4"], -#HotcueButton[value="2"][highlight="4"] { - color: #4B4B4B; - background-color: #f8d200; -} - -#HotcueButton[value="1"][highlight="4"]:hover, -#HotcueButton[value="2"][highlight="4"]:hover { - color: #4B4B4B; - background-color: #f8f200; -} - -/* Hotcue Color: Celeste */ -#HotcueButton[value="1"][highlight="5"], -#HotcueButton[value="2"][highlight="5"] { - color: #4B4B4B; - background-color: #42d4f4; -} - -#HotcueButton[value="1"][highlight="5"]:hover, -#HotcueButton[value="2"][highlight="5"]:hover { - color: #4B4B4B; - background-color: #62f4f4; -} - -/* Hotcue Color: Purple */ -#HotcueButton[value="1"][highlight="6"], -#HotcueButton[value="2"][highlight="6"] { - background-color: #af00cc; -} - -#HotcueButton[value="1"][highlight="6"]:hover, -#HotcueButton[value="2"][highlight="6"]:hover { - background-color: #cf00ec; -} - -/* Hotcue Color: Pink */ -#HotcueButton[value="1"][highlight="7"], -#HotcueButton[value="2"][highlight="7"] { - color: #4B4B4B; - background-color: #fca6d7; -} - -#HotcueButton[value="1"][highlight="7"]:hover, -#HotcueButton[value="2"][highlight="7"]:hover { - color: #4B4B4B; - background-color: #fcc6f7; -} - -/* Hotcue Color: White */ -#HotcueButton[value="1"][highlight="8"], -#HotcueButton[value="2"][highlight="8"] { - color: #4B4B4B; - background-color: #f2f2ff; -} - -#HotcueButton[value="1"][highlight="8"]:hover, -#HotcueButton[value="2"][highlight="8"]:hover { - color: #4B4B4B; - background-color: #ffffff; -} - -/*"Enabled" state, e.g. for recording status - 0 -- disconnected / off - 1 -- connecting / enabling - 2 -- connected / enabled -WPushButton[value="2"] { - color: #FDFDFD; - background-color: #4B4B4B; - border: 0px solid #006596; -} - -WPushButton[value="2"]:hover { - color: #FDFDFD; - background-color: #4B4B4B; - border: 0px solid #0080BE; -} -*/ - #PlayToggle[value="0"] { image: url(skin:/icon/ic_play_48px.svg) no-repeat center center; } diff --git a/res/skins/LateNight/button_hotcue.xml b/res/skins/LateNight/button_hotcue.xml index fc9eba27700..920ffc05d32 100644 --- a/res/skins/LateNight/button_hotcue.xml +++ b/res/skins/LateNight/button_hotcue.xml @@ -38,7 +38,7 @@ ,hotcue__color - highlight + backgroundColorRgba diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index ec9943b3ae4..e489aa9c356 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -716,44 +716,6 @@ QPushButton#pushButtonAutoDJ:checked, } /* ToDo * orange Play button when playing from Cue / Hotcue */ -/* Hotcue Color: Green */ -#HotcueButton[displayValue="1"][highlight="2"], -#HotcueButton[displayValue="2"][highlight="2"] { - background-color: #32be44; -} -/* Hotcue Color: Blue */ -#HotcueButton[displayValue="1"][highlight="3"], -#HotcueButton[displayValue="2"][highlight="3"], -#SpecialCueButton[value="1"] { - background-color: #0044ff; -} -/* Hotcue Color: Yellow */ -#HotcueButton[displayValue="1"][highlight="4"], -#HotcueButton[displayValue="2"][highlight="4"] { - background-color: #f8d200; -} -/* Hotcue Color: Celeste */ -#HotcueButton[displayValue="1"][highlight="5"], -#HotcueButton[displayValue="2"][highlight="5"] { - background-color: #42d4f4; -} -/* Hotcue Color: Purple */ -#HotcueButton[displayValue="1"][highlight="6"], -#HotcueButton[displayValue="2"][highlight="6"] { - background-color: #af00cc; -} -/* Hotcue Color: Pink */ -#HotcueButton[displayValue="1"][highlight="7"], -#HotcueButton[displayValue="2"][highlight="7"] { - background-color: #fca6d7; -} -/* Hotcue Color: White */ -#HotcueButton[displayValue="1"][highlight="8"], -#HotcueButton[displayValue="2"][highlight="8"] { - background-color: #f2f2ff; -} -/************** Button borders & backgrounds **********************************/ - /************** Button icons **************************************************/ diff --git a/res/skins/Shade/hotcue_button.xml b/res/skins/Shade/hotcue_button.xml index f31ffdf7b1b..eeb31fbb4a2 100644 --- a/res/skins/Shade/hotcue_button.xml +++ b/res/skins/Shade/hotcue_button.xml @@ -28,7 +28,7 @@ ,hotcue__color - highlight + backgroundColorRgba diff --git a/res/skins/Shade/style.qss b/res/skins/Shade/style.qss index 5051566ea5e..ba426573ba5 100644 --- a/res/skins/Shade/style.qss +++ b/res/skins/Shade/style.qss @@ -783,48 +783,3 @@ QPushButton#pushButtonRepeatPlaylist { image: url(skin:/btn/btn_autodj_repeat_playlist.svg) no-repeat center center; } /* AutoDJ button icons */ - -/* Hotcue Color: No Color */ -#HotcueButton[highlight="0"] { - background-color: #fd0564; -} - -/* Hotcue Color: Red */ -#HotcueButton[highlight="1"] { - background-color: #c50a08; -} - -/* Hotcue Color: Green */ -#HotcueButton[highlight="2"] { - background-color: #32be44; -} - -/* Hotcue Color: Blue */ -#HotcueButton[highlight="3"] { - background-color: #0044ff; -} - -/* Hotcue Color: Yellow */ -#HotcueButton[highlight="4"] { - background-color: #f8d200; -} - -/* Hotcue Color: Celeste */ -#HotcueButton[highlight="5"] { - background-color: #42d4f4; -} - -/* Hotcue Color: Purple */ -#HotcueButton[highlight="6"] { - background-color: #af00cc; -} - -/* Hotcue Color: Pink */ -#HotcueButton[highlight="7"] { - background-color: #fca6d7; -} - -/* Hotcue Color: White */ -#HotcueButton[highlight="8"] { - background-color: #f2f2ff; -} diff --git a/res/skins/Shade/style_dark.qss b/res/skins/Shade/style_dark.qss index fbe409391e0..365e5d283d5 100644 --- a/res/skins/Shade/style_dark.qss +++ b/res/skins/Shade/style_dark.qss @@ -187,8 +187,3 @@ WLibrary QPushButton:enabled { WLibrary QRadioButton::indicator:checked { image: url(skin:/btn/btn_lib_radio_button_on_mustard.svg) center center; } - -/* Hotcue Color: No Color */ -#HotcueButton[highlight="0"] { - background-color: #b39a00; -} diff --git a/res/skins/Shade/style_summer_sunset.qss b/res/skins/Shade/style_summer_sunset.qss index 86da85fbe15..6d569a63760 100644 --- a/res/skins/Shade/style_summer_sunset.qss +++ b/res/skins/Shade/style_summer_sunset.qss @@ -109,7 +109,9 @@ WLibrary QRadioButton::indicator:checked { image: url(skin:/btn/btn_lib_radio_button_on_neongreen.svg) center center; } -/* Hotcue Color: No Color */ -#HotcueButton[highlight="0"] { - background-color: #52f904; -} +/* 'Enable AutoDJ' button */ +QPushButton#pushButtonAutoDJ:hover, +QPushButton#pushButtonRecording:hover, +QPushButton#pushButtonAnalyze:hover { + border: 1px solid #52F904; + } diff --git a/res/skins/Tango/button_hotcue_deck.xml b/res/skins/Tango/button_hotcue_deck.xml index c858ef7640c..eb0785f234c 100644 --- a/res/skins/Tango/button_hotcue_deck.xml +++ b/res/skins/Tango/button_hotcue_deck.xml @@ -39,7 +39,7 @@ Variables: ,hotcue__color - highlight + backgroundColorRgba diff --git a/res/skins/Tango/style.qss b/res/skins/Tango/style.qss index 4e77414dbf8..4eb39b17eff 100644 --- a/res/skins/Tango/style.qss +++ b/res/skins/Tango/style.qss @@ -1006,65 +1006,6 @@ WLabel#TrackComment { border: 1px solid #eeeeee; } -/* Hotcue Color: No Color */ -#HotcueButton[displayValue="1"][highlight="0"], -#HotcueButton[displayValue="2"][highlight="0"] { - background-color: #666; -} - -/* Hotcue Color: Red */ -#HotcueButton[displayValue="1"][highlight="1"], -#HotcueButton[displayValue="2"][highlight="1"] { - background-color: #c50a08; -} - -/* Hotcue Color: Green */ -#HotcueButton[displayValue="1"][highlight="2"], -#HotcueButton[displayValue="2"][highlight="2"] { - background-color: #32be44; - color: #111; -} - -/* Hotcue Color: Blue */ -#HotcueButton[displayValue="1"][highlight="3"], -#HotcueButton[displayValue="2"][highlight="3"] { - background-color: #0044ff; -} - -/* Hotcue Color: Yellow */ -#HotcueButton[displayValue="1"][highlight="4"], -#HotcueButton[displayValue="2"][highlight="4"] { - color: #222; - background-color: #f8d200; -} - -/* Hotcue Color: Celeste */ -#HotcueButton[displayValue="1"][highlight="5"], -#HotcueButton[displayValue="2"][highlight="5"] { - color: #111; - background-color: #42d4f4; -} - -/* Hotcue Color: Purple */ -#HotcueButton[displayValue="1"][highlight="6"], -#HotcueButton[displayValue="2"][highlight="6"] { - background-color: #af00cc; -} - -/* Hotcue Color: Pink */ -#HotcueButton[displayValue="1"][highlight="7"], -#HotcueButton[displayValue="2"][highlight="7"] { - color: #333; - background-color: #fca6d7; -} - -/* Hotcue Color: White */ -#HotcueButton[displayValue="1"][highlight="8"], -#HotcueButton[displayValue="2"][highlight="8"] { - color: #222; - background-color: #f2f2ff; -} - #CueButton { /* is styled like #HotcueButton, lights up if play position is at main Cue point */ diff --git a/src/widget/wwidget.cpp b/src/widget/wwidget.cpp index 364b46280a1..b5421aec06e 100644 --- a/src/widget/wwidget.cpp +++ b/src/widget/wwidget.cpp @@ -37,6 +37,30 @@ WWidget::~WWidget() { delete m_pTouchShift; } +double WWidget::getBackgroundColorRgba() const { + if (m_backgroundColorRgba >= 0) { + return m_backgroundColorRgba; + } + return -1; +} + +void WWidget::setBackgroundColorRgba(double rgba) { + QColor backgroundColor = QColor::fromRgba(rgba); + QColor textColor = Color::chooseColorByBrightness( + backgroundColor, Qt::white, Qt::black); + + QString style = + "background-color: %1;" + "color: %2;"; + + if (rgba >= 0) { + setStyleSheet(style.arg(backgroundColor.name()).arg(textColor.name())); + } else { + setStyleSheet(""); + } + m_backgroundColorRgba = rgba; +} + bool WWidget::touchIsRightButton() { return (m_pTouchShift->get() != 0.0); } diff --git a/src/widget/wwidget.h b/src/widget/wwidget.h index cbadf8ab2fe..fdd571b036b 100644 --- a/src/widget/wwidget.h +++ b/src/widget/wwidget.h @@ -23,6 +23,7 @@ #include #include "preferences/usersettings.h" +#include "util/color/color.h" #include "widget/wbasewidget.h" class ControlProxy; @@ -44,6 +45,11 @@ class WWidget : public QWidget, public WBaseWidget { ~WWidget() override; Q_PROPERTY(double value READ getControlParameterDisplay); + Q_PROPERTY(double backgroundColorRgba READ getBackgroundColorRgba WRITE + setBackgroundColorRgba); + + double getBackgroundColorRgba() const; + void setBackgroundColorRgba(double rgba); protected: bool touchIsRightButton(); @@ -60,6 +66,7 @@ class WWidget : public QWidget, public WBaseWidget { private: ControlProxy* m_pTouchShift; double m_scaleFactor; + double m_backgroundColorRgba; }; #endif From 75fdbed24bd11ba98aff9d45e9add9038e88ad24 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Mon, 11 Nov 2019 23:47:19 +0100 Subject: [PATCH 021/158] Allow skins to configure text color depending on background --- res/skins/Deere/style.qss | 9 ++++++++- res/skins/Tango/style.qss | 8 ++++++++ src/widget/wwidget.cpp | 10 +++------- src/widget/wwidget.h | 9 +++++++++ 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index 89bb8e9418a..53ff1e88846 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -1546,7 +1546,6 @@ WPushButton:hover { /*"Pressed" state*/ WPushButton[value="1"], WPushButton[value="2"] { - /*color: #FDFDFD;*/ color: #FDFDFD; background-color: #006596; border: 1px solid #006596; @@ -1559,6 +1558,14 @@ WPushButton[value="2"]:hover { border: 1px solid #0080BE; } +#HotcueButton[backgroundIsDark=true][hasBackgroundColor=true] { + color: #FDFDFD; +} + +#HotcueButton[backgroundIsDark=false][hasBackgroundColor=true] { + color: #1f1e1e; +} + #PlayToggle[value="0"] { image: url(skin:/icon/ic_play_48px.svg) no-repeat center center; } diff --git a/res/skins/Tango/style.qss b/res/skins/Tango/style.qss index 4eb39b17eff..0938c92be55 100644 --- a/res/skins/Tango/style.qss +++ b/res/skins/Tango/style.qss @@ -1006,6 +1006,14 @@ WLabel#TrackComment { border: 1px solid #eeeeee; } +#HotcueButton[backgroundIsDark=true][hasBackgroundColor=true] { + color: #eeeeee; +} + +#HotcueButton[backgroundIsDark=false][hasBackgroundColor=true] { + color: #0f0f0f; +} + #CueButton { /* is styled like #HotcueButton, lights up if play position is at main Cue point */ diff --git a/src/widget/wwidget.cpp b/src/widget/wwidget.cpp index b5421aec06e..09ad3fa530b 100644 --- a/src/widget/wwidget.cpp +++ b/src/widget/wwidget.cpp @@ -46,19 +46,15 @@ double WWidget::getBackgroundColorRgba() const { void WWidget::setBackgroundColorRgba(double rgba) { QColor backgroundColor = QColor::fromRgba(rgba); - QColor textColor = Color::chooseColorByBrightness( - backgroundColor, Qt::white, Qt::black); - - QString style = - "background-color: %1;" - "color: %2;"; + QString style = "background-color: %1;"; if (rgba >= 0) { - setStyleSheet(style.arg(backgroundColor.name()).arg(textColor.name())); + setStyleSheet(style.arg(backgroundColor.name())); } else { setStyleSheet(""); } m_backgroundColorRgba = rgba; + m_bBackgroundIsDark = Color::isDimmColor(backgroundColor); } bool WWidget::touchIsRightButton() { diff --git a/src/widget/wwidget.h b/src/widget/wwidget.h index fdd571b036b..e0956488834 100644 --- a/src/widget/wwidget.h +++ b/src/widget/wwidget.h @@ -47,9 +47,17 @@ class WWidget : public QWidget, public WBaseWidget { Q_PROPERTY(double value READ getControlParameterDisplay); Q_PROPERTY(double backgroundColorRgba READ getBackgroundColorRgba WRITE setBackgroundColorRgba); + Q_PROPERTY(bool hasBackgroundColor READ hasBackgroundColor); + Q_PROPERTY(bool backgroundIsDark READ backgroundIsDark); double getBackgroundColorRgba() const; void setBackgroundColorRgba(double rgba); + bool hasBackgroundColor() const { + return m_backgroundColorRgba >= 0; + } + bool backgroundIsDark() const { + return m_bBackgroundIsDark; + } protected: bool touchIsRightButton(); @@ -67,6 +75,7 @@ class WWidget : public QWidget, public WBaseWidget { ControlProxy* m_pTouchShift; double m_scaleFactor; double m_backgroundColorRgba; + bool m_bBackgroundIsDark; }; #endif From 7702c6c9ad294b150eead5c7624d266cfe05951c Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Mon, 11 Nov 2019 23:58:27 +0100 Subject: [PATCH 022/158] Highlight hotcue buttons when hovered --- src/widget/wwidget.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/widget/wwidget.cpp b/src/widget/wwidget.cpp index 09ad3fa530b..f85c3433651 100644 --- a/src/widget/wwidget.cpp +++ b/src/widget/wwidget.cpp @@ -46,10 +46,14 @@ double WWidget::getBackgroundColorRgba() const { void WWidget::setBackgroundColorRgba(double rgba) { QColor backgroundColor = QColor::fromRgba(rgba); - QString style = "background-color: %1;"; + QColor highlightedBackgroundColor = backgroundColor.lighter(); + QString style = + QString("WWidget { background-color: %1; }" + "WWidget:hover { background-color: %2; }"); if (rgba >= 0) { - setStyleSheet(style.arg(backgroundColor.name())); + setStyleSheet(style.arg(backgroundColor.name()) + .arg(highlightedBackgroundColor.name())); } else { setStyleSheet(""); } From 738db3a6ccecd32fff7064125b31784a56af2131 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Tue, 12 Nov 2019 12:39:31 +0100 Subject: [PATCH 023/158] Fix Shade hotcue buttons color --- res/skins/Shade/btn/btn_hotcue_1.png | Bin 386 -> 3173 bytes res/skins/Shade/btn/btn_hotcue_1_down.png | Bin 385 -> 0 bytes res/skins/Shade/btn/btn_hotcue_1_over.png | Bin 592 -> 0 bytes res/skins/Shade/btn/btn_hotcue_1_overdown.png | Bin 594 -> 0 bytes res/skins/Shade/btn/btn_hotcue_2.png | Bin 392 -> 3711 bytes res/skins/Shade/btn/btn_hotcue_2_down.png | Bin 392 -> 0 bytes res/skins/Shade/btn/btn_hotcue_2_over.png | Bin 3436 -> 0 bytes res/skins/Shade/btn/btn_hotcue_2_overdown.png | Bin 2265 -> 0 bytes res/skins/Shade/btn/btn_hotcue_3.png | Bin 397 -> 3582 bytes res/skins/Shade/btn/btn_hotcue_3_down.png | Bin 397 -> 0 bytes res/skins/Shade/btn/btn_hotcue_3_over.png | Bin 3242 -> 0 bytes res/skins/Shade/btn/btn_hotcue_3_overdown.png | Bin 2271 -> 0 bytes res/skins/Shade/btn/btn_hotcue_4.png | Bin 389 -> 3504 bytes res/skins/Shade/btn/btn_hotcue_4_down.png | Bin 388 -> 0 bytes res/skins/Shade/btn/btn_hotcue_4_over.png | Bin 3085 -> 0 bytes res/skins/Shade/btn/btn_hotcue_4_overdown.png | Bin 2160 -> 0 bytes res/skins/Shade/btn/btn_hotcue_5.png | Bin 201 -> 3723 bytes res/skins/Shade/btn/btn_hotcue_5_down.png | Bin 201 -> 0 bytes res/skins/Shade/btn/btn_hotcue_5_over.png | Bin 204 -> 0 bytes res/skins/Shade/btn/btn_hotcue_5_overdown.png | Bin 208 -> 0 bytes res/skins/Shade/btn/btn_hotcue_6.png | Bin 202 -> 3593 bytes res/skins/Shade/btn/btn_hotcue_6_down.png | Bin 202 -> 0 bytes res/skins/Shade/btn/btn_hotcue_6_over.png | Bin 205 -> 0 bytes res/skins/Shade/btn/btn_hotcue_6_overdown.png | Bin 209 -> 0 bytes res/skins/Shade/btn/btn_hotcue_7.png | Bin 203 -> 3473 bytes res/skins/Shade/btn/btn_hotcue_7_down.png | Bin 202 -> 0 bytes res/skins/Shade/btn/btn_hotcue_7_over.png | Bin 206 -> 0 bytes res/skins/Shade/btn/btn_hotcue_7_overdown.png | Bin 210 -> 0 bytes res/skins/Shade/btn/btn_hotcue_8.png | Bin 196 -> 3581 bytes res/skins/Shade/btn/btn_hotcue_8_down.png | Bin 195 -> 0 bytes res/skins/Shade/btn/btn_hotcue_8_over.png | Bin 601 -> 0 bytes res/skins/Shade/btn/btn_hotcue_8_overdown.png | Bin 603 -> 0 bytes res/skins/Shade/hotcue_button.xml | 6 +++--- res/skins/Shade/style.qss | 4 ++++ 34 files changed, 7 insertions(+), 3 deletions(-) delete mode 100644 res/skins/Shade/btn/btn_hotcue_1_down.png delete mode 100644 res/skins/Shade/btn/btn_hotcue_1_over.png delete mode 100644 res/skins/Shade/btn/btn_hotcue_1_overdown.png delete mode 100644 res/skins/Shade/btn/btn_hotcue_2_down.png delete mode 100644 res/skins/Shade/btn/btn_hotcue_2_over.png delete mode 100644 res/skins/Shade/btn/btn_hotcue_2_overdown.png delete mode 100644 res/skins/Shade/btn/btn_hotcue_3_down.png delete mode 100644 res/skins/Shade/btn/btn_hotcue_3_over.png delete mode 100644 res/skins/Shade/btn/btn_hotcue_3_overdown.png delete mode 100644 res/skins/Shade/btn/btn_hotcue_4_down.png delete mode 100644 res/skins/Shade/btn/btn_hotcue_4_over.png delete mode 100644 res/skins/Shade/btn/btn_hotcue_4_overdown.png delete mode 100644 res/skins/Shade/btn/btn_hotcue_5_down.png delete mode 100644 res/skins/Shade/btn/btn_hotcue_5_over.png delete mode 100644 res/skins/Shade/btn/btn_hotcue_5_overdown.png delete mode 100644 res/skins/Shade/btn/btn_hotcue_6_down.png delete mode 100644 res/skins/Shade/btn/btn_hotcue_6_over.png delete mode 100644 res/skins/Shade/btn/btn_hotcue_6_overdown.png delete mode 100644 res/skins/Shade/btn/btn_hotcue_7_down.png delete mode 100644 res/skins/Shade/btn/btn_hotcue_7_over.png delete mode 100644 res/skins/Shade/btn/btn_hotcue_7_overdown.png delete mode 100644 res/skins/Shade/btn/btn_hotcue_8_down.png delete mode 100644 res/skins/Shade/btn/btn_hotcue_8_over.png delete mode 100644 res/skins/Shade/btn/btn_hotcue_8_overdown.png diff --git a/res/skins/Shade/btn/btn_hotcue_1.png b/res/skins/Shade/btn/btn_hotcue_1.png index bbcc063c52533d5515480db28be7a660fbc6dbd4..86f572261d970428cd8e69f8e38e1f2ed9ebf307 100644 GIT binary patch delta 3149 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 delta 360 zcmaDV(ZoDKxt@Wg*vT`50|;t3QaTtI7&r?&B8wRqxP?HN@zUM8KR`jT64!_l=c3fa zlFa-(g^eIqk{1IsTA!OwsyDnTmp5_407Q%i~&sufaFi<65o3qb0vlw9)5 z^K$YNQxr-vQWav9{D8_*6oON8Qj_b!27>g&C@B;q=B4H+q!s1oDrA(D6jrda73>L?TgwOLgwDAX#{Ml4xB8|VrdkSl`o(@M${ zi&7aJQ}UBi72IHEC^!e3z1Xv<2dFO8)5S5wqBnU;;*{{8=N()R96E5|fI;D>lvNVb z=FdKTz(sWOgaa!Yn=d$sIdLU9B|UhfnmtXxWWoaOPQw-zW>41U`wmSL4;^rbvf!)J i?{{F9Tp7#Cz_5A+&*}9)^tpgGFnGH9xvX)e0%8#mPmP1t9fSN-p{3c{%xsDGDVSsR}Vlen4d@3c;y4smWmTKw4sy6bcga zQgam2it=+6GD=Dctn~HMGK*5n^NX^J^%9d(6LWI(lJj$wbQCgEtaJ@^6pDe`tg00h zY87fDmaLx*bc77Z5yAOsCFO}lsSJ)O`AMk?ZZI=Mo z_|NkWt_KbsIB;OXta*N-httl_IeEZEbn=7)D;k?GIEXoMSxH$vc+=I!)x;)LqG;GQ zAw^+j!Ut&&gCGeB5ANd!-#-=1P*C2wnt|cqWA4Ldrjk#A<}-M@`njxgN@xNA9OQpF diff --git a/res/skins/Shade/btn/btn_hotcue_1_over.png b/res/skins/Shade/btn/btn_hotcue_1_over.png deleted file mode 100644 index b02f6cbbfc77dc7aec56eee4678d0056f6e4c46f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 592 zcmV-W0EX>4Tx04R}tkv&MmKpe$iQ%glEA{J3`$WR5rf~bh2R-p(LLaorMgUR(vXws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;i>s5Oix`&UicTt|@eeTcEna!CD@QK7TOgAjzb>gW_ zOXs{#9A-s1OMFf|YS0CVAGxl${KmQ9u)s6JMk+Z+93~bEEv&RKD;g^CByl9GYLqXe zUCwge;;fb`tZ`5N!cb0IUgA2C8D2mgcL-J1D{aW^Rx0|GC${V@atcY%7UyM6-rpMfi_=`YuS=}*$D zO)YW+bZr9{*G)~?11@)fz9(HaWJmJT6!LlC{fxdT1N7Vi9jk6{jeVRx04eG!aRVG2 z0>cH$Uh{Z&duwn1o@w;=1A4Y{s&4pKSO5S324YJ`L;(K){{a7>y{D4^000SaNLh0L z01FZT01FZU(%pXi00007bV*G`2jl?;2oD=t*4A2`~N^jid{&IA)}E(7?2W| e8pufPDgXfE4G(jJmMDGz0000EX>4Tx04R}tkv&MmKpe$iTT4YM4i-^y$WWauh>CR7DionYs1;guFuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|;_9U6A|?JWDYS_3;J6>}?mh0_0scmXsb<#%plX(p zP9}tGZdC}qB8VXjAdaxaOnpuiQ}7&L_we!cF2=LG&;2=imAuISpFljzbi*RvAfDN@ zbk6(45mu5E;&bA0gDyz?$aUG}H_kbWYY7*5n`d(!Ey()lA#h$6Gs(QqkMnX zWrgz=XSGset$XqphV$CWGS_L2Ac;jRL4*JqHIz|-g&3_GDJIgipYZSxJARQ|GP%lN zZ37qAZB5<-E_Z;zCtWfmM+(sN7Ye}p8GTa@=)VPe*4*A&`#607GSpS-1~@nb z#)_1^?(y#K&ffk#)9UXBleTiS%{j=S00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3labT3lag+-G2N4000McNliruuhdwn7ll;eVk%@uIVAQ}tXdnwA1#C~hUxcxLNptE`>_TD;8I2UefRu0?%_)O5 gmL>mjT%?wP0LX+66;)>EX#fBK07*qoM6N<$g8O{_Z2$lO diff --git a/res/skins/Shade/btn/btn_hotcue_2.png b/res/skins/Shade/btn/btn_hotcue_2.png index f085b9f63a356efa79e8a440f68439f717e3a370..6c93b48fe2ed78c5fafb4b26416e3c764af0ab6a 100644 GIT binary patch delta 3691 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 JPDHLkV1hfe2Y>(o delta 366 zcmew_)4@DJxt@Wg*vT`50|;t3QaTtI7&r?&B8wRqxP?HN@zUM8KR`jT64!_l=c3fa zlFa-(g^eIqk{1IsTA!OwsyDnTmp5_407Q%i~&sufaFi<65o3qb0vlw9)5 z^K$YNQxr-vQWav9{D8_*6oON8Qj_b!27>g&C@B;q=B4H+q!s1oDrA(D6jrda73>L?TgwOLgwDAX#{Ml4xB8|VrdkSl`o(@M${ zi&7aJQ}UBi72IHEC^!e3z1Xv<2dFOE)5S5wqBnU;`jqgW=N()R96E5|fI;D>lvNVb z=FdKTz(sWOgaa!Yn=d$s)l4!}G>kYpeNCj(yv7$&g^>zopr02FhDNB{r; diff --git a/res/skins/Shade/btn/btn_hotcue_2_down.png b/res/skins/Shade/btn/btn_hotcue_2_down.png deleted file mode 100644 index 93b227bafe4436da27378ab12d3fa5ac45c28d27..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 392 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VOR)e0%8#mPmP1t9fSN-p{3c{%xsDGDVSsR}Vlen4d@3c;y4smWmTKw4sy6bcga zQgam2it=+6GD=Dctn~HMGK*5n^NX^J^%9d(6LWI(lJj$wbQCgEtaJ@^6pDe`tg00h zY87fDmaLx*bc77Z5yAOsCFO}lsSJ)O`AMk?ZZI=Mo z_|NkWt_KbsIB;OXta*N-httl_IeEZEbn=7)D;k?GIEd9ulI4|+II1nBb;4L6R#}g` z!)$^CvxkuY+lR`DI?NYiy|x;tu<`sWv0&m&SyCp-z;LKbIQrk#oC2UV44$rjF6*2U FngARoe!&0$ diff --git a/res/skins/Shade/btn/btn_hotcue_2_over.png b/res/skins/Shade/btn/btn_hotcue_2_over.png deleted file mode 100644 index 248fb1ea95740ee4658f23fe1541e1a8a108a82b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3436 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 O0000 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 L`njxgN@xNA`PYF7 diff --git a/res/skins/Shade/btn/btn_hotcue_3_over.png b/res/skins/Shade/btn/btn_hotcue_3_over.png deleted file mode 100644 index bc39f10974a604572a2402332206e51c804a3155..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3242 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 cMrv0907+jNF#^Kw8vp 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 JPDHLkV1oFAkd*)c delta 363 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 mxp*{T4-o@dU?nZJ3* diff --git a/res/skins/Shade/btn/btn_hotcue_5.png b/res/skins/Shade/btn/btn_hotcue_5.png index dab5e3ce7b0928e3ce7f095ceaf92ac21156ac21..002cf0cc546fe6636bf27af4f8af89a482886f0b 100644 GIT binary patch delta 3713 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 diff --git a/res/skins/Shade/btn/btn_hotcue_5_over.png b/res/skins/Shade/btn/btn_hotcue_5_over.png deleted file mode 100644 index 65f7deda2ed197096a2964f332cb5172f64337cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 204 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VTavfC3&Vd9T(EcfWS|IVfk$L9 z0|U1Z2s2)~TlWVj$X?><>&pIwk&Q!1h*{`y2T&-|)5S5w;&k$qDd9iQJGdS=bl|{& z4^L(?E1U96o@n)9erMyUgewOeGZeV(JpGP+jkx^c`~SwC6iJUB#uUkpcR`zCJJtz? t3k1ltrAT{t-RONb#W6=gdFyHhhO56MjW=7*3I|%k;OXk;vd$@?2>^gtME?K) diff --git a/res/skins/Shade/btn/btn_hotcue_5_overdown.png b/res/skins/Shade/btn/btn_hotcue_5_overdown.png deleted file mode 100644 index 9c4a9e443d8a082f059c58fe62edee5567006b45..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VTavfC3&Vd9T(EcfWS|IVfk$L9 z0|U1Z2s2)~TlWVj$X?><>&pIwk&Q!9aHHA7k3gYVPZ!4!i_^(driA}I@8Eji(18O7 zKFoR9ZfD9f`OopfiJgt760RI@%uwLA^W3)lzJ8MMf7P=q{iih^k#LyS_(D(hcIykN yLRQA3i5}Y;m$cl?@RNKK>HkUoxNDXq2ZLg%#D%_-YO8=2F?hQAxvXaB^>EX>4U6ba`-PAZ2)IW&i+q+U;3ea>FoD&-hoaDP60{KGkit+(eX9alIV zhK>uTL8mh_KJ;rRah~`2(-F#Je~3BBwX2o)v7H{LkH3_cFKTRG!gsnp;RR9Z0TVgq z;jA<3-S06D-nr}w-tBs4)-#OH&I#cVmLaY_ z#WEf-!iR?!Y=3wh{1xJ>iQUB`zP-?`b)S}V{LR_ZoMW%9_=t$cBclwR(b50Gz>1K& z^=}a`!C$~gae z5Mk~BXHWv(nrL0H(HdbEYZ1o;fC@Zk=eYs_8v=JY$=xhSJq>OG z5Wz(!z<&l+2C%#j$RF_uIaGoRK7s5>oN~^kFcnNxV5?w!!I{d{RbNAmRcflamWK3czJ(T>wA6AdoxAIx zi5|Q3)N?Px(g0HoKf;JZMjCmPiCmj*`Wa@NGJn&|vs_R+Q2q3J12ub~#tSJOCl}Ok zmPAeyR_P=tW&LzD1#|xCRy)UkyFe}W)wwWI2jZh>Q)g0gnn2K(_XOqK<*{n zD5RHg2VOp9 zYk%Q8+}8R@wkJCz+kh&GA=uCrP%fiKkfsc(eyY`qnf2IwK&hKjv9PJWbf@RX9P5b5 zysKTAg0G6Qez0%>yT!93eK+8Rqa8l0 zVykob7;DrRl<9&Vp|3_wX|0H}tQF~6@XsUGHPY6u;=(kp6@*M-oyHy&8i-jkP7Z7& z0Ra`Yt>1N?jEGE!GnfPIhU;-jH3Q;Ho8-LGU zPeB}XG5AbaO<9?e;?(tE%eY{T{pUb?#isArTo7M?qhDH((}}ri+8>~PInpmtzkp70 zp%E4u4-wyZ-=nQyA5bG%05;vBZLaZNc@>YmdW88ELi8utKQMH`e53J!x`J_w`%Ytg zTfozNg!`8@{&k7dbF?A45>%4uy?+na#1%{mkrL73dNfCNWS=0f<{)t)8Jo$~`W9`1Zgp*V?0+FZ3-7{*G;cJa!1k+qb@97}3rF2nnIL#JONa$C3(ac86znr($ zcJ^fiJ4W7%#889idAm{%5P#&IE~z+FrP!I!h>heriWcSW7N{!x84icguuD&D|94|` z@hle&05s5ipv{6SMo44tQOi>q0?r_kBcQ26XQ8{=;gYuCaB91xne@pex|?S^<%J8< zzN`hM&}0};R54TW%CAa_h|JfSzIYSdOpiC@WYf2Kepb`olj-rMtanCx-=&$ht9sA# zIO_6tMqzo`>B=q0KY#MEbiMX*MK5G$(eFx`*~@TtCuN8oOB+3Dk)|{%(8VtDYzTgl zS=c$$HBGM4H3?Dq=wc=H+8p}$g05WK^^!m}dJnl9)J*kQd99uq4g45hZ=^*BdfAFD zMH$e%n#)_aSGJ%T}xVuG!T(rXU-dqTtm^(3Q<2O(t;Hg_yrMgw(2q`R6M z=vr?{kJ6+D$Ql4##>dw0P&V!)Iawqp6NI`cPA?r77R8;He99DGVfGiqGd)+&uZw4T zuAZ+1&{ynztbdvw)Bc6q6(Otj?+aAPT3Bp|l=mL24MsXg(8D446)>fZ%e|sRpc!dI zkl1L@TI|L9ik!w`LxD6y(FT_j6p!v1D3J!ruE^?QZE6mETIkprPzqDhp~o3?yh1() z0*$R3x#kT?);bz%&@^rK!8`0o&$K?t+(K_SLC7V6cz>-#B$dgXnY*unE4CvyLW&_b zkG3&(G<+@&F0E%|ohH5Y6Dd8C85|ED8RO(ytl{8V)sQLkrUGSx`vF(iGXn5s%F^?k z1q+0U~^nZgPS0nI?L{4Gveku@DuqZ2LdQ6ISxH`?D7n|>hM#awFz)#&{v?hu#km?>H z$VsbNTT!rbV5Ps=ir#?O;z0NL4-JB}RAs<}m%a$t6u^I0DI^7501QRz_U#NGkfdYX z(ohv5^;(4_cc_pCmNIfU%DI{}ny9LUr(N@}6@QLldFq=>ddnIL4LcC_sy2{I_+HQ0 zJVzC4-UhC?=Z|do_uKxR`p02X|he_^+ES;Sq1l>?b zK}jmKedh@RccZ}*u1GfYHqP=u;4L$xASiW!_(l#>pU!zu7nC< zJL1g9y$;zMdj}9&+W{!H-C0MiQs6q!AJaoU9QjrF#l&(OWN#pKVtHnMz_~s@!%9c_<1f6|~)e zypDBmH+7T_CQ3X|KstsV4N|)gtSX}f8%^Ca-;SXBiJ^{`RWu=L_w&?`M_Kx6QGa*S zf4gvczVg=>PFGXMIPrpx&B<4WP{T>cAnX7(>Ayv6R#(Y(D}?Ex68^z04*GmY@n^R< z$p6jFW4$->&A=C{j^2|~UsoOd_MyRFJUqAon|}My;B0&7w+{_oxaa@thX?OHG&to2 zU1PnTMu&+;*dR!*cl1DFDta%pIDh&~-Lf+tdN85(k_|bmiT5oHL<4QndU6%cCs$i{ zoLeIrw>5MKdgXN+s-n2heb(+(#C?nP4~)_2+HZ}~>Dq6N(e*liV~p;D_ETf@2!Wp% zqp#q6*BCv^jdzUEcZv3@F?uCyUol3nmcVz$=$(3cW{ln~&aaHo`;{KcsDEJ1-UXbD z)_35?B?v9=Q}W(;Hp!yl%L8h`wOm@+H!#4m8JYV(`^0W;X6pK80004mX+uL$Nkc;* zaB^>EX>4Tx0C=2zkv&MmP!xqvQ$^8=Lpz8#WT;LSL`5C73Pq?8YK2xEOkVm2O&XFE z7e~Rh;NZ_<)xpJCR|i)?5P$puadCB0bdeJ8OA0Mwd~kUm=e={d?><1NmzidDi~*W% zo2f)x%w$)^u2=LTL>0!g%q(M0l9KRUU-t;`{Vv9{{O|p_`qZ4ofPhFm%M8;d-XNaZ zv<=St#1U4MRpN8vQIi@Ze&o91@f+uY%L31gnCa9!afDbbw6W60tbb@~#FNBPRnsY7 z$at)B-r}s4tE|~4e_<%6uPk$&Y6uA|VhIvND5#=@GHk?X*GaLEqVu?qf6(4yW|h1F z4i15l0%foJyt})7ZvWnC&hH0xMsldY*&1X3000JJOGiWi000000Qp0^e*gdg32;bR za{vGf5&!@T5&_cPe*6Fc00(qQO+^Re3k(Y-G^7xQmH+?%ZINFWYDQ`pmYNt6#xKOk{&?8)XoF|0000sAT*E#pJYr(42IZ}HA~1hkXS=V zHW1yV_$*)|)`i5nk}MaJZ6GOOH=0uhv4M=#t^xqEJQT&i9lF>60000<>&pI^U5r!Ox@Q;PJD^awr;B5V#p&cJQ^J3qcW^y$=)i#k z6K2ix6Fr=Ee$L4QM;uZOvK}ayOkka#;_l4e7UAm5`jbs4o8u(gqTM3%S$&S|nh+5_ r>8aBuUKQ0hZpEh*%qC2{70STiwnNy`-R-(R&<>&pIwk&Q#qvZdLR8z>az>Eak-aXNX*l<=SD9b69_I&k2? zhbJ?cl}&jjPqg|lzq9dF!j%J#84BEXo_@!^N@RZd{olcD6R*lOfl0hB<(hWfGdfBY uH?C7T-I^lp;dP_;*%Zed1?8=)85rE;BoFS|<>&pIwk&Q!bP0l+XkK0+C99 diff --git a/res/skins/Shade/btn/btn_hotcue_7.png b/res/skins/Shade/btn/btn_hotcue_7.png index f0821440d8c2d7f5d17b8d92a44861096ade4ae0..998978cde5e3c3facf533e73f67952e6aed2ca13 100644 GIT binary patch delta 3459 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 l4J6i;qj{Nfz)0;X004X(BpdL$8pBB0);Y jCd+w}m?c-nvNA9ndn$C^%r9>f&_o7LS3j3^P6(MR diff --git a/res/skins/Shade/btn/btn_hotcue_7_down.png b/res/skins/Shade/btn/btn_hotcue_7_down.png deleted file mode 100644 index c6da80d83a13fc0111ae00780334e47ff5565912..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 202 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 diff --git a/res/skins/Shade/btn/btn_hotcue_8_down.png b/res/skins/Shade/btn/btn_hotcue_8_down.png deleted file mode 100644 index 9644ffd1ca1b78f6c59dbd05e57013c15d18894b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VTavfC3&Vd9T(EcfWS|IVfk$L9 z0|U1Z2s2)~TlWVj$X?><>&pI^U5rzlWBz@GFF>IHPZ!4!i_^(driA}I@8Eji(18O7 zCd``WCwe&T{G5{qjyR+mWIa$YnZP|<9O*QuC@ivf+-1s276oLK67xmBkn k#%$Jx_QuAZE9;mT_HPn4pFH~~H_&VbPgg&ebxsLQ0C{gh_W%F@ diff --git a/res/skins/Shade/btn/btn_hotcue_8_over.png b/res/skins/Shade/btn/btn_hotcue_8_over.png deleted file mode 100644 index 331d76d12bf29fa1c117075a4264b68f58ddd981..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 601 zcmV-f0;c_mP)EX>4Tx04R}tkv&MmKpe$iQ%glEA{J3`$WR5rf~bh2R-p(LLaorMgUR(vXws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;i>s5Oix`&UicTt|@eeTcEna!CD@QK7TOgAjzb>gW_ zOXs{#9A-s1OMFf|YS0CVAGxl${KmQ9u)s6JMk+Z+93~bEEv&RKD;g^CByl9GYLqXe zUCwge;;fb`tZ`5N!cb0IUgA2C8D2mgcL-J1D{aW^Rx0|GC${V@atcY%7UyM6-rpMfi_=`YuS=}*$D zO)YW+bZr9{*G)~?11@)fz9(HaWJmJT6!LlC{fxdT1N7Vi9jk6{jeVRx04eG!aRVG2 z0>cH$Uh{Z&duwn1o@w;=1A4Y{s&4pKSO5S324YJ`L;(K){{a7>y{D4^000SaNLh0L z01FZT01FZU(%pXi00007bV*G`2jl?;2qFym9p38z0031EX>4Tx04R}tkv&MmKpe$iTT4YM4i-^y$WWauh>CR7DionYs1;guFuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|;_9U6A|?JWDYS_3;J6>}?mh0_0scmXsb<#%plX(p zP9}tGZdC}qB8VXjAdaxaOnpuiQ}7&L_we!cF2=LG&;2=imAuISpFljzbi*RvAfDN@ zbk6(45mu5E;&bA0gDyz?$aUG}H_kbWYY7*5n`d(!Ey()lA#h$6Gs(QqkMnX zWrgz=XSGset$XqphV$CWGS_L2Ac;jRL4*JqHIz|-g&3_GDJIgipYZSxJARQ|GP%lN zZ37qAZB5<-E_Z;zCtWfmM+(sN7Ye}p8GTa@=)VPe*4*A&`#607GSpS-1~@nb z#)_1^?(y#K&ffk#)9UXBleTiS%{j=S00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3labT3lag+-G2N4000McNliruuhdwn7ll;eVk%@uIVAQ}tXdnwdNw%loFJcq_CC#Z%kqduGbL!(WglHEMa_P`? pAqydwjVA2jlJzA2aa^R9fdIO~7iRVp+eH8X002ovPDHLkV1gpo1Z@BS diff --git a/res/skins/Shade/hotcue_button.xml b/res/skins/Shade/hotcue_button.xml index eeb31fbb4a2..40149e41b8d 100644 --- a/res/skins/Shade/hotcue_button.xml +++ b/res/skins/Shade/hotcue_button.xml @@ -6,13 +6,13 @@ 2 0 - skin:/btn/btn_hotcue__down.png + skin:/btn/btn_hotcue_.png skin:/btn/btn_hotcue_.png 1 - skin:/btn/btn_hotcue__overdown.png - skin:/btn/btn_hotcue__over.png + skin:/btn/btn_hotcue_.png + skin:/btn/btn_hotcue_.png ,hotcue__activate diff --git a/res/skins/Shade/style.qss b/res/skins/Shade/style.qss index ba426573ba5..38bdbcae5c0 100644 --- a/res/skins/Shade/style.qss +++ b/res/skins/Shade/style.qss @@ -783,3 +783,7 @@ QPushButton#pushButtonRepeatPlaylist { image: url(skin:/btn/btn_autodj_repeat_playlist.svg) no-repeat center center; } /* AutoDJ button icons */ + +#HotcueButton { + background-color: #aab2b7; +} From 123172cbe1f50b5681de9a29f9cca000b62eda7e Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Tue, 12 Nov 2019 22:38:34 +0100 Subject: [PATCH 024/158] Make hotcue button hover highlighting configurable --- res/skins/Deere/style.qss | 4 ++++ src/widget/wwidget.cpp | 10 ++++++---- src/widget/wwidget.h | 3 +++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index 53ff1e88846..5480087178c 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -1558,6 +1558,10 @@ WPushButton[value="2"]:hover { border: 1px solid #0080BE; } +#HotcueButton { + qproperty-shouldHighlightBackgroundOnHover: true; +} + #HotcueButton[backgroundIsDark=true][hasBackgroundColor=true] { color: #FDFDFD; } diff --git a/src/widget/wwidget.cpp b/src/widget/wwidget.cpp index f85c3433651..5d523663139 100644 --- a/src/widget/wwidget.cpp +++ b/src/widget/wwidget.cpp @@ -26,7 +26,8 @@ WWidget::WWidget(QWidget* parent, Qt::WindowFlags flags) : QWidget(parent, flags), WBaseWidget(this), m_activeTouchButton(Qt::NoButton), - m_scaleFactor(1.0) { + m_scaleFactor(1.0), + m_bShouldHighlightBackgroundOnHover(false) { m_pTouchShift = new ControlProxy("[Controls]", "touch_shift"); setAttribute(Qt::WA_StaticContents); setAttribute(Qt::WA_AcceptTouchEvents); @@ -47,9 +48,10 @@ double WWidget::getBackgroundColorRgba() const { void WWidget::setBackgroundColorRgba(double rgba) { QColor backgroundColor = QColor::fromRgba(rgba); QColor highlightedBackgroundColor = backgroundColor.lighter(); - QString style = - QString("WWidget { background-color: %1; }" - "WWidget:hover { background-color: %2; }"); + QString style = QString("WWidget { background-color: %1; }"); + if (m_bShouldHighlightBackgroundOnHover) { + style += "WWidget:hover { background-color: %2; }"; + } if (rgba >= 0) { setStyleSheet(style.arg(backgroundColor.name()) diff --git a/src/widget/wwidget.h b/src/widget/wwidget.h index e0956488834..0fbf10631c2 100644 --- a/src/widget/wwidget.h +++ b/src/widget/wwidget.h @@ -47,6 +47,8 @@ class WWidget : public QWidget, public WBaseWidget { Q_PROPERTY(double value READ getControlParameterDisplay); Q_PROPERTY(double backgroundColorRgba READ getBackgroundColorRgba WRITE setBackgroundColorRgba); + Q_PROPERTY(bool shouldHighlightBackgroundOnHover MEMBER + m_bShouldHighlightBackgroundOnHover); Q_PROPERTY(bool hasBackgroundColor READ hasBackgroundColor); Q_PROPERTY(bool backgroundIsDark READ backgroundIsDark); @@ -76,6 +78,7 @@ class WWidget : public QWidget, public WBaseWidget { double m_scaleFactor; double m_backgroundColorRgba; bool m_bBackgroundIsDark; + bool m_bShouldHighlightBackgroundOnHover; }; #endif From f3153b7db95561d1d01ae211edb650143f6792f1 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sun, 17 Nov 2019 12:54:39 +0100 Subject: [PATCH 025/158] Fix auto_hotcue_colors not assigning first color --- src/engine/controls/cuecontrol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index 5f45195c0f7..8a3cf182618 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -604,7 +604,7 @@ void CueControl::hotcueSet(HotcueControl* pControl, double v) { ConfigKey autoHotcueColorsKey("[Controls]", "auto_hotcue_colors"); if (getConfig()->getValue(autoHotcueColorsKey, false)) { auto colors = hotcueColorPalette.m_colorList; - pCue->setColor(colors.at((hotcue % (colors.count() - 1)) + 1)); + pCue->setColor(colors.at(hotcue % colors.count())); } else { pCue->setColor(hotcueColorPalette.m_colorList.first()); }; From 39928d64db1abfb0663c482007d16c72d4ddc837 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 26 Feb 2020 16:42:09 +0100 Subject: [PATCH 026/158] Migrate hotcue color logic to mixxx::RgbColor --- src/controllers/colorjsproxy.cpp | 19 ++++--- src/engine/controls/cuecontrol.cpp | 36 +++++++----- src/engine/controls/cuecontrol.h | 4 +- src/library/dao/cuedao.cpp | 14 +++-- src/preferences/configobject.cpp | 55 +++++++++++++++---- .../hotcuecolorpalettesettings.cpp | 12 ++-- src/test/colorconfig_test.cpp | 54 ++++++++---------- src/test/controllerengine_test.cpp | 24 ++++---- src/track/cue.cpp | 9 +-- src/track/cue.h | 13 +++-- src/util/color/colorpalette.cpp | 17 +++--- src/util/color/colorpalette.h | 15 ++--- src/waveform/renderers/waveformrendermark.cpp | 2 +- src/widget/wcolorpicker.cpp | 29 ++++++---- src/widget/wcolorpicker.h | 10 ++-- src/widget/wcolorpickeraction.cpp | 2 +- src/widget/wcolorpickeraction.h | 4 +- src/widget/wcuemenupopup.cpp | 9 ++- src/widget/wcuemenupopup.h | 2 +- src/widget/woverview.cpp | 4 +- src/widget/wtracktableview.cpp | 6 +- src/widget/wtracktableview.h | 2 +- 22 files changed, 194 insertions(+), 148 deletions(-) diff --git a/src/controllers/colorjsproxy.cpp b/src/controllers/colorjsproxy.cpp index f7ef331f704..24aa43797ee 100644 --- a/src/controllers/colorjsproxy.cpp +++ b/src/controllers/colorjsproxy.cpp @@ -1,5 +1,7 @@ #include "controllers/colorjsproxy.h" + #include "preferences/hotcuecolorpalettesettings.h" +#include "util/color/rgbcolor.h" ColorJSProxy::ColorJSProxy(QScriptEngine* pScriptEngine, HotcueColorPaletteSettings colorPaletteSettings) @@ -16,25 +18,24 @@ Q_INVOKABLE QScriptValue ColorJSProxy::hotcueColorPalette() { } QScriptValue ColorJSProxy::colorFromHexCode(uint colorCode) { - QColor color = QColor::fromRgba(colorCode); + QRgb rgb = QRgb(colorCode); QScriptValue jsColor = m_pScriptEngine->newObject(); - jsColor.setProperty("red", color.red()); - jsColor.setProperty("green", color.green()); - jsColor.setProperty("blue", color.blue()); - jsColor.setProperty("alpha", color.alpha()); + jsColor.setProperty("red", qRed(rgb)); + jsColor.setProperty("green", qGreen(rgb)); + jsColor.setProperty("blue", qBlue(rgb)); + jsColor.setProperty("alpha", qAlpha(rgb)); return jsColor; } QScriptValue ColorJSProxy::makeHotcueColorPalette(QScriptEngine* pScriptEngine, HotcueColorPaletteSettings colorPaletteSettings) { // TODO: make sure we get notified when the palette changes - QList colorList = - colorPaletteSettings.getHotcueColorPalette().m_colorList; + QList colorList = colorPaletteSettings.getHotcueColorPalette().m_colorList; int numColors = colorList.length(); QScriptValue jsColorList = pScriptEngine->newArray(numColors); for (int i = 0; i < numColors; ++i) { - QColor color = colorList.at(i); - jsColorList.setProperty(i, colorFromHexCode(color.rgba())); + mixxx::RgbColor color = colorList.at(i); + jsColorList.setProperty(i, colorFromHexCode(color)); } return jsColorList; } diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index 8a3cf182618..ae38a9900c5 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -318,7 +318,7 @@ void CueControl::detachCue(HotcueControl* pControl) { disconnect(pCue.get(), 0, this, 0); pControl->resetCue(); // Reset the color CO to -1 - pControl->setColor(QColor()); + pControl->setColor(std::nullopt); } void CueControl::trackLoaded(TrackPointer pNewTrack) { @@ -1694,8 +1694,11 @@ void CueControl::hotcueFocusColorPrev(double v) { return; } - QColor color = pControl->getColor(); - DEBUG_ASSERT(color.isValid()); + mixxx::RgbColor::optional_t controlColor = pControl->getColor(); + if (!controlColor) { + return; + } + mixxx::RgbColor color = controlColor.value(); HotcueColorPaletteSettings m_colorPaletteSettings(m_pConfig); ColorPalette colorPalette = m_colorPaletteSettings.getHotcueColorPalette(); @@ -1725,8 +1728,11 @@ void CueControl::hotcueFocusColorNext(double v) { return; } - QColor color = pControl->getColor(); - DEBUG_ASSERT(color.isValid()); + mixxx::RgbColor::optional_t controlColor = pControl->getColor(); + if (!controlColor) { + return; + } + mixxx::RgbColor color = controlColor.value(); HotcueColorPaletteSettings colorPaletteSettings(m_pConfig); ColorPalette colorPalette = colorPaletteSettings.getHotcueColorPalette(); @@ -1857,7 +1863,7 @@ void HotcueControl::slotHotcuePositionChanged(double newPosition) { } void HotcueControl::slotHotcueColorChanged(double newColor) { - m_pCue->setColor(QColor::fromRgba(newColor)); + m_pCue->setColor(mixxx::RgbColor(newColor)); emit(hotcueColorChanged(this, newColor)); } @@ -1872,16 +1878,20 @@ void HotcueControl::setCue(CuePointer pCue) { // because we have a null check for valid data else where in the code m_pCue = pCue; } -QColor HotcueControl::getColor() const { - return QColor::fromRgba(m_hotcueColor->get()); +mixxx::RgbColor::optional_t HotcueControl::getColor() const { + double value = m_hotcueColor->get(); + if (value < 0) { + return std::nullopt; + } + return mixxx::RgbColor(value); } -void HotcueControl::setColor(const QColor& newColor) { - if (newColor.isValid()) { - m_hotcueColor->set(newColor.rgba()); - } else { - m_hotcueColor->set(-1); +void HotcueControl::setColor(const mixxx::RgbColor::optional_t& newColor) { + if (newColor) { + m_hotcueColor->set(newColor.value()); + return; } + m_hotcueColor->set(-1); } void HotcueControl::resetCue() { // clear pCue first because we have a null check for valid data else where diff --git a/src/engine/controls/cuecontrol.h b/src/engine/controls/cuecontrol.h index 414191fdf06..ef4432d8b5f 100644 --- a/src/engine/controls/cuecontrol.h +++ b/src/engine/controls/cuecontrol.h @@ -51,8 +51,8 @@ class HotcueControl : public QObject { void setCue(CuePointer pCue); void resetCue(); void setPosition(double position); - void setColor(const QColor& newColor); - QColor getColor() const; + void setColor(const mixxx::RgbColor::optional_t& newColor); + mixxx::RgbColor::optional_t getColor() const; // Used for caching the preview state of this hotcue control. inline bool isPreviewing() { diff --git a/src/library/dao/cuedao.cpp b/src/library/dao/cuedao.cpp index e43859645ee..0781c5752dd 100644 --- a/src/library/dao/cuedao.cpp +++ b/src/library/dao/cuedao.cpp @@ -1,15 +1,17 @@ // cuedao.cpp // Created 10/26/2009 by RJ Ryan (rryan@mit.edu) +#include "library/dao/cuedao.h" + +#include #include #include -#include -#include "library/dao/cuedao.h" +#include "library/queryutil.h" #include "track/cue.h" #include "track/track.h" -#include "library/queryutil.h" #include "util/assert.h" +#include "util/color/rgbcolor.h" #include "util/performancetimer.h" int CueDAO::cueCount() { @@ -52,7 +54,7 @@ CuePointer CueDAO::cueFromRow(const QSqlQuery& query) const { int hotcue = record.value(record.indexOf("hotcue")).toInt(); QString label = record.value(record.indexOf("label")).toString(); uint colorValue = record.value(record.indexOf("color")).toUInt(); - QColor color = QColor::fromRgba(colorValue); + mixxx::RgbColor color = mixxx::RgbColor(colorValue); CuePointer pCue(new Cue(id, trackId, (Cue::Type)type, @@ -152,7 +154,7 @@ bool CueDAO::saveCue(Cue* cue) { query.bindValue(":length", cue->getLength()); query.bindValue(":hotcue", cue->getHotCue()); query.bindValue(":label", cue->getLabel()); - query.bindValue(":color", cue->getColor().rgba()); + query.bindValue(":color", static_cast(cue->getColor())); if (query.exec()) { int id = query.lastInsertId().toInt(); @@ -180,7 +182,7 @@ bool CueDAO::saveCue(Cue* cue) { query.bindValue(":length", cue->getLength()); query.bindValue(":hotcue", cue->getHotCue()); query.bindValue(":label", cue->getLabel()); - query.bindValue(":color", cue->getColor().rgba()); + query.bindValue(":color", static_cast(cue->getColor())); if (query.exec()) { cue->setDirty(false); diff --git a/src/preferences/configobject.cpp b/src/preferences/configobject.cpp index 22900ac4e48..a05030b039e 100644 --- a/src/preferences/configobject.cpp +++ b/src/preferences/configobject.cpp @@ -1,14 +1,15 @@ #include "preferences/configobject.h" -#include -#include #include #include +#include +#include #include -#include "widget/wwidget.h" #include "util/cmdlineargs.h" +#include "util/color/rgbcolor.h" #include "util/xml.h" +#include "widget/wwidget.h" // TODO(rryan): Move to a utility file. namespace { @@ -285,8 +286,19 @@ void ConfigObject::setValue( template<> template<> void ConfigObject::setValue( - const ConfigKey& key, const QColor& value) { - set(key, ConfigValue(value.name(QColor::NameFormat::HexArgb))); + const ConfigKey& key, const mixxx::RgbColor::optional_t& value) { + if (!value) { + set(key, ConfigValue("")); + return; + } + set(key, ConfigValue(mixxx::toQColor(value.value()).name(QColor::NameFormat::HexArgb))); +} + +template<> +template<> +void ConfigObject::setValue( + const ConfigKey& key, const mixxx::RgbColor& value) { + set(key, ConfigValue(mixxx::toQColor(value).name(QColor::NameFormat::HexArgb))); } template <> template <> @@ -327,20 +339,41 @@ double ConfigObject::getValue( template<> template<> -QColor ConfigObject::getValue( - const ConfigKey& key, const QColor& default_value) const { +mixxx::RgbColor::optional_t ConfigObject::getValue( + const ConfigKey& key, const mixxx::RgbColor::optional_t& default_value) const { const ConfigValue value = get(key); if (value.isNull()) { return default_value; } - auto color = QColor(value.value); - return color.isValid() ? color : default_value; + QColor parsedColor(value.value); + if (!parsedColor.isValid()) { + return default_value; + } + auto color = mixxx::RgbColor::optional_t(parsedColor.rgb()); + return color ? color : default_value; +} + +template<> +template<> +mixxx::RgbColor::optional_t ConfigObject::getValue(const ConfigKey& key) const { + return getValue(key, mixxx::RgbColor::optional_t(std::nullopt)); +} + +template<> +template<> +mixxx::RgbColor ConfigObject::getValue( + const ConfigKey& key, const mixxx::RgbColor& default_value) const { + const mixxx::RgbColor::optional_t value = getValue(key, mixxx::RgbColor::optional_t(std::nullopt)); + if (!value) { + return default_value; + } + return *value; } template<> template<> -QColor ConfigObject::getValue(const ConfigKey& key) const { - return getValue(key, QColor()); +mixxx::RgbColor ConfigObject::getValue(const ConfigKey& key) const { + return getValue(key, mixxx::RgbColor(0)); } // For string literal default diff --git a/src/preferences/hotcuecolorpalettesettings.cpp b/src/preferences/hotcuecolorpalettesettings.cpp index 4faf0f93086..76903b054e0 100644 --- a/src/preferences/hotcuecolorpalettesettings.cpp +++ b/src/preferences/hotcuecolorpalettesettings.cpp @@ -3,12 +3,10 @@ const QString HotcueColorPaletteSettings::sGroup = "[HotcueColorPalette]"; ColorPalette HotcueColorPaletteSettings::getHotcueColorPalette() const { - QList colorList; + QList colorList; for (const ConfigKey& key : m_pConfig->getKeysWithGroup(sGroup)) { - QColor color = m_pConfig->getValue(key); - if (color.isValid()) { - colorList.append(color); - } + mixxx::RgbColor color = mixxx::RgbColor(m_pConfig->getValue(key, mixxx::RgbColor(0))); + colorList.append(color); } // If no palette is defined in the settings, we use the default one. @@ -24,8 +22,8 @@ void HotcueColorPaletteSettings::setHotcueColorPalette( removePalette(); for (int index = 0; index < colorPalette.m_colorList.count(); ++index) { - QColor color = colorPalette.m_colorList[index]; - m_pConfig->setValue(keyForIndex(index), color); + mixxx::RgbColor color = colorPalette.m_colorList[index]; + m_pConfig->setValue(keyForIndex(index), color); } } diff --git a/src/test/colorconfig_test.cpp b/src/test/colorconfig_test.cpp index 477bab40a52..81a5e36fdbe 100644 --- a/src/test/colorconfig_test.cpp +++ b/src/test/colorconfig_test.cpp @@ -1,45 +1,35 @@ #include -#include +#include "preferences/hotcuecolorpalettesettings.h" #include "test/mixxxtest.h" - -#include -#include +#include "util/color/colorpalette.h" +#include "util/color/rgbcolor.h" class ColorConfigTest : public MixxxTest {}; -TEST_F(ColorConfigTest, SavingColorWithoutAlpha) { - ConfigKey key("[Color]", "color"); - QColor originalColor("#FF9900"); - config()->setValue(key, originalColor); - saveAndReloadConfig(); - QColor colorFromConfig = config()->getValue(key); - ASSERT_EQ(originalColor, colorFromConfig); -} - -TEST_F(ColorConfigTest, SavingColorWithAlpha) { +TEST_F(ColorConfigTest, SavingColor) { ConfigKey key("[Color]", "color"); - QColor originalColor("#66FF9900"); + mixxx::RgbColor originalColor(0xFF9900); config()->setValue(key, originalColor); saveAndReloadConfig(); - QColor colorFromConfig = config()->getValue(key); + mixxx::RgbColor colorFromConfig = config()->getValue(key, mixxx::RgbColor(0)); ASSERT_EQ(originalColor, colorFromConfig); } TEST_F(ColorConfigTest, GetDefaultColorWhenNoStoredColor) { ConfigKey key("[Color]", "color"); - QColor defaultColor("#66FF9900"); - QColor colorFromConfig = config()->getValue(key, defaultColor); + mixxx::RgbColor defaultColor(0x66FF99); + mixxx::RgbColor colorFromConfig = config()->getValue(key, defaultColor); ASSERT_EQ(defaultColor, colorFromConfig); } TEST_F(ColorConfigTest, SaveColorPalette) { HotcueColorPaletteSettings colorPaletteSettings(config()); - ColorPalette originalColorPalette(QList{ - QColor("#66FF9900"), - QColor("#FF9900"), - QColor("#00000000"), - QColor("#FFFFFF"), + ColorPalette originalColorPalette(QList{ + mixxx::RgbColor(0x66FF99), + mixxx::RgbColor(0xFF9900), + mixxx::RgbColor(0x000000), + mixxx::RgbColor(0xFFFFFF), }); ConfigKey key("[ColorPalette]", "colorPalette"); colorPaletteSettings.setHotcueColorPalette(originalColorPalette); @@ -51,15 +41,15 @@ TEST_F(ColorConfigTest, SaveColorPalette) { TEST_F(ColorConfigTest, ReplaceColorPalette) { HotcueColorPaletteSettings colorPaletteSettings(config()); - ColorPalette colorPalette1(QList{ - QColor("#66FF9900"), - QColor("#FF9900"), - QColor("#00000000"), - QColor("#FFFFFF"), + ColorPalette colorPalette1(QList{ + mixxx::RgbColor(0x66FF99), + mixxx::RgbColor(0xFF9900), + mixxx::RgbColor(0x000000), + mixxx::RgbColor(0xFFFFFF), }); - ColorPalette colorPalette2(QList{ - QColor("#0000FF"), - QColor("#FF0000"), + ColorPalette colorPalette2(QList{ + mixxx::RgbColor(0x0000FF), + mixxx::RgbColor(0xFF0000), }); ConfigKey key("[ColorPalette]", "colorPalette"); colorPaletteSettings.setHotcueColorPalette(colorPalette1); @@ -75,5 +65,5 @@ TEST_F(ColorConfigTest, DefaultColorPalette) { HotcueColorPaletteSettings colorPaletteSettings(config()); ColorPalette colorPaletteFromConfig = colorPaletteSettings.getHotcueColorPalette(); - ASSERT_EQ(ColorPalette::mixxxHotcuesPalette, colorPaletteFromConfig); + ASSERT_EQ(ColorPalette::mixxxPalette, colorPaletteFromConfig); } diff --git a/src/test/controllerengine_test.cpp b/src/test/controllerengine_test.cpp index ea6a9ad0117..18976c5f342 100644 --- a/src/test/controllerengine_test.cpp +++ b/src/test/controllerengine_test.cpp @@ -620,23 +620,23 @@ TEST_F(ControllerEngineTest, connectionExecutesWithCorrectThisObject) { } TEST_F(ControllerEngineTest, colorProxyTestMixxxPalette) { - QList allColors = ColorPalette::mixxxPalette.m_colorList; + QList allColors = ColorPalette::mixxxPalette.m_colorList; for (int i = 0; i < allColors.length(); ++i) { - QColor color = allColors[i]; - qDebug() << "Testing color " << color.name(); - QString colorCode = QString::number(color.rgba()); + mixxx::RgbColor color = allColors[i]; + qDebug() << "Testing color " << mixxx::RgbColor::toQString(color); + QString colorCode = QString::number(color); QScriptValue jsColor = pScriptEngine->evaluate( "color.colorFromHexCode(" + colorCode + ")"); - EXPECT_EQ(jsColor.property("red").toInt32(), color.red()); - EXPECT_EQ(jsColor.property("green").toInt32(), color.green()); - EXPECT_EQ(jsColor.property("blue").toInt32(), color.blue()); - EXPECT_EQ(jsColor.property("alpha").toInt32(), color.alpha()); + EXPECT_EQ(jsColor.property("red").toInt32(), qRed(color)); + EXPECT_EQ(jsColor.property("green").toInt32(), qGreen(color)); + EXPECT_EQ(jsColor.property("blue").toInt32(), qBlue(color)); + EXPECT_EQ(jsColor.property("alpha").toInt32(), qAlpha(color)); QScriptValue jsColor2 = pScriptEngine->evaluate( "color.hotcueColorPalette()[" + QString::number(i) + "]"); - EXPECT_EQ(jsColor2.property("red").toInt32(), color.red()); - EXPECT_EQ(jsColor2.property("green").toInt32(), color.green()); - EXPECT_EQ(jsColor2.property("blue").toInt32(), color.blue()); - EXPECT_EQ(jsColor2.property("alpha").toInt32(), color.alpha()); + EXPECT_EQ(jsColor2.property("red").toInt32(), qRed(color)); + EXPECT_EQ(jsColor2.property("green").toInt32(), qGreen(color)); + EXPECT_EQ(jsColor2.property("blue").toInt32(), qBlue(color)); + EXPECT_EQ(jsColor2.property("alpha").toInt32(), qAlpha(color)); } } diff --git a/src/track/cue.cpp b/src/track/cue.cpp index 99ec0f74271..286d2269aa5 100644 --- a/src/track/cue.cpp +++ b/src/track/cue.cpp @@ -10,6 +10,7 @@ namespace { const QString kDefaultLabel = ""; // empty string, not null + const mixxx::RgbColor kDefaultCueColor = mixxx::RgbColor(0xFFF2F2FF); // white } //static @@ -28,7 +29,7 @@ Cue::Cue(TrackId trackId) m_sampleEndPosition(Cue::kNoPosition), m_iHotCue(-1), m_label(kDefaultLabel), - m_color(QColor()) { + m_color(kDefaultCueColor) { DEBUG_ASSERT(!m_label.isNull()); } @@ -39,7 +40,7 @@ Cue::Cue(int id, double length, int hotCue, QString label, - QColor color) + mixxx::RgbColor color) : m_bDirty(false), m_iId(id), m_trackId(trackId), @@ -159,12 +160,12 @@ void Cue::setLabel(const QString label) { emit updated(); } -QColor Cue::getColor() const { +mixxx::RgbColor Cue::getColor() const { QMutexLocker lock(&m_mutex); return m_color; } -void Cue::setColor(const QColor& color) { +void Cue::setColor(const mixxx::RgbColor& color) { QMutexLocker lock(&m_mutex); m_color = color; m_bDirty = true; diff --git a/src/track/cue.h b/src/track/cue.h index 9b6d133766a..cf86b4393d8 100644 --- a/src/track/cue.h +++ b/src/track/cue.h @@ -1,11 +1,12 @@ #ifndef MIXXX_CUE_H #define MIXXX_CUE_H -#include -#include #include +#include +#include #include "track/trackid.h" +#include "util/color/rgbcolor.h" #include "util/memory.h" class CuePosition; @@ -53,8 +54,8 @@ class Cue : public QObject { QString getLabel() const; void setLabel(QString label); - QColor getColor() const; - void setColor(const QColor& color); + mixxx::RgbColor getColor() const; + void setColor(const mixxx::RgbColor& color); double getEndPosition() const; @@ -70,7 +71,7 @@ class Cue : public QObject { double length, int hotCue, QString label, - QColor color); + mixxx::RgbColor color); void setDirty(bool dirty); void setId(int id); void setTrackId(TrackId trackId); @@ -85,7 +86,7 @@ class Cue : public QObject { double m_sampleEndPosition; int m_iHotCue; QString m_label; - QColor m_color; + mixxx::RgbColor m_color; friend class Track; friend class CueDAO; diff --git a/src/util/color/colorpalette.cpp b/src/util/color/colorpalette.cpp index 3f16c8f676d..9b3a3f725ff 100644 --- a/src/util/color/colorpalette.cpp +++ b/src/util/color/colorpalette.cpp @@ -1,11 +1,12 @@ #include "colorpalette.h" const ColorPalette ColorPalette::mixxxPalette = - ColorPalette(QList{QColor("#c50a08"), - QColor("#32be44"), - QColor("#0044ff"), - QColor("#f8d200"), - QColor("#42d4f4"), - QColor("#af00cc"), - QColor("#fca6d7"), - QColor("#f2f2ff")}); + ColorPalette(QList{ + mixxx::RgbColor(0xC50A08), + mixxx::RgbColor(0x32BE44), + mixxx::RgbColor(0x0044FF), + mixxx::RgbColor(0xF8D200), + mixxx::RgbColor(0x42D4F4), + mixxx::RgbColor(0xAF00CC), + mixxx::RgbColor(0xFCA6D7), + mixxx::RgbColor(0xF2F2FF)}); diff --git a/src/util/color/colorpalette.h b/src/util/color/colorpalette.h index 5bd2eb836d8..26375fe76f7 100644 --- a/src/util/color/colorpalette.h +++ b/src/util/color/colorpalette.h @@ -1,15 +1,16 @@ #pragma once -#include #include +#include "util/color/rgbcolor.h" + class ColorPalette { public: - ColorPalette(QList colorList) + ColorPalette(QList colorList) : m_colorList(colorList) { } - QColor at(int i) const { + mixxx::RgbColor at(int i) const { return m_colorList.at(i); } @@ -17,21 +18,21 @@ class ColorPalette { return m_colorList.size(); } - int indexOf(QColor color) const { + int indexOf(mixxx::RgbColor color) const { return m_colorList.indexOf(color); } - QList::const_iterator begin() const { + QList::const_iterator begin() const { return m_colorList.begin(); } - QList::const_iterator end() const { + QList::const_iterator end() const { return m_colorList.end(); } static const ColorPalette mixxxPalette; - QList m_colorList; + QList m_colorList; }; inline bool operator==( diff --git a/src/waveform/renderers/waveformrendermark.cpp b/src/waveform/renderers/waveformrendermark.cpp index 26a840e8974..61aa4f1b1f5 100644 --- a/src/waveform/renderers/waveformrendermark.cpp +++ b/src/waveform/renderers/waveformrendermark.cpp @@ -123,7 +123,7 @@ void WaveformRenderMark::slotCuesUpdated() { } QString newLabel = pCue->getLabel(); - QColor newColor = pCue->getColor(); + QColor newColor = mixxx::RgbColor::toQColor(pCue->getColor()); if (pMark->m_text.isNull() || newLabel != pMark->m_text || !pMark->fillColor().isValid() || newColor != pMark->fillColor()) { pMark->m_text = newLabel; diff --git a/src/widget/wcolorpicker.cpp b/src/widget/wcolorpicker.cpp index 717ea97a27f..f74a121569c 100644 --- a/src/widget/wcolorpicker.cpp +++ b/src/widget/wcolorpicker.cpp @@ -36,7 +36,7 @@ WColorPicker::WColorPicker(ColorOption colorOption, QWidget* parent) int column = 0; if (m_colorOption == ColorOption::AllowNoColor) { - addColorButton(QColor(), pLayout, row, column); + addColorButton(std::nullopt, pLayout, row, column); column++; } @@ -50,17 +50,17 @@ WColorPicker::WColorPicker(ColorOption colorOption, QWidget* parent) } } -void WColorPicker::addColorButton(const QColor& color, QGridLayout* pLayout, int row, int column) { +void WColorPicker::addColorButton(const mixxx::RgbColor::optional_t& color, QGridLayout* pLayout, int row, int column) { setLayout(pLayout); parented_ptr pColorButton = make_parented("", this); if (m_pStyle) { pColorButton->setStyle(m_pStyle); } - if (color.isValid()) { + if (color) { // Set the background color of the button. This can't be overridden in skin stylesheets. pColorButton->setStyleSheet( - QString("QPushButton { background-color: %1; }").arg(color.name())); + QString("QPushButton { background-color: %1; }").arg(mixxx::RgbColor::toQString(color))); } else { pColorButton->setProperty("noColor", true); } @@ -85,10 +85,13 @@ void WColorPicker::addColorButton(const QColor& color, QGridLayout* pLayout, int void WColorPicker::resetSelectedColor() { // Unset currently selected color int i; - if (m_colorOption == ColorOption::AllowNoColor && !m_selectedColor.isValid()) { + if (!m_selectedColor) { + if (m_colorOption != ColorOption::AllowNoColor) { + return; + } i = 0; } else { - i = m_palette.indexOf(m_selectedColor); + i = m_palette.indexOf(m_selectedColor.value()); if (i == -1) { return; } @@ -109,16 +112,19 @@ void WColorPicker::resetSelectedColor() { pButton->style()->polish(pButton); } -void WColorPicker::setSelectedColor(const QColor& color) { +void WColorPicker::setSelectedColor(const mixxx::RgbColor::optional_t& color) { resetSelectedColor(); m_selectedColor = color; int i; - if (m_colorOption == ColorOption::AllowNoColor && !color.isValid()) { + if (!color) { + if (m_colorOption != ColorOption::AllowNoColor) { + return; + } i = 0; } else { - i = m_palette.indexOf(color); + i = m_palette.indexOf(color.value()); if (i == -1) { return; } @@ -153,11 +159,10 @@ void WColorPicker::useColorSet(const ColorPalette& palette) { // Set the background color of the button. This can't be overridden in skin stylesheets. m_colorButtons.at(j)->setStyleSheet( QString("QPushButton { background-color: %1; }") - .arg(palette.at(i).name())); + .arg(mixxx::RgbColor::toQString(palette.at(i)))); } } - -void WColorPicker::slotColorPicked(const QColor& color) { +void WColorPicker::slotColorPicked(const mixxx::RgbColor::optional_t& color) { setSelectedColor(color); } diff --git a/src/widget/wcolorpicker.h b/src/widget/wcolorpicker.h index cb3d45e6b32..2a97b2e0cfe 100644 --- a/src/widget/wcolorpicker.h +++ b/src/widget/wcolorpicker.h @@ -20,19 +20,19 @@ class WColorPicker : public QWidget { explicit WColorPicker(ColorOption colorOption, QWidget* parent = nullptr); void resetSelectedColor(); - void setSelectedColor(const QColor& color); + void setSelectedColor(const mixxx::RgbColor::optional_t& color); void useColorSet(const ColorPalette& palette); signals: - void colorPicked(QColor color); + void colorPicked(mixxx::RgbColor::optional_t color); private slots: - void slotColorPicked(const QColor& color); + void slotColorPicked(const mixxx::RgbColor::optional_t& color); private: - void addColorButton(const QColor& color, QGridLayout* pLayout, int row, int column); + void addColorButton(const mixxx::RgbColor::optional_t& color, QGridLayout* pLayout, int row, int column); ColorOption m_colorOption; - QColor m_selectedColor; + mixxx::RgbColor::optional_t m_selectedColor; ColorPalette m_palette; QList m_colorButtons; QStyle* m_pStyle; diff --git a/src/widget/wcolorpickeraction.cpp b/src/widget/wcolorpickeraction.cpp index 5270a75a4ba..6c2afc65798 100644 --- a/src/widget/wcolorpickeraction.cpp +++ b/src/widget/wcolorpickeraction.cpp @@ -17,6 +17,6 @@ void WColorPickerAction::resetSelectedColor() { m_pColorPicker->resetSelectedColor(); } -void WColorPickerAction::setSelectedColor(QColor color) { +void WColorPickerAction::setSelectedColor(mixxx::RgbColor::optional_t color) { m_pColorPicker->setSelectedColor(color); } diff --git a/src/widget/wcolorpickeraction.h b/src/widget/wcolorpickeraction.h index 9c9ced435bd..e565f330043 100644 --- a/src/widget/wcolorpickeraction.h +++ b/src/widget/wcolorpickeraction.h @@ -15,10 +15,10 @@ class WColorPickerAction : public QWidgetAction { QWidget* parent = nullptr); void resetSelectedColor(); - void setSelectedColor(QColor color = QColor()); + void setSelectedColor(mixxx::RgbColor::optional_t color); signals: - void colorPicked(QColor color); + void colorPicked(mixxx::RgbColor::optional_t color); private: parented_ptr m_pColorPicker; diff --git a/src/widget/wcuemenupopup.cpp b/src/widget/wcuemenupopup.cpp index 97a2cff3ea6..9e22308fdb6 100644 --- a/src/widget/wcuemenupopup.cpp +++ b/src/widget/wcuemenupopup.cpp @@ -97,7 +97,7 @@ void WCueMenuPopup::setTrackAndCue(TrackPointer pTrack, CuePointer pCue) { m_pCueNumber->setText(QString("")); m_pCuePosition->setText(QString("")); m_pEditLabel->setText(QString("")); - m_pColorPicker->setSelectedColor(QColor()); + m_pColorPicker->setSelectedColor(std::nullopt); } } @@ -108,11 +108,14 @@ void WCueMenuPopup::slotEditLabel() { m_pCue->setLabel(m_pEditLabel->text()); } -void WCueMenuPopup::slotChangeCueColor(const QColor& color) { +void WCueMenuPopup::slotChangeCueColor(const mixxx::RgbColor::optional_t& color) { VERIFY_OR_DEBUG_ASSERT(m_pCue != nullptr) { return; } - m_pCue->setColor(color); + VERIFY_OR_DEBUG_ASSERT(color) { + return; + } + m_pCue->setColor(color.value()); m_pColorPicker->setSelectedColor(color); hide(); } diff --git a/src/widget/wcuemenupopup.h b/src/widget/wcuemenupopup.h index 1861a82203b..14d448d91e9 100644 --- a/src/widget/wcuemenupopup.h +++ b/src/widget/wcuemenupopup.h @@ -54,7 +54,7 @@ class WCueMenuPopup : public QWidget { private slots: void slotEditLabel(); void slotDeleteCue(); - void slotChangeCueColor(const QColor& color); + void slotChangeCueColor(const mixxx::RgbColor::optional_t& color); private: CuePointer m_pCue; diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index 4b7a74814c7..c72cbea0873 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -350,7 +350,7 @@ void WOverview::updateCues(const QList &loadedCues) { if (pMark != nullptr && pMark->isValid() && pMark->isVisible() && pMark->getSamplePosition() != Cue::kNoPosition) { - QColor newColor = currentCue->getColor(); + QColor newColor = mixxx::RgbColor::toQColor(currentCue->getColor()); if (newColor != pMark->fillColor() || newColor != pMark->m_textColor) { pMark->setBaseColor(newColor); } @@ -1096,7 +1096,7 @@ double WOverview::samplePositionToSeconds(double sample) { } void WOverview::resizeEvent(QResizeEvent* pEvent) { - Q_UNUSED(pEvent); + Q_UNUSED(pEvent); // Play-position potmeters range from 0 to 1 but they allow out-of-range // sets. This is to give VC access to the pre-roll area. const double kMaxPlayposRange = 1.0; diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 740e8d08258..b393f0dbc60 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -1110,7 +1110,7 @@ void WTrackTableView::contextMenuEvent(QContextMenuEvent* event) { if (multipleTrackColors) { m_pColorPickerAction->resetSelectedColor(); } else { - m_pColorPickerAction->setSelectedColor(toQColor(trackColor)); + m_pColorPickerAction->setSelectedColor(trackColor); } m_pColorMenu->addAction(m_pColorPickerAction); m_pMenu->addMenu(m_pColorMenu); @@ -1970,7 +1970,7 @@ void WTrackTableView::lockBpm(bool lock) { } } -void WTrackTableView::slotColorPicked(const QColor& color) { +void WTrackTableView::slotColorPicked(const mixxx::RgbColor::optional_t& color) { TrackModel* trackModel = getTrackModel(); if (trackModel == nullptr) { return; @@ -1980,7 +1980,7 @@ void WTrackTableView::slotColorPicked(const QColor& color) { // TODO: This should be done in a thread for large selections for (const auto& index : selectedTrackIndices) { TrackPointer track = trackModel->getTrack(index); - track->setColor(mixxx::RgbColor::optional(color)); + track->setColor(color); } m_pMenu->hide(); diff --git a/src/widget/wtracktableview.h b/src/widget/wtracktableview.h index 895731950fd..ef22de80807 100644 --- a/src/widget/wtracktableview.h +++ b/src/widget/wtracktableview.h @@ -81,7 +81,7 @@ class WTrackTableView : public WLibraryTableView { void slotLockBpm(); void slotUnlockBpm(); void slotScaleBpm(int); - void slotColorPicked(const QColor& color); + void slotColorPicked(const mixxx::RgbColor::optional_t& color); void slotClearBeats(); void slotClearPlayCount(); From f2595585fbb841c7f65a31b4cd7c6d583629b6c1 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 27 Feb 2020 11:04:03 +0100 Subject: [PATCH 027/158] engine/controls/cuecontrol: Use constant for no color control value --- src/engine/controls/cuecontrol.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index ae38a9900c5..b1fde7bbd93 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -23,6 +23,8 @@ static const double CUE_MODE_NUMARK = 3.0; static const double CUE_MODE_MIXXX_NO_BLINK = 4.0; static const double CUE_MODE_CUP = 5.0; +constexpr double kNoColorControlValue = -1; + CueControl::CueControl(QString group, UserSettingsPointer pConfig) : EngineControl(group, pConfig), @@ -1891,7 +1893,7 @@ void HotcueControl::setColor(const mixxx::RgbColor::optional_t& newColor) { m_hotcueColor->set(newColor.value()); return; } - m_hotcueColor->set(-1); + m_hotcueColor->set(kNoColorControlValue); } void HotcueControl::resetCue() { // clear pCue first because we have a null check for valid data else where From 5732911d6e4a05d811d0dd785c52eaea2735a193 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 27 Feb 2020 11:07:54 +0100 Subject: [PATCH 028/158] Use *value instead of value.value() for std::optional --- src/engine/controls/cuecontrol.cpp | 6 +++--- src/preferences/configobject.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index b1fde7bbd93..d36b71769b6 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -1700,7 +1700,7 @@ void CueControl::hotcueFocusColorPrev(double v) { if (!controlColor) { return; } - mixxx::RgbColor color = controlColor.value(); + mixxx::RgbColor color = *controlColor; HotcueColorPaletteSettings m_colorPaletteSettings(m_pConfig); ColorPalette colorPalette = m_colorPaletteSettings.getHotcueColorPalette(); @@ -1734,7 +1734,7 @@ void CueControl::hotcueFocusColorNext(double v) { if (!controlColor) { return; } - mixxx::RgbColor color = controlColor.value(); + mixxx::RgbColor color = *controlColor; HotcueColorPaletteSettings colorPaletteSettings(m_pConfig); ColorPalette colorPalette = colorPaletteSettings.getHotcueColorPalette(); @@ -1890,7 +1890,7 @@ mixxx::RgbColor::optional_t HotcueControl::getColor() const { void HotcueControl::setColor(const mixxx::RgbColor::optional_t& newColor) { if (newColor) { - m_hotcueColor->set(newColor.value()); + m_hotcueColor->set(*newColor); return; } m_hotcueColor->set(kNoColorControlValue); diff --git a/src/preferences/configobject.cpp b/src/preferences/configobject.cpp index a05030b039e..765bf6d18cb 100644 --- a/src/preferences/configobject.cpp +++ b/src/preferences/configobject.cpp @@ -291,7 +291,7 @@ void ConfigObject::setValue( set(key, ConfigValue("")); return; } - set(key, ConfigValue(mixxx::toQColor(value.value()).name(QColor::NameFormat::HexArgb))); + set(key, ConfigValue(mixxx::toQColor(*value).name(QColor::NameFormat::HexArgb))); } template<> From fafe58ba4b2609a9f9b7299e9baed717cb3d2c8d Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 27 Feb 2020 11:09:30 +0100 Subject: [PATCH 029/158] Fix RgbColor typecasts and range checks --- src/engine/controls/cuecontrol.cpp | 8 ++++++-- src/library/dao/cuedao.cpp | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index d36b71769b6..4df3369d6b6 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -1865,7 +1865,11 @@ void HotcueControl::slotHotcuePositionChanged(double newPosition) { } void HotcueControl::slotHotcueColorChanged(double newColor) { - m_pCue->setColor(mixxx::RgbColor(newColor)); + if (newColor < 0) { + qWarning() << "slotHotcueColorChanged got invalid value:" << newColor; + return; + } + m_pCue->setColor(mixxx::RgbColor(static_cast(newColor))); emit(hotcueColorChanged(this, newColor)); } @@ -1885,7 +1889,7 @@ mixxx::RgbColor::optional_t HotcueControl::getColor() const { if (value < 0) { return std::nullopt; } - return mixxx::RgbColor(value); + return mixxx::RgbColor(static_cast(value)); } void HotcueControl::setColor(const mixxx::RgbColor::optional_t& newColor) { diff --git a/src/library/dao/cuedao.cpp b/src/library/dao/cuedao.cpp index 0781c5752dd..2621a94e1c9 100644 --- a/src/library/dao/cuedao.cpp +++ b/src/library/dao/cuedao.cpp @@ -154,7 +154,7 @@ bool CueDAO::saveCue(Cue* cue) { query.bindValue(":length", cue->getLength()); query.bindValue(":hotcue", cue->getHotCue()); query.bindValue(":label", cue->getLabel()); - query.bindValue(":color", static_cast(cue->getColor())); + query.bindValue(":color", static_cast(cue->getColor())); if (query.exec()) { int id = query.lastInsertId().toInt(); @@ -182,7 +182,7 @@ bool CueDAO::saveCue(Cue* cue) { query.bindValue(":length", cue->getLength()); query.bindValue(":hotcue", cue->getHotCue()); query.bindValue(":label", cue->getLabel()); - query.bindValue(":color", static_cast(cue->getColor())); + query.bindValue(":color", static_cast(cue->getColor())); if (query.exec()) { cue->setDirty(false); From 37133d9c478626f0f0f2fbfd510ede58bc01766f Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 27 Feb 2020 11:10:06 +0100 Subject: [PATCH 030/158] engine/controls/cuecontrol: Pass RgbColor by value --- src/engine/controls/cuecontrol.cpp | 2 +- src/engine/controls/cuecontrol.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index 4df3369d6b6..a95dc4af0f4 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -1892,7 +1892,7 @@ mixxx::RgbColor::optional_t HotcueControl::getColor() const { return mixxx::RgbColor(static_cast(value)); } -void HotcueControl::setColor(const mixxx::RgbColor::optional_t& newColor) { +void HotcueControl::setColor(const mixxx::RgbColor::optional_t newColor) { if (newColor) { m_hotcueColor->set(*newColor); return; diff --git a/src/engine/controls/cuecontrol.h b/src/engine/controls/cuecontrol.h index ef4432d8b5f..59fccf385a0 100644 --- a/src/engine/controls/cuecontrol.h +++ b/src/engine/controls/cuecontrol.h @@ -51,7 +51,7 @@ class HotcueControl : public QObject { void setCue(CuePointer pCue); void resetCue(); void setPosition(double position); - void setColor(const mixxx::RgbColor::optional_t& newColor); + void setColor(const mixxx::RgbColor::optional_t newColor); mixxx::RgbColor::optional_t getColor() const; // Used for caching the preview state of this hotcue control. From ac28f215184aefff5667e0412513e7700c3d9fe9 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 27 Feb 2020 11:10:37 +0100 Subject: [PATCH 031/158] color/colorpalette: Improve readability by adding names to constants --- src/util/color/colorpalette.cpp | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/util/color/colorpalette.cpp b/src/util/color/colorpalette.cpp index 9b3a3f725ff..2b04c25b1eb 100644 --- a/src/util/color/colorpalette.cpp +++ b/src/util/color/colorpalette.cpp @@ -1,12 +1,22 @@ #include "colorpalette.h" +constexpr mixxx::RgbColor kColorMixxxRed = mixxx::RgbColor(0xC50A08); +constexpr mixxx::RgbColor kColorMixxxYellow = mixxx::RgbColor(0x32BE44); +constexpr mixxx::RgbColor kColorMixxxGreen = mixxx::RgbColor(0x0044FF); +constexpr mixxx::RgbColor kColorMixxxCeleste = mixxx::RgbColor(0xF8D200); +constexpr mixxx::RgbColor kColorMixxxBlue = mixxx::RgbColor(0x42D4F4); +constexpr mixxx::RgbColor kColorMixxxPurple = mixxx::RgbColor(0xAF00CC); +constexpr mixxx::RgbColor kColorMixxxPink = mixxx::RgbColor(0xFCA6D7); +constexpr mixxx::RgbColor kColorMixxxWhite = mixxx::RgbColor(0xF2F2FF); + const ColorPalette ColorPalette::mixxxPalette = ColorPalette(QList{ - mixxx::RgbColor(0xC50A08), - mixxx::RgbColor(0x32BE44), - mixxx::RgbColor(0x0044FF), - mixxx::RgbColor(0xF8D200), - mixxx::RgbColor(0x42D4F4), - mixxx::RgbColor(0xAF00CC), - mixxx::RgbColor(0xFCA6D7), - mixxx::RgbColor(0xF2F2FF)}); + kColorMixxxRed, + kColorMixxxYellow, + kColorMixxxGreen, + kColorMixxxCeleste, + kColorMixxxBlue, + kColorMixxxPurple, + kColorMixxxPink, + kColorMixxxWhite, + }); From a477c8747166bf6dc9e4e5142b60732592348a95 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 14 Nov 2019 16:33:19 +0100 Subject: [PATCH 032/158] src/controllers/colorjsproxy: Add nearestColorMidiCode function --- src/controllers/colorjsproxy.cpp | 45 ++++++++++++++++++++++++++++++++ src/controllers/colorjsproxy.h | 1 + 2 files changed, 46 insertions(+) diff --git a/src/controllers/colorjsproxy.cpp b/src/controllers/colorjsproxy.cpp index 24aa43797ee..7f93d524aaa 100644 --- a/src/controllers/colorjsproxy.cpp +++ b/src/controllers/colorjsproxy.cpp @@ -1,8 +1,26 @@ +#include +#include #include "controllers/colorjsproxy.h" #include "preferences/hotcuecolorpalettesettings.h" #include "util/color/rgbcolor.h" +namespace { + double colorDistance(QColor a, QColor b) + { + long mean_red = ((long)a.red() + (long)b.red()) / 2; + long delta_red = (long)a.red() - (long)b.red(); + long delta_green = (long)a.green() - (long)b.green(); + long delta_blue = (long)a.blue() - (long)b.blue(); + return sqrt( + (((512 + mean_red) * delta_red * delta_red) >> 8) + + (4 * delta_green * delta_green) + + (((767 - mean_red) * delta_blue * delta_blue) >> 8) + ); + } +} + + ColorJSProxy::ColorJSProxy(QScriptEngine* pScriptEngine, HotcueColorPaletteSettings colorPaletteSettings) : m_pScriptEngine(pScriptEngine), @@ -27,6 +45,33 @@ QScriptValue ColorJSProxy::colorFromHexCode(uint colorCode) { return jsColor; } +QScriptValue ColorJSProxy::nearestColorMidiCode(uint colorCode, QVariantMap availableColors) { + QColor desiredColor = QColor::fromRgba(colorCode); + uint nearestColorValue = 0; + double nearestColorDistance = qInf(); + QMapIterator it(availableColors); + while (it.hasNext()) { + it.next(); + QColor availableColor(it.key()); + VERIFY_OR_DEBUG_ASSERT(availableColor.isValid()) { + qWarning() << "Received invalid color name from controller script:" << it.key(); + continue; + } + + double distance = colorDistance(desiredColor, availableColor); + if (distance < nearestColorDistance) { + nearestColorDistance = distance; + bool valueOk; + nearestColorValue = it.value().toUInt(&valueOk); + VERIFY_OR_DEBUG_ASSERT(availableColor.isValid()) { + qWarning() << "Failed to convert value to uint:" << it.value(); + } + qDebug() << "Match for " << desiredColor << " -> " << availableColor << "(distance =" << distance << ", value = " << nearestColorValue << ")"; + } + } + return nearestColorValue; +} + QScriptValue ColorJSProxy::makeHotcueColorPalette(QScriptEngine* pScriptEngine, HotcueColorPaletteSettings colorPaletteSettings) { // TODO: make sure we get notified when the palette changes diff --git a/src/controllers/colorjsproxy.h b/src/controllers/colorjsproxy.h index dda4d693798..45bd52569c8 100644 --- a/src/controllers/colorjsproxy.h +++ b/src/controllers/colorjsproxy.h @@ -21,6 +21,7 @@ class ColorJSProxy final : public QObject { // of a color. The parameter is the hexadecimal representation of the color // i.e. 0xAARRGGBB Q_INVOKABLE QScriptValue colorFromHexCode(uint colorCode); + Q_INVOKABLE QScriptValue nearestColorMidiCode(uint colorCode, QVariantMap availableColorCodes); private: QScriptValue makeHotcueColorPalette(QScriptEngine* pScriptEngine, From d803ea80c5b7d1a85bdd314ee4a9bcccb88444c5 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 14 Nov 2019 16:34:02 +0100 Subject: [PATCH 033/158] res/controllers/midi-components: Update HotcueButton to use new API --- res/controllers/midi-components-0.0.js | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/res/controllers/midi-components-0.0.js b/res/controllers/midi-components-0.0.js index 7db8bd503b6..caf0c52789f 100644 --- a/res/controllers/midi-components-0.0.js +++ b/res/controllers/midi-components-0.0.js @@ -330,20 +330,16 @@ this.send(outval); } }, - outputColor: function(id) { - var color = this.colors[id]; - if (color instanceof Array) { - if (color.length !== 3) { - print("ERROR: invalid color array for id: " + id); - return; - } + outputColor: function (colorCode) { + if (this.colors !== undefined) { + var nearestColor = color.nearestColorMidiCode(colorCode, this.colors); + this.send(nearestColor); + } else { if (this.sendRGB === undefined) { print("ERROR: no function defined for sending RGB colors"); return; } - this.sendRGB(color); - } else if (typeof color === "number") { - this.send(color); + this.sendRGB(color.colorFromHexCode(colorCode)); } }, connect: function() { From 78c5101640c3a2da68f1e3f39860cd697d89cbea Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 14 Nov 2019 16:34:44 +0100 Subject: [PATCH 034/158] Roland DJ-505: Update controller script for new color API --- res/controllers/Roland_DJ-505-scripts.js | 41 ++++++++++++++---------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/res/controllers/Roland_DJ-505-scripts.js b/res/controllers/Roland_DJ-505-scripts.js index ca091acab03..4d0abc50208 100644 --- a/res/controllers/Roland_DJ-505-scripts.js +++ b/res/controllers/Roland_DJ-505-scripts.js @@ -970,17 +970,24 @@ DJ505.PadColor = { DIM_MODIFIER: 0x10, }; -DJ505.PadColorMap = [ - DJ505.PadColor.OFF, - DJ505.PadColor.RED, - DJ505.PadColor.GREEN, - DJ505.PadColor.BLUE, - DJ505.PadColor.YELLOW, - DJ505.PadColor.CELESTE, - DJ505.PadColor.PURPLE, - DJ505.PadColor.APRICOT, - DJ505.PadColor.WHITE, -]; +DJ505.PadColorMap = { + '#FFCC0000': DJ505.PadColor.RED, + '#FFCC4400': DJ505.PadColor.CORAL, + '#FFCC8800': DJ505.PadColor.ORANGE, + '#FFCCCC00': DJ505.PadColor.YELLOW, + '#FF88CC00': DJ505.PadColor.GREEN, + '#FF00CC00': DJ505.PadColor.APPLEGREEN, + '#FF00CC88': DJ505.PadColor.AQUAMARINE, + '#FF00CCCC': DJ505.PadColor.TURQUOISE, + '#FF0088CC': DJ505.PadColor.CELESTE, + '#FF0000CC': DJ505.PadColor.BLUE, + '#FF4400CC': DJ505.PadColor.AZURE, + '#FF8800CC': DJ505.PadColor.PURPLE, + '#FFCC00CC': DJ505.PadColor.MAGENTA, + '#FFCC0044': DJ505.PadColor.RED, + '#FFFFCCCC': DJ505.PadColor.APRICOT, + '#FFFFFFFF': DJ505.PadColor.WHITE, +}; DJ505.PadSection = function(deck, offset) { // TODO: Add support for missing modes (flip, slicer, slicerloop) @@ -1239,7 +1246,7 @@ DJ505.HotcueMode = function(deck, offset) { this.ledControl = DJ505.PadMode.HOTCUE; this.color = DJ505.PadColor.WHITE; - var hotcueColors = [this.color].concat(DJ505.PadColorMap.slice(1)); + var hotcueColors = DJ505.PadColorMap; this.pads = new components.ComponentContainer(); for (var i = 0; i <= 7; i++) { this.pads[i] = new components.HotcueButton({ @@ -1287,7 +1294,7 @@ DJ505.CueLoopMode = function(deck, offset) { this.ledControl = DJ505.PadMode.HOTCUE; this.color = DJ505.PadColor.BLUE; - var cueloopColors = [this.color].concat(DJ505.PadColorMap.slice(1)); + var cueloopColors = DJ505.PadColorMap; this.PerformancePad = function(n) { this.midi = [0x94 + offset, 0x14 + n]; this.number = n + 1; @@ -1596,7 +1603,7 @@ DJ505.PitchPlayMode = function(deck, offset) { this.color = DJ505.PadColor.GREEN; this.cuepoint = 1; this.range = PitchPlayRange.MID; - var pitchplayColors = [this.color].concat(DJ505.PadColorMap.slice(1)); + var pitchplayColors = DJ505.PadColorMap; this.PerformancePad = function(n) { this.midi = [0x94 + offset, 0x14 + n]; @@ -1614,10 +1621,10 @@ DJ505.PitchPlayMode = function(deck, offset) { mode: this, outConnect: false, off: DJ505.PadColor.OFF, - outputColor: function(id) { + outputColor: function(colorCode) { // For colored hotcues (shifted only) - var color = this.colors[id]; - this.send((this.mode.cuepoint === this.number) ? color : (color + DJ505.PadColor.DIM_MODIFIER)); + var midiColor = color.nearestColorMidiCode(colorCode, this.colors) + this.send((this.mode.cuepoint === this.number) ? midiColor : (midiColor + DJ505.PadColor.DIM_MODIFIER)); }, unshift: function() { this.outKey = "pitch_adjust"; From 080663ca46113644fa523af46099ad24d9d90d21 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Fri, 15 Nov 2019 23:05:58 +0100 Subject: [PATCH 035/158] src/controllers/colorjsproxy: Fix indentation in colorDistance function --- src/controllers/colorjsproxy.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/controllers/colorjsproxy.cpp b/src/controllers/colorjsproxy.cpp index 7f93d524aaa..1dc27ad6e2e 100644 --- a/src/controllers/colorjsproxy.cpp +++ b/src/controllers/colorjsproxy.cpp @@ -8,15 +8,15 @@ namespace { double colorDistance(QColor a, QColor b) { - long mean_red = ((long)a.red() + (long)b.red()) / 2; - long delta_red = (long)a.red() - (long)b.red(); - long delta_green = (long)a.green() - (long)b.green(); - long delta_blue = (long)a.blue() - (long)b.blue(); - return sqrt( - (((512 + mean_red) * delta_red * delta_red) >> 8) + - (4 * delta_green * delta_green) + - (((767 - mean_red) * delta_blue * delta_blue) >> 8) - ); + long mean_red = ((long)a.red() + (long)b.red()) / 2; + long delta_red = (long)a.red() - (long)b.red(); + long delta_green = (long)a.green() - (long)b.green(); + long delta_blue = (long)a.blue() - (long)b.blue(); + return sqrt( + (((512 + mean_red) * delta_red * delta_red) >> 8) + + (4 * delta_green * delta_green) + + (((767 - mean_red) * delta_blue * delta_blue) >> 8) + ); } } From 3864c800bd7b9b81b326f5f7243d271115be29a3 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Fri, 15 Nov 2019 23:19:57 +0100 Subject: [PATCH 036/158] src/controllers/colorjsproxy: Add comment to colorDistance algorithm --- src/controllers/colorjsproxy.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/controllers/colorjsproxy.cpp b/src/controllers/colorjsproxy.cpp index 1dc27ad6e2e..43c853f9e62 100644 --- a/src/controllers/colorjsproxy.cpp +++ b/src/controllers/colorjsproxy.cpp @@ -8,6 +8,13 @@ namespace { double colorDistance(QColor a, QColor b) { + // This algorithm calculates the distance between two colors. In + // contrast to the L2 norm, this also tries take the human perception + // of colors into account. More accurate algorithms like the CIELAB2000 + // Delta-E rely on sophisticated color space conversions and need a lot + // of costly computations. In contrast, this is a low-cost + // approximation and should be sufficently accurate. + // More details: https://www.compuphase.com/cmetric.htm long mean_red = ((long)a.red() + (long)b.red()) / 2; long delta_red = (long)a.red() - (long)b.red(); long delta_green = (long)a.green() - (long)b.green(); From 16a4778d17408ddee031c7d8ee3f7f1102debd1f Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sat, 16 Nov 2019 04:18:36 +0100 Subject: [PATCH 037/158] src/controllers: Add ColorMapper class for controller scripts --- CMakeLists.txt | 2 + build/depends.py | 2 + src/controllers/colorjsproxy.cpp | 52 ----------------------- src/controllers/colorjsproxy.h | 1 - src/controllers/colormapper.cpp | 59 ++++++++++++++++++++++++++ src/controllers/colormapper.h | 27 ++++++++++++ src/controllers/colormapperjsproxy.cpp | 37 ++++++++++++++++ src/controllers/colormapperjsproxy.h | 26 ++++++++++++ src/controllers/controllerengine.cpp | 6 ++- 9 files changed, 158 insertions(+), 54 deletions(-) create mode 100644 src/controllers/colormapper.cpp create mode 100644 src/controllers/colormapper.h create mode 100644 src/controllers/colormapperjsproxy.cpp create mode 100644 src/controllers/colormapperjsproxy.h diff --git a/CMakeLists.txt b/CMakeLists.txt index af9b88af50c..c3aecc6f763 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -168,6 +168,8 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL src/control/controlpushbutton.cpp src/control/controlttrotary.cpp src/controllers/colorjsproxy.cpp + src/controllers/colormapper.cpp + src/controllers/colormapperjsproxy.cpp src/controllers/controller.cpp src/controllers/controllerdebug.cpp src/controllers/controllerengine.cpp diff --git a/build/depends.py b/build/depends.py index ac62b65794a..41dd2019b58 100644 --- a/build/depends.py +++ b/build/depends.py @@ -927,6 +927,8 @@ def sources(self, build): "src/controllers/softtakeover.cpp", "src/controllers/keyboard/keyboardeventfilter.cpp", "src/controllers/colorjsproxy.cpp", + "src/controllers/colormapper.cpp", + "src/controllers/colormapperjsproxy.cpp", "src/main.cpp", "src/mixxx.cpp", diff --git a/src/controllers/colorjsproxy.cpp b/src/controllers/colorjsproxy.cpp index 43c853f9e62..24aa43797ee 100644 --- a/src/controllers/colorjsproxy.cpp +++ b/src/controllers/colorjsproxy.cpp @@ -1,33 +1,8 @@ -#include -#include #include "controllers/colorjsproxy.h" #include "preferences/hotcuecolorpalettesettings.h" #include "util/color/rgbcolor.h" -namespace { - double colorDistance(QColor a, QColor b) - { - // This algorithm calculates the distance between two colors. In - // contrast to the L2 norm, this also tries take the human perception - // of colors into account. More accurate algorithms like the CIELAB2000 - // Delta-E rely on sophisticated color space conversions and need a lot - // of costly computations. In contrast, this is a low-cost - // approximation and should be sufficently accurate. - // More details: https://www.compuphase.com/cmetric.htm - long mean_red = ((long)a.red() + (long)b.red()) / 2; - long delta_red = (long)a.red() - (long)b.red(); - long delta_green = (long)a.green() - (long)b.green(); - long delta_blue = (long)a.blue() - (long)b.blue(); - return sqrt( - (((512 + mean_red) * delta_red * delta_red) >> 8) + - (4 * delta_green * delta_green) + - (((767 - mean_red) * delta_blue * delta_blue) >> 8) - ); - } -} - - ColorJSProxy::ColorJSProxy(QScriptEngine* pScriptEngine, HotcueColorPaletteSettings colorPaletteSettings) : m_pScriptEngine(pScriptEngine), @@ -52,33 +27,6 @@ QScriptValue ColorJSProxy::colorFromHexCode(uint colorCode) { return jsColor; } -QScriptValue ColorJSProxy::nearestColorMidiCode(uint colorCode, QVariantMap availableColors) { - QColor desiredColor = QColor::fromRgba(colorCode); - uint nearestColorValue = 0; - double nearestColorDistance = qInf(); - QMapIterator it(availableColors); - while (it.hasNext()) { - it.next(); - QColor availableColor(it.key()); - VERIFY_OR_DEBUG_ASSERT(availableColor.isValid()) { - qWarning() << "Received invalid color name from controller script:" << it.key(); - continue; - } - - double distance = colorDistance(desiredColor, availableColor); - if (distance < nearestColorDistance) { - nearestColorDistance = distance; - bool valueOk; - nearestColorValue = it.value().toUInt(&valueOk); - VERIFY_OR_DEBUG_ASSERT(availableColor.isValid()) { - qWarning() << "Failed to convert value to uint:" << it.value(); - } - qDebug() << "Match for " << desiredColor << " -> " << availableColor << "(distance =" << distance << ", value = " << nearestColorValue << ")"; - } - } - return nearestColorValue; -} - QScriptValue ColorJSProxy::makeHotcueColorPalette(QScriptEngine* pScriptEngine, HotcueColorPaletteSettings colorPaletteSettings) { // TODO: make sure we get notified when the palette changes diff --git a/src/controllers/colorjsproxy.h b/src/controllers/colorjsproxy.h index 45bd52569c8..dda4d693798 100644 --- a/src/controllers/colorjsproxy.h +++ b/src/controllers/colorjsproxy.h @@ -21,7 +21,6 @@ class ColorJSProxy final : public QObject { // of a color. The parameter is the hexadecimal representation of the color // i.e. 0xAARRGGBB Q_INVOKABLE QScriptValue colorFromHexCode(uint colorCode); - Q_INVOKABLE QScriptValue nearestColorMidiCode(uint colorCode, QVariantMap availableColorCodes); private: QScriptValue makeHotcueColorPalette(QScriptEngine* pScriptEngine, diff --git a/src/controllers/colormapper.cpp b/src/controllers/colormapper.cpp new file mode 100644 index 00000000000..3caa515806e --- /dev/null +++ b/src/controllers/colormapper.cpp @@ -0,0 +1,59 @@ +#include "controllers/colormapper.h" + +#include +#include + +#include "util/debug.h" + +namespace { +double colorDistance(QRgb a, QRgb b) { + // This algorithm calculates the distance between two colors. In + // contrast to the L2 norm, this also tries take the human perception + // of colors into account. More accurate algorithms like the CIELAB2000 + // Delta-E rely on sophisticated color space conversions and need a lot + // of costly computations. In contrast, this is a low-cost + // approximation and should be sufficently accurate. + // More details: https://www.compuphase.com/cmetric.htm + long mean_red = ((long)qRed(a) + (long)qRed(b)) / 2; + long delta_red = (long)qRed(a) - (long)qRed(b); + long delta_green = (long)qGreen(a) - (long)qGreen(b); + long delta_blue = (long)qBlue(a) - (long)qBlue(b); + return sqrt( + (((512 + mean_red) * delta_red * delta_red) >> 8) + + (4 * delta_green * delta_green) + + (((767 - mean_red) * delta_blue * delta_blue) >> 8)); +} +} // namespace + +QPair ColorMapper::getNearestColor(QRgb desiredColor) { + // If desired color is already in cache, use cache entry + QMap::const_iterator i = m_cache.find(desiredColor); + QMap::const_iterator j; + if (i != m_cache.constEnd()) { + j = m_availableColors.find(i.value()); + DEBUG_ASSERT(j != m_availableColors.constEnd()); + qDebug() << "ColorMapper cache hit for" << desiredColor << ":" + << "Color =" << j.key() << "," + << "Value =" << j.value(); + return QPair(j.key(), j.value()); + } + + // Color is not cached + QMap::const_iterator nearestColorIterator; + double nearestColorDistance = qInf(); + for (j = m_availableColors.constBegin(); j != m_availableColors.constEnd(); j++) { + QRgb availableColor = j.key(); + double distance = colorDistance(desiredColor, availableColor); + if (distance < nearestColorDistance) { + nearestColorDistance = distance; + nearestColorIterator = j; + } + } + + DEBUG_ASSERT(nearestColorDistance < qInf()); + qDebug() << "ColorMapper found matching color for" << desiredColor << ":" + << "Color =" << nearestColorIterator.key() << "," + << "Value =" << nearestColorIterator.value(); + m_cache.insert(desiredColor, nearestColorIterator.key()); + return QPair(nearestColorIterator.key(), nearestColorIterator.value()); +} diff --git a/src/controllers/colormapper.h b/src/controllers/colormapper.h new file mode 100644 index 00000000000..f30b5a8ae80 --- /dev/null +++ b/src/controllers/colormapper.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include "util/assert.h" + +class ColorMapper final : public QObject { + Q_OBJECT + public: + ColorMapper() = delete; + ColorMapper(const QMap availableColors) + : m_availableColors(availableColors) { + DEBUG_ASSERT(!m_availableColors.isEmpty()); + } + + ~ColorMapper() = default; + + QPair getNearestColor(QRgb desiredColor); + + private: + const QMap m_availableColors; + QMap m_cache; +}; diff --git a/src/controllers/colormapperjsproxy.cpp b/src/controllers/colormapperjsproxy.cpp new file mode 100644 index 00000000000..3e1db371780 --- /dev/null +++ b/src/controllers/colormapperjsproxy.cpp @@ -0,0 +1,37 @@ +#include + +#include "controllers/colormapperjsproxy.h" + +ColorMapperJSProxy::ColorMapperJSProxy(QScriptEngine* pScriptEngine, QMap availableColors) + : m_pScriptEngine(pScriptEngine) { + m_colorMapper = new ColorMapper(availableColors); +} + +QScriptValue ColorMapperJSProxy::getNearestColor(uint colorCode) { + QPair result = m_colorMapper->getNearestColor(static_cast(colorCode)); + return m_pScriptEngine->toScriptValue(result.second); +} + +QScriptValue ColorMapperJSProxyConstructor(QScriptContext* pScriptContext, QScriptEngine* pScriptEngine) { + QMap availableColors; + DEBUG_ASSERT(pScriptContext->argumentCount() == 1); + QScriptValueIterator it(pScriptContext->argument(0)); + while (it.hasNext()) { + it.next(); + DEBUG_ASSERT(!it.value().isObject()); + QColor color(it.name()); + VERIFY_OR_DEBUG_ASSERT(color.isValid()) { + qWarning() << "Received invalid color name from controller script:" << it.name(); + continue; + } + availableColors.insert(color.rgb(), it.value().toVariant()); + } + + if (availableColors.isEmpty()) { + qWarning() << "Failed to create ColorMapper object: available colors mustn't be empty!"; + return pScriptEngine->undefinedValue(); + } + + QObject* colorMapper = new ColorMapperJSProxy(pScriptEngine, availableColors); + return pScriptEngine->newQObject(colorMapper, QScriptEngine::ScriptOwnership); +} diff --git a/src/controllers/colormapperjsproxy.h b/src/controllers/colormapperjsproxy.h new file mode 100644 index 00000000000..ead0eab0410 --- /dev/null +++ b/src/controllers/colormapperjsproxy.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include + +#include "controllers/colormapper.h" + +class ColorMapperJSProxy final : public QObject { + Q_OBJECT + public: + ColorMapperJSProxy() = delete; + ColorMapperJSProxy(QScriptEngine* pScriptEngine, QMap availableColors); + + ~ColorMapperJSProxy() { + delete m_colorMapper; + }; + + public slots: + QScriptValue getNearestColor(uint ColorCode); + + private: + QScriptEngine* m_pScriptEngine; + ColorMapper* m_colorMapper; +}; + +QScriptValue ColorMapperJSProxyConstructor(QScriptContext* context, QScriptEngine* engine); diff --git a/src/controllers/controllerengine.cpp b/src/controllers/controllerengine.cpp index 961dbc2a947..3b42e057f6d 100644 --- a/src/controllers/controllerengine.cpp +++ b/src/controllers/controllerengine.cpp @@ -6,8 +6,8 @@ email : spappalardo@mixxx.org ***************************************************************************/ +#include "controllers/colormapperjsproxy.h" #include "controllers/controllerengine.h" - #include "controllers/controller.h" #include "controllers/controllerdebug.h" #include "control/controlobject.h" @@ -219,6 +219,10 @@ void ControllerEngine::initializeScriptEngine() { m_pEngine, HotcueColorPaletteSettings(m_pConfig)); engineGlobalObject.setProperty("color", m_pEngine->newQObject(m_pColorJSProxy.get())); + QScriptValue constructor = m_pEngine->newFunction(ColorMapperJSProxyConstructor); + QScriptValue metaObject = m_pEngine->newQMetaObject(&ColorMapperJSProxy::staticMetaObject, constructor); + engineGlobalObject.setProperty("ColorMapper", metaObject); + m_pBaClass = new ByteArrayClass(m_pEngine); engineGlobalObject.setProperty("ByteArray", m_pBaClass->constructor()); } From b3b9c0d33c46a9984857e98931c83d95753a82ec Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 27 Feb 2020 12:45:29 +0100 Subject: [PATCH 038/158] .eslintrc.json: Add ColorMapper class to globals --- res/controllers/.eslintrc.json | 1 + 1 file changed, 1 insertion(+) diff --git a/res/controllers/.eslintrc.json b/res/controllers/.eslintrc.json index a5f60376e3f..0a7c34d9961 100644 --- a/res/controllers/.eslintrc.json +++ b/res/controllers/.eslintrc.json @@ -1,5 +1,6 @@ { "globals": { + "ColorMapper": "readonly", "_": "readonly", "color": "readonly", "components": "readonly", From d4a0508409f8f8abcce46bd8eaf5b8033de3e4f4 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sat, 16 Nov 2019 04:19:45 +0100 Subject: [PATCH 039/158] res/controllers/midi-components: Add support for ColorMapper class --- res/controllers/midi-components-0.0.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/controllers/midi-components-0.0.js b/res/controllers/midi-components-0.0.js index caf0c52789f..23e2a74c990 100644 --- a/res/controllers/midi-components-0.0.js +++ b/res/controllers/midi-components-0.0.js @@ -332,7 +332,7 @@ }, outputColor: function (colorCode) { if (this.colors !== undefined) { - var nearestColor = color.nearestColorMidiCode(colorCode, this.colors); + var nearestColor = this.colors.getNearestColor(colorCode); this.send(nearestColor); } else { if (this.sendRGB === undefined) { From e1cc9be5aec016aabf5a9241598aa01bb53f2076 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sat, 16 Nov 2019 04:20:28 +0100 Subject: [PATCH 040/158] Roland DJ-505: Add support for ColorMapper class --- res/controllers/Roland_DJ-505-scripts.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/res/controllers/Roland_DJ-505-scripts.js b/res/controllers/Roland_DJ-505-scripts.js index 4d0abc50208..ace060bac28 100644 --- a/res/controllers/Roland_DJ-505-scripts.js +++ b/res/controllers/Roland_DJ-505-scripts.js @@ -970,7 +970,7 @@ DJ505.PadColor = { DIM_MODIFIER: 0x10, }; -DJ505.PadColorMap = { +DJ505.PadColorMap = new ColorMapper({ '#FFCC0000': DJ505.PadColor.RED, '#FFCC4400': DJ505.PadColor.CORAL, '#FFCC8800': DJ505.PadColor.ORANGE, @@ -987,7 +987,7 @@ DJ505.PadColorMap = { '#FFCC0044': DJ505.PadColor.RED, '#FFFFCCCC': DJ505.PadColor.APRICOT, '#FFFFFFFF': DJ505.PadColor.WHITE, -}; +}); DJ505.PadSection = function(deck, offset) { // TODO: Add support for missing modes (flip, slicer, slicerloop) @@ -1623,7 +1623,7 @@ DJ505.PitchPlayMode = function(deck, offset) { off: DJ505.PadColor.OFF, outputColor: function(colorCode) { // For colored hotcues (shifted only) - var midiColor = color.nearestColorMidiCode(colorCode, this.colors) + var midiColor = this.colors.getNearestColor(colorCode); this.send((this.mode.cuepoint === this.number) ? midiColor : (midiColor + DJ505.PadColor.DIM_MODIFIER)); }, unshift: function() { From f97a15b13a2c3624c85404291b09655d2cb6817c Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 19 Nov 2019 18:48:40 +0100 Subject: [PATCH 041/158] controllers/colormapperjsproxy: Add separate getNearestValue method --- res/controllers/midi-components-0.0.js | 4 ++-- src/controllers/colormapperjsproxy.cpp | 10 ++++++++++ src/controllers/colormapperjsproxy.h | 1 + 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/res/controllers/midi-components-0.0.js b/res/controllers/midi-components-0.0.js index 23e2a74c990..6117793f9ac 100644 --- a/res/controllers/midi-components-0.0.js +++ b/res/controllers/midi-components-0.0.js @@ -332,8 +332,8 @@ }, outputColor: function (colorCode) { if (this.colors !== undefined) { - var nearestColor = this.colors.getNearestColor(colorCode); - this.send(nearestColor); + var nearestColorValue = this.colors.getNearestValue(colorCode); + this.send(nearestColorValue); } else { if (this.sendRGB === undefined) { print("ERROR: no function defined for sending RGB colors"); diff --git a/src/controllers/colormapperjsproxy.cpp b/src/controllers/colormapperjsproxy.cpp index 3e1db371780..f806cb9752e 100644 --- a/src/controllers/colormapperjsproxy.cpp +++ b/src/controllers/colormapperjsproxy.cpp @@ -8,6 +8,16 @@ ColorMapperJSProxy::ColorMapperJSProxy(QScriptEngine* pScriptEngine, QMap result = m_colorMapper->getNearestColor(static_cast(colorCode)); + QScriptValue jsColor = m_pScriptEngine->newObject(); + jsColor.setProperty("red", qRed(result.first)); + jsColor.setProperty("green", qGreen(result.first)); + jsColor.setProperty("blue", qBlue(result.first)); + jsColor.setProperty("alpha", qAlpha(result.first)); + return jsColor; +} + +QScriptValue ColorMapperJSProxy::getNearestValue(uint colorCode) { QPair result = m_colorMapper->getNearestColor(static_cast(colorCode)); return m_pScriptEngine->toScriptValue(result.second); } diff --git a/src/controllers/colormapperjsproxy.h b/src/controllers/colormapperjsproxy.h index ead0eab0410..f8e54f0890b 100644 --- a/src/controllers/colormapperjsproxy.h +++ b/src/controllers/colormapperjsproxy.h @@ -17,6 +17,7 @@ class ColorMapperJSProxy final : public QObject { public slots: QScriptValue getNearestColor(uint ColorCode); + QScriptValue getNearestValue(uint ColorCode); private: QScriptEngine* m_pScriptEngine; From f8ccbcd004ca10704033a9ccc1dea0236b264612 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 19 Nov 2019 18:49:12 +0100 Subject: [PATCH 042/158] Roland DJ-505: Switch to ControllerMapper::getNearestValue --- res/controllers/Roland_DJ-505-scripts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/controllers/Roland_DJ-505-scripts.js b/res/controllers/Roland_DJ-505-scripts.js index ace060bac28..8e733c2b85d 100644 --- a/res/controllers/Roland_DJ-505-scripts.js +++ b/res/controllers/Roland_DJ-505-scripts.js @@ -1623,7 +1623,7 @@ DJ505.PitchPlayMode = function(deck, offset) { off: DJ505.PadColor.OFF, outputColor: function(colorCode) { // For colored hotcues (shifted only) - var midiColor = this.colors.getNearestColor(colorCode); + var midiColor = this.colors.getNearestValue(colorCode); this.send((this.mode.cuepoint === this.number) ? midiColor : (midiColor + DJ505.PadColor.DIM_MODIFIER)); }, unshift: function() { From 8fe1bd2c9388b4ce55117b73371c3cff7691a5b4 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 19 Nov 2019 18:54:41 +0100 Subject: [PATCH 043/158] controllers/midi-components: Remove default value for HotcueButton.colors --- res/controllers/midi-components-0.0.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/res/controllers/midi-components-0.0.js b/res/controllers/midi-components-0.0.js index 6117793f9ac..2c54f1d4b2e 100644 --- a/res/controllers/midi-components-0.0.js +++ b/res/controllers/midi-components-0.0.js @@ -296,9 +296,6 @@ } if (options.colors !== undefined || options.sendRGB !== undefined) { this.colorKey = 'hotcue_' + options.number + '_color'; - if (options.colors === undefined) { - options.colors = color.hotcueColorPalette(); - } } this.number = options.number; this.outKey = "hotcue_" + this.number + "_enabled"; From f313cc7a1bf163651816c5f68248d3901aa381d8 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 19 Nov 2019 18:55:23 +0100 Subject: [PATCH 044/158] controllers/midi-components: Rename HotcueButton.colors to .colorMapper --- res/controllers/midi-components-0.0.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/res/controllers/midi-components-0.0.js b/res/controllers/midi-components-0.0.js index 2c54f1d4b2e..352ce40cf6d 100644 --- a/res/controllers/midi-components-0.0.js +++ b/res/controllers/midi-components-0.0.js @@ -294,7 +294,7 @@ print("ERROR: No hotcue number specified for new HotcueButton."); return; } - if (options.colors !== undefined || options.sendRGB !== undefined) { + if (options.colorMapper !== undefined || options.sendRGB !== undefined) { this.colorKey = 'hotcue_' + options.number + '_color'; } this.number = options.number; @@ -328,8 +328,8 @@ } }, outputColor: function (colorCode) { - if (this.colors !== undefined) { - var nearestColorValue = this.colors.getNearestValue(colorCode); + if (this.colorMapper !== undefined) { + var nearestColorValue = this.colorMapper.getNearestValue(colorCode); this.send(nearestColorValue); } else { if (this.sendRGB === undefined) { From 1dad29440f2005fb90e3bef68b66b78c25831679 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 27 Feb 2020 12:43:56 +0100 Subject: [PATCH 045/158] res/controllers/midi-components-0.0: Fix some eslint issues --- res/controllers/midi-components-0.0.js | 38 +++++++++++++------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/res/controllers/midi-components-0.0.js b/res/controllers/midi-components-0.0.js index 352ce40cf6d..db2ac092f8c 100644 --- a/res/controllers/midi-components-0.0.js +++ b/res/controllers/midi-components-0.0.js @@ -295,7 +295,7 @@ return; } if (options.colorMapper !== undefined || options.sendRGB !== undefined) { - this.colorKey = 'hotcue_' + options.number + '_color'; + this.colorKey = "hotcue_" + options.number + "_color"; } this.number = options.number; this.outKey = "hotcue_" + this.number + "_enabled"; @@ -310,7 +310,7 @@ }, getColor: function() { if (this.colorKey !== undefined) { - return color.colorFromHexCode(engine.getValue(this.group,this.colorKey)); + return color.colorFromHexCode(engine.getValue(this.group, this.colorKey)); } else { return null; } @@ -327,7 +327,7 @@ this.send(outval); } }, - outputColor: function (colorCode) { + outputColor: function(colorCode) { if (this.colorMapper !== undefined) { var nearestColorValue = this.colorMapper.getNearestValue(colorCode); this.send(nearestColorValue); @@ -342,8 +342,8 @@ connect: function() { Button.prototype.connect.call(this); // call parent connect if (undefined !== this.group && this.colorKey !== undefined) { - this.connections[1] = engine.makeConnection(this.group, this.colorKey, function (id) { - if (engine.getValue(this.group,this.outKey)) { + this.connections[1] = engine.makeConnection(this.group, this.colorKey, function(id) { + if (engine.getValue(this.group, this.outKey)) { this.outputColor(id); } }); @@ -725,14 +725,14 @@ if (engine.getValue(eu.group, "show_focus") > 0) { engine.setValue(eu.group, "show_focus", 0); eu.previouslyFocusedEffect = engine.getValue(eu.group, - "focused_effect"); + "focused_effect"); engine.setValue(eu.group, "focused_effect", 0); } } else { engine.setValue(eu.group, "show_focus", 1); if (eu.previouslyFocusedEffect !== undefined) { engine.setValue(eu.group, "focused_effect", - eu.previouslyFocusedEffect); + eu.previouslyFocusedEffect); } } if (eu.enableButtons !== undefined) { @@ -763,8 +763,8 @@ // show_focus is always in the correct state, even if the user // presses the skin button for show_parameters. this.showParametersConnection = engine.makeConnection(this.group, - "show_parameters", - this.onShowParametersChange); + "show_parameters", + this.onShowParametersChange); this.showParametersConnection.trigger(); } @@ -909,7 +909,7 @@ outKey: "focused_effect", connect: function() { this.connections[0] = engine.makeConnection(eu.group, "focused_effect", - this.onFocusChange); + this.onFocusChange); }, disconnect: function() { engine.softTakeoverIgnoreNextValue(this.group, this.inKey); @@ -972,7 +972,7 @@ this.connect = function() { this.connections[0] = engine.makeConnection(eu.group, "focused_effect", - this.onFocusChange); + this.onFocusChange); // this.onFocusChange sets this.group and this.outKey, so trigger it // before making the connection for LED output this.connections[0].trigger(); @@ -1019,8 +1019,8 @@ // of assigning to this.connections[0] to avoid // Component.prototype.trigger() triggering the disconnected connection. this.connections = [engine.makeConnection(eu.group, - "focused_effect", - this.output)]; + "focused_effect", + this.output)]; }; }, }); @@ -1062,8 +1062,8 @@ var showParameters = engine.getValue(this.group, "show_parameters"); if (this.isPress(channel, control, value, status)) { this.longPressTimer = engine.beginTimer(this.longPressTimeout, - this.startEffectFocusChooseMode, - true); + this.startEffectFocusChooseMode, + true); if (!showParameters) { if (!allowFocusWhenParametersHidden) { engine.setValue(this.group, "show_parameters", 1); @@ -1086,11 +1086,11 @@ eu.focusChooseModeActive = false; } else { if (!showParameters && allowFocusWhenParametersHidden) { - engine.setValue(this.group, "show_parameters", 1); + engine.setValue(this.group, "show_parameters", 1); } else if (showParameters && !this.pressedWhenParametersHidden) { - engine.setValue(this.group, "show_parameters", 0); - // eu.onShowParametersChange will save the focused effect, - // unfocus, and hide focus buttons in skin + engine.setValue(this.group, "show_parameters", 0); + // eu.onShowParametersChange will save the focused effect, + // unfocus, and hide focus buttons in skin } } this.pressedWhenParametersHidden = false; From 09f6982393641dbcdb2e8a76f16353700c0006d5 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 19 Nov 2019 18:59:18 +0100 Subject: [PATCH 046/158] Roland DJ-505: Rename Component.colors to .colorMapper --- res/controllers/Roland_DJ-505-scripts.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/res/controllers/Roland_DJ-505-scripts.js b/res/controllers/Roland_DJ-505-scripts.js index 8e733c2b85d..6e6c45284d0 100644 --- a/res/controllers/Roland_DJ-505-scripts.js +++ b/res/controllers/Roland_DJ-505-scripts.js @@ -1246,7 +1246,6 @@ DJ505.HotcueMode = function(deck, offset) { this.ledControl = DJ505.PadMode.HOTCUE; this.color = DJ505.PadColor.WHITE; - var hotcueColors = DJ505.PadColorMap; this.pads = new components.ComponentContainer(); for (var i = 0; i <= 7; i++) { this.pads[i] = new components.HotcueButton({ @@ -1258,7 +1257,7 @@ DJ505.HotcueMode = function(deck, offset) { group: deck.currentDeck, on: this.color, off: this.color + DJ505.PadColor.DIM_MODIFIER, - colors: hotcueColors, + colorMapper: DJ505.PadColorMap, outConnect: false, }); } @@ -1294,7 +1293,6 @@ DJ505.CueLoopMode = function(deck, offset) { this.ledControl = DJ505.PadMode.HOTCUE; this.color = DJ505.PadColor.BLUE; - var cueloopColors = DJ505.PadColorMap; this.PerformancePad = function(n) { this.midi = [0x94 + offset, 0x14 + n]; this.number = n + 1; @@ -1310,7 +1308,7 @@ DJ505.CueLoopMode = function(deck, offset) { group: deck.currentDeck, on: this.color, off: this.color + DJ505.PadColor.DIM_MODIFIER, - colors: cueloopColors, + colorMapper: DJ505.PadColorMap, outConnect: false, unshift: function() { this.input = function(channel, control, value, status, group) { @@ -1603,13 +1601,12 @@ DJ505.PitchPlayMode = function(deck, offset) { this.color = DJ505.PadColor.GREEN; this.cuepoint = 1; this.range = PitchPlayRange.MID; - var pitchplayColors = DJ505.PadColorMap; this.PerformancePad = function(n) { this.midi = [0x94 + offset, 0x14 + n]; this.number = n + 1; this.on = this.color + DJ505.PadColor.DIM_MODIFIER; - this.colors = pitchplayColors; + this.colorMapper = DJ505.PadColorMap; this.colorKey = "hotcue_" + this.number + "_color"; components.Button.call(this); }; @@ -1623,7 +1620,7 @@ DJ505.PitchPlayMode = function(deck, offset) { off: DJ505.PadColor.OFF, outputColor: function(colorCode) { // For colored hotcues (shifted only) - var midiColor = this.colors.getNearestValue(colorCode); + var midiColor = this.colorMapper.getNearestValue(colorCode); this.send((this.mode.cuepoint === this.number) ? midiColor : (midiColor + DJ505.PadColor.DIM_MODIFIER)); }, unshift: function() { From 5da79b0dfee41732f186f01b4ab64a37827dbde5 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 27 Feb 2020 14:51:30 +0100 Subject: [PATCH 047/158] util/color: Remove obsolete hotcuecolorpalette.h file --- src/util/color/hotcuecolorpalette.h | 44 ----------------------------- 1 file changed, 44 deletions(-) delete mode 100644 src/util/color/hotcuecolorpalette.h diff --git a/src/util/color/hotcuecolorpalette.h b/src/util/color/hotcuecolorpalette.h deleted file mode 100644 index de9f2c33af6..00000000000 --- a/src/util/color/hotcuecolorpalette.h +++ /dev/null @@ -1,44 +0,0 @@ -// -// Created by Ferran Pujol Camins on 27/10/2019. -// - -#pragma once - -#include -#include - -class HotcueColorPalette { - public: - HotcueColorPalette(QList colorList) - : m_colorList(colorList) { - } - - QColor at(int i) const { - return m_colorList.at(i); - } - - int size() const { - return m_colorList.size(); - } - - int indexOf(QColor color) const { - return m_colorList.indexOf(color); - } - - QList::const_iterator begin() const { - return m_colorList.begin(); - } - - QList::const_iterator end() const { - return m_colorList.end(); - } - - static const HotcueColorPalette mixxxPalette; - - QList m_colorList; -}; - -inline bool operator==( - const HotcueColorPalette& lhs, const HotcueColorPalette& rhs) { - return lhs.m_colorList == rhs.m_colorList; -} From 7e90a64e33ad6f91ee320cccc156f052bf85c281 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 27 Feb 2020 15:30:08 +0100 Subject: [PATCH 048/158] widget/wcolorpicker: Remove use of std::optional::value() --- src/widget/wcolorpicker.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widget/wcolorpicker.cpp b/src/widget/wcolorpicker.cpp index f74a121569c..76d3d7505cf 100644 --- a/src/widget/wcolorpicker.cpp +++ b/src/widget/wcolorpicker.cpp @@ -91,7 +91,7 @@ void WColorPicker::resetSelectedColor() { } i = 0; } else { - i = m_palette.indexOf(m_selectedColor.value()); + i = m_palette.indexOf(*m_selectedColor); if (i == -1) { return; } @@ -124,7 +124,7 @@ void WColorPicker::setSelectedColor(const mixxx::RgbColor::optional_t& color) { } i = 0; } else { - i = m_palette.indexOf(color.value()); + i = m_palette.indexOf(*color); if (i == -1) { return; } From 6c8496f7f8285a7b3fe16d7b20edf41156ac3acb Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 27 Feb 2020 15:38:06 +0100 Subject: [PATCH 049/158] widget: Add ColorPalette support to WColorPicker --- src/widget/wcolorpicker.cpp | 6 ++-- src/widget/wcolorpicker.h | 2 +- src/widget/wcolorpickeraction.cpp | 4 +-- src/widget/wcolorpickeraction.h | 1 + src/widget/wcuemenupopup.cpp | 6 ++-- src/widget/wcuemenupopup.h | 2 +- src/widget/woverview.cpp | 2 +- src/widget/wtracktableview.cpp | 54 ++++++++++++++++--------------- 8 files changed, 42 insertions(+), 35 deletions(-) diff --git a/src/widget/wcolorpicker.cpp b/src/widget/wcolorpicker.cpp index 76d3d7505cf..ff32b4de008 100644 --- a/src/widget/wcolorpicker.cpp +++ b/src/widget/wcolorpicker.cpp @@ -11,10 +11,10 @@ namespace { const int kNumColumns = 4; } -WColorPicker::WColorPicker(ColorOption colorOption, QWidget* parent) +WColorPicker::WColorPicker(ColorOption colorOption, const ColorPalette& palette, QWidget* parent) : QWidget(parent), m_colorOption(colorOption), - m_palette(ColorPalette::mixxxPalette) { + m_palette(palette) { QGridLayout* pLayout = new QGridLayout(); pLayout->setMargin(0); pLayout->setContentsMargins(0, 0, 0, 0); @@ -146,6 +146,8 @@ void WColorPicker::setSelectedColor(const mixxx::RgbColor::optional_t& color) { } void WColorPicker::useColorSet(const ColorPalette& palette) { + resetSelectedColor(); + for (int i = 0; i < m_colorButtons.size(); ++i) { int j = i; if (m_colorOption == ColorOption::AllowNoColor) { diff --git a/src/widget/wcolorpicker.h b/src/widget/wcolorpicker.h index 2a97b2e0cfe..f43419c425b 100644 --- a/src/widget/wcolorpicker.h +++ b/src/widget/wcolorpicker.h @@ -17,7 +17,7 @@ class WColorPicker : public QWidget { AllowNoColor, }; - explicit WColorPicker(ColorOption colorOption, QWidget* parent = nullptr); + explicit WColorPicker(ColorOption colorOption, const ColorPalette& palette, QWidget* parent = nullptr); void resetSelectedColor(); void setSelectedColor(const mixxx::RgbColor::optional_t& color); diff --git a/src/widget/wcolorpickeraction.cpp b/src/widget/wcolorpickeraction.cpp index 6c2afc65798..b57f1e4b78d 100644 --- a/src/widget/wcolorpickeraction.cpp +++ b/src/widget/wcolorpickeraction.cpp @@ -1,8 +1,8 @@ #include "widget/wcolorpickeraction.h" -WColorPickerAction::WColorPickerAction(WColorPicker::ColorOption colorOption, QWidget* parent) +WColorPickerAction::WColorPickerAction(WColorPicker::ColorOption colorOption, const ColorPalette& palette, QWidget* parent) : QWidgetAction(parent), - m_pColorPicker(make_parented(colorOption)) { + m_pColorPicker(make_parented(colorOption, palette)) { connect(m_pColorPicker.get(), &WColorPicker::colorPicked, this, &WColorPickerAction::colorPicked); QHBoxLayout* pLayout = new QHBoxLayout(); diff --git a/src/widget/wcolorpickeraction.h b/src/widget/wcolorpickeraction.h index e565f330043..e7ca0095b4b 100644 --- a/src/widget/wcolorpickeraction.h +++ b/src/widget/wcolorpickeraction.h @@ -12,6 +12,7 @@ class WColorPickerAction : public QWidgetAction { public: explicit WColorPickerAction( WColorPicker::ColorOption colorOption, + const ColorPalette& palette, QWidget* parent = nullptr); void resetSelectedColor(); diff --git a/src/widget/wcuemenupopup.cpp b/src/widget/wcuemenupopup.cpp index 9e22308fdb6..4ff1e13f66a 100644 --- a/src/widget/wcuemenupopup.cpp +++ b/src/widget/wcuemenupopup.cpp @@ -5,9 +5,10 @@ #include #include "engine/engine.h" +#include "preferences/hotcuecolorpalettesettings.h" #include "util/color/color.h" -WCueMenuPopup::WCueMenuPopup(QWidget* parent) +WCueMenuPopup::WCueMenuPopup(UserSettingsPointer pConfig, QWidget* parent) : QWidget(parent) { QWidget::hide(); setWindowFlags(Qt::Popup); @@ -30,7 +31,8 @@ WCueMenuPopup::WCueMenuPopup(QWidget* parent) connect(m_pEditLabel, &QLineEdit::textEdited, this, &WCueMenuPopup::slotEditLabel); connect(m_pEditLabel, &QLineEdit::returnPressed, this, &WCueMenuPopup::hide); - m_pColorPicker = new WColorPicker(WColorPicker::ColorOption::DenyNoColor, this); + HotcueColorPaletteSettings colorPaletteSettings(pConfig); + m_pColorPicker = new WColorPicker(WColorPicker::ColorOption::DenyNoColor, colorPaletteSettings.getHotcueColorPalette(), this); m_pColorPicker->setObjectName("CueColorPicker"); connect(m_pColorPicker, &WColorPicker::colorPicked, this, &WCueMenuPopup::slotChangeCueColor); diff --git a/src/widget/wcuemenupopup.h b/src/widget/wcuemenupopup.h index 14d448d91e9..9338783c766 100644 --- a/src/widget/wcuemenupopup.h +++ b/src/widget/wcuemenupopup.h @@ -11,7 +11,7 @@ class WCueMenuPopup : public QWidget { Q_OBJECT public: - WCueMenuPopup(QWidget* parent = nullptr); + WCueMenuPopup(UserSettingsPointer pConfig, QWidget* parent = nullptr); ~WCueMenuPopup() { delete m_pCueNumber; diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index c72cbea0873..a59bc84fa73 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -55,7 +55,7 @@ WOverview::WOverview( m_group(group), m_pConfig(pConfig), m_endOfTrack(false), - m_pCueMenuPopup(std::make_unique(this)), + m_pCueMenuPopup(std::make_unique(pConfig, this)), m_bShowCueTimes(true), m_iPosSeconds(0), m_bLeftClickDragging(false), diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index b393f0dbc60..a23a1020b2f 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -1,44 +1,45 @@ -#include -#include +#include "widget/wtracktableview.h" + +#include #include -#include #include -#include -#include -#include +#include #include +#include #include +#include +#include +#include -#include "widget/wtracktableview.h" - -#include "widget/wcolorpickeraction.h" -#include "widget/wcoverartmenu.h" -#include "widget/wskincolor.h" -#include "widget/wtracktableviewheader.h" -#include "widget/wwidget.h" +#include "control/controlobject.h" +#include "control/controlproxy.h" #include "library/coverartcache.h" -#include "library/dlgtagfetcher.h" -#include "library/dlgtrackinfo.h" -#include "library/librarytablemodel.h" #include "library/crate/cratefeaturehelper.h" #include "library/dao/trackschema.h" +#include "library/dlgtagfetcher.h" +#include "library/dlgtrackinfo.h" #include "library/dlgtrackmetadataexport.h" #include "library/externaltrackcollection.h" +#include "library/librarytablemodel.h" #include "library/trackcollection.h" #include "library/trackcollectionmanager.h" -#include "control/controlobject.h" -#include "control/controlproxy.h" -#include "track/track.h" -#include "track/trackref.h" -#include "sources/soundsourceproxy.h" #include "mixer/playermanager.h" #include "preferences/dialog/dlgpreflibrary.h" -#include "waveform/guitick.h" -#include "util/dnd.h" -#include "util/time.h" +#include "preferences/hotcuecolorpalettesettings.h" +#include "sources/soundsourceproxy.h" +#include "track/track.h" +#include "track/trackref.h" #include "util/assert.h" -#include "util/parented_ptr.h" #include "util/desktophelper.h" +#include "util/dnd.h" +#include "util/parented_ptr.h" +#include "util/time.h" +#include "waveform/guitick.h" +#include "widget/wcolorpickeraction.h" +#include "widget/wcoverartmenu.h" +#include "widget/wskincolor.h" +#include "widget/wtracktableviewheader.h" +#include "widget/wwidget.h" WTrackTableView::WTrackTableView(QWidget * parent, UserSettingsPointer pConfig, @@ -573,7 +574,8 @@ void WTrackTableView::createActions() { connect(m_pBpmThreeHalvesAction, &QAction::triggered, this, [this] { slotScaleBpm(Beats::THREEHALVES); }); - m_pColorPickerAction = new WColorPickerAction(WColorPicker::ColorOption::AllowNoColor, this); + HotcueColorPaletteSettings colorPaletteSettings(m_pConfig); + m_pColorPickerAction = new WColorPickerAction(WColorPicker::ColorOption::AllowNoColor, colorPaletteSettings.getHotcueColorPalette(), this); m_pColorPickerAction->setObjectName("TrackColorPickerAction"); connect(m_pColorPickerAction, &WColorPickerAction::colorPicked, From 8a4e87dd0d126afd83650153f0ddb112abf7e4c8 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 27 Feb 2020 15:49:14 +0100 Subject: [PATCH 050/158] preferences: Make HotcuePaletteSettings support other palette types, too --- CMakeLists.txt | 2 +- build/depends.py | 2 +- src/controllers/colorjsproxy.cpp | 6 +-- src/controllers/colorjsproxy.h | 8 ++-- src/controllers/controllerengine.cpp | 2 +- src/engine/controls/cuecontrol.cpp | 40 ++++++++--------- src/engine/controls/cuecontrol.h | 4 +- src/library/dlgtrackinfo.cpp | 6 +-- src/preferences/colorpalettesettings.cpp | 43 +++++++++++++++++++ src/preferences/colorpalettesettings.h | 28 ++++++++++++ .../hotcuecolorpalettesettings.cpp | 34 --------------- src/preferences/hotcuecolorpalettesettings.h | 26 ----------- src/test/colorconfig_test.cpp | 10 ++--- src/test/controllerengine_test.cpp | 2 +- src/util/color/colorpalette.cpp | 2 +- src/util/color/colorpalette.h | 2 +- src/widget/wcuemenupopup.cpp | 4 +- src/widget/woverview.cpp | 17 ++++---- src/widget/wtracktableview.cpp | 4 +- 19 files changed, 126 insertions(+), 116 deletions(-) create mode 100644 src/preferences/colorpalettesettings.cpp create mode 100644 src/preferences/colorpalettesettings.h delete mode 100644 src/preferences/hotcuecolorpalettesettings.cpp delete mode 100644 src/preferences/hotcuecolorpalettesettings.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c3aecc6f763..06092cec65c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -475,7 +475,7 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL src/preferences/dialog/dlgprefwaveformdlg.ui src/preferences/dlgpreferencepage.cpp src/preferences/effectsettingsmodel.cpp - src/preferences/hotcuecolorpalettesettings.cpp + src/preferences/colorpalettesettings.cpp src/preferences/replaygainsettings.cpp src/preferences/settingsmanager.cpp src/preferences/upgrade.cpp diff --git a/build/depends.py b/build/depends.py index 41dd2019b58..fbc05c69c14 100644 --- a/build/depends.py +++ b/build/depends.py @@ -790,7 +790,7 @@ def sources(self, build): "src/preferences/effectsettingsmodel.cpp", "src/preferences/broadcastprofile.cpp", "src/preferences/upgrade.cpp", - "src/preferences/hotcuecolorpalettesettings.cpp", + "src/preferences/colorpalettesettings.cpp", "src/preferences/dlgpreferencepage.cpp", "src/effects/effectmanifest.cpp", diff --git a/src/controllers/colorjsproxy.cpp b/src/controllers/colorjsproxy.cpp index 24aa43797ee..29a051b6110 100644 --- a/src/controllers/colorjsproxy.cpp +++ b/src/controllers/colorjsproxy.cpp @@ -1,10 +1,10 @@ #include "controllers/colorjsproxy.h" -#include "preferences/hotcuecolorpalettesettings.h" +#include "preferences/colorpalettesettings.h" #include "util/color/rgbcolor.h" ColorJSProxy::ColorJSProxy(QScriptEngine* pScriptEngine, - HotcueColorPaletteSettings colorPaletteSettings) + ColorPaletteSettings colorPaletteSettings) : m_pScriptEngine(pScriptEngine), m_JsHotcueColorPalette( makeHotcueColorPalette(pScriptEngine, colorPaletteSettings)), @@ -28,7 +28,7 @@ QScriptValue ColorJSProxy::colorFromHexCode(uint colorCode) { } QScriptValue ColorJSProxy::makeHotcueColorPalette(QScriptEngine* pScriptEngine, - HotcueColorPaletteSettings colorPaletteSettings) { + ColorPaletteSettings colorPaletteSettings) { // TODO: make sure we get notified when the palette changes QList colorList = colorPaletteSettings.getHotcueColorPalette().m_colorList; int numColors = colorList.length(); diff --git a/src/controllers/colorjsproxy.h b/src/controllers/colorjsproxy.h index dda4d693798..4f16847135c 100644 --- a/src/controllers/colorjsproxy.h +++ b/src/controllers/colorjsproxy.h @@ -5,14 +5,14 @@ #include #include -#include "preferences/hotcuecolorpalettesettings.h" +#include "preferences/colorpalettesettings.h" #include "util/color/color.h" class ColorJSProxy final : public QObject { Q_OBJECT public: ColorJSProxy(QScriptEngine* pScriptEngine, - HotcueColorPaletteSettings colorPaletteSettings); + ColorPaletteSettings colorPaletteSettings); ~ColorJSProxy() override; @@ -24,10 +24,10 @@ class ColorJSProxy final : public QObject { private: QScriptValue makeHotcueColorPalette(QScriptEngine* pScriptEngine, - HotcueColorPaletteSettings colorPaletteSettings); + ColorPaletteSettings colorPaletteSettings); QScriptEngine* m_pScriptEngine; QScriptValue m_JsHotcueColorPalette; - HotcueColorPaletteSettings m_colorPaletteSettings; + ColorPaletteSettings m_colorPaletteSettings; }; #endif /* COLORJSPROXY_H */ diff --git a/src/controllers/controllerengine.cpp b/src/controllers/controllerengine.cpp index 3b42e057f6d..2c5df67c03e 100644 --- a/src/controllers/controllerengine.cpp +++ b/src/controllers/controllerengine.cpp @@ -216,7 +216,7 @@ void ControllerEngine::initializeScriptEngine() { } m_pColorJSProxy = std::make_unique( - m_pEngine, HotcueColorPaletteSettings(m_pConfig)); + m_pEngine, ColorPaletteSettings(m_pConfig)); engineGlobalObject.setProperty("color", m_pEngine->newQObject(m_pColorJSProxy.get())); QScriptValue constructor = m_pEngine->newFunction(ColorMapperJSProxyConstructor); diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index a95dc4af0f4..c5b3a394d8e 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -1,15 +1,15 @@ // cuecontrol.cpp // Created 11/5/2009 by RJ Ryan (rryan@mit.edu) -#include - -#include "engine/enginebuffer.h" #include "engine/controls/cuecontrol.h" +#include + #include "control/controlindicator.h" #include "control/controlobject.h" #include "control/controlpushbutton.h" -#include "preferences/hotcuecolorpalettesettings.h" +#include "engine/enginebuffer.h" +#include "preferences/colorpalettesettings.h" #include "util/color/color.h" #include "util/sample.h" #include "vinylcontrol/defs_vinylcontrol.h" @@ -26,20 +26,20 @@ static const double CUE_MODE_CUP = 5.0; constexpr double kNoColorControlValue = -1; CueControl::CueControl(QString group, - UserSettingsPointer pConfig) : - EngineControl(group, pConfig), - m_pConfig(pConfig), - m_colorPaletteSettings(HotcueColorPaletteSettings(pConfig)), - m_bPreviewing(false), - // m_pPlay->toBoo() -> engine play state - // m_pPlay->set(1.0) -> emulate play button press - m_pPlay(ControlObject::getControl(ConfigKey(group, "play"))), - m_pStopButton(ControlObject::getControl(ConfigKey(group, "stop"))), - m_iCurrentlyPreviewingHotcues(0), - m_bypassCueSetByPlay(false), - m_iNumHotCues(NUM_HOT_CUES), - m_pLoadedTrack(), - m_mutex(QMutex::Recursive) { + UserSettingsPointer pConfig) + : EngineControl(group, pConfig), + m_pConfig(pConfig), + m_colorPaletteSettings(ColorPaletteSettings(pConfig)), + m_bPreviewing(false), + // m_pPlay->toBoo() -> engine play state + // m_pPlay->set(1.0) -> emulate play button press + m_pPlay(ControlObject::getControl(ConfigKey(group, "play"))), + m_pStopButton(ControlObject::getControl(ConfigKey(group, "stop"))), + m_iCurrentlyPreviewingHotcues(0), + m_bypassCueSetByPlay(false), + m_iNumHotCues(NUM_HOT_CUES), + m_pLoadedTrack(), + m_mutex(QMutex::Recursive) { // To silence a compiler warning about CUE_MODE_PIONEER. Q_UNUSED(CUE_MODE_PIONEER); createControls(); @@ -1702,7 +1702,7 @@ void CueControl::hotcueFocusColorPrev(double v) { } mixxx::RgbColor color = *controlColor; - HotcueColorPaletteSettings m_colorPaletteSettings(m_pConfig); + ColorPaletteSettings m_colorPaletteSettings(m_pConfig); ColorPalette colorPalette = m_colorPaletteSettings.getHotcueColorPalette(); // Get previous color in color set @@ -1736,7 +1736,7 @@ void CueControl::hotcueFocusColorNext(double v) { } mixxx::RgbColor color = *controlColor; - HotcueColorPaletteSettings colorPaletteSettings(m_pConfig); + ColorPaletteSettings colorPaletteSettings(m_pConfig); ColorPalette colorPalette = colorPaletteSettings.getHotcueColorPalette(); // Get previous color in color set diff --git a/src/engine/controls/cuecontrol.h b/src/engine/controls/cuecontrol.h index 59fccf385a0..ecc071e97fc 100644 --- a/src/engine/controls/cuecontrol.h +++ b/src/engine/controls/cuecontrol.h @@ -9,7 +9,7 @@ #include "control/controlproxy.h" #include "engine/controls/enginecontrol.h" -#include "preferences/hotcuecolorpalettesettings.h" +#include "preferences/colorpalettesettings.h" #include "preferences/usersettings.h" #include "track/track.h" @@ -195,7 +195,7 @@ class CueControl : public EngineControl { TrackAt getTrackAt() const; UserSettingsPointer m_pConfig; - HotcueColorPaletteSettings m_colorPaletteSettings; + ColorPaletteSettings m_colorPaletteSettings; bool m_bPreviewing; ControlObject* m_pPlay; ControlObject* m_pStopButton; diff --git a/src/library/dlgtrackinfo.cpp b/src/library/dlgtrackinfo.cpp index 9a4429be713..333342471bb 100644 --- a/src/library/dlgtrackinfo.cpp +++ b/src/library/dlgtrackinfo.cpp @@ -1,13 +1,13 @@ +#include "library/dlgtrackinfo.h" + #include #include #include -#include #include #include "library/coverartcache.h" #include "library/coverartutils.h" -#include "library/dlgtrackinfo.h" -#include "preferences/hotcuecolorpalettesettings.h" +#include "preferences/colorpalettesettings.h" #include "sources/soundsourceproxy.h" #include "track/beatfactory.h" #include "track/cue.h" diff --git a/src/preferences/colorpalettesettings.cpp b/src/preferences/colorpalettesettings.cpp new file mode 100644 index 00000000000..147b626ef78 --- /dev/null +++ b/src/preferences/colorpalettesettings.cpp @@ -0,0 +1,43 @@ +#include "preferences/colorpalettesettings.h" + +const QString ColorPaletteSettings::hotcueColorPaletteGroup = QStringLiteral("[HotcueColorPalette]"); + +ColorPalette ColorPaletteSettings::getColorPalette( + const QString& group, const ColorPalette& defaultPalette) const { + QList colorList; + for (const ConfigKey& key : m_pConfig->getKeysWithGroup(group)) { + mixxx::RgbColor color = mixxx::RgbColor(m_pConfig->getValue(key, mixxx::RgbColor(0))); + colorList.append(color); + } + + // If no palette is defined in the settings, we use the default one. + if (colorList.isEmpty()) { + return defaultPalette; + } + + return colorList; +} + +void ColorPaletteSettings::setColorPalette( + const QString& group, const ColorPalette& colorPalette) { + removePalette(group); + + for (int index = 0; index < colorPalette.m_colorList.count(); ++index) { + mixxx::RgbColor color = colorPalette.m_colorList[index]; + m_pConfig->setValue(keyForIndex(group, index), color); + } +} + +void ColorPaletteSettings::removePalette(const QString& group) { + for (const ConfigKey& key : m_pConfig->getKeysWithGroup(group)) { + m_pConfig->remove(key); + } +} + +ColorPalette ColorPaletteSettings::getHotcueColorPalette() const { + return getColorPalette(hotcueColorPaletteGroup, ColorPalette::mixxxHotcuePalette); +} + +void ColorPaletteSettings::setHotcueColorPalette(const ColorPalette& colorPalette) { + setColorPalette(hotcueColorPaletteGroup, colorPalette); +} diff --git a/src/preferences/colorpalettesettings.h b/src/preferences/colorpalettesettings.h new file mode 100644 index 00000000000..bffa6c31963 --- /dev/null +++ b/src/preferences/colorpalettesettings.h @@ -0,0 +1,28 @@ +#pragma once + +#include "preferences/usersettings.h" +#include "util/color/colorpalette.h" + +class ColorPaletteSettings { + public: + explicit ColorPaletteSettings(UserSettingsPointer pConfig) + : m_pConfig(pConfig) { + } + + ColorPalette getHotcueColorPalette() const; + void setHotcueColorPalette(const ColorPalette& colorPalette); + + private: + static const QString hotcueColorPaletteGroup; + + ColorPalette getColorPalette(const QString& group, const ColorPalette& defaultPalette) const; + void setColorPalette(const QString& group, const ColorPalette& colorPalette); + + void removePalette(const QString& group); + + ConfigKey keyForIndex(const QString& group, int index) { + return ConfigKey(group, QString::number(index)); + } + + UserSettingsPointer m_pConfig; +}; diff --git a/src/preferences/hotcuecolorpalettesettings.cpp b/src/preferences/hotcuecolorpalettesettings.cpp deleted file mode 100644 index 76903b054e0..00000000000 --- a/src/preferences/hotcuecolorpalettesettings.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "preferences/hotcuecolorpalettesettings.h" - -const QString HotcueColorPaletteSettings::sGroup = "[HotcueColorPalette]"; - -ColorPalette HotcueColorPaletteSettings::getHotcueColorPalette() const { - QList colorList; - for (const ConfigKey& key : m_pConfig->getKeysWithGroup(sGroup)) { - mixxx::RgbColor color = mixxx::RgbColor(m_pConfig->getValue(key, mixxx::RgbColor(0))); - colorList.append(color); - } - - // If no palette is defined in the settings, we use the default one. - if (colorList.isEmpty()) { - return ColorPalette::mixxxPalette; - } - - return colorList; -} - -void HotcueColorPaletteSettings::setHotcueColorPalette( - const ColorPalette& colorPalette) { - removePalette(); - - for (int index = 0; index < colorPalette.m_colorList.count(); ++index) { - mixxx::RgbColor color = colorPalette.m_colorList[index]; - m_pConfig->setValue(keyForIndex(index), color); - } -} - -void HotcueColorPaletteSettings::removePalette() { - for (const ConfigKey& key : m_pConfig->getKeysWithGroup(sGroup)) { - m_pConfig->remove(key); - } -} diff --git a/src/preferences/hotcuecolorpalettesettings.h b/src/preferences/hotcuecolorpalettesettings.h deleted file mode 100644 index 9ed134146a2..00000000000 --- a/src/preferences/hotcuecolorpalettesettings.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "preferences/usersettings.h" -#include "util/color/colorpalette.h" - -class HotcueColorPaletteSettings { - public: - explicit HotcueColorPaletteSettings(UserSettingsPointer pConfig) - : m_pConfig(pConfig) { - } - - ColorPalette getHotcueColorPalette() const; - - void setHotcueColorPalette(const ColorPalette& colorPalette); - - private: - static const QString sGroup; - - void removePalette(); - - ConfigKey keyForIndex(int index) { - return ConfigKey(sGroup, QString::number(index)); - } - - UserSettingsPointer m_pConfig; -}; diff --git a/src/test/colorconfig_test.cpp b/src/test/colorconfig_test.cpp index 81a5e36fdbe..560c0f7b2ef 100644 --- a/src/test/colorconfig_test.cpp +++ b/src/test/colorconfig_test.cpp @@ -1,6 +1,6 @@ #include -#include "preferences/hotcuecolorpalettesettings.h" +#include "preferences/colorpalettesettings.h" #include "test/mixxxtest.h" #include "util/color/colorpalette.h" #include "util/color/rgbcolor.h" @@ -24,7 +24,7 @@ TEST_F(ColorConfigTest, GetDefaultColorWhenNoStoredColor) { } TEST_F(ColorConfigTest, SaveColorPalette) { - HotcueColorPaletteSettings colorPaletteSettings(config()); + ColorPaletteSettings colorPaletteSettings(config()); ColorPalette originalColorPalette(QList{ mixxx::RgbColor(0x66FF99), mixxx::RgbColor(0xFF9900), @@ -40,7 +40,7 @@ TEST_F(ColorConfigTest, SaveColorPalette) { } TEST_F(ColorConfigTest, ReplaceColorPalette) { - HotcueColorPaletteSettings colorPaletteSettings(config()); + ColorPaletteSettings colorPaletteSettings(config()); ColorPalette colorPalette1(QList{ mixxx::RgbColor(0x66FF99), mixxx::RgbColor(0xFF9900), @@ -62,8 +62,8 @@ TEST_F(ColorConfigTest, ReplaceColorPalette) { } TEST_F(ColorConfigTest, DefaultColorPalette) { - HotcueColorPaletteSettings colorPaletteSettings(config()); + ColorPaletteSettings colorPaletteSettings(config()); ColorPalette colorPaletteFromConfig = colorPaletteSettings.getHotcueColorPalette(); - ASSERT_EQ(ColorPalette::mixxxPalette, colorPaletteFromConfig); + ASSERT_EQ(ColorPalette::mixxxHotcuePalette, colorPaletteFromConfig); } diff --git a/src/test/controllerengine_test.cpp b/src/test/controllerengine_test.cpp index 18976c5f342..b788caac4b6 100644 --- a/src/test/controllerengine_test.cpp +++ b/src/test/controllerengine_test.cpp @@ -620,7 +620,7 @@ TEST_F(ControllerEngineTest, connectionExecutesWithCorrectThisObject) { } TEST_F(ControllerEngineTest, colorProxyTestMixxxPalette) { - QList allColors = ColorPalette::mixxxPalette.m_colorList; + QList allColors = ColorPalette::mixxxHotcuePalette.m_colorList; for (int i = 0; i < allColors.length(); ++i) { mixxx::RgbColor color = allColors[i]; qDebug() << "Testing color " << mixxx::RgbColor::toQString(color); diff --git a/src/util/color/colorpalette.cpp b/src/util/color/colorpalette.cpp index 2b04c25b1eb..47b1cc5cc65 100644 --- a/src/util/color/colorpalette.cpp +++ b/src/util/color/colorpalette.cpp @@ -9,7 +9,7 @@ constexpr mixxx::RgbColor kColorMixxxPurple = mixxx::RgbColor(0xAF00CC); constexpr mixxx::RgbColor kColorMixxxPink = mixxx::RgbColor(0xFCA6D7); constexpr mixxx::RgbColor kColorMixxxWhite = mixxx::RgbColor(0xF2F2FF); -const ColorPalette ColorPalette::mixxxPalette = +const ColorPalette ColorPalette::mixxxHotcuePalette = ColorPalette(QList{ kColorMixxxRed, kColorMixxxYellow, diff --git a/src/util/color/colorpalette.h b/src/util/color/colorpalette.h index 26375fe76f7..a5675ed15ac 100644 --- a/src/util/color/colorpalette.h +++ b/src/util/color/colorpalette.h @@ -30,7 +30,7 @@ class ColorPalette { return m_colorList.end(); } - static const ColorPalette mixxxPalette; + static const ColorPalette mixxxHotcuePalette; QList m_colorList; }; diff --git a/src/widget/wcuemenupopup.cpp b/src/widget/wcuemenupopup.cpp index 4ff1e13f66a..d4e0006c2f3 100644 --- a/src/widget/wcuemenupopup.cpp +++ b/src/widget/wcuemenupopup.cpp @@ -5,7 +5,7 @@ #include #include "engine/engine.h" -#include "preferences/hotcuecolorpalettesettings.h" +#include "preferences/colorpalettesettings.h" #include "util/color/color.h" WCueMenuPopup::WCueMenuPopup(UserSettingsPointer pConfig, QWidget* parent) @@ -31,7 +31,7 @@ WCueMenuPopup::WCueMenuPopup(UserSettingsPointer pConfig, QWidget* parent) connect(m_pEditLabel, &QLineEdit::textEdited, this, &WCueMenuPopup::slotEditLabel); connect(m_pEditLabel, &QLineEdit::returnPressed, this, &WCueMenuPopup::hide); - HotcueColorPaletteSettings colorPaletteSettings(pConfig); + ColorPaletteSettings colorPaletteSettings(pConfig); m_pColorPicker = new WColorPicker(WColorPicker::ColorOption::DenyNoColor, colorPaletteSettings.getHotcueColorPalette(), this); m_pColorPicker->setObjectName("CueColorPicker"); connect(m_pColorPicker, &WColorPicker::colorPicked, this, &WCueMenuPopup::slotChangeCueColor); diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index a59bc84fa73..1cbd94eb25b 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -10,22 +10,23 @@ // // +#include "woverview.h" + #include -#include +#include #include #include #include -#include #include #include -#include +#include #include "analyzer/analyzerprogress.h" #include "control/controlobject.h" #include "control/controlproxy.h" #include "engine/engine.h" #include "mixer/playermanager.h" -#include "preferences/hotcuecolorpalettesettings.h" +#include "preferences/colorpalettesettings.h" #include "track/track.h" #include "util/color/color.h" #include "util/compatibility.h" @@ -34,12 +35,10 @@ #include "util/math.h" #include "util/painterscope.h" #include "util/timer.h" -#include "widget/controlwidgetconnection.h" -#include "woverview.h" -#include "wskincolor.h" - #include "waveform/waveform.h" #include "waveform/waveformwidgetfactory.h" +#include "widget/controlwidgetconnection.h" +#include "wskincolor.h" WOverview::WOverview( const char* group, @@ -133,7 +132,7 @@ void WOverview::setup(const QDomNode& node, const SkinContext& context) { // setup hotcues and cue and loop(s) m_marks.setup(m_group, node, context, m_signalColors); - HotcueColorPaletteSettings colorPaletteSettings(m_pConfig); + ColorPaletteSettings colorPaletteSettings(m_pConfig); auto colorPalette = colorPaletteSettings.getHotcueColorPalette(); m_pCueMenuPopup->useColorSet(colorPalette); diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index a23a1020b2f..934aed39c89 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -24,8 +24,8 @@ #include "library/trackcollection.h" #include "library/trackcollectionmanager.h" #include "mixer/playermanager.h" +#include "preferences/colorpalettesettings.h" #include "preferences/dialog/dlgpreflibrary.h" -#include "preferences/hotcuecolorpalettesettings.h" #include "sources/soundsourceproxy.h" #include "track/track.h" #include "track/trackref.h" @@ -574,7 +574,7 @@ void WTrackTableView::createActions() { connect(m_pBpmThreeHalvesAction, &QAction::triggered, this, [this] { slotScaleBpm(Beats::THREEHALVES); }); - HotcueColorPaletteSettings colorPaletteSettings(m_pConfig); + ColorPaletteSettings colorPaletteSettings(m_pConfig); m_pColorPickerAction = new WColorPickerAction(WColorPicker::ColorOption::AllowNoColor, colorPaletteSettings.getHotcueColorPalette(), this); m_pColorPickerAction->setObjectName("TrackColorPickerAction"); connect(m_pColorPickerAction, From df91a83af614ac3a3ac9e29e4ccdadd0acb8f9a4 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 27 Feb 2020 16:11:01 +0100 Subject: [PATCH 051/158] util/color/colorpalette: Add support for a dedicated track color palette --- src/preferences/colorpalettesettings.cpp | 9 +++++++++ src/preferences/colorpalettesettings.h | 4 ++++ src/widget/wtracktableview.cpp | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/preferences/colorpalettesettings.cpp b/src/preferences/colorpalettesettings.cpp index 147b626ef78..a3f7ef52466 100644 --- a/src/preferences/colorpalettesettings.cpp +++ b/src/preferences/colorpalettesettings.cpp @@ -1,6 +1,7 @@ #include "preferences/colorpalettesettings.h" const QString ColorPaletteSettings::hotcueColorPaletteGroup = QStringLiteral("[HotcueColorPalette]"); +const QString ColorPaletteSettings::trackColorPaletteGroup = QStringLiteral("[TrackColorPalette]"); ColorPalette ColorPaletteSettings::getColorPalette( const QString& group, const ColorPalette& defaultPalette) const { @@ -41,3 +42,11 @@ ColorPalette ColorPaletteSettings::getHotcueColorPalette() const { void ColorPaletteSettings::setHotcueColorPalette(const ColorPalette& colorPalette) { setColorPalette(hotcueColorPaletteGroup, colorPalette); } + +ColorPalette ColorPaletteSettings::getTrackColorPalette() const { + return getColorPalette(trackColorPaletteGroup, ColorPalette::mixxxHotcuePalette); +} + +void ColorPaletteSettings::setTrackColorPalette(const ColorPalette& colorPalette) { + setColorPalette(trackColorPaletteGroup, colorPalette); +} diff --git a/src/preferences/colorpalettesettings.h b/src/preferences/colorpalettesettings.h index bffa6c31963..8112eaf7045 100644 --- a/src/preferences/colorpalettesettings.h +++ b/src/preferences/colorpalettesettings.h @@ -12,8 +12,12 @@ class ColorPaletteSettings { ColorPalette getHotcueColorPalette() const; void setHotcueColorPalette(const ColorPalette& colorPalette); + ColorPalette getTrackColorPalette() const; + void setTrackColorPalette(const ColorPalette& colorPalette); + private: static const QString hotcueColorPaletteGroup; + static const QString trackColorPaletteGroup; ColorPalette getColorPalette(const QString& group, const ColorPalette& defaultPalette) const; void setColorPalette(const QString& group, const ColorPalette& colorPalette); diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 934aed39c89..2bbf3895d1e 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -575,7 +575,7 @@ void WTrackTableView::createActions() { this, [this] { slotScaleBpm(Beats::THREEHALVES); }); ColorPaletteSettings colorPaletteSettings(m_pConfig); - m_pColorPickerAction = new WColorPickerAction(WColorPicker::ColorOption::AllowNoColor, colorPaletteSettings.getHotcueColorPalette(), this); + m_pColorPickerAction = new WColorPickerAction(WColorPicker::ColorOption::AllowNoColor, colorPaletteSettings.getTrackColorPalette(), this); m_pColorPickerAction->setObjectName("TrackColorPickerAction"); connect(m_pColorPickerAction, &WColorPickerAction::colorPicked, From dac88104e30233792e915a4c5d74c249e82709d0 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 27 Feb 2020 16:59:19 +0100 Subject: [PATCH 052/158] widget/wcolorpicker: Determine best number of columns for palette size --- src/widget/wcolorpicker.cpp | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/widget/wcolorpicker.cpp b/src/widget/wcolorpicker.cpp index ff32b4de008..8b3bcf75b41 100644 --- a/src/widget/wcolorpicker.cpp +++ b/src/widget/wcolorpicker.cpp @@ -8,7 +8,30 @@ #include "util/parented_ptr.h" namespace { - const int kNumColumns = 4; +constexpr int kNumColumnsCandidates[] = {5, 4, 3}; +} + +// Determine the best number of columns for items in a QGridView. +// +// Ideally, numItems % numColumn == 0 holds true. Rows that are almost +// empty do not look good, so if the we can't find the ideal column count, +// we fall back to a column count with the biggest number of elements in +// the last row. +inline int idealColumnCount(int numItems) { + int numColumns = 4; // Default in case kNumColumnsCandidates is empty + int numColumnsRemainder = -1; + for (const int numColumnsCandidate : kNumColumnsCandidates) { + int remainder = numItems % numColumnsCandidate; + if (remainder == 0) { + numColumns = numColumnsCandidate; + break; + } else if (remainder > numColumnsRemainder) { + numColumnsRemainder = numColumnsCandidate; + numColumns = numColumnsCandidate; + } + } + + return numColumns; } WColorPicker::WColorPicker(ColorOption colorOption, const ColorPalette& palette, QWidget* parent) @@ -35,6 +58,12 @@ WColorPicker::WColorPicker(ColorOption colorOption, const ColorPalette& palette, int row = 0; int column = 0; + int numColors = m_palette.size(); + if (m_colorOption == ColorOption::AllowNoColor) { + numColors++; + } + + int numColumns = idealColumnCount(numColors); if (m_colorOption == ColorOption::AllowNoColor) { addColorButton(std::nullopt, pLayout, row, column); column++; @@ -43,7 +72,7 @@ WColorPicker::WColorPicker(ColorOption colorOption, const ColorPalette& palette, for (const auto& color : m_palette) { addColorButton(color, pLayout, row, column); column++; - if (column == kNumColumns) { + if (column == numColumns) { column = 0; row++; } From 0e2792551530b86f905b44869500d0f57d8f58d0 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 27 Feb 2020 17:19:56 +0100 Subject: [PATCH 053/158] engine/controls/cuecontrol: Add some debug asserts for color conversions --- src/engine/controls/cuecontrol.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index c5b3a394d8e..e6fc8582003 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -1869,6 +1869,8 @@ void HotcueControl::slotHotcueColorChanged(double newColor) { qWarning() << "slotHotcueColorChanged got invalid value:" << newColor; return; } + + DEBUG_ASSERT(newColor == mixxx::RgbColor::validateCode(static_cast(newColor))); m_pCue->setColor(mixxx::RgbColor(static_cast(newColor))); emit(hotcueColorChanged(this, newColor)); } @@ -1889,6 +1891,8 @@ mixxx::RgbColor::optional_t HotcueControl::getColor() const { if (value < 0) { return std::nullopt; } + + DEBUG_ASSERT(value == mixxx::RgbColor::validateCode(static_cast(value))); return mixxx::RgbColor(static_cast(value)); } From 327702ed8d4a8529bf80a939f7ea0e152b235bb8 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 27 Feb 2020 17:35:29 +0100 Subject: [PATCH 054/158] engine/control/cuecontrol: Add helper func to convert RgbColor values --- src/engine/controls/cuecontrol.cpp | 36 +++++++++++++++++++----------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index e6fc8582003..4cb7b789901 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -25,6 +25,22 @@ static const double CUE_MODE_CUP = 5.0; constexpr double kNoColorControlValue = -1; +namespace { + +// Helper function to convert doubles into RgbColor instances (or nullopt) +inline mixxx::RgbColor::optional_t doubleToRgbColor(double value) { + if (value < 0) { + return std::nullopt; + } + mixxx::RgbColor::code_t colorCode = static_cast(value); + if (value != mixxx::RgbColor::validateCode(colorCode)) { + return std::nullopt; + } + return mixxx::RgbColor::optional(colorCode); +} + +} // namespace + CueControl::CueControl(QString group, UserSettingsPointer pConfig) : EngineControl(group, pConfig), @@ -1865,13 +1881,13 @@ void HotcueControl::slotHotcuePositionChanged(double newPosition) { } void HotcueControl::slotHotcueColorChanged(double newColor) { - if (newColor < 0) { + mixxx::RgbColor::optional_t color = doubleToRgbColor(newColor); + if (!color) { qWarning() << "slotHotcueColorChanged got invalid value:" << newColor; return; } - DEBUG_ASSERT(newColor == mixxx::RgbColor::validateCode(static_cast(newColor))); - m_pCue->setColor(mixxx::RgbColor(static_cast(newColor))); + m_pCue->setColor(*color); emit(hotcueColorChanged(this, newColor)); } @@ -1887,21 +1903,15 @@ void HotcueControl::setCue(CuePointer pCue) { m_pCue = pCue; } mixxx::RgbColor::optional_t HotcueControl::getColor() const { - double value = m_hotcueColor->get(); - if (value < 0) { - return std::nullopt; - } - - DEBUG_ASSERT(value == mixxx::RgbColor::validateCode(static_cast(value))); - return mixxx::RgbColor(static_cast(value)); + return doubleToRgbColor(m_hotcueColor->get()); } void HotcueControl::setColor(const mixxx::RgbColor::optional_t newColor) { - if (newColor) { - m_hotcueColor->set(*newColor); + if (!newColor) { + m_hotcueColor->set(kNoColorControlValue); return; } - m_hotcueColor->set(kNoColorControlValue); + m_hotcueColor->set(*newColor); } void HotcueControl::resetCue() { // clear pCue first because we have a null check for valid data else where From e964345cf565a59f50345bf8398951f07ffd7ea9 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 27 Feb 2020 17:36:11 +0100 Subject: [PATCH 055/158] engine/controls/cuecontrol: Fix wrong color index in hotcueFocusColorPrev --- src/engine/controls/cuecontrol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index 4cb7b789901..b91e819bcbe 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -1723,7 +1723,7 @@ void CueControl::hotcueFocusColorPrev(double v) { // Get previous color in color set int iColorIndex = colorPalette.indexOf(color) - 1; - if (iColorIndex <= 0) { + if (iColorIndex < 0) { iColorIndex = colorPalette.size() - 1; } color = colorPalette.at(iColorIndex); From a2d789ce615f5e369addb1deb634e45b44e8b293 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 27 Feb 2020 22:43:12 +0100 Subject: [PATCH 056/158] Roland DJ-505: Fix eslint issues in controller script --- res/controllers/Roland_DJ-505-scripts.js | 32 ++++++++++++------------ 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/res/controllers/Roland_DJ-505-scripts.js b/res/controllers/Roland_DJ-505-scripts.js index 6e6c45284d0..fa9e126fd15 100644 --- a/res/controllers/Roland_DJ-505-scripts.js +++ b/res/controllers/Roland_DJ-505-scripts.js @@ -971,22 +971,22 @@ DJ505.PadColor = { }; DJ505.PadColorMap = new ColorMapper({ - '#FFCC0000': DJ505.PadColor.RED, - '#FFCC4400': DJ505.PadColor.CORAL, - '#FFCC8800': DJ505.PadColor.ORANGE, - '#FFCCCC00': DJ505.PadColor.YELLOW, - '#FF88CC00': DJ505.PadColor.GREEN, - '#FF00CC00': DJ505.PadColor.APPLEGREEN, - '#FF00CC88': DJ505.PadColor.AQUAMARINE, - '#FF00CCCC': DJ505.PadColor.TURQUOISE, - '#FF0088CC': DJ505.PadColor.CELESTE, - '#FF0000CC': DJ505.PadColor.BLUE, - '#FF4400CC': DJ505.PadColor.AZURE, - '#FF8800CC': DJ505.PadColor.PURPLE, - '#FFCC00CC': DJ505.PadColor.MAGENTA, - '#FFCC0044': DJ505.PadColor.RED, - '#FFFFCCCC': DJ505.PadColor.APRICOT, - '#FFFFFFFF': DJ505.PadColor.WHITE, + "#FFCC0000": DJ505.PadColor.RED, + "#FFCC4400": DJ505.PadColor.CORAL, + "#FFCC8800": DJ505.PadColor.ORANGE, + "#FFCCCC00": DJ505.PadColor.YELLOW, + "#FF88CC00": DJ505.PadColor.GREEN, + "#FF00CC00": DJ505.PadColor.APPLEGREEN, + "#FF00CC88": DJ505.PadColor.AQUAMARINE, + "#FF00CCCC": DJ505.PadColor.TURQUOISE, + "#FF0088CC": DJ505.PadColor.CELESTE, + "#FF0000CC": DJ505.PadColor.BLUE, + "#FF4400CC": DJ505.PadColor.AZURE, + "#FF8800CC": DJ505.PadColor.PURPLE, + "#FFCC00CC": DJ505.PadColor.MAGENTA, + "#FFCC0044": DJ505.PadColor.RED, + "#FFFFCCCC": DJ505.PadColor.APRICOT, + "#FFFFFFFF": DJ505.PadColor.WHITE, }); DJ505.PadSection = function(deck, offset) { From 982f7b79f275047b248e164e322e895fb62a6ee7 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 27 Feb 2020 22:45:48 +0100 Subject: [PATCH 057/158] res/skins: Fix trailing whitespace errors in style.qss files --- res/skins/LateNight/style.qss | 14 +++++--------- res/skins/Shade/style.qss | 2 +- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index e489aa9c356..c51102c3e5b 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -1074,7 +1074,7 @@ QPushButton#pushButtonRepeatPlaylist:!checked { padding: 3px 6px; */ qproperty-icon: url(skin:/buttons_classic/btn__delete.svg); /* color buttons are 42x24 px. - To get the final size for the Delete button consider border width. + To get the final size for the Delete button consider border width. wide button: width: 38px; height: 20px; @@ -2178,7 +2178,7 @@ WCueMenuPopup QPushButton:focus { padding-right: 3px; border-right: 1px solid #000; /* gradient colors should match those of QHeaderView gradient, - with a litte transparency added to not cut off the header label */ + with a litte transparency added to not cut off the header label */ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgba(34,34,34,190), stop:1 rgba(17,17,17,190)); @@ -2523,7 +2523,7 @@ WEffectSelector, #fadeModeCombobox { height: 19px; padding: 0px 0px 1px 5px; - margin: 0px 1px 2px 1px; + margin: 0px 1px 2px 1px; } WEffectSelector::down-arrow, #fadeModeCombobox::down-arrow { @@ -2546,7 +2546,7 @@ WEffectSelector, WEffectSelector::indicator:checked, #fadeModeCombobox::indicator:checked { /* checkbox container is 28 x 22px; - use margin + border to create a square checkbox sized like kill buttons */ + use margin + border to create a square checkbox sized like kill buttons */ margin: 2px; image: url(skin:/buttons_classic/btn__lib_checkmark_orange.svg); } @@ -2595,7 +2595,7 @@ WEffectSelector, padding: 5px 12px 5px 26px; } /* Icons in QLineEdit menus: - beatsize spinbox, searchbox, editable track properties */ + beatsize spinbox, searchbox, editable track properties */ WBeatSpinBox QMenu::icon, #LibraryContainer QMenu::icon, WCueMenuPopup QMenu::icon, @@ -2736,7 +2736,3 @@ WEffectSelector, #Border58 { border: 1px solid #585858; } - - - - diff --git a/res/skins/Shade/style.qss b/res/skins/Shade/style.qss index 38bdbcae5c0..b0bc06487d9 100644 --- a/res/skins/Shade/style.qss +++ b/res/skins/Shade/style.qss @@ -220,7 +220,7 @@ WCoverArtMenu { /* unchecked menu checkbox */ #LibraryContainer QMenu QCheckBox::indicator:enabled:!checked, #LibraryContainer QMenu::indicator:!checked { - border-color: #1a2025;/* + border-color: #1a2025;/* background-color: #7e868b; remove OS focus indicator */ outline: none; From e8ce23e4ccc414b169d48da9814a50e0dcaf55bb Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 27 Feb 2020 22:46:41 +0100 Subject: [PATCH 058/158] controllers/controller: Fix end-of-line linter issues --- src/controllers/controller.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controllers/controller.h b/src/controllers/controller.h index 387b0640973..a1c1a8c020e 100644 --- a/src/controllers/controller.h +++ b/src/controllers/controller.h @@ -101,7 +101,7 @@ class Controller : public QObject, ConstControllerPresetVisitor { // To be called in sub-class' close() functions after stopping any input // polling/processing but before closing the device. void stopEngine(); - + // To be called when receiving events void triggerActivity(); From 49388981c9436c683a5e6358ee644ef543f9be3d Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 27 Feb 2020 23:07:44 +0100 Subject: [PATCH 059/158] preferences/configobject: Replace mixxx::RgbColor::optional_t with optional --- src/preferences/configobject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/preferences/configobject.cpp b/src/preferences/configobject.cpp index 765bf6d18cb..fb3cb078745 100644 --- a/src/preferences/configobject.cpp +++ b/src/preferences/configobject.cpp @@ -349,7 +349,7 @@ mixxx::RgbColor::optional_t ConfigObject::getValue( if (!parsedColor.isValid()) { return default_value; } - auto color = mixxx::RgbColor::optional_t(parsedColor.rgb()); + auto color = mixxx::RgbColor::optional(parsedColor.rgb()); return color ? color : default_value; } From ba3b84d2a0c2f2289716cc4d1acb2b547c669ea4 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Fri, 28 Feb 2020 09:42:54 +0100 Subject: [PATCH 060/158] widget/cuemenupopup: Remove usage of std::optional::value() --- src/widget/wcuemenupopup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widget/wcuemenupopup.cpp b/src/widget/wcuemenupopup.cpp index d4e0006c2f3..1d9dea71b0b 100644 --- a/src/widget/wcuemenupopup.cpp +++ b/src/widget/wcuemenupopup.cpp @@ -117,7 +117,7 @@ void WCueMenuPopup::slotChangeCueColor(const mixxx::RgbColor::optional_t& color) VERIFY_OR_DEBUG_ASSERT(color) { return; } - m_pCue->setColor(color.value()); + m_pCue->setColor(*color); m_pColorPicker->setSelectedColor(color); hide(); } From 11935e23d746d8a1299d373d25d31816f3b86464 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Fri, 28 Feb 2020 12:40:06 +0100 Subject: [PATCH 061/158] Do not pass RgbColor/RgbColor::optional_t by reference --- src/track/cue.cpp | 2 +- src/track/cue.h | 2 +- src/widget/wcolorpicker.cpp | 6 +++--- src/widget/wcolorpicker.h | 6 +++--- src/widget/wcuemenupopup.cpp | 2 +- src/widget/wcuemenupopup.h | 2 +- src/widget/wtracktableview.cpp | 2 +- src/widget/wtracktableview.h | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/track/cue.cpp b/src/track/cue.cpp index 286d2269aa5..45e3ec3e2e2 100644 --- a/src/track/cue.cpp +++ b/src/track/cue.cpp @@ -165,7 +165,7 @@ mixxx::RgbColor Cue::getColor() const { return m_color; } -void Cue::setColor(const mixxx::RgbColor& color) { +void Cue::setColor(const mixxx::RgbColor color) { QMutexLocker lock(&m_mutex); m_color = color; m_bDirty = true; diff --git a/src/track/cue.h b/src/track/cue.h index cf86b4393d8..6846041b70e 100644 --- a/src/track/cue.h +++ b/src/track/cue.h @@ -55,7 +55,7 @@ class Cue : public QObject { void setLabel(QString label); mixxx::RgbColor getColor() const; - void setColor(const mixxx::RgbColor& color); + void setColor(const mixxx::RgbColor color); double getEndPosition() const; diff --git a/src/widget/wcolorpicker.cpp b/src/widget/wcolorpicker.cpp index 8b3bcf75b41..8d7b8cb2ae9 100644 --- a/src/widget/wcolorpicker.cpp +++ b/src/widget/wcolorpicker.cpp @@ -79,7 +79,7 @@ WColorPicker::WColorPicker(ColorOption colorOption, const ColorPalette& palette, } } -void WColorPicker::addColorButton(const mixxx::RgbColor::optional_t& color, QGridLayout* pLayout, int row, int column) { +void WColorPicker::addColorButton(const mixxx::RgbColor::optional_t color, QGridLayout* pLayout, int row, int column) { setLayout(pLayout); parented_ptr pColorButton = make_parented("", this); if (m_pStyle) { @@ -141,7 +141,7 @@ void WColorPicker::resetSelectedColor() { pButton->style()->polish(pButton); } -void WColorPicker::setSelectedColor(const mixxx::RgbColor::optional_t& color) { +void WColorPicker::setSelectedColor(const mixxx::RgbColor::optional_t color) { resetSelectedColor(); m_selectedColor = color; @@ -194,6 +194,6 @@ void WColorPicker::useColorSet(const ColorPalette& palette) { } } -void WColorPicker::slotColorPicked(const mixxx::RgbColor::optional_t& color) { +void WColorPicker::slotColorPicked(const mixxx::RgbColor::optional_t color) { setSelectedColor(color); } diff --git a/src/widget/wcolorpicker.h b/src/widget/wcolorpicker.h index f43419c425b..671be786b08 100644 --- a/src/widget/wcolorpicker.h +++ b/src/widget/wcolorpicker.h @@ -20,17 +20,17 @@ class WColorPicker : public QWidget { explicit WColorPicker(ColorOption colorOption, const ColorPalette& palette, QWidget* parent = nullptr); void resetSelectedColor(); - void setSelectedColor(const mixxx::RgbColor::optional_t& color); + void setSelectedColor(const mixxx::RgbColor::optional_t color); void useColorSet(const ColorPalette& palette); signals: void colorPicked(mixxx::RgbColor::optional_t color); private slots: - void slotColorPicked(const mixxx::RgbColor::optional_t& color); + void slotColorPicked(const mixxx::RgbColor::optional_t color); private: - void addColorButton(const mixxx::RgbColor::optional_t& color, QGridLayout* pLayout, int row, int column); + void addColorButton(const mixxx::RgbColor::optional_t color, QGridLayout* pLayout, int row, int column); ColorOption m_colorOption; mixxx::RgbColor::optional_t m_selectedColor; ColorPalette m_palette; diff --git a/src/widget/wcuemenupopup.cpp b/src/widget/wcuemenupopup.cpp index 1d9dea71b0b..0d21dcdc8ed 100644 --- a/src/widget/wcuemenupopup.cpp +++ b/src/widget/wcuemenupopup.cpp @@ -110,7 +110,7 @@ void WCueMenuPopup::slotEditLabel() { m_pCue->setLabel(m_pEditLabel->text()); } -void WCueMenuPopup::slotChangeCueColor(const mixxx::RgbColor::optional_t& color) { +void WCueMenuPopup::slotChangeCueColor(const mixxx::RgbColor::optional_t color) { VERIFY_OR_DEBUG_ASSERT(m_pCue != nullptr) { return; } diff --git a/src/widget/wcuemenupopup.h b/src/widget/wcuemenupopup.h index 9338783c766..e052b948dec 100644 --- a/src/widget/wcuemenupopup.h +++ b/src/widget/wcuemenupopup.h @@ -54,7 +54,7 @@ class WCueMenuPopup : public QWidget { private slots: void slotEditLabel(); void slotDeleteCue(); - void slotChangeCueColor(const mixxx::RgbColor::optional_t& color); + void slotChangeCueColor(const mixxx::RgbColor::optional_t color); private: CuePointer m_pCue; diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 2bbf3895d1e..562658d860c 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -1972,7 +1972,7 @@ void WTrackTableView::lockBpm(bool lock) { } } -void WTrackTableView::slotColorPicked(const mixxx::RgbColor::optional_t& color) { +void WTrackTableView::slotColorPicked(const mixxx::RgbColor::optional_t color) { TrackModel* trackModel = getTrackModel(); if (trackModel == nullptr) { return; diff --git a/src/widget/wtracktableview.h b/src/widget/wtracktableview.h index ef22de80807..03cb8c3cf3e 100644 --- a/src/widget/wtracktableview.h +++ b/src/widget/wtracktableview.h @@ -81,7 +81,7 @@ class WTrackTableView : public WLibraryTableView { void slotLockBpm(); void slotUnlockBpm(); void slotScaleBpm(int); - void slotColorPicked(const mixxx::RgbColor::optional_t& color); + void slotColorPicked(const mixxx::RgbColor::optional_t color); void slotClearBeats(); void slotClearPlayCount(); From 74e884ae1cb32d2e96e3d5ba9d582562338c8f9f Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Fri, 28 Feb 2020 23:24:05 +0100 Subject: [PATCH 062/158] preferences/configobject: Use RgbColor conversion functions --- src/preferences/configobject.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/preferences/configobject.cpp b/src/preferences/configobject.cpp index fb3cb078745..e3814e1683d 100644 --- a/src/preferences/configobject.cpp +++ b/src/preferences/configobject.cpp @@ -291,14 +291,14 @@ void ConfigObject::setValue( set(key, ConfigValue("")); return; } - set(key, ConfigValue(mixxx::toQColor(*value).name(QColor::NameFormat::HexArgb))); + set(key, ConfigValue(mixxx::RgbColor::toQString(value))); } template<> template<> void ConfigObject::setValue( const ConfigKey& key, const mixxx::RgbColor& value) { - set(key, ConfigValue(mixxx::toQColor(value).name(QColor::NameFormat::HexArgb))); + set(key, ConfigValue(mixxx::RgbColor::toQString(value))); } template <> template <> @@ -345,12 +345,7 @@ mixxx::RgbColor::optional_t ConfigObject::getValue( if (value.isNull()) { return default_value; } - QColor parsedColor(value.value); - if (!parsedColor.isValid()) { - return default_value; - } - auto color = mixxx::RgbColor::optional(parsedColor.rgb()); - return color ? color : default_value; + return mixxx::RgbColor::fromQString(value.value, default_value); } template<> From d54fd95b052d930ca4f0583810d0c40fa3f6836f Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Fri, 28 Feb 2020 23:32:44 +0100 Subject: [PATCH 063/158] widget/wcolorpicker: Add tooltip to color picker --- src/widget/wcolorpicker.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/widget/wcolorpicker.cpp b/src/widget/wcolorpicker.cpp index 8d7b8cb2ae9..a2ba6d8d9c3 100644 --- a/src/widget/wcolorpicker.cpp +++ b/src/widget/wcolorpicker.cpp @@ -93,6 +93,7 @@ void WColorPicker::addColorButton(const mixxx::RgbColor::optional_t color, QGrid } else { pColorButton->setProperty("noColor", true); } + pColorButton->setToolTip(mixxx::RgbColor::toQString(color, tr("No Color"))); pColorButton->setCheckable(true); m_colorButtons.append(pColorButton); @@ -191,6 +192,7 @@ void WColorPicker::useColorSet(const ColorPalette& palette) { m_colorButtons.at(j)->setStyleSheet( QString("QPushButton { background-color: %1; }") .arg(mixxx::RgbColor::toQString(palette.at(i)))); + m_colorButtons.at(j)->setToolTip(mixxx::RgbColor::toQString(palette.at(i), tr("No Color"))); } } From 709cb3fdc0542bf960d15368984c1023f722c6c2 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 1 Mar 2020 00:31:37 +0100 Subject: [PATCH 064/158] controllers: Remove obsolete ColorJSProxy --- CMakeLists.txt | 1 - build/depends.py | 1 - src/controllers/colorjsproxy.cpp | 41 ---------------------------- src/controllers/colorjsproxy.h | 33 ---------------------- src/controllers/controllerengine.cpp | 5 ---- src/controllers/controllerengine.h | 2 -- 6 files changed, 83 deletions(-) delete mode 100644 src/controllers/colorjsproxy.cpp delete mode 100644 src/controllers/colorjsproxy.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 06092cec65c..f66527a1171 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,7 +167,6 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL src/control/controlproxy.cpp src/control/controlpushbutton.cpp src/control/controlttrotary.cpp - src/controllers/colorjsproxy.cpp src/controllers/colormapper.cpp src/controllers/colormapperjsproxy.cpp src/controllers/controller.cpp diff --git a/build/depends.py b/build/depends.py index fbc05c69c14..95fa4c374d4 100644 --- a/build/depends.py +++ b/build/depends.py @@ -926,7 +926,6 @@ def sources(self, build): "src/controllers/midi/midioutputhandler.cpp", "src/controllers/softtakeover.cpp", "src/controllers/keyboard/keyboardeventfilter.cpp", - "src/controllers/colorjsproxy.cpp", "src/controllers/colormapper.cpp", "src/controllers/colormapperjsproxy.cpp", diff --git a/src/controllers/colorjsproxy.cpp b/src/controllers/colorjsproxy.cpp deleted file mode 100644 index 29a051b6110..00000000000 --- a/src/controllers/colorjsproxy.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "controllers/colorjsproxy.h" - -#include "preferences/colorpalettesettings.h" -#include "util/color/rgbcolor.h" - -ColorJSProxy::ColorJSProxy(QScriptEngine* pScriptEngine, - ColorPaletteSettings colorPaletteSettings) - : m_pScriptEngine(pScriptEngine), - m_JsHotcueColorPalette( - makeHotcueColorPalette(pScriptEngine, colorPaletteSettings)), - m_colorPaletteSettings(colorPaletteSettings) { -} - -ColorJSProxy::~ColorJSProxy() = default; - -Q_INVOKABLE QScriptValue ColorJSProxy::hotcueColorPalette() { - return m_JsHotcueColorPalette; -} - -QScriptValue ColorJSProxy::colorFromHexCode(uint colorCode) { - QRgb rgb = QRgb(colorCode); - QScriptValue jsColor = m_pScriptEngine->newObject(); - jsColor.setProperty("red", qRed(rgb)); - jsColor.setProperty("green", qGreen(rgb)); - jsColor.setProperty("blue", qBlue(rgb)); - jsColor.setProperty("alpha", qAlpha(rgb)); - return jsColor; -} - -QScriptValue ColorJSProxy::makeHotcueColorPalette(QScriptEngine* pScriptEngine, - ColorPaletteSettings colorPaletteSettings) { - // TODO: make sure we get notified when the palette changes - QList colorList = colorPaletteSettings.getHotcueColorPalette().m_colorList; - int numColors = colorList.length(); - QScriptValue jsColorList = pScriptEngine->newArray(numColors); - for (int i = 0; i < numColors; ++i) { - mixxx::RgbColor color = colorList.at(i); - jsColorList.setProperty(i, colorFromHexCode(color)); - } - return jsColorList; -} diff --git a/src/controllers/colorjsproxy.h b/src/controllers/colorjsproxy.h deleted file mode 100644 index 4f16847135c..00000000000 --- a/src/controllers/colorjsproxy.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef COLORJSPROXY_H -#define COLORJSPROXY_H - -#include -#include -#include - -#include "preferences/colorpalettesettings.h" -#include "util/color/color.h" - -class ColorJSProxy final : public QObject { - Q_OBJECT - public: - ColorJSProxy(QScriptEngine* pScriptEngine, - ColorPaletteSettings colorPaletteSettings); - - ~ColorJSProxy() override; - - Q_INVOKABLE QScriptValue hotcueColorPalette(); - // Return a JS object with the red, green, blue and alpha components - // of a color. The parameter is the hexadecimal representation of the color - // i.e. 0xAARRGGBB - Q_INVOKABLE QScriptValue colorFromHexCode(uint colorCode); - - private: - QScriptValue makeHotcueColorPalette(QScriptEngine* pScriptEngine, - ColorPaletteSettings colorPaletteSettings); - QScriptEngine* m_pScriptEngine; - QScriptValue m_JsHotcueColorPalette; - ColorPaletteSettings m_colorPaletteSettings; -}; - -#endif /* COLORJSPROXY_H */ diff --git a/src/controllers/controllerengine.cpp b/src/controllers/controllerengine.cpp index 2c5df67c03e..1488353b5d4 100644 --- a/src/controllers/controllerengine.cpp +++ b/src/controllers/controllerengine.cpp @@ -187,7 +187,6 @@ void ControllerEngine::gracefulShutdown() { ++it; } - m_pColorJSProxy.reset(); delete m_pBaClass; m_pBaClass = nullptr; } @@ -215,10 +214,6 @@ void ControllerEngine::initializeScriptEngine() { engineGlobalObject.setProperty("midi", m_pEngine->newQObject(m_pController)); } - m_pColorJSProxy = std::make_unique( - m_pEngine, ColorPaletteSettings(m_pConfig)); - engineGlobalObject.setProperty("color", m_pEngine->newQObject(m_pColorJSProxy.get())); - QScriptValue constructor = m_pEngine->newFunction(ColorMapperJSProxyConstructor); QScriptValue metaObject = m_pEngine->newQMetaObject(&ColorMapperJSProxy::staticMetaObject, constructor); engineGlobalObject.setProperty("ColorMapper", metaObject); diff --git a/src/controllers/controllerengine.h b/src/controllers/controllerengine.h index 7eafb1763ea..25b2893d501 100644 --- a/src/controllers/controllerengine.h +++ b/src/controllers/controllerengine.h @@ -16,7 +16,6 @@ #include "bytearrayclass.h" #include "preferences/usersettings.h" #include "controllers/controllerpreset.h" -#include "controllers/colorjsproxy.h" #include "controllers/softtakeover.h" #include "util/alphabetafilter.h" #include "util/duration.h" @@ -211,7 +210,6 @@ class ControllerEngine : public QObject { QHash m_timers; SoftTakeoverCtrl m_st; ByteArrayClass* m_pBaClass; - std::unique_ptr m_pColorJSProxy; // 256 (default) available virtual decks is enough I would think. // If more are needed at run-time, these will move to the heap automatically QVarLengthArray m_intervalAccumulator; From e6a47350680c63720c8725639b40873b90d12aaf Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 1 Mar 2020 00:32:03 +0100 Subject: [PATCH 065/158] controllers/colormapperjsproxy: Remove alpha channel from JS script color --- src/controllers/colormapperjsproxy.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/controllers/colormapperjsproxy.cpp b/src/controllers/colormapperjsproxy.cpp index f806cb9752e..42d33cb0dc8 100644 --- a/src/controllers/colormapperjsproxy.cpp +++ b/src/controllers/colormapperjsproxy.cpp @@ -13,7 +13,6 @@ QScriptValue ColorMapperJSProxy::getNearestColor(uint colorCode) { jsColor.setProperty("red", qRed(result.first)); jsColor.setProperty("green", qGreen(result.first)); jsColor.setProperty("blue", qBlue(result.first)); - jsColor.setProperty("alpha", qAlpha(result.first)); return jsColor; } From 5b846c5a34ff33bcf17e2ce56b8abf9c8c6ddf25 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 1 Mar 2020 00:45:36 +0100 Subject: [PATCH 066/158] res/controllers: Remove global color constant from .eslint.json --- res/controllers/.eslintrc.json | 1 - 1 file changed, 1 deletion(-) diff --git a/res/controllers/.eslintrc.json b/res/controllers/.eslintrc.json index 0a7c34d9961..b2687b106a2 100644 --- a/res/controllers/.eslintrc.json +++ b/res/controllers/.eslintrc.json @@ -2,7 +2,6 @@ "globals": { "ColorMapper": "readonly", "_": "readonly", - "color": "readonly", "components": "readonly", "engine": "readonly", "midi": "readonly", From 52062f33177578a78803a1b675fdffdafe4f79d3 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 1 Mar 2020 01:13:36 +0100 Subject: [PATCH 067/158] res/controllers/midi-components: Remove references to global color object --- res/controllers/midi-components-0.0.js | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/res/controllers/midi-components-0.0.js b/res/controllers/midi-components-0.0.js index db2ac092f8c..9936e0841e3 100644 --- a/res/controllers/midi-components-0.0.js +++ b/res/controllers/midi-components-0.0.js @@ -308,12 +308,20 @@ shift: function() { this.inKey = "hotcue_" + this.number + "_clear"; }, - getColor: function() { - if (this.colorKey !== undefined) { - return color.colorFromHexCode(engine.getValue(this.group, this.colorKey)); - } else { - return null; + getColor: function(colorCode) { + if (colorCode === undefined && this.colorKey !== undefined) { + colorCode = engine.getValue(this.group, this.colorKey); } + + if (colorCode !== undefined) { + return { + "red": (colorCode >> 16) & 0xFF, + "green": (colorCode >> 8) & 0xFF, + "blue": colorCode & 0xFF, + }; + } + + return null; }, output: function(value) { var outval = this.outValueScale(value); @@ -336,7 +344,7 @@ print("ERROR: no function defined for sending RGB colors"); return; } - this.sendRGB(color.colorFromHexCode(colorCode)); + this.sendRGB(this.getColor(colorCode)); } }, connect: function() { From 6181401de5762534c4f07be689acb9f1deb29b5b Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 1 Mar 2020 09:12:07 +0100 Subject: [PATCH 068/158] test/controllerengine_test: Remove test for ColorJSProxy --- src/test/controllerengine_test.cpp | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/src/test/controllerengine_test.cpp b/src/test/controllerengine_test.cpp index b788caac4b6..4b16d53b8e7 100644 --- a/src/test/controllerengine_test.cpp +++ b/src/test/controllerengine_test.cpp @@ -618,25 +618,3 @@ TEST_F(ControllerEngineTest, connectionExecutesWithCorrectThisObject) { // The counter should have been incremented exactly once. EXPECT_DOUBLE_EQ(1.0, pass->get()); } - -TEST_F(ControllerEngineTest, colorProxyTestMixxxPalette) { - QList allColors = ColorPalette::mixxxHotcuePalette.m_colorList; - for (int i = 0; i < allColors.length(); ++i) { - mixxx::RgbColor color = allColors[i]; - qDebug() << "Testing color " << mixxx::RgbColor::toQString(color); - QString colorCode = QString::number(color); - QScriptValue jsColor = pScriptEngine->evaluate( - "color.colorFromHexCode(" + colorCode + ")"); - EXPECT_EQ(jsColor.property("red").toInt32(), qRed(color)); - EXPECT_EQ(jsColor.property("green").toInt32(), qGreen(color)); - EXPECT_EQ(jsColor.property("blue").toInt32(), qBlue(color)); - EXPECT_EQ(jsColor.property("alpha").toInt32(), qAlpha(color)); - - QScriptValue jsColor2 = pScriptEngine->evaluate( - "color.hotcueColorPalette()[" + QString::number(i) + "]"); - EXPECT_EQ(jsColor2.property("red").toInt32(), qRed(color)); - EXPECT_EQ(jsColor2.property("green").toInt32(), qGreen(color)); - EXPECT_EQ(jsColor2.property("blue").toInt32(), qBlue(color)); - EXPECT_EQ(jsColor2.property("alpha").toInt32(), qAlpha(color)); - } -} From dc9e476985f3f17626debaefc2e1f1ae0bcc473e Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 1 Mar 2020 09:16:34 +0100 Subject: [PATCH 069/158] cuecontrol: Remove unnecessary instantiation of ColorPaletteSettings --- src/engine/controls/cuecontrol.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index b91e819bcbe..d3a53229ea1 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -1718,7 +1718,6 @@ void CueControl::hotcueFocusColorPrev(double v) { } mixxx::RgbColor color = *controlColor; - ColorPaletteSettings m_colorPaletteSettings(m_pConfig); ColorPalette colorPalette = m_colorPaletteSettings.getHotcueColorPalette(); // Get previous color in color set @@ -1752,8 +1751,7 @@ void CueControl::hotcueFocusColorNext(double v) { } mixxx::RgbColor color = *controlColor; - ColorPaletteSettings colorPaletteSettings(m_pConfig); - ColorPalette colorPalette = colorPaletteSettings.getHotcueColorPalette(); + ColorPalette colorPalette = m_colorPaletteSettings.getHotcueColorPalette(); // Get previous color in color set int iColorIndex = colorPalette.indexOf(color) + 1; From fcf24010e6586736a0fcbb9ea512fcc4f93a1b8c Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 1 Mar 2020 09:18:53 +0100 Subject: [PATCH 070/158] track/cue: Remove misleading alpha channel --- src/track/cue.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/track/cue.cpp b/src/track/cue.cpp index 45e3ec3e2e2..d7bc86e8fa0 100644 --- a/src/track/cue.cpp +++ b/src/track/cue.cpp @@ -10,7 +10,7 @@ namespace { const QString kDefaultLabel = ""; // empty string, not null - const mixxx::RgbColor kDefaultCueColor = mixxx::RgbColor(0xFFF2F2FF); // white + const mixxx::RgbColor kDefaultCueColor = mixxx::RgbColor(0xF2F2FF); // white } //static From b8ee8d656a2591f212411cac29da1ad6faf33ad9 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 1 Mar 2020 09:19:29 +0100 Subject: [PATCH 071/158] util/color/colorpalette: Enclose color consts in anonymous namespace --- src/util/color/colorpalette.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/util/color/colorpalette.cpp b/src/util/color/colorpalette.cpp index 47b1cc5cc65..8f542e699be 100644 --- a/src/util/color/colorpalette.cpp +++ b/src/util/color/colorpalette.cpp @@ -1,5 +1,6 @@ #include "colorpalette.h" +namespace { constexpr mixxx::RgbColor kColorMixxxRed = mixxx::RgbColor(0xC50A08); constexpr mixxx::RgbColor kColorMixxxYellow = mixxx::RgbColor(0x32BE44); constexpr mixxx::RgbColor kColorMixxxGreen = mixxx::RgbColor(0x0044FF); @@ -8,6 +9,7 @@ constexpr mixxx::RgbColor kColorMixxxBlue = mixxx::RgbColor(0x42D4F4); constexpr mixxx::RgbColor kColorMixxxPurple = mixxx::RgbColor(0xAF00CC); constexpr mixxx::RgbColor kColorMixxxPink = mixxx::RgbColor(0xFCA6D7); constexpr mixxx::RgbColor kColorMixxxWhite = mixxx::RgbColor(0xF2F2FF); +} // anonymous namespace const ColorPalette ColorPalette::mixxxHotcuePalette = ColorPalette(QList{ From 26f8c3bb84c4afa20898c320f9b65577076d88f6 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 1 Mar 2020 09:22:24 +0100 Subject: [PATCH 072/158] Remove unnecessary const from (optional) RgbColor parameters --- src/engine/controls/cuecontrol.cpp | 2 +- src/engine/controls/cuecontrol.h | 2 +- src/track/cue.cpp | 2 +- src/track/cue.h | 2 +- src/widget/wcolorpicker.cpp | 6 +++--- src/widget/wcolorpicker.h | 6 +++--- src/widget/wcuemenupopup.cpp | 2 +- src/widget/wcuemenupopup.h | 2 +- src/widget/wtracktableview.cpp | 2 +- src/widget/wtracktableview.h | 2 +- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index d3a53229ea1..f7255059e85 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -1904,7 +1904,7 @@ mixxx::RgbColor::optional_t HotcueControl::getColor() const { return doubleToRgbColor(m_hotcueColor->get()); } -void HotcueControl::setColor(const mixxx::RgbColor::optional_t newColor) { +void HotcueControl::setColor(mixxx::RgbColor::optional_t newColor) { if (!newColor) { m_hotcueColor->set(kNoColorControlValue); return; diff --git a/src/engine/controls/cuecontrol.h b/src/engine/controls/cuecontrol.h index ecc071e97fc..4c9f0e32a78 100644 --- a/src/engine/controls/cuecontrol.h +++ b/src/engine/controls/cuecontrol.h @@ -51,7 +51,7 @@ class HotcueControl : public QObject { void setCue(CuePointer pCue); void resetCue(); void setPosition(double position); - void setColor(const mixxx::RgbColor::optional_t newColor); + void setColor(mixxx::RgbColor::optional_t newColor); mixxx::RgbColor::optional_t getColor() const; // Used for caching the preview state of this hotcue control. diff --git a/src/track/cue.cpp b/src/track/cue.cpp index d7bc86e8fa0..57406665e8c 100644 --- a/src/track/cue.cpp +++ b/src/track/cue.cpp @@ -165,7 +165,7 @@ mixxx::RgbColor Cue::getColor() const { return m_color; } -void Cue::setColor(const mixxx::RgbColor color) { +void Cue::setColor(mixxx::RgbColor color) { QMutexLocker lock(&m_mutex); m_color = color; m_bDirty = true; diff --git a/src/track/cue.h b/src/track/cue.h index 6846041b70e..34631127fac 100644 --- a/src/track/cue.h +++ b/src/track/cue.h @@ -55,7 +55,7 @@ class Cue : public QObject { void setLabel(QString label); mixxx::RgbColor getColor() const; - void setColor(const mixxx::RgbColor color); + void setColor(mixxx::RgbColor color); double getEndPosition() const; diff --git a/src/widget/wcolorpicker.cpp b/src/widget/wcolorpicker.cpp index a2ba6d8d9c3..a1adc31ae9c 100644 --- a/src/widget/wcolorpicker.cpp +++ b/src/widget/wcolorpicker.cpp @@ -79,7 +79,7 @@ WColorPicker::WColorPicker(ColorOption colorOption, const ColorPalette& palette, } } -void WColorPicker::addColorButton(const mixxx::RgbColor::optional_t color, QGridLayout* pLayout, int row, int column) { +void WColorPicker::addColorButton(mixxx::RgbColor::optional_t color, QGridLayout* pLayout, int row, int column) { setLayout(pLayout); parented_ptr pColorButton = make_parented("", this); if (m_pStyle) { @@ -142,7 +142,7 @@ void WColorPicker::resetSelectedColor() { pButton->style()->polish(pButton); } -void WColorPicker::setSelectedColor(const mixxx::RgbColor::optional_t color) { +void WColorPicker::setSelectedColor(mixxx::RgbColor::optional_t color) { resetSelectedColor(); m_selectedColor = color; @@ -196,6 +196,6 @@ void WColorPicker::useColorSet(const ColorPalette& palette) { } } -void WColorPicker::slotColorPicked(const mixxx::RgbColor::optional_t color) { +void WColorPicker::slotColorPicked(mixxx::RgbColor::optional_t color) { setSelectedColor(color); } diff --git a/src/widget/wcolorpicker.h b/src/widget/wcolorpicker.h index 671be786b08..8c744c13851 100644 --- a/src/widget/wcolorpicker.h +++ b/src/widget/wcolorpicker.h @@ -20,17 +20,17 @@ class WColorPicker : public QWidget { explicit WColorPicker(ColorOption colorOption, const ColorPalette& palette, QWidget* parent = nullptr); void resetSelectedColor(); - void setSelectedColor(const mixxx::RgbColor::optional_t color); + void setSelectedColor(mixxx::RgbColor::optional_t color); void useColorSet(const ColorPalette& palette); signals: void colorPicked(mixxx::RgbColor::optional_t color); private slots: - void slotColorPicked(const mixxx::RgbColor::optional_t color); + void slotColorPicked(mixxx::RgbColor::optional_t color); private: - void addColorButton(const mixxx::RgbColor::optional_t color, QGridLayout* pLayout, int row, int column); + void addColorButton(mixxx::RgbColor::optional_t color, QGridLayout* pLayout, int row, int column); ColorOption m_colorOption; mixxx::RgbColor::optional_t m_selectedColor; ColorPalette m_palette; diff --git a/src/widget/wcuemenupopup.cpp b/src/widget/wcuemenupopup.cpp index 0d21dcdc8ed..0ab8f54ac4b 100644 --- a/src/widget/wcuemenupopup.cpp +++ b/src/widget/wcuemenupopup.cpp @@ -110,7 +110,7 @@ void WCueMenuPopup::slotEditLabel() { m_pCue->setLabel(m_pEditLabel->text()); } -void WCueMenuPopup::slotChangeCueColor(const mixxx::RgbColor::optional_t color) { +void WCueMenuPopup::slotChangeCueColor(mixxx::RgbColor::optional_t color) { VERIFY_OR_DEBUG_ASSERT(m_pCue != nullptr) { return; } diff --git a/src/widget/wcuemenupopup.h b/src/widget/wcuemenupopup.h index e052b948dec..3c8094e8be5 100644 --- a/src/widget/wcuemenupopup.h +++ b/src/widget/wcuemenupopup.h @@ -54,7 +54,7 @@ class WCueMenuPopup : public QWidget { private slots: void slotEditLabel(); void slotDeleteCue(); - void slotChangeCueColor(const mixxx::RgbColor::optional_t color); + void slotChangeCueColor(mixxx::RgbColor::optional_t color); private: CuePointer m_pCue; diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 562658d860c..11791c1acb3 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -1972,7 +1972,7 @@ void WTrackTableView::lockBpm(bool lock) { } } -void WTrackTableView::slotColorPicked(const mixxx::RgbColor::optional_t color) { +void WTrackTableView::slotColorPicked(mixxx::RgbColor::optional_t color) { TrackModel* trackModel = getTrackModel(); if (trackModel == nullptr) { return; diff --git a/src/widget/wtracktableview.h b/src/widget/wtracktableview.h index 03cb8c3cf3e..fd6beae9d6a 100644 --- a/src/widget/wtracktableview.h +++ b/src/widget/wtracktableview.h @@ -81,7 +81,7 @@ class WTrackTableView : public WLibraryTableView { void slotLockBpm(); void slotUnlockBpm(); void slotScaleBpm(int); - void slotColorPicked(const mixxx::RgbColor::optional_t color); + void slotColorPicked(mixxx::RgbColor::optional_t color); void slotClearBeats(); void slotClearPlayCount(); From a0379dc33e14b6e75caa4380d003d4ebb6b71e39 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 1 Mar 2020 09:27:34 +0100 Subject: [PATCH 073/158] engine/controls/cuecontrol: Use emit without braces --- src/engine/controls/cuecontrol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index f7255059e85..6772a70bd42 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -1886,7 +1886,7 @@ void HotcueControl::slotHotcueColorChanged(double newColor) { } m_pCue->setColor(*color); - emit(hotcueColorChanged(this, newColor)); + emit hotcueColorChanged(this, newColor); } double HotcueControl::getPosition() const { From dd353e6b7f6c012435fca1c669296b2f87b18c20 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 1 Mar 2020 09:28:02 +0100 Subject: [PATCH 074/158] library/dao/cuedao: Replace static_cast with RgbColor::toQVariant --- src/library/dao/cuedao.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/library/dao/cuedao.cpp b/src/library/dao/cuedao.cpp index 2621a94e1c9..b47769477e4 100644 --- a/src/library/dao/cuedao.cpp +++ b/src/library/dao/cuedao.cpp @@ -154,7 +154,7 @@ bool CueDAO::saveCue(Cue* cue) { query.bindValue(":length", cue->getLength()); query.bindValue(":hotcue", cue->getHotCue()); query.bindValue(":label", cue->getLabel()); - query.bindValue(":color", static_cast(cue->getColor())); + query.bindValue(":color", mixxx::RgbColor::toQVariant(cue->getColor())); if (query.exec()) { int id = query.lastInsertId().toInt(); @@ -182,7 +182,7 @@ bool CueDAO::saveCue(Cue* cue) { query.bindValue(":length", cue->getLength()); query.bindValue(":hotcue", cue->getHotCue()); query.bindValue(":label", cue->getLabel()); - query.bindValue(":color", static_cast(cue->getColor())); + query.bindValue(":color", mixxx::RgbColor::toQVariant(cue->getColor())); if (query.exec()) { cue->setDirty(false); From 328edfb16dc9488b95ae6cba1eaa467cbfec253f Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 1 Mar 2020 15:48:48 +0100 Subject: [PATCH 075/158] engine/controls/cuecontrol: Clean up auto_hotcue_colors logic --- src/engine/controls/cuecontrol.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index 6772a70bd42..5975fb482cb 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -620,12 +620,12 @@ void CueControl::hotcueSet(HotcueControl* pControl, double v) { auto hotcueColorPalette = m_colorPaletteSettings.getHotcueColorPalette(); ConfigKey autoHotcueColorsKey("[Controls]", "auto_hotcue_colors"); + int iColorIndex = 0; if (getConfig()->getValue(autoHotcueColorsKey, false)) { - auto colors = hotcueColorPalette.m_colorList; - pCue->setColor(colors.at(hotcue % colors.count())); - } else { - pCue->setColor(hotcueColorPalette.m_colorList.first()); + // For hotcue n, get nth color from palette + iColorIndex = (hotcue % hotcueColorPalette.size()); }; + pCue->setColor(hotcueColorPalette.at(iColorIndex)); // TODO(XXX) deal with spurious signals attachCue(pCue, pControl); From bb2f30b583e0051dc2947645b41766cd9a5d6286 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 1 Mar 2020 15:49:41 +0100 Subject: [PATCH 076/158] engine/controls/cuecontrol: Improve HotcueControl::setColor code --- src/engine/controls/cuecontrol.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index 5975fb482cb..78f30a0d519 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -1905,11 +1905,11 @@ mixxx::RgbColor::optional_t HotcueControl::getColor() const { } void HotcueControl::setColor(mixxx::RgbColor::optional_t newColor) { - if (!newColor) { + if (newColor) { + m_hotcueColor->set(*newColor); + } else { m_hotcueColor->set(kNoColorControlValue); - return; } - m_hotcueColor->set(*newColor); } void HotcueControl::resetCue() { // clear pCue first because we have a null check for valid data else where From 129e0e6df5d92a64da8f17752d25aeb56f908bdb Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 1 Mar 2020 15:56:52 +0100 Subject: [PATCH 077/158] engine/controls/cuecontrol: Use kNoColorControlValue const instead of -1 --- src/engine/controls/cuecontrol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index 78f30a0d519..52a85aa7bc1 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -1789,7 +1789,7 @@ HotcueControl::HotcueControl(QString group, int i) // The rgba value of the color assigned to this color. m_hotcueColor = new ControlObject(keyForControl(i, "color")); - m_hotcueColor->set(-1); + m_hotcueColor->set(kNoColorControlValue); connect(m_hotcueColor, &ControlObject::valueChanged, this, From 7022535e1c1be9eeaae4dc5865e855fe59ab61c8 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 1 Mar 2020 15:50:32 +0100 Subject: [PATCH 078/158] preferences/colorpalettesettings: Do not access m_colorList directly --- src/preferences/colorpalettesettings.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/preferences/colorpalettesettings.cpp b/src/preferences/colorpalettesettings.cpp index a3f7ef52466..a676265016c 100644 --- a/src/preferences/colorpalettesettings.cpp +++ b/src/preferences/colorpalettesettings.cpp @@ -23,8 +23,8 @@ void ColorPaletteSettings::setColorPalette( const QString& group, const ColorPalette& colorPalette) { removePalette(group); - for (int index = 0; index < colorPalette.m_colorList.count(); ++index) { - mixxx::RgbColor color = colorPalette.m_colorList[index]; + for (int index = 0; index < colorPalette.size(); ++index) { + mixxx::RgbColor color = colorPalette.at(index); m_pConfig->setValue(keyForIndex(group, index), color); } } From 35e2e790a14a64eecd6d69263d71bc9430ea120d Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 1 Mar 2020 15:51:36 +0100 Subject: [PATCH 079/158] util/color/colorpalette: Make sure that ColorPalette has at least 1 color --- src/util/color/colorpalette.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util/color/colorpalette.h b/src/util/color/colorpalette.h index a5675ed15ac..b67998fd279 100644 --- a/src/util/color/colorpalette.h +++ b/src/util/color/colorpalette.h @@ -8,6 +8,7 @@ class ColorPalette { public: ColorPalette(QList colorList) : m_colorList(colorList) { + DEBUG_ASSERT(m_colorList.size() != 0); } mixxx::RgbColor at(int i) const { From 8060f916cbc61c013e9e8cf8e5f4565e05f13e76 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 1 Mar 2020 15:52:28 +0100 Subject: [PATCH 080/158] util/color/colorpalette: Make m_colorList private --- src/util/color/colorpalette.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/util/color/colorpalette.h b/src/util/color/colorpalette.h index b67998fd279..d12e22da4c0 100644 --- a/src/util/color/colorpalette.h +++ b/src/util/color/colorpalette.h @@ -33,10 +33,15 @@ class ColorPalette { static const ColorPalette mixxxHotcuePalette; + const QList& getColorList() const { + return m_colorList; + } + + private: QList m_colorList; }; inline bool operator==( const ColorPalette& lhs, const ColorPalette& rhs) { - return lhs.m_colorList == rhs.m_colorList; + return lhs.getColorList() == rhs.getColorList(); } From d7557adcb2a9f9c9701a32fe2996996ce3b2e08f Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 1 Mar 2020 15:53:06 +0100 Subject: [PATCH 081/158] util/color/colorpalette: Add nextColor/previousColor methods --- src/engine/controls/cuecontrol.cpp | 22 ++-------------------- src/util/color/colorpalette.cpp | 19 +++++++++++++++++++ src/util/color/colorpalette.h | 3 +++ 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index 52a85aa7bc1..103092d011b 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -1716,18 +1716,9 @@ void CueControl::hotcueFocusColorPrev(double v) { if (!controlColor) { return; } - mixxx::RgbColor color = *controlColor; ColorPalette colorPalette = m_colorPaletteSettings.getHotcueColorPalette(); - - // Get previous color in color set - int iColorIndex = colorPalette.indexOf(color) - 1; - if (iColorIndex < 0) { - iColorIndex = colorPalette.size() - 1; - } - color = colorPalette.at(iColorIndex); - - pControl->setColor(color); + pControl->setColor(colorPalette.previousColor(*controlColor)); } void CueControl::hotcueFocusColorNext(double v) { @@ -1749,18 +1740,9 @@ void CueControl::hotcueFocusColorNext(double v) { if (!controlColor) { return; } - mixxx::RgbColor color = *controlColor; ColorPalette colorPalette = m_colorPaletteSettings.getHotcueColorPalette(); - - // Get previous color in color set - int iColorIndex = colorPalette.indexOf(color) + 1; - if (iColorIndex >= colorPalette.size()) { - iColorIndex = 0; - } - color = colorPalette.at(iColorIndex); - - pControl->setColor(color); + pControl->setColor(colorPalette.nextColor(*controlColor)); } diff --git a/src/util/color/colorpalette.cpp b/src/util/color/colorpalette.cpp index 8f542e699be..74db5e255fa 100644 --- a/src/util/color/colorpalette.cpp +++ b/src/util/color/colorpalette.cpp @@ -22,3 +22,22 @@ const ColorPalette ColorPalette::mixxxHotcuePalette = kColorMixxxPink, kColorMixxxWhite, }); + +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()); +} + +mixxx::RgbColor ColorPalette::previousColor(mixxx::RgbColor color) const { + int iIndex = indexOf(color); + if (iIndex < 0) { + // Return first color if color not in palette + iIndex = 0; + } else { + iIndex = (iIndex - 1) % size(); + if (iIndex < 0) { + iIndex += size(); + } + } + return at(iIndex); +} diff --git a/src/util/color/colorpalette.h b/src/util/color/colorpalette.h index d12e22da4c0..dc865980bb7 100644 --- a/src/util/color/colorpalette.h +++ b/src/util/color/colorpalette.h @@ -23,6 +23,9 @@ class ColorPalette { return m_colorList.indexOf(color); } + mixxx::RgbColor nextColor(mixxx::RgbColor color) const; + mixxx::RgbColor previousColor(mixxx::RgbColor color) const; + QList::const_iterator begin() const { return m_colorList.begin(); } From 9d1cbf4402d451e88c9c03a3a508f55ea908c8c9 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 1 Mar 2020 16:16:56 +0100 Subject: [PATCH 082/158] test/colorpalette_test: Add tests for ColorPalette methods --- CMakeLists.txt | 1 + src/test/colorpalette_test.cpp | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 src/test/colorpalette_test.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f66527a1171..c141907523c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -924,6 +924,7 @@ add_executable(mixxx-test src/test/cache_test.cpp src/test/channelhandle_test.cpp src/test/colorconfig_test.cpp + src/test/colorpalette_test.cpp src/test/compatibility_test.cpp src/test/configobject_test.cpp src/test/controller_preset_validation_test.cpp diff --git a/src/test/colorpalette_test.cpp b/src/test/colorpalette_test.cpp new file mode 100644 index 00000000000..77b13d731de --- /dev/null +++ b/src/test/colorpalette_test.cpp @@ -0,0 +1,30 @@ +#include "util/color/colorpalette.h" + +#include + +#include "test/mixxxtest.h" + +class ColorPaletteTest : public MixxxTest {}; + +TEST_F(ColorPaletteTest, NextColor) { + const ColorPalette palette = ColorPalette::mixxxHotcuePalette; + 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; + 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; + 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)); + ASSERT_EQ(palette.previousColor(palette.nextColor(palette.at(0))), palette.at(0)); + ASSERT_EQ(palette.previousColor(palette.nextColor(palette.at(palette.size() - 1))), palette.at(palette.size() - 1)); +} From b648a5dc0e7460446f02414ac93c080923f33ef3 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 1 Mar 2020 16:30:16 +0100 Subject: [PATCH 083/158] library/dao/cuedao: Use RgbColor::fromQVariant in cueFromRow method --- src/library/dao/cuedao.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/library/dao/cuedao.cpp b/src/library/dao/cuedao.cpp index b47769477e4..3111a88bb2d 100644 --- a/src/library/dao/cuedao.cpp +++ b/src/library/dao/cuedao.cpp @@ -53,8 +53,10 @@ CuePointer CueDAO::cueFromRow(const QSqlQuery& query) const { int length = record.value(record.indexOf("length")).toInt(); int hotcue = record.value(record.indexOf("hotcue")).toInt(); QString label = record.value(record.indexOf("label")).toString(); - uint colorValue = record.value(record.indexOf("color")).toUInt(); - mixxx::RgbColor color = mixxx::RgbColor(colorValue); + mixxx::RgbColor::optional_t color = mixxx::RgbColor::fromQVariant(record.indexOf("color")); + VERIFY_OR_DEBUG_ASSERT(color) { + return CuePointer(); + } CuePointer pCue(new Cue(id, trackId, (Cue::Type)type, @@ -62,7 +64,7 @@ CuePointer CueDAO::cueFromRow(const QSqlQuery& query) const { length, hotcue, label, - color)); + *color)); m_cues[id] = pCue; return pCue; } From c8ad295268efced1c9120942e7cccf7182f32a6c Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 1 Mar 2020 16:39:41 +0100 Subject: [PATCH 084/158] Make all single argument constructors explicit --- src/controllers/bulk/bulkenumerator.h | 2 +- src/controllers/controller.h | 2 +- src/controllers/hid/hidenumerator.h | 2 +- src/controllers/midi/hss1394enumerator.h | 2 +- src/controllers/midi/midicontroller.h | 2 +- src/controllers/midi/portmidienumerator.h | 2 +- src/preferences/colorpalettesettings.cpp | 2 +- src/test/controller_preset_validation_test.cpp | 2 +- src/test/midicontrollertest.cpp | 3 ++- src/util/color/colorpalette.h | 2 +- 10 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/controllers/bulk/bulkenumerator.h b/src/controllers/bulk/bulkenumerator.h index 2018a4a1181..effd0044d68 100644 --- a/src/controllers/bulk/bulkenumerator.h +++ b/src/controllers/bulk/bulkenumerator.h @@ -14,7 +14,7 @@ struct libusb_context; class BulkEnumerator : public ControllerEnumerator { public: - BulkEnumerator(UserSettingsPointer pConfig); + explicit BulkEnumerator(UserSettingsPointer pConfig); virtual ~BulkEnumerator(); QList queryDevices(); diff --git a/src/controllers/controller.h b/src/controllers/controller.h index a1c1a8c020e..09a20d8181b 100644 --- a/src/controllers/controller.h +++ b/src/controllers/controller.h @@ -23,7 +23,7 @@ class Controller : public QObject, ConstControllerPresetVisitor { Q_OBJECT public: - Controller(UserSettingsPointer pConfig); + explicit Controller(UserSettingsPointer pConfig); ~Controller() override; // Subclass should call close() at minimum. // Returns the extension for the controller (type) preset files. This is diff --git a/src/controllers/hid/hidenumerator.h b/src/controllers/hid/hidenumerator.h index 9b39b75c947..a61490f1ab4 100644 --- a/src/controllers/hid/hidenumerator.h +++ b/src/controllers/hid/hidenumerator.h @@ -12,7 +12,7 @@ class HidEnumerator : public ControllerEnumerator { public: - HidEnumerator(UserSettingsPointer pConfig); + explicit HidEnumerator(UserSettingsPointer pConfig); virtual ~HidEnumerator(); QList queryDevices(); diff --git a/src/controllers/midi/hss1394enumerator.h b/src/controllers/midi/hss1394enumerator.h index 78d581425fd..184fcfb233c 100644 --- a/src/controllers/midi/hss1394enumerator.h +++ b/src/controllers/midi/hss1394enumerator.h @@ -13,7 +13,7 @@ class Hss1394Enumerator : public MidiEnumerator { Q_OBJECT public: - Hss1394Enumerator(UserSettingsPointer pConfig); + explicit Hss1394Enumerator(UserSettingsPointer pConfig); virtual ~Hss1394Enumerator(); QList queryDevices(); diff --git a/src/controllers/midi/midicontroller.h b/src/controllers/midi/midicontroller.h index b8ebb8b94b4..a81ff7d680c 100644 --- a/src/controllers/midi/midicontroller.h +++ b/src/controllers/midi/midicontroller.h @@ -23,7 +23,7 @@ class MidiController : public Controller { Q_OBJECT public: - MidiController(UserSettingsPointer pConfig); + explicit MidiController(UserSettingsPointer pConfig); ~MidiController() override; QString presetExtension() override; diff --git a/src/controllers/midi/portmidienumerator.h b/src/controllers/midi/portmidienumerator.h index 9566b54df1b..5169efbfa06 100644 --- a/src/controllers/midi/portmidienumerator.h +++ b/src/controllers/midi/portmidienumerator.h @@ -13,7 +13,7 @@ class PortMidiEnumerator : public MidiEnumerator { Q_OBJECT public: - PortMidiEnumerator(UserSettingsPointer pConfig); + explicit PortMidiEnumerator(UserSettingsPointer pConfig); virtual ~PortMidiEnumerator(); QList queryDevices(); diff --git a/src/preferences/colorpalettesettings.cpp b/src/preferences/colorpalettesettings.cpp index a676265016c..b2af4d12930 100644 --- a/src/preferences/colorpalettesettings.cpp +++ b/src/preferences/colorpalettesettings.cpp @@ -16,7 +16,7 @@ ColorPalette ColorPaletteSettings::getColorPalette( return defaultPalette; } - return colorList; + return ColorPalette(colorList); } void ColorPaletteSettings::setColorPalette( diff --git a/src/test/controller_preset_validation_test.cpp b/src/test/controller_preset_validation_test.cpp index 970cf0158c9..a1a65f4015f 100644 --- a/src/test/controller_preset_validation_test.cpp +++ b/src/test/controller_preset_validation_test.cpp @@ -15,7 +15,7 @@ class FakeController : public Controller { public: - FakeController(UserSettingsPointer pConfig); + explicit FakeController(UserSettingsPointer pConfig); ~FakeController() override; QString presetExtension() override { diff --git a/src/test/midicontrollertest.cpp b/src/test/midicontrollertest.cpp index 0d10c4c54a0..ac520908638 100644 --- a/src/test/midicontrollertest.cpp +++ b/src/test/midicontrollertest.cpp @@ -12,7 +12,8 @@ class MockMidiController : public MidiController { public: - MockMidiController(UserSettingsPointer pConfig) : MidiController(pConfig) { + explicit MockMidiController(UserSettingsPointer pConfig) + : MidiController(pConfig) { } ~MockMidiController() override { } diff --git a/src/util/color/colorpalette.h b/src/util/color/colorpalette.h index dc865980bb7..8f92b436fa2 100644 --- a/src/util/color/colorpalette.h +++ b/src/util/color/colorpalette.h @@ -6,7 +6,7 @@ class ColorPalette { public: - ColorPalette(QList colorList) + explicit ColorPalette(QList colorList) : m_colorList(colorList) { DEBUG_ASSERT(m_colorList.size() != 0); } From 6841da634a754e68d5c8abf49ef18b3b38c51c7a Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 1 Mar 2020 21:58:40 +0100 Subject: [PATCH 085/158] library/dlgtrackinfo: Swap DlgTrackInfo constructor arguments --- src/library/dlgtrackinfo.cpp | 2 +- src/library/dlgtrackinfo.h | 2 +- src/widget/wtracktableview.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/library/dlgtrackinfo.cpp b/src/library/dlgtrackinfo.cpp index 333342471bb..8796016c0b3 100644 --- a/src/library/dlgtrackinfo.cpp +++ b/src/library/dlgtrackinfo.cpp @@ -24,7 +24,7 @@ const int kMinBpm = 30; // Maximum allowed interval between beats (calculated from kMinBpm). const mixxx::Duration kMaxInterval = mixxx::Duration::fromMillis(1000.0 * (60.0 / kMinBpm)); -DlgTrackInfo::DlgTrackInfo(QWidget* parent, UserSettingsPointer pConfig) +DlgTrackInfo::DlgTrackInfo(UserSettingsPointer pConfig, QWidget* parent) : QDialog(parent), m_pTapFilter(new TapFilter(this, kFilterLength, kMaxInterval)), m_dLastTapedBpm(-1.), diff --git a/src/library/dlgtrackinfo.h b/src/library/dlgtrackinfo.h index 51ecc69a184..fca2b0cf1f2 100644 --- a/src/library/dlgtrackinfo.h +++ b/src/library/dlgtrackinfo.h @@ -18,7 +18,7 @@ class DlgTrackInfo : public QDialog, public Ui::DlgTrackInfo { Q_OBJECT public: - DlgTrackInfo(QWidget* parent, UserSettingsPointer pConfig); + DlgTrackInfo(UserSettingsPointer pConfig, QWidget* parent); virtual ~DlgTrackInfo(); public slots: diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 11791c1acb3..f2e0e40b750 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -754,7 +754,7 @@ void WTrackTableView::showTrackInfo(QModelIndex index) { if (m_pTrackInfo.isNull()) { // Give a NULL parent because otherwise it inherits our style which can // make it unreadable. Bug #673411 - m_pTrackInfo.reset(new DlgTrackInfo(nullptr, m_pConfig)); + m_pTrackInfo.reset(new DlgTrackInfo(m_pConfig, nullptr)); connect(m_pTrackInfo.data(), SIGNAL(next()), this, SLOT(slotNextTrackInfo())); From 4180310276a571f508af3f31c7cc6358f262fbc7 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Mon, 2 Mar 2020 23:37:49 +0100 Subject: [PATCH 086/158] controllers/colormapper: Use static_casts instead of C-style casts --- src/controllers/colormapper.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/controllers/colormapper.cpp b/src/controllers/colormapper.cpp index 3caa515806e..20571668bec 100644 --- a/src/controllers/colormapper.cpp +++ b/src/controllers/colormapper.cpp @@ -14,10 +14,10 @@ double colorDistance(QRgb a, QRgb b) { // of costly computations. In contrast, this is a low-cost // approximation and should be sufficently accurate. // More details: https://www.compuphase.com/cmetric.htm - long mean_red = ((long)qRed(a) + (long)qRed(b)) / 2; - long delta_red = (long)qRed(a) - (long)qRed(b); - long delta_green = (long)qGreen(a) - (long)qGreen(b); - long delta_blue = (long)qBlue(a) - (long)qBlue(b); + long mean_red = (static_cast(qRed(a)) + static_cast(qRed(b))) / 2; + long delta_red = static_cast(qRed(a)) - static_cast(qRed(b)); + long delta_green = static_cast(qGreen(a)) - static_cast(qGreen(b)); + long delta_blue = static_cast(qBlue(a)) - static_cast(qBlue(b)); return sqrt( (((512 + mean_red) * delta_red * delta_red) >> 8) + (4 * delta_green * delta_green) + From 1ef508452697c29e11467e1344cf5eb1eb0d5fc8 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Mon, 2 Mar 2020 23:38:22 +0100 Subject: [PATCH 087/158] engine/controls/cuecontrol: Use auto to avoid repeating type names --- src/engine/controls/cuecontrol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index 09070e40720..a8107850330 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -32,7 +32,7 @@ inline mixxx::RgbColor::optional_t doubleToRgbColor(double value) { if (value < 0) { return std::nullopt; } - mixxx::RgbColor::code_t colorCode = static_cast(value); + auto colorCode = static_cast(value); if (value != mixxx::RgbColor::validateCode(colorCode)) { return std::nullopt; } From 43cbedb474eb1d8c0162ddcb33aa7e4611c7c664 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Mon, 2 Mar 2020 23:39:04 +0100 Subject: [PATCH 088/158] preferences/colorpalettesettings: Move group constans into anon namespace --- src/preferences/colorpalettesettings.cpp | 14 ++++++++------ src/preferences/colorpalettesettings.h | 3 --- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/preferences/colorpalettesettings.cpp b/src/preferences/colorpalettesettings.cpp index b2af4d12930..4fa8f641f3c 100644 --- a/src/preferences/colorpalettesettings.cpp +++ b/src/preferences/colorpalettesettings.cpp @@ -1,7 +1,9 @@ #include "preferences/colorpalettesettings.h" -const QString ColorPaletteSettings::hotcueColorPaletteGroup = QStringLiteral("[HotcueColorPalette]"); -const QString ColorPaletteSettings::trackColorPaletteGroup = QStringLiteral("[TrackColorPalette]"); +namespace { +const QString kHotcueColorPaletteGroup = QStringLiteral("[HotcueColorPalette]"); +const QString kTrackColorPaletteGroup = QStringLiteral("[TrackColorPalette]"); +} // anonymous namespace ColorPalette ColorPaletteSettings::getColorPalette( const QString& group, const ColorPalette& defaultPalette) const { @@ -36,17 +38,17 @@ void ColorPaletteSettings::removePalette(const QString& group) { } ColorPalette ColorPaletteSettings::getHotcueColorPalette() const { - return getColorPalette(hotcueColorPaletteGroup, ColorPalette::mixxxHotcuePalette); + return getColorPalette(kHotcueColorPaletteGroup, ColorPalette::mixxxHotcuePalette); } void ColorPaletteSettings::setHotcueColorPalette(const ColorPalette& colorPalette) { - setColorPalette(hotcueColorPaletteGroup, colorPalette); + setColorPalette(kHotcueColorPaletteGroup, colorPalette); } ColorPalette ColorPaletteSettings::getTrackColorPalette() const { - return getColorPalette(trackColorPaletteGroup, ColorPalette::mixxxHotcuePalette); + return getColorPalette(kTrackColorPaletteGroup, ColorPalette::mixxxHotcuePalette); } void ColorPaletteSettings::setTrackColorPalette(const ColorPalette& colorPalette) { - setColorPalette(trackColorPaletteGroup, colorPalette); + setColorPalette(kTrackColorPaletteGroup, colorPalette); } diff --git a/src/preferences/colorpalettesettings.h b/src/preferences/colorpalettesettings.h index 8112eaf7045..f2086557040 100644 --- a/src/preferences/colorpalettesettings.h +++ b/src/preferences/colorpalettesettings.h @@ -16,9 +16,6 @@ class ColorPaletteSettings { void setTrackColorPalette(const ColorPalette& colorPalette); private: - static const QString hotcueColorPaletteGroup; - static const QString trackColorPaletteGroup; - ColorPalette getColorPalette(const QString& group, const ColorPalette& defaultPalette) const; void setColorPalette(const QString& group, const ColorPalette& colorPalette); From 287855a3661bbac6a0214a916859597cc402f190 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Mon, 2 Mar 2020 23:39:48 +0100 Subject: [PATCH 089/158] util/color/colorpalette: Simplify ColorPalette::previousColor modulo logic --- src/util/color/colorpalette.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/util/color/colorpalette.cpp b/src/util/color/colorpalette.cpp index 74db5e255fa..dd55e4e5b60 100644 --- a/src/util/color/colorpalette.cpp +++ b/src/util/color/colorpalette.cpp @@ -34,10 +34,7 @@ mixxx::RgbColor ColorPalette::previousColor(mixxx::RgbColor color) const { // Return first color if color not in palette iIndex = 0; } else { - iIndex = (iIndex - 1) % size(); - if (iIndex < 0) { - iIndex += size(); - } + iIndex = (iIndex + size() - 1) % size(); } return at(iIndex); } From 0621d0a82987e88fe50c14f2d808d8fc45a03825 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Mon, 2 Mar 2020 23:40:33 +0100 Subject: [PATCH 090/158] widget/wcolorpicker: Avoid negation in if (expr) { } else { } conditions --- src/widget/wcolorpicker.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/widget/wcolorpicker.cpp b/src/widget/wcolorpicker.cpp index a1adc31ae9c..542133bbf96 100644 --- a/src/widget/wcolorpicker.cpp +++ b/src/widget/wcolorpicker.cpp @@ -115,12 +115,7 @@ void WColorPicker::addColorButton(mixxx::RgbColor::optional_t color, QGridLayout void WColorPicker::resetSelectedColor() { // Unset currently selected color int i; - if (!m_selectedColor) { - if (m_colorOption != ColorOption::AllowNoColor) { - return; - } - i = 0; - } else { + if (m_selectedColor) { i = m_palette.indexOf(*m_selectedColor); if (i == -1) { return; @@ -128,6 +123,11 @@ void WColorPicker::resetSelectedColor() { if (m_colorOption == ColorOption::AllowNoColor) { i++; } + } else { + i = 0; + if (m_colorOption != ColorOption::AllowNoColor) { + return; + } } DEBUG_ASSERT(i < m_colorButtons.size()); @@ -148,12 +148,7 @@ void WColorPicker::setSelectedColor(mixxx::RgbColor::optional_t color) { m_selectedColor = color; int i; - if (!color) { - if (m_colorOption != ColorOption::AllowNoColor) { - return; - } - i = 0; - } else { + if (color) { i = m_palette.indexOf(*color); if (i == -1) { return; @@ -161,6 +156,11 @@ void WColorPicker::setSelectedColor(mixxx::RgbColor::optional_t color) { if (m_colorOption == ColorOption::AllowNoColor) { i++; } + } else { + i = 0; + if (m_colorOption != ColorOption::AllowNoColor) { + return; + } } DEBUG_ASSERT(i < m_colorButtons.size()); From 3f94fd676c29297e0a1c46f60b59d93d2def0f9e Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 3 Mar 2020 15:29:46 +0100 Subject: [PATCH 091/158] Add support for multiple named color palettes --- src/preferences/colorpalettesettings.cpp | 62 ++++++++++++++++----- src/preferences/colorpalettesettings.h | 10 ++-- src/preferences/configobject.cpp | 10 ++++ src/preferences/configobject.h | 1 + src/test/colorconfig_test.cpp | 69 +++++++++++++++++------- src/util/color/colorpalette.cpp | 22 ++++---- src/util/color/colorpalette.h | 17 ++++-- 7 files changed, 143 insertions(+), 48 deletions(-) diff --git a/src/preferences/colorpalettesettings.cpp b/src/preferences/colorpalettesettings.cpp index 4fa8f641f3c..d87cd5a070b 100644 --- a/src/preferences/colorpalettesettings.cpp +++ b/src/preferences/colorpalettesettings.cpp @@ -1,13 +1,18 @@ #include "preferences/colorpalettesettings.h" namespace { -const QString kHotcueColorPaletteGroup = QStringLiteral("[HotcueColorPalette]"); -const QString kTrackColorPaletteGroup = QStringLiteral("[TrackColorPalette]"); +const QString kColorPaletteConfigGroup = QStringLiteral("[Config]"); +const QString kColorPaletteGroup = QStringLiteral("[ColorPalette %1]"); +const QRegExp kColorPaletteGroupNameRegex("^\\[ColorPalette (.+)\\]$"); +const ConfigKey kHotcueColorPaletteConfigKey(kColorPaletteConfigGroup, QStringLiteral("HotcueColorPalette")); +const ConfigKey kTrackColorPaletteConfigKey(kColorPaletteConfigGroup, QStringLiteral("TrackColorPalette")); } // anonymous namespace ColorPalette ColorPaletteSettings::getColorPalette( - const QString& group, const ColorPalette& defaultPalette) const { + const QString& name, const ColorPalette& defaultPalette) const { QList colorList; + + const QString group = kColorPaletteGroup.arg(name); for (const ConfigKey& key : m_pConfig->getKeysWithGroup(group)) { mixxx::RgbColor color = mixxx::RgbColor(m_pConfig->getValue(key, mixxx::RgbColor(0))); colorList.append(color); @@ -18,12 +23,12 @@ ColorPalette ColorPaletteSettings::getColorPalette( return defaultPalette; } - return ColorPalette(colorList); + return ColorPalette(name, colorList); } -void ColorPaletteSettings::setColorPalette( - const QString& group, const ColorPalette& colorPalette) { - removePalette(group); +void ColorPaletteSettings::setColorPalette(const QString& name, const ColorPalette& colorPalette) { + removePalette(name); + const QString group = kColorPaletteGroup.arg(name); for (int index = 0; index < colorPalette.size(); ++index) { mixxx::RgbColor color = colorPalette.at(index); @@ -31,24 +36,57 @@ void ColorPaletteSettings::setColorPalette( } } -void ColorPaletteSettings::removePalette(const QString& group) { +void ColorPaletteSettings::removePalette(const QString& name) { + const QString group = kColorPaletteGroup.arg(name); for (const ConfigKey& key : m_pConfig->getKeysWithGroup(group)) { m_pConfig->remove(key); } } ColorPalette ColorPaletteSettings::getHotcueColorPalette() const { - return getColorPalette(kHotcueColorPaletteGroup, ColorPalette::mixxxHotcuePalette); + QString name = m_pConfig->getValueString(kHotcueColorPaletteConfigKey); + qWarning() << "name" << name; + if (name.isEmpty()) { + return ColorPalette::mixxxHotcuePalette; + } + return getColorPalette(name, ColorPalette::mixxxHotcuePalette); } void ColorPaletteSettings::setHotcueColorPalette(const ColorPalette& colorPalette) { - setColorPalette(kHotcueColorPaletteGroup, colorPalette); + QString name = colorPalette.getName(); + VERIFY_OR_DEBUG_ASSERT(!name.isEmpty()) { + qWarning() << "Palette name must not be empty!"; + return; + } + m_pConfig->setValue(kHotcueColorPaletteConfigKey, name); + setColorPalette(name, colorPalette); } ColorPalette ColorPaletteSettings::getTrackColorPalette() const { - return getColorPalette(kTrackColorPaletteGroup, ColorPalette::mixxxHotcuePalette); + QString name = m_pConfig->getValueString(kTrackColorPaletteConfigKey); + if (name.isEmpty()) { + return ColorPalette::mixxxHotcuePalette; + } + return getColorPalette(name, ColorPalette::mixxxHotcuePalette); } void ColorPaletteSettings::setTrackColorPalette(const ColorPalette& colorPalette) { - setColorPalette(kTrackColorPaletteGroup, colorPalette); + QString name = colorPalette.getName(); + VERIFY_OR_DEBUG_ASSERT(!name.isEmpty()) { + qWarning() << "Palette name must not be empty!"; + return; + } + m_pConfig->setValue(kTrackColorPaletteConfigKey, name); + setColorPalette(name, colorPalette); +} + +QSet ColorPaletteSettings::getColorPaletteNames() { + QSet names; + for (const QString& group : m_pConfig->getGroups()) { + int pos = kColorPaletteGroupNameRegex.indexIn(group); + if (pos > -1) { + names.insert(kColorPaletteGroupNameRegex.cap(1)); + } + } + return names; } diff --git a/src/preferences/colorpalettesettings.h b/src/preferences/colorpalettesettings.h index f2086557040..ae5a58ea188 100644 --- a/src/preferences/colorpalettesettings.h +++ b/src/preferences/colorpalettesettings.h @@ -15,12 +15,12 @@ class ColorPaletteSettings { ColorPalette getTrackColorPalette() const; void setTrackColorPalette(const ColorPalette& colorPalette); - private: - ColorPalette getColorPalette(const QString& group, const ColorPalette& defaultPalette) const; - void setColorPalette(const QString& group, const ColorPalette& colorPalette); - - void removePalette(const QString& group); + ColorPalette getColorPalette(const QString& name, const ColorPalette& defaultPalette) const; + void setColorPalette(const QString& name, const ColorPalette& colorPalette); + void removePalette(const QString& name); + QSet getColorPaletteNames(); + private: ConfigKey keyForIndex(const QString& group, int index) { return ConfigKey(group, QString::number(index)); } diff --git a/src/preferences/configobject.cpp b/src/preferences/configobject.cpp index e3814e1683d..dc973013fee 100644 --- a/src/preferences/configobject.cpp +++ b/src/preferences/configobject.cpp @@ -216,6 +216,16 @@ template void ConfigObject::save() { } } +template +QSet ConfigObject::getGroups() { + QWriteLocker lock(&m_valuesLock); + QSet groups; + for (const ConfigKey& key : m_values.uniqueKeys()) { + groups.insert(key.group); + } + return groups; +} + template QList ConfigObject::getKeysWithGroup(QString group) { QWriteLocker lock(&m_valuesLock); diff --git a/src/preferences/configobject.h b/src/preferences/configobject.h index 3791de6ecd7..a9ff720f0dd 100644 --- a/src/preferences/configobject.h +++ b/src/preferences/configobject.h @@ -187,6 +187,7 @@ template class ConfigObject { return m_settingsPath; } + QSet getGroups(); QList getKeysWithGroup(QString group); protected: diff --git a/src/test/colorconfig_test.cpp b/src/test/colorconfig_test.cpp index 560c0f7b2ef..330cc8451e6 100644 --- a/src/test/colorconfig_test.cpp +++ b/src/test/colorconfig_test.cpp @@ -25,13 +25,13 @@ TEST_F(ColorConfigTest, GetDefaultColorWhenNoStoredColor) { TEST_F(ColorConfigTest, SaveColorPalette) { ColorPaletteSettings colorPaletteSettings(config()); - ColorPalette originalColorPalette(QList{ - mixxx::RgbColor(0x66FF99), - mixxx::RgbColor(0xFF9900), - mixxx::RgbColor(0x000000), - mixxx::RgbColor(0xFFFFFF), - }); - ConfigKey key("[ColorPalette]", "colorPalette"); + ColorPalette originalColorPalette( + "SaveColorPaletteTest", QList{ + mixxx::RgbColor(0x66FF99), + mixxx::RgbColor(0xFF9900), + mixxx::RgbColor(0x000000), + mixxx::RgbColor(0xFFFFFF), + }); colorPaletteSettings.setHotcueColorPalette(originalColorPalette); saveAndReloadConfig(); ColorPalette colorPaletteFromConfig = @@ -41,17 +41,18 @@ TEST_F(ColorConfigTest, SaveColorPalette) { TEST_F(ColorConfigTest, ReplaceColorPalette) { ColorPaletteSettings colorPaletteSettings(config()); - ColorPalette colorPalette1(QList{ - mixxx::RgbColor(0x66FF99), - mixxx::RgbColor(0xFF9900), - mixxx::RgbColor(0x000000), - mixxx::RgbColor(0xFFFFFF), - }); - ColorPalette colorPalette2(QList{ - mixxx::RgbColor(0x0000FF), - mixxx::RgbColor(0xFF0000), - }); - ConfigKey key("[ColorPalette]", "colorPalette"); + ColorPalette colorPalette1( + "ReplaceColorPaletteTest", QList{ + mixxx::RgbColor(0x66FF99), + mixxx::RgbColor(0xFF9900), + mixxx::RgbColor(0x000000), + mixxx::RgbColor(0xFFFFFF), + }); + ColorPalette colorPalette2( + "ReplaceColorPaletteTest", QList{ + mixxx::RgbColor(0x0000FF), + mixxx::RgbColor(0xFF0000), + }); colorPaletteSettings.setHotcueColorPalette(colorPalette1); saveAndReloadConfig(); colorPaletteSettings.setHotcueColorPalette(colorPalette2); @@ -61,6 +62,38 @@ TEST_F(ColorConfigTest, ReplaceColorPalette) { ASSERT_EQ(colorPalette2, colorPaletteFromConfig); } +TEST_F(ColorConfigTest, LoadSavePalettes) { + ColorPaletteSettings colorPaletteSettings(config()); + ColorPalette colorPalette1( + "Custom Palette No. 1", QList{ + mixxx::RgbColor(0x66FF99), + mixxx::RgbColor(0xFF9900), + mixxx::RgbColor(0x000000), + mixxx::RgbColor(0xFFFFFF), + }); + colorPaletteSettings.setColorPalette(colorPalette1.getName(), colorPalette1); + ColorPalette colorPalette2( + "My Custom Palette 2", QList{ + mixxx::RgbColor(0x0000FF), + mixxx::RgbColor(0xFF0000), + }); + colorPaletteSettings.setColorPalette(colorPalette2.getName(), colorPalette2); + ColorPalette colorPalette3( + "I'm blue, da ba dee", QList{ + mixxx::RgbColor(0x0000FF), + mixxx::RgbColor(0x123456), + mixxx::RgbColor(0x000080), + }); + colorPaletteSettings.setColorPalette(colorPalette3.getName(), colorPalette3); + saveAndReloadConfig(); + QSet expectedNames{ + colorPalette1.getName(), + colorPalette2.getName(), + colorPalette3.getName(), + }; + ASSERT_EQ(expectedNames, colorPaletteSettings.getColorPaletteNames()); +} + TEST_F(ColorConfigTest, DefaultColorPalette) { ColorPaletteSettings colorPaletteSettings(config()); ColorPalette colorPaletteFromConfig = diff --git a/src/util/color/colorpalette.cpp b/src/util/color/colorpalette.cpp index dd55e4e5b60..78bcb44f0b0 100644 --- a/src/util/color/colorpalette.cpp +++ b/src/util/color/colorpalette.cpp @@ -12,16 +12,18 @@ constexpr mixxx::RgbColor kColorMixxxWhite = mixxx::RgbColor(0xF2F2FF); } // anonymous namespace const ColorPalette ColorPalette::mixxxHotcuePalette = - ColorPalette(QList{ - kColorMixxxRed, - kColorMixxxYellow, - kColorMixxxGreen, - kColorMixxxCeleste, - kColorMixxxBlue, - kColorMixxxPurple, - kColorMixxxPink, - kColorMixxxWhite, - }); + ColorPalette( + QStringLiteral("Mixxx Hotcue Colors"), + QList{ + kColorMixxxRed, + kColorMixxxYellow, + kColorMixxxGreen, + kColorMixxxCeleste, + kColorMixxxBlue, + kColorMixxxPurple, + kColorMixxxPink, + kColorMixxxWhite, + }); mixxx::RgbColor ColorPalette::nextColor(mixxx::RgbColor color) const { // Return first color if color not in palette ((-1 + 1) % size) diff --git a/src/util/color/colorpalette.h b/src/util/color/colorpalette.h index 8f92b436fa2..6a2714d4cf5 100644 --- a/src/util/color/colorpalette.h +++ b/src/util/color/colorpalette.h @@ -6,8 +6,9 @@ class ColorPalette { public: - explicit ColorPalette(QList colorList) - : m_colorList(colorList) { + explicit ColorPalette(QString name, QList colorList) + : m_name(name), + m_colorList(colorList) { DEBUG_ASSERT(m_colorList.size() != 0); } @@ -34,6 +35,14 @@ class ColorPalette { return m_colorList.end(); } + QString getName() const { + return m_name; + } + + void setName(const QString name) { + m_name = name; + } + static const ColorPalette mixxxHotcuePalette; const QList& getColorList() const { @@ -41,10 +50,12 @@ class ColorPalette { } private: + QString m_name; QList m_colorList; }; inline bool operator==( const ColorPalette& lhs, const ColorPalette& rhs) { - return lhs.getColorList() == rhs.getColorList(); + return lhs.getName() == rhs.getName() && + lhs.getColorList() == rhs.getColorList(); } From 5b4c695789ec81f89b8f2d2f65c339148a1906dd Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 3 Mar 2020 18:30:21 +0100 Subject: [PATCH 092/158] widget/wcolorpicker: Add support for switching palettes with different sizes --- src/widget/wcolorpicker.cpp | 51 +++++++++++++++++++++++-------------- src/widget/wcolorpicker.h | 4 ++- src/widget/wcuemenupopup.h | 4 +-- src/widget/woverview.cpp | 2 +- 4 files changed, 38 insertions(+), 23 deletions(-) diff --git a/src/widget/wcolorpicker.cpp b/src/widget/wcolorpicker.cpp index 542133bbf96..b02a6ff7692 100644 --- a/src/widget/wcolorpicker.cpp +++ b/src/widget/wcolorpicker.cpp @@ -54,6 +54,30 @@ WColorPicker::WColorPicker(ColorOption colorOption, const ColorPalette& palette, // better than having buttons without any colors (which would make the // color picker unusable). m_pStyle = QStyleFactory::create(QString("fusion")); + setLayout(pLayout); + addColorButtons(); +} + +void WColorPicker::removeColorButtons() { + QGridLayout* pLayout = static_cast(layout()); + VERIFY_OR_DEBUG_ASSERT(pLayout) { + qWarning() << "Color Picker has no layout!"; + return; + } + + while (!m_colorButtons.isEmpty()) { + QPushButton* pColorButton = m_colorButtons.takeLast(); + pLayout->removeWidget(pColorButton); + delete pColorButton; + } +} + +void WColorPicker::addColorButtons() { + QGridLayout* pLayout = static_cast(layout()); + VERIFY_OR_DEBUG_ASSERT(pLayout) { + qWarning() << "Color Picker has no layout!"; + return; + } int row = 0; int column = 0; @@ -80,7 +104,6 @@ WColorPicker::WColorPicker(ColorOption colorOption, const ColorPalette& palette, } void WColorPicker::addColorButton(mixxx::RgbColor::optional_t color, QGridLayout* pLayout, int row, int column) { - setLayout(pLayout); parented_ptr pColorButton = make_parented("", this); if (m_pStyle) { pColorButton->setStyle(m_pStyle); @@ -175,25 +198,15 @@ void WColorPicker::setSelectedColor(mixxx::RgbColor::optional_t color) { pButton->style()->polish(pButton); } -void WColorPicker::useColorSet(const ColorPalette& palette) { - resetSelectedColor(); - - for (int i = 0; i < m_colorButtons.size(); ++i) { - int j = i; - if (m_colorOption == ColorOption::AllowNoColor) { - j++; - } - - if (i >= palette.size() || j >= m_colorButtons.size()) { - return; - } - - // Set the background color of the button. This can't be overridden in skin stylesheets. - m_colorButtons.at(j)->setStyleSheet( - QString("QPushButton { background-color: %1; }") - .arg(mixxx::RgbColor::toQString(palette.at(i)))); - m_colorButtons.at(j)->setToolTip(mixxx::RgbColor::toQString(palette.at(i), tr("No Color"))); +void WColorPicker::setColorPalette(const ColorPalette& palette) { + if (m_palette == palette) { + return; } + + resetSelectedColor(); + removeColorButtons(); + m_palette = palette; + addColorButtons(); } void WColorPicker::slotColorPicked(mixxx::RgbColor::optional_t color) { diff --git a/src/widget/wcolorpicker.h b/src/widget/wcolorpicker.h index 8c744c13851..d905e612462 100644 --- a/src/widget/wcolorpicker.h +++ b/src/widget/wcolorpicker.h @@ -21,7 +21,7 @@ class WColorPicker : public QWidget { void resetSelectedColor(); void setSelectedColor(mixxx::RgbColor::optional_t color); - void useColorSet(const ColorPalette& palette); + void setColorPalette(const ColorPalette& palette); signals: void colorPicked(mixxx::RgbColor::optional_t color); @@ -30,6 +30,8 @@ class WColorPicker : public QWidget { void slotColorPicked(mixxx::RgbColor::optional_t color); private: + void addColorButtons(); + void removeColorButtons(); void addColorButton(mixxx::RgbColor::optional_t color, QGridLayout* pLayout, int row, int column); ColorOption m_colorOption; mixxx::RgbColor::optional_t m_selectedColor; diff --git a/src/widget/wcuemenupopup.h b/src/widget/wcuemenupopup.h index 3c8094e8be5..2cdf8307b8f 100644 --- a/src/widget/wcuemenupopup.h +++ b/src/widget/wcuemenupopup.h @@ -23,9 +23,9 @@ class WCueMenuPopup : public QWidget { void setTrackAndCue(TrackPointer pTrack, CuePointer pCue); - void useColorSet(const ColorPalette& palette) { + void setColorPalette(const ColorPalette& palette) { if (m_pColorPicker != nullptr) { - m_pColorPicker->useColorSet(palette); + m_pColorPicker->setColorPalette(palette); } } diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index fe6c3eb52d8..4fb65c6fbfe 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -134,7 +134,7 @@ void WOverview::setup(const QDomNode& node, const SkinContext& context) { ColorPaletteSettings colorPaletteSettings(m_pConfig); auto colorPalette = colorPaletteSettings.getHotcueColorPalette(); - m_pCueMenuPopup->useColorSet(colorPalette); + m_pCueMenuPopup->setColorPalette(colorPalette); for (const auto& pMark: m_marks) { if (pMark->isValid()) { From 4bc091e8ae56bd8678a43ea76b4f1f38927ab72a Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 3 Mar 2020 18:31:20 +0100 Subject: [PATCH 093/158] wcolorpickeraction: Use current track color palette when opening menu --- src/widget/wcolorpickeraction.cpp | 4 ++++ src/widget/wcolorpickeraction.h | 1 + src/widget/wtracktableview.cpp | 3 +++ 3 files changed, 8 insertions(+) diff --git a/src/widget/wcolorpickeraction.cpp b/src/widget/wcolorpickeraction.cpp index b57f1e4b78d..8837695ac61 100644 --- a/src/widget/wcolorpickeraction.cpp +++ b/src/widget/wcolorpickeraction.cpp @@ -20,3 +20,7 @@ void WColorPickerAction::resetSelectedColor() { void WColorPickerAction::setSelectedColor(mixxx::RgbColor::optional_t color) { m_pColorPicker->setSelectedColor(color); } + +void WColorPickerAction::setColorPalette(const ColorPalette& palette) { + m_pColorPicker->setColorPalette(palette); +} diff --git a/src/widget/wcolorpickeraction.h b/src/widget/wcolorpickeraction.h index e7ca0095b4b..ce222ff49cc 100644 --- a/src/widget/wcolorpickeraction.h +++ b/src/widget/wcolorpickeraction.h @@ -17,6 +17,7 @@ class WColorPickerAction : public QWidgetAction { void resetSelectedColor(); void setSelectedColor(mixxx::RgbColor::optional_t color); + void setColorPalette(const ColorPalette& palette); signals: void colorPicked(mixxx::RgbColor::optional_t color); diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index a22b51cbc6b..a3e8c9a9be0 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -1089,6 +1089,9 @@ void WTrackTableView::contextMenuEvent(QContextMenuEvent* event) { // Track color menu only appears if at least one track is selected if (indices.size()) { + m_pColorPickerAction->setColorPalette( + ColorPaletteSettings(m_pConfig).getTrackColorPalette()); + // Get color of first selected track int column = trackModel->fieldIndex(LIBRARYTABLE_COLOR); QModelIndex index = indices.at(0).sibling(indices.at(0).row(), column); From dcec320a0e5e040ae3af80175b497430004285c0 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 3 Mar 2020 18:47:40 +0100 Subject: [PATCH 094/158] widget/wcuemenupopup: Use current hotcue color palette when menu is shown --- src/widget/wcuemenupopup.cpp | 7 +++---- src/widget/wcuemenupopup.h | 3 +++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/widget/wcuemenupopup.cpp b/src/widget/wcuemenupopup.cpp index 0ab8f54ac4b..3c2817c4ab3 100644 --- a/src/widget/wcuemenupopup.cpp +++ b/src/widget/wcuemenupopup.cpp @@ -5,11 +5,11 @@ #include #include "engine/engine.h" -#include "preferences/colorpalettesettings.h" #include "util/color/color.h" WCueMenuPopup::WCueMenuPopup(UserSettingsPointer pConfig, QWidget* parent) - : QWidget(parent) { + : QWidget(parent), + m_colorPaletteSettings(ColorPaletteSettings(pConfig)) { QWidget::hide(); setWindowFlags(Qt::Popup); setAttribute(Qt::WA_StyledBackground); @@ -31,8 +31,7 @@ WCueMenuPopup::WCueMenuPopup(UserSettingsPointer pConfig, QWidget* parent) connect(m_pEditLabel, &QLineEdit::textEdited, this, &WCueMenuPopup::slotEditLabel); connect(m_pEditLabel, &QLineEdit::returnPressed, this, &WCueMenuPopup::hide); - ColorPaletteSettings colorPaletteSettings(pConfig); - m_pColorPicker = new WColorPicker(WColorPicker::ColorOption::DenyNoColor, colorPaletteSettings.getHotcueColorPalette(), this); + m_pColorPicker = new WColorPicker(WColorPicker::ColorOption::DenyNoColor, m_colorPaletteSettings.getHotcueColorPalette(), this); m_pColorPicker->setObjectName("CueColorPicker"); connect(m_pColorPicker, &WColorPicker::colorPicked, this, &WCueMenuPopup::slotChangeCueColor); diff --git a/src/widget/wcuemenupopup.h b/src/widget/wcuemenupopup.h index 2cdf8307b8f..7e1743590d0 100644 --- a/src/widget/wcuemenupopup.h +++ b/src/widget/wcuemenupopup.h @@ -4,6 +4,7 @@ #include #include +#include "preferences/colorpalettesettings.h" #include "track/cue.h" #include "track/track.h" #include "widget/wcolorpicker.h" @@ -42,6 +43,7 @@ class WCueMenuPopup : public QWidget { } void show() { + setColorPalette(m_colorPaletteSettings.getHotcueColorPalette()); m_pEditLabel->setFocus(); emit aboutToShow(); QWidget::show(); @@ -57,6 +59,7 @@ class WCueMenuPopup : public QWidget { void slotChangeCueColor(mixxx::RgbColor::optional_t color); private: + ColorPaletteSettings m_colorPaletteSettings; CuePointer m_pCue; TrackPointer m_pTrack; From 80eb2ba94a7e8e436c8e4f8b5e9d9d98279bb64d Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 4 Mar 2020 11:34:17 +0100 Subject: [PATCH 095/158] res/schema.xml: Fix comment of hotcue color migration (s/RGBA/RGB/) --- res/schema.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/schema.xml b/res/schema.xml index 648be453ac9..365ae196df5 100644 --- a/res/schema.xml +++ b/res/schema.xml @@ -491,7 +491,7 @@ METADATA - Convert the PredefinedColor ID to the actual RGBA value. + Convert the PredefinedColor ID to the actual RGB value. From 9b68234b83e21da8b319aa290b053fa891583855 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 4 Mar 2020 11:35:21 +0100 Subject: [PATCH 096/158] controllers/colormapper: Do not inherit from QObject --- src/controllers/colormapper.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/controllers/colormapper.h b/src/controllers/colormapper.h index f30b5a8ae80..d78c5e4fe7c 100644 --- a/src/controllers/colormapper.h +++ b/src/controllers/colormapper.h @@ -8,8 +8,7 @@ #include "util/assert.h" -class ColorMapper final : public QObject { - Q_OBJECT +class ColorMapper final { public: ColorMapper() = delete; ColorMapper(const QMap availableColors) From df02deccc93e5df69c0e015ca0db6fc37bc482bf Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 4 Mar 2020 11:36:21 +0100 Subject: [PATCH 097/158] engine/controls/cuecontrol: Remove superfluous comment --- src/engine/controls/cuecontrol.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index a8107850330..0265bddbb1f 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -335,7 +335,6 @@ void CueControl::detachCue(HotcueControl* pControl) { } disconnect(pCue.get(), 0, this, 0); pControl->resetCue(); - // Reset the color CO to -1 pControl->setColor(std::nullopt); } From c4be50033ce2b1cb5d6c283349dada410cee86c0 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 4 Mar 2020 11:36:43 +0100 Subject: [PATCH 098/158] preferences/colorpalettesettings: Use constant for fallback color --- src/preferences/colorpalettesettings.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/preferences/colorpalettesettings.cpp b/src/preferences/colorpalettesettings.cpp index d87cd5a070b..04d84390109 100644 --- a/src/preferences/colorpalettesettings.cpp +++ b/src/preferences/colorpalettesettings.cpp @@ -1,6 +1,7 @@ #include "preferences/colorpalettesettings.h" namespace { +const mixxx::RgbColor kColorBlack(0x000000); const QString kColorPaletteConfigGroup = QStringLiteral("[Config]"); const QString kColorPaletteGroup = QStringLiteral("[ColorPalette %1]"); const QRegExp kColorPaletteGroupNameRegex("^\\[ColorPalette (.+)\\]$"); @@ -14,7 +15,7 @@ ColorPalette ColorPaletteSettings::getColorPalette( const QString group = kColorPaletteGroup.arg(name); for (const ConfigKey& key : m_pConfig->getKeysWithGroup(group)) { - mixxx::RgbColor color = mixxx::RgbColor(m_pConfig->getValue(key, mixxx::RgbColor(0))); + mixxx::RgbColor color = mixxx::RgbColor(m_pConfig->getValue(key, kColorBlack)); colorList.append(color); } From 448d1b7199d35582414e75177d01d4305206d9c7 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 4 Mar 2020 11:37:12 +0100 Subject: [PATCH 099/158] preferences/configobject: Remove key if color value is not set --- src/preferences/configobject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/preferences/configobject.cpp b/src/preferences/configobject.cpp index dc973013fee..9a05c012548 100644 --- a/src/preferences/configobject.cpp +++ b/src/preferences/configobject.cpp @@ -298,7 +298,7 @@ template<> void ConfigObject::setValue( const ConfigKey& key, const mixxx::RgbColor::optional_t& value) { if (!value) { - set(key, ConfigValue("")); + remove(key); return; } set(key, ConfigValue(mixxx::RgbColor::toQString(value))); From f1ac5def5d047205b6dfcc526ffa4b776e4a787e Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 4 Mar 2020 11:37:53 +0100 Subject: [PATCH 100/158] util/color/colorpalette: Make class final --- src/util/color/colorpalette.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/color/colorpalette.h b/src/util/color/colorpalette.h index 6a2714d4cf5..f8b47552c1b 100644 --- a/src/util/color/colorpalette.h +++ b/src/util/color/colorpalette.h @@ -4,7 +4,7 @@ #include "util/color/rgbcolor.h" -class ColorPalette { +class ColorPalette final { public: explicit ColorPalette(QString name, QList colorList) : m_name(name), From 8b222ff4ee5046ec5c223a75b1acd42f079054d9 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 4 Mar 2020 11:38:09 +0100 Subject: [PATCH 101/158] widget/wcolorpicker: Swap order of captured lambda variables --- src/widget/wcolorpicker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widget/wcolorpicker.cpp b/src/widget/wcolorpicker.cpp index b02a6ff7692..803142f2f77 100644 --- a/src/widget/wcolorpicker.cpp +++ b/src/widget/wcolorpicker.cpp @@ -130,7 +130,7 @@ void WColorPicker::addColorButton(mixxx::RgbColor::optional_t color, QGridLayout connect(pColorButton, &QPushButton::clicked, this, - [color, this]() { + [this, color]() { emit colorPicked(color); }); } From c52f8b32142204712872ce69dbb3092a125660a4 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 4 Mar 2020 11:51:19 +0100 Subject: [PATCH 102/158] track/cue: Reuse default cue color constant from ColorPalette --- src/track/cue.cpp | 6 +++--- src/util/color/colorpalette.cpp | 2 ++ src/util/color/colorpalette.h | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/track/cue.cpp b/src/track/cue.cpp index f39f84ceb67..8831d68596a 100644 --- a/src/track/cue.cpp +++ b/src/track/cue.cpp @@ -9,10 +9,10 @@ #include "engine/engine.h" #include "util/assert.h" #include "util/color/color.h" +#include "util/color/colorpalette.h" namespace { const QString kDefaultLabel = ""; // empty string, not null - const mixxx::RgbColor kDefaultCueColor = mixxx::RgbColor(0xF2F2FF); // white } //static @@ -31,7 +31,7 @@ Cue::Cue(TrackId trackId) m_sampleEndPosition(Cue::kNoPosition), m_iHotCue(-1), m_label(kDefaultLabel), - m_color(kDefaultCueColor) { + m_color(ColorPalette::kDefaultCueColor) { DEBUG_ASSERT(!m_label.isNull()); } @@ -72,7 +72,7 @@ Cue::Cue(TrackId trackId, mixxx::AudioSignal::SampleRate sampleRate, const mixxx m_sampleEndPosition(Cue::kNoPosition), m_iHotCue(Cue::kNoHotCue), m_label(cueInfo.getLabel()), - m_color(cueInfo.getColor().value_or(kDefaultCueColor)) { + m_color(cueInfo.getColor().value_or(ColorPalette::kDefaultCueColor)) { DEBUG_ASSERT(!m_label.isNull()); DEBUG_ASSERT(sampleRate.valid()); diff --git a/src/util/color/colorpalette.cpp b/src/util/color/colorpalette.cpp index 78bcb44f0b0..4bdfc0bf00e 100644 --- a/src/util/color/colorpalette.cpp +++ b/src/util/color/colorpalette.cpp @@ -25,6 +25,8 @@ const ColorPalette ColorPalette::mixxxHotcuePalette = kColorMixxxWhite, }); +const mixxx::RgbColor ColorPalette::kDefaultCueColor = kColorMixxxWhite; + 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()); diff --git a/src/util/color/colorpalette.h b/src/util/color/colorpalette.h index f8b47552c1b..b673e8baa2d 100644 --- a/src/util/color/colorpalette.h +++ b/src/util/color/colorpalette.h @@ -44,6 +44,7 @@ class ColorPalette final { } static const ColorPalette mixxxHotcuePalette; + static const mixxx::RgbColor kDefaultCueColor; const QList& getColorList() const { return m_colorList; From 9e0c651ecc5f85735cb6fbd3e16408f301bf9e1b Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Fri, 6 Mar 2020 13:58:44 +0100 Subject: [PATCH 103/158] res/schema.xml: Remove useless alpha channel --- res/schema.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/res/schema.xml b/res/schema.xml index 365ae196df5..f49cb964f72 100644 --- a/res/schema.xml +++ b/res/schema.xml @@ -495,23 +495,23 @@ METADATA - UPDATE cues SET color=0xFFF2F2FF WHERE color=0; + UPDATE cues SET color=0xF2F2FF WHERE color=0; - UPDATE cues SET color=0xFFC50A08 WHERE color=1; + UPDATE cues SET color=0xC50A08 WHERE color=1; - UPDATE cues SET color=0xFF32BE44 WHERE color=2; + UPDATE cues SET color=0x32BE44 WHERE color=2; - UPDATE cues SET color=0xFF0044FF WHERE color=3; + UPDATE cues SET color=0x0044FF WHERE color=3; - UPDATE cues SET color=0xFFF8D200 WHERE color=4; + UPDATE cues SET color=0xF8D200 WHERE color=4; - UPDATE cues SET color=0xFF42D4F4 WHERE color=5; + UPDATE cues SET color=0x42D4F4 WHERE color=5; - UPDATE cues SET color=0xFFAF00CC WHERE color=6; + UPDATE cues SET color=0xAF00CC WHERE color=6; - UPDATE cues SET color=0xFFFCA6D7 WHERE color=7; + UPDATE cues SET color=0xFCA6D7 WHERE color=7; - UPDATE cues SET color=0xFFF2F2FF WHERE color=8; + UPDATE cues SET color=0xF2F2FF WHERE color=8; From abea66910e8d296e247ba5c03170b01743359483 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Fri, 6 Mar 2020 14:09:38 +0100 Subject: [PATCH 104/158] util/color/colorpalette: Use shorter initialization for color constexprs --- src/util/color/colorpalette.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/util/color/colorpalette.cpp b/src/util/color/colorpalette.cpp index 4bdfc0bf00e..91cfed80dd4 100644 --- a/src/util/color/colorpalette.cpp +++ b/src/util/color/colorpalette.cpp @@ -1,14 +1,14 @@ #include "colorpalette.h" namespace { -constexpr mixxx::RgbColor kColorMixxxRed = mixxx::RgbColor(0xC50A08); -constexpr mixxx::RgbColor kColorMixxxYellow = mixxx::RgbColor(0x32BE44); -constexpr mixxx::RgbColor kColorMixxxGreen = mixxx::RgbColor(0x0044FF); -constexpr mixxx::RgbColor kColorMixxxCeleste = mixxx::RgbColor(0xF8D200); -constexpr mixxx::RgbColor kColorMixxxBlue = mixxx::RgbColor(0x42D4F4); -constexpr mixxx::RgbColor kColorMixxxPurple = mixxx::RgbColor(0xAF00CC); -constexpr mixxx::RgbColor kColorMixxxPink = mixxx::RgbColor(0xFCA6D7); -constexpr mixxx::RgbColor kColorMixxxWhite = mixxx::RgbColor(0xF2F2FF); +constexpr mixxx::RgbColor kColorMixxxRed(0xC50A08); +constexpr mixxx::RgbColor kColorMixxxYellow(0x32BE44); +constexpr mixxx::RgbColor kColorMixxxGreen(0x0044FF); +constexpr mixxx::RgbColor kColorMixxxCeleste(0xF8D200); +constexpr mixxx::RgbColor kColorMixxxBlue(0x42D4F4); +constexpr mixxx::RgbColor kColorMixxxPurple(0xAF00CC); +constexpr mixxx::RgbColor kColorMixxxPink(0xFCA6D7); +constexpr mixxx::RgbColor kColorMixxxWhite(0xF2F2FF); } // anonymous namespace const ColorPalette ColorPalette::mixxxHotcuePalette = From 67af3025a6db3c2841e2ccdd8c8afe877a1b053a Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Fri, 6 Mar 2020 13:38:53 +0100 Subject: [PATCH 105/158] preferences/colorpalettesettings: Fix order of palettes with >=10 colors --- src/preferences/colorpalettesettings.cpp | 16 +++++++++++++++- src/preferences/colorpalettesettings.h | 5 +---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/preferences/colorpalettesettings.cpp b/src/preferences/colorpalettesettings.cpp index 04d84390109..205b3661a5d 100644 --- a/src/preferences/colorpalettesettings.cpp +++ b/src/preferences/colorpalettesettings.cpp @@ -7,6 +7,15 @@ const QString kColorPaletteGroup = QStringLiteral("[ColorPalette %1]"); const QRegExp kColorPaletteGroupNameRegex("^\\[ColorPalette (.+)\\]$"); const ConfigKey kHotcueColorPaletteConfigKey(kColorPaletteConfigGroup, QStringLiteral("HotcueColorPalette")); const ConfigKey kTrackColorPaletteConfigKey(kColorPaletteConfigGroup, QStringLiteral("TrackColorPalette")); + +int numberOfDecimalDigits(int number) { + int numDigits = 1; + while (number /= 10) { + numDigits++; + } + return numDigits; +} + } // anonymous namespace ColorPalette ColorPaletteSettings::getColorPalette( @@ -31,9 +40,10 @@ void ColorPaletteSettings::setColorPalette(const QString& name, const ColorPalet removePalette(name); const QString group = kColorPaletteGroup.arg(name); + int maxDigits = numberOfDecimalDigits(colorPalette.size() - 1); for (int index = 0; index < colorPalette.size(); ++index) { mixxx::RgbColor color = colorPalette.at(index); - m_pConfig->setValue(keyForIndex(group, index), color); + m_pConfig->setValue(keyForIndex(group, index, maxDigits), color); } } @@ -91,3 +101,7 @@ QSet ColorPaletteSettings::getColorPaletteNames() { } return names; } + +ConfigKey ColorPaletteSettings::keyForIndex(const QString& group, int index, int maxDigits) { + return ConfigKey(group, QString::number(index).rightJustified(maxDigits, '0')); +} diff --git a/src/preferences/colorpalettesettings.h b/src/preferences/colorpalettesettings.h index ae5a58ea188..12889661dca 100644 --- a/src/preferences/colorpalettesettings.h +++ b/src/preferences/colorpalettesettings.h @@ -21,9 +21,6 @@ class ColorPaletteSettings { QSet getColorPaletteNames(); private: - ConfigKey keyForIndex(const QString& group, int index) { - return ConfigKey(group, QString::number(index)); - } - + ConfigKey keyForIndex(const QString& group, int index, int maxDigits); UserSettingsPointer m_pConfig; }; From ef8e535cf856ff5b41581f97c71048219ccc01fc Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 5 Mar 2020 21:40:38 +0100 Subject: [PATCH 106/158] util/color/colorpalette: Add colorForHotcueIndex method --- src/engine/controls/cuecontrol.cpp | 11 +++++------ src/util/color/colorpalette.cpp | 5 +++++ src/util/color/colorpalette.h | 1 + 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index 0265bddbb1f..bef85ac31ba 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -617,14 +617,13 @@ void CueControl::hotcueSet(HotcueControl* pControl, double v) { pCue->setLabel(""); pCue->setType(mixxx::CueType::HotCue); - auto hotcueColorPalette = m_colorPaletteSettings.getHotcueColorPalette(); ConfigKey autoHotcueColorsKey("[Controls]", "auto_hotcue_colors"); - int iColorIndex = 0; if (getConfig()->getValue(autoHotcueColorsKey, false)) { - // For hotcue n, get nth color from palette - iColorIndex = (hotcue % hotcueColorPalette.size()); - }; - pCue->setColor(hotcueColorPalette.at(iColorIndex)); + auto hotcueColorPalette = m_colorPaletteSettings.getHotcueColorPalette(); + pCue->setColor(hotcueColorPalette.colorForHotcueIndex(hotcue)); + } else { + pCue->setColor(hotcueColorPalette.at(0)); + } // TODO(XXX) deal with spurious signals attachCue(pCue, pControl); diff --git a/src/util/color/colorpalette.cpp b/src/util/color/colorpalette.cpp index 91cfed80dd4..1623d5be47d 100644 --- a/src/util/color/colorpalette.cpp +++ b/src/util/color/colorpalette.cpp @@ -42,3 +42,8 @@ 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()); +} diff --git a/src/util/color/colorpalette.h b/src/util/color/colorpalette.h index b673e8baa2d..1f0165a8b39 100644 --- a/src/util/color/colorpalette.h +++ b/src/util/color/colorpalette.h @@ -26,6 +26,7 @@ class ColorPalette final { mixxx::RgbColor nextColor(mixxx::RgbColor color) const; mixxx::RgbColor previousColor(mixxx::RgbColor color) const; + mixxx::RgbColor colorForHotcueIndex(unsigned int index) const; QList::const_iterator begin() const { return m_colorList.begin(); From fbcea0b91727c6c182020041c66c2a27edaf5ac0 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Fri, 6 Mar 2020 13:52:08 +0100 Subject: [PATCH 107/158] engine/controls/cuecontrol: Use default color if auto_hotcue_colors is off --- src/engine/controls/cuecontrol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index bef85ac31ba..7ceede1af38 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -622,7 +622,7 @@ void CueControl::hotcueSet(HotcueControl* pControl, double v) { auto hotcueColorPalette = m_colorPaletteSettings.getHotcueColorPalette(); pCue->setColor(hotcueColorPalette.colorForHotcueIndex(hotcue)); } else { - pCue->setColor(hotcueColorPalette.at(0)); + pCue->setColor(ColorPalette::kDefaultCueColor); } // TODO(XXX) deal with spurious signals From 5cda96df3d793d53aa9f47a349390dbcae54d0e5 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Fri, 6 Mar 2020 13:59:06 +0100 Subject: [PATCH 108/158] Use orange (not in palette) for "no color" schema migration and new cues --- res/schema.xml | 4 ++-- src/util/color/colorpalette.cpp | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/res/schema.xml b/res/schema.xml index f49cb964f72..54ecf75e5db 100644 --- a/res/schema.xml +++ b/res/schema.xml @@ -494,8 +494,8 @@ METADATA Convert the PredefinedColor ID to the actual RGB value. - - UPDATE cues SET color=0xF2F2FF WHERE color=0; + + UPDATE cues SET color=0xFF8000 WHERE color=0; UPDATE cues SET color=0xC50A08 WHERE color=1; diff --git a/src/util/color/colorpalette.cpp b/src/util/color/colorpalette.cpp index 1623d5be47d..846feabdb85 100644 --- a/src/util/color/colorpalette.cpp +++ b/src/util/color/colorpalette.cpp @@ -1,6 +1,7 @@ #include "colorpalette.h" namespace { + constexpr mixxx::RgbColor kColorMixxxRed(0xC50A08); constexpr mixxx::RgbColor kColorMixxxYellow(0x32BE44); constexpr mixxx::RgbColor kColorMixxxGreen(0x0044FF); @@ -9,6 +10,11 @@ constexpr mixxx::RgbColor kColorMixxxBlue(0x42D4F4); 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(0xFF8000); + } // anonymous namespace const ColorPalette ColorPalette::mixxxHotcuePalette = @@ -25,7 +31,7 @@ const ColorPalette ColorPalette::mixxxHotcuePalette = kColorMixxxWhite, }); -const mixxx::RgbColor ColorPalette::kDefaultCueColor = 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) From e719af5488e21c69ad21eef3458c5b27edc35e5e Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Fri, 6 Mar 2020 23:14:01 +0100 Subject: [PATCH 109/158] Roland DJ-505: Remove unnecessary alpha channel from ColorMapper --- res/controllers/Roland_DJ-505-scripts.js | 32 ++++++++++++------------ 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/res/controllers/Roland_DJ-505-scripts.js b/res/controllers/Roland_DJ-505-scripts.js index fa9e126fd15..ceee4d06b3b 100644 --- a/res/controllers/Roland_DJ-505-scripts.js +++ b/res/controllers/Roland_DJ-505-scripts.js @@ -971,22 +971,22 @@ DJ505.PadColor = { }; DJ505.PadColorMap = new ColorMapper({ - "#FFCC0000": DJ505.PadColor.RED, - "#FFCC4400": DJ505.PadColor.CORAL, - "#FFCC8800": DJ505.PadColor.ORANGE, - "#FFCCCC00": DJ505.PadColor.YELLOW, - "#FF88CC00": DJ505.PadColor.GREEN, - "#FF00CC00": DJ505.PadColor.APPLEGREEN, - "#FF00CC88": DJ505.PadColor.AQUAMARINE, - "#FF00CCCC": DJ505.PadColor.TURQUOISE, - "#FF0088CC": DJ505.PadColor.CELESTE, - "#FF0000CC": DJ505.PadColor.BLUE, - "#FF4400CC": DJ505.PadColor.AZURE, - "#FF8800CC": DJ505.PadColor.PURPLE, - "#FFCC00CC": DJ505.PadColor.MAGENTA, - "#FFCC0044": DJ505.PadColor.RED, - "#FFFFCCCC": DJ505.PadColor.APRICOT, - "#FFFFFFFF": DJ505.PadColor.WHITE, + "#CC0000": DJ505.PadColor.RED, + "#CC4400": DJ505.PadColor.CORAL, + "#CC8800": DJ505.PadColor.ORANGE, + "#CCCC00": DJ505.PadColor.YELLOW, + "#88CC00": DJ505.PadColor.GREEN, + "#00CC00": DJ505.PadColor.APPLEGREEN, + "#00CC88": DJ505.PadColor.AQUAMARINE, + "#00CCCC": DJ505.PadColor.TURQUOISE, + "#0088CC": DJ505.PadColor.CELESTE, + "#0000CC": DJ505.PadColor.BLUE, + "#4400CC": DJ505.PadColor.AZURE, + "#8800CC": DJ505.PadColor.PURPLE, + "#CC00CC": DJ505.PadColor.MAGENTA, + "#CC0044": DJ505.PadColor.RED, + "#FFCCCC": DJ505.PadColor.APRICOT, + "#FFFFFF": DJ505.PadColor.WHITE, }); DJ505.PadSection = function(deck, offset) { From 74e6cf7f44ea22ae8bc5fb07514811a73f22e4ce Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Fri, 6 Mar 2020 22:30:15 +0100 Subject: [PATCH 110/158] preferences/colorpalettesettings: Replace maxDigits with numDigits --- src/preferences/colorpalettesettings.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/preferences/colorpalettesettings.cpp b/src/preferences/colorpalettesettings.cpp index 205b3661a5d..dd63df6eaba 100644 --- a/src/preferences/colorpalettesettings.cpp +++ b/src/preferences/colorpalettesettings.cpp @@ -40,10 +40,10 @@ void ColorPaletteSettings::setColorPalette(const QString& name, const ColorPalet removePalette(name); const QString group = kColorPaletteGroup.arg(name); - int maxDigits = numberOfDecimalDigits(colorPalette.size() - 1); + int numDigits = numberOfDecimalDigits(colorPalette.size() - 1); for (int index = 0; index < colorPalette.size(); ++index) { mixxx::RgbColor color = colorPalette.at(index); - m_pConfig->setValue(keyForIndex(group, index, maxDigits), color); + m_pConfig->setValue(keyForIndex(group, index, numDigits), color); } } @@ -102,6 +102,6 @@ QSet ColorPaletteSettings::getColorPaletteNames() { return names; } -ConfigKey ColorPaletteSettings::keyForIndex(const QString& group, int index, int maxDigits) { - return ConfigKey(group, QString::number(index).rightJustified(maxDigits, '0')); +ConfigKey ColorPaletteSettings::keyForIndex(const QString& group, int index, int numDigits) { + return ConfigKey(group, QString::number(index).rightJustified(numDigits, '0')); } From 078e595d44846ff5655ce21e5eb5037b2d648ea3 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sat, 7 Mar 2020 10:49:13 +0100 Subject: [PATCH 111/158] Use #FF8C00 instead of #FF8000 as "no color" replacement Color taken from: https://github.com/mixxxdj/mixxx/pull/2031#issuecomment-466168921 --- res/schema.xml | 2 +- src/util/color/colorpalette.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/res/schema.xml b/res/schema.xml index 54ecf75e5db..98cbef7d844 100644 --- a/res/schema.xml +++ b/res/schema.xml @@ -495,7 +495,7 @@ METADATA - UPDATE cues SET color=0xFF8000 WHERE color=0; + UPDATE cues SET color=0xFF8C00 WHERE color=0; UPDATE cues SET color=0xC50A08 WHERE color=1; diff --git a/src/util/color/colorpalette.cpp b/src/util/color/colorpalette.cpp index 846feabdb85..60fe96411cb 100644 --- a/src/util/color/colorpalette.cpp +++ b/src/util/color/colorpalette.cpp @@ -13,7 +13,7 @@ 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(0xFF8000); +constexpr mixxx::RgbColor kSchemaMigrationReplacementColor(0xFF8C00); } // anonymous namespace From 43fc59d9bf612259f7cc48c72d72f55d93c58e02 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 8 Mar 2020 16:56:48 +0100 Subject: [PATCH 112/158] engine/controls/cuecontrol: Remove commented lines --- src/engine/controls/cuecontrol.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index 7ceede1af38..bd669a27da0 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -47,8 +47,6 @@ CueControl::CueControl(QString group, m_pConfig(pConfig), m_colorPaletteSettings(ColorPaletteSettings(pConfig)), m_bPreviewing(false), - // m_pPlay->toBoo() -> engine play state - // m_pPlay->set(1.0) -> emulate play button press m_pPlay(ControlObject::getControl(ConfigKey(group, "play"))), m_pStopButton(ControlObject::getControl(ConfigKey(group, "stop"))), m_iCurrentlyPreviewingHotcues(0), From ee5e5e469fa0414e7b1b7ca5287a45da47ed3991 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 8 Mar 2020 17:11:14 +0100 Subject: [PATCH 113/158] controllers/colormapper: Improve constructor and remove destructor --- src/controllers/colormapper.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/controllers/colormapper.h b/src/controllers/colormapper.h index d78c5e4fe7c..69766f3e68c 100644 --- a/src/controllers/colormapper.h +++ b/src/controllers/colormapper.h @@ -11,13 +11,11 @@ class ColorMapper final { public: ColorMapper() = delete; - ColorMapper(const QMap availableColors) + explicit ColorMapper(QMap availableColors) : m_availableColors(availableColors) { DEBUG_ASSERT(!m_availableColors.isEmpty()); } - ~ColorMapper() = default; - QPair getNearestColor(QRgb desiredColor); private: From 7fe6f810ffa19016475ebd9924ed41fc812b1e23 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 8 Mar 2020 17:12:02 +0100 Subject: [PATCH 114/158] controllers/colormapperjsproxy: Add small code style improvements --- src/controllers/colormapperjsproxy.cpp | 4 ++-- src/controllers/colormapperjsproxy.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/controllers/colormapperjsproxy.cpp b/src/controllers/colormapperjsproxy.cpp index 42d33cb0dc8..97a9c06b202 100644 --- a/src/controllers/colormapperjsproxy.cpp +++ b/src/controllers/colormapperjsproxy.cpp @@ -3,8 +3,8 @@ #include "controllers/colormapperjsproxy.h" ColorMapperJSProxy::ColorMapperJSProxy(QScriptEngine* pScriptEngine, QMap availableColors) - : m_pScriptEngine(pScriptEngine) { - m_colorMapper = new ColorMapper(availableColors); + : m_pScriptEngine(pScriptEngine), + m_colorMapper(new ColorMapper(availableColors)) { } QScriptValue ColorMapperJSProxy::getNearestColor(uint colorCode) { diff --git a/src/controllers/colormapperjsproxy.h b/src/controllers/colormapperjsproxy.h index f8e54f0890b..26a8f1d6599 100644 --- a/src/controllers/colormapperjsproxy.h +++ b/src/controllers/colormapperjsproxy.h @@ -11,7 +11,7 @@ class ColorMapperJSProxy final : public QObject { ColorMapperJSProxy() = delete; ColorMapperJSProxy(QScriptEngine* pScriptEngine, QMap availableColors); - ~ColorMapperJSProxy() { + ~ColorMapperJSProxy() override { delete m_colorMapper; }; From 0a423a0297e01891a6b1c7102fe30868e8d6e177 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Mon, 9 Mar 2020 10:14:51 +0100 Subject: [PATCH 115/158] res/schema.xml: Add comment regarding hotcue palette to schema --- res/schema.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/res/schema.xml b/res/schema.xml index 98cbef7d844..d33460b9b3b 100644 --- a/res/schema.xml +++ b/res/schema.xml @@ -496,6 +496,7 @@ METADATA UPDATE cues SET color=0xFF8C00 WHERE color=0; + UPDATE cues SET color=0xC50A08 WHERE color=1; From ba01c5f2611c095b63c677ff364e1a6371867e6d Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Mon, 9 Mar 2020 10:15:26 +0100 Subject: [PATCH 116/158] controllers/colormapper: Replace qDebug() with kLogger.trace() --- src/controllers/colormapper.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/controllers/colormapper.cpp b/src/controllers/colormapper.cpp index 20571668bec..a7323951198 100644 --- a/src/controllers/colormapper.cpp +++ b/src/controllers/colormapper.cpp @@ -3,9 +3,12 @@ #include #include -#include "util/debug.h" +#include "util/logger.h" namespace { + +const mixxx::Logger kLogger("ColorMapper"); + double colorDistance(QRgb a, QRgb b) { // This algorithm calculates the distance between two colors. In // contrast to the L2 norm, this also tries take the human perception @@ -23,6 +26,7 @@ double colorDistance(QRgb a, QRgb b) { (4 * delta_green * delta_green) + (((767 - mean_red) * delta_blue * delta_blue) >> 8)); } + } // namespace QPair ColorMapper::getNearestColor(QRgb desiredColor) { @@ -32,9 +36,10 @@ QPair ColorMapper::getNearestColor(QRgb desiredColor) { if (i != m_cache.constEnd()) { j = m_availableColors.find(i.value()); DEBUG_ASSERT(j != m_availableColors.constEnd()); - qDebug() << "ColorMapper cache hit for" << desiredColor << ":" - << "Color =" << j.key() << "," - << "Value =" << j.value(); + kLogger.trace() + << "ColorMapper cache hit for" << desiredColor << ":" + << "Color =" << j.key() << "," + << "Value =" << j.value(); return QPair(j.key(), j.value()); } @@ -51,9 +56,10 @@ QPair ColorMapper::getNearestColor(QRgb desiredColor) { } DEBUG_ASSERT(nearestColorDistance < qInf()); - qDebug() << "ColorMapper found matching color for" << desiredColor << ":" - << "Color =" << nearestColorIterator.key() << "," - << "Value =" << nearestColorIterator.value(); + kLogger.trace() + << "ColorMapper found matching color for" << desiredColor << ":" + << "Color =" << nearestColorIterator.key() << "," + << "Value =" << nearestColorIterator.value(); m_cache.insert(desiredColor, nearestColorIterator.key()); return QPair(nearestColorIterator.key(), nearestColorIterator.value()); } From 9883318f7bba1612176ede83d7e4fe6322350eac Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Mon, 9 Mar 2020 10:32:59 +0100 Subject: [PATCH 117/158] Add/improve comments for new classes and free functions --- src/controllers/colormapper.h | 3 +++ src/controllers/colormapperjsproxy.h | 3 +++ src/engine/controls/cuecontrol.cpp | 4 +++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/controllers/colormapper.h b/src/controllers/colormapper.h index 69766f3e68c..9f2de26a9ba 100644 --- a/src/controllers/colormapper.h +++ b/src/controllers/colormapper.h @@ -8,6 +8,9 @@ #include "util/assert.h" +// This class allows to find the nearest color representation of a given color +// in a set of fixed colors. Additional user data (e.g. MIDI byte values) can +// be linked to colors in the color set as QVariant. class ColorMapper final { public: ColorMapper() = delete; diff --git a/src/controllers/colormapperjsproxy.h b/src/controllers/colormapperjsproxy.h index 26a8f1d6599..1a2a0024314 100644 --- a/src/controllers/colormapperjsproxy.h +++ b/src/controllers/colormapperjsproxy.h @@ -5,6 +5,9 @@ #include "controllers/colormapper.h" +// This is a wrapper class that exposes ColorMapper via the QScriptEngine and +// makes it possible to create and use ColorMapper object from JavaScript +// controller mappings. class ColorMapperJSProxy final : public QObject { Q_OBJECT public: diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index bd669a27da0..0297c7bdfb9 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -27,7 +27,9 @@ constexpr double kNoColorControlValue = -1; namespace { -// Helper function to convert doubles into RgbColor instances (or nullopt) +// Helper function to convert control values (i.e. doubles) into RgbColor +// instances (or nullopt if value < 0). This happens by using the integer +// component as RGB color codes (e.g. 0xFF0000). inline mixxx::RgbColor::optional_t doubleToRgbColor(double value) { if (value < 0) { return std::nullopt; From 3c0a3feee2f6e1192535196c84d016549bbcc51c Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Mon, 9 Mar 2020 10:33:58 +0100 Subject: [PATCH 118/158] controllers/colormapperjsproxy: Use auto instead of long type name --- src/controllers/colormapperjsproxy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controllers/colormapperjsproxy.cpp b/src/controllers/colormapperjsproxy.cpp index 97a9c06b202..fada130a418 100644 --- a/src/controllers/colormapperjsproxy.cpp +++ b/src/controllers/colormapperjsproxy.cpp @@ -8,7 +8,7 @@ ColorMapperJSProxy::ColorMapperJSProxy(QScriptEngine* pScriptEngine, QMap result = m_colorMapper->getNearestColor(static_cast(colorCode)); + auto result = m_colorMapper->getNearestColor(static_cast(colorCode)); QScriptValue jsColor = m_pScriptEngine->newObject(); jsColor.setProperty("red", qRed(result.first)); jsColor.setProperty("green", qGreen(result.first)); From b4e9de9d8f86e4ee2ec5363cc39dc05f57c48ec0 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Mon, 9 Mar 2020 10:39:02 +0100 Subject: [PATCH 119/158] controllers: Use const refs instead of const-by-value for HID/HSS1394 --- src/controllers/hid/hidcontroller.cpp | 2 +- src/controllers/hid/hidcontroller.h | 2 +- src/controllers/midi/hss1394controller.cpp | 2 +- src/controllers/midi/hss1394controller.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/controllers/hid/hidcontroller.cpp b/src/controllers/hid/hidcontroller.cpp index 32912447f72..ec118012088 100644 --- a/src/controllers/hid/hidcontroller.cpp +++ b/src/controllers/hid/hidcontroller.cpp @@ -16,7 +16,7 @@ #include "controllers/controllerdebug.h" #include "util/time.h" -HidController::HidController(const hid_device_info deviceInfo, UserSettingsPointer pConfig) +HidController::HidController(const hid_device_info& deviceInfo, UserSettingsPointer pConfig) : Controller(pConfig), m_pHidDevice(NULL) { // Copy required variables from deviceInfo, which will be freed after diff --git a/src/controllers/hid/hidcontroller.h b/src/controllers/hid/hidcontroller.h index b85b6cdfaf2..f60843067a8 100644 --- a/src/controllers/hid/hidcontroller.h +++ b/src/controllers/hid/hidcontroller.h @@ -20,7 +20,7 @@ class HidController final : public Controller { Q_OBJECT public: - HidController(const hid_device_info deviceInfo, UserSettingsPointer pConfig); + HidController(const hid_device_info& deviceInfo, UserSettingsPointer pConfig); ~HidController() override; QString presetExtension() override; diff --git a/src/controllers/midi/hss1394controller.cpp b/src/controllers/midi/hss1394controller.cpp index 1b87a4e834e..886530d2929 100644 --- a/src/controllers/midi/hss1394controller.cpp +++ b/src/controllers/midi/hss1394controller.cpp @@ -65,7 +65,7 @@ void DeviceChannelListener::Reconnected() { } Hss1394Controller::Hss1394Controller( - const hss1394::TNodeInfo deviceInfo, + const hss1394::TNodeInfo& deviceInfo, int deviceIndex, UserSettingsPointer pConfig) : MidiController(pConfig), diff --git a/src/controllers/midi/hss1394controller.h b/src/controllers/midi/hss1394controller.h index 284d00629fe..c4a0045c59f 100644 --- a/src/controllers/midi/hss1394controller.h +++ b/src/controllers/midi/hss1394controller.h @@ -44,7 +44,7 @@ class Hss1394Controller : public MidiController { Q_OBJECT public: Hss1394Controller( - const hss1394::TNodeInfo deviceInfo, + const hss1394::TNodeInfo& deviceInfo, int deviceIndex, UserSettingsPointer pConfig); ~Hss1394Controller() override; From 90b1109d32edad4c055c01406e0cfadfb5939b39 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Mon, 9 Mar 2020 10:48:48 +0100 Subject: [PATCH 120/158] controllers/controllerengine: Declare immutable m_pConfig member as const --- src/controllers/controllerengine.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controllers/controllerengine.h b/src/controllers/controllerengine.h index 25b2893d501..87a75abd730 100644 --- a/src/controllers/controllerengine.h +++ b/src/controllers/controllerengine.h @@ -197,7 +197,7 @@ class ControllerEngine : public QObject { double getDeckRate(const QString& group); Controller* m_pController; - UserSettingsPointer m_pConfig; + const UserSettingsPointer m_pConfig; bool m_bPopups; QList m_scriptFunctionPrefixes; QMap m_scriptErrors; From 8ca8003a235a501e9b437fde9d7c453902149506 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Mon, 9 Mar 2020 20:53:14 +0100 Subject: [PATCH 121/158] controllers/colormapperjsproxy: Use script errors instead of assertions --- src/controllers/colormapperjsproxy.cpp | 27 +++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/controllers/colormapperjsproxy.cpp b/src/controllers/colormapperjsproxy.cpp index fada130a418..412e490e94b 100644 --- a/src/controllers/colormapperjsproxy.cpp +++ b/src/controllers/colormapperjsproxy.cpp @@ -23,21 +23,34 @@ QScriptValue ColorMapperJSProxy::getNearestValue(uint colorCode) { QScriptValue ColorMapperJSProxyConstructor(QScriptContext* pScriptContext, QScriptEngine* pScriptEngine) { QMap availableColors; - DEBUG_ASSERT(pScriptContext->argumentCount() == 1); - QScriptValueIterator it(pScriptContext->argument(0)); + if (pScriptContext->argumentCount() != 1) { + pScriptContext->throwError( + QStringLiteral("Failed to create ColorMapper object: constructor takes exactly one argument!")); + return pScriptEngine->undefinedValue(); + } + QScriptValue argument = pScriptContext->argument(0); + if (!argument.isValid() || !argument.isObject()) { + pScriptContext->throwError( + QStringLiteral("Failed to create ColorMapper object: argument needs to be an object!")); + return pScriptEngine->undefinedValue(); + } + + QScriptValueIterator it(argument); while (it.hasNext()) { it.next(); - DEBUG_ASSERT(!it.value().isObject()); QColor color(it.name()); - VERIFY_OR_DEBUG_ASSERT(color.isValid()) { - qWarning() << "Received invalid color name from controller script:" << it.name(); + if (color.isValid()) { + availableColors.insert(color.rgb(), it.value().toVariant()); + } else { + pScriptContext->throwError( + QStringLiteral("Invalid color name passed to ColorMapper: ") + it.name()); continue; } - availableColors.insert(color.rgb(), it.value().toVariant()); } if (availableColors.isEmpty()) { - qWarning() << "Failed to create ColorMapper object: available colors mustn't be empty!"; + pScriptContext->throwError( + QStringLiteral("Failed to create ColorMapper object: available colors mustn't be empty!")); return pScriptEngine->undefinedValue(); } From 6eb21245b55c50489ea991eb65a4ee8bc8b88e52 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Mon, 9 Mar 2020 21:48:13 +0100 Subject: [PATCH 122/158] controllers/colormapperjsproxy: Add comment to slots with return value --- src/controllers/colormapperjsproxy.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/controllers/colormapperjsproxy.h b/src/controllers/colormapperjsproxy.h index 1a2a0024314..065f1b58d4c 100644 --- a/src/controllers/colormapperjsproxy.h +++ b/src/controllers/colormapperjsproxy.h @@ -19,6 +19,8 @@ class ColorMapperJSProxy final : public QObject { }; public slots: + // These slots have a return value, because they are callable from + // controller scripts QScriptValue getNearestColor(uint ColorCode); QScriptValue getNearestValue(uint ColorCode); From be415babc383e358741c00a09008f6cba02284c3 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 10 Mar 2020 00:11:27 +0100 Subject: [PATCH 123/158] util/color/colorpalette: Fix swapped green/blue hotcue palette colors --- src/util/color/colorpalette.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/color/colorpalette.cpp b/src/util/color/colorpalette.cpp index 60fe96411cb..66824eb3a82 100644 --- a/src/util/color/colorpalette.cpp +++ b/src/util/color/colorpalette.cpp @@ -4,9 +4,9 @@ namespace { constexpr mixxx::RgbColor kColorMixxxRed(0xC50A08); constexpr mixxx::RgbColor kColorMixxxYellow(0x32BE44); -constexpr mixxx::RgbColor kColorMixxxGreen(0x0044FF); +constexpr mixxx::RgbColor kColorMixxxGreen(0x42D4F4); constexpr mixxx::RgbColor kColorMixxxCeleste(0xF8D200); -constexpr mixxx::RgbColor kColorMixxxBlue(0x42D4F4); +constexpr mixxx::RgbColor kColorMixxxBlue(0x0044FF); constexpr mixxx::RgbColor kColorMixxxPurple(0xAF00CC); constexpr mixxx::RgbColor kColorMixxxPink(0xFCA6D7); constexpr mixxx::RgbColor kColorMixxxWhite(0xF2F2FF); From eb2fd283c7a7da4606bc4a7d55b90339ae209d99 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 10 Mar 2020 00:12:33 +0100 Subject: [PATCH 124/158] test/colormapperjsproxy_test: Add tests for ColorMapperJSProxy --- CMakeLists.txt | 1 + src/test/colormapperjsproxy_test.cpp | 120 +++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 src/test/colormapperjsproxy_test.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 6b9a320981e..9068de21cc7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -929,6 +929,7 @@ add_executable(mixxx-test src/test/cache_test.cpp src/test/channelhandle_test.cpp src/test/colorconfig_test.cpp + src/test/colormapperjsproxy_test.cpp src/test/colorpalette_test.cpp src/test/compatibility_test.cpp src/test/configobject_test.cpp diff --git a/src/test/colormapperjsproxy_test.cpp b/src/test/colormapperjsproxy_test.cpp new file mode 100644 index 00000000000..bc4ac3ac6d8 --- /dev/null +++ b/src/test/colormapperjsproxy_test.cpp @@ -0,0 +1,120 @@ +#include "controllers/colormapperjsproxy.h" + +#include + +#include "test/mixxxtest.h" + +namespace { + +QScriptEngine* createScriptEngine() { + QScriptEngine* pEngine = new QScriptEngine(); + QScriptValue constructor = pEngine->newFunction(ColorMapperJSProxyConstructor); + QScriptValue metaObject = pEngine->newQMetaObject(&ColorMapperJSProxy::staticMetaObject, constructor); + pEngine->globalObject().setProperty("ColorMapper", metaObject); + return pEngine; +} + +} // namespace + +class ColorMapperJSProxyTest : public MixxxTest {}; + +TEST_F(ColorMapperJSProxyTest, Instantiation) { + QScriptEngine* pEngine = createScriptEngine(); + + // Valid instantiation + pEngine->evaluate( + "var mapper = new ColorMapper({" + " '#FF0000': 1," + " '#00FF00': 2," + " '#0000FF': 3," + "});"); + EXPECT_FALSE(pEngine->hasUncaughtException()); + pEngine->clearExceptions(); + + // Invalid instantiation: no arguments + pEngine->evaluate("var mapper = new ColorMapper();"); + EXPECT_TRUE(pEngine->hasUncaughtException()); + pEngine->clearExceptions(); + + // Invalid instantiation: invalid argument + pEngine->evaluate("var mapper = new ColorMapper('hello');"); + EXPECT_TRUE(pEngine->hasUncaughtException()); + pEngine->clearExceptions(); + + // Invalid instantiation: argument is an empty object + pEngine->evaluate("var mapper = new ColorMapper({});"); + EXPECT_TRUE(pEngine->hasUncaughtException()); + pEngine->clearExceptions(); + + // Invalid instantiation: argument is an empty object + pEngine->evaluate( + "var mapper = new ColorMapper({" + " 'not a color': 1" + "});"); + EXPECT_TRUE(pEngine->hasUncaughtException()); + pEngine->clearExceptions(); +} + +TEST_F(ColorMapperJSProxyTest, GetNearestColor) { + QScriptEngine* pEngine = createScriptEngine(); + pEngine->evaluate( + "var mapper = new ColorMapper({" + " '#C50A08': 1," + " '#32BE44': 2," + " '#42D4F4': 3," + " '#F8D200': 4," + " '#0044FF': 5," + " '#AF00CC': 6," + " '#FCA6D7': 7," + " '#F2F2FF': 8," + "});" + "/* white */" + "var color1 = mapper.getNearestColor(0xFFFFFF);" + "if (color1.red != 0xF2 || color1.green != 0xF2 || color1.blue != 0xFF) {" + " throw Error();" + "};" + "/* white */" + "var color2 = mapper.getNearestColor(0xDCDCDC);" + "if (color2.red != 0xF2 || color2.green != 0xF2 || color2.blue != 0xFF) {" + " throw Error();" + "};" + "/* red */" + "var color3 = mapper.getNearestColor(0xFF0000);" + "if (color3.red != 0xC5 || color3.green != 0x0A || color3.blue != 0x08) {" + " throw Error();" + "};" + "/* yellow */" + "var color4 = mapper.getNearestColor(0x22CC22);" + "if (color4.red != 0x32 || color4.green != 0xBE || color4.blue != 0x44) {" + " throw Error();" + "};"); + EXPECT_FALSE(pEngine->hasUncaughtException()); +} + +TEST_F(ColorMapperJSProxyTest, GetNearestValue) { + QScriptEngine* pEngine = createScriptEngine(); + pEngine->evaluate( + "var mapper = new ColorMapper({" + " '#C50A08': 1," + " '#32BE44': 2," + " '#42D4F4': 3," + " '#F8D200': 4," + " '#0044FF': 5," + " '#AF00CC': 6," + " '#FCA6D7': 7," + " '#F2F2FF': 8," + "});" + "/* red */" + "if (mapper.getNearestValue(0xFF0000) != 1) {" + " throw Error();" + "};" + "/* blue */" + "if (mapper.getNearestValue(0x0000AA) != 5) {" + " throw Error();" + "};" + "/* white */" + "if (mapper.getNearestValue(0xFFFFFF) != 8) {" + " throw Error();" + "};"); + EXPECT_FALSE(pEngine->hasUncaughtException()); +} From 6046abf7f065a2b2361a8445edec6e42451bd1bc Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 10 Mar 2020 00:19:06 +0100 Subject: [PATCH 125/158] controllers/colormapperjsproxy: Use Q_INVOKABLE instead of slots --- src/controllers/colormapperjsproxy.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/controllers/colormapperjsproxy.h b/src/controllers/colormapperjsproxy.h index 065f1b58d4c..d699f2a39a0 100644 --- a/src/controllers/colormapperjsproxy.h +++ b/src/controllers/colormapperjsproxy.h @@ -18,11 +18,9 @@ class ColorMapperJSProxy final : public QObject { delete m_colorMapper; }; - public slots: - // These slots have a return value, because they are callable from - // controller scripts - QScriptValue getNearestColor(uint ColorCode); - QScriptValue getNearestValue(uint ColorCode); + // These method callable from controller scripts + Q_INVOKABLE QScriptValue getNearestColor(uint ColorCode); + Q_INVOKABLE QScriptValue getNearestValue(uint ColorCode); private: QScriptEngine* m_pScriptEngine; From a538a0958356874d1994654d11fec1105937c6fa Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 10 Mar 2020 11:08:53 +0100 Subject: [PATCH 126/158] res/controllers/common-controller-scripts.js: Fix eslint errors --- res/controllers/.eslintrc.json | 14 +- res/controllers/common-controller-scripts.js | 441 ++++++++++--------- 2 files changed, 243 insertions(+), 212 deletions(-) diff --git a/res/controllers/.eslintrc.json b/res/controllers/.eslintrc.json index b2687b106a2..c5d64fad4f5 100644 --- a/res/controllers/.eslintrc.json +++ b/res/controllers/.eslintrc.json @@ -5,6 +5,18 @@ "components": "readonly", "engine": "readonly", "midi": "readonly", - "script": "readonly" + "printObject": "readonly", + "stringifyObject": "readonly", + "arrayContains": "readonly", + "secondstominutes": "readonly", + "msecondstominutes": "readonly", + "script": "readonly", + "bpm": "readonly", + "ButtonState": "readonly", + "LedState": "readonly", + "Controller": "readonly", + "Button": "readonly", + "Control": "readonly", + "Deck": "readonly" } } diff --git a/res/controllers/common-controller-scripts.js b/res/controllers/common-controller-scripts.js index c1d2d09f58f..f22b96d0b5e 100644 --- a/res/controllers/common-controller-scripts.js +++ b/res/controllers/common-controller-scripts.js @@ -1,119 +1,137 @@ // Functions common to all controllers go in this file +/* global print:off + printObject:off + stringifyObject:off + arrayContains:off + secondstominutes:off + msecondstominutes:off + script:off + bpm:off + ButtonState:off + LedState:off + Controller:off + Button:off + Control:off + Deck:off + */ // ----------------- Prototype enhancements --------------------- // Returns an ASCII byte array for the string String.prototype.toInt = function() { - var a = new Array() + var a = new Array(); for (var i = 0; i < this.length; i++) { - a[i] = this.charCodeAt(i) + a[i] = this.charCodeAt(i); } - return a -} + return a; +}; // ----------------- Function overloads --------------------- // Causes script print() calls to appear in the log file as well -print = function(string) { - engine.log(string) -} +var print = function(string) { + engine.log(string); +}; -printObject = function(obj, maxdepth) { - print(stringifyObject(obj, maxdepth)) -} +// eslint-disable-next-line no-unused-vars +var printObject = function(obj, maxdepth) { + print(stringifyObject(obj, maxdepth)); +}; -stringifyObject = function(obj, maxdepth, checked, prefix) { +var stringifyObject = function(obj, maxdepth, checked, prefix) { if (!maxdepth) - maxdepth = 2 + maxdepth = 2; try { - return JSON.stringify(obj, null, maxdepth) + return JSON.stringify(obj, null, maxdepth); } catch (e) { if (!checked) - checked = [] + checked = []; if (!prefix) - prefix = "" + prefix = ""; if (maxdepth > 0 && typeof obj === "object" && obj !== null && Object.getPrototypeOf(obj) !== "" && !arrayContains(checked, obj)) { - checked.push(obj) - var output = "{\n" + checked.push(obj); + var output = "{\n"; for (var property in obj) { - var value = obj[property] + var value = obj[property]; if (typeof value === "function") - continue - output += prefix + property + ": " + stringifyObject(value, maxdepth - 1, checked, prefix + " ") + "\n" + continue; + output += prefix + property + ": " + stringifyObject(value, maxdepth - 1, checked, prefix + " ") + "\n"; } - return output + prefix.substr(2) + "}" + return output + prefix.substr(2) + "}"; } } - return obj -} + return obj; +}; -arrayContains = function(array, elem) { +var arrayContains = function(array, elem) { for (var i = 0; i < array.length; i++) { if (array[i] === elem) - return true + return true; } - return false -} + return false; +}; // ----------------- Generic functions --------------------- -secondstominutes = function(secs) { - var m = (secs / 60) | 0 +// eslint-disable-next-line no-unused-vars +var secondstominutes = function(secs) { + var m = (secs / 60) | 0; return (m < 10 ? "0" + m : m) + ":" - + ((secs %= 60) < 10 ? "0" + secs : secs) -} - -msecondstominutes = function(msecs) { - var m = (msecs / 60000) | 0 - msecs %= 60000 - var secs = (msecs / 1000) | 0 - msecs %= 1000 - msecs = Math.round(msecs * 100 / 1000) + + ((secs %= 60) < 10 ? "0" + secs : secs); +}; + +// eslint-disable-next-line no-unused-vars +var msecondstominutes = function(msecs) { + var m = (msecs / 60000) | 0; + msecs %= 60000; + var secs = (msecs / 1000) | 0; + msecs %= 1000; + msecs = Math.round(msecs * 100 / 1000); if (msecs === 100) - msecs = 99 + msecs = 99; return (m < 10 ? "0" + m : m) + ":" + (secs < 10 ? "0" + secs : secs) + "." - + (msecs < 10 ? "0" + msecs : msecs) -} + + (msecs < 10 ? "0" + msecs : msecs); +}; -script = function() { -} +var script = function() { +}; // DEPRECATED -- use script.midiDebug() instead script.debug = function(channel, control, value, status, group) { - print("Warning: script.debug() is deprecated. Use script.midiDebug() instead.") - script.midiDebug(channel, control, value, status, group) -} + print("Warning: script.debug() is deprecated. Use script.midiDebug() instead."); + script.midiDebug(channel, control, value, status, group); +}; // DEPRECATED -- use script.midiPitch() instead script.pitch = function(LSB, MSB, status) { - print("Warning: script.pitch() is deprecated. Use script.midiPitch() instead.") - return script.midiPitch(LSB, MSB, status) -} + print("Warning: script.pitch() is deprecated. Use script.midiPitch() instead."); + return script.midiPitch(LSB, MSB, status); +}; // DEPRECATED -- use script.absoluteLin() instead script.absoluteSlider = function(group, key, value, low, high, min, max) { - print("Warning: script.absoluteSlider() is deprecated. Use engine.setValue(group, key, script.absoluteLin(...)) instead.") - engine.setValue(group, key, script.absoluteLin(value, low, high, min, max)) -} + print("Warning: script.absoluteSlider() is deprecated. Use engine.setValue(group, key, script.absoluteLin(...)) instead."); + engine.setValue(group, key, script.absoluteLin(value, low, high, min, max)); +}; script.midiDebug = function(channel, control, value, status, group) { print("Script.midiDebug - channel: 0x" + channel.toString(16) + " control: 0x" + control.toString(16) + " value: 0x" + value.toString(16) + - " status: 0x" + status.toString(16) + " group: " + group) -} + " status: 0x" + status.toString(16) + " group: " + group); +}; // Returns the deck number of a "ChannelN" or "SamplerN" group script.deckFromGroup = function(group) { - var deck = 0 - if (group.substring(2, 8) == "hannel") { + var deck = 0; + if (group.substring(2, 8) === "hannel") { // Extract deck number from the group text - deck = group.substring(8, group.length - 1) + deck = group.substring(8, group.length - 1); } /* else if (group.substring(2,8)=="ampler") { @@ -121,8 +139,8 @@ script.deckFromGroup = function(group) { deck = group.substring(8,group.length-1); } */ - return parseInt(deck) -} + return parseInt(deck); +}; /* -------- ------------------------------------------------------ script.bindConnections @@ -134,16 +152,16 @@ script.deckFromGroup = function(group) { Output: none -------- ------------------------------------------------------ */ script.bindConnections = function(group, controlsToFunctions, remove) { - var control - remove = (remove === undefined) ? false : remove + var control; + remove = (remove === undefined) ? false : remove; for (control in controlsToFunctions) { - engine.connectControl(group, control, controlsToFunctions[control], remove) + engine.connectControl(group, control, controlsToFunctions[control], remove); if (!remove) { - engine.trigger(group, control) + engine.trigger(group, control); } } -} +}; /* -------- ------------------------------------------------------ script.toggleControl @@ -152,8 +170,8 @@ script.bindConnections = function(group, controlsToFunctions, remove) { Output: none -------- ------------------------------------------------------ */ script.toggleControl = function(group, control) { - engine.setValue(group, control, !(engine.getValue(group, control))) -} + engine.setValue(group, control, !(engine.getValue(group, control))); +}; /* -------- ------------------------------------------------------ script.toggleControl @@ -166,13 +184,13 @@ script.toggleControl = function(group, control) { -------- ------------------------------------------------------ */ script.triggerControl = function(group, control, delay) { if (typeof delay !== "number") { - delay = 200 + delay = 200; } - engine.setValue(group, control, 1) + engine.setValue(group, control, 1); engine.beginTimer(delay, function() { - engine.setValue(group, control, 0) - }, true) -} + engine.setValue(group, control, 0); + }, true); +}; /* -------- ------------------------------------------------------ script.absoluteLin @@ -185,20 +203,20 @@ script.triggerControl = function(group, control, delay) { -------- ------------------------------------------------------ */ script.absoluteLin = function(value, low, high, min, max) { if (!min) { - min = 0 + min = 0; } if (!max) { - max = 127 + max = 127; } if (value <= min) { - return low + return low; } else if (value >= max) { - return high + return high; } else { - return ((((high - low) / (max - min)) * (value - min)) + low) + return ((((high - low) / (max - min)) * (value - min)) + low); } -} +}; /* -------- ------------------------------------------------------ script.absoluteLinInverse @@ -211,20 +229,20 @@ script.absoluteLin = function(value, low, high, min, max) { -------- ------------------------------------------------------ */ script.absoluteLinInverse = function(value, low, high, min, max) { if (!min) { - min = 0 + min = 0; } if (!max) { - max = 127 + max = 127; } - var result = (((value - low) * (max - min)) / (high - low)) + min + var result = (((value - low) * (max - min)) / (high - low)) + min; if (result < min) { - return min + return min; } else if (result > max) { - return max + return max; } else { - return result + return result; } -} +}; /* -------- ------------------------------------------------------ @@ -238,20 +256,20 @@ script.absoluteLinInverse = function(value, low, high, min, max) { -------- ------------------------------------------------------ */ script.absoluteNonLin = function(value, low, mid, high, min, max) { if (!min) { - min = 0 + min = 0; } if (!max) { - max = 127 + max = 127; } - var center = (max - min) / 2 - if (value == center || value == Math.round(center)) { - return mid + var center = (max - min) / 2; + if (value === center || value === Math.round(center)) { + return mid; } else if (value < center) { - return low + (value / (center / (mid - low))) + return low + (value / (center / (mid - low))); } else { - return mid + ((value - center) / (center / (high - mid))) + return mid + ((value - center) / (center / (high - mid))); } -} +}; /* -------- ------------------------------------------------------ script.absoluteNonLinInverse @@ -263,30 +281,30 @@ script.absoluteNonLin = function(value, low, mid, high, min, max) { -------- ------------------------------------------------------ */ script.absoluteNonLinInverse = function(value, low, mid, high, min, max) { if (!min) { - min = 0 + min = 0; } if (!max) { - max = 127 + max = 127; } - var center = (max - min) / 2 - var result + var center = (max - min) / 2; + var result; - if (value == mid) { - return center + if (value === mid) { + return center; } else if (value < mid) { - result = (center / (mid - low)) * (value - low) + result = (center / (mid - low)) * (value - low); } else { - result = center + (center / (high - mid)) * (value - mid) + result = center + (center / (high - mid)) * (value - mid); } if (result < min) { - return min + return min; } else if (result > max) { - return max + return max; } else { - return result + return result; } -} +}; /* -------- ------------------------------------------------------ script.crossfaderCurve @@ -295,14 +313,14 @@ script.absoluteNonLinInverse = function(value, low, mid, high, min, max) { Output: none -------- ------------------------------------------------------ */ script.crossfaderCurve = function(value, min, max) { - if (engine.getValue("[Mixer Profile]", "xFaderMode") == 1) { + if (engine.getValue("[Mixer Profile]", "xFaderMode") === 1) { // Constant Power - engine.setValue("[Mixer Profile]", "xFaderCalibration", script.absoluteLin(value, 0.5, 0.962, min, max)) + engine.setValue("[Mixer Profile]", "xFaderCalibration", script.absoluteLin(value, 0.5, 0.962, min, max)); } else { // Additive - engine.setValue("[Mixer Profile]", "xFaderCurve", script.absoluteLin(value, 1, 2, min, max)) + engine.setValue("[Mixer Profile]", "xFaderCurve", script.absoluteLin(value, 1, 2, min, max)); } -} +}; /* -------- ------------------------------------------------------ script.loopMove @@ -314,14 +332,14 @@ script.crossfaderCurve = function(value, min, max) { Output: none -------- ------------------------------------------------------ */ script.loopMove = function(group, direction, numberOfBeats) { - if (!numberOfBeats || numberOfBeats == 0) numberOfBeats = 0.5 + if (!numberOfBeats || numberOfBeats === 0) numberOfBeats = 0.5; if (direction < 0) { - engine.setValue(group, "loop_move", -numberOfBeats) + engine.setValue(group, "loop_move", -numberOfBeats); } else { - engine.setValue(group, "loop_move", numberOfBeats) + engine.setValue(group, "loop_move", numberOfBeats); } -} +}; /* -------- ------------------------------------------------------ script.midiPitch @@ -335,15 +353,15 @@ script.loopMove = function(group, direction, numberOfBeats) { // TODO: Is this still useful now that MidiController.cpp properly handles these? script.midiPitch = function(LSB, MSB, status) { if ((status & 0xF0) !== 0xE0) { // Mask the upper nybble so we can check the opcode regardless of the channel - print("Script.midiPitch: Error, not a MIDI pitch (0xEn) message: " + status) - return false + print("Script.midiPitch: Error, not a MIDI pitch (0xEn) message: " + status); + return false; } - var value = (MSB << 7) | LSB // Construct the 14-bit number + var value = (MSB << 7) | LSB; // Construct the 14-bit number // Range is 0x0000..0x3FFF center @ 0x2000, i.e. 0..16383 center @ 8192 - var rate = (value - 8192) / 8191 -// print("Script.Pitch: MSB="+MSB+", LSB="+LSB+", value="+value+", rate="+rate); - return rate -} + var rate = (value - 8192) / 8191; + // print("Script.Pitch: MSB="+MSB+", LSB="+LSB+", value="+value+", rate="+rate); + return rate; +}; /* -------- ------------------------------------------------------ script.spinback @@ -356,15 +374,15 @@ script.midiPitch = function(LSB, MSB, status) { script.spinback = function(channel, control, value, status, group, factor, rate) { // if brake is called without defined factor and rate, reset to defaults if (factor === undefined) { - factor = 1 + factor = 1; } // if brake is called without defined rate, reset to default if (rate === undefined) { - rate = -10 + rate = -10; } // disable on note-off or zero value note/cc - engine.spinback(parseInt(group.substring(8, 9)), ((status & 0xF0) !== 0x80 && value > 0), factor, rate) -} + engine.spinback(parseInt(group.substring(8, 9)), ((status & 0xF0) !== 0x80 && value > 0), factor, rate); +}; /* -------- ------------------------------------------------------ script.brake @@ -377,11 +395,11 @@ script.spinback = function(channel, control, value, status, group, factor, rate) script.brake = function(channel, control, value, status, group, factor) { // if brake is called without factor defined, reset to default if (factor === undefined) { - factor = 1 + factor = 1; } // disable on note-off or zero value note/cc, use default decay rate '1' - engine.brake(parseInt(group.substring(8, 9)), ((status & 0xF0) !== 0x80 && value > 0), factor) -} + engine.brake(parseInt(group.substring(8, 9)), ((status & 0xF0) !== 0x80 && value > 0), factor); +}; /* -------- ------------------------------------------------------ script.softStart @@ -395,18 +413,18 @@ script.brake = function(channel, control, value, status, group, factor) { script.softStart = function(channel, control, value, status, group, factor) { // if softStart is called without factor defined, reset to default if (factor === undefined) { - factor = 1 + factor = 1; } // disable on note-off or zero value note/cc, use default increase rate '1' - engine.softStart(parseInt(group.substring(8, 9)), ((status & 0xF0) !== 0x80 && value > 0), factor) -} + engine.softStart(parseInt(group.substring(8, 9)), ((status & 0xF0) !== 0x80 && value > 0), factor); +}; // bpm - Used for tapping the desired BPM for a deck -bpm = function() { -} +var bpm = function() { +}; -bpm.tapTime = 0.0 -bpm.tap = [] // Tap sample values +bpm.tapTime = 0.0; +bpm.tap = []; // Tap sample values /* -------- ------------------------------------------------------ bpm.tapButton @@ -418,122 +436,123 @@ bpm.tap = [] // Tap sample values Output: - -------- ------------------------------------------------------ */ bpm.tapButton = function(deck) { - var now = new Date() / 1000 // Current time in seconds - var tapDelta = now - bpm.tapTime - bpm.tapTime = now + var now = new Date() / 1000; // Current time in seconds + var tapDelta = now - bpm.tapTime; + bpm.tapTime = now; if (tapDelta > 2.0) { // reset if longer than two seconds between taps - bpm.tap = [] - return + bpm.tap = []; + return; } - bpm.tap.push(60 / tapDelta) - if (bpm.tap.length > 8) bpm.tap.shift() // Keep the last 8 samples for averaging - var sum = 0 - for (i = 0; i < bpm.tap.length; i++) { - sum += bpm.tap[i] + bpm.tap.push(60 / tapDelta); + if (bpm.tap.length > 8) bpm.tap.shift(); // Keep the last 8 samples for averaging + var sum = 0; + for (var i = 0; i < bpm.tap.length; i++) { + sum += bpm.tap[i]; } - var average = sum / bpm.tap.length + var average = sum / bpm.tap.length; - var fRateScale = average / engine.getValue("[Channel" + deck + "]", "bpm") + var fRateScale = average / engine.getValue("[Channel" + deck + "]", "bpm"); // Adjust the rate: - fRateScale = (fRateScale - 1.) / engine.getValue("[Channel" + deck + "]", "rateRange") + fRateScale = (fRateScale - 1.) / engine.getValue("[Channel" + deck + "]", "rateRange"); - engine.setValue("[Channel" + deck + "]", "rate", fRateScale * engine.getValue("[Channel" + deck + "]", "rate_dir")) + engine.setValue("[Channel" + deck + "]", "rate", fRateScale * engine.getValue("[Channel" + deck + "]", "rate_dir")); // print("Script: BPM="+average+" setting to "+fRateScale); -} +}; // ----------------- Common regular expressions -------------------------- -script.samplerRegEx = /^\[Sampler(\d+)\]$/ -script.channelRegEx = /^\[Channel(\d+)\]$/ -script.eqRegEx = /^\[EqualizerRack1_(\[.*\])_Effect1\]$/ -script.quickEffectRegEx = /^\[QuickEffectRack1_(\[.*\])\]$/ -script.effectUnitRegEx = /^\[EffectRack1_EffectUnit(\d+)\]$/ -script.individualEffectRegEx = /^\[EffectRack1_EffectUnit(\d+)_Effect(\d+)\]$/ +script.samplerRegEx = /^\[Sampler(\d+)\]$/; +script.channelRegEx = /^\[Channel(\d+)\]$/; +script.eqRegEx = /^\[EqualizerRack1_(\[.*\])_Effect1\]$/; +script.quickEffectRegEx = /^\[QuickEffectRack1_(\[.*\])\]$/; +script.effectUnitRegEx = /^\[EffectRack1_EffectUnit(\d+)\]$/; +script.individualEffectRegEx = /^\[EffectRack1_EffectUnit(\d+)_Effect(\d+)\]$/; // ----------------- Object definitions -------------------------- -ButtonState = {"released": 0x00, "pressed": 0x7F} -LedState = {"off": 0x00, "on": 0x7F} +var ButtonState = {"released": 0x00, "pressed": 0x7F}; +// eslint-disable-next-line no-unused-vars +var LedState = {"off": 0x00, "on": 0x7F}; -//Controller -function Controller() { - this.group = "[Master]" - this.Controls = [] - this.Buttons = [] -} +// Controller +var Controller = function() { + this.group = "[Master]"; + this.Controls = []; + this.Buttons = []; +}; Controller.prototype.addButton = function(buttonName, button, eventHandler) { if (eventHandler) { - var executionEnvironment = this - handler = function(value) { - button.state = value - executionEnvironment[eventHandler](value) - } - button.handler = handler + var executionEnvironment = this; + var handler = function(value) { + button.state = value; + executionEnvironment[eventHandler](value); + }; + button.handler = handler; } - this.Buttons[buttonName] = button -} + this.Buttons[buttonName] = button; +}; Controller.prototype.setControlValue = function(control, value) { - this.Controls[control].setValue(this.group, value) -} - -//Button -Button = function(controlId) { - this.controlId = controlId - this.state = ButtonState.released -} + this.Controls[control].setValue(this.group, value); +}; + +// Button +var Button = function(controlId) { + this.controlId = controlId; + this.state = ButtonState.released; +}; Button.prototype.handleEvent = function(value) { - this.handler(value) -} + this.handler(value); +}; -//Control -Control = function(mappedFunction, softMode) { +// Control +var Control = function(mappedFunction, softMode) { // These defaults are for MIDI controllers - this.minInput = 0 - this.midInput = 0x3F - this.maxInput = 0x7F + this.minInput = 0; + this.midInput = 0x3F; + this.maxInput = 0x7F; // ---- - this.minOutput = -1.0 - this.midOutput = 0.0 - this.maxOutput = 1.0 - this.mappedFunction = mappedFunction - this.softMode = softMode - this.maxJump = 10 -} + this.minOutput = -1.0; + this.midOutput = 0.0; + this.maxOutput = 1.0; + this.mappedFunction = mappedFunction; + this.softMode = softMode; + this.maxJump = 10; +}; Control.prototype.setValue = function(group, inputValue) { - var outputValue = 0 + var outputValue = 0; if (inputValue <= this.midInput) { - outputValue = this.minOutput + ((inputValue - this.minInput) / (this.midInput - this.minInput)) * (this.midOutput - this.minOutput) + outputValue = this.minOutput + ((inputValue - this.minInput) / (this.midInput - this.minInput)) * (this.midOutput - this.minOutput); } else { - outputValue = this.midOutput + ((inputValue - this.midInput) / (this.maxInput - this.midInput)) * (this.maxOutput - this.midOutput) + outputValue = this.midOutput + ((inputValue - this.midInput) / (this.maxInput - this.midInput)) * (this.maxOutput - this.midOutput); } if (this.softMode) { - var currentValue = engine.getValue(group, this.mappedFunction) - var currentRelative = 0.0 + var currentValue = engine.getValue(group, this.mappedFunction); + var currentRelative = 0.0; if (currentValue <= this.midOutput) { - currentRelative = this.minInput + ((currentValue - this.minOutput) / (this.midOutput - this.minOutput)) * (this.midInput - this.minInput) + currentRelative = this.minInput + ((currentValue - this.minOutput) / (this.midOutput - this.minOutput)) * (this.midInput - this.minInput); } else { - currentRelative = this.midInput + ((currentValue - this.midOutput) / (this.maxOutput - this.midOutput)) * (this.maxInput - this.midInput) + currentRelative = this.midInput + ((currentValue - this.midOutput) / (this.maxOutput - this.midOutput)) * (this.maxInput - this.midInput); } if (inputValue > currentRelative - this.maxJump && inputValue < currentRelative + this.maxJump) { - engine.setValue(group, this.mappedFunction, outputValue) + engine.setValue(group, this.mappedFunction, outputValue); } } else { - engine.setValue(group, this.mappedFunction, outputValue) + engine.setValue(group, this.mappedFunction, outputValue); } -} - -//Deck -Deck = function(deckNumber, group) { - this.deckNumber = deckNumber - this.group = group - this.Buttons = [] -} -Deck.prototype.setControlValue = Controller.prototype.setControlValue -Deck.prototype.addButton = Controller.prototype.addButton +}; + +// Deck +var Deck = function(deckNumber, group) { + this.deckNumber = deckNumber; + this.group = group; + this.Buttons = []; +}; +Deck.prototype.setControlValue = Controller.prototype.setControlValue; +Deck.prototype.addButton = Controller.prototype.addButton; // ----------------- END Object definitions ---------------------- From 702050f0b8c52622849d0db1fa5146589c52d11f Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 10 Mar 2020 11:09:27 +0100 Subject: [PATCH 127/158] res/controllers: Add color conv. functions to common-controller-scripts --- res/controllers/.eslintrc.json | 2 ++ res/controllers/common-controller-scripts.js | 16 ++++++++++++++++ res/controllers/midi-components-0.0.js | 17 +---------------- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/res/controllers/.eslintrc.json b/res/controllers/.eslintrc.json index c5d64fad4f5..cf23b6dba95 100644 --- a/res/controllers/.eslintrc.json +++ b/res/controllers/.eslintrc.json @@ -10,6 +10,8 @@ "arrayContains": "readonly", "secondstominutes": "readonly", "msecondstominutes": "readonly", + "colorCodeToColor": "readonly", + "colorToColorCode": "readonly", "script": "readonly", "bpm": "readonly", "ButtonState": "readonly", diff --git a/res/controllers/common-controller-scripts.js b/res/controllers/common-controller-scripts.js index f22b96d0b5e..0340b4d73da 100644 --- a/res/controllers/common-controller-scripts.js +++ b/res/controllers/common-controller-scripts.js @@ -5,6 +5,8 @@ arrayContains:off secondstominutes:off msecondstominutes:off + colorCodeToColor:off + colorToColorCode:off script:off bpm:off ButtonState:off @@ -99,6 +101,20 @@ var msecondstominutes = function(msecs) { + (msecs < 10 ? "0" + msecs : msecs); }; +// eslint-disable-next-line no-unused-vars +var colorToColorCode = function(color) { + return ((color.red & 0xFF) << 16 | (color.green & 0xFF) << 8 | (color.blue & 0xFF)); +}; + +// eslint-disable-next-line no-unused-vars +var colorCodeToColor = function(colorCode) { + return { + "red": (colorCode >> 16) & 0xFF, + "green": (colorCode >> 8) & 0xFF, + "blue": colorCode & 0xFF, + }; +}; + var script = function() { }; diff --git a/res/controllers/midi-components-0.0.js b/res/controllers/midi-components-0.0.js index 9936e0841e3..3c61cbf3838 100644 --- a/res/controllers/midi-components-0.0.js +++ b/res/controllers/midi-components-0.0.js @@ -308,21 +308,6 @@ shift: function() { this.inKey = "hotcue_" + this.number + "_clear"; }, - getColor: function(colorCode) { - if (colorCode === undefined && this.colorKey !== undefined) { - colorCode = engine.getValue(this.group, this.colorKey); - } - - if (colorCode !== undefined) { - return { - "red": (colorCode >> 16) & 0xFF, - "green": (colorCode >> 8) & 0xFF, - "blue": colorCode & 0xFF, - }; - } - - return null; - }, output: function(value) { var outval = this.outValueScale(value); // WARNING: outputColor only handles hotcueColors @@ -344,7 +329,7 @@ print("ERROR: no function defined for sending RGB colors"); return; } - this.sendRGB(this.getColor(colorCode)); + this.sendRGB(colorCodeToColor(colorCode)); } }, connect: function() { From e859c7d077c145a1f4153b92e3e8f85df7253d35 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 11 Mar 2020 09:55:30 +0100 Subject: [PATCH 128/158] res/controllers/common-controller-scripts.js: Break long lines --- res/controllers/common-controller-scripts.js | 48 ++++++++++++++------ 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/res/controllers/common-controller-scripts.js b/res/controllers/common-controller-scripts.js index 0340b4d73da..b03caeebad4 100644 --- a/res/controllers/common-controller-scripts.js +++ b/res/controllers/common-controller-scripts.js @@ -50,14 +50,17 @@ var stringifyObject = function(obj, maxdepth, checked, prefix) { checked = []; if (!prefix) prefix = ""; - if (maxdepth > 0 && typeof obj === "object" && obj !== null && Object.getPrototypeOf(obj) !== "" && !arrayContains(checked, obj)) { + if (maxdepth > 0 && typeof obj === "object" && obj !== null && + Object.getPrototypeOf(obj) !== "" && !arrayContains(checked, obj)) { checked.push(obj); var output = "{\n"; for (var property in obj) { var value = obj[property]; if (typeof value === "function") continue; - output += prefix + property + ": " + stringifyObject(value, maxdepth - 1, checked, prefix + " ") + "\n"; + output += prefix + property + ": " + + stringifyObject(value, maxdepth - 1, checked, prefix + " ") + + "\n"; } return output + prefix.substr(2) + "}"; } @@ -331,10 +334,12 @@ script.absoluteNonLinInverse = function(value, low, mid, high, min, max) { script.crossfaderCurve = function(value, min, max) { if (engine.getValue("[Mixer Profile]", "xFaderMode") === 1) { // Constant Power - engine.setValue("[Mixer Profile]", "xFaderCalibration", script.absoluteLin(value, 0.5, 0.962, min, max)); + engine.setValue("[Mixer Profile]", "xFaderCalibration", + script.absoluteLin(value, 0.5, 0.962, min, max)); } else { // Additive - engine.setValue("[Mixer Profile]", "xFaderCurve", script.absoluteLin(value, 1, 2, min, max)); + engine.setValue("[Mixer Profile]", "xFaderCurve", + script.absoluteLin(value, 1, 2, min, max)); } }; @@ -397,7 +402,9 @@ script.spinback = function(channel, control, value, status, group, factor, rate) rate = -10; } // disable on note-off or zero value note/cc - engine.spinback(parseInt(group.substring(8, 9)), ((status & 0xF0) !== 0x80 && value > 0), factor, rate); + engine.spinback( + parseInt(group.substring(8, 9)), ((status & 0xF0) !== 0x80 && value > 0), + factor, rate); }; /* -------- ------------------------------------------------------ @@ -414,7 +421,9 @@ script.brake = function(channel, control, value, status, group, factor) { factor = 1; } // disable on note-off or zero value note/cc, use default decay rate '1' - engine.brake(parseInt(group.substring(8, 9)), ((status & 0xF0) !== 0x80 && value > 0), factor); + engine.brake( + parseInt(group.substring(8, 9)), ((status & 0xF0) !== 0x80 && value > 0), + factor); }; /* -------- ------------------------------------------------------ @@ -432,7 +441,9 @@ script.softStart = function(channel, control, value, status, group, factor) { factor = 1; } // disable on note-off or zero value note/cc, use default increase rate '1' - engine.softStart(parseInt(group.substring(8, 9)), ((status & 0xF0) !== 0x80 && value > 0), factor); + engine.softStart( + parseInt(group.substring(8, 9)), ((status & 0xF0) !== 0x80 && value > 0), + factor); }; // bpm - Used for tapping the desired BPM for a deck @@ -472,7 +483,9 @@ bpm.tapButton = function(deck) { // Adjust the rate: fRateScale = (fRateScale - 1.) / engine.getValue("[Channel" + deck + "]", "rateRange"); - engine.setValue("[Channel" + deck + "]", "rate", fRateScale * engine.getValue("[Channel" + deck + "]", "rate_dir")); + engine.setValue( + "[Channel" + deck + "]", "rate", + fRateScale * engine.getValue("[Channel" + deck + "]", "rate_dir")); // print("Script: BPM="+average+" setting to "+fRateScale); }; @@ -542,19 +555,28 @@ var Control = function(mappedFunction, softMode) { Control.prototype.setValue = function(group, inputValue) { var outputValue = 0; if (inputValue <= this.midInput) { - outputValue = this.minOutput + ((inputValue - this.minInput) / (this.midInput - this.minInput)) * (this.midOutput - this.minOutput); + outputValue = this.minOutput + + ((inputValue - this.minInput) / (this.midInput - this.minInput)) + * (this.midOutput - this.minOutput); } else { - outputValue = this.midOutput + ((inputValue - this.midInput) / (this.maxInput - this.midInput)) * (this.maxOutput - this.midOutput); + outputValue = this.midOutput + + ((inputValue - this.midInput) / (this.maxInput - this.midInput)) + * (this.maxOutput - this.midOutput); } if (this.softMode) { var currentValue = engine.getValue(group, this.mappedFunction); var currentRelative = 0.0; if (currentValue <= this.midOutput) { - currentRelative = this.minInput + ((currentValue - this.minOutput) / (this.midOutput - this.minOutput)) * (this.midInput - this.minInput); + currentRelative = this.minInput + + ((currentValue - this.minOutput) / (this.midOutput - this.minOutput)) + * (this.midInput - this.minInput); } else { - currentRelative = this.midInput + ((currentValue - this.midOutput) / (this.maxOutput - this.midOutput)) * (this.maxInput - this.midInput); + currentRelative = this.midInput + + ((currentValue - this.midOutput) / (this.maxOutput - this.midOutput)) + * (this.maxInput - this.midInput); } - if (inputValue > currentRelative - this.maxJump && inputValue < currentRelative + this.maxJump) { + if (inputValue > currentRelative - this.maxJump + && inputValue < currentRelative + this.maxJump) { engine.setValue(group, this.mappedFunction, outputValue); } } else { From 42f82a34105fd6d725e4422a3779b002511ddc74 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 11 Mar 2020 10:06:39 +0100 Subject: [PATCH 129/158] controllers/colormapper: Split function to avoid using QPair --- src/controllers/colormapper.cpp | 16 +++++++++------- src/controllers/colormapper.h | 4 ++-- src/controllers/colormapperjsproxy.cpp | 12 ++++++------ 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/controllers/colormapper.cpp b/src/controllers/colormapper.cpp index a7323951198..11c9644dc2c 100644 --- a/src/controllers/colormapper.cpp +++ b/src/controllers/colormapper.cpp @@ -29,18 +29,17 @@ double colorDistance(QRgb a, QRgb b) { } // namespace -QPair ColorMapper::getNearestColor(QRgb desiredColor) { +QRgb ColorMapper::getNearestColor(QRgb desiredColor) { // If desired color is already in cache, use cache entry - QMap::const_iterator i = m_cache.find(desiredColor); + QMap::const_iterator i = m_cache.constFind(desiredColor); QMap::const_iterator j; if (i != m_cache.constEnd()) { j = m_availableColors.find(i.value()); DEBUG_ASSERT(j != m_availableColors.constEnd()); kLogger.trace() << "ColorMapper cache hit for" << desiredColor << ":" - << "Color =" << j.key() << "," - << "Value =" << j.value(); - return QPair(j.key(), j.value()); + << "Color =" << j.key(); + return j.key(); } // Color is not cached @@ -55,11 +54,14 @@ QPair ColorMapper::getNearestColor(QRgb desiredColor) { } } - DEBUG_ASSERT(nearestColorDistance < qInf()); kLogger.trace() << "ColorMapper found matching color for" << desiredColor << ":" << "Color =" << nearestColorIterator.key() << "," << "Value =" << nearestColorIterator.value(); m_cache.insert(desiredColor, nearestColorIterator.key()); - return QPair(nearestColorIterator.key(), nearestColorIterator.value()); + return nearestColorIterator.key(); +} + +QVariant ColorMapper::getValueForNearestColor(QRgb desiredColor) { + return m_availableColors.value(getNearestColor(desiredColor)); } diff --git a/src/controllers/colormapper.h b/src/controllers/colormapper.h index 9f2de26a9ba..05e2cb90551 100644 --- a/src/controllers/colormapper.h +++ b/src/controllers/colormapper.h @@ -3,7 +3,6 @@ #include #include #include -#include #include #include "util/assert.h" @@ -19,7 +18,8 @@ class ColorMapper final { DEBUG_ASSERT(!m_availableColors.isEmpty()); } - QPair getNearestColor(QRgb desiredColor); + QRgb getNearestColor(QRgb desiredColor); + QVariant getValueForNearestColor(QRgb desiredColor); private: const QMap m_availableColors; diff --git a/src/controllers/colormapperjsproxy.cpp b/src/controllers/colormapperjsproxy.cpp index 412e490e94b..20a0790e35a 100644 --- a/src/controllers/colormapperjsproxy.cpp +++ b/src/controllers/colormapperjsproxy.cpp @@ -8,17 +8,17 @@ ColorMapperJSProxy::ColorMapperJSProxy(QScriptEngine* pScriptEngine, QMapgetNearestColor(static_cast(colorCode)); + QRgb result = m_colorMapper->getNearestColor(static_cast(colorCode)); QScriptValue jsColor = m_pScriptEngine->newObject(); - jsColor.setProperty("red", qRed(result.first)); - jsColor.setProperty("green", qGreen(result.first)); - jsColor.setProperty("blue", qBlue(result.first)); + jsColor.setProperty("red", qRed(result)); + jsColor.setProperty("green", qGreen(result)); + jsColor.setProperty("blue", qBlue(result)); return jsColor; } QScriptValue ColorMapperJSProxy::getNearestValue(uint colorCode) { - QPair result = m_colorMapper->getNearestColor(static_cast(colorCode)); - return m_pScriptEngine->toScriptValue(result.second); + return m_pScriptEngine->toScriptValue( + m_colorMapper->getValueForNearestColor(static_cast(colorCode))); } QScriptValue ColorMapperJSProxyConstructor(QScriptContext* pScriptContext, QScriptEngine* pScriptEngine) { From 9e9a56f4ec6a62fae8c867a92b31dab225b90725 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 11 Mar 2020 10:08:30 +0100 Subject: [PATCH 130/158] controllers/bulk/bulkenumerator: Use one initialization per line --- src/controllers/bulk/bulkenumerator.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/controllers/bulk/bulkenumerator.cpp b/src/controllers/bulk/bulkenumerator.cpp index 27b5eea15d3..8df74892935 100644 --- a/src/controllers/bulk/bulkenumerator.cpp +++ b/src/controllers/bulk/bulkenumerator.cpp @@ -12,7 +12,9 @@ #include "controllers/bulk/bulksupported.h" BulkEnumerator::BulkEnumerator(UserSettingsPointer pConfig) - : ControllerEnumerator(), m_context(NULL), m_pConfig(pConfig) { + : ControllerEnumerator(), + m_context(nullptr), + m_pConfig(pConfig) { libusb_init(&m_context); } From 2a0608bb65ae0afef5d97d88899200c3448a1984 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 11 Mar 2020 10:14:37 +0100 Subject: [PATCH 131/158] controllers/colormapperjsproxy: Add comments that explain the invokable methods --- src/controllers/colormapperjsproxy.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/controllers/colormapperjsproxy.h b/src/controllers/colormapperjsproxy.h index d699f2a39a0..5c46ae61a9c 100644 --- a/src/controllers/colormapperjsproxy.h +++ b/src/controllers/colormapperjsproxy.h @@ -18,8 +18,17 @@ class ColorMapperJSProxy final : public QObject { delete m_colorMapper; }; - // These method callable from controller scripts + // Q_INVOKABLE is need here because these methods callable from controller + // scripts + + // For a given RGB color code (e.g. 0xFF0000), this finds the nearest + // available color and returns a JS object with properties "red", "green", + // "blue" (each with value range 0-255). Q_INVOKABLE QScriptValue getNearestColor(uint ColorCode); + + // For a given RGB color code (e.g. 0xFF0000), this finds the nearest + // available color, then returns the value associated with that color + // (which could be a MIDI byte value for example). Q_INVOKABLE QScriptValue getNearestValue(uint ColorCode); private: From a48afde9f541380d76beebb87c14a1bc9d20aa59 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 11 Mar 2020 10:19:33 +0100 Subject: [PATCH 132/158] controllers/colormapperjsproxy: Rename getNearestValue to getValueForNearestColor --- res/controllers/midi-components-0.0.js | 2 +- src/controllers/colormapperjsproxy.cpp | 2 +- src/controllers/colormapperjsproxy.h | 2 +- src/test/colormapperjsproxy_test.cpp | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/res/controllers/midi-components-0.0.js b/res/controllers/midi-components-0.0.js index 3c61cbf3838..9c3793af5d7 100644 --- a/res/controllers/midi-components-0.0.js +++ b/res/controllers/midi-components-0.0.js @@ -322,7 +322,7 @@ }, outputColor: function(colorCode) { if (this.colorMapper !== undefined) { - var nearestColorValue = this.colorMapper.getNearestValue(colorCode); + var nearestColorValue = this.colorMapper.getValueForNearestColor(colorCode); this.send(nearestColorValue); } else { if (this.sendRGB === undefined) { diff --git a/src/controllers/colormapperjsproxy.cpp b/src/controllers/colormapperjsproxy.cpp index 20a0790e35a..12ed2d77df1 100644 --- a/src/controllers/colormapperjsproxy.cpp +++ b/src/controllers/colormapperjsproxy.cpp @@ -16,7 +16,7 @@ QScriptValue ColorMapperJSProxy::getNearestColor(uint colorCode) { return jsColor; } -QScriptValue ColorMapperJSProxy::getNearestValue(uint colorCode) { +QScriptValue ColorMapperJSProxy::getValueForNearestColor(uint colorCode) { return m_pScriptEngine->toScriptValue( m_colorMapper->getValueForNearestColor(static_cast(colorCode))); } diff --git a/src/controllers/colormapperjsproxy.h b/src/controllers/colormapperjsproxy.h index 5c46ae61a9c..3a08f062d55 100644 --- a/src/controllers/colormapperjsproxy.h +++ b/src/controllers/colormapperjsproxy.h @@ -29,7 +29,7 @@ class ColorMapperJSProxy final : public QObject { // For a given RGB color code (e.g. 0xFF0000), this finds the nearest // available color, then returns the value associated with that color // (which could be a MIDI byte value for example). - Q_INVOKABLE QScriptValue getNearestValue(uint ColorCode); + Q_INVOKABLE QScriptValue getValueForNearestColor(uint ColorCode); private: QScriptEngine* m_pScriptEngine; diff --git a/src/test/colormapperjsproxy_test.cpp b/src/test/colormapperjsproxy_test.cpp index bc4ac3ac6d8..f5346490ed2 100644 --- a/src/test/colormapperjsproxy_test.cpp +++ b/src/test/colormapperjsproxy_test.cpp @@ -105,15 +105,15 @@ TEST_F(ColorMapperJSProxyTest, GetNearestValue) { " '#F2F2FF': 8," "});" "/* red */" - "if (mapper.getNearestValue(0xFF0000) != 1) {" + "if (mapper.getValueForNearestColor(0xFF0000) != 1) {" " throw Error();" "};" "/* blue */" - "if (mapper.getNearestValue(0x0000AA) != 5) {" + "if (mapper.getValueForNearestColor(0x0000AA) != 5) {" " throw Error();" "};" "/* white */" - "if (mapper.getNearestValue(0xFFFFFF) != 8) {" + "if (mapper.getValueForNearestColor(0xFFFFFF) != 8) {" " throw Error();" "};"); EXPECT_FALSE(pEngine->hasUncaughtException()); From 05012ec7795e5785ec06ad0502bc3ea91b0e4f60 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 11 Mar 2020 10:37:31 +0100 Subject: [PATCH 133/158] res/controllers/common-controller-scripts: Document color conv. functions --- res/controllers/.eslintrc.json | 4 ++-- res/controllers/common-controller-scripts.js | 12 ++++++++---- res/controllers/midi-components-0.0.js | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/res/controllers/.eslintrc.json b/res/controllers/.eslintrc.json index cf23b6dba95..2a6722aac48 100644 --- a/res/controllers/.eslintrc.json +++ b/res/controllers/.eslintrc.json @@ -10,8 +10,8 @@ "arrayContains": "readonly", "secondstominutes": "readonly", "msecondstominutes": "readonly", - "colorCodeToColor": "readonly", - "colorToColorCode": "readonly", + "colorCodeToObject": "readonly", + "colorCodeFromObject": "readonly", "script": "readonly", "bpm": "readonly", "ButtonState": "readonly", diff --git a/res/controllers/common-controller-scripts.js b/res/controllers/common-controller-scripts.js index b03caeebad4..a7421d613f6 100644 --- a/res/controllers/common-controller-scripts.js +++ b/res/controllers/common-controller-scripts.js @@ -5,8 +5,8 @@ arrayContains:off secondstominutes:off msecondstominutes:off - colorCodeToColor:off - colorToColorCode:off + colorCodeToObject:off + colorCodeFromObject:off script:off bpm:off ButtonState:off @@ -104,13 +104,17 @@ var msecondstominutes = function(msecs) { + (msecs < 10 ? "0" + msecs : msecs); }; +// Converts an object with "red", "green" and "blue" properties (value range +// 0-255) into an RGB color code (e.g. 0xFF0000). // eslint-disable-next-line no-unused-vars -var colorToColorCode = function(color) { +var colorCodeFromObject = function(color) { return ((color.red & 0xFF) << 16 | (color.green & 0xFF) << 8 | (color.blue & 0xFF)); }; +// Converts an RGB color code (e.g. 0xFF0000) into an object with "red", +// "green" and "blue" properties (value range 0-255). // eslint-disable-next-line no-unused-vars -var colorCodeToColor = function(colorCode) { +var colorCodeToObject = function(colorCode) { return { "red": (colorCode >> 16) & 0xFF, "green": (colorCode >> 8) & 0xFF, diff --git a/res/controllers/midi-components-0.0.js b/res/controllers/midi-components-0.0.js index 9c3793af5d7..fa3efe1f98f 100644 --- a/res/controllers/midi-components-0.0.js +++ b/res/controllers/midi-components-0.0.js @@ -329,7 +329,7 @@ print("ERROR: no function defined for sending RGB colors"); return; } - this.sendRGB(colorCodeToColor(colorCode)); + this.sendRGB(colorCodeToObject(colorCode)); } }, connect: function() { From f3a954e46c50f5e40885a4d41c6f2229d9054acf Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 11 Mar 2020 10:38:30 +0100 Subject: [PATCH 134/158] res/controllers/midi-components-0.0.js: Add range change to outputColor() --- res/controllers/midi-components-0.0.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/res/controllers/midi-components-0.0.js b/res/controllers/midi-components-0.0.js index fa3efe1f98f..7294809e522 100644 --- a/res/controllers/midi-components-0.0.js +++ b/res/controllers/midi-components-0.0.js @@ -321,6 +321,11 @@ } }, outputColor: function(colorCode) { + if (colorCode === undefined || colorCode < 0) { + print("Ignoring invalid color code in outputColor()"); + return; + } + if (this.colorMapper !== undefined) { var nearestColorValue = this.colorMapper.getValueForNearestColor(colorCode); this.send(nearestColorValue); From 2f95d2d61497ccfd448bc0f7aab6b429ff56a728 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 11 Mar 2020 10:39:45 +0100 Subject: [PATCH 135/158] res/controllers/midi-components-0.0.js: Throw error if sendRGB is undefined --- res/controllers/midi-components-0.0.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/res/controllers/midi-components-0.0.js b/res/controllers/midi-components-0.0.js index 7294809e522..63f1154d29a 100644 --- a/res/controllers/midi-components-0.0.js +++ b/res/controllers/midi-components-0.0.js @@ -331,8 +331,7 @@ this.send(nearestColorValue); } else { if (this.sendRGB === undefined) { - print("ERROR: no function defined for sending RGB colors"); - return; + throw Error("sendRGB(color) not defined - unable to send RGB colors!"); } this.sendRGB(colorCodeToObject(colorCode)); } From f50ccbe0a07198b50d34427e0b6389e889eccc89 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 11 Mar 2020 10:54:04 +0100 Subject: [PATCH 136/158] res/controllers/midi-components-0.0.js: Add some more comments --- res/controllers/midi-components-0.0.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/res/controllers/midi-components-0.0.js b/res/controllers/midi-components-0.0.js index 63f1154d29a..5ba3e0e53aa 100644 --- a/res/controllers/midi-components-0.0.js +++ b/res/controllers/midi-components-0.0.js @@ -321,15 +321,24 @@ } }, outputColor: function(colorCode) { + // Sends the color from the colorCode to the controller. This + // method will not be called if no colorKey has been specified. if (colorCode === undefined || colorCode < 0) { print("Ignoring invalid color code in outputColor()"); return; } if (this.colorMapper !== undefined) { + // This HotcueButton holds a reference to a ColorMapper. This means + // that the controller only supports a fixed set of colors, so we + // get the MIDI value for the nearest supported color and send it. var nearestColorValue = this.colorMapper.getValueForNearestColor(colorCode); this.send(nearestColorValue); } else { + // Since outputColor has been called but no ColorMapper is + // available, we can assume that controller supports arbitrary + // RGB color output. The user needs to specify a sendRGB() + // function, because the procedure is controller-dependent. if (this.sendRGB === undefined) { throw Error("sendRGB(color) not defined - unable to send RGB colors!"); } From 44b8237d3e4033e0b38376b5a766575a3fc65a81 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 11 Mar 2020 10:58:25 +0100 Subject: [PATCH 137/158] res/controllers/midi-components-0.0.js: Add HotcueButton.sendRGB function stub --- res/controllers/midi-components-0.0.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/res/controllers/midi-components-0.0.js b/res/controllers/midi-components-0.0.js index 5ba3e0e53aa..0773ffc3f39 100644 --- a/res/controllers/midi-components-0.0.js +++ b/res/controllers/midi-components-0.0.js @@ -337,14 +337,15 @@ } else { // Since outputColor has been called but no ColorMapper is // available, we can assume that controller supports arbitrary - // RGB color output. The user needs to specify a sendRGB() - // function, because the procedure is controller-dependent. - if (this.sendRGB === undefined) { - throw Error("sendRGB(color) not defined - unable to send RGB colors!"); - } + // RGB color output. this.sendRGB(colorCodeToObject(colorCode)); } }, + sendRGB: function(_colorObject) { + // This method needs to be overridden in controller mappings, + // because the procedure is controller-dependent. + throw Error("sendRGB(colorObject) not implemented - unable to send RGB colors!"); + }, connect: function() { Button.prototype.connect.call(this); // call parent connect if (undefined !== this.group && this.colorKey !== undefined) { From abd663f99fa20e013587730582ef8cb0efe1ec5e Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 11 Mar 2020 11:00:51 +0100 Subject: [PATCH 138/158] preferences/colorpalettesettings: Remove leftover qWarning() statement --- src/preferences/colorpalettesettings.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/preferences/colorpalettesettings.cpp b/src/preferences/colorpalettesettings.cpp index dd63df6eaba..964bd6917ec 100644 --- a/src/preferences/colorpalettesettings.cpp +++ b/src/preferences/colorpalettesettings.cpp @@ -56,7 +56,6 @@ void ColorPaletteSettings::removePalette(const QString& name) { ColorPalette ColorPaletteSettings::getHotcueColorPalette() const { QString name = m_pConfig->getValueString(kHotcueColorPaletteConfigKey); - qWarning() << "name" << name; if (name.isEmpty()) { return ColorPalette::mixxxHotcuePalette; } From e7a3553bb8c9552c439c9ccc58c2c578aeddb05e Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 11 Mar 2020 21:14:23 +0100 Subject: [PATCH 139/158] test/colorconfig_test: Use literal names for LoadSavePalettes tests --- src/test/colorconfig_test.cpp | 39 +++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/test/colorconfig_test.cpp b/src/test/colorconfig_test.cpp index 330cc8451e6..58a17f706a2 100644 --- a/src/test/colorconfig_test.cpp +++ b/src/test/colorconfig_test.cpp @@ -63,33 +63,36 @@ TEST_F(ColorConfigTest, ReplaceColorPalette) { } TEST_F(ColorConfigTest, LoadSavePalettes) { + const QString kName1 = QStringLiteral("Custom Palette No. 1"); + const QString kName2 = QStringLiteral("My Custom Palette 2"); + const QString kName3 = QStringLiteral("I'm blue, da ba dee"); ColorPaletteSettings colorPaletteSettings(config()); ColorPalette colorPalette1( - "Custom Palette No. 1", QList{ - mixxx::RgbColor(0x66FF99), - mixxx::RgbColor(0xFF9900), - mixxx::RgbColor(0x000000), - mixxx::RgbColor(0xFFFFFF), - }); + kName1, QList{ + mixxx::RgbColor(0x66FF99), + mixxx::RgbColor(0xFF9900), + mixxx::RgbColor(0x000000), + mixxx::RgbColor(0xFFFFFF), + }); colorPaletteSettings.setColorPalette(colorPalette1.getName(), colorPalette1); ColorPalette colorPalette2( - "My Custom Palette 2", QList{ - mixxx::RgbColor(0x0000FF), - mixxx::RgbColor(0xFF0000), - }); + kName2, QList{ + mixxx::RgbColor(0x0000FF), + mixxx::RgbColor(0xFF0000), + }); colorPaletteSettings.setColorPalette(colorPalette2.getName(), colorPalette2); ColorPalette colorPalette3( - "I'm blue, da ba dee", QList{ - mixxx::RgbColor(0x0000FF), - mixxx::RgbColor(0x123456), - mixxx::RgbColor(0x000080), - }); + kName3, QList{ + mixxx::RgbColor(0x0000FF), + mixxx::RgbColor(0x123456), + mixxx::RgbColor(0x000080), + }); colorPaletteSettings.setColorPalette(colorPalette3.getName(), colorPalette3); saveAndReloadConfig(); QSet expectedNames{ - colorPalette1.getName(), - colorPalette2.getName(), - colorPalette3.getName(), + kName1, + kName2, + kName3, }; ASSERT_EQ(expectedNames, colorPaletteSettings.getColorPaletteNames()); } From ec11d6b7da925efd3b193509dea45b7aad91637e Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 11 Mar 2020 21:19:47 +0100 Subject: [PATCH 140/158] test/colormapperjsproxy_test: Use raw c++ string literals for JS code --- src/test/colormapperjsproxy_test.cpp | 128 ++++++++++++++------------- 1 file changed, 68 insertions(+), 60 deletions(-) diff --git a/src/test/colormapperjsproxy_test.cpp b/src/test/colormapperjsproxy_test.cpp index f5346490ed2..4f1a291aadf 100644 --- a/src/test/colormapperjsproxy_test.cpp +++ b/src/test/colormapperjsproxy_test.cpp @@ -23,11 +23,13 @@ TEST_F(ColorMapperJSProxyTest, Instantiation) { // Valid instantiation pEngine->evaluate( - "var mapper = new ColorMapper({" - " '#FF0000': 1," - " '#00FF00': 2," - " '#0000FF': 3," - "});"); + R"JavaScript( + var mapper = new ColorMapper({ + '#FF0000': 1, + '#00FF00': 2, + '#0000FF': 3, + }); + )JavaScript"); EXPECT_FALSE(pEngine->hasUncaughtException()); pEngine->clearExceptions(); @@ -48,9 +50,11 @@ TEST_F(ColorMapperJSProxyTest, Instantiation) { // Invalid instantiation: argument is an empty object pEngine->evaluate( - "var mapper = new ColorMapper({" - " 'not a color': 1" - "});"); + R"JavaScript( + var mapper = new ColorMapper({ + 'not a color': 1 + }); + )JavaScript"); EXPECT_TRUE(pEngine->hasUncaughtException()); pEngine->clearExceptions(); } @@ -58,63 +62,67 @@ TEST_F(ColorMapperJSProxyTest, Instantiation) { TEST_F(ColorMapperJSProxyTest, GetNearestColor) { QScriptEngine* pEngine = createScriptEngine(); pEngine->evaluate( - "var mapper = new ColorMapper({" - " '#C50A08': 1," - " '#32BE44': 2," - " '#42D4F4': 3," - " '#F8D200': 4," - " '#0044FF': 5," - " '#AF00CC': 6," - " '#FCA6D7': 7," - " '#F2F2FF': 8," - "});" - "/* white */" - "var color1 = mapper.getNearestColor(0xFFFFFF);" - "if (color1.red != 0xF2 || color1.green != 0xF2 || color1.blue != 0xFF) {" - " throw Error();" - "};" - "/* white */" - "var color2 = mapper.getNearestColor(0xDCDCDC);" - "if (color2.red != 0xF2 || color2.green != 0xF2 || color2.blue != 0xFF) {" - " throw Error();" - "};" - "/* red */" - "var color3 = mapper.getNearestColor(0xFF0000);" - "if (color3.red != 0xC5 || color3.green != 0x0A || color3.blue != 0x08) {" - " throw Error();" - "};" - "/* yellow */" - "var color4 = mapper.getNearestColor(0x22CC22);" - "if (color4.red != 0x32 || color4.green != 0xBE || color4.blue != 0x44) {" - " throw Error();" - "};"); + R"JavaScript( + var mapper = new ColorMapper({ + '#C50A08': 1, + '#32BE44': 2, + '#42D4F4': 3, + '#F8D200': 4, + '#0044FF': 5, + '#AF00CC': 6, + '#FCA6D7': 7, + '#F2F2FF': 8, + }); + /* white */ + var color1 = mapper.getNearestColor(0xFFFFFF); + if (color1.red != 0xF2 || color1.green != 0xF2 || color1.blue != 0xFF) { + throw Error(); + }; + /* white */ + var color2 = mapper.getNearestColor(0xDCDCDC); + if (color2.red != 0xF2 || color2.green != 0xF2 || color2.blue != 0xFF) { + throw Error(); + }; + /* red */ + var color3 = mapper.getNearestColor(0xFF0000); + if (color3.red != 0xC5 || color3.green != 0x0A || color3.blue != 0x08) { + throw Error(); + }; + /* yellow */ + var color4 = mapper.getNearestColor(0x22CC22); + if (color4.red != 0x32 || color4.green != 0xBE || color4.blue != 0x44) { + throw Error(); + } + )JavaScript"); EXPECT_FALSE(pEngine->hasUncaughtException()); } TEST_F(ColorMapperJSProxyTest, GetNearestValue) { QScriptEngine* pEngine = createScriptEngine(); pEngine->evaluate( - "var mapper = new ColorMapper({" - " '#C50A08': 1," - " '#32BE44': 2," - " '#42D4F4': 3," - " '#F8D200': 4," - " '#0044FF': 5," - " '#AF00CC': 6," - " '#FCA6D7': 7," - " '#F2F2FF': 8," - "});" - "/* red */" - "if (mapper.getValueForNearestColor(0xFF0000) != 1) {" - " throw Error();" - "};" - "/* blue */" - "if (mapper.getValueForNearestColor(0x0000AA) != 5) {" - " throw Error();" - "};" - "/* white */" - "if (mapper.getValueForNearestColor(0xFFFFFF) != 8) {" - " throw Error();" - "};"); + R"JavaScript( + var mapper = new ColorMapper({ + '#C50A08': 1, + '#32BE44': 2, + '#42D4F4': 3, + '#F8D200': 4, + '#0044FF': 5, + '#AF00CC': 6, + '#FCA6D7': 7, + '#F2F2FF': 8, + }); + /* red */ + if (mapper.getValueForNearestColor(0xFF0000) != 1) { + throw Error(); + }; + /* blue */ + if (mapper.getValueForNearestColor(0x0000AA) != 5) { + throw Error(); + }; + /* white */ + if (mapper.getValueForNearestColor(0xFFFFFF) != 8) { + throw Error(); + }; + )JavaScript"); EXPECT_FALSE(pEngine->hasUncaughtException()); } From 714f4467b1d912edd2f9511bfc46507fa9f8d25a Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 11 Mar 2020 21:24:48 +0100 Subject: [PATCH 141/158] util/color/colorpalette: Return last color if color not in palette --- src/util/color/colorpalette.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/color/colorpalette.cpp b/src/util/color/colorpalette.cpp index 66824eb3a82..a606f8e73b4 100644 --- a/src/util/color/colorpalette.cpp +++ b/src/util/color/colorpalette.cpp @@ -41,8 +41,8 @@ mixxx::RgbColor ColorPalette::nextColor(mixxx::RgbColor color) const { mixxx::RgbColor ColorPalette::previousColor(mixxx::RgbColor color) const { int iIndex = indexOf(color); if (iIndex < 0) { - // Return first color if color not in palette - iIndex = 0; + // Return last color if color not in palette + iIndex = size() - 1; } else { iIndex = (iIndex + size() - 1) % size(); } From 8dca9a60f7e138a536d19410d3bec9a444063d3a Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 12 Mar 2020 09:32:15 +0100 Subject: [PATCH 142/158] controllers/colormapper: Simplify and speed up code in getNearestColor --- src/controllers/colormapper.cpp | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/controllers/colormapper.cpp b/src/controllers/colormapper.cpp index 11c9644dc2c..e308c7b1d83 100644 --- a/src/controllers/colormapper.cpp +++ b/src/controllers/colormapper.cpp @@ -32,34 +32,31 @@ double colorDistance(QRgb a, QRgb b) { QRgb ColorMapper::getNearestColor(QRgb desiredColor) { // If desired color is already in cache, use cache entry QMap::const_iterator i = m_cache.constFind(desiredColor); - QMap::const_iterator j; if (i != m_cache.constEnd()) { - j = m_availableColors.find(i.value()); - DEBUG_ASSERT(j != m_availableColors.constEnd()); + DEBUG_ASSERT(m_availableColors.contains(i.value())); kLogger.trace() << "ColorMapper cache hit for" << desiredColor << ":" - << "Color =" << j.key(); - return j.key(); + << "Color =" << i.value(); + return i.value(); } // Color is not cached - QMap::const_iterator nearestColorIterator; + QRgb nearestColor; double nearestColorDistance = qInf(); - for (j = m_availableColors.constBegin(); j != m_availableColors.constEnd(); j++) { + for (auto j = m_availableColors.constBegin(); j != m_availableColors.constEnd(); j++) { QRgb availableColor = j.key(); double distance = colorDistance(desiredColor, availableColor); if (distance < nearestColorDistance) { nearestColorDistance = distance; - nearestColorIterator = j; + nearestColor = j.key(); } } kLogger.trace() << "ColorMapper found matching color for" << desiredColor << ":" - << "Color =" << nearestColorIterator.key() << "," - << "Value =" << nearestColorIterator.value(); - m_cache.insert(desiredColor, nearestColorIterator.key()); - return nearestColorIterator.key(); + << "Color =" << nearestColor; + m_cache.insert(desiredColor, nearestColor); + return nearestColor; } QVariant ColorMapper::getValueForNearestColor(QRgb desiredColor) { From 9130b8056c548192af2f17bc675d84d3ec60ae9a Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 12 Mar 2020 09:34:11 +0100 Subject: [PATCH 143/158] controllers/midi-components: Change comment wording in output() --- res/controllers/midi-components-0.0.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/controllers/midi-components-0.0.js b/res/controllers/midi-components-0.0.js index 0773ffc3f39..54b8a385c0e 100644 --- a/res/controllers/midi-components-0.0.js +++ b/res/controllers/midi-components-0.0.js @@ -310,7 +310,7 @@ }, output: function(value) { var outval = this.outValueScale(value); - // WARNING: outputColor only handles hotcueColors + // NOTE: outputColor only handles hotcueColors // and there is no hotcueColor for turning the LED // off. So the `send()` function is responsible for turning the // actual LED off. From 4a79af31621410bebe458fb537e4f337cad6ae94 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Thu, 12 Mar 2020 09:35:19 +0100 Subject: [PATCH 144/158] controllers/midi-components: Print invalid colorCodes --- res/controllers/midi-components-0.0.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/controllers/midi-components-0.0.js b/res/controllers/midi-components-0.0.js index 54b8a385c0e..8a8da84719a 100644 --- a/res/controllers/midi-components-0.0.js +++ b/res/controllers/midi-components-0.0.js @@ -324,7 +324,7 @@ // Sends the color from the colorCode to the controller. This // method will not be called if no colorKey has been specified. if (colorCode === undefined || colorCode < 0) { - print("Ignoring invalid color code in outputColor()"); + print("Ignoring invalid color code '" + colorCode + "' in outputColor()"); return; } From 92df887d911d53246d360910f3866514019a2893 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Fri, 13 Mar 2020 13:07:28 +0100 Subject: [PATCH 145/158] engine/controls/cuecontrol: Prevent segfaults in slotHotcueColorChanged --- src/engine/controls/cuecontrol.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index ba5a1437857..d087506dbc4 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -1859,6 +1859,10 @@ void HotcueControl::slotHotcuePositionChanged(double newPosition) { } void HotcueControl::slotHotcueColorChanged(double newColor) { + if (!m_pCue) { + return; + } + mixxx::RgbColor::optional_t color = doubleToRgbColor(newColor); if (!color) { qWarning() << "slotHotcueColorChanged got invalid value:" << newColor; From be48247682d326082e225f6caa7749a32e57ba14 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Fri, 13 Mar 2020 21:38:45 +0100 Subject: [PATCH 146/158] widget/wcolorpicker: Simplify (re-)setSelectedColor logic --- src/widget/wcolorpicker.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/widget/wcolorpicker.cpp b/src/widget/wcolorpicker.cpp index 803142f2f77..dbd5dff7935 100644 --- a/src/widget/wcolorpicker.cpp +++ b/src/widget/wcolorpicker.cpp @@ -137,7 +137,7 @@ void WColorPicker::addColorButton(mixxx::RgbColor::optional_t color, QGridLayout void WColorPicker::resetSelectedColor() { // Unset currently selected color - int i; + int i = 0; if (m_selectedColor) { i = m_palette.indexOf(*m_selectedColor); if (i == -1) { @@ -146,11 +146,8 @@ void WColorPicker::resetSelectedColor() { if (m_colorOption == ColorOption::AllowNoColor) { i++; } - } else { - i = 0; - if (m_colorOption != ColorOption::AllowNoColor) { - return; - } + } else if (m_colorOption != ColorOption::AllowNoColor) { + return; } DEBUG_ASSERT(i < m_colorButtons.size()); @@ -170,7 +167,7 @@ void WColorPicker::setSelectedColor(mixxx::RgbColor::optional_t color) { m_selectedColor = color; - int i; + int i = 0; if (color) { i = m_palette.indexOf(*color); if (i == -1) { @@ -179,11 +176,8 @@ void WColorPicker::setSelectedColor(mixxx::RgbColor::optional_t color) { if (m_colorOption == ColorOption::AllowNoColor) { i++; } - } else { - i = 0; - if (m_colorOption != ColorOption::AllowNoColor) { - return; - } + } else if (m_colorOption != ColorOption::AllowNoColor) { + return; } DEBUG_ASSERT(i < m_colorButtons.size()); From b4855e0bccb2725d395802e931274f0cda47ec25 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Fri, 13 Mar 2020 21:40:26 +0100 Subject: [PATCH 147/158] widget/wwidget: Early exit for error case in getBackgroundColorRgba() --- src/widget/wwidget.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/widget/wwidget.cpp b/src/widget/wwidget.cpp index 5d523663139..801678a107a 100644 --- a/src/widget/wwidget.cpp +++ b/src/widget/wwidget.cpp @@ -39,10 +39,10 @@ WWidget::~WWidget() { } double WWidget::getBackgroundColorRgba() const { - if (m_backgroundColorRgba >= 0) { - return m_backgroundColorRgba; + if (m_backgroundColorRgba < 0) { + return -1; } - return -1; + return m_backgroundColorRgba; } void WWidget::setBackgroundColorRgba(double rgba) { From 4e943f89014dfea974723c2bfc5c2e57500ab13f Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sat, 14 Mar 2020 16:32:33 +0100 Subject: [PATCH 148/158] preferences/colorpalettesettings: Use QStringLiteral for regex --- src/preferences/colorpalettesettings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/preferences/colorpalettesettings.cpp b/src/preferences/colorpalettesettings.cpp index 964bd6917ec..0526be36653 100644 --- a/src/preferences/colorpalettesettings.cpp +++ b/src/preferences/colorpalettesettings.cpp @@ -4,7 +4,7 @@ namespace { const mixxx::RgbColor kColorBlack(0x000000); const QString kColorPaletteConfigGroup = QStringLiteral("[Config]"); const QString kColorPaletteGroup = QStringLiteral("[ColorPalette %1]"); -const QRegExp kColorPaletteGroupNameRegex("^\\[ColorPalette (.+)\\]$"); +const QRegExp kColorPaletteGroupNameRegex(QStringLiteral("^\\[ColorPalette (.+)\\]$")); const ConfigKey kHotcueColorPaletteConfigKey(kColorPaletteConfigGroup, QStringLiteral("HotcueColorPalette")); const ConfigKey kTrackColorPaletteConfigKey(kColorPaletteConfigGroup, QStringLiteral("TrackColorPalette")); From 0e18f19cde13541ca18460604d45ed0e3424dd58 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sat, 14 Mar 2020 17:22:08 +0100 Subject: [PATCH 149/158] preferences/colorpalettesettings: Use StringBuilder for group names --- src/preferences/colorpalettesettings.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/preferences/colorpalettesettings.cpp b/src/preferences/colorpalettesettings.cpp index 0526be36653..c0c70449846 100644 --- a/src/preferences/colorpalettesettings.cpp +++ b/src/preferences/colorpalettesettings.cpp @@ -3,7 +3,8 @@ namespace { const mixxx::RgbColor kColorBlack(0x000000); const QString kColorPaletteConfigGroup = QStringLiteral("[Config]"); -const QString kColorPaletteGroup = QStringLiteral("[ColorPalette %1]"); +const QString kColorPaletteGroupStart = QStringLiteral("[ColorPalette "); +const QString kColorPaletteGroupEnd = QStringLiteral("]"); const QRegExp kColorPaletteGroupNameRegex(QStringLiteral("^\\[ColorPalette (.+)\\]$")); const ConfigKey kHotcueColorPaletteConfigKey(kColorPaletteConfigGroup, QStringLiteral("HotcueColorPalette")); const ConfigKey kTrackColorPaletteConfigKey(kColorPaletteConfigGroup, QStringLiteral("TrackColorPalette")); @@ -22,7 +23,7 @@ ColorPalette ColorPaletteSettings::getColorPalette( const QString& name, const ColorPalette& defaultPalette) const { QList colorList; - const QString group = kColorPaletteGroup.arg(name); + const QString group = kColorPaletteGroupStart + name + kColorPaletteGroupEnd; for (const ConfigKey& key : m_pConfig->getKeysWithGroup(group)) { mixxx::RgbColor color = mixxx::RgbColor(m_pConfig->getValue(key, kColorBlack)); colorList.append(color); @@ -38,7 +39,7 @@ ColorPalette ColorPaletteSettings::getColorPalette( void ColorPaletteSettings::setColorPalette(const QString& name, const ColorPalette& colorPalette) { removePalette(name); - const QString group = kColorPaletteGroup.arg(name); + const QString group = kColorPaletteGroupStart + name + kColorPaletteGroupEnd; int numDigits = numberOfDecimalDigits(colorPalette.size() - 1); for (int index = 0; index < colorPalette.size(); ++index) { @@ -48,7 +49,7 @@ void ColorPaletteSettings::setColorPalette(const QString& name, const ColorPalet } void ColorPaletteSettings::removePalette(const QString& name) { - const QString group = kColorPaletteGroup.arg(name); + const QString group = kColorPaletteGroupStart + name + kColorPaletteGroupEnd; for (const ConfigKey& key : m_pConfig->getKeysWithGroup(group)) { m_pConfig->remove(key); } From dac09b254080ff40bbdba7c51bb34dfc2cacc623 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sat, 14 Mar 2020 17:22:55 +0100 Subject: [PATCH 150/158] preferences/colorpalettesettings: Prevent setting empty color palettes --- src/preferences/colorpalettesettings.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/preferences/colorpalettesettings.cpp b/src/preferences/colorpalettesettings.cpp index c0c70449846..39f73024f01 100644 --- a/src/preferences/colorpalettesettings.cpp +++ b/src/preferences/colorpalettesettings.cpp @@ -38,6 +38,11 @@ ColorPalette ColorPaletteSettings::getColorPalette( } void ColorPaletteSettings::setColorPalette(const QString& name, const ColorPalette& colorPalette) { + VERIFY_OR_DEBUG_ASSERT(!name.isEmpty()) { + qWarning() << "Palette name must not be empty!"; + return; + } + removePalette(name); const QString group = kColorPaletteGroupStart + name + kColorPaletteGroupEnd; From 64990252dc5c9383c76645fb8d1d853be2171c97 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sat, 14 Mar 2020 17:23:33 +0100 Subject: [PATCH 151/158] widget/wcolorpicker: Use const int for remainder --- src/widget/wcolorpicker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widget/wcolorpicker.cpp b/src/widget/wcolorpicker.cpp index dbd5dff7935..131e90b11f2 100644 --- a/src/widget/wcolorpicker.cpp +++ b/src/widget/wcolorpicker.cpp @@ -21,7 +21,7 @@ inline int idealColumnCount(int numItems) { int numColumns = 4; // Default in case kNumColumnsCandidates is empty int numColumnsRemainder = -1; for (const int numColumnsCandidate : kNumColumnsCandidates) { - int remainder = numItems % numColumnsCandidate; + const int remainder = numItems % numColumnsCandidate; if (remainder == 0) { numColumns = numColumnsCandidate; break; From 5380904c63834d917be963bf369fd4a928a69388 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sat, 14 Mar 2020 17:24:04 +0100 Subject: [PATCH 152/158] widget/wcolorpicker: Do not use else if after break --- src/widget/wcolorpicker.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/widget/wcolorpicker.cpp b/src/widget/wcolorpicker.cpp index 131e90b11f2..fb154720650 100644 --- a/src/widget/wcolorpicker.cpp +++ b/src/widget/wcolorpicker.cpp @@ -25,7 +25,8 @@ inline int idealColumnCount(int numItems) { if (remainder == 0) { numColumns = numColumnsCandidate; break; - } else if (remainder > numColumnsRemainder) { + } + if (remainder > numColumnsRemainder) { numColumnsRemainder = numColumnsCandidate; numColumns = numColumnsCandidate; } From c0fd0b4183922f621df15619e1735218f167c1f9 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sat, 14 Mar 2020 20:28:51 +0100 Subject: [PATCH 153/158] library/dao/cuedao: Fix loading of cue colors from DB As reported by @ywwg, all cues become black when they are loaded from the database. Investigation shows that the color is always 7 (the column index) instead of the actual value. --- src/library/dao/cuedao.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/library/dao/cuedao.cpp b/src/library/dao/cuedao.cpp index 6162a50dd93..c8576109d7d 100644 --- a/src/library/dao/cuedao.cpp +++ b/src/library/dao/cuedao.cpp @@ -78,7 +78,7 @@ CuePointer CueDAO::cueFromRow(const QSqlQuery& query) const { int length = record.value(record.indexOf("length")).toInt(); int hotcue = record.value(record.indexOf("hotcue")).toInt(); QString label = labelFromQVariant(record.value(record.indexOf("label"))); - mixxx::RgbColor::optional_t color = mixxx::RgbColor::fromQVariant(record.indexOf("color")); + mixxx::RgbColor::optional_t color = mixxx::RgbColor::fromQVariant(record.value(record.indexOf("color"))); VERIFY_OR_DEBUG_ASSERT(color) { return CuePointer(); } From 96ca1d209a4a662b62de4c6a79f4ac7ea045398d Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 15 Mar 2020 22:15:53 +0100 Subject: [PATCH 154/158] preferences/configobject: Make getKeysWithGroup() const --- src/preferences/configobject.cpp | 2 +- src/preferences/configobject.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/preferences/configobject.cpp b/src/preferences/configobject.cpp index 9a05c012548..d4961788772 100644 --- a/src/preferences/configobject.cpp +++ b/src/preferences/configobject.cpp @@ -227,7 +227,7 @@ QSet ConfigObject::getGroups() { } template -QList ConfigObject::getKeysWithGroup(QString group) { +QList ConfigObject::getKeysWithGroup(QString group) const { QWriteLocker lock(&m_valuesLock); QList filteredList; for (const ConfigKey& key : m_values.uniqueKeys()) { diff --git a/src/preferences/configobject.h b/src/preferences/configobject.h index a9ff720f0dd..93d1b242523 100644 --- a/src/preferences/configobject.h +++ b/src/preferences/configobject.h @@ -188,7 +188,7 @@ template class ConfigObject { } QSet getGroups(); - QList getKeysWithGroup(QString group); + QList getKeysWithGroup(QString group) const; protected: // We use QMap because we want a sorted list in mixxx.cfg From 827f6a04fde89be32077ccaa893963040a4a4baf Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 15 Mar 2020 22:16:24 +0100 Subject: [PATCH 155/158] preferences/colorpalettesettings: Make some methods const --- src/preferences/colorpalettesettings.cpp | 4 ++-- src/preferences/colorpalettesettings.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/preferences/colorpalettesettings.cpp b/src/preferences/colorpalettesettings.cpp index 39f73024f01..c477d69b71c 100644 --- a/src/preferences/colorpalettesettings.cpp +++ b/src/preferences/colorpalettesettings.cpp @@ -96,7 +96,7 @@ void ColorPaletteSettings::setTrackColorPalette(const ColorPalette& colorPalette setColorPalette(name, colorPalette); } -QSet ColorPaletteSettings::getColorPaletteNames() { +QSet ColorPaletteSettings::getColorPaletteNames() const { QSet names; for (const QString& group : m_pConfig->getGroups()) { int pos = kColorPaletteGroupNameRegex.indexIn(group); @@ -107,6 +107,6 @@ QSet ColorPaletteSettings::getColorPaletteNames() { return names; } -ConfigKey ColorPaletteSettings::keyForIndex(const QString& group, int index, int numDigits) { +ConfigKey ColorPaletteSettings::keyForIndex(const QString& group, int index, int numDigits) const { return ConfigKey(group, QString::number(index).rightJustified(numDigits, '0')); } diff --git a/src/preferences/colorpalettesettings.h b/src/preferences/colorpalettesettings.h index 12889661dca..070596848aa 100644 --- a/src/preferences/colorpalettesettings.h +++ b/src/preferences/colorpalettesettings.h @@ -18,9 +18,9 @@ class ColorPaletteSettings { ColorPalette getColorPalette(const QString& name, const ColorPalette& defaultPalette) const; void setColorPalette(const QString& name, const ColorPalette& colorPalette); void removePalette(const QString& name); - QSet getColorPaletteNames(); + QSet getColorPaletteNames() const; private: - ConfigKey keyForIndex(const QString& group, int index, int maxDigits); + ConfigKey keyForIndex(const QString& group, int index, int maxDigits) const; UserSettingsPointer m_pConfig; }; From e18f8d5e67518212c04f0d0f0b6d64596a8c2b05 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 15 Mar 2020 22:21:55 +0100 Subject: [PATCH 156/158] preferences/colorpalettesettings: Move keyForIndex into anon namespace --- src/preferences/colorpalettesettings.cpp | 8 ++++---- src/preferences/colorpalettesettings.h | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/preferences/colorpalettesettings.cpp b/src/preferences/colorpalettesettings.cpp index c477d69b71c..63976e4cbdb 100644 --- a/src/preferences/colorpalettesettings.cpp +++ b/src/preferences/colorpalettesettings.cpp @@ -17,6 +17,10 @@ int numberOfDecimalDigits(int number) { return numDigits; } +ConfigKey keyForIndex(const QString& group, int index, int numDigits) { + return ConfigKey(group, QString::number(index).rightJustified(numDigits, '0')); +} + } // anonymous namespace ColorPalette ColorPaletteSettings::getColorPalette( @@ -106,7 +110,3 @@ QSet ColorPaletteSettings::getColorPaletteNames() const { } return names; } - -ConfigKey ColorPaletteSettings::keyForIndex(const QString& group, int index, int numDigits) const { - return ConfigKey(group, QString::number(index).rightJustified(numDigits, '0')); -} diff --git a/src/preferences/colorpalettesettings.h b/src/preferences/colorpalettesettings.h index 070596848aa..39ce03e49e1 100644 --- a/src/preferences/colorpalettesettings.h +++ b/src/preferences/colorpalettesettings.h @@ -21,6 +21,5 @@ class ColorPaletteSettings { QSet getColorPaletteNames() const; private: - ConfigKey keyForIndex(const QString& group, int index, int maxDigits) const; UserSettingsPointer m_pConfig; }; From 243fb3237c0661fb4f1af18ea714a4f18ba4212e Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Mon, 16 Mar 2020 00:29:40 +0100 Subject: [PATCH 157/158] res/schema.xml: Fix cue colors from previous schema migrations --- res/schema.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/res/schema.xml b/res/schema.xml index a2a4a453d2d..5f332d04844 100644 --- a/res/schema.xml +++ b/res/schema.xml @@ -489,6 +489,10 @@ METADATA UPDATE cues SET color=0xFCA6D7 WHERE color=7; UPDATE cues SET color=0xF2F2FF WHERE color=8; + + UPDATE cues SET color = (color & 0xFFFFFF) WHERE color > 0xFFFFFF; From 49445940e44b266f4ad9c035540ab834ffdf5ef8 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Mon, 16 Mar 2020 16:20:18 +0100 Subject: [PATCH 158/158] res/controllers/midi-components: Add check for CO values > 0xFFFFFF --- res/controllers/midi-components-0.0.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/controllers/midi-components-0.0.js b/res/controllers/midi-components-0.0.js index 8a8da84719a..3a87fec128d 100644 --- a/res/controllers/midi-components-0.0.js +++ b/res/controllers/midi-components-0.0.js @@ -323,7 +323,7 @@ outputColor: function(colorCode) { // Sends the color from the colorCode to the controller. This // method will not be called if no colorKey has been specified. - if (colorCode === undefined || colorCode < 0) { + if (colorCode === undefined || colorCode < 0 || colorCode > 0xFFFFFF) { print("Ignoring invalid color code '" + colorCode + "' in outputColor()"); return; }