From 93c04517f8c7e9a8441cda5b12373be7d1f8dde4 Mon Sep 17 00:00:00 2001 From: Swiftb0y Date: Tue, 2 Oct 2018 16:31:38 +0200 Subject: [PATCH 01/56] added color column to properties dlg but UI and DB dont update --- src/library/dlgtrackinfo.cpp | 20 +++++++++++++++++--- src/library/dlgtrackinfo.ui | 5 +++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/library/dlgtrackinfo.cpp b/src/library/dlgtrackinfo.cpp index c0db2d815fe..5d88ea2c019 100644 --- a/src/library/dlgtrackinfo.cpp +++ b/src/library/dlgtrackinfo.cpp @@ -332,12 +332,15 @@ void DlgTrackInfo::populateCues(TrackPointer pTrack) { // Make the duration read only durationItem->setFlags(Qt::NoItemFlags); + QColor cueColor = pCue->getColor(); + m_cueMap[row] = pCue; cueTable->insertRow(row); cueTable->setItem(row, 0, new QTableWidgetItem(rowStr)); cueTable->setItem(row, 1, durationItem); cueTable->setItem(row, 2, new QTableWidgetItem(hotcue)); - cueTable->setItem(row, 3, new QTableWidgetItem(pCue->getLabel())); + cueTable->setItem(row, 3, new QTableWidgetItem(cueColor.name().toUpper())); + cueTable->setItem(row, 4, new QTableWidgetItem(pCue->getLabel())); row += 1; } cueTable->setSortingEnabled(true); @@ -381,9 +384,10 @@ void DlgTrackInfo::saveTrack() { for (int row = 0; row < cueTable->rowCount(); ++row) { QTableWidgetItem* rowItem = cueTable->item(row, 0); QTableWidgetItem* hotcueItem = cueTable->item(row, 2); - QTableWidgetItem* labelItem = cueTable->item(row, 3); + QTableWidgetItem* colorItem = cueTable->item(row, 3); + QTableWidgetItem* labelItem = cueTable->item(row, 4); - if (!rowItem || !hotcueItem || !labelItem) + if (!rowItem || !hotcueItem || !colorItem|| !labelItem) continue; int oldRow = rowItem->data(Qt::DisplayRole).toInt(); @@ -404,6 +408,16 @@ void DlgTrackInfo::saveTrack() { pCue->setHotCue(-1); } + QVariant vHotCueColor = colorItem->data(Qt::DisplayRole); + if (vHotcue.canConvert()) { + QString colorString = vHotcue.toString(); + auto color = QColor(colorString); + if (color.isValid()) { + pCue->setColor(color); + } + // do nothing for now. + } + QString label = labelItem->data(Qt::DisplayRole).toString(); pCue->setLabel(label); } diff --git a/src/library/dlgtrackinfo.ui b/src/library/dlgtrackinfo.ui index 665520572dc..79bfd39a6c1 100644 --- a/src/library/dlgtrackinfo.ui +++ b/src/library/dlgtrackinfo.ui @@ -820,6 +820,11 @@ Often results in higher quality beatgrids, but will not do well on tracks that h Hotcue + + + Color + + Label From e0d73a074f8c7b1cf3f566764adb4fb58d5e904d Mon Sep 17 00:00:00 2001 From: Swiftb0y Date: Thu, 4 Oct 2018 19:53:29 +0200 Subject: [PATCH 02/56] fixed functionality broken by previous commit. --- src/library/dlgtrackinfo.cpp | 2 +- src/waveform/renderers/waveformmarkproperties.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/library/dlgtrackinfo.cpp b/src/library/dlgtrackinfo.cpp index 5d88ea2c019..383970cf75a 100644 --- a/src/library/dlgtrackinfo.cpp +++ b/src/library/dlgtrackinfo.cpp @@ -410,7 +410,7 @@ void DlgTrackInfo::saveTrack() { QVariant vHotCueColor = colorItem->data(Qt::DisplayRole); if (vHotcue.canConvert()) { - QString colorString = vHotcue.toString(); + QString colorString = vHotCueColor.toString(); auto color = QColor(colorString); if (color.isValid()) { pCue->setColor(color); diff --git a/src/waveform/renderers/waveformmarkproperties.cpp b/src/waveform/renderers/waveformmarkproperties.cpp index 3efae649beb..0a9138bbf95 100644 --- a/src/waveform/renderers/waveformmarkproperties.cpp +++ b/src/waveform/renderers/waveformmarkproperties.cpp @@ -47,6 +47,7 @@ WaveformMarkProperties::WaveformMarkProperties(const QDomNode& node, const WaveformSignalColors& signalColors, int hotCue) { m_color = context.selectString(node, "Color"); + // TODO (Swiftb0y): get CuePointer and color for m_color instead of skin color. if (!m_color.isValid()) { // As a fallback, grab the color from the parent's AxesColor m_color = signalColors.getAxesColor(); From 29df355ce071d1d9fd9a8174e66de646e4990aad Mon Sep 17 00:00:00 2001 From: Swiftb0y Date: Sat, 6 Oct 2018 23:15:26 +0200 Subject: [PATCH 03/56] woverview waveformsmarks will now reflect their hotcue color --- src/widget/woverview.cpp | 28 +++++++++++++++++++++++++++- src/widget/woverview.h | 1 + 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index 4872d950f0d..2529a6ab805 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -230,6 +230,8 @@ void WOverview::slotLoadingTrack(TrackPointer pNewTrack, TrackPointer pOldTrack) this, SLOT(slotWaveformSummaryUpdated())); connect(pNewTrack.get(), SIGNAL(analyzerProgress(int)), this, SLOT(slotAnalyzerProgress(int))); + connect(pNewTrack.get(), SIGNAL(cuesUpdated(void)), + this, SLOT(onTrackCueChange(void))); slotAnalyzerProgress(pNewTrack->getAnalyzerProgress()); } else { @@ -247,7 +249,8 @@ void WOverview::onEndOfTrackChange(double v) { void WOverview::onMarkChanged(double /*v*/) { //qDebug() << "WOverview::onMarkChanged()" << v; - update(); + onTrackCueChange(); + //update(); } void WOverview::onMarkRangeChange(double /*v*/) { @@ -255,6 +258,29 @@ void WOverview::onMarkRangeChange(double /*v*/) { update(); } +// currently only updates the mark color but it could be easily extended. +void WOverview::onTrackCueChange(void) { + + const QList loadedCues = m_pCurrentTrack->getCuePoints(); + + for (CuePointer currentCue: loadedCues) { + + const WaveformMarkPointer currentMark = m_marks.getHotCueMark(currentCue->getHotCue()); + + if (currentMark && currentMark->isValid()) { + + WaveformMarkProperties markProperties = currentMark->getProperties(); + const QColor newColor = currentCue->getColor(); + + if (newColor != markProperties.m_color) { + markProperties.m_color = newColor; + currentMark->setProperties(markProperties); + } + } + } + update(); +} + void WOverview::mouseMoveEvent(QMouseEvent* e) { if (m_orientation == Qt::Horizontal) { m_iPos = math_clamp(e->x(), 0, width() - 1); diff --git a/src/widget/woverview.h b/src/widget/woverview.h index 952caf75130..aa644f3185a 100644 --- a/src/widget/woverview.h +++ b/src/widget/woverview.h @@ -84,6 +84,7 @@ class WOverview : public WWidget { void onMarkChanged(double v); void onMarkRangeChange(double v); + void onTrackCueChange(void); void slotWaveformSummaryUpdated(); void slotAnalyzerProgress(int progress); From 68efc42c8a30b44409bef498d46bb220f5f76e97 Mon Sep 17 00:00:00 2001 From: Swiftb0y Date: Sat, 6 Oct 2018 23:24:43 +0200 Subject: [PATCH 04/56] markproperties.m_textColor is now the same color as the mark itself; fixed codefactor issues --- src/widget/woverview.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index 2529a6ab805..e52c08851fb 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -260,20 +260,18 @@ void WOverview::onMarkRangeChange(double /*v*/) { // currently only updates the mark color but it could be easily extended. void WOverview::onTrackCueChange(void) { - const QList loadedCues = m_pCurrentTrack->getCuePoints(); for (CuePointer currentCue: loadedCues) { - const WaveformMarkPointer currentMark = m_marks.getHotCueMark(currentCue->getHotCue()); if (currentMark && currentMark->isValid()) { - WaveformMarkProperties markProperties = currentMark->getProperties(); const QColor newColor = currentCue->getColor(); - if (newColor != markProperties.m_color) { + if (newColor != markProperties.m_color || newColor != markProperties.m_textColor) { markProperties.m_color = newColor; + markProperties.m_textColor = newColor; currentMark->setProperties(markProperties); } } From 92d381dbcdd820acfac7ec0ae5b079a71886554e Mon Sep 17 00:00:00 2001 From: Swiftb0y Date: Sat, 13 Oct 2018 15:54:32 +0200 Subject: [PATCH 05/56] followed daschauers request to VERIFY_OR_DEBUG_ASSERT in a case --- src/library/dlgtrackinfo.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/library/dlgtrackinfo.cpp b/src/library/dlgtrackinfo.cpp index 383970cf75a..36a355cd837 100644 --- a/src/library/dlgtrackinfo.cpp +++ b/src/library/dlgtrackinfo.cpp @@ -387,8 +387,10 @@ void DlgTrackInfo::saveTrack() { QTableWidgetItem* colorItem = cueTable->item(row, 3); QTableWidgetItem* labelItem = cueTable->item(row, 4); - if (!rowItem || !hotcueItem || !colorItem|| !labelItem) + VERIFY_OR_DEBUG_ASSERT(!rowItem || !hotcueItem || !colorItem || !labelItem) { + qWarning() << "unable to retrieve cells from cueTable row"; continue; + } int oldRow = rowItem->data(Qt::DisplayRole).toInt(); CuePointer pCue(m_cueMap.value(oldRow, CuePointer())); From d8057bd81cf4981bf130ba33c3ea278ed451c464 Mon Sep 17 00:00:00 2001 From: Swiftb0y Date: Sat, 13 Oct 2018 16:02:54 +0200 Subject: [PATCH 06/56] followed uklotzde change requests in widget/woverview --- src/widget/woverview.cpp | 18 +++++++++++------- src/widget/woverview.h | 4 +++- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index e52c08851fb..86e6e19f729 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -230,8 +230,8 @@ void WOverview::slotLoadingTrack(TrackPointer pNewTrack, TrackPointer pOldTrack) this, SLOT(slotWaveformSummaryUpdated())); connect(pNewTrack.get(), SIGNAL(analyzerProgress(int)), this, SLOT(slotAnalyzerProgress(int))); - connect(pNewTrack.get(), SIGNAL(cuesUpdated(void)), - this, SLOT(onTrackCueChange(void))); + connect(pNewTrack.get(), SIGNAL(cuesUpdated()), + this, SLOT(receiveCuesUpdated())); slotAnalyzerProgress(pNewTrack->getAnalyzerProgress()); } else { @@ -249,8 +249,8 @@ void WOverview::onEndOfTrackChange(double v) { void WOverview::onMarkChanged(double /*v*/) { //qDebug() << "WOverview::onMarkChanged()" << v; - onTrackCueChange(); - //update(); + updateCues(m_pCurrentTrack->getCuePoints()); + update(); } void WOverview::onMarkRangeChange(double /*v*/) { @@ -259,8 +259,7 @@ void WOverview::onMarkRangeChange(double /*v*/) { } // currently only updates the mark color but it could be easily extended. -void WOverview::onTrackCueChange(void) { - const QList loadedCues = m_pCurrentTrack->getCuePoints(); +void WOverview::updateCues(const QList &loadedCues) { for (CuePointer currentCue: loadedCues) { const WaveformMarkPointer currentMark = m_marks.getHotCueMark(currentCue->getHotCue()); @@ -276,7 +275,12 @@ void WOverview::onTrackCueChange(void) { } } } - update(); +} + +// connecting the tracks cuesUpdated and onMarkChanged is not possible +// due to the incompatible signatures. This is a "wrapper" workaround +void WOverview::receiveCuesUpdated() { + onMarkChanged(0); } void WOverview::mouseMoveEvent(QMouseEvent* e) { diff --git a/src/widget/woverview.h b/src/widget/woverview.h index aa644f3185a..b61048fda09 100644 --- a/src/widget/woverview.h +++ b/src/widget/woverview.h @@ -84,7 +84,7 @@ class WOverview : public WWidget { void onMarkChanged(double v); void onMarkRangeChange(double v); - void onTrackCueChange(void); + void receiveCuesUpdated(); void slotWaveformSummaryUpdated(); void slotAnalyzerProgress(int progress); @@ -100,6 +100,8 @@ class WOverview : public WWidget { return (static_cast(position) + m_b) / m_a; } + void updateCues(const QList &loadedCues); + const QString m_group; UserSettingsPointer m_pConfig; ControlProxy* m_endOfTrackControl; From d4e0735b6e694b5eedc6b48bddbad97303b8237f Mon Sep 17 00:00:00 2001 From: Swiftb0y Date: Sun, 14 Oct 2018 15:50:35 +0200 Subject: [PATCH 07/56] fixed redundant blank line (codefactor complained) --- src/widget/woverview.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index 86e6e19f729..85405ed240a 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -260,7 +260,6 @@ void WOverview::onMarkRangeChange(double /*v*/) { // currently only updates the mark color but it could be easily extended. void WOverview::updateCues(const QList &loadedCues) { - for (CuePointer currentCue: loadedCues) { const WaveformMarkPointer currentMark = m_marks.getHotCueMark(currentCue->getHotCue()); From 2c253ff65b82cc204167a2709d66de5e17922e48 Mon Sep 17 00:00:00 2001 From: Swiftb0y Date: Sun, 14 Oct 2018 19:11:15 +0200 Subject: [PATCH 08/56] fixed inverted VERIFY_OR_DEBUG Statement --- src/library/dlgtrackinfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/library/dlgtrackinfo.cpp b/src/library/dlgtrackinfo.cpp index 36a355cd837..7030a5c0be8 100644 --- a/src/library/dlgtrackinfo.cpp +++ b/src/library/dlgtrackinfo.cpp @@ -387,7 +387,7 @@ void DlgTrackInfo::saveTrack() { QTableWidgetItem* colorItem = cueTable->item(row, 3); QTableWidgetItem* labelItem = cueTable->item(row, 4); - VERIFY_OR_DEBUG_ASSERT(!rowItem || !hotcueItem || !colorItem || !labelItem) { + VERIFY_OR_DEBUG_ASSERT(rowItem && hotcueItem && colorItem && labelItem) { qWarning() << "unable to retrieve cells from cueTable row"; continue; } From f57e682aa4b63c057e6478676bf8ec443bf30660 Mon Sep 17 00:00:00 2001 From: Swiftb0y Date: Sun, 14 Oct 2018 19:32:42 +0200 Subject: [PATCH 09/56] Added R/W ControlObject for the HotcueColor --- src/engine/cuecontrol.cpp | 26 ++++++++++++++++++++++++++ src/engine/cuecontrol.h | 5 +++++ 2 files changed, 31 insertions(+) diff --git a/src/engine/cuecontrol.cpp b/src/engine/cuecontrol.cpp index 6bd5c6cb835..f91f8b35794 100644 --- a/src/engine/cuecontrol.cpp +++ b/src/engine/cuecontrol.cpp @@ -299,6 +299,9 @@ void CueControl::trackCuesUpdated() { } else { // If the old hotcue is the same, then we only need to update pControl->setPosition(pCue->getPosition()); + // NOTE(Swiftb0y): I don't know if this is the smartest location to manage + // please suggest whether this should rather go somewhere else. + pControl->setColor(pCue->getColor()); } // Add the hotcue to the list of active hotcues active_hotcues.insert(hotcue); @@ -1018,6 +1021,14 @@ HotcueControl::HotcueControl(QString group, int i) m_hotcueEnabled = new ControlObject(keyForControl(i, "enabled")); m_hotcueEnabled->setReadOnly(); + // NOTE(Swiftb0y): since ControlObjects only deal with double values, + // the Color is stored as a QRgb (which is just a unsigned int + // representation of the color (AARRGGBB) + m_hotcueColor = new ControlObject(keyForControl(i, "color")); + connect(m_hotcueColor, SIGNAL(valueChanged(double)), + this, SLOT(slotHotcueColorChanged(double)), + Qt::DirectConnection); + m_hotcueSet = new ControlPushButton(keyForControl(i, "set")); connect(m_hotcueSet, SIGNAL(valueChanged(double)), this, SLOT(slotHotcueSet(double)), @@ -1057,6 +1068,7 @@ HotcueControl::HotcueControl(QString group, int i) HotcueControl::~HotcueControl() { delete m_hotcuePosition; delete m_hotcueEnabled; + delete m_hotcueColor; delete m_hotcueSet; delete m_hotcueGoto; delete m_hotcueGotoAndPlay; @@ -1099,6 +1111,11 @@ void HotcueControl::slotHotcuePositionChanged(double newPosition) { emit(hotcuePositionChanged(this, newPosition)); } +void HotcueControl::slotHotcueColorChanged(double newColor) { + m_pCue->setColor(QColor(static_cast(newColor))); + emit(hotcueColorChanged(this, newColor)); +} + double HotcueControl::getPosition() const { return m_hotcuePosition->get(); } @@ -1109,7 +1126,16 @@ 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 { + // QRgb is just an unsigned int representation of the + // color components (AARRGGBB) so conversion + // from double shouldn't be an issue + return QColor::fromRgb(static_cast(m_hotcueColor->get())); +} +void HotcueControl::setColor(QColor newColor) { + m_hotcueColor->set(static_cast(newColor.rgb())); +} void HotcueControl::resetCue() { // clear pCue first because we have a null check for valid data else where // in the code diff --git a/src/engine/cuecontrol.h b/src/engine/cuecontrol.h index 7b8faddb0cd..00a74dfe5ff 100644 --- a/src/engine/cuecontrol.h +++ b/src/engine/cuecontrol.h @@ -30,6 +30,8 @@ class HotcueControl : public QObject { void setCue(CuePointer pCue); void resetCue(); void setPosition(double position); + void setColor(QColor newColor); + QColor getColor() const; // Used for caching the preview state of this hotcue control. inline bool isPreviewing() { @@ -54,6 +56,7 @@ class HotcueControl : public QObject { void slotHotcueActivatePreview(double v); void slotHotcueClear(double v); void slotHotcuePositionChanged(double newPosition); + void slotHotcueColorChanged(double newColor); signals: void hotcueSet(HotcueControl* pHotcue, double v); @@ -64,6 +67,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 newColor); void hotcuePlay(double v); private: @@ -76,6 +80,7 @@ class HotcueControl : public QObject { // Hotcue state controls ControlObject* m_hotcuePosition; ControlObject* m_hotcueEnabled; + ControlObject* m_hotcueColor; // Hotcue button controls ControlObject* m_hotcueSet; ControlObject* m_hotcueGoto; From b0270ba0b5676b6832eeb385df5aa431a0847cef Mon Sep 17 00:00:00 2001 From: Swiftb0y Date: Thu, 18 Oct 2018 17:02:14 +0200 Subject: [PATCH 10/56] contrastLineColor of Markers now adapt to MarkerColor Brightness --- src/waveform/renderers/waveformrendermark.cpp | 4 +++- src/waveform/renderers/waveformrendermark.h | 11 ++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/waveform/renderers/waveformrendermark.cpp b/src/waveform/renderers/waveformrendermark.cpp index 4904e024bfb..6c4990e941e 100644 --- a/src/waveform/renderers/waveformrendermark.cpp +++ b/src/waveform/renderers/waveformrendermark.cpp @@ -224,7 +224,9 @@ void WaveformRenderMark::generateMarkImage(WaveformMark* pMark) { // Prepare colors for drawing of marker lines QColor lineColor = markProperties.m_color; lineColor.setAlpha(200); - QColor contrastLineColor(0,0,0,120); + QColor contrastLineColor = (brightness(lineColor) < 130) ? + QColor(255,255,255,120) : + QColor(0,0,0,120); // Draw marker lines if (m_waveformRenderer->getOrientation() == Qt::Horizontal) { diff --git a/src/waveform/renderers/waveformrendermark.h b/src/waveform/renderers/waveformrendermark.h index fd515478b5b..bc7d59ee213 100644 --- a/src/waveform/renderers/waveformrendermark.h +++ b/src/waveform/renderers/waveformrendermark.h @@ -5,6 +5,7 @@ #include "skin/skincontext.h" #include "util/class.h" +#include "util/math.h" #include "waveform/renderers/waveformmarkset.h" #include "waveform/renderers/waveformrendererabstract.h" #include "library/dao/cue.h" @@ -31,7 +32,15 @@ class WaveformRenderMark : public QObject, public WaveformRendererAbstract { private: void generateMarkImage(WaveformMark* pMark); - + // 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 + int brightness(QColor& c) { + return static_cast(sqrtf( + c.red() * c.red() * .241 + + c.green() * c.green() * .691 + + c.blue() * c.blue() * .068)); + }; WaveformMarkSet m_marks; DISALLOW_COPY_AND_ASSIGN(WaveformRenderMark); }; From 9833f67a54537de7503b48096744de279796d285 Mon Sep 17 00:00:00 2001 From: Swiftb0y Date: Fri, 19 Oct 2018 20:43:06 +0200 Subject: [PATCH 11/56] Removed Comment in cuecontrol.cpp --- src/engine/cuecontrol.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/engine/cuecontrol.cpp b/src/engine/cuecontrol.cpp index f91f8b35794..d0f2957f79b 100644 --- a/src/engine/cuecontrol.cpp +++ b/src/engine/cuecontrol.cpp @@ -299,8 +299,6 @@ void CueControl::trackCuesUpdated() { } else { // If the old hotcue is the same, then we only need to update pControl->setPosition(pCue->getPosition()); - // NOTE(Swiftb0y): I don't know if this is the smartest location to manage - // please suggest whether this should rather go somewhere else. pControl->setColor(pCue->getColor()); } // Add the hotcue to the list of active hotcues From d52f1070895ce066796865f10ee3ddd47b0ffd17 Mon Sep 17 00:00:00 2001 From: Swiftb0y Date: Sat, 20 Oct 2018 00:50:19 +0200 Subject: [PATCH 12/56] the marker number color is now set by the skin again, not the m_color --- src/widget/woverview.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index 85405ed240a..32fd0480f4c 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -269,7 +269,6 @@ void WOverview::updateCues(const QList &loadedCues) { if (newColor != markProperties.m_color || newColor != markProperties.m_textColor) { markProperties.m_color = newColor; - markProperties.m_textColor = newColor; currentMark->setProperties(markProperties); } } From c8c41507e8ee20070f8b80c7aff30c12ffd6b2bf Mon Sep 17 00:00:00 2001 From: Swiftb0y Date: Sat, 20 Oct 2018 00:54:15 +0200 Subject: [PATCH 13/56] moved brightness function to color.h; rendermark textColor adapts now --- src/util/color.h | 21 +++++++++++++++++++ .../renderers/waveformmarkproperties.cpp | 2 +- src/waveform/renderers/waveformrendermark.cpp | 9 ++++---- src/waveform/renderers/waveformrendermark.h | 13 +++--------- src/widget/woverview.h | 2 ++ 5 files changed, 32 insertions(+), 15 deletions(-) create mode 100644 src/util/color.h diff --git a/src/util/color.h b/src/util/color.h new file mode 100644 index 00000000000..6afbf4f7083 --- /dev/null +++ b/src/util/color.h @@ -0,0 +1,21 @@ +#ifndef COLOR_H +#define COLOR_H + +#include "util/math.h" + +#define BRIGHTNESS_TRESHOLD 130 + +// 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 +inline int brightness(int red, int green, int blue) { + return static_cast(sqrtf( + red * red * .241 + + green * green * .691 + + blue * blue * .068)); +}; +inline bool isDimmColor(int red, int green, int blue) { + return brightness(red,green,blue) < BRIGHTNESS_TRESHOLD; +} + +#endif /* COLOR_H */ diff --git a/src/waveform/renderers/waveformmarkproperties.cpp b/src/waveform/renderers/waveformmarkproperties.cpp index 0a9138bbf95..d3ee395d1a6 100644 --- a/src/waveform/renderers/waveformmarkproperties.cpp +++ b/src/waveform/renderers/waveformmarkproperties.cpp @@ -47,7 +47,7 @@ WaveformMarkProperties::WaveformMarkProperties(const QDomNode& node, const WaveformSignalColors& signalColors, int hotCue) { m_color = context.selectString(node, "Color"); - // TODO (Swiftb0y): get CuePointer and color for m_color instead of skin color. + // TODO (Swiftb0y): remove context.selectString because the color will be overriden by the cuepoints regardless if (!m_color.isValid()) { // As a fallback, grab the color from the parent's AxesColor m_color = signalColors.getAxesColor(); diff --git a/src/waveform/renderers/waveformrendermark.cpp b/src/waveform/renderers/waveformrendermark.cpp index 6c4990e941e..819297d7865 100644 --- a/src/waveform/renderers/waveformrendermark.cpp +++ b/src/waveform/renderers/waveformrendermark.cpp @@ -224,9 +224,10 @@ void WaveformRenderMark::generateMarkImage(WaveformMark* pMark) { // Prepare colors for drawing of marker lines QColor lineColor = markProperties.m_color; lineColor.setAlpha(200); - QColor contrastLineColor = (brightness(lineColor) < 130) ? - QColor(255,255,255,120) : - QColor(0,0,0,120); + bool markerBrightnessLow= isDimmColor(lineColor.red(),lineColor.green(),lineColor.blue()); + QColor contrastLineColor = markerBrightnessLow ? + QColor(255,255,255,180) : + QColor(0,0,0,180); // Draw marker lines if (m_waveformRenderer->getOrientation() == Qt::Horizontal) { @@ -297,7 +298,7 @@ void WaveformRenderMark::generateMarkImage(WaveformMark* pMark) { // Draw text painter.setBrush(QBrush(QColor(0,0,0,0))); painter.setFont(font); - painter.setPen(markProperties.m_textColor); + painter.setPen(markerBrightnessLow ? QColor(255,255,255,255) : QColor(0,0,0,255)); painter.drawText(labelRect, Qt::AlignCenter, label); } else //no text draw triangle diff --git a/src/waveform/renderers/waveformrendermark.h b/src/waveform/renderers/waveformrendermark.h index bc7d59ee213..5c2c4718290 100644 --- a/src/waveform/renderers/waveformrendermark.h +++ b/src/waveform/renderers/waveformrendermark.h @@ -5,7 +5,7 @@ #include "skin/skincontext.h" #include "util/class.h" -#include "util/math.h" +#include "util/color.h" #include "waveform/renderers/waveformmarkset.h" #include "waveform/renderers/waveformrendererabstract.h" #include "library/dao/cue.h" @@ -13,6 +13,7 @@ class WaveformRenderMark : public QObject, public WaveformRendererAbstract { Q_OBJECT + public: explicit WaveformRenderMark(WaveformWidgetRenderer* waveformWidgetRenderer); @@ -32,15 +33,7 @@ class WaveformRenderMark : public QObject, public WaveformRendererAbstract { private: void generateMarkImage(WaveformMark* pMark); - // 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 - int brightness(QColor& c) { - return static_cast(sqrtf( - c.red() * c.red() * .241 + - c.green() * c.green() * .691 + - c.blue() * c.blue() * .068)); - }; + WaveformMarkSet m_marks; DISALLOW_COPY_AND_ASSIGN(WaveformRenderMark); }; diff --git a/src/widget/woverview.h b/src/widget/woverview.h index b61048fda09..a114e3382a6 100644 --- a/src/widget/woverview.h +++ b/src/widget/woverview.h @@ -21,6 +21,8 @@ #include "track/track.h" #include "widget/wwidget.h" +#include "util/color.h" + #include "waveform/renderers/waveformsignalcolors.h" #include "waveform/renderers/waveformmarkset.h" #include "waveform/renderers/waveformmarkrange.h" From e58b361ef40850196a24032eaff9f75902e65e23 Mon Sep 17 00:00:00 2001 From: Swiftb0y Date: Sat, 20 Oct 2018 20:26:30 +0200 Subject: [PATCH 14/56] Color is now settable via ComboBox in trackpropertie cuepoints table. --- src/library/dlgtrackinfo.cpp | 93 ++++++++++++++++++++++++++++++++---- 1 file changed, 85 insertions(+), 8 deletions(-) diff --git a/src/library/dlgtrackinfo.cpp b/src/library/dlgtrackinfo.cpp index 7030a5c0be8..5c60e8967f1 100644 --- a/src/library/dlgtrackinfo.cpp +++ b/src/library/dlgtrackinfo.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "library/dlgtrackinfo.h" #include "sources/soundsourceproxy.h" @@ -11,9 +12,63 @@ #include "track/keyfactory.h" #include "track/keyutils.h" #include "util/duration.h" +#include "util/color.h" const int kFilterLength = 80; const int kMinBpm = 30; + +// NOTE(Swiftb0y): Maybe this should be defined somewhere more global/logical? + +const static QList ColorNames = { + QObject::tr("Red"), + QObject::tr("Green"), + QObject::tr("Yellow"), + QObject::tr("Blue"), + QObject::tr("Orange"), + QObject::tr("Purple"), + QObject::tr("Cyan"), + QObject::tr("Magenta"), + QObject::tr("Lime"), + QObject::tr("Pink"), + QObject::tr("Teal"), + QObject::tr("Lavender"), + QObject::tr("Brown"), + QObject::tr("Beige"), + QObject::tr("Maroon"), + QObject::tr("Mint"), + QObject::tr("Olive"), + QObject::tr("Apricot"), + QObject::tr("Navy"), + QObject::tr("Grey"), + QObject::tr("White"), + QObject::tr("Black"), +}; + +const static QList Colors = { + QColor("#E6194B"), + QColor("#3CB44B"), + QColor("#FFE119"), + QColor("#4363D8"), + QColor("#F58231"), + QColor("#911EB4"), + QColor("#42D4F4"), + QColor("#F032E6"), + QColor("#BFEF45"), + QColor("#FABEBE"), + QColor("#469990"), + QColor("#E6BEFF"), + QColor("#9A6324"), + QColor("#FFFAC8"), + QColor("#800000"), + QColor("#AAFFC3"), + QColor("#808000"), + QColor("#FFD8B1"), + QColor("#000075"), + QColor("#A9A9A9"), + QColor("#FFFFFF"), + QColor("#000000"), +}; + // Maximum allowed interval between beats (calculated from kMinBpm). const mixxx::Duration kMaxInterval = mixxx::Duration::fromMillis(1000.0 * (60.0 / kMinBpm)); @@ -35,6 +90,8 @@ void DlgTrackInfo::init() { cueTable->hideColumn(0); coverBox->insertWidget(1, m_pWCoverArtLabel); + RELEASE_ASSERT(ColorNames.length() == Colors.length()); + connect(btnNext, SIGNAL(clicked()), this, SLOT(slotNext())); connect(btnPrev, SIGNAL(clicked()), @@ -332,14 +389,35 @@ void DlgTrackInfo::populateCues(TrackPointer pTrack) { // Make the duration read only durationItem->setFlags(Qt::NoItemFlags); + + QComboBox* colorComboBox = new QComboBox(); + for (int i = 0 ; i < ColorNames.length() ;i++) { + const QColor color = Colors.at(i); + colorComboBox->addItem(ColorNames.at(i),color); + const QModelIndex idx = colorComboBox->model()->index(i, 0); + colorComboBox->model()->setData(idx, color, Qt::BackgroundColorRole); + // TODO (Swiftb0y): put color choosing function into util/color.h + colorComboBox->setItemData( + i, + isDimmColor( + color.red(), + color.green(), + color.blue()) ? + QColor(255,255,255,255) : + QColor(0,0,0,255), + Qt::TextColorRole); + + } QColor cueColor = pCue->getColor(); + colorComboBox->setCurrentIndex(Colors.contains(cueColor) ? Colors.indexOf(cueColor) : 0); m_cueMap[row] = pCue; cueTable->insertRow(row); cueTable->setItem(row, 0, new QTableWidgetItem(rowStr)); cueTable->setItem(row, 1, durationItem); cueTable->setItem(row, 2, new QTableWidgetItem(hotcue)); - cueTable->setItem(row, 3, new QTableWidgetItem(cueColor.name().toUpper())); + // cueTable->setItem(row, 3, new QTableWidgetItem(cueColor.name().toUpper())); + cueTable->setCellWidget(row, 3, colorComboBox); cueTable->setItem(row, 4, new QTableWidgetItem(pCue->getLabel())); row += 1; } @@ -384,10 +462,10 @@ void DlgTrackInfo::saveTrack() { for (int row = 0; row < cueTable->rowCount(); ++row) { QTableWidgetItem* rowItem = cueTable->item(row, 0); QTableWidgetItem* hotcueItem = cueTable->item(row, 2); - QTableWidgetItem* colorItem = cueTable->item(row, 3); + QWidget* colorWidget = cueTable->cellWidget(row, 3); QTableWidgetItem* labelItem = cueTable->item(row, 4); - VERIFY_OR_DEBUG_ASSERT(rowItem && hotcueItem && colorItem && labelItem) { + VERIFY_OR_DEBUG_ASSERT(rowItem && hotcueItem && colorWidget && labelItem) { qWarning() << "unable to retrieve cells from cueTable row"; continue; } @@ -410,15 +488,14 @@ void DlgTrackInfo::saveTrack() { pCue->setHotCue(-1); } - QVariant vHotCueColor = colorItem->data(Qt::DisplayRole); - if (vHotcue.canConvert()) { - QString colorString = vHotCueColor.toString(); - auto color = QColor(colorString); + auto colorComboBox = qobject_cast(colorWidget); + if (colorComboBox) { + const auto color = Colors.at(colorComboBox->currentIndex()); if (color.isValid()) { pCue->setColor(color); } - // do nothing for now. } + // do nothing for now. QString label = labelItem->data(Qt::DisplayRole).toString(); pCue->setLabel(label); From 2372bdfcf0f78ee699927dd21304fcb25a2877e6 Mon Sep 17 00:00:00 2001 From: Swiftb0y Date: Sat, 20 Oct 2018 23:28:57 +0200 Subject: [PATCH 15/56] added more utility functions to util/color.h --- src/library/dlgtrackinfo.cpp | 10 +---- src/util/color.h | 43 ++++++++++++++++--- src/waveform/renderers/waveformrendermark.cpp | 9 ++-- 3 files changed, 42 insertions(+), 20 deletions(-) diff --git a/src/library/dlgtrackinfo.cpp b/src/library/dlgtrackinfo.cpp index 5c60e8967f1..ee511743a89 100644 --- a/src/library/dlgtrackinfo.cpp +++ b/src/library/dlgtrackinfo.cpp @@ -397,15 +397,7 @@ void DlgTrackInfo::populateCues(TrackPointer pTrack) { const QModelIndex idx = colorComboBox->model()->index(i, 0); colorComboBox->model()->setData(idx, color, Qt::BackgroundColorRole); // TODO (Swiftb0y): put color choosing function into util/color.h - colorComboBox->setItemData( - i, - isDimmColor( - color.red(), - color.green(), - color.blue()) ? - QColor(255,255,255,255) : - QColor(0,0,0,255), - Qt::TextColorRole); + colorComboBox->setItemData(i, chooseContrastColor(color), Qt::TextColorRole); } QColor cueColor = pCue->getColor(); diff --git a/src/util/color.h b/src/util/color.h index 6afbf4f7083..1873961012f 100644 --- a/src/util/color.h +++ b/src/util/color.h @@ -3,19 +3,50 @@ #include "util/math.h" +#include + #define BRIGHTNESS_TRESHOLD 130 // 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 +// NOTE: the author did not take alpha transparency into account! inline int brightness(int red, int green, int blue) { - return static_cast(sqrtf( - red * red * .241 + - green * green * .691 + - blue * blue * .068)); + return static_cast(sqrtf( + red * red * .241 + + green * green * .691 + + blue * blue * .068) + ); }; -inline bool isDimmColor(int red, int green, int blue) { - return brightness(red,green,blue) < BRIGHTNESS_TRESHOLD; + +inline int brightness(QColor color) { + return brightness(color.red(), color.green(), color.red()); +} + +inline bool isDimmColor(QColor color) { + qDebug() << color.name(); + return brightness(color) < BRIGHTNESS_TRESHOLD; } +// if the ColorToChooseBy is darker than the global threshold, +// the Color from the second argument will be returned. + +inline QColor chooseColorByBrightnessB(bool precalculated, QColor dimmColor , QColor brightColor) { + return precalculated ? dimmColor : brightColor; +} + +inline QColor chooseColorByBrightness(QColor ColorToChooseBy, QColor dimmColor , QColor brightColor) { + return chooseColorByBrightnessB(isDimmColor(ColorToChooseBy), dimmColor, brightColor); +} + +inline QColor chooseContrastColor(QColor colorToChooseBy) { + return chooseColorByBrightness(colorToChooseBy, QColor(255,255,255,255), QColor(0,0,0,255)); +} + +inline QColor chooseContrastColorB(bool precalculated) { + return chooseColorByBrightnessB(precalculated, QColor(255,255,255,255), QColor(0,0,0,255)); +} + + + #endif /* COLOR_H */ diff --git a/src/waveform/renderers/waveformrendermark.cpp b/src/waveform/renderers/waveformrendermark.cpp index 819297d7865..e0a0c15303b 100644 --- a/src/waveform/renderers/waveformrendermark.cpp +++ b/src/waveform/renderers/waveformrendermark.cpp @@ -224,10 +224,9 @@ void WaveformRenderMark::generateMarkImage(WaveformMark* pMark) { // Prepare colors for drawing of marker lines QColor lineColor = markProperties.m_color; lineColor.setAlpha(200); - bool markerBrightnessLow= isDimmColor(lineColor.red(),lineColor.green(),lineColor.blue()); - QColor contrastLineColor = markerBrightnessLow ? - QColor(255,255,255,180) : - QColor(0,0,0,180); + bool markerBrightnessLow= isDimmColor(lineColor); + QColor contrastLineColor = chooseContrastColorB(markerBrightnessLow); + contrastLineColor.setAlpha(180); // Draw marker lines if (m_waveformRenderer->getOrientation() == Qt::Horizontal) { @@ -298,7 +297,7 @@ void WaveformRenderMark::generateMarkImage(WaveformMark* pMark) { // Draw text painter.setBrush(QBrush(QColor(0,0,0,0))); painter.setFont(font); - painter.setPen(markerBrightnessLow ? QColor(255,255,255,255) : QColor(0,0,0,255)); + painter.setPen(chooseContrastColorB(markerBrightnessLow)); painter.drawText(labelRect, Qt::AlignCenter, label); } else //no text draw triangle From 3088c1e6c7e0644125e8f164d9c50a7f03144146 Mon Sep 17 00:00:00 2001 From: Swiftb0y Date: Sun, 21 Oct 2018 11:38:59 +0200 Subject: [PATCH 16/56] minor changes for performance and codefactor --- src/library/dlgtrackinfo.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/library/dlgtrackinfo.cpp b/src/library/dlgtrackinfo.cpp index ee511743a89..6d90237d311 100644 --- a/src/library/dlgtrackinfo.cpp +++ b/src/library/dlgtrackinfo.cpp @@ -400,7 +400,7 @@ void DlgTrackInfo::populateCues(TrackPointer pTrack) { colorComboBox->setItemData(i, chooseContrastColor(color), Qt::TextColorRole); } - QColor cueColor = pCue->getColor(); + const QColor cueColor = pCue->getColor(); colorComboBox->setCurrentIndex(Colors.contains(cueColor) ? Colors.indexOf(cueColor) : 0); m_cueMap[row] = pCue; @@ -529,7 +529,6 @@ void DlgTrackInfo::unloadTrack(bool save) { } void DlgTrackInfo::clear() { - disconnect(this, SLOT(updateTrackMetadata())); m_pLoadedTrack.reset(); From 20ff8dcdb46ab313aa816576ed571ef77d3f0318 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Mon, 3 Dec 2018 00:58:03 +0100 Subject: [PATCH 17/56] Let skins override cue colors --- src/library/dlgtrackinfo.cpp | 71 +---- src/util/color.h | 275 ++++++++++++++++-- src/waveform/renderers/waveformrendermark.cpp | 22 +- src/waveform/renderers/waveformrendermark.h | 3 + 4 files changed, 275 insertions(+), 96 deletions(-) diff --git a/src/library/dlgtrackinfo.cpp b/src/library/dlgtrackinfo.cpp index 6d90237d311..64449b5aa75 100644 --- a/src/library/dlgtrackinfo.cpp +++ b/src/library/dlgtrackinfo.cpp @@ -17,58 +17,6 @@ const int kFilterLength = 80; const int kMinBpm = 30; -// NOTE(Swiftb0y): Maybe this should be defined somewhere more global/logical? - -const static QList ColorNames = { - QObject::tr("Red"), - QObject::tr("Green"), - QObject::tr("Yellow"), - QObject::tr("Blue"), - QObject::tr("Orange"), - QObject::tr("Purple"), - QObject::tr("Cyan"), - QObject::tr("Magenta"), - QObject::tr("Lime"), - QObject::tr("Pink"), - QObject::tr("Teal"), - QObject::tr("Lavender"), - QObject::tr("Brown"), - QObject::tr("Beige"), - QObject::tr("Maroon"), - QObject::tr("Mint"), - QObject::tr("Olive"), - QObject::tr("Apricot"), - QObject::tr("Navy"), - QObject::tr("Grey"), - QObject::tr("White"), - QObject::tr("Black"), -}; - -const static QList Colors = { - QColor("#E6194B"), - QColor("#3CB44B"), - QColor("#FFE119"), - QColor("#4363D8"), - QColor("#F58231"), - QColor("#911EB4"), - QColor("#42D4F4"), - QColor("#F032E6"), - QColor("#BFEF45"), - QColor("#FABEBE"), - QColor("#469990"), - QColor("#E6BEFF"), - QColor("#9A6324"), - QColor("#FFFAC8"), - QColor("#800000"), - QColor("#AAFFC3"), - QColor("#808000"), - QColor("#FFD8B1"), - QColor("#000075"), - QColor("#A9A9A9"), - QColor("#FFFFFF"), - QColor("#000000"), -}; - // Maximum allowed interval between beats (calculated from kMinBpm). const mixxx::Duration kMaxInterval = mixxx::Duration::fromMillis(1000.0 * (60.0 / kMinBpm)); @@ -90,8 +38,6 @@ void DlgTrackInfo::init() { cueTable->hideColumn(0); coverBox->insertWidget(1, m_pWCoverArtLabel); - RELEASE_ASSERT(ColorNames.length() == Colors.length()); - connect(btnNext, SIGNAL(clicked()), this, SLOT(slotNext())); connect(btnPrev, SIGNAL(clicked()), @@ -391,17 +337,19 @@ void DlgTrackInfo::populateCues(TrackPointer pTrack) { QComboBox* colorComboBox = new QComboBox(); - for (int i = 0 ; i < ColorNames.length() ;i++) { - const QColor color = Colors.at(i); - colorComboBox->addItem(ColorNames.at(i),color); + QList predefinedColors = Color::predefinedColors(); + for (int i = 0; i < predefinedColors.count(); i++) { + QColor color = predefinedColors.at(i); + colorComboBox->addItem(Color::displayName(color), color); const QModelIndex idx = colorComboBox->model()->index(i, 0); colorComboBox->model()->setData(idx, color, Qt::BackgroundColorRole); - // TODO (Swiftb0y): put color choosing function into util/color.h - colorComboBox->setItemData(i, chooseContrastColor(color), Qt::TextColorRole); + colorComboBox->setItemData(i, Color::chooseContrastColor(color), Qt::TextColorRole); } const QColor cueColor = pCue->getColor(); - colorComboBox->setCurrentIndex(Colors.contains(cueColor) ? Colors.indexOf(cueColor) : 0); + colorComboBox->setCurrentIndex(predefinedColors.contains(cueColor) + ? predefinedColors.indexOf(cueColor) + : 0); m_cueMap[row] = pCue; cueTable->insertRow(row); @@ -482,7 +430,8 @@ void DlgTrackInfo::saveTrack() { auto colorComboBox = qobject_cast(colorWidget); if (colorComboBox) { - const auto color = Colors.at(colorComboBox->currentIndex()); + QList predefinedColors = Color::predefinedColors(); + QColor color = predefinedColors.at(colorComboBox->currentIndex()); if (color.isValid()) { pCue->setColor(color); } diff --git a/src/util/color.h b/src/util/color.h index 1873961012f..b7525465465 100644 --- a/src/util/color.h +++ b/src/util/color.h @@ -2,51 +2,264 @@ #define COLOR_H #include "util/math.h" +#include "util/memory.h" #include +#include #define BRIGHTNESS_TRESHOLD 130 -// 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 -// NOTE: the author did not take alpha transparency into account! -inline int brightness(int red, int green, int blue) { - return static_cast(sqrtf( - red * red * .241 + - green * green * .691 + - blue * blue * .068) - ); +// Map the predefined colors to another color representation of them. +class ColorsRepresentation final { + public: + // Set a color representation for a given color + void setRepresentation(QColor color, QColor representation) { + colorNameMap[color.name()] = representation.name(); + } + + // Returns the representation of a color + QColor map(QColor color) const { + if (colorNameMap.contains(color.name())) { + return QColor(colorNameMap[color.name()]); + } + return color; + } + + private: + QHash colorNameMap; }; -inline int brightness(QColor color) { - return brightness(color.red(), color.green(), color.red()); -} +namespace Color { + static const QString Red = "#E6194B"; + static const QString Green = "#3CB44B"; + static const QString Yellow = "#FFE119"; + static const QString Blue = "#4363D8"; + static const QString Orange = "#F58231"; + static const QString Purple = "#911EB4"; + static const QString Cyan = "#42D4F4"; + static const QString Magenta = "#F032E6"; + static const QString Lime = "#BFEF45"; + static const QString Pink = "#FABEBE"; + static const QString Teal = "#469990"; + static const QString Lavender = "#E6BEFF"; + static const QString Brown = "#9A6324"; + static const QString Beige = "#FFFAC8"; + static const QString Maroon = "#800000"; + static const QString Mint = "#AAFFC3"; + static const QString Olive = "#808000"; + static const QString Apricot = "#FFD8B1"; + static const QString Navy = "#000075"; + static const QString Grey = "#A9A9A9"; + static const QString White = "#FFFFFF"; + static const QString Black = "#000000"; + + // Return a list with the predefined colors. + static QList predefinedColors() { + return QList { + QColor(Red), + QColor(Green), + QColor(Yellow), + QColor(Blue), + QColor(Orange), + QColor(Purple), + QColor(Cyan), + QColor(Magenta), + QColor(Lime), + QColor(Pink), + QColor(Teal), + QColor(Lavender), + QColor(Brown), + QColor(Beige), + QColor(Maroon), + QColor(Mint), + QColor(Olive), + QColor(Apricot), + QColor(Navy), + QColor(Grey), + QColor(White), + QColor(Black), + }; + }; + + // Return a list with the internal names of the predefined colors. + static QList predefinedColorsNames() { + return QList { + "Red", + "Green", + "Yellow", + "Blue", + "Orange", + "Purple", + "Cyan", + "Magenta", + "Lime", + "Pink", + "Teal", + "Lavender", + "Brown", + "Beige", + "Maroon", + "Mint", + "Olive", + "Apricot", + "Navy", + "Grey", + "White", + "Black", + }; + }; + + // Return a predefined color code from its internal name. + static QString predefinedColorFromName(QString name) { + if (name == "Red") { + return Red; + } else if (name == "Green") { + return Green; + } else if (name == "Yellow") { + return Yellow; + } else if (name == "Blue") { + return Blue; + } else if (name == "Orange") { + return Orange; + } else if (name == "Purple") { + return Purple; + } else if (name == "Cyan") { + return Cyan; + } else if (name == "Magenta") { + return Magenta; + } else if (name == "Lime") { + return Lime; + } else if (name == "Pink") { + return Pink; + } else if (name == "Teal") { + return Teal; + } else if (name == "Lavender") { + return Lavender; + } else if (name == "Brown") { + return Brown; + } else if (name == "Beige") { + return Beige; + } else if (name == "Maroon") { + return Maroon; + } else if (name == "Mint") { + return Mint; + } else if (name == "Olive") { + return Olive; + } else if (name == "Apricot") { + return Apricot; + } else if (name == "Navy") { + return Navy; + } else if (name == "Grey") { + return Grey; + } else if (name == "White") { + return White; + } else if (name == "Black") { + return Black; + } + return Black; + }; -inline bool isDimmColor(QColor color) { - qDebug() << color.name(); - return brightness(color) < BRIGHTNESS_TRESHOLD; -} + // Return the localized name of a predefined color. + // Returns "Undefined Color" if color is not a predefined color. + static QString displayName(QColor color) { + if (color.name().toUpper() == Red.toUpper()) { + return QObject::tr("Red"); + } else if (color.name().toUpper() == Green.toUpper()) { + return QObject::tr("Green"); + } else if (color.name().toUpper() == Yellow.toUpper()) { + return QObject::tr("Yellow"); + } else if (color.name().toUpper() == Blue.toUpper()) { + return QObject::tr("Blue"); + } else if (color.name().toUpper() == Orange.toUpper()) { + return QObject::tr("Orange"); + } else if (color.name().toUpper() == Purple.toUpper()) { + return QObject::tr("Purple"); + } else if (color.name().toUpper() == Cyan.toUpper()) { + return QObject::tr("Cyan"); + } else if (color.name().toUpper() == Magenta.toUpper()) { + return QObject::tr("Magenta"); + } else if (color.name().toUpper() == Lime.toUpper()) { + return QObject::tr("Lime"); + } else if (color.name().toUpper() == Pink.toUpper()) { + return QObject::tr("Pink"); + } else if (color.name().toUpper() == Teal.toUpper()) { + return QObject::tr("Teal"); + } else if (color.name().toUpper() == Lavender.toUpper()) { + return QObject::tr("Lavender"); + } else if (color.name().toUpper() == Brown.toUpper()) { + return QObject::tr("Brown"); + } else if (color.name().toUpper() == Beige.toUpper()) { + return QObject::tr("Beige"); + } else if (color.name().toUpper() == Maroon.toUpper()) { + return QObject::tr("Maroon"); + } else if (color.name().toUpper() == Mint.toUpper()) { + return QObject::tr("Mint"); + } else if (color.name().toUpper() == Olive.toUpper()) { + return QObject::tr("Olive"); + } else if (color.name().toUpper() == Apricot.toUpper()) { + return QObject::tr("Apricot"); + } else if (color.name().toUpper() == Navy.toUpper()) { + return QObject::tr("Navy"); + } else if (color.name().toUpper() == Grey.toUpper()) { + return QObject::tr("Grey"); + } else if (color.name().toUpper() == White.toUpper()) { + return QObject::tr("White"); + } else if (color.name().toUpper() == Black.toUpper()) { + return QObject::tr("Black"); + } + return QObject::tr("Undefined Color"); + }; -// if the ColorToChooseBy is darker than the global threshold, -// the Color from the second argument will be returned. + // Returns a new default colors representation, i.e. maps each default color to itself. + // Stores the color's name() property, e.g. "#A9A9A9" + static std::unique_ptr defaultRepresentation() { + std::unique_ptr representation = std::make_unique(); + for (QColor color : predefinedColors()) { + representation->setRepresentation(color, color); + } + return representation; + } -inline QColor chooseColorByBrightnessB(bool precalculated, QColor dimmColor , QColor brightColor) { - return precalculated ? dimmColor : brightColor; -} -inline QColor chooseColorByBrightness(QColor ColorToChooseBy, QColor dimmColor , QColor brightColor) { - return chooseColorByBrightnessB(isDimmColor(ColorToChooseBy), dimmColor, brightColor); -} + // 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 + // NOTE: the author did not take alpha transparency into account! + static inline int brightness(int red, int green, int blue) { + return static_cast(sqrtf( + red * red * .241 + + green * green * .691 + + blue * blue * .068) + ); + }; -inline QColor chooseContrastColor(QColor colorToChooseBy) { - return chooseColorByBrightness(colorToChooseBy, QColor(255,255,255,255), QColor(0,0,0,255)); -} + static inline int brightness(QColor color) { + return brightness(color.red(), color.green(), color.red()); + } -inline QColor chooseContrastColorB(bool precalculated) { - return chooseColorByBrightnessB(precalculated, QColor(255,255,255,255), QColor(0,0,0,255)); -} + static inline bool isDimmColor(QColor color) { +// qDebug() << color.name(); + return brightness(color) < BRIGHTNESS_TRESHOLD; + } + // if the ColorToChooseBy is darker than the global threshold, + // the Color from the second argument will be returned. + static inline QColor chooseColorByBrightnessB(bool precalculated, QColor dimmColor , QColor brightColor) { + return precalculated ? dimmColor : brightColor; + } + static inline QColor chooseColorByBrightness(QColor ColorToChooseBy, QColor dimmColor , QColor brightColor) { + return chooseColorByBrightnessB(isDimmColor(ColorToChooseBy), dimmColor, brightColor); + } + + static inline QColor chooseContrastColor(QColor colorToChooseBy) { + return chooseColorByBrightness(colorToChooseBy, QColor(255,255,255,255), QColor(0,0,0,255)); + } + + static inline QColor chooseContrastColorB(bool precalculated) { + return chooseColorByBrightnessB(precalculated, QColor(255,255,255,255), QColor(0,0,0,255)); + } + +}; #endif /* COLOR_H */ diff --git a/src/waveform/renderers/waveformrendermark.cpp b/src/waveform/renderers/waveformrendermark.cpp index e0a0c15303b..2adbd857b70 100644 --- a/src/waveform/renderers/waveformrendermark.cpp +++ b/src/waveform/renderers/waveformrendermark.cpp @@ -6,6 +6,7 @@ #include "control/controlproxy.h" #include "track/track.h" +#include "util/color.h" #include "waveform/renderers/waveformwidgetrenderer.h" #include "waveform/waveform.h" #include "widget/wskincolor.h" @@ -22,6 +23,7 @@ WaveformRenderMark::WaveformRenderMark( } void WaveformRenderMark::setup(const QDomNode& node, const SkinContext& context) { + setupColorsRepresentation(node, context); m_marks.setup(m_waveformRenderer->getGroup(), node, context, *m_waveformRenderer->getWaveformSignalColors()); } @@ -108,7 +110,7 @@ void WaveformRenderMark::slotCuesUpdated() { } QString newLabel = pCue->getLabel(); - QColor newColor = pCue->getColor(); + QColor newColor = m_pPredefinedColorsRepresentation->map(pCue->getColor()); // Here we assume no two cues can have the same hotcue assigned, // because WaveformMarkSet stores one mark for each hotcue. @@ -224,8 +226,8 @@ void WaveformRenderMark::generateMarkImage(WaveformMark* pMark) { // Prepare colors for drawing of marker lines QColor lineColor = markProperties.m_color; lineColor.setAlpha(200); - bool markerBrightnessLow= isDimmColor(lineColor); - QColor contrastLineColor = chooseContrastColorB(markerBrightnessLow); + bool markerBrightnessLow= Color::isDimmColor(lineColor); + QColor contrastLineColor = Color::chooseContrastColorB(markerBrightnessLow); contrastLineColor.setAlpha(180); // Draw marker lines @@ -297,7 +299,7 @@ void WaveformRenderMark::generateMarkImage(WaveformMark* pMark) { // Draw text painter.setBrush(QBrush(QColor(0,0,0,0))); painter.setFont(font); - painter.setPen(chooseContrastColorB(markerBrightnessLow)); + painter.setPen(Color::chooseContrastColorB(markerBrightnessLow)); painter.drawText(labelRect, Qt::AlignCenter, label); } else //no text draw triangle @@ -370,3 +372,15 @@ void WaveformRenderMark::generateMarkImage(WaveformMark* pMark) { painter.drawLine(middle + 1, lineTop, middle + 1, lineBottom); } } + +void WaveformRenderMark::setupColorsRepresentation(const QDomNode& node, const SkinContext& context) { + m_pPredefinedColorsRepresentation = Color::defaultRepresentation(); + + for (QString colorName : Color::predefinedColorsNames()) { + QColor representation = context.selectColor(node, colorName); + if (representation.isValid()) { + QString colorCode = Color::predefinedColorFromName(colorName); + m_pPredefinedColorsRepresentation->setRepresentation(colorCode, representation); + } + } +} diff --git a/src/waveform/renderers/waveformrendermark.h b/src/waveform/renderers/waveformrendermark.h index 5c2c4718290..ee618cebaa8 100644 --- a/src/waveform/renderers/waveformrendermark.h +++ b/src/waveform/renderers/waveformrendermark.h @@ -33,6 +33,9 @@ class WaveformRenderMark : public QObject, public WaveformRendererAbstract { private: void generateMarkImage(WaveformMark* pMark); + void setupColorsRepresentation(const QDomNode& node, const SkinContext& context); + + std::unique_ptr m_pPredefinedColorsRepresentation; WaveformMarkSet m_marks; DISALLOW_COPY_AND_ASSIGN(WaveformRenderMark); From 1b460cfe9c8833aa777aa4584e775df3e2252c5c Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Tue, 4 Dec 2018 00:50:29 +0100 Subject: [PATCH 18/56] Add example, revert before merge. --- res/skins/Deere/deck_visual_row.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/res/skins/Deere/deck_visual_row.xml b/res/skins/Deere/deck_visual_row.xml index 8601e8158fe..e469dfea8a1 100644 --- a/res/skins/Deere/deck_visual_row.xml +++ b/res/skins/Deere/deck_visual_row.xml @@ -26,6 +26,8 @@ + #00FFFF + #FF0000 #ffffff #00FF00 From ca30b3bc34a6c91632a5fee123612fbcd0ef7cfd Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Fri, 28 Dec 2018 20:08:51 +0100 Subject: [PATCH 19/56] Improve color methods efficiency --- src/util/color.h | 227 +++++++++--------- src/waveform/renderers/waveformrendermark.cpp | 6 +- 2 files changed, 117 insertions(+), 116 deletions(-) diff --git a/src/util/color.h b/src/util/color.h index b7525465465..f8b94c2adc7 100644 --- a/src/util/color.h +++ b/src/util/color.h @@ -30,130 +30,131 @@ class ColorsRepresentation final { }; namespace Color { - static const QString Red = "#E6194B"; - static const QString Green = "#3CB44B"; - static const QString Yellow = "#FFE119"; - static const QString Blue = "#4363D8"; - static const QString Orange = "#F58231"; - static const QString Purple = "#911EB4"; - static const QString Cyan = "#42D4F4"; - static const QString Magenta = "#F032E6"; - static const QString Lime = "#BFEF45"; - static const QString Pink = "#FABEBE"; - static const QString Teal = "#469990"; - static const QString Lavender = "#E6BEFF"; - static const QString Brown = "#9A6324"; - static const QString Beige = "#FFFAC8"; - static const QString Maroon = "#800000"; - static const QString Mint = "#AAFFC3"; - static const QString Olive = "#808000"; - static const QString Apricot = "#FFD8B1"; - static const QString Navy = "#000075"; - static const QString Grey = "#A9A9A9"; - static const QString White = "#FFFFFF"; - static const QString Black = "#000000"; + static const QColor Red = QColor("#E6194B"); + static const QColor Green = QColor("#3CB44B"); + static const QColor Yellow = QColor("#FFE119"); + static const QColor Blue = QColor("#4363D8"); + static const QColor Orange = QColor("#F58231"); + static const QColor Purple = QColor("#911EB4"); + static const QColor Cyan = QColor("#42D4F4"); + static const QColor Magenta = QColor("#F032E6"); + static const QColor Lime = QColor("#BFEF45"); + static const QColor Pink = QColor("#FABEBE"); + static const QColor Teal = QColor("#469990"); + static const QColor Lavender = QColor("#E6BEFF"); + static const QColor Brown = QColor("#9A6324"); + static const QColor Beige = QColor("#FFFAC8"); + static const QColor Maroon = QColor("#800000"); + static const QColor Mint = QColor("#AAFFC3"); + static const QColor Olive = QColor("#808000"); + static const QColor Apricot = QColor("#FFD8B1"); + static const QColor Navy = QColor("#000075"); + static const QColor Grey = QColor("#A9A9A9"); + static const QColor White = QColor("#FFFFFF"); + static const QColor Black = QColor("#000000"); // Return a list with the predefined colors. static QList predefinedColors() { return QList { - QColor(Red), - QColor(Green), - QColor(Yellow), - QColor(Blue), - QColor(Orange), - QColor(Purple), - QColor(Cyan), - QColor(Magenta), - QColor(Lime), - QColor(Pink), - QColor(Teal), - QColor(Lavender), - QColor(Brown), - QColor(Beige), - QColor(Maroon), - QColor(Mint), - QColor(Olive), - QColor(Apricot), - QColor(Navy), - QColor(Grey), - QColor(White), - QColor(Black), + Red, + Green, + Yellow, + Blue, + Orange, + Purple, + Cyan, + Magenta, + Lime, + Pink, + Teal, + Lavender, + Brown, + Beige, + Maroon, + Mint, + Olive, + Apricot, + Navy, + Grey, + White, + Black, }; }; // Return a list with the internal names of the predefined colors. - static QList predefinedColorsNames() { - return QList { - "Red", - "Green", - "Yellow", - "Blue", - "Orange", - "Purple", - "Cyan", - "Magenta", - "Lime", - "Pink", - "Teal", - "Lavender", - "Brown", - "Beige", - "Maroon", - "Mint", - "Olive", - "Apricot", - "Navy", - "Grey", - "White", - "Black", + static QList predefinedColorsNames() { + return QList { + QLatin1String("Red"), + QLatin1String("Green"), + QLatin1String("Yellow"), + QLatin1String("Blue"), + QLatin1String("Orange"), + QLatin1String("Purple"), + QLatin1String("Cyan"), + QLatin1String("Magenta"), + QLatin1String("Lime"), + QLatin1String("Pink"), + QLatin1String("Teal"), + QLatin1String("Lavender"), + QLatin1String("Brown"), + QLatin1String("Beige"), + QLatin1String("Maroon"), + QLatin1String("Mint"), + QLatin1String("Olive"), + QLatin1String("Apricot"), + QLatin1String("Navy"), + QLatin1String("Grey"), + QLatin1String("White"), + QLatin1String("Black"), }; }; // Return a predefined color code from its internal name. - static QString predefinedColorFromName(QString name) { - if (name == "Red") { + // TODO: use literals here + static QColor predefinedColorFromName(QLatin1String name) { + if (name == QLatin1String("Red")) { return Red; - } else if (name == "Green") { + } else if (name == QLatin1String("Green")) { return Green; - } else if (name == "Yellow") { + } else if (name == QLatin1String("Yellow")) { return Yellow; - } else if (name == "Blue") { + } else if (name == QLatin1String("Blue")) { return Blue; - } else if (name == "Orange") { + } else if (name == QLatin1String("Orange")) { return Orange; - } else if (name == "Purple") { + } else if (name == QLatin1String("Purple")) { return Purple; - } else if (name == "Cyan") { + } else if (name == QLatin1String("Cyan")) { return Cyan; - } else if (name == "Magenta") { + } else if (name == QLatin1String("Magenta")) { return Magenta; - } else if (name == "Lime") { + } else if (name == QLatin1String("Lime")) { return Lime; - } else if (name == "Pink") { + } else if (name == QLatin1String("Pink")) { return Pink; - } else if (name == "Teal") { + } else if (name == QLatin1String("Teal")) { return Teal; - } else if (name == "Lavender") { + } else if (name == QLatin1String("Lavender")) { return Lavender; - } else if (name == "Brown") { + } else if (name == QLatin1String("Brown")) { return Brown; - } else if (name == "Beige") { + } else if (name == QLatin1String("Beige")) { return Beige; - } else if (name == "Maroon") { + } else if (name == QLatin1String("Maroon")) { return Maroon; - } else if (name == "Mint") { + } else if (name == QLatin1String("Mint")) { return Mint; - } else if (name == "Olive") { + } else if (name == QLatin1String("Olive")) { return Olive; - } else if (name == "Apricot") { + } else if (name == QLatin1String("Apricot")) { return Apricot; - } else if (name == "Navy") { + } else if (name == QLatin1String("Navy")) { return Navy; - } else if (name == "Grey") { + } else if (name == QLatin1String("Grey")) { return Grey; - } else if (name == "White") { + } else if (name == QLatin1String("White")) { return White; - } else if (name == "Black") { + } else if (name == QLatin1String("Black")) { return Black; } return Black; @@ -162,49 +163,49 @@ namespace Color { // Return the localized name of a predefined color. // Returns "Undefined Color" if color is not a predefined color. static QString displayName(QColor color) { - if (color.name().toUpper() == Red.toUpper()) { + if (color == Red) { return QObject::tr("Red"); - } else if (color.name().toUpper() == Green.toUpper()) { + } else if (color == Green) { return QObject::tr("Green"); - } else if (color.name().toUpper() == Yellow.toUpper()) { + } else if (color == Yellow) { return QObject::tr("Yellow"); - } else if (color.name().toUpper() == Blue.toUpper()) { + } else if (color == Blue) { return QObject::tr("Blue"); - } else if (color.name().toUpper() == Orange.toUpper()) { + } else if (color == Orange) { return QObject::tr("Orange"); - } else if (color.name().toUpper() == Purple.toUpper()) { + } else if (color == Purple) { return QObject::tr("Purple"); - } else if (color.name().toUpper() == Cyan.toUpper()) { + } else if (color == Cyan) { return QObject::tr("Cyan"); - } else if (color.name().toUpper() == Magenta.toUpper()) { + } else if (color == Magenta) { return QObject::tr("Magenta"); - } else if (color.name().toUpper() == Lime.toUpper()) { + } else if (color == Lime) { return QObject::tr("Lime"); - } else if (color.name().toUpper() == Pink.toUpper()) { + } else if (color == Pink) { return QObject::tr("Pink"); - } else if (color.name().toUpper() == Teal.toUpper()) { + } else if (color == Teal) { return QObject::tr("Teal"); - } else if (color.name().toUpper() == Lavender.toUpper()) { + } else if (color == Lavender) { return QObject::tr("Lavender"); - } else if (color.name().toUpper() == Brown.toUpper()) { + } else if (color == Brown) { return QObject::tr("Brown"); - } else if (color.name().toUpper() == Beige.toUpper()) { + } else if (color == Beige) { return QObject::tr("Beige"); - } else if (color.name().toUpper() == Maroon.toUpper()) { + } else if (color == Maroon) { return QObject::tr("Maroon"); - } else if (color.name().toUpper() == Mint.toUpper()) { + } else if (color == Mint) { return QObject::tr("Mint"); - } else if (color.name().toUpper() == Olive.toUpper()) { + } else if (color == Olive) { return QObject::tr("Olive"); - } else if (color.name().toUpper() == Apricot.toUpper()) { + } else if (color == Apricot) { return QObject::tr("Apricot"); - } else if (color.name().toUpper() == Navy.toUpper()) { + } else if (color == Navy){ return QObject::tr("Navy"); - } else if (color.name().toUpper() == Grey.toUpper()) { + } else if (color == Grey) { return QObject::tr("Grey"); - } else if (color.name().toUpper() == White.toUpper()) { + } else if (color == White) { return QObject::tr("White"); - } else if (color.name().toUpper() == Black.toUpper()) { + } else if (color == Black) { return QObject::tr("Black"); } return QObject::tr("Undefined Color"); diff --git a/src/waveform/renderers/waveformrendermark.cpp b/src/waveform/renderers/waveformrendermark.cpp index 2adbd857b70..44e3ff06af4 100644 --- a/src/waveform/renderers/waveformrendermark.cpp +++ b/src/waveform/renderers/waveformrendermark.cpp @@ -376,11 +376,11 @@ void WaveformRenderMark::generateMarkImage(WaveformMark* pMark) { void WaveformRenderMark::setupColorsRepresentation(const QDomNode& node, const SkinContext& context) { m_pPredefinedColorsRepresentation = Color::defaultRepresentation(); - for (QString colorName : Color::predefinedColorsNames()) { + for (QLatin1String colorName : Color::predefinedColorsNames()) { QColor representation = context.selectColor(node, colorName); if (representation.isValid()) { - QString colorCode = Color::predefinedColorFromName(colorName); - m_pPredefinedColorsRepresentation->setRepresentation(colorCode, representation); + QColor originalColor = Color::predefinedColorFromName(colorName); + m_pPredefinedColorsRepresentation->setRepresentation(originalColor, representation); } } } From b194d21ddc322477710958ce46f6d366c3a26eb3 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Fri, 28 Dec 2018 20:23:53 +0100 Subject: [PATCH 20/56] Rename Color::defaultRepresentation() to makeDefaultRepresentation() --- src/util/color.h | 2 +- src/waveform/renderers/waveformrendermark.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/color.h b/src/util/color.h index f8b94c2adc7..cf513c7021c 100644 --- a/src/util/color.h +++ b/src/util/color.h @@ -213,7 +213,7 @@ namespace Color { // Returns a new default colors representation, i.e. maps each default color to itself. // Stores the color's name() property, e.g. "#A9A9A9" - static std::unique_ptr defaultRepresentation() { + static std::unique_ptr makeDefaultRepresentation() { std::unique_ptr representation = std::make_unique(); for (QColor color : predefinedColors()) { representation->setRepresentation(color, color); diff --git a/src/waveform/renderers/waveformrendermark.cpp b/src/waveform/renderers/waveformrendermark.cpp index 44e3ff06af4..68746c4c8b8 100644 --- a/src/waveform/renderers/waveformrendermark.cpp +++ b/src/waveform/renderers/waveformrendermark.cpp @@ -374,7 +374,7 @@ void WaveformRenderMark::generateMarkImage(WaveformMark* pMark) { } void WaveformRenderMark::setupColorsRepresentation(const QDomNode& node, const SkinContext& context) { - m_pPredefinedColorsRepresentation = Color::defaultRepresentation(); + m_pPredefinedColorsRepresentation = Color::makeDefaultRepresentation(); for (QLatin1String colorName : Color::predefinedColorsNames()) { QColor representation = context.selectColor(node, colorName); From 54798f3c5d0d9026123899204a895369683093aa Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Fri, 28 Dec 2018 20:56:50 +0100 Subject: [PATCH 21/56] Let skins override cue colors on overview --- src/waveform/renderers/waveformrendermark.cpp | 4 ++-- src/waveform/renderers/waveformrendermark.h | 2 +- src/widget/woverview.cpp | 16 +++++++++++++++- src/widget/woverview.h | 2 ++ 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/waveform/renderers/waveformrendermark.cpp b/src/waveform/renderers/waveformrendermark.cpp index 68746c4c8b8..33e4c56252b 100644 --- a/src/waveform/renderers/waveformrendermark.cpp +++ b/src/waveform/renderers/waveformrendermark.cpp @@ -23,7 +23,7 @@ WaveformRenderMark::WaveformRenderMark( } void WaveformRenderMark::setup(const QDomNode& node, const SkinContext& context) { - setupColorsRepresentation(node, context); + setupCueColorsRepresentation(node, context); m_marks.setup(m_waveformRenderer->getGroup(), node, context, *m_waveformRenderer->getWaveformSignalColors()); } @@ -373,7 +373,7 @@ void WaveformRenderMark::generateMarkImage(WaveformMark* pMark) { } } -void WaveformRenderMark::setupColorsRepresentation(const QDomNode& node, const SkinContext& context) { +void WaveformRenderMark::setupCueColorsRepresentation(const QDomNode& node, const SkinContext& context) { m_pPredefinedColorsRepresentation = Color::makeDefaultRepresentation(); for (QLatin1String colorName : Color::predefinedColorsNames()) { diff --git a/src/waveform/renderers/waveformrendermark.h b/src/waveform/renderers/waveformrendermark.h index ee618cebaa8..34bbc45dde6 100644 --- a/src/waveform/renderers/waveformrendermark.h +++ b/src/waveform/renderers/waveformrendermark.h @@ -33,7 +33,7 @@ class WaveformRenderMark : public QObject, public WaveformRendererAbstract { private: void generateMarkImage(WaveformMark* pMark); - void setupColorsRepresentation(const QDomNode& node, const SkinContext& context); + void setupCueColorsRepresentation(const QDomNode& node, const SkinContext& context); std::unique_ptr m_pPredefinedColorsRepresentation; diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index 32fd0480f4c..6e0c0e744a9 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -26,6 +26,7 @@ #include "wskincolor.h" #include "widget/controlwidgetconnection.h" #include "track/track.h" +#include "util/color.h" #include "util/math.h" #include "util/timer.h" #include "util/dnd.h" @@ -84,6 +85,7 @@ void WOverview::setup(const QDomNode& node, const SkinContext& context) { } // setup hotcues and cue and loop(s) + setupCueColorsRepresentation(node, context); m_marks.setup(m_group, node, context, m_signalColors); for (const auto& pMark: m_marks) { @@ -265,7 +267,7 @@ void WOverview::updateCues(const QList &loadedCues) { if (currentMark && currentMark->isValid()) { WaveformMarkProperties markProperties = currentMark->getProperties(); - const QColor newColor = currentCue->getColor(); + const QColor newColor = m_pPredefinedColorsRepresentation->map(currentCue->getColor()); if (newColor != markProperties.m_color || newColor != markProperties.m_textColor) { markProperties.m_color = newColor; @@ -632,3 +634,15 @@ void WOverview::dropEvent(QDropEvent* event) { } event->ignore(); } + +void WOverview::setupCueColorsRepresentation(const QDomNode& node, const SkinContext& context) { + m_pPredefinedColorsRepresentation = Color::makeDefaultRepresentation(); + + for (QLatin1String colorName : Color::predefinedColorsNames()) { + QColor representation = context.selectColor(node, colorName); + if (representation.isValid()) { + QColor originalColor = Color::predefinedColorFromName(colorName); + m_pPredefinedColorsRepresentation->setRepresentation(originalColor, representation); + } + } +} diff --git a/src/widget/woverview.h b/src/widget/woverview.h index a114e3382a6..effb0847634 100644 --- a/src/widget/woverview.h +++ b/src/widget/woverview.h @@ -95,6 +95,7 @@ class WOverview : public WWidget { // Append the waveform overview pixmap according to available data in waveform virtual bool drawNextPixmapPart() = 0; void paintText(const QString &text, QPainter *painter); + void setupCueColorsRepresentation(const QDomNode& node, const SkinContext& context); inline int valueToPosition(double value) const { return static_cast(m_a * value - m_b); } @@ -127,6 +128,7 @@ class WOverview : public WWidget { QColor m_qColorBackground; QColor m_endOfTrackColor; + std::unique_ptr m_pPredefinedColorsRepresentation; WaveformMarkSet m_marks; std::vector m_markRanges; From 3b324f8cf15f2874f04f23ce8cd0f3b2a7ddec83 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Fri, 28 Dec 2018 21:04:10 +0100 Subject: [PATCH 22/56] Append "Cue" to the skin node name for waveform cue color overrides --- src/waveform/renderers/waveformrendermark.cpp | 2 +- src/widget/woverview.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/waveform/renderers/waveformrendermark.cpp b/src/waveform/renderers/waveformrendermark.cpp index 33e4c56252b..f6d9c663ee8 100644 --- a/src/waveform/renderers/waveformrendermark.cpp +++ b/src/waveform/renderers/waveformrendermark.cpp @@ -377,7 +377,7 @@ void WaveformRenderMark::setupCueColorsRepresentation(const QDomNode& node, cons m_pPredefinedColorsRepresentation = Color::makeDefaultRepresentation(); for (QLatin1String colorName : Color::predefinedColorsNames()) { - QColor representation = context.selectColor(node, colorName); + QColor representation = context.selectColor(node, "Cue" + colorName); if (representation.isValid()) { QColor originalColor = Color::predefinedColorFromName(colorName); m_pPredefinedColorsRepresentation->setRepresentation(originalColor, representation); diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index 6e0c0e744a9..579ed3a0502 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -639,7 +639,7 @@ void WOverview::setupCueColorsRepresentation(const QDomNode& node, const SkinCon m_pPredefinedColorsRepresentation = Color::makeDefaultRepresentation(); for (QLatin1String colorName : Color::predefinedColorsNames()) { - QColor representation = context.selectColor(node, colorName); + QColor representation = context.selectColor(node, "Cue" + colorName); if (representation.isValid()) { QColor originalColor = Color::predefinedColorFromName(colorName); m_pPredefinedColorsRepresentation->setRepresentation(originalColor, representation); From b6a7dd2470cae31d0fa03294c50b5470d22aa6ee Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Fri, 28 Dec 2018 21:05:17 +0100 Subject: [PATCH 23/56] Revert "Add example, revert before merge." This reverts commit 3f986a706cb275df4ead1f41981920f8f971008d. --- res/skins/Deere/deck_visual_row.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/res/skins/Deere/deck_visual_row.xml b/res/skins/Deere/deck_visual_row.xml index e469dfea8a1..8601e8158fe 100644 --- a/res/skins/Deere/deck_visual_row.xml +++ b/res/skins/Deere/deck_visual_row.xml @@ -26,8 +26,6 @@ - #00FFFF - #FF0000 #ffffff #00FF00 From 9afc8d440364715a795fc965ff6ce29d5f0fa2b3 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sat, 29 Dec 2018 17:58:12 +0100 Subject: [PATCH 24/56] Fix WOverview cue colors not being mapped after skin reload --- src/widget/woverview.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index 579ed3a0502..a3d7cd81b49 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -203,6 +203,9 @@ void WOverview::slotAnalyzerProgress(int progress) { void WOverview::slotTrackLoaded(TrackPointer pTrack) { DEBUG_ASSERT(m_pCurrentTrack == pTrack); m_trackLoaded = true; + if (m_pCurrentTrack) { + updateCues(m_pCurrentTrack->getCuePoints()); + } update(); } From 19480bd34c42b93db32bb704144834541788fc7a Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sun, 30 Dec 2018 11:18:35 +0100 Subject: [PATCH 25/56] Convert color lists to static const vars --- src/library/dlgtrackinfo.cpp | 5 +- src/util/color.h | 100 +++++++++--------- src/waveform/renderers/waveformrendermark.cpp | 2 +- src/widget/woverview.cpp | 2 +- 4 files changed, 52 insertions(+), 57 deletions(-) diff --git a/src/library/dlgtrackinfo.cpp b/src/library/dlgtrackinfo.cpp index 64449b5aa75..aa43f1be614 100644 --- a/src/library/dlgtrackinfo.cpp +++ b/src/library/dlgtrackinfo.cpp @@ -337,7 +337,7 @@ void DlgTrackInfo::populateCues(TrackPointer pTrack) { QComboBox* colorComboBox = new QComboBox(); - QList predefinedColors = Color::predefinedColors(); + const QList& predefinedColors = Color::predefinedColors; for (int i = 0; i < predefinedColors.count(); i++) { QColor color = predefinedColors.at(i); colorComboBox->addItem(Color::displayName(color), color); @@ -430,8 +430,7 @@ void DlgTrackInfo::saveTrack() { auto colorComboBox = qobject_cast(colorWidget); if (colorComboBox) { - QList predefinedColors = Color::predefinedColors(); - QColor color = predefinedColors.at(colorComboBox->currentIndex()); + QColor color = Color::predefinedColors.at(colorComboBox->currentIndex()); if (color.isValid()) { pCue->setColor(color); } diff --git a/src/util/color.h b/src/util/color.h index cf513c7021c..6e17380284f 100644 --- a/src/util/color.h +++ b/src/util/color.h @@ -29,6 +29,7 @@ class ColorsRepresentation final { QHash colorNameMap; }; +// These methods and properties are not thread-safe, use them only on the GUI thread namespace Color { static const QColor Red = QColor("#E6194B"); static const QColor Green = QColor("#3CB44B"); @@ -54,63 +55,58 @@ namespace Color { static const QColor Black = QColor("#000000"); // Return a list with the predefined colors. - static QList predefinedColors() { - return QList { - Red, - Green, - Yellow, - Blue, - Orange, - Purple, - Cyan, - Magenta, - Lime, - Pink, - Teal, - Lavender, - Brown, - Beige, - Maroon, - Mint, - Olive, - Apricot, - Navy, - Grey, - White, - Black, - }; + static const QList predefinedColors { + Red, + Green, + Yellow, + Blue, + Orange, + Purple, + Cyan, + Magenta, + Lime, + Pink, + Teal, + Lavender, + Brown, + Beige, + Maroon, + Mint, + Olive, + Apricot, + Navy, + Grey, + White, + Black, }; // Return a list with the internal names of the predefined colors. - static QList predefinedColorsNames() { - return QList { - QLatin1String("Red"), - QLatin1String("Green"), - QLatin1String("Yellow"), - QLatin1String("Blue"), - QLatin1String("Orange"), - QLatin1String("Purple"), - QLatin1String("Cyan"), - QLatin1String("Magenta"), - QLatin1String("Lime"), - QLatin1String("Pink"), - QLatin1String("Teal"), - QLatin1String("Lavender"), - QLatin1String("Brown"), - QLatin1String("Beige"), - QLatin1String("Maroon"), - QLatin1String("Mint"), - QLatin1String("Olive"), - QLatin1String("Apricot"), - QLatin1String("Navy"), - QLatin1String("Grey"), - QLatin1String("White"), - QLatin1String("Black"), - }; + static const QList predefinedColorsNames { + QLatin1String("Red"), + QLatin1String("Green"), + QLatin1String("Yellow"), + QLatin1String("Blue"), + QLatin1String("Orange"), + QLatin1String("Purple"), + QLatin1String("Cyan"), + QLatin1String("Magenta"), + QLatin1String("Lime"), + QLatin1String("Pink"), + QLatin1String("Teal"), + QLatin1String("Lavender"), + QLatin1String("Brown"), + QLatin1String("Beige"), + QLatin1String("Maroon"), + QLatin1String("Mint"), + QLatin1String("Olive"), + QLatin1String("Apricot"), + QLatin1String("Navy"), + QLatin1String("Grey"), + QLatin1String("White"), + QLatin1String("Black"), }; // Return a predefined color code from its internal name. - // TODO: use literals here static QColor predefinedColorFromName(QLatin1String name) { if (name == QLatin1String("Red")) { return Red; @@ -215,7 +211,7 @@ namespace Color { // Stores the color's name() property, e.g. "#A9A9A9" static std::unique_ptr makeDefaultRepresentation() { std::unique_ptr representation = std::make_unique(); - for (QColor color : predefinedColors()) { + for (QColor color : predefinedColors) { representation->setRepresentation(color, color); } return representation; diff --git a/src/waveform/renderers/waveformrendermark.cpp b/src/waveform/renderers/waveformrendermark.cpp index f6d9c663ee8..3c1432a72a8 100644 --- a/src/waveform/renderers/waveformrendermark.cpp +++ b/src/waveform/renderers/waveformrendermark.cpp @@ -376,7 +376,7 @@ void WaveformRenderMark::generateMarkImage(WaveformMark* pMark) { void WaveformRenderMark::setupCueColorsRepresentation(const QDomNode& node, const SkinContext& context) { m_pPredefinedColorsRepresentation = Color::makeDefaultRepresentation(); - for (QLatin1String colorName : Color::predefinedColorsNames()) { + for (QLatin1String colorName : Color::predefinedColorsNames) { QColor representation = context.selectColor(node, "Cue" + colorName); if (representation.isValid()) { QColor originalColor = Color::predefinedColorFromName(colorName); diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index a3d7cd81b49..faa80c3a19b 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -641,7 +641,7 @@ void WOverview::dropEvent(QDropEvent* event) { void WOverview::setupCueColorsRepresentation(const QDomNode& node, const SkinContext& context) { m_pPredefinedColorsRepresentation = Color::makeDefaultRepresentation(); - for (QLatin1String colorName : Color::predefinedColorsNames()) { + for (QLatin1String colorName : Color::predefinedColorsNames) { QColor representation = context.selectColor(node, "Cue" + colorName); if (representation.isValid()) { QColor originalColor = Color::predefinedColorFromName(colorName); From f950c2564d26a9fb5c229a7a530bd3b9fdc83686 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sun, 30 Dec 2018 11:49:10 +0100 Subject: [PATCH 26/56] Reduce the number of runtime copies of ColorsRepresentation --- src/util/color.h | 24 +++++++++++-------- src/waveform/renderers/waveformrendermark.cpp | 6 ++--- src/waveform/renderers/waveformrendermark.h | 2 +- src/widget/woverview.cpp | 6 ++--- src/widget/woverview.h | 2 +- 5 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/util/color.h b/src/util/color.h index 6e17380284f..c1ba4412b83 100644 --- a/src/util/color.h +++ b/src/util/color.h @@ -2,7 +2,6 @@ #define COLOR_H #include "util/math.h" -#include "util/memory.h" #include #include @@ -10,23 +9,26 @@ #define BRIGHTNESS_TRESHOLD 130 // Map the predefined colors to another color representation of them. +// +// Since QHash has copy-on-write, making a copy of ColorsRepresentation is fast. +// A deep copy of the QHash will be made when the copy is modified. class ColorsRepresentation final { public: // Set a color representation for a given color void setRepresentation(QColor color, QColor representation) { - colorNameMap[color.name()] = representation.name(); + m_colorNameMap[color.name()] = representation.name(); } // Returns the representation of a color QColor map(QColor color) const { - if (colorNameMap.contains(color.name())) { - return QColor(colorNameMap[color.name()]); + if (m_colorNameMap.contains(color.name())) { + return QColor(m_colorNameMap[color.name()]); } return color; } private: - QHash colorNameMap; + QHash m_colorNameMap; }; // These methods and properties are not thread-safe, use them only on the GUI thread @@ -207,15 +209,17 @@ namespace Color { return QObject::tr("Undefined Color"); }; - // Returns a new default colors representation, i.e. maps each default color to itself. + // The default colors representation, i.e. maps each default color to itself. // Stores the color's name() property, e.g. "#A9A9A9" - static std::unique_ptr makeDefaultRepresentation() { - std::unique_ptr representation = std::make_unique(); + // + // It's fast to copy the default representation. See comment on ColorsRepresentation. + static const ColorsRepresentation defaultRepresentation = [](){ + ColorsRepresentation representation = ColorsRepresentation(); for (QColor color : predefinedColors) { - representation->setRepresentation(color, color); + representation.setRepresentation(color, color); } return representation; - } + }(); // algorithm by http://www.nbdtech.com/Blog/archive/2008/04/27/Calculating-the-Perceived-Brightness-of-a-Color.aspx diff --git a/src/waveform/renderers/waveformrendermark.cpp b/src/waveform/renderers/waveformrendermark.cpp index 3c1432a72a8..a77bae57ec8 100644 --- a/src/waveform/renderers/waveformrendermark.cpp +++ b/src/waveform/renderers/waveformrendermark.cpp @@ -110,7 +110,7 @@ void WaveformRenderMark::slotCuesUpdated() { } QString newLabel = pCue->getLabel(); - QColor newColor = m_pPredefinedColorsRepresentation->map(pCue->getColor()); + QColor newColor = m_predefinedColorsRepresentation.map(pCue->getColor()); // Here we assume no two cues can have the same hotcue assigned, // because WaveformMarkSet stores one mark for each hotcue. @@ -374,13 +374,13 @@ void WaveformRenderMark::generateMarkImage(WaveformMark* pMark) { } void WaveformRenderMark::setupCueColorsRepresentation(const QDomNode& node, const SkinContext& context) { - m_pPredefinedColorsRepresentation = Color::makeDefaultRepresentation(); + m_predefinedColorsRepresentation = Color::defaultRepresentation; for (QLatin1String colorName : Color::predefinedColorsNames) { QColor representation = context.selectColor(node, "Cue" + colorName); if (representation.isValid()) { QColor originalColor = Color::predefinedColorFromName(colorName); - m_pPredefinedColorsRepresentation->setRepresentation(originalColor, representation); + m_predefinedColorsRepresentation.setRepresentation(originalColor, representation); } } } diff --git a/src/waveform/renderers/waveformrendermark.h b/src/waveform/renderers/waveformrendermark.h index 34bbc45dde6..e0ad61f8a50 100644 --- a/src/waveform/renderers/waveformrendermark.h +++ b/src/waveform/renderers/waveformrendermark.h @@ -35,7 +35,7 @@ class WaveformRenderMark : public QObject, public WaveformRendererAbstract { void generateMarkImage(WaveformMark* pMark); void setupCueColorsRepresentation(const QDomNode& node, const SkinContext& context); - std::unique_ptr m_pPredefinedColorsRepresentation; + ColorsRepresentation m_predefinedColorsRepresentation; WaveformMarkSet m_marks; DISALLOW_COPY_AND_ASSIGN(WaveformRenderMark); diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index faa80c3a19b..4a17445bb94 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -270,7 +270,7 @@ void WOverview::updateCues(const QList &loadedCues) { if (currentMark && currentMark->isValid()) { WaveformMarkProperties markProperties = currentMark->getProperties(); - const QColor newColor = m_pPredefinedColorsRepresentation->map(currentCue->getColor()); + const QColor newColor = m_predefinedColorsRepresentation.map(currentCue->getColor()); if (newColor != markProperties.m_color || newColor != markProperties.m_textColor) { markProperties.m_color = newColor; @@ -639,13 +639,13 @@ void WOverview::dropEvent(QDropEvent* event) { } void WOverview::setupCueColorsRepresentation(const QDomNode& node, const SkinContext& context) { - m_pPredefinedColorsRepresentation = Color::makeDefaultRepresentation(); + m_predefinedColorsRepresentation = Color::defaultRepresentation; for (QLatin1String colorName : Color::predefinedColorsNames) { QColor representation = context.selectColor(node, "Cue" + colorName); if (representation.isValid()) { QColor originalColor = Color::predefinedColorFromName(colorName); - m_pPredefinedColorsRepresentation->setRepresentation(originalColor, representation); + m_predefinedColorsRepresentation.setRepresentation(originalColor, representation); } } } diff --git a/src/widget/woverview.h b/src/widget/woverview.h index effb0847634..ab904cc7480 100644 --- a/src/widget/woverview.h +++ b/src/widget/woverview.h @@ -128,7 +128,7 @@ class WOverview : public WWidget { QColor m_qColorBackground; QColor m_endOfTrackColor; - std::unique_ptr m_pPredefinedColorsRepresentation; + ColorsRepresentation m_predefinedColorsRepresentation; WaveformMarkSet m_marks; std::vector m_markRanges; From f951a941f9d56eda5e0f4ffa6a8e441f9f9586f7 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sun, 30 Dec 2018 12:10:42 +0100 Subject: [PATCH 27/56] Move setupCueColorsRepresentation() to SkinContext --- src/skin/skincontext.h | 13 +++++++++++++ src/waveform/renderers/waveformrendermark.cpp | 14 +------------- src/waveform/renderers/waveformrendermark.h | 1 - src/widget/woverview.cpp | 14 +------------- src/widget/woverview.h | 1 - 5 files changed, 15 insertions(+), 28 deletions(-) diff --git a/src/skin/skincontext.h b/src/skin/skincontext.h index 205a204aedc..95753914dad 100644 --- a/src/skin/skincontext.h +++ b/src/skin/skincontext.h @@ -14,6 +14,7 @@ #include "preferences/usersettings.h" #include "skin/pixmapsource.h" +#include "util/color.h" #include "widget/wsingletoncontainer.h" #include "widget/wpixmapstore.h" @@ -266,6 +267,18 @@ class SkinContext { return m_scaleFactor; } + ColorsRepresentation getCueColorsRepresentation(const QDomNode& node) const { + ColorsRepresentation colorsReprsentation = Color::defaultRepresentation; + for (QLatin1String colorName : Color::predefinedColorsNames) { + QColor representation = selectColor(node, "Cue" + colorName); + if (representation.isValid()) { + QColor originalColor = Color::predefinedColorFromName(colorName); + colorsReprsentation.setRepresentation(originalColor, representation); + } + } + return colorsReprsentation; + } + private: PixmapSource getPixmapSourceInner(const QString& filename) const; diff --git a/src/waveform/renderers/waveformrendermark.cpp b/src/waveform/renderers/waveformrendermark.cpp index a77bae57ec8..2e078b9a340 100644 --- a/src/waveform/renderers/waveformrendermark.cpp +++ b/src/waveform/renderers/waveformrendermark.cpp @@ -23,7 +23,7 @@ WaveformRenderMark::WaveformRenderMark( } void WaveformRenderMark::setup(const QDomNode& node, const SkinContext& context) { - setupCueColorsRepresentation(node, context); + m_predefinedColorsRepresentation = context.getCueColorsRepresentation(node); m_marks.setup(m_waveformRenderer->getGroup(), node, context, *m_waveformRenderer->getWaveformSignalColors()); } @@ -372,15 +372,3 @@ void WaveformRenderMark::generateMarkImage(WaveformMark* pMark) { painter.drawLine(middle + 1, lineTop, middle + 1, lineBottom); } } - -void WaveformRenderMark::setupCueColorsRepresentation(const QDomNode& node, const SkinContext& context) { - m_predefinedColorsRepresentation = Color::defaultRepresentation; - - for (QLatin1String colorName : Color::predefinedColorsNames) { - QColor representation = context.selectColor(node, "Cue" + colorName); - if (representation.isValid()) { - QColor originalColor = Color::predefinedColorFromName(colorName); - m_predefinedColorsRepresentation.setRepresentation(originalColor, representation); - } - } -} diff --git a/src/waveform/renderers/waveformrendermark.h b/src/waveform/renderers/waveformrendermark.h index e0ad61f8a50..bb5a9ee04f6 100644 --- a/src/waveform/renderers/waveformrendermark.h +++ b/src/waveform/renderers/waveformrendermark.h @@ -33,7 +33,6 @@ class WaveformRenderMark : public QObject, public WaveformRendererAbstract { private: void generateMarkImage(WaveformMark* pMark); - void setupCueColorsRepresentation(const QDomNode& node, const SkinContext& context); ColorsRepresentation m_predefinedColorsRepresentation; diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index 4a17445bb94..ffda58a1856 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -85,7 +85,7 @@ void WOverview::setup(const QDomNode& node, const SkinContext& context) { } // setup hotcues and cue and loop(s) - setupCueColorsRepresentation(node, context); + m_predefinedColorsRepresentation = context.getCueColorsRepresentation(node); m_marks.setup(m_group, node, context, m_signalColors); for (const auto& pMark: m_marks) { @@ -637,15 +637,3 @@ void WOverview::dropEvent(QDropEvent* event) { } event->ignore(); } - -void WOverview::setupCueColorsRepresentation(const QDomNode& node, const SkinContext& context) { - m_predefinedColorsRepresentation = Color::defaultRepresentation; - - for (QLatin1String colorName : Color::predefinedColorsNames) { - QColor representation = context.selectColor(node, "Cue" + colorName); - if (representation.isValid()) { - QColor originalColor = Color::predefinedColorFromName(colorName); - m_predefinedColorsRepresentation.setRepresentation(originalColor, representation); - } - } -} diff --git a/src/widget/woverview.h b/src/widget/woverview.h index ab904cc7480..e1f0a02bc26 100644 --- a/src/widget/woverview.h +++ b/src/widget/woverview.h @@ -95,7 +95,6 @@ class WOverview : public WWidget { // Append the waveform overview pixmap according to available data in waveform virtual bool drawNextPixmapPart() = 0; void paintText(const QString &text, QPainter *painter); - void setupCueColorsRepresentation(const QDomNode& node, const SkinContext& context); inline int valueToPosition(double value) const { return static_cast(m_a * value - m_b); } From c49961f8a84bac3b83087a5b74675e515c33ab16 Mon Sep 17 00:00:00 2001 From: Swiftb0y Date: Tue, 1 Jan 2019 21:25:46 +0100 Subject: [PATCH 28/56] Added JS utility object for dealing with hotcue colors from MixxxControl --- res/controllers/common-controller-scripts.js | 42 ++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/res/controllers/common-controller-scripts.js b/res/controllers/common-controller-scripts.js index f52940ef9b4..71fd4132ac5 100644 --- a/res/controllers/common-controller-scripts.js +++ b/res/controllers/common-controller-scripts.js @@ -413,6 +413,48 @@ bpm.tapButton = function(deck) { // print("Script: BPM="+average+" setting to "+fRateScale); } +// color - Basic Object used for convient interface with the hotcue_color ControlObjects +color = { + // member should be set directly but only in the [0;255] range. + red: 0, + green: 0, + blue: 0, + alpha: 255, +} + + +/* -------- ------------------------------------------------------ + color.fromCO + Purpose: Setter that splits the combined colors into their components + and sets the color components in the object + Input: combined color value + Output: - + -------- ------------------------------------------------------ */ + +color.fromCO = function(color) { + this.alpha = color >> 24 & 0xFF; + this.red = color >> 16 & 0xFF; + this.green = color >> 8 & 0xFF; + this.blue = color & 0xFF; +} +/* -------- ------------------------------------------------------ + color.toCO + Purpose: Combines the colors back into a single value that + that could be used to set the MixxxControl value + Input: - + Output: struct containing the color components + -------- ------------------------------------------------------ */ +color.toCO = function() { + // javascript objects don't have "access control" and this object + // doesn't provide setters (interaction is supposed to be done via direct access) + // so this getter function sanitizes the values on export. + return (this.alpha % 255) << 24 + + (this.red % 255) << 16 + + (this.green % 255) << 8 + + this. blue % 255; +} + + // ----------------- Common regular expressions -------------------------- script.samplerRegEx = /^\[Sampler(\d+)\]$/ ; script.channelRegEx = /^\[Channel(\d+)\]$/ ; From 9437cd66b2afcc4e1bba98b5f7376217dab1d1fc Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sun, 27 Jan 2019 15:45:19 +0100 Subject: [PATCH 29/56] Reduce number of colors --- src/util/color.h | 94 ++---------------------------------------------- 1 file changed, 2 insertions(+), 92 deletions(-) diff --git a/src/util/color.h b/src/util/color.h index c1ba4412b83..6bcaa20adfc 100644 --- a/src/util/color.h +++ b/src/util/color.h @@ -37,24 +37,11 @@ namespace Color { static const QColor Green = QColor("#3CB44B"); static const QColor Yellow = QColor("#FFE119"); static const QColor Blue = QColor("#4363D8"); - static const QColor Orange = QColor("#F58231"); - static const QColor Purple = QColor("#911EB4"); static const QColor Cyan = QColor("#42D4F4"); static const QColor Magenta = QColor("#F032E6"); - static const QColor Lime = QColor("#BFEF45"); static const QColor Pink = QColor("#FABEBE"); static const QColor Teal = QColor("#469990"); - static const QColor Lavender = QColor("#E6BEFF"); - static const QColor Brown = QColor("#9A6324"); - static const QColor Beige = QColor("#FFFAC8"); - static const QColor Maroon = QColor("#800000"); - static const QColor Mint = QColor("#AAFFC3"); - static const QColor Olive = QColor("#808000"); - static const QColor Apricot = QColor("#FFD8B1"); - static const QColor Navy = QColor("#000075"); static const QColor Grey = QColor("#A9A9A9"); - static const QColor White = QColor("#FFFFFF"); - static const QColor Black = QColor("#000000"); // Return a list with the predefined colors. static const QList predefinedColors { @@ -62,24 +49,11 @@ namespace Color { Green, Yellow, Blue, - Orange, - Purple, Cyan, Magenta, - Lime, Pink, Teal, - Lavender, - Brown, - Beige, - Maroon, - Mint, - Olive, - Apricot, - Navy, Grey, - White, - Black, }; // Return a list with the internal names of the predefined colors. @@ -88,24 +62,11 @@ namespace Color { QLatin1String("Green"), QLatin1String("Yellow"), QLatin1String("Blue"), - QLatin1String("Orange"), - QLatin1String("Purple"), QLatin1String("Cyan"), QLatin1String("Magenta"), - QLatin1String("Lime"), QLatin1String("Pink"), QLatin1String("Teal"), - QLatin1String("Lavender"), - QLatin1String("Brown"), - QLatin1String("Beige"), - QLatin1String("Maroon"), - QLatin1String("Mint"), - QLatin1String("Olive"), - QLatin1String("Apricot"), - QLatin1String("Navy"), QLatin1String("Grey"), - QLatin1String("White"), - QLatin1String("Black"), }; // Return a predefined color code from its internal name. @@ -118,44 +79,18 @@ namespace Color { return Yellow; } else if (name == QLatin1String("Blue")) { return Blue; - } else if (name == QLatin1String("Orange")) { - return Orange; - } else if (name == QLatin1String("Purple")) { - return Purple; } else if (name == QLatin1String("Cyan")) { return Cyan; } else if (name == QLatin1String("Magenta")) { return Magenta; - } else if (name == QLatin1String("Lime")) { - return Lime; } else if (name == QLatin1String("Pink")) { return Pink; } else if (name == QLatin1String("Teal")) { return Teal; - } else if (name == QLatin1String("Lavender")) { - return Lavender; - } else if (name == QLatin1String("Brown")) { - return Brown; - } else if (name == QLatin1String("Beige")) { - return Beige; - } else if (name == QLatin1String("Maroon")) { - return Maroon; - } else if (name == QLatin1String("Mint")) { - return Mint; - } else if (name == QLatin1String("Olive")) { - return Olive; - } else if (name == QLatin1String("Apricot")) { - return Apricot; - } else if (name == QLatin1String("Navy")) { - return Navy; } else if (name == QLatin1String("Grey")) { return Grey; - } else if (name == QLatin1String("White")) { - return White; - } else if (name == QLatin1String("Black")) { - return Black; } - return Black; + return Red; }; // Return the localized name of a predefined color. @@ -169,42 +104,17 @@ namespace Color { return QObject::tr("Yellow"); } else if (color == Blue) { return QObject::tr("Blue"); - } else if (color == Orange) { - return QObject::tr("Orange"); - } else if (color == Purple) { - return QObject::tr("Purple"); } else if (color == Cyan) { return QObject::tr("Cyan"); } else if (color == Magenta) { return QObject::tr("Magenta"); - } else if (color == Lime) { - return QObject::tr("Lime"); } else if (color == Pink) { return QObject::tr("Pink"); } else if (color == Teal) { return QObject::tr("Teal"); - } else if (color == Lavender) { - return QObject::tr("Lavender"); - } else if (color == Brown) { - return QObject::tr("Brown"); - } else if (color == Beige) { - return QObject::tr("Beige"); - } else if (color == Maroon) { - return QObject::tr("Maroon"); - } else if (color == Mint) { - return QObject::tr("Mint"); - } else if (color == Olive) { - return QObject::tr("Olive"); - } else if (color == Apricot) { - return QObject::tr("Apricot"); - } else if (color == Navy){ - return QObject::tr("Navy"); + } else if (color == Grey) { return QObject::tr("Grey"); - } else if (color == White) { - return QObject::tr("White"); - } else if (color == Black) { - return QObject::tr("Black"); } return QObject::tr("Undefined Color"); }; From 181fbe99af84e017b2d3a2cdd3eb6470b171d40e Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Fri, 25 Jan 2019 23:42:41 +0100 Subject: [PATCH 30/56] Improve waveform marks visibility Precalculate mark colors and save them in WaveformMarkProperties. --- src/util/color.h | 43 ++++++++-------- .../renderers/waveformmarkproperties.cpp | 27 ++++++++-- .../renderers/waveformmarkproperties.h | 12 ++++- src/waveform/renderers/waveformrendermark.cpp | 49 +++++++------------ src/widget/woverview.cpp | 10 ++-- 5 files changed, 78 insertions(+), 63 deletions(-) diff --git a/src/util/color.h b/src/util/color.h index 6bcaa20adfc..c0b85f9ff38 100644 --- a/src/util/color.h +++ b/src/util/color.h @@ -6,8 +6,6 @@ #include #include -#define BRIGHTNESS_TRESHOLD 130 - // Map the predefined colors to another color representation of them. // // Since QHash has copy-on-write, making a copy of ColorsRepresentation is fast. @@ -144,33 +142,34 @@ namespace Color { ); }; - static inline int brightness(QColor color) { + static inline int brightness(const QColor& color) { return brightness(color.red(), color.green(), color.red()); } - static inline bool isDimmColor(QColor color) { -// qDebug() << color.name(); - return brightness(color) < BRIGHTNESS_TRESHOLD; - } - - // if the ColorToChooseBy is darker than the global threshold, - // the Color from the second argument will be returned. - - static inline QColor chooseColorByBrightnessB(bool precalculated, QColor dimmColor , QColor brightColor) { - return precalculated ? dimmColor : brightColor; - } - - static inline QColor chooseColorByBrightness(QColor ColorToChooseBy, QColor dimmColor , QColor brightColor) { - return chooseColorByBrightnessB(isDimmColor(ColorToChooseBy), dimmColor, brightColor); + static inline bool isDimmColor(const QColor& color) { + return brightness(color) <= 127; } - static inline QColor chooseContrastColor(QColor colorToChooseBy) { - return chooseColorByBrightness(colorToChooseBy, QColor(255,255,255,255), QColor(0,0,0,255)); + // If the colorToChooseBy is darker than the global threshold, + // dimmColor will be returned. Otherwise brightColor will be returned. + static inline QColor chooseColorByBrightness(QColor colorToChooseBy, QColor dimmColor , QColor brightColor) { + return isDimmColor(colorToChooseBy) ? dimmColor : brightColor; } - static inline QColor chooseContrastColorB(bool precalculated) { - return chooseColorByBrightnessB(precalculated, QColor(255,255,255,255), QColor(0,0,0,255)); + // If the baseColor is darker than the global threshold, + // returns white, otherwise returns black. + static inline QColor chooseContrastColor(QColor baseColor) { + QColor lightColor = baseColor.lighter(); + QColor darkColor = baseColor.darker(); + + // QColor::lighter() multiplies the HSV Value by some factor. When baseColor is black, Value is 0, + // thus after multiplication it's still 0 and we get the same color. + // We manually set lightColor to darkGray in this case. + if (baseColor.toHsv().value() == 0) { + lightColor = Qt::darkGray; + lightColor.setAlpha(baseColor.alpha()); + } + return chooseColorByBrightness(baseColor, lightColor, darkColor); } - }; #endif /* COLOR_H */ diff --git a/src/waveform/renderers/waveformmarkproperties.cpp b/src/waveform/renderers/waveformmarkproperties.cpp index d3ee395d1a6..bde16e1e06c 100644 --- a/src/waveform/renderers/waveformmarkproperties.cpp +++ b/src/waveform/renderers/waveformmarkproperties.cpp @@ -46,14 +46,14 @@ WaveformMarkProperties::WaveformMarkProperties(const QDomNode& node, const SkinContext& context, const WaveformSignalColors& signalColors, int hotCue) { - m_color = context.selectString(node, "Color"); + QColor color(context.selectString(node, "Color")); // TODO (Swiftb0y): remove context.selectString because the color will be overriden by the cuepoints regardless - if (!m_color.isValid()) { + if (!color.isValid()) { // As a fallback, grab the color from the parent's AxesColor - m_color = signalColors.getAxesColor(); - qDebug() << "Didn't get mark , using parent's :" << m_color; + setBaseColor(signalColors.getAxesColor()); + qDebug() << "Didn't get mark , using parent's :" << m_fillColor; } else { - m_color = WSkinColor::getCorrectColor(m_color); + setBaseColor(WSkinColor::getCorrectColor(m_fillColor)); } m_textColor = context.selectString(node, "TextColor"); @@ -76,3 +76,20 @@ WaveformMarkProperties::WaveformMarkProperties(const QDomNode& node, m_pixmapPath = context.makeSkinPath(m_pixmapPath); } } + +void WaveformMarkProperties::setBaseColor(QColor baseColor) { + m_fillColor = baseColor; + m_borderColor = Color::chooseContrastColor(baseColor); + m_labelColor = Color::chooseColorByBrightness(baseColor, QColor(255,255,255,255), QColor(0,0,0,255)); +} + +QColor WaveformMarkProperties::fillColor() const { + return m_fillColor; +} + +QColor WaveformMarkProperties::borderColor() const { + return m_borderColor; +} +QColor WaveformMarkProperties::labelColor() const { + return m_labelColor; +} diff --git a/src/waveform/renderers/waveformmarkproperties.h b/src/waveform/renderers/waveformmarkproperties.h index 1215b36e28f..6f3cf0ea4c2 100644 --- a/src/waveform/renderers/waveformmarkproperties.h +++ b/src/waveform/renderers/waveformmarkproperties.h @@ -15,11 +15,21 @@ class WaveformMarkProperties final { const WaveformSignalColors& signalColors, int hotCue); - QColor m_color; + // Sets the appropriate mark colors based on the base color + void setBaseColor(QColor baseColor); + QColor fillColor() const; + QColor borderColor() const; + QColor labelColor() const; + QColor m_textColor; QString m_text; Qt::Alignment m_align; QString m_pixmapPath; + + private: + QColor m_fillColor; + QColor m_borderColor; + QColor m_labelColor; }; #endif // WAVEFORMMARKPROPERTIES_H diff --git a/src/waveform/renderers/waveformrendermark.cpp b/src/waveform/renderers/waveformrendermark.cpp index 2e078b9a340..b6119e13709 100644 --- a/src/waveform/renderers/waveformrendermark.cpp +++ b/src/waveform/renderers/waveformrendermark.cpp @@ -120,9 +120,9 @@ void WaveformRenderMark::slotCuesUpdated() { } WaveformMarkProperties markProperties = pMark->getProperties(); if (markProperties.m_text.isNull() || newLabel != markProperties.m_text || - !markProperties.m_color.isValid() || newColor != markProperties.m_color) { + !markProperties.fillColor().isValid() || newColor != markProperties.fillColor()) { markProperties.m_text = newLabel; - markProperties.m_color = newColor; + markProperties.setBaseColor(newColor); pMark->setProperties(markProperties); generateMarkImage(pMark.data()); } @@ -223,39 +223,32 @@ void WaveformRenderMark::generateMarkImage(WaveformMark* pMark) { painter.setWorldMatrixEnabled(false); - // Prepare colors for drawing of marker lines - QColor lineColor = markProperties.m_color; - lineColor.setAlpha(200); - bool markerBrightnessLow= Color::isDimmColor(lineColor); - QColor contrastLineColor = Color::chooseContrastColorB(markerBrightnessLow); - contrastLineColor.setAlpha(180); - // Draw marker lines if (m_waveformRenderer->getOrientation() == Qt::Horizontal) { int middle = width / 2; if (markAlignH == Qt::AlignHCenter) { if (labelRect.top() > 0) { - painter.setPen(lineColor); + painter.setPen(markProperties.fillColor()); painter.drawLine(middle, 0, middle, labelRect.top()); - painter.setPen(contrastLineColor); + painter.setPen(markProperties.borderColor()); painter.drawLine(middle - 1, 0, middle - 1, labelRect.top()); painter.drawLine(middle + 1, 0, middle + 1, labelRect.top()); } if (labelRect.bottom() < height) { - painter.setPen(lineColor); + painter.setPen(markProperties.fillColor()); painter.drawLine(middle, labelRect.bottom(), middle, height); - painter.setPen(contrastLineColor); + painter.setPen(markProperties.borderColor()); painter.drawLine(middle - 1, labelRect.bottom(), middle - 1, height); painter.drawLine(middle + 1, labelRect.bottom(), middle + 1, height); } } else { // AlignLeft || AlignRight - painter.setPen(lineColor); + painter.setPen(markProperties.fillColor()); painter.drawLine(middle, 0, middle, height); - painter.setPen(contrastLineColor); + painter.setPen(markProperties.borderColor()); painter.drawLine(middle - 1, 0, middle - 1, height); painter.drawLine(middle + 1, 0, middle + 1, height); } @@ -263,43 +256,41 @@ void WaveformRenderMark::generateMarkImage(WaveformMark* pMark) { int middle = height / 2; if (markAlignV == Qt::AlignVCenter) { if (labelRect.left() > 0) { - painter.setPen(lineColor); + painter.setPen(markProperties.fillColor()); painter.drawLine(0, middle, labelRect.left(), middle); - painter.setPen(contrastLineColor); + painter.setPen(markProperties.borderColor()); painter.drawLine(0, middle - 1, labelRect.left(), middle - 1); painter.drawLine(0, middle + 1, labelRect.left(), middle + 1); } if (labelRect.right() < width) { - painter.setPen(lineColor); + painter.setPen(markProperties.fillColor()); painter.drawLine(labelRect.right(), middle, width, middle); - painter.setPen(contrastLineColor); + painter.setPen(markProperties.borderColor()); painter.drawLine(labelRect.right(), middle - 1, width, middle - 1); painter.drawLine(labelRect.right(), middle + 1, width, middle + 1); } } else { // AlignTop || AlignBottom - painter.setPen(lineColor); + painter.setPen(markProperties.fillColor()); painter.drawLine(0, middle, width, middle); - painter.setPen(contrastLineColor); + painter.setPen(markProperties.borderColor()); painter.drawLine(0, middle - 1, width, middle - 1); painter.drawLine(0, middle + 1, width, middle + 1); } } // Draw the label rect - QColor rectColor = markProperties.m_color; - rectColor.setAlpha(200); - painter.setPen(markProperties.m_color); - painter.setBrush(QBrush(rectColor)); + painter.setPen(markProperties.borderColor()); + painter.setBrush(QBrush(markProperties.fillColor())); painter.drawRoundedRect(labelRect, 2.0, 2.0); // Draw text painter.setBrush(QBrush(QColor(0,0,0,0))); painter.setFont(font); - painter.setPen(Color::chooseContrastColorB(markerBrightnessLow)); + painter.setPen(markProperties.labelColor()); painter.drawText(labelRect, Qt::AlignCenter, label); } else //no text draw triangle @@ -331,8 +322,7 @@ void WaveformRenderMark::generateMarkImage(WaveformMark* pMark) { painter.setTransform(QTransform(0, 1, 1, 0, 0, 0)); } - QColor triangleColor = markProperties.m_color; - triangleColor.setAlpha(140); + QColor triangleColor = markProperties.fillColor(); painter.setPen(QColor(0,0,0,0)); painter.setBrush(QBrush(triangleColor)); @@ -355,8 +345,7 @@ void WaveformRenderMark::generateMarkImage(WaveformMark* pMark) { //TODO vRince duplicated code make a method //draw line - QColor lineColor = markProperties.m_color; - lineColor.setAlpha(140); + QColor lineColor = markProperties.fillColor(); painter.setPen(lineColor); float middle = markLength / 2.0; diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index 3599966fe49..47031d94efb 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -268,8 +268,8 @@ void WOverview::updateCues(const QList &loadedCues) { WaveformMarkProperties markProperties = currentMark->getProperties(); const QColor newColor = m_predefinedColorsRepresentation.map(currentCue->getColor()); - if (newColor != markProperties.m_color || newColor != markProperties.m_textColor) { - markProperties.m_color = newColor; + if (newColor != markProperties.fillColor() || newColor != markProperties.m_textColor) { + markProperties.setBaseColor(newColor); currentMark->setProperties(markProperties); } } @@ -463,8 +463,6 @@ void WOverview::paintEvent(QPaintEvent * /*unused*/) { } // Draw markers (Cue & hotcues) - QPen shadowPen(QBrush(m_qColorBackground), 2.5 * m_scaleFactor); - QFont markerFont = painter.font(); markerFont.setPixelSize(10 * m_scaleFactor); @@ -481,6 +479,8 @@ void WOverview::paintEvent(QPaintEvent * /*unused*/) { // (currentMark.m_pointControl->get() / (float)m_trackSamplesControl->get()) * (float)(width()-2); const float markPosition = offset + currentMark->getSamplePosition() * gain; + QPen shadowPen(QBrush(markProperties.borderColor()), 2.5 * m_scaleFactor); + QLineF line; if (m_orientation == Qt::Horizontal) { line.setLine(markPosition, 0.0, markPosition, static_cast(height())); @@ -490,7 +490,7 @@ void WOverview::paintEvent(QPaintEvent * /*unused*/) { painter.setPen(shadowPen); painter.drawLine(line); - painter.setPen(markProperties.m_color); + painter.setPen(markProperties.fillColor()); painter.drawLine(line); if (!markProperties.m_text.isEmpty()) { From 60e5a09202503bfcb986837c553ef980f1537144 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Wed, 30 Jan 2019 19:34:03 +0100 Subject: [PATCH 31/56] Refactor color.h --- build/depends.py | 2 + src/engine/controls/cuecontrol.cpp | 1 + src/library/dao/cue.cpp | 4 +- src/library/dao/cue.h | 5 +- src/library/dlgtrackinfo.cpp | 23 +-- src/skin/skincontext.h | 15 +- src/util/color.h | 175 ------------------ src/util/color/color.h | 55 ++++++ src/util/color/predefinedcolor.cpp | 10 + src/util/color/predefinedcolor.h | 17 ++ src/util/color/predefinedcolormap.cpp | 13 ++ src/util/color/predefinedcolormap.h | 27 +++ src/util/color/predefinedcolorset.cpp | 13 ++ src/util/color/predefinedcolorset.h | 100 ++++++++++ src/waveform/renderers/waveformrendermark.cpp | 2 +- src/waveform/renderers/waveformrendermark.h | 2 +- src/widget/woverview.cpp | 2 +- src/widget/woverview.h | 4 +- 18 files changed, 268 insertions(+), 202 deletions(-) delete mode 100644 src/util/color.h create mode 100644 src/util/color/color.h create mode 100644 src/util/color/predefinedcolor.cpp create mode 100644 src/util/color/predefinedcolor.h create mode 100644 src/util/color/predefinedcolormap.cpp create mode 100644 src/util/color/predefinedcolormap.h create mode 100644 src/util/color/predefinedcolorset.cpp create mode 100644 src/util/color/predefinedcolorset.h diff --git a/build/depends.py b/build/depends.py index eb7110dfc7e..3dfe8f4ce58 100644 --- a/build/depends.py +++ b/build/depends.py @@ -1225,6 +1225,8 @@ def sources(self, build): "src/util/widgetrendertimer.cpp", "src/util/workerthread.cpp", "src/util/workerthreadscheduler.cpp", + "src/util/color/predefinedcolormap.cpp" + "src/util/color/predefinedcolorset.cpp" ] proto_args = { diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index 40dd90731f0..85a0cb3d818 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -1041,6 +1041,7 @@ HotcueControl::HotcueControl(QString group, int i) // the Color is stored as a QRgb (which is just a unsigned int // representation of the color (AARRGGBB) m_hotcueColor = new ControlObject(keyForControl(i, "color")); + m_hotcueColor->setReadOnly(); connect(m_hotcueColor, SIGNAL(valueChanged(double)), this, SLOT(slotHotcueColorChanged(double)), Qt::DirectConnection); diff --git a/src/library/dao/cue.cpp b/src/library/dao/cue.cpp index 8efc6f9a272..e6564798b4b 100644 --- a/src/library/dao/cue.cpp +++ b/src/library/dao/cue.cpp @@ -138,12 +138,12 @@ void Cue::setLabel(const QString label) { emit(updated()); } -QColor Cue::getColor() const { +PredefinedColorPointer Cue::getColor() const { QMutexLocker lock(&m_mutex); return m_color; } -void Cue::setColor(const QColor color) { +void Cue::setColor(const PredefinedColorPointer color) { QMutexLocker lock(&m_mutex); m_color = color; m_bDirty = true; diff --git a/src/library/dao/cue.h b/src/library/dao/cue.h index 796dba0493a..21344d60716 100644 --- a/src/library/dao/cue.h +++ b/src/library/dao/cue.h @@ -6,6 +6,7 @@ #include #include "track/trackid.h" +#include "util/color/predefinedcolor.h" #include "util/memory.h" class CueDAO; @@ -44,8 +45,8 @@ class Cue : public QObject { QString getLabel() const; void setLabel(QString label); - QColor getColor() const; - void setColor(QColor color); + PredefinedColorPointer getColor() const; + void setColor(PredefinedColorPointer color); signals: void updated(); diff --git a/src/library/dlgtrackinfo.cpp b/src/library/dlgtrackinfo.cpp index 7a1ae72f5a6..ad303e7efa7 100644 --- a/src/library/dlgtrackinfo.cpp +++ b/src/library/dlgtrackinfo.cpp @@ -13,7 +13,7 @@ #include "track/keyfactory.h" #include "track/keyutils.h" #include "util/duration.h" -#include "util/color.h" +#include "util/color/color.h" const int kFilterLength = 80; const int kMinBpm = 30; @@ -323,16 +323,17 @@ void DlgTrackInfo::populateCues(TrackPointer pTrack) { QComboBox* colorComboBox = new QComboBox(); - const QList& predefinedColors = Color::predefinedColors; + QList predefinedColors = Color::predefinedColorSet.allColors; for (int i = 0; i < predefinedColors.count(); i++) { - QColor color = predefinedColors.at(i); - colorComboBox->addItem(Color::displayName(color), color); + PredefinedColorPointer color = predefinedColors.at(i); + QColor colorRepresentation = color->m_defaultRepresentation; + colorComboBox->addItem(color->m_sDisplayName, colorRepresentation); const QModelIndex idx = colorComboBox->model()->index(i, 0); - colorComboBox->model()->setData(idx, color, Qt::BackgroundColorRole); - colorComboBox->setItemData(i, Color::chooseContrastColor(color), Qt::TextColorRole); + colorComboBox->model()->setData(idx, colorRepresentation, Qt::BackgroundColorRole); + colorComboBox->setItemData(i, Color::chooseContrastColor(colorRepresentation), Qt::TextColorRole); } - const QColor cueColor = pCue->getColor(); + PredefinedColorPointer cueColor = pCue->getColor(); colorComboBox->setCurrentIndex(predefinedColors.contains(cueColor) ? predefinedColors.indexOf(cueColor) : 0); @@ -416,10 +417,10 @@ void DlgTrackInfo::saveTrack() { auto colorComboBox = qobject_cast(colorWidget); if (colorComboBox) { - QColor color = Color::predefinedColors.at(colorComboBox->currentIndex()); - if (color.isValid()) { - pCue->setColor(color); - } + PredefinedColorPointer color = Color::predefinedColorSet.allColors.at(colorComboBox->currentIndex()); +// if (color.isValid()) { + //pCue->setColor(color); +// } } // do nothing for now. diff --git a/src/skin/skincontext.h b/src/skin/skincontext.h index 95753914dad..68aa3c371ea 100644 --- a/src/skin/skincontext.h +++ b/src/skin/skincontext.h @@ -14,7 +14,8 @@ #include "preferences/usersettings.h" #include "skin/pixmapsource.h" -#include "util/color.h" +#include "util/color/color.h" +#include "util/color/predefinedcolormap.h" #include "widget/wsingletoncontainer.h" #include "widget/wpixmapstore.h" @@ -267,16 +268,16 @@ class SkinContext { return m_scaleFactor; } - ColorsRepresentation getCueColorsRepresentation(const QDomNode& node) const { - ColorsRepresentation colorsReprsentation = Color::defaultRepresentation; - for (QLatin1String colorName : Color::predefinedColorsNames) { + PredefinedColorMap getCueColorMap(const QDomNode& node) const { + PredefinedColorMap colorMap = Color::predefinedColorSet.defaultMap(); + for (QString colorName : Color::predefinedColorSet.predefinedColorNames()) { QColor representation = selectColor(node, "Cue" + colorName); if (representation.isValid()) { - QColor originalColor = Color::predefinedColorFromName(colorName); - colorsReprsentation.setRepresentation(originalColor, representation); + PredefinedColorPointer originalColor = Color::predefinedColorSet.predefinedColorFromName(colorName); + colorMap.setRepresentation(originalColor, representation); } } - return colorsReprsentation; + return colorMap; } private: diff --git a/src/util/color.h b/src/util/color.h deleted file mode 100644 index c0b85f9ff38..00000000000 --- a/src/util/color.h +++ /dev/null @@ -1,175 +0,0 @@ -#ifndef COLOR_H -#define COLOR_H - -#include "util/math.h" - -#include -#include - -// Map the predefined colors to another color representation of them. -// -// Since QHash has copy-on-write, making a copy of ColorsRepresentation is fast. -// A deep copy of the QHash will be made when the copy is modified. -class ColorsRepresentation final { - public: - // Set a color representation for a given color - void setRepresentation(QColor color, QColor representation) { - m_colorNameMap[color.name()] = representation.name(); - } - - // Returns the representation of a color - QColor map(QColor color) const { - if (m_colorNameMap.contains(color.name())) { - return QColor(m_colorNameMap[color.name()]); - } - return color; - } - - private: - QHash m_colorNameMap; -}; - -// These methods and properties are not thread-safe, use them only on the GUI thread -namespace Color { - static const QColor Red = QColor("#E6194B"); - static const QColor Green = QColor("#3CB44B"); - static const QColor Yellow = QColor("#FFE119"); - static const QColor Blue = QColor("#4363D8"); - static const QColor Cyan = QColor("#42D4F4"); - static const QColor Magenta = QColor("#F032E6"); - static const QColor Pink = QColor("#FABEBE"); - static const QColor Teal = QColor("#469990"); - static const QColor Grey = QColor("#A9A9A9"); - - // Return a list with the predefined colors. - static const QList predefinedColors { - Red, - Green, - Yellow, - Blue, - Cyan, - Magenta, - Pink, - Teal, - Grey, - }; - - // Return a list with the internal names of the predefined colors. - static const QList predefinedColorsNames { - QLatin1String("Red"), - QLatin1String("Green"), - QLatin1String("Yellow"), - QLatin1String("Blue"), - QLatin1String("Cyan"), - QLatin1String("Magenta"), - QLatin1String("Pink"), - QLatin1String("Teal"), - QLatin1String("Grey"), - }; - - // Return a predefined color code from its internal name. - static QColor predefinedColorFromName(QLatin1String name) { - if (name == QLatin1String("Red")) { - return Red; - } else if (name == QLatin1String("Green")) { - return Green; - } else if (name == QLatin1String("Yellow")) { - return Yellow; - } else if (name == QLatin1String("Blue")) { - return Blue; - } else if (name == QLatin1String("Cyan")) { - return Cyan; - } else if (name == QLatin1String("Magenta")) { - return Magenta; - } else if (name == QLatin1String("Pink")) { - return Pink; - } else if (name == QLatin1String("Teal")) { - return Teal; - } else if (name == QLatin1String("Grey")) { - return Grey; - } - return Red; - }; - - // Return the localized name of a predefined color. - // Returns "Undefined Color" if color is not a predefined color. - static QString displayName(QColor color) { - if (color == Red) { - return QObject::tr("Red"); - } else if (color == Green) { - return QObject::tr("Green"); - } else if (color == Yellow) { - return QObject::tr("Yellow"); - } else if (color == Blue) { - return QObject::tr("Blue"); - } else if (color == Cyan) { - return QObject::tr("Cyan"); - } else if (color == Magenta) { - return QObject::tr("Magenta"); - } else if (color == Pink) { - return QObject::tr("Pink"); - } else if (color == Teal) { - return QObject::tr("Teal"); - - } else if (color == Grey) { - return QObject::tr("Grey"); - } - return QObject::tr("Undefined Color"); - }; - - // The default colors representation, i.e. maps each default color to itself. - // Stores the color's name() property, e.g. "#A9A9A9" - // - // It's fast to copy the default representation. See comment on ColorsRepresentation. - static const ColorsRepresentation defaultRepresentation = [](){ - ColorsRepresentation representation = ColorsRepresentation(); - for (QColor color : predefinedColors) { - representation.setRepresentation(color, color); - } - return representation; - }(); - - - // 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 - // NOTE: the author did not take alpha transparency into account! - static inline int brightness(int red, int green, int blue) { - return static_cast(sqrtf( - red * red * .241 + - green * green * .691 + - blue * blue * .068) - ); - }; - - static inline int brightness(const QColor& color) { - return brightness(color.red(), color.green(), color.red()); - } - - static inline bool isDimmColor(const QColor& color) { - return brightness(color) <= 127; - } - - // If the colorToChooseBy is darker than the global threshold, - // dimmColor will be returned. Otherwise brightColor will be returned. - static inline QColor chooseColorByBrightness(QColor colorToChooseBy, QColor dimmColor , QColor brightColor) { - return isDimmColor(colorToChooseBy) ? dimmColor : brightColor; - } - - // If the baseColor is darker than the global threshold, - // returns white, otherwise returns black. - static inline QColor chooseContrastColor(QColor baseColor) { - QColor lightColor = baseColor.lighter(); - QColor darkColor = baseColor.darker(); - - // QColor::lighter() multiplies the HSV Value by some factor. When baseColor is black, Value is 0, - // thus after multiplication it's still 0 and we get the same color. - // We manually set lightColor to darkGray in this case. - if (baseColor.toHsv().value() == 0) { - lightColor = Qt::darkGray; - lightColor.setAlpha(baseColor.alpha()); - } - return chooseColorByBrightness(baseColor, lightColor, darkColor); - } -}; -#endif /* COLOR_H */ diff --git a/src/util/color/color.h b/src/util/color/color.h new file mode 100644 index 00000000000..3ec531937aa --- /dev/null +++ b/src/util/color/color.h @@ -0,0 +1,55 @@ +#ifndef PREDEFINEDCOLORSET_H +#define PREDEFINEDCOLORSET_H + +#include +#include + +#include "util/color/predefinedcolorset.h" +#include "util/math.h" + +namespace Color { + static const PredefinedColorSet predefinedColorSet = PredefinedColorSet(); + + // 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 + // NOTE: the author did not take alpha transparency into account! + static inline int brightness(int red, int green, int blue) { + return static_cast(sqrtf( + red * red * .241 + + green * green * .691 + + blue * blue * .068) + ); + }; + + static inline int brightness(const QColor& color) { + return brightness(color.red(), color.green(), color.red()); + } + + static inline bool isDimmColor(const QColor& color) { + return brightness(color) <= 127; + } + + // If the colorToChooseBy is darker than the global threshold, + // dimmColor will be returned. Otherwise brightColor will be returned. + static inline QColor chooseColorByBrightness(QColor colorToChooseBy, QColor dimmColor , QColor brightColor) { + return isDimmColor(colorToChooseBy) ? dimmColor : brightColor; + } + + // If the baseColor is darker than the global threshold, + // returns white, otherwise returns black. + static inline QColor chooseContrastColor(QColor baseColor) { + QColor lightColor = baseColor.lighter(); + QColor darkColor = baseColor.darker(); + + // QColor::lighter() multiplies the HSV Value by some factor. When baseColor is black, Value is 0, + // thus after multiplication it's still 0 and we get the same color. + // We manually set lightColor to darkGray in this case. + if (baseColor.toHsv().value() == 0) { + lightColor = Qt::darkGray; + lightColor.setAlpha(baseColor.alpha()); + } + return chooseColorByBrightness(baseColor, lightColor, darkColor); + } +} +#endif /* PREDEFINEDCOLORSET_H */ diff --git a/src/util/color/predefinedcolor.cpp b/src/util/color/predefinedcolor.cpp new file mode 100644 index 00000000000..34a83216360 --- /dev/null +++ b/src/util/color/predefinedcolor.cpp @@ -0,0 +1,10 @@ +#include "util/color/predefinedcolor.h" + +#include "utils/color/color.h" + +PredefinedColor::PredefinedColor(QColor defaultRepresentation, QString sName, QString sDisplayName) + : m_defaultRepresentation(defaultRepresentation), + m_sName(sName), + m_sDisplayName(sDisplayName), + m_iBrightness(Color::brightness(defaultRepresentation)) { +} diff --git a/src/util/color/predefinedcolor.h b/src/util/color/predefinedcolor.h new file mode 100644 index 00000000000..a26039f225e --- /dev/null +++ b/src/util/color/predefinedcolor.h @@ -0,0 +1,17 @@ +#ifndef PREDEFINEDCOLOR_H +#define PREDEFINEDCOLOR_H + +#include + +class PredefinedColor final { + public: + PredefinedColor(QColor defaultRepresentation, QString sName, QString sDisplayName); + + const QColor m_defaultRepresentation; + const QString m_sName; + const QString m_sDisplayName; + const int m_iBrightness; +}; +typedef std::shared_ptr PredefinedColorPointer; + +#endif /* PREDEFINEDCOLOR_H */ diff --git a/src/util/color/predefinedcolormap.cpp b/src/util/color/predefinedcolormap.cpp new file mode 100644 index 00000000000..66e64674857 --- /dev/null +++ b/src/util/color/predefinedcolormap.cpp @@ -0,0 +1,13 @@ +#include "predefinedcolormap.h" + +void PredefinedColorMap::setRepresentation(PredefinedColorPointer color, QColor representation) { + m_colorNameMap[color.m_defaultRepresentation.name()] = representation.name(); +} + +QColor PredefinedColorMap::map(PredefinedColorPointer color) const { + QColor defaultRepresentation = color->m_defaultRepresentation; + if (m_colorNameMap.contains(defaultRepresentation.name())) { + return QColor(m_colorNameMap[defaultRepresentation.name()]); + } + return color; +} diff --git a/src/util/color/predefinedcolormap.h b/src/util/color/predefinedcolormap.h new file mode 100644 index 00000000000..92cd637d4f5 --- /dev/null +++ b/src/util/color/predefinedcolormap.h @@ -0,0 +1,27 @@ +#ifndef PREDEFINEDCOLORMAP_H +#define PREDEFINEDCOLORMAP_H + +#include +#include + +#include "util/color/predefinedcolor.h" + +// Map the predefined colors to another color representation of them. +// +// Uses the color's name() property as key, e.g. "#A9A9A9" +// Since QHash has copy-on-write, making a copy of ColorsRepresentation is fast. +// A deep copy of the QHash will be made when the copy is modified. +class PredefinedColorMap final { + public: + // Set a color representation for a given color + void setRepresentation(PredefinedColorPointer color, QColor representation); + + // Returns the representation of a color + QColor map(PredefinedColorPointer color) const; + + + private: + QHash m_colorNameMap; +}; + +#endif /* PREDEFINEDCOLORMAP_H */ diff --git a/src/util/color/predefinedcolorset.cpp b/src/util/color/predefinedcolorset.cpp new file mode 100644 index 00000000000..5e240bfa800 --- /dev/null +++ b/src/util/color/predefinedcolorset.cpp @@ -0,0 +1,13 @@ +#include "util/color/predefinedcolorset.h" + +PredefinedColorSet::PredefinedColorSet() + : m_predefinedColorsNames(), m_defaultMap() { + + for (PredefinedColor color : allColors) { + m_predefinedColorsNames << color.m_sName; + } + + for (PredefinedColor color : allColors) { + m_defaultMap.setRepresentation(color, color.m_defaultRepresentation); + } +} diff --git a/src/util/color/predefinedcolorset.h b/src/util/color/predefinedcolorset.h new file mode 100644 index 00000000000..7149bfb962a --- /dev/null +++ b/src/util/color/predefinedcolorset.h @@ -0,0 +1,100 @@ +#ifndef COLOR_H +#define COLOR_H + +#include + +#include "util/color/predefinedcolor.h" +#include "util/color/predefinedcolormap.h" + +// These methods and properties are not thread-safe, use them only on the GUI thread +class PredefinedColorSet final { + public: + const PredefinedColorPointer red = std::make_shared( + QColor("#E6194B"), + QLatin1String("Red"), + QObject::tr("Red") + ); + const PredefinedColorPointer green = std::make_shared( + QColor("#3CB44B"), + QLatin1String("Green"), + QObject::tr("Green") + ); + const PredefinedColorPointer yellow = std::make_shared( + QColor("#FFE119"), + QLatin1String("Yellow"), + QObject::tr("Yellow") + ); + const PredefinedColorPointer blue = std::make_shared( + QColor("#4363D8"), + QLatin1String("Blue"), + QObject::tr("Blue") + ); + const PredefinedColorPointer cyan = std::make_shared( + QColor("#42D4F4"), + QLatin1String("Cyan"), + QObject::tr("Cyan") + ); + const PredefinedColorPointer magenta = std::make_shared( + QColor("#F032E6"), + QLatin1String("Magenta"), + QObject::tr("Magenta") + ); + const PredefinedColorPointer pink = std::make_shared( + QColor("#FABEBE"), + QLatin1String("Pink"), + QObject::tr("Pink") + ); + const PredefinedColorPointer teal = std::make_shared( + QColor("#469990"), + QLatin1String("Teal"), + QObject::tr("Teal") + ); + const PredefinedColorPointer grey = std::make_shared( + QColor("#A9A9A9"), + QLatin1String("Grey"), + QObject::tr("Grey") + ); + const PredefinedColorPointer invalid = std::make_shared( + QColor(), + QLatin1String("Invalid Color"), + QObject::tr("Invalid Color") + ); + + // The list of the predefined colors. + const QList allColors { + red, + green, + yellow, + blue, + cyan, + magenta, + pink, + teal, + grey, + }; + + PredefinedColorSet(); + + // A list with the internal names of the predefined colors. + QList predefinedColorNames() const { return m_predefinedColorsNames; }; + + // Return a predefined color from its internal name. + PredefinedColorPointer predefinedColorFromName(QString name) const { + for (PredefinedColorPointer color : allColors) { + if (color->m_sName == name) { + return color; + } + } + return invalid; + }; + + // The default color map, i.e. maps each predefined color to itself. + // + // It's fast to copy the default representation. See comment on ColorsRepresentation. + PredefinedColorMap defaultMap() const { return m_defaultMap; }; + + private: + QList m_predefinedColorsNames; + PredefinedColorMap m_defaultMap; +}; +#endif /* COLOR_H */ diff --git a/src/waveform/renderers/waveformrendermark.cpp b/src/waveform/renderers/waveformrendermark.cpp index b6119e13709..0b9dcfa429b 100644 --- a/src/waveform/renderers/waveformrendermark.cpp +++ b/src/waveform/renderers/waveformrendermark.cpp @@ -23,7 +23,7 @@ WaveformRenderMark::WaveformRenderMark( } void WaveformRenderMark::setup(const QDomNode& node, const SkinContext& context) { - m_predefinedColorsRepresentation = context.getCueColorsRepresentation(node); + m_predefinedColorsRepresentation = context.getCueColorMap(node); m_marks.setup(m_waveformRenderer->getGroup(), node, context, *m_waveformRenderer->getWaveformSignalColors()); } diff --git a/src/waveform/renderers/waveformrendermark.h b/src/waveform/renderers/waveformrendermark.h index bb5a9ee04f6..6207ac87b5a 100644 --- a/src/waveform/renderers/waveformrendermark.h +++ b/src/waveform/renderers/waveformrendermark.h @@ -34,7 +34,7 @@ class WaveformRenderMark : public QObject, public WaveformRendererAbstract { private: void generateMarkImage(WaveformMark* pMark); - ColorsRepresentation m_predefinedColorsRepresentation; + PredefinedColorMap m_predefinedColorsRepresentation; WaveformMarkSet m_marks; DISALLOW_COPY_AND_ASSIGN(WaveformRenderMark); diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index 47031d94efb..9eb4a8e26f4 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -91,7 +91,7 @@ void WOverview::setup(const QDomNode& node, const SkinContext& context) { } // setup hotcues and cue and loop(s) - m_predefinedColorsRepresentation = context.getCueColorsRepresentation(node); + m_predefinedColorsRepresentation = context.getCueColorMap(node); m_marks.setup(m_group, node, context, m_signalColors); for (const auto& pMark: m_marks) { diff --git a/src/widget/woverview.h b/src/widget/woverview.h index f4e746ce5af..d6e0dda5de2 100644 --- a/src/widget/woverview.h +++ b/src/widget/woverview.h @@ -22,7 +22,7 @@ #include "widget/wwidget.h" #include "analyzer/analyzerprogress.h" -#include "util/color.h" +#include "util/color/color.h" #include "waveform/renderers/waveformsignalcolors.h" #include "waveform/renderers/waveformmarkset.h" @@ -130,7 +130,7 @@ class WOverview : public WWidget { QColor m_qColorBackground; QColor m_endOfTrackColor; - ColorsRepresentation m_predefinedColorsRepresentation; + PredefinedColorMap m_predefinedColorsRepresentation; WaveformMarkSet m_marks; std::vector m_markRanges; From e2caa1eb205d434707f0a23f635d4edfd219060d Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Wed, 30 Jan 2019 21:38:55 +0100 Subject: [PATCH 32/56] Represent cue colors by id instead of color code in CO and DB --- build/depends.py | 3 +- src/engine/controls/cuecontrol.cpp | 5 +- src/library/dao/cue.cpp | 6 +- src/library/dao/cue.h | 4 +- src/library/dao/cuedao.cpp | 9 ++- src/library/dlgtrackinfo.cpp | 13 ++-- src/util/color/predefinedcolor.cpp | 5 +- src/util/color/predefinedcolor.h | 11 +++- src/util/color/predefinedcolormap.cpp | 4 +- src/util/color/predefinedcolorset.cpp | 9 +-- src/util/color/predefinedcolorset.h | 62 ++++++++++++++----- src/waveform/renderers/waveformrendermark.cpp | 2 +- src/waveform/renderers/waveformrendermark.h | 2 +- src/widget/woverview.cpp | 2 +- 14 files changed, 90 insertions(+), 47 deletions(-) diff --git a/build/depends.py b/build/depends.py index 3dfe8f4ce58..479d29f79d2 100644 --- a/build/depends.py +++ b/build/depends.py @@ -1225,7 +1225,8 @@ def sources(self, build): "src/util/widgetrendertimer.cpp", "src/util/workerthread.cpp", "src/util/workerthreadscheduler.cpp", - "src/util/color/predefinedcolormap.cpp" + "src/util/color/predefinedcolor.cpp", + "src/util/color/predefinedcolormap.cpp", "src/util/color/predefinedcolorset.cpp" ] diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index 85a0cb3d818..9f29317f6cb 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -12,6 +12,7 @@ #include "control/controlindicator.h" #include "vinylcontrol/defs_vinylcontrol.h" #include "util/sample.h" +#include "util/color/color.h" // TODO: Convert these doubles to a standard enum // and convert elseif logic to switch statements @@ -297,7 +298,7 @@ void CueControl::trackCuesUpdated() { } else { // If the old hotcue is the same, then we only need to update pControl->setPosition(pCue->getPosition()); - pControl->setColor(pCue->getColor()); + pControl->setColor(pCue->getColor()->m_iId); } // Add the hotcue to the list of active hotcues active_hotcues.insert(hotcue); @@ -1129,7 +1130,7 @@ void HotcueControl::slotHotcuePositionChanged(double newPosition) { } void HotcueControl::slotHotcueColorChanged(double newColor) { - m_pCue->setColor(QColor(static_cast(newColor))); + m_pCue->setColor(Color::predefinedColorSet.predefinedColorFromId(newColor)); emit(hotcueColorChanged(this, newColor)); } diff --git a/src/library/dao/cue.cpp b/src/library/dao/cue.cpp index e6564798b4b..e5fe794be32 100644 --- a/src/library/dao/cue.cpp +++ b/src/library/dao/cue.cpp @@ -6,9 +6,9 @@ #include "library/dao/cue.h" #include "util/assert.h" +#include "util/color/color.h" namespace { - const QColor kDefaultColor = QColor("#FF0000"); const QString kDefaultLabel = ""; // empty string, not null } @@ -25,13 +25,13 @@ Cue::Cue(TrackId trackId) m_length(0.0), m_iHotCue(-1), m_label(kDefaultLabel), - m_color(kDefaultColor) { + m_color(Color::predefinedColorSet.invalid) { DEBUG_ASSERT(!m_label.isNull()); } Cue::Cue(int id, TrackId trackId, Cue::CueType type, double position, double length, - int hotCue, QString label, QColor color) + int hotCue, QString label, PredefinedColorPointer color) : m_bDirty(false), m_iId(id), m_trackId(trackId), diff --git a/src/library/dao/cue.h b/src/library/dao/cue.h index 21344d60716..e249645bf97 100644 --- a/src/library/dao/cue.h +++ b/src/library/dao/cue.h @@ -54,7 +54,7 @@ class Cue : public QObject { private: explicit Cue(TrackId trackId); Cue(int id, TrackId trackId, CueType type, double position, double length, - int hotCue, QString label, QColor color); + int hotCue, QString label, PredefinedColorPointer color); void setDirty(bool dirty); void setId(int id); void setTrackId(TrackId trackId); @@ -69,7 +69,7 @@ class Cue : public QObject { double m_length; int m_iHotCue; QString m_label; - QColor m_color; + PredefinedColorPointer m_color; friend class Track; friend class CueDAO; diff --git a/src/library/dao/cuedao.cpp b/src/library/dao/cuedao.cpp index 66a4e440c90..872f5b1da14 100644 --- a/src/library/dao/cuedao.cpp +++ b/src/library/dao/cuedao.cpp @@ -11,6 +11,8 @@ #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() { qDebug() << "CueDAO::cueCount" << QThread::currentThread() << m_database.connectionName(); @@ -51,7 +53,8 @@ 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(); - QColor color = QColor::fromRgba(record.value(record.indexOf("color")).toInt()); + int iColorId = record.value(record.indexOf("color")).toInt(); + PredefinedColorPointer color = Color::predefinedColorSet.predefinedColorFromId(iColorId); CuePointer pCue(new Cue(id, trackId, (Cue::CueType)type, position, length, hotcue, label, color)); m_cues[id] = pCue; @@ -145,7 +148,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", cue->getColor()->m_iId); if (query.exec()) { int id = query.lastInsertId().toInt(); @@ -173,7 +176,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", cue->getColor()->m_iId); if (query.exec()) { cue->setDirty(false); diff --git a/src/library/dlgtrackinfo.cpp b/src/library/dlgtrackinfo.cpp index ad303e7efa7..4dbdbb3db5a 100644 --- a/src/library/dlgtrackinfo.cpp +++ b/src/library/dlgtrackinfo.cpp @@ -329,21 +329,20 @@ void DlgTrackInfo::populateCues(TrackPointer pTrack) { QColor colorRepresentation = color->m_defaultRepresentation; colorComboBox->addItem(color->m_sDisplayName, colorRepresentation); const QModelIndex idx = colorComboBox->model()->index(i, 0); - colorComboBox->model()->setData(idx, colorRepresentation, Qt::BackgroundColorRole); + if (*color != *Color::predefinedColorSet.invalid) { + colorComboBox->model()->setData(idx, colorRepresentation, Qt::BackgroundColorRole); + } colorComboBox->setItemData(i, Color::chooseContrastColor(colorRepresentation), Qt::TextColorRole); } PredefinedColorPointer cueColor = pCue->getColor(); - colorComboBox->setCurrentIndex(predefinedColors.contains(cueColor) - ? predefinedColors.indexOf(cueColor) - : 0); + colorComboBox->setCurrentIndex(Color::predefinedColorSet.predefinedColorIndex(cueColor)); m_cueMap[row] = pCue; cueTable->insertRow(row); cueTable->setItem(row, 0, new QTableWidgetItem(rowStr)); cueTable->setItem(row, 1, durationItem); cueTable->setItem(row, 2, new QTableWidgetItem(hotcue)); - // cueTable->setItem(row, 3, new QTableWidgetItem(cueColor.name().toUpper())); cueTable->setCellWidget(row, 3, colorComboBox); cueTable->setItem(row, 4, new QTableWidgetItem(pCue->getLabel())); row += 1; @@ -418,9 +417,7 @@ void DlgTrackInfo::saveTrack() { auto colorComboBox = qobject_cast(colorWidget); if (colorComboBox) { PredefinedColorPointer color = Color::predefinedColorSet.allColors.at(colorComboBox->currentIndex()); -// if (color.isValid()) { - //pCue->setColor(color); -// } + pCue->setColor(color); } // do nothing for now. diff --git a/src/util/color/predefinedcolor.cpp b/src/util/color/predefinedcolor.cpp index 34a83216360..516b9a12711 100644 --- a/src/util/color/predefinedcolor.cpp +++ b/src/util/color/predefinedcolor.cpp @@ -1,10 +1,11 @@ #include "util/color/predefinedcolor.h" -#include "utils/color/color.h" +#include "util/color/color.h" -PredefinedColor::PredefinedColor(QColor defaultRepresentation, QString sName, QString sDisplayName) +PredefinedColor::PredefinedColor(QColor defaultRepresentation, QString sName, QString sDisplayName, int iId) : m_defaultRepresentation(defaultRepresentation), m_sName(sName), m_sDisplayName(sDisplayName), + m_iId(iId), m_iBrightness(Color::brightness(defaultRepresentation)) { } diff --git a/src/util/color/predefinedcolor.h b/src/util/color/predefinedcolor.h index a26039f225e..83012f48062 100644 --- a/src/util/color/predefinedcolor.h +++ b/src/util/color/predefinedcolor.h @@ -5,11 +5,20 @@ class PredefinedColor final { public: - PredefinedColor(QColor defaultRepresentation, QString sName, QString sDisplayName); + PredefinedColor(QColor defaultRepresentation, 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; + } const QColor m_defaultRepresentation; const QString m_sName; const QString m_sDisplayName; + const int m_iId; const int m_iBrightness; }; typedef std::shared_ptr PredefinedColorPointer; diff --git a/src/util/color/predefinedcolormap.cpp b/src/util/color/predefinedcolormap.cpp index 66e64674857..fa46b6ba63d 100644 --- a/src/util/color/predefinedcolormap.cpp +++ b/src/util/color/predefinedcolormap.cpp @@ -1,7 +1,7 @@ #include "predefinedcolormap.h" void PredefinedColorMap::setRepresentation(PredefinedColorPointer color, QColor representation) { - m_colorNameMap[color.m_defaultRepresentation.name()] = representation.name(); + m_colorNameMap[color->m_defaultRepresentation.name()] = representation.name(); } QColor PredefinedColorMap::map(PredefinedColorPointer color) const { @@ -9,5 +9,5 @@ QColor PredefinedColorMap::map(PredefinedColorPointer color) const { if (m_colorNameMap.contains(defaultRepresentation.name())) { return QColor(m_colorNameMap[defaultRepresentation.name()]); } - return color; + return defaultRepresentation; } diff --git a/src/util/color/predefinedcolorset.cpp b/src/util/color/predefinedcolorset.cpp index 5e240bfa800..1f298b80632 100644 --- a/src/util/color/predefinedcolorset.cpp +++ b/src/util/color/predefinedcolorset.cpp @@ -3,11 +3,8 @@ PredefinedColorSet::PredefinedColorSet() : m_predefinedColorsNames(), m_defaultMap() { - for (PredefinedColor color : allColors) { - m_predefinedColorsNames << color.m_sName; - } - - for (PredefinedColor color : allColors) { - m_defaultMap.setRepresentation(color, color.m_defaultRepresentation); + for (PredefinedColorPointer color : allColors) { + m_predefinedColorsNames << color->m_sName; + m_defaultMap.setRepresentation(color, color->m_defaultRepresentation); } } diff --git a/src/util/color/predefinedcolorset.h b/src/util/color/predefinedcolorset.h index 7149bfb962a..b91486ffab9 100644 --- a/src/util/color/predefinedcolorset.h +++ b/src/util/color/predefinedcolorset.h @@ -2,6 +2,7 @@ #define COLOR_H #include +#include #include "util/color/predefinedcolor.h" #include "util/color/predefinedcolormap.h" @@ -9,59 +10,70 @@ // These methods and properties are not thread-safe, use them only on the GUI thread class PredefinedColorSet final { public: + const PredefinedColorPointer invalid = std::make_shared( + QColor(), + QLatin1String("Invalid Color"), + QObject::tr("Invalid Color"), + 0 + ); const PredefinedColorPointer red = std::make_shared( QColor("#E6194B"), QLatin1String("Red"), - QObject::tr("Red") + QObject::tr("Red"), + 1 ); const PredefinedColorPointer green = std::make_shared( QColor("#3CB44B"), QLatin1String("Green"), - QObject::tr("Green") + QObject::tr("Green"), + 2 ); const PredefinedColorPointer yellow = std::make_shared( QColor("#FFE119"), QLatin1String("Yellow"), - QObject::tr("Yellow") + QObject::tr("Yellow"), + 3 ); const PredefinedColorPointer blue = std::make_shared( QColor("#4363D8"), QLatin1String("Blue"), - QObject::tr("Blue") + QObject::tr("Blue"), + 4 ); const PredefinedColorPointer cyan = std::make_shared( QColor("#42D4F4"), QLatin1String("Cyan"), - QObject::tr("Cyan") + QObject::tr("Cyan"), + 5 ); const PredefinedColorPointer magenta = std::make_shared( QColor("#F032E6"), QLatin1String("Magenta"), - QObject::tr("Magenta") + QObject::tr("Magenta"), + 6 ); const PredefinedColorPointer pink = std::make_shared( QColor("#FABEBE"), QLatin1String("Pink"), - QObject::tr("Pink") + QObject::tr("Pink"), + 7 ); const PredefinedColorPointer teal = std::make_shared( QColor("#469990"), QLatin1String("Teal"), - QObject::tr("Teal") + QObject::tr("Teal"), + 8 ); const PredefinedColorPointer grey = std::make_shared( QColor("#A9A9A9"), QLatin1String("Grey"), - QObject::tr("Grey") - ); - const PredefinedColorPointer invalid = std::make_shared( - QColor(), - QLatin1String("Invalid Color"), - QObject::tr("Invalid Color") + QObject::tr("Grey"), + 9 ); // The list of the predefined colors. const QList allColors { + invalid, red, green, yellow, @@ -78,6 +90,18 @@ class PredefinedColorSet final { // A list with the internal names of the predefined colors. QList predefinedColorNames() const { return m_predefinedColorsNames; }; + // Returns the position of a PredefinedColor in the allColors list. + int predefinedColorIndex(PredefinedColorPointer searchedColor) const { + int position = 0; + for (PredefinedColorPointer color : allColors) { + if (*color == *searchedColor) { + return position; + } + position++; + } + return 0; + }; + // Return a predefined color from its internal name. PredefinedColorPointer predefinedColorFromName(QString name) const { for (PredefinedColorPointer color : allColors) { @@ -88,6 +112,16 @@ class PredefinedColorSet final { return invalid; }; + // Return a predefined color from its id. + PredefinedColorPointer predefinedColorFromId(int iId) const { + for (PredefinedColorPointer color : allColors) { + if (color->m_iId == iId) { + return color; + } + } + return invalid; + }; + // The default color map, i.e. maps each predefined color to itself. // // It's fast to copy the default representation. See comment on ColorsRepresentation. diff --git a/src/waveform/renderers/waveformrendermark.cpp b/src/waveform/renderers/waveformrendermark.cpp index 0b9dcfa429b..b0a95a690ac 100644 --- a/src/waveform/renderers/waveformrendermark.cpp +++ b/src/waveform/renderers/waveformrendermark.cpp @@ -6,7 +6,7 @@ #include "control/controlproxy.h" #include "track/track.h" -#include "util/color.h" +#include "util/color/color.h" #include "waveform/renderers/waveformwidgetrenderer.h" #include "waveform/waveform.h" #include "widget/wskincolor.h" diff --git a/src/waveform/renderers/waveformrendermark.h b/src/waveform/renderers/waveformrendermark.h index 6207ac87b5a..92dc64b89df 100644 --- a/src/waveform/renderers/waveformrendermark.h +++ b/src/waveform/renderers/waveformrendermark.h @@ -5,7 +5,7 @@ #include "skin/skincontext.h" #include "util/class.h" -#include "util/color.h" +#include "util/color/color.h" #include "waveform/renderers/waveformmarkset.h" #include "waveform/renderers/waveformrendererabstract.h" #include "library/dao/cue.h" diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index 9eb4a8e26f4..72c6aaa9ccb 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -27,7 +27,7 @@ #include "widget/controlwidgetconnection.h" #include "track/track.h" #include "analyzer/analyzerprogress.h" -#include "util/color.h" +#include "util/color/color.h" #include "util/math.h" #include "util/timer.h" #include "util/dnd.h" From 7308ba07b89ea96e28018679dcd1b239f5340459 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Wed, 30 Jan 2019 21:46:49 +0100 Subject: [PATCH 33/56] Rename invalid color to noColor --- src/library/dao/cue.cpp | 2 +- src/library/dlgtrackinfo.cpp | 2 +- src/util/color/predefinedcolorset.h | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/library/dao/cue.cpp b/src/library/dao/cue.cpp index e5fe794be32..377c97740d1 100644 --- a/src/library/dao/cue.cpp +++ b/src/library/dao/cue.cpp @@ -25,7 +25,7 @@ Cue::Cue(TrackId trackId) m_length(0.0), m_iHotCue(-1), m_label(kDefaultLabel), - m_color(Color::predefinedColorSet.invalid) { + m_color(Color::predefinedColorSet.noColor) { DEBUG_ASSERT(!m_label.isNull()); } diff --git a/src/library/dlgtrackinfo.cpp b/src/library/dlgtrackinfo.cpp index 4dbdbb3db5a..4496a92bf6c 100644 --- a/src/library/dlgtrackinfo.cpp +++ b/src/library/dlgtrackinfo.cpp @@ -329,7 +329,7 @@ void DlgTrackInfo::populateCues(TrackPointer pTrack) { QColor colorRepresentation = color->m_defaultRepresentation; colorComboBox->addItem(color->m_sDisplayName, colorRepresentation); const QModelIndex idx = colorComboBox->model()->index(i, 0); - if (*color != *Color::predefinedColorSet.invalid) { + if (*color != *Color::predefinedColorSet.noColor) { colorComboBox->model()->setData(idx, colorRepresentation, Qt::BackgroundColorRole); } colorComboBox->setItemData(i, Color::chooseContrastColor(colorRepresentation), Qt::TextColorRole); diff --git a/src/util/color/predefinedcolorset.h b/src/util/color/predefinedcolorset.h index b91486ffab9..ae29e9cc897 100644 --- a/src/util/color/predefinedcolorset.h +++ b/src/util/color/predefinedcolorset.h @@ -10,10 +10,10 @@ // These methods and properties are not thread-safe, use them only on the GUI thread class PredefinedColorSet final { public: - const PredefinedColorPointer invalid = std::make_shared( + const PredefinedColorPointer noColor = std::make_shared( QColor(), - QLatin1String("Invalid Color"), - QObject::tr("Invalid Color"), + QLatin1String("No Color"), + QObject::tr("No Color"), 0 ); const PredefinedColorPointer red = std::make_shared( @@ -73,7 +73,7 @@ class PredefinedColorSet final { // The list of the predefined colors. const QList allColors { - invalid, + noColor, red, green, yellow, @@ -109,7 +109,7 @@ class PredefinedColorSet final { return color; } } - return invalid; + return noColor; }; // Return a predefined color from its id. @@ -119,7 +119,7 @@ class PredefinedColorSet final { return color; } } - return invalid; + return noColor; }; // The default color map, i.e. maps each predefined color to itself. From 4bc2549b48c31209217c2ed451ee8a59c92e730c Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Wed, 30 Jan 2019 21:58:37 +0100 Subject: [PATCH 34/56] Remove some cpp files --- build/depends.py | 4 +--- src/util/color/predefinedcolormap.cpp | 13 ------------- src/util/color/predefinedcolormap.h | 12 ++++++++++-- src/util/color/predefinedcolorset.cpp | 10 ---------- src/util/color/predefinedcolorset.h | 9 ++++++++- 5 files changed, 19 insertions(+), 29 deletions(-) delete mode 100644 src/util/color/predefinedcolormap.cpp delete mode 100644 src/util/color/predefinedcolorset.cpp diff --git a/build/depends.py b/build/depends.py index 479d29f79d2..d06b247a1cb 100644 --- a/build/depends.py +++ b/build/depends.py @@ -1225,9 +1225,7 @@ def sources(self, build): "src/util/widgetrendertimer.cpp", "src/util/workerthread.cpp", "src/util/workerthreadscheduler.cpp", - "src/util/color/predefinedcolor.cpp", - "src/util/color/predefinedcolormap.cpp", - "src/util/color/predefinedcolorset.cpp" + "src/util/color/predefinedcolor.cpp" ] proto_args = { diff --git a/src/util/color/predefinedcolormap.cpp b/src/util/color/predefinedcolormap.cpp deleted file mode 100644 index fa46b6ba63d..00000000000 --- a/src/util/color/predefinedcolormap.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "predefinedcolormap.h" - -void PredefinedColorMap::setRepresentation(PredefinedColorPointer color, QColor representation) { - m_colorNameMap[color->m_defaultRepresentation.name()] = representation.name(); -} - -QColor PredefinedColorMap::map(PredefinedColorPointer color) const { - QColor defaultRepresentation = color->m_defaultRepresentation; - if (m_colorNameMap.contains(defaultRepresentation.name())) { - return QColor(m_colorNameMap[defaultRepresentation.name()]); - } - return defaultRepresentation; -} diff --git a/src/util/color/predefinedcolormap.h b/src/util/color/predefinedcolormap.h index 92cd637d4f5..58575614ee0 100644 --- a/src/util/color/predefinedcolormap.h +++ b/src/util/color/predefinedcolormap.h @@ -14,10 +14,18 @@ class PredefinedColorMap final { public: // Set a color representation for a given color - void setRepresentation(PredefinedColorPointer color, QColor representation); + void setRepresentation(PredefinedColorPointer color, QColor representation) { + m_colorNameMap[color->m_defaultRepresentation.name()] = representation.name(); + } // Returns the representation of a color - QColor map(PredefinedColorPointer color) const; + QColor map(PredefinedColorPointer color) const { + QColor defaultRepresentation = color->m_defaultRepresentation; + if (m_colorNameMap.contains(defaultRepresentation.name())) { + return QColor(m_colorNameMap[defaultRepresentation.name()]); + } + return defaultRepresentation; + } private: diff --git a/src/util/color/predefinedcolorset.cpp b/src/util/color/predefinedcolorset.cpp deleted file mode 100644 index 1f298b80632..00000000000 --- a/src/util/color/predefinedcolorset.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "util/color/predefinedcolorset.h" - -PredefinedColorSet::PredefinedColorSet() - : m_predefinedColorsNames(), m_defaultMap() { - - for (PredefinedColorPointer color : allColors) { - m_predefinedColorsNames << color->m_sName; - m_defaultMap.setRepresentation(color, color->m_defaultRepresentation); - } -} diff --git a/src/util/color/predefinedcolorset.h b/src/util/color/predefinedcolorset.h index ae29e9cc897..6e2bb8ee602 100644 --- a/src/util/color/predefinedcolorset.h +++ b/src/util/color/predefinedcolorset.h @@ -85,7 +85,14 @@ class PredefinedColorSet final { grey, }; - PredefinedColorSet(); + PredefinedColorSet() + : m_predefinedColorsNames(), m_defaultMap() { + + for (PredefinedColorPointer color : allColors) { + m_predefinedColorsNames << color->m_sName; + m_defaultMap.setRepresentation(color, color->m_defaultRepresentation); + } + } // A list with the internal names of the predefined colors. QList predefinedColorNames() const { return m_predefinedColorsNames; }; From 84bb67045c68f351c264efa5118cf29ebdfa0182 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Thu, 31 Jan 2019 00:34:49 +0100 Subject: [PATCH 35/56] Improve code comments --- src/util/color/predefinedcolor.h | 5 +++++ src/util/color/predefinedcolormap.h | 10 +++++++--- src/util/color/predefinedcolorset.h | 14 ++++++++------ 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/util/color/predefinedcolor.h b/src/util/color/predefinedcolor.h index 83012f48062..dfda5993cbf 100644 --- a/src/util/color/predefinedcolor.h +++ b/src/util/color/predefinedcolor.h @@ -15,10 +15,15 @@ class PredefinedColor final { return m_iId != other.m_iId; } + // The QColor that is used by default to render this PredefinedColor. const QColor m_defaultRepresentation; + // The name of the color used programatically, 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. const int m_iId; + // The brightness of this color, calculated with Color::brightness(const QColor&) const int m_iBrightness; }; typedef std::shared_ptr PredefinedColorPointer; diff --git a/src/util/color/predefinedcolormap.h b/src/util/color/predefinedcolormap.h index 58575614ee0..7feb37be8a0 100644 --- a/src/util/color/predefinedcolormap.h +++ b/src/util/color/predefinedcolormap.h @@ -6,11 +6,14 @@ #include "util/color/predefinedcolor.h" -// Map the predefined colors to another color representation of them. +// Maps a PredefinedColorMap to an actual QColor (a.k.a its representation). +// +// Initially no color has a representation set. +// Call setRepresentation(PredefinedColorPointer, QColor) to add representations and customize the color map. // // Uses the color's name() property as key, e.g. "#A9A9A9" // Since QHash has copy-on-write, making a copy of ColorsRepresentation is fast. -// A deep copy of the QHash will be made when the copy is modified. +// A deep copy of the QHash will be made when a copy is modified. class PredefinedColorMap final { public: // Set a color representation for a given color @@ -18,7 +21,8 @@ class PredefinedColorMap final { m_colorNameMap[color->m_defaultRepresentation.name()] = representation.name(); } - // Returns the representation of a color + // Returnsthe representation of a color. + // If no representation is set for color, returns color->m_defaultRepresentation. QColor map(PredefinedColorPointer color) const { QColor defaultRepresentation = color->m_defaultRepresentation; if (m_colorNameMap.contains(defaultRepresentation.name())) { diff --git a/src/util/color/predefinedcolorset.h b/src/util/color/predefinedcolorset.h index 6e2bb8ee602..b1040f948b8 100644 --- a/src/util/color/predefinedcolorset.h +++ b/src/util/color/predefinedcolorset.h @@ -7,7 +7,9 @@ #include "util/color/predefinedcolor.h" #include "util/color/predefinedcolormap.h" -// These methods and properties are not thread-safe, use them only on the GUI thread +// 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 PredefinedColorSet final { public: const PredefinedColorPointer noColor = std::make_shared( @@ -94,7 +96,7 @@ class PredefinedColorSet final { } } - // A list with the internal names of the predefined colors. + // A list with the names of the predefined colors. QList predefinedColorNames() const { return m_predefinedColorsNames; }; // Returns the position of a PredefinedColor in the allColors list. @@ -109,7 +111,8 @@ class PredefinedColorSet final { return 0; }; - // Return a predefined color from its internal name. + // 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) { @@ -120,6 +123,7 @@ class PredefinedColorSet final { }; // 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) { @@ -129,9 +133,7 @@ class PredefinedColorSet final { return noColor; }; - // The default color map, i.e. maps each predefined color to itself. - // - // It's fast to copy the default representation. See comment on ColorsRepresentation. + // The default color map, i.e. maps each predefined color to its default representation. PredefinedColorMap defaultMap() const { return m_defaultMap; }; private: From 7938f0de393dbd8f5661db37d818c0a9a276c743 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Thu, 31 Jan 2019 20:35:22 +0100 Subject: [PATCH 36/56] Use skin provided DefaultMark color when a hotcue has noColor --- src/waveform/renderers/waveformmarkproperties.cpp | 8 ++++---- src/waveform/renderers/waveformmarkproperties.h | 2 ++ src/waveform/renderers/waveformrendermark.cpp | 13 ++++++++++--- src/widget/woverview.cpp | 9 +++++++-- 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/waveform/renderers/waveformmarkproperties.cpp b/src/waveform/renderers/waveformmarkproperties.cpp index bde16e1e06c..23c7d62241d 100644 --- a/src/waveform/renderers/waveformmarkproperties.cpp +++ b/src/waveform/renderers/waveformmarkproperties.cpp @@ -47,14 +47,14 @@ WaveformMarkProperties::WaveformMarkProperties(const QDomNode& node, const WaveformSignalColors& signalColors, int hotCue) { QColor color(context.selectString(node, "Color")); - // TODO (Swiftb0y): remove context.selectString because the color will be overriden by the cuepoints regardless if (!color.isValid()) { // As a fallback, grab the color from the parent's AxesColor - setBaseColor(signalColors.getAxesColor()); - qDebug() << "Didn't get mark , using parent's :" << m_fillColor; + m_defaultColor = signalColors.getAxesColor(); + qDebug() << "Didn't get mark , using parent's :" << m_defaultColor; } else { - setBaseColor(WSkinColor::getCorrectColor(m_fillColor)); + m_defaultColor = WSkinColor::getCorrectColor(color); } + setBaseColor(m_defaultColor); m_textColor = context.selectString(node, "TextColor"); if (!m_textColor.isValid()) { diff --git a/src/waveform/renderers/waveformmarkproperties.h b/src/waveform/renderers/waveformmarkproperties.h index 6f3cf0ea4c2..df0b957b171 100644 --- a/src/waveform/renderers/waveformmarkproperties.h +++ b/src/waveform/renderers/waveformmarkproperties.h @@ -21,6 +21,8 @@ class WaveformMarkProperties final { QColor borderColor() const; QColor labelColor() const; + // The default color defined by the skin + QColor m_defaultColor; QColor m_textColor; QString m_text; Qt::Alignment m_align; diff --git a/src/waveform/renderers/waveformrendermark.cpp b/src/waveform/renderers/waveformrendermark.cpp index b0a95a690ac..5080e08781b 100644 --- a/src/waveform/renderers/waveformrendermark.cpp +++ b/src/waveform/renderers/waveformrendermark.cpp @@ -109,16 +109,23 @@ void WaveformRenderMark::slotCuesUpdated() { continue; } - QString newLabel = pCue->getLabel(); - QColor newColor = m_predefinedColorsRepresentation.map(pCue->getColor()); - // Here we assume no two cues can have the same hotcue assigned, // because WaveformMarkSet stores one mark for each hotcue. WaveformMarkPointer pMark = m_marks.getHotCueMark(hotCue); if (pMark.isNull()) { continue; } + WaveformMarkProperties markProperties = pMark->getProperties(); + QString newLabel = pCue->getLabel(); + QColor newColor; + PredefinedColorPointer cueColor = pCue->getColor(); + if (*cueColor == *Color::predefinedColorSet.noColor) { + newColor = markProperties.m_defaultColor; + } else { + newColor = m_predefinedColorsRepresentation.map(cueColor); + } + if (markProperties.m_text.isNull() || newLabel != markProperties.m_text || !markProperties.fillColor().isValid() || newColor != markProperties.fillColor()) { markProperties.m_text = newLabel; diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index 72c6aaa9ccb..7159e64d3bb 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -266,8 +266,13 @@ void WOverview::updateCues(const QList &loadedCues) { if (currentMark && currentMark->isValid()) { WaveformMarkProperties markProperties = currentMark->getProperties(); - const QColor newColor = m_predefinedColorsRepresentation.map(currentCue->getColor()); - + QColor newColor; + PredefinedColorPointer cueColor = currentCue->getColor(); + if (*cueColor == *Color::predefinedColorSet.noColor) { + newColor = markProperties.m_defaultColor; + } else { + newColor = m_predefinedColorsRepresentation.map(cueColor); + } if (newColor != markProperties.fillColor() || newColor != markProperties.m_textColor) { markProperties.setBaseColor(newColor); currentMark->setProperties(markProperties); From 86337abab47421d55272e5346ac0cee02adab400 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Thu, 31 Jan 2019 23:15:02 +0100 Subject: [PATCH 37/56] Remove m_iBrightness field from PredefinedColor --- src/util/color/predefinedcolor.cpp | 3 +-- src/util/color/predefinedcolor.h | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/util/color/predefinedcolor.cpp b/src/util/color/predefinedcolor.cpp index 516b9a12711..52c35f2b5d7 100644 --- a/src/util/color/predefinedcolor.cpp +++ b/src/util/color/predefinedcolor.cpp @@ -6,6 +6,5 @@ PredefinedColor::PredefinedColor(QColor defaultRepresentation, QString sName, QS : m_defaultRepresentation(defaultRepresentation), m_sName(sName), m_sDisplayName(sDisplayName), - m_iId(iId), - m_iBrightness(Color::brightness(defaultRepresentation)) { + m_iId(iId) { } diff --git a/src/util/color/predefinedcolor.h b/src/util/color/predefinedcolor.h index dfda5993cbf..2ec19c9e4ee 100644 --- a/src/util/color/predefinedcolor.h +++ b/src/util/color/predefinedcolor.h @@ -23,8 +23,6 @@ class PredefinedColor final { const QString m_sDisplayName; // An Id uniquely identifying this predefined color. const int m_iId; - // The brightness of this color, calculated with Color::brightness(const QColor&) - const int m_iBrightness; }; typedef std::shared_ptr PredefinedColorPointer; From 85a6605e2f527478f2450209269bdd16c64930bf Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Thu, 31 Jan 2019 23:24:08 +0100 Subject: [PATCH 38/56] Add missing include --- src/util/color/predefinedcolor.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/util/color/predefinedcolor.h b/src/util/color/predefinedcolor.h index 2ec19c9e4ee..ce659f88243 100644 --- a/src/util/color/predefinedcolor.h +++ b/src/util/color/predefinedcolor.h @@ -3,6 +3,8 @@ #include +#include "util/memory.h" + class PredefinedColor final { public: PredefinedColor(QColor defaultRepresentation, QString sName, QString sDisplayName, int iId); From 85bbcf94a0730d81765dd43791a83654c15f5f2f Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Fri, 1 Feb 2019 00:05:02 +0100 Subject: [PATCH 39/56] Rename all the things --- src/engine/controls/cuecontrol.cpp | 7 +--- src/library/dlgtrackinfo.cpp | 8 ++-- src/skin/skincontext.h | 12 +++--- src/util/color/predefinedcolor.cpp | 4 +- src/util/color/predefinedcolor.h | 4 +- src/util/color/predefinedcolormap.h | 39 ------------------ src/util/color/predefinedcolorset.h | 10 ++--- src/util/color/predefinedcolorsmap.h | 40 +++++++++++++++++++ src/waveform/renderers/waveformrendermark.cpp | 4 +- src/waveform/renderers/waveformrendermark.h | 2 +- src/widget/woverview.cpp | 4 +- src/widget/woverview.h | 2 +- 12 files changed, 66 insertions(+), 70 deletions(-) delete mode 100644 src/util/color/predefinedcolormap.h create mode 100644 src/util/color/predefinedcolorsmap.h diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index 9f29317f6cb..24b2d3f7392 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -1038,9 +1038,7 @@ HotcueControl::HotcueControl(QString group, int i) m_hotcueEnabled = new ControlObject(keyForControl(i, "enabled")); m_hotcueEnabled->setReadOnly(); - // NOTE(Swiftb0y): since ControlObjects only deal with double values, - // the Color is stored as a QRgb (which is just a unsigned int - // representation of the color (AARRGGBB) + // The id of the predefined color assigned to this color. m_hotcueColor = new ControlObject(keyForControl(i, "color")); m_hotcueColor->setReadOnly(); connect(m_hotcueColor, SIGNAL(valueChanged(double)), @@ -1145,9 +1143,6 @@ void HotcueControl::setCue(CuePointer pCue) { m_pCue = pCue; } QColor HotcueControl::getColor() const { - // QRgb is just an unsigned int representation of the - // color components (AARRGGBB) so conversion - // from double shouldn't be an issue return QColor::fromRgb(static_cast(m_hotcueColor->get())); } diff --git a/src/library/dlgtrackinfo.cpp b/src/library/dlgtrackinfo.cpp index 4496a92bf6c..57d36f4e387 100644 --- a/src/library/dlgtrackinfo.cpp +++ b/src/library/dlgtrackinfo.cpp @@ -326,13 +326,13 @@ void DlgTrackInfo::populateCues(TrackPointer pTrack) { QList predefinedColors = Color::predefinedColorSet.allColors; for (int i = 0; i < predefinedColors.count(); i++) { PredefinedColorPointer color = predefinedColors.at(i); - QColor colorRepresentation = color->m_defaultRepresentation; - colorComboBox->addItem(color->m_sDisplayName, colorRepresentation); + QColor defaultRgba = color->m_defaultRgba; + colorComboBox->addItem(color->m_sDisplayName, defaultRgba); const QModelIndex idx = colorComboBox->model()->index(i, 0); if (*color != *Color::predefinedColorSet.noColor) { - colorComboBox->model()->setData(idx, colorRepresentation, Qt::BackgroundColorRole); + colorComboBox->model()->setData(idx, defaultRgba, Qt::BackgroundColorRole); } - colorComboBox->setItemData(i, Color::chooseContrastColor(colorRepresentation), Qt::TextColorRole); + colorComboBox->setItemData(i, Color::chooseContrastColor(defaultRgba), Qt::TextColorRole); } PredefinedColorPointer cueColor = pCue->getColor(); diff --git a/src/skin/skincontext.h b/src/skin/skincontext.h index 68aa3c371ea..7d0148300b2 100644 --- a/src/skin/skincontext.h +++ b/src/skin/skincontext.h @@ -12,10 +12,10 @@ #include #include +#include "../util/color/predefinedcolorsmap.h" #include "preferences/usersettings.h" #include "skin/pixmapsource.h" #include "util/color/color.h" -#include "util/color/predefinedcolormap.h" #include "widget/wsingletoncontainer.h" #include "widget/wpixmapstore.h" @@ -268,13 +268,13 @@ class SkinContext { return m_scaleFactor; } - PredefinedColorMap getCueColorMap(const QDomNode& node) const { - PredefinedColorMap colorMap = Color::predefinedColorSet.defaultMap(); + PredefinedColorsMap getCueColorMap(const QDomNode& node) const { + PredefinedColorsMap colorMap = Color::predefinedColorSet.defaultMap(); for (QString colorName : Color::predefinedColorSet.predefinedColorNames()) { - QColor representation = selectColor(node, "Cue" + colorName); - if (representation.isValid()) { + QColor skinRgba = selectColor(node, "Cue" + colorName); + if (skinRgba.isValid()) { PredefinedColorPointer originalColor = Color::predefinedColorSet.predefinedColorFromName(colorName); - colorMap.setRepresentation(originalColor, representation); + colorMap.setCustomRgba(originalColor, skinRgba); } } return colorMap; diff --git a/src/util/color/predefinedcolor.cpp b/src/util/color/predefinedcolor.cpp index 52c35f2b5d7..2a5db56e987 100644 --- a/src/util/color/predefinedcolor.cpp +++ b/src/util/color/predefinedcolor.cpp @@ -2,8 +2,8 @@ #include "util/color/color.h" -PredefinedColor::PredefinedColor(QColor defaultRepresentation, QString sName, QString sDisplayName, int iId) - : m_defaultRepresentation(defaultRepresentation), +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 index ce659f88243..b00ff246155 100644 --- a/src/util/color/predefinedcolor.h +++ b/src/util/color/predefinedcolor.h @@ -7,7 +7,7 @@ class PredefinedColor final { public: - PredefinedColor(QColor defaultRepresentation, QString sName, QString sDisplayName, int iId); + PredefinedColor(QColor defaultRgba, QString sName, QString sDisplayName, int iId); inline bool operator==(const PredefinedColor& other) const { return m_iId == other.m_iId; @@ -18,7 +18,7 @@ class PredefinedColor final { } // The QColor that is used by default to render this PredefinedColor. - const QColor m_defaultRepresentation; + const QColor m_defaultRgba; // The name of the color used programatically, e.g. on skin files. const QString m_sName; // The name of the color used on UI. diff --git a/src/util/color/predefinedcolormap.h b/src/util/color/predefinedcolormap.h deleted file mode 100644 index 7feb37be8a0..00000000000 --- a/src/util/color/predefinedcolormap.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef PREDEFINEDCOLORMAP_H -#define PREDEFINEDCOLORMAP_H - -#include -#include - -#include "util/color/predefinedcolor.h" - -// Maps a PredefinedColorMap to an actual QColor (a.k.a its representation). -// -// Initially no color has a representation set. -// Call setRepresentation(PredefinedColorPointer, QColor) to add representations and customize the color map. -// -// Uses the color's name() property as key, e.g. "#A9A9A9" -// Since QHash has copy-on-write, making a copy of ColorsRepresentation is fast. -// A deep copy of the QHash will be made when a copy is modified. -class PredefinedColorMap final { - public: - // Set a color representation for a given color - void setRepresentation(PredefinedColorPointer color, QColor representation) { - m_colorNameMap[color->m_defaultRepresentation.name()] = representation.name(); - } - - // Returnsthe representation of a color. - // If no representation is set for color, returns color->m_defaultRepresentation. - QColor map(PredefinedColorPointer color) const { - QColor defaultRepresentation = color->m_defaultRepresentation; - if (m_colorNameMap.contains(defaultRepresentation.name())) { - return QColor(m_colorNameMap[defaultRepresentation.name()]); - } - return defaultRepresentation; - } - - - private: - QHash m_colorNameMap; -}; - -#endif /* PREDEFINEDCOLORMAP_H */ diff --git a/src/util/color/predefinedcolorset.h b/src/util/color/predefinedcolorset.h index b1040f948b8..a13f1292d55 100644 --- a/src/util/color/predefinedcolorset.h +++ b/src/util/color/predefinedcolorset.h @@ -4,8 +4,8 @@ #include #include +#include "predefinedcolorsmap.h" #include "util/color/predefinedcolor.h" -#include "util/color/predefinedcolormap.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. @@ -92,7 +92,7 @@ class PredefinedColorSet final { for (PredefinedColorPointer color : allColors) { m_predefinedColorsNames << color->m_sName; - m_defaultMap.setRepresentation(color, color->m_defaultRepresentation); + m_defaultMap.setCustomRgba(color, color->m_defaultRgba); } } @@ -133,11 +133,11 @@ class PredefinedColorSet final { return noColor; }; - // The default color map, i.e. maps each predefined color to its default representation. - PredefinedColorMap defaultMap() const { return m_defaultMap; }; + // The default color map, i.e. maps each predefined color to its default Rgba. + PredefinedColorsMap defaultMap() const { return m_defaultMap; }; private: QList m_predefinedColorsNames; - PredefinedColorMap m_defaultMap; + PredefinedColorsMap m_defaultMap; }; #endif /* COLOR_H */ diff --git a/src/util/color/predefinedcolorsmap.h b/src/util/color/predefinedcolorsmap.h new file mode 100644 index 00000000000..4d26f746ad4 --- /dev/null +++ b/src/util/color/predefinedcolorsmap.h @@ -0,0 +1,40 @@ +#ifndef PREDEFINEDCOLORSMAP_H +#define PREDEFINEDCOLORSMAP_H + +#include +#include + +#include "util/color/predefinedcolor.h" + +// Maps a PredefinedColor to 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 PredefinedColorsMap is fast. +// A deep copy of the QHash will be made when a copy is modified. +class PredefinedColorsMap 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 map(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 /* PREDEFINEDCOLORSMAP_H */ diff --git a/src/waveform/renderers/waveformrendermark.cpp b/src/waveform/renderers/waveformrendermark.cpp index 5080e08781b..8e2d918cc09 100644 --- a/src/waveform/renderers/waveformrendermark.cpp +++ b/src/waveform/renderers/waveformrendermark.cpp @@ -23,7 +23,7 @@ WaveformRenderMark::WaveformRenderMark( } void WaveformRenderMark::setup(const QDomNode& node, const SkinContext& context) { - m_predefinedColorsRepresentation = context.getCueColorMap(node); + m_predefinedColorsMap = context.getCueColorMap(node); m_marks.setup(m_waveformRenderer->getGroup(), node, context, *m_waveformRenderer->getWaveformSignalColors()); } @@ -123,7 +123,7 @@ void WaveformRenderMark::slotCuesUpdated() { if (*cueColor == *Color::predefinedColorSet.noColor) { newColor = markProperties.m_defaultColor; } else { - newColor = m_predefinedColorsRepresentation.map(cueColor); + newColor = m_predefinedColorsMap.map(cueColor); } if (markProperties.m_text.isNull() || newLabel != markProperties.m_text || diff --git a/src/waveform/renderers/waveformrendermark.h b/src/waveform/renderers/waveformrendermark.h index 92dc64b89df..ca36318e9c0 100644 --- a/src/waveform/renderers/waveformrendermark.h +++ b/src/waveform/renderers/waveformrendermark.h @@ -34,7 +34,7 @@ class WaveformRenderMark : public QObject, public WaveformRendererAbstract { private: void generateMarkImage(WaveformMark* pMark); - PredefinedColorMap m_predefinedColorsRepresentation; + PredefinedColorsMap m_predefinedColorsMap; WaveformMarkSet m_marks; DISALLOW_COPY_AND_ASSIGN(WaveformRenderMark); diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index 7159e64d3bb..98ecf03bac0 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -91,7 +91,7 @@ void WOverview::setup(const QDomNode& node, const SkinContext& context) { } // setup hotcues and cue and loop(s) - m_predefinedColorsRepresentation = context.getCueColorMap(node); + m_predefinedColorsMap = context.getCueColorMap(node); m_marks.setup(m_group, node, context, m_signalColors); for (const auto& pMark: m_marks) { @@ -271,7 +271,7 @@ void WOverview::updateCues(const QList &loadedCues) { if (*cueColor == *Color::predefinedColorSet.noColor) { newColor = markProperties.m_defaultColor; } else { - newColor = m_predefinedColorsRepresentation.map(cueColor); + newColor = m_predefinedColorsMap.map(cueColor); } if (newColor != markProperties.fillColor() || newColor != markProperties.m_textColor) { markProperties.setBaseColor(newColor); diff --git a/src/widget/woverview.h b/src/widget/woverview.h index d6e0dda5de2..e718d945a15 100644 --- a/src/widget/woverview.h +++ b/src/widget/woverview.h @@ -130,7 +130,7 @@ class WOverview : public WWidget { QColor m_qColorBackground; QColor m_endOfTrackColor; - PredefinedColorMap m_predefinedColorsRepresentation; + PredefinedColorsMap m_predefinedColorsMap; WaveformMarkSet m_marks; std::vector m_markRanges; From a4b947f4e2f50543f694596ab12781d94d22fc70 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Fri, 1 Feb 2019 00:18:42 +0100 Subject: [PATCH 40/56] Fix hotcue color CO --- src/engine/controls/cuecontrol.cpp | 17 ++++++++--------- src/engine/controls/cuecontrol.h | 8 ++++---- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index 24b2d3f7392..0bd7371c10a 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -298,7 +298,7 @@ void CueControl::trackCuesUpdated() { } else { // If the old hotcue is the same, then we only need to update pControl->setPosition(pCue->getPosition()); - pControl->setColor(pCue->getColor()->m_iId); + pControl->setColor(pCue->getColor()); } // Add the hotcue to the list of active hotcues active_hotcues.insert(hotcue); @@ -1040,7 +1040,6 @@ HotcueControl::HotcueControl(QString group, int i) // The id of the predefined color assigned to this color. m_hotcueColor = new ControlObject(keyForControl(i, "color")); - m_hotcueColor->setReadOnly(); connect(m_hotcueColor, SIGNAL(valueChanged(double)), this, SLOT(slotHotcueColorChanged(double)), Qt::DirectConnection); @@ -1127,9 +1126,9 @@ void HotcueControl::slotHotcuePositionChanged(double newPosition) { emit(hotcuePositionChanged(this, newPosition)); } -void HotcueControl::slotHotcueColorChanged(double newColor) { - m_pCue->setColor(Color::predefinedColorSet.predefinedColorFromId(newColor)); - emit(hotcueColorChanged(this, newColor)); +void HotcueControl::slotHotcueColorChanged(double newColorId) { + m_pCue->setColor(Color::predefinedColorSet.predefinedColorFromId(newColorId)); + emit(hotcueColorChanged(this, newColorId)); } double HotcueControl::getPosition() const { @@ -1142,12 +1141,12 @@ 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::fromRgb(static_cast(m_hotcueColor->get())); +PredefinedColorPointer HotcueControl::getColor() const { + return Color::predefinedColorSet.predefinedColorFromId(m_hotcueColor->get()); } -void HotcueControl::setColor(QColor newColor) { - m_hotcueColor->set(static_cast(newColor.rgb())); +void HotcueControl::setColor(PredefinedColorPointer newColor) { + m_hotcueColor->set(static_cast(newColor->m_iId)); } 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 7fa8124c1f5..ae2dfab701e 100644 --- a/src/engine/controls/cuecontrol.h +++ b/src/engine/controls/cuecontrol.h @@ -30,8 +30,8 @@ class HotcueControl : public QObject { void setCue(CuePointer pCue); void resetCue(); void setPosition(double position); - void setColor(QColor newColor); - QColor getColor() const; + void setColor(PredefinedColorPointer newColor); + PredefinedColorPointer getColor() const; // Used for caching the preview state of this hotcue control. inline bool isPreviewing() { @@ -56,7 +56,7 @@ class HotcueControl : public QObject { void slotHotcueActivatePreview(double v); void slotHotcueClear(double v); void slotHotcuePositionChanged(double newPosition); - void slotHotcueColorChanged(double newColor); + void slotHotcueColorChanged(double newColorId); signals: void hotcueSet(HotcueControl* pHotcue, double v); @@ -67,7 +67,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 newColor); + void hotcueColorChanged(HotcueControl* pHotcue, double newColorId); void hotcuePlay(double v); private: From 36e367041a2e2876c73c9d3e60873158d102a272 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Fri, 1 Feb 2019 00:37:20 +0100 Subject: [PATCH 41/56] Remove predefinedColorNames list from PredefinedColorSet --- src/skin/skincontext.h | 7 ++++--- src/util/color/predefinedcolorset.h | 7 +------ 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/skin/skincontext.h b/src/skin/skincontext.h index 7d0148300b2..a9d6aac2ebc 100644 --- a/src/skin/skincontext.h +++ b/src/skin/skincontext.h @@ -270,10 +270,11 @@ class SkinContext { PredefinedColorsMap getCueColorMap(const QDomNode& node) const { PredefinedColorsMap colorMap = Color::predefinedColorSet.defaultMap(); - for (QString colorName : Color::predefinedColorSet.predefinedColorNames()) { - QColor skinRgba = selectColor(node, "Cue" + colorName); + for (PredefinedColorPointer color : Color::predefinedColorSet.allColors) { + QString sColorName(color->m_sName); + QColor skinRgba = selectColor(node, "Cue" + sColorName); if (skinRgba.isValid()) { - PredefinedColorPointer originalColor = Color::predefinedColorSet.predefinedColorFromName(colorName); + PredefinedColorPointer originalColor = Color::predefinedColorSet.predefinedColorFromName(sColorName); colorMap.setCustomRgba(originalColor, skinRgba); } } diff --git a/src/util/color/predefinedcolorset.h b/src/util/color/predefinedcolorset.h index a13f1292d55..dfa63ce6a80 100644 --- a/src/util/color/predefinedcolorset.h +++ b/src/util/color/predefinedcolorset.h @@ -88,17 +88,13 @@ class PredefinedColorSet final { }; PredefinedColorSet() - : m_predefinedColorsNames(), m_defaultMap() { + : m_defaultMap() { for (PredefinedColorPointer color : allColors) { - m_predefinedColorsNames << color->m_sName; m_defaultMap.setCustomRgba(color, color->m_defaultRgba); } } - // A list with the names of the predefined colors. - QList predefinedColorNames() const { return m_predefinedColorsNames; }; - // Returns the position of a PredefinedColor in the allColors list. int predefinedColorIndex(PredefinedColorPointer searchedColor) const { int position = 0; @@ -137,7 +133,6 @@ class PredefinedColorSet final { PredefinedColorsMap defaultMap() const { return m_defaultMap; }; private: - QList m_predefinedColorsNames; PredefinedColorsMap m_defaultMap; }; #endif /* COLOR_H */ From 614183d48db1d5069733d3a028a3720e7d3c121d Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Fri, 1 Feb 2019 00:41:38 +0100 Subject: [PATCH 42/56] Rename PredefinedColorSet to PredefinedColorsSet --- src/util/color/color.h | 4 ++-- .../color/{predefinedcolorset.h => predefinedcolorsset.h} | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/util/color/{predefinedcolorset.h => predefinedcolorsset.h} (98%) diff --git a/src/util/color/color.h b/src/util/color/color.h index 3ec531937aa..058afce6a7f 100644 --- a/src/util/color/color.h +++ b/src/util/color/color.h @@ -4,11 +4,11 @@ #include #include -#include "util/color/predefinedcolorset.h" +#include "predefinedcolorsset.h" #include "util/math.h" namespace Color { - static const PredefinedColorSet predefinedColorSet = PredefinedColorSet(); + static const PredefinedColorsSet predefinedColorSet = 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 diff --git a/src/util/color/predefinedcolorset.h b/src/util/color/predefinedcolorsset.h similarity index 98% rename from src/util/color/predefinedcolorset.h rename to src/util/color/predefinedcolorsset.h index dfa63ce6a80..80c2adafb57 100644 --- a/src/util/color/predefinedcolorset.h +++ b/src/util/color/predefinedcolorsset.h @@ -10,7 +10,7 @@ // 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 PredefinedColorSet final { +class PredefinedColorsSet final { public: const PredefinedColorPointer noColor = std::make_shared( QColor(), @@ -87,7 +87,7 @@ class PredefinedColorSet final { grey, }; - PredefinedColorSet() + PredefinedColorsSet() : m_defaultMap() { for (PredefinedColorPointer color : allColors) { From bfca628b63e1c17ca462a3cfa81f276410d3ed64 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Fri, 1 Feb 2019 01:30:08 +0100 Subject: [PATCH 43/56] Add default cue color in PredefinedColorsMap --- src/skin/skincontext.h | 3 ++- .../renderers/waveformmarkproperties.cpp | 8 ++++---- .../renderers/waveformmarkproperties.h | 2 -- src/waveform/renderers/waveformmarkset.cpp | 6 +++++- src/waveform/renderers/waveformmarkset.h | 5 +++-- src/waveform/renderers/waveformrendermark.cpp | 19 ++++++++----------- src/widget/woverview.cpp | 14 ++++++-------- 7 files changed, 28 insertions(+), 29 deletions(-) diff --git a/src/skin/skincontext.h b/src/skin/skincontext.h index a9d6aac2ebc..5e02afeb2c9 100644 --- a/src/skin/skincontext.h +++ b/src/skin/skincontext.h @@ -268,7 +268,7 @@ class SkinContext { return m_scaleFactor; } - PredefinedColorsMap getCueColorMap(const QDomNode& node) const { + PredefinedColorsMap getCueColorMap(const QDomNode& node, QColor defaultColor) const { PredefinedColorsMap colorMap = Color::predefinedColorSet.defaultMap(); for (PredefinedColorPointer color : Color::predefinedColorSet.allColors) { QString sColorName(color->m_sName); @@ -278,6 +278,7 @@ class SkinContext { colorMap.setCustomRgba(originalColor, skinRgba); } } + colorMap.setCustomRgba(Color::predefinedColorSet.noColor, defaultColor); return colorMap; } diff --git a/src/waveform/renderers/waveformmarkproperties.cpp b/src/waveform/renderers/waveformmarkproperties.cpp index 23c7d62241d..18ee9195e49 100644 --- a/src/waveform/renderers/waveformmarkproperties.cpp +++ b/src/waveform/renderers/waveformmarkproperties.cpp @@ -49,12 +49,12 @@ WaveformMarkProperties::WaveformMarkProperties(const QDomNode& node, QColor color(context.selectString(node, "Color")); if (!color.isValid()) { // As a fallback, grab the color from the parent's AxesColor - m_defaultColor = signalColors.getAxesColor(); - qDebug() << "Didn't get mark , using parent's :" << m_defaultColor; + color = signalColors.getAxesColor(); + qDebug() << "Didn't get mark , using parent's :" << color; } else { - m_defaultColor = WSkinColor::getCorrectColor(color); + color = WSkinColor::getCorrectColor(color); } - setBaseColor(m_defaultColor); + setBaseColor(color); m_textColor = context.selectString(node, "TextColor"); if (!m_textColor.isValid()) { diff --git a/src/waveform/renderers/waveformmarkproperties.h b/src/waveform/renderers/waveformmarkproperties.h index df0b957b171..6f3cf0ea4c2 100644 --- a/src/waveform/renderers/waveformmarkproperties.h +++ b/src/waveform/renderers/waveformmarkproperties.h @@ -21,8 +21,6 @@ class WaveformMarkProperties final { QColor borderColor() const; QColor labelColor() const; - // The default color defined by the skin - QColor m_defaultColor; QColor m_textColor; QString m_text; Qt::Alignment m_align; diff --git a/src/waveform/renderers/waveformmarkset.cpp b/src/waveform/renderers/waveformmarkset.cpp index 3865930a7d5..d35266b2a4c 100644 --- a/src/waveform/renderers/waveformmarkset.cpp +++ b/src/waveform/renderers/waveformmarkset.cpp @@ -27,7 +27,7 @@ void WaveformMarkSet::setup(const QString& group, const QDomNode& node, QDomNode defaultChild; while (!child.isNull()) { if (child.nodeName() == "DefaultMark") { - m_pDefaultMark = std::make_unique(group, child, context, signalColors); + m_pDefaultMark = WaveformMarkPointer(new WaveformMark(group, child, context, signalColors)); hasDefaultMark = true; defaultChild = child; } else if (child.nodeName() == "Mark") { @@ -65,3 +65,7 @@ void WaveformMarkSet::setup(const QString& group, const QDomNode& node, WaveformMarkPointer WaveformMarkSet::getHotCueMark(int hotCue) const { return m_hotCueMarks.value(hotCue); } + +WaveformMarkPointer WaveformMarkSet::getDefaultMark() const { + return m_pDefaultMark; +} diff --git a/src/waveform/renderers/waveformmarkset.h b/src/waveform/renderers/waveformmarkset.h index b7e49a857e3..198d6876620 100644 --- a/src/waveform/renderers/waveformmarkset.h +++ b/src/waveform/renderers/waveformmarkset.h @@ -23,10 +23,11 @@ class WaveformMarkSet { // hotCue must be valid (>= 0 and < NUM_HOT_CUES) WaveformMarkPointer getHotCueMark(int hotCue) const; + WaveformMarkPointer getDefaultMark() const; private: - void clear(){ m_marks.clear(); } - std::unique_ptr m_pDefaultMark; + void clear() { m_marks.clear(); } + WaveformMarkPointer m_pDefaultMark; QList m_marks; QMap m_hotCueMarks; diff --git a/src/waveform/renderers/waveformrendermark.cpp b/src/waveform/renderers/waveformrendermark.cpp index 8e2d918cc09..f1182d4b5a8 100644 --- a/src/waveform/renderers/waveformrendermark.cpp +++ b/src/waveform/renderers/waveformrendermark.cpp @@ -23,9 +23,13 @@ WaveformRenderMark::WaveformRenderMark( } void WaveformRenderMark::setup(const QDomNode& node, const SkinContext& context) { - m_predefinedColorsMap = context.getCueColorMap(node); - m_marks.setup(m_waveformRenderer->getGroup(), node, context, - *m_waveformRenderer->getWaveformSignalColors()); + WaveformSignalColors signalColors = *m_waveformRenderer->getWaveformSignalColors(); + m_marks.setup(m_waveformRenderer->getGroup(), node, context, signalColors); + WaveformMarkPointer defaultMark(m_marks.getDefaultMark()); + QColor defaultColor = defaultMark + ? defaultMark->getProperties().fillColor() + : signalColors.getAxesColor(); + m_predefinedColorsMap = context.getCueColorMap(node, defaultColor); } void WaveformRenderMark::draw(QPainter* painter, QPaintEvent* /*event*/) { @@ -118,14 +122,7 @@ void WaveformRenderMark::slotCuesUpdated() { WaveformMarkProperties markProperties = pMark->getProperties(); QString newLabel = pCue->getLabel(); - QColor newColor; - PredefinedColorPointer cueColor = pCue->getColor(); - if (*cueColor == *Color::predefinedColorSet.noColor) { - newColor = markProperties.m_defaultColor; - } else { - newColor = m_predefinedColorsMap.map(cueColor); - } - + QColor newColor = m_predefinedColorsMap.map(pCue->getColor()); if (markProperties.m_text.isNull() || newLabel != markProperties.m_text || !markProperties.fillColor().isValid() || newColor != markProperties.fillColor()) { markProperties.m_text = newLabel; diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index 98ecf03bac0..f80d3cf53ab 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -91,8 +91,12 @@ void WOverview::setup(const QDomNode& node, const SkinContext& context) { } // setup hotcues and cue and loop(s) - m_predefinedColorsMap = context.getCueColorMap(node); m_marks.setup(m_group, node, context, m_signalColors); + WaveformMarkPointer defaultMark(m_marks.getDefaultMark()); + QColor defaultColor = defaultMark + ? defaultMark->getProperties().fillColor() + : m_signalColors.getAxesColor(); + m_predefinedColorsMap = context.getCueColorMap(node, defaultColor); for (const auto& pMark: m_marks) { if (pMark->isValid()) { @@ -266,13 +270,7 @@ void WOverview::updateCues(const QList &loadedCues) { if (currentMark && currentMark->isValid()) { WaveformMarkProperties markProperties = currentMark->getProperties(); - QColor newColor; - PredefinedColorPointer cueColor = currentCue->getColor(); - if (*cueColor == *Color::predefinedColorSet.noColor) { - newColor = markProperties.m_defaultColor; - } else { - newColor = m_predefinedColorsMap.map(cueColor); - } + QColor newColor = m_predefinedColorsMap.map(currentCue->getColor()); if (newColor != markProperties.fillColor() || newColor != markProperties.m_textColor) { markProperties.setBaseColor(newColor); currentMark->setProperties(markProperties); From dd29a4b5947108a6fe32ef74ee2600ffa4620880 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sat, 2 Feb 2019 19:26:14 +0100 Subject: [PATCH 44/56] Improve code comments --- src/util/color/predefinedcolor.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/util/color/predefinedcolor.h b/src/util/color/predefinedcolor.h index b00ff246155..6ae48e410f4 100644 --- a/src/util/color/predefinedcolor.h +++ b/src/util/color/predefinedcolor.h @@ -19,11 +19,12 @@ class PredefinedColor final { // The QColor that is used by default to render this PredefinedColor. const QColor m_defaultRgba; - // The name of the color used programatically, e.g. on skin files. + // 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; From ce5bb156e4be37424806bc69076eb8511ea14e35 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sat, 2 Feb 2019 20:04:35 +0100 Subject: [PATCH 45/56] Improve code comments --- src/util/color/predefinedcolor.h | 6 ++++++ src/util/color/predefinedcolorsmap.h | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/util/color/predefinedcolor.h b/src/util/color/predefinedcolor.h index 6ae48e410f4..54e9eac02c7 100644 --- a/src/util/color/predefinedcolor.h +++ b/src/util/color/predefinedcolor.h @@ -5,6 +5,12 @@ #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); diff --git a/src/util/color/predefinedcolorsmap.h b/src/util/color/predefinedcolorsmap.h index 4d26f746ad4..6b4d147d757 100644 --- a/src/util/color/predefinedcolorsmap.h +++ b/src/util/color/predefinedcolorsmap.h @@ -6,8 +6,9 @@ #include "util/color/predefinedcolor.h" -// Maps a PredefinedColor to custom Rgba color. +// PredefinedColorsMap defines a particular way to render Mixxx PredefinedColors. // +// PredefinedColorsMap maps a PredefinedColor to 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. From 4ed4d8f04c956342575a6b10ee3c030cae581a1f Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sat, 2 Feb 2019 20:14:38 +0100 Subject: [PATCH 46/56] Rename hotcue color CO to "hotcue_color_id" --- 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 0bd7371c10a..c5c8951ab7a 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -1039,7 +1039,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")); + m_hotcueColor = new ControlObject(keyForControl(i, "color_id")); connect(m_hotcueColor, SIGNAL(valueChanged(double)), this, SLOT(slotHotcueColorChanged(double)), Qt::DirectConnection); From 65b721973d7d9a35866731468bbae947652577b9 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sat, 2 Feb 2019 20:23:13 +0100 Subject: [PATCH 47/56] Add const --- src/library/dlgtrackinfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/library/dlgtrackinfo.cpp b/src/library/dlgtrackinfo.cpp index 57d36f4e387..0137c1ff8fe 100644 --- a/src/library/dlgtrackinfo.cpp +++ b/src/library/dlgtrackinfo.cpp @@ -323,7 +323,7 @@ void DlgTrackInfo::populateCues(TrackPointer pTrack) { QComboBox* colorComboBox = new QComboBox(); - QList predefinedColors = Color::predefinedColorSet.allColors; + const QList predefinedColors = Color::predefinedColorSet.allColors; for (int i = 0; i < predefinedColors.count(); i++) { PredefinedColorPointer color = predefinedColors.at(i); QColor defaultRgba = color->m_defaultRgba; From f1c84ea34b3edfc0f297140c1f6d60eb198d97de Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sat, 2 Feb 2019 20:45:31 +0100 Subject: [PATCH 48/56] Use normal for loop --- src/util/color/predefinedcolorsset.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/util/color/predefinedcolorsset.h b/src/util/color/predefinedcolorsset.h index 80c2adafb57..f5913494d4d 100644 --- a/src/util/color/predefinedcolorsset.h +++ b/src/util/color/predefinedcolorsset.h @@ -97,12 +97,11 @@ class PredefinedColorsSet final { // Returns the position of a PredefinedColor in the allColors list. int predefinedColorIndex(PredefinedColorPointer searchedColor) const { - int position = 0; - for (PredefinedColorPointer color : allColors) { + for (int position = 0; position < allColors.count(); ++position) { + PredefinedColorPointer color(allColors.at(position)); if (*color == *searchedColor) { return position; } - position++; } return 0; }; From e1db34d770bbfe6e7df45c27b0131054ddc6926e Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sat, 2 Feb 2019 21:04:01 +0100 Subject: [PATCH 49/56] Don't show THE CUE in track preferences hotcue list --- src/library/dlgtrackinfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/library/dlgtrackinfo.cpp b/src/library/dlgtrackinfo.cpp index 0137c1ff8fe..b07b43557cb 100644 --- a/src/library/dlgtrackinfo.cpp +++ b/src/library/dlgtrackinfo.cpp @@ -277,7 +277,7 @@ void DlgTrackInfo::populateCues(TrackPointer pTrack) { QListIterator it(cuePoints); while (it.hasNext()) { CuePointer pCue = it.next(); - if (pCue->getType() == Cue::CUE || pCue->getType() == Cue::LOAD) { + if (pCue->getType() == Cue::CUE) { listPoints.push_back(pCue); } } From df3a40ca3d6111f5cd38d001d702fbad834b324e Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Wed, 6 Feb 2019 22:09:35 +0100 Subject: [PATCH 50/56] Make Color::chooseContrastColor(QColor) work for dark colors, not only black --- src/util/color/color.h | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/util/color/color.h b/src/util/color/color.h index 058afce6a7f..8dbfc98e8f9 100644 --- a/src/util/color/color.h +++ b/src/util/color/color.h @@ -37,19 +37,31 @@ namespace Color { } // If the baseColor is darker than the global threshold, - // returns white, otherwise returns black. + // returns a lighter color, otherwise returns a darker color. static inline QColor chooseContrastColor(QColor baseColor) { - QColor lightColor = baseColor.lighter(); - QColor darkColor = baseColor.darker(); - - // QColor::lighter() multiplies the HSV Value by some factor. When baseColor is black, Value is 0, - // thus after multiplication it's still 0 and we get the same color. - // We manually set lightColor to darkGray in this case. - if (baseColor.toHsv().value() == 0) { - lightColor = Qt::darkGray; - lightColor.setAlpha(baseColor.alpha()); + // Will produce a color that is 60% brighter. + static const int iLighterFactor = 160; + // We consider a hsv color dark if its value is <= 20% of max value + static const int iMinimumValue = 20 * 255 / 100; + + // Convert to Hsv to make sure the conversion only happens once. + // QColor::darker() and QColor::lighter() internally convert from and to Hsv if the color is not already in Hsv. + baseColor = baseColor.toHsv(); + + QColor lightColor; + QColor darkColor = baseColor.darker().toRgb(); + // QColor::lighter() multiplies the HSV Value by some factor. When baseColor is dark, Value is near 0, + // thus after multiplication it's still near 0 and we get roughly the same color. + // We manually set lightColor in this case. + if (baseColor.value() <= iMinimumValue) { + lightColor = baseColor; + int newValue = iMinimumValue * iLighterFactor / 100; + lightColor.setHsl(baseColor.hue(), baseColor.saturation(), newValue); + } else { + lightColor = baseColor.lighter(iLighterFactor); } - return chooseColorByBrightness(baseColor, lightColor, darkColor); + QColor contrastColor = chooseColorByBrightness(baseColor, lightColor.toRgb(), darkColor.toRgb()); + return contrastColor; } } #endif /* PREDEFINEDCOLORSET_H */ From dcdfbf92c012efa1066fa0a418a13a04ff966e50 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Wed, 6 Feb 2019 23:25:53 +0100 Subject: [PATCH 51/56] Rename PredefinedColorsMap to PredefinedColorsRepresentation --- src/skin/skincontext.h | 12 ++++++------ ...orsmap.h => predefinedcolorsrepresentation.h} | 16 ++++++++-------- src/util/color/predefinedcolorsset.h | 12 ++++++------ src/waveform/renderers/waveformrendermark.cpp | 4 ++-- src/waveform/renderers/waveformrendermark.h | 2 +- src/widget/woverview.cpp | 4 ++-- src/widget/woverview.h | 2 +- 7 files changed, 26 insertions(+), 26 deletions(-) rename src/util/color/{predefinedcolorsmap.h => predefinedcolorsrepresentation.h} (70%) diff --git a/src/skin/skincontext.h b/src/skin/skincontext.h index 5e02afeb2c9..6773e2c39b5 100644 --- a/src/skin/skincontext.h +++ b/src/skin/skincontext.h @@ -12,7 +12,7 @@ #include #include -#include "../util/color/predefinedcolorsmap.h" +#include "../util/color/predefinedcolorsrepresentation.h" #include "preferences/usersettings.h" #include "skin/pixmapsource.h" #include "util/color/color.h" @@ -268,18 +268,18 @@ class SkinContext { return m_scaleFactor; } - PredefinedColorsMap getCueColorMap(const QDomNode& node, QColor defaultColor) const { - PredefinedColorsMap colorMap = Color::predefinedColorSet.defaultMap(); + PredefinedColorsRepresentation getCueColorRepresentation(const QDomNode& node, QColor defaultColor) const { + PredefinedColorsRepresentation colorRepresentation = Color::predefinedColorSet.defaultRepresentation(); for (PredefinedColorPointer color : Color::predefinedColorSet.allColors) { QString sColorName(color->m_sName); QColor skinRgba = selectColor(node, "Cue" + sColorName); if (skinRgba.isValid()) { PredefinedColorPointer originalColor = Color::predefinedColorSet.predefinedColorFromName(sColorName); - colorMap.setCustomRgba(originalColor, skinRgba); + colorRepresentation.setCustomRgba(originalColor, skinRgba); } } - colorMap.setCustomRgba(Color::predefinedColorSet.noColor, defaultColor); - return colorMap; + colorRepresentation.setCustomRgba(Color::predefinedColorSet.noColor, defaultColor); + return colorRepresentation; } private: diff --git a/src/util/color/predefinedcolorsmap.h b/src/util/color/predefinedcolorsrepresentation.h similarity index 70% rename from src/util/color/predefinedcolorsmap.h rename to src/util/color/predefinedcolorsrepresentation.h index 6b4d147d757..83f16405447 100644 --- a/src/util/color/predefinedcolorsmap.h +++ b/src/util/color/predefinedcolorsrepresentation.h @@ -1,22 +1,22 @@ -#ifndef PREDEFINEDCOLORSMAP_H -#define PREDEFINEDCOLORSMAP_H +#ifndef PREDEFINEDCOLORSREPRESENTATION_H +#define PREDEFINEDCOLORSREPRESENTATION_H #include #include #include "util/color/predefinedcolor.h" -// PredefinedColorsMap defines a particular way to render Mixxx PredefinedColors. +// PredefinedColorsRepresentation defines a particular way to render Mixxx PredefinedColors. // -// PredefinedColorsMap maps a PredefinedColor to custom Rgba color. +// 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 PredefinedColorsMap is fast. +// 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 PredefinedColorsMap final { +class PredefinedColorsRepresentation final { public: // Set a custom Rgba for a given color void setCustomRgba(PredefinedColorPointer color, QColor cutomizedRgba) { @@ -25,7 +25,7 @@ class PredefinedColorsMap final { // Returns the custom Rgba of a color. // If no custom Rgba is set for color, returns color->m_defaultRgba. - QColor map(PredefinedColorPointer color) const { + QColor representationFor(PredefinedColorPointer color) const { QColor defaultRgba = color->m_defaultRgba; if (m_colorNameMap.contains(defaultRgba.name())) { return QColor(m_colorNameMap[defaultRgba.name()]); @@ -38,4 +38,4 @@ class PredefinedColorsMap final { QHash m_colorNameMap; }; -#endif /* PREDEFINEDCOLORSMAP_H */ +#endif /* PREDEFINEDCOLORSREPRESENTATION_H */ diff --git a/src/util/color/predefinedcolorsset.h b/src/util/color/predefinedcolorsset.h index f5913494d4d..0d9bc054c80 100644 --- a/src/util/color/predefinedcolorsset.h +++ b/src/util/color/predefinedcolorsset.h @@ -4,7 +4,7 @@ #include #include -#include "predefinedcolorsmap.h" +#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. @@ -88,10 +88,10 @@ class PredefinedColorsSet final { }; PredefinedColorsSet() - : m_defaultMap() { + : m_defaultRepresentation() { for (PredefinedColorPointer color : allColors) { - m_defaultMap.setCustomRgba(color, color->m_defaultRgba); + m_defaultRepresentation.setCustomRgba(color, color->m_defaultRgba); } } @@ -128,10 +128,10 @@ class PredefinedColorsSet final { return noColor; }; - // The default color map, i.e. maps each predefined color to its default Rgba. - PredefinedColorsMap defaultMap() const { return m_defaultMap; }; + // The default color representation, i.e. maps each predefined color to its default Rgba. + PredefinedColorsRepresentation defaultRepresentation() const { return m_defaultRepresentation; }; private: - PredefinedColorsMap m_defaultMap; + PredefinedColorsRepresentation m_defaultRepresentation; }; #endif /* COLOR_H */ diff --git a/src/waveform/renderers/waveformrendermark.cpp b/src/waveform/renderers/waveformrendermark.cpp index f1182d4b5a8..dd38852aecd 100644 --- a/src/waveform/renderers/waveformrendermark.cpp +++ b/src/waveform/renderers/waveformrendermark.cpp @@ -29,7 +29,7 @@ void WaveformRenderMark::setup(const QDomNode& node, const SkinContext& context) QColor defaultColor = defaultMark ? defaultMark->getProperties().fillColor() : signalColors.getAxesColor(); - m_predefinedColorsMap = context.getCueColorMap(node, defaultColor); + m_predefinedColorsRepresentation = context.getCueColorRepresentation(node, defaultColor); } void WaveformRenderMark::draw(QPainter* painter, QPaintEvent* /*event*/) { @@ -122,7 +122,7 @@ void WaveformRenderMark::slotCuesUpdated() { WaveformMarkProperties markProperties = pMark->getProperties(); QString newLabel = pCue->getLabel(); - QColor newColor = m_predefinedColorsMap.map(pCue->getColor()); + QColor newColor = m_predefinedColorsRepresentation.representationFor(pCue->getColor()); if (markProperties.m_text.isNull() || newLabel != markProperties.m_text || !markProperties.fillColor().isValid() || newColor != markProperties.fillColor()) { markProperties.m_text = newLabel; diff --git a/src/waveform/renderers/waveformrendermark.h b/src/waveform/renderers/waveformrendermark.h index ca36318e9c0..acd65f81a53 100644 --- a/src/waveform/renderers/waveformrendermark.h +++ b/src/waveform/renderers/waveformrendermark.h @@ -34,7 +34,7 @@ class WaveformRenderMark : public QObject, public WaveformRendererAbstract { private: void generateMarkImage(WaveformMark* pMark); - PredefinedColorsMap m_predefinedColorsMap; + PredefinedColorsRepresentation m_predefinedColorsRepresentation; WaveformMarkSet m_marks; DISALLOW_COPY_AND_ASSIGN(WaveformRenderMark); diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index 1d23a0e49e3..ec54d989821 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -96,7 +96,7 @@ void WOverview::setup(const QDomNode& node, const SkinContext& context) { QColor defaultColor = defaultMark ? defaultMark->getProperties().fillColor() : m_signalColors.getAxesColor(); - m_predefinedColorsMap = context.getCueColorMap(node, defaultColor); + m_predefinedColorsRepresentation = context.getCueColorRepresentation(node, defaultColor); for (const auto& pMark: m_marks) { if (pMark->isValid()) { @@ -269,7 +269,7 @@ void WOverview::updateCues(const QList &loadedCues) { if (currentMark && currentMark->isValid()) { WaveformMarkProperties markProperties = currentMark->getProperties(); - QColor newColor = m_predefinedColorsMap.map(currentCue->getColor()); + QColor newColor = m_predefinedColorsRepresentation.representationFor(currentCue->getColor()); if (newColor != markProperties.fillColor() || newColor != markProperties.m_textColor) { markProperties.setBaseColor(newColor); currentMark->setProperties(markProperties); diff --git a/src/widget/woverview.h b/src/widget/woverview.h index e718d945a15..0fe5c670b0b 100644 --- a/src/widget/woverview.h +++ b/src/widget/woverview.h @@ -130,7 +130,7 @@ class WOverview : public WWidget { QColor m_qColorBackground; QColor m_endOfTrackColor; - PredefinedColorsMap m_predefinedColorsMap; + PredefinedColorsRepresentation m_predefinedColorsRepresentation; WaveformMarkSet m_marks; std::vector m_markRanges; From 3e10c98947515e389bf9a8eb8d8674b67cd29a2e Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sun, 10 Feb 2019 13:20:14 +0100 Subject: [PATCH 52/56] Make selected color visible in track preferences cue list --- src/library/dlgtrackinfo.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/library/dlgtrackinfo.cpp b/src/library/dlgtrackinfo.cpp index b07b43557cb..34add6b9c72 100644 --- a/src/library/dlgtrackinfo.cpp +++ b/src/library/dlgtrackinfo.cpp @@ -328,12 +328,12 @@ void DlgTrackInfo::populateCues(TrackPointer pTrack) { PredefinedColorPointer color = predefinedColors.at(i); QColor defaultRgba = color->m_defaultRgba; colorComboBox->addItem(color->m_sDisplayName, defaultRgba); - const QModelIndex idx = colorComboBox->model()->index(i, 0); if (*color != *Color::predefinedColorSet.noColor) { - colorComboBox->model()->setData(idx, defaultRgba, Qt::BackgroundColorRole); + QPixmap pixmap(80,80); + pixmap.fill(defaultRgba); + QIcon icon(pixmap); + colorComboBox->setItemIcon(i, icon); } - colorComboBox->setItemData(i, Color::chooseContrastColor(defaultRgba), Qt::TextColorRole); - } PredefinedColorPointer cueColor = pCue->getColor(); colorComboBox->setCurrentIndex(Color::predefinedColorSet.predefinedColorIndex(cueColor)); From d3e5a5f257549e45c7e0e91ed348c52f9680d88d Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sun, 10 Feb 2019 13:34:04 +0100 Subject: [PATCH 53/56] Correct size of cue color column in track preferences --- src/library/dlgtrackinfo.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/library/dlgtrackinfo.cpp b/src/library/dlgtrackinfo.cpp index 34add6b9c72..0af9256dca5 100644 --- a/src/library/dlgtrackinfo.cpp +++ b/src/library/dlgtrackinfo.cpp @@ -349,6 +349,7 @@ void DlgTrackInfo::populateCues(TrackPointer pTrack) { } cueTable->setSortingEnabled(true); cueTable->horizontalHeader()->setStretchLastSection(true); + cueTable->horizontalHeader()->setSectionResizeMode(3, QHeaderView::ResizeToContents); } void DlgTrackInfo::saveTrack() { From 6f83fe7657c54466303a210ddf725a4da20aaeb4 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Sun, 10 Feb 2019 13:56:05 +0100 Subject: [PATCH 54/56] Revert "Added JS utility object for dealing with hotcue colors from MixxxControl" This reverts commit c49961f8a84bac3b83087a5b74675e515c33ab16. --- res/controllers/common-controller-scripts.js | 42 -------------------- 1 file changed, 42 deletions(-) diff --git a/res/controllers/common-controller-scripts.js b/res/controllers/common-controller-scripts.js index c55c8d5b926..c1d2d09f58f 100644 --- a/res/controllers/common-controller-scripts.js +++ b/res/controllers/common-controller-scripts.js @@ -442,48 +442,6 @@ bpm.tapButton = function(deck) { // print("Script: BPM="+average+" setting to "+fRateScale); } -// color - Basic Object used for convient interface with the hotcue_color ControlObjects -color = { - // member should be set directly but only in the [0;255] range. - red: 0, - green: 0, - blue: 0, - alpha: 255, -} - - -/* -------- ------------------------------------------------------ - color.fromCO - Purpose: Setter that splits the combined colors into their components - and sets the color components in the object - Input: combined color value - Output: - - -------- ------------------------------------------------------ */ - -color.fromCO = function(color) { - this.alpha = color >> 24 & 0xFF; - this.red = color >> 16 & 0xFF; - this.green = color >> 8 & 0xFF; - this.blue = color & 0xFF; -} -/* -------- ------------------------------------------------------ - color.toCO - Purpose: Combines the colors back into a single value that - that could be used to set the MixxxControl value - Input: - - Output: struct containing the color components - -------- ------------------------------------------------------ */ -color.toCO = function() { - // javascript objects don't have "access control" and this object - // doesn't provide setters (interaction is supposed to be done via direct access) - // so this getter function sanitizes the values on export. - return (this.alpha % 255) << 24 + - (this.red % 255) << 16 + - (this.green % 255) << 8 + - this. blue % 255; -} - - // ----------------- Common regular expressions -------------------------- script.samplerRegEx = /^\[Sampler(\d+)\]$/ script.channelRegEx = /^\[Channel(\d+)\]$/ From 4c47b3ad045733c2095251b94850a5e4c30f86e9 Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Tue, 12 Feb 2019 01:03:34 +0100 Subject: [PATCH 55/56] Add JS api for cue colors --- build/depends.py | 1 + src/controllers/colorjsproxy.cpp | 36 ++++++++++++++++++++++++++++ src/controllers/colorjsproxy.h | 27 +++++++++++++++++++++ src/controllers/controllerengine.cpp | 4 ++++ src/controllers/controllerengine.h | 3 +++ src/test/controllerengine_test.cpp | 24 +++++++++++++++++++ 6 files changed, 95 insertions(+) create mode 100644 src/controllers/colorjsproxy.cpp create mode 100644 src/controllers/colorjsproxy.h diff --git a/build/depends.py b/build/depends.py index d06b247a1cb..7092cf7414e 100644 --- a/build/depends.py +++ b/build/depends.py @@ -871,6 +871,7 @@ def sources(self, build): "src/controllers/midi/midioutputhandler.cpp", "src/controllers/softtakeover.cpp", "src/controllers/keyboard/keyboardeventfilter.cpp", + "src/controllers/colorjsproxy.cpp", "src/main.cpp", "src/mixxx.cpp", diff --git a/src/controllers/colorjsproxy.cpp b/src/controllers/colorjsproxy.cpp new file mode 100644 index 00000000000..2208510cc75 --- /dev/null +++ b/src/controllers/colorjsproxy.cpp @@ -0,0 +1,36 @@ +#include "controllers/colorjsproxy.h" + +ColorJSProxy::ColorJSProxy(QScriptEngine* pScriptEngine) + : m_pScriptEngine(pScriptEngine), + m_predefinedColorsList(makePredefinedColorsList(pScriptEngine)){}; + +ColorJSProxy::~ColorJSProxy() {}; + +QScriptValue ColorJSProxy::predefinedColorFromId(int iId) { + PredefinedColorPointer color(Color::predefinedColorSet.predefinedColorFromId(iId)); + return jsColorFrom(color); +}; + +Q_INVOKABLE QScriptValue ColorJSProxy::predefinedColorsList() { + return m_predefinedColorsList; +} + +QScriptValue ColorJSProxy::jsColorFrom(PredefinedColorPointer predefinedColor) { + 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); + return jsColor; +} + +QScriptValue ColorJSProxy::makePredefinedColorsList(QScriptEngine* pScriptEngine) { + int numColors = Color::predefinedColorSet.allColors.length(); + QScriptValue colorList = pScriptEngine->newArray(numColors); + for (int i = 0; i < numColors; ++i) { + PredefinedColorPointer color = Color::predefinedColorSet.allColors.at(i); + colorList.setProperty(i, jsColorFrom(color)); + } + return colorList; +} diff --git a/src/controllers/colorjsproxy.h b/src/controllers/colorjsproxy.h new file mode 100644 index 00000000000..e6ebeda1d9b --- /dev/null +++ b/src/controllers/colorjsproxy.h @@ -0,0 +1,27 @@ +#ifndef COLORJSPROXY_H +#define COLORJSPROXY_H + +#include +#include +#include + +#include "util/color/color.h" + +class ColorJSProxy: public QObject { + Q_OBJECT + public: + ColorJSProxy(QScriptEngine* pScriptEngine); + + virtual ~ColorJSProxy(); + + Q_INVOKABLE QScriptValue predefinedColorFromId(int iId); + Q_INVOKABLE QScriptValue predefinedColorsList(); + + private: + QScriptValue jsColorFrom(PredefinedColorPointer predefinedColor); + QScriptValue makePredefinedColorsList(QScriptEngine* pScriptEngine); + QScriptEngine* m_pScriptEngine; + QScriptValue m_predefinedColorsList; +}; + +#endif /* COLORJSPROXY_H */ diff --git a/src/controllers/controllerengine.cpp b/src/controllers/controllerengine.cpp index 0aa1d102a5b..87d7d56071d 100644 --- a/src/controllers/controllerengine.cpp +++ b/src/controllers/controllerengine.cpp @@ -185,6 +185,7 @@ void ControllerEngine::gracefulShutdown() { ++it; } + m_pColorJSProxy.reset(); delete m_pBaClass; m_pBaClass = nullptr; } @@ -212,6 +213,9 @@ void ControllerEngine::initializeScriptEngine() { engineGlobalObject.setProperty("midi", m_pEngine->newQObject(m_pController)); } + m_pColorJSProxy = std::make_unique(m_pEngine); + engineGlobalObject.setProperty("color", m_pEngine->newQObject(m_pColorJSProxy.get())); + m_pBaClass = new ByteArrayClass(m_pEngine); engineGlobalObject.setProperty("ByteArray", m_pBaClass->constructor()); } diff --git a/src/controllers/controllerengine.h b/src/controllers/controllerengine.h index 6b00c46172b..e9ed4bb88fe 100644 --- a/src/controllers/controllerengine.h +++ b/src/controllers/controllerengine.h @@ -16,9 +16,11 @@ #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" +#include "util/memory.h" // Forward declaration(s) class Controller; @@ -204,6 +206,7 @@ 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; diff --git a/src/test/controllerengine_test.cpp b/src/test/controllerengine_test.cpp index 2f5ba3cfa98..1c9876fdf77 100644 --- a/src/test/controllerengine_test.cpp +++ b/src/test/controllerengine_test.cpp @@ -18,6 +18,7 @@ class ControllerEngineTest : public MixxxTest { mixxx::Time::setTestElapsedTime(mixxx::Duration::fromMillis(10)); QThread::currentThread()->setObjectName("Main"); cEngine = new ControllerEngine(nullptr); + pScriptEngine = cEngine->m_pEngine; ControllerDebug::enable(); cEngine->setPopups(false); } @@ -35,6 +36,7 @@ class ControllerEngineTest : public MixxxTest { } ControllerEngine *cEngine; + QScriptEngine *pScriptEngine; }; TEST_F(ControllerEngineTest, commonScriptHasNoErrors) { @@ -588,3 +590,25 @@ TEST_F(ControllerEngineTest, connectionExecutesWithCorrectThisObject) { // The counter should have been incremented exactly once. EXPECT_DOUBLE_EQ(1.0, pass->get()); } + +TEST_F(ControllerEngineTest, colorProxy) { + QList allColors = Color::predefinedColorSet.allColors; + 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); + } +} From b55604ea5898428f945bebe09826cfb0870bc96d Mon Sep 17 00:00:00 2001 From: Ferran Pujol Camins Date: Wed, 13 Feb 2019 13:24:18 +0100 Subject: [PATCH 56/56] Add comment --- src/util/color/color.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/color/color.h b/src/util/color/color.h index 8dbfc98e8f9..df6eea05c60 100644 --- a/src/util/color/color.h +++ b/src/util/color/color.h @@ -60,6 +60,11 @@ namespace Color { } else { lightColor = baseColor.lighter(iLighterFactor); } + + // Even though we have the HSV representation fo the color here, the "value" component alone is + // not a good indicator of a color brightness (saturation comes into play too). + // That's why we call chooseColorByBrightness so the proper brightness of the color is used + // to choose between the light and the dark colors. QColor contrastColor = chooseColorByBrightness(baseColor, lightColor.toRgb(), darkColor.toRgb()); return contrastColor; }