From 93c04517f8c7e9a8441cda5b12373be7d1f8dde4 Mon Sep 17 00:00:00 2001 From: Swiftb0y Date: Tue, 2 Oct 2018 16:31:38 +0200 Subject: [PATCH 01/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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+)\]$/ ;