summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBe <be@mixxx.org>2020-04-19 03:57:50 -0500
committerGitHub <noreply@github.com>2020-04-19 03:57:50 -0500
commitf1e13f93ad35dc1de34a6e8741f369cbb95bc71e (patch)
treefe75d53e8ee9300a41173fd45c0e2893cf1a7f57
parented56ea0ed76afff014ad108ed491c07dc32ea219 (diff)
parent7bf740cdd4492134f78482f5e88b3430ff218758 (diff)
Merge pull request #2541 from Holzhaus/track-colors-from-controller
Allow changing track colors from controller
-rw-r--r--res/controllers/Roland_DJ-505-scripts.js19
-rw-r--r--src/library/librarycontrol.cpp44
-rw-r--r--src/library/librarycontrol.h7
-rw-r--r--src/library/libraryview.h31
-rw-r--r--src/util/color/colorpalette.cpp22
-rw-r--r--src/util/color/colorpalette.h2
-rw-r--r--src/widget/wtracktableview.cpp97
-rw-r--r--src/widget/wtracktableview.h2
8 files changed, 186 insertions, 38 deletions
diff --git a/res/controllers/Roland_DJ-505-scripts.js b/res/controllers/Roland_DJ-505-scripts.js
index abb3f8ea8f..89264bf625 100644
--- a/res/controllers/Roland_DJ-505-scripts.js
+++ b/res/controllers/Roland_DJ-505-scripts.js
@@ -201,6 +201,8 @@ DJ505.shutdown = function() {
DJ505.browseEncoder = new components.Encoder({
longPressTimer: 0,
longPressTimeout: 250,
+ trackColorCycleEnabled: false,
+ trackColorCycleHappened: false,
previewSeekEnabled: false,
previewSeekHappened: false,
unshift: function() {
@@ -249,12 +251,25 @@ DJ505.browseEncoder = new components.Encoder({
shift: function() {
this.onKnobEvent = function(rotateValue) {
if (rotateValue !== 0) {
- engine.setValue("[Playlist]", "SelectPlaylist", rotateValue);
+ if (this.trackColorCycleEnabled) {
+ var key = (rotateValue > 0) ? "track_color_next" : "track_color_prev";
+ engine.setValue("[Library]", key, 1.0);
+ this.trackColorCycleHappened = true;
+ } else {
+ engine.setValue("[Playlist]", "SelectPlaylist", rotateValue);
+ }
}
};
this.onButtonEvent = function(value) {
if (value) {
- script.triggerControl("[Playlist]", "ToggleSelectedSidebarItem");
+ this.trackColorCycleEnabled = true;
+ this.trackColorCycleHappened = false;
+ } else {
+ if (!this.trackColorCycleHappened) {
+ script.triggerControl("[Playlist]", "ToggleSelectedSidebarItem");
+ }
+ this.trackColorCycleEnabled = false;
+ this.trackColorCycleHappened = false;
}
};
},
diff --git a/src/library/librarycontrol.cpp b/src/library/librarycontrol.cpp
index aed741c1ce..feacf2baa0 100644
--- a/src/library/librarycontrol.cpp
+++ b/src/library/librarycontrol.cpp
@@ -190,6 +190,18 @@ LibraryControl::LibraryControl(Library* pLibrary)
this,
&LibraryControl::slotIncrementFontSize);
+ // Track Color controls
+ m_pTrackColorPrev = std::make_unique<ControlPushButton>(ConfigKey("[Library]", "track_color_prev"));
+ m_pTrackColorNext = std::make_unique<ControlPushButton>(ConfigKey("[Library]", "track_color_next"));
+ connect(m_pTrackColorPrev.get(),
+ &ControlPushButton::valueChanged,
+ this,
+ &LibraryControl::slotTrackColorPrev);
+ connect(m_pTrackColorNext.get(),
+ &ControlPushButton::valueChanged,
+ this,
+ &LibraryControl::slotTrackColorNext);
+
/// Deprecated controls
m_pSelectNextTrack = std::make_unique<ControlPushButton>(ConfigKey("[Playlist]", "SelectNextTrack"));
connect(m_pSelectNextTrack.get(),
@@ -563,8 +575,8 @@ void LibraryControl::slotGoToItem(double v) {
slotToggleSelectedSidebarItem(v);
}
}
- // TODO(xxx) instead of remote control the widgets individual, we should
- // translate this into Alt+Return and handle it at each library widget
+ // TODO(xxx) instead of remote control the widgets individual, we should
+ // translate this into Alt+Return and handle it at each library widget
// individual https://bugs.launchpad.net/mixxx/+bug/1758618
//emitKeyEvent(QKeyEvent{QEvent::KeyPress, Qt::Key_Return, Qt::AltModifier});
}
@@ -603,3 +615,31 @@ void LibraryControl::slotDecrementFontSize(double v) {
slotFontSize(-1);
}
}
+
+void LibraryControl::slotTrackColorPrev(double v) {
+ if (!m_pLibraryWidget) {
+ return;
+ }
+
+ if (v > 0) {
+ LibraryView* activeView = m_pLibraryWidget->getActiveView();
+ if (!activeView) {
+ return;
+ }
+ activeView->assignPreviousTrackColor();
+ }
+}
+
+void LibraryControl::slotTrackColorNext(double v) {
+ if (!m_pLibraryWidget) {
+ return;
+ }
+
+ if (v > 0) {
+ LibraryView* activeView = m_pLibraryWidget->getActiveView();
+ if (!activeView) {
+ return;
+ }
+ activeView->assignNextTrackColor();
+ }
+}
diff --git a/src/library/librarycontrol.h b/src/library/librarycontrol.h
index 47524dfa4b..3afd2909e7 100644
--- a/src/library/librarycontrol.h
+++ b/src/library/librarycontrol.h
@@ -65,6 +65,9 @@ class LibraryControl : public QObject {
void slotMoveFocus(double);
void slotGoToItem(double v);
+ void slotTrackColorPrev(double v);
+ void slotTrackColorNext(double v);
+
// Deprecated navigation slots
void slotSelectNextTrack(double v);
void slotSelectPrevTrack(double v);
@@ -129,6 +132,10 @@ class LibraryControl : public QObject {
std::unique_ptr<ControlEncoder> m_pSortColumnToggle;
std::unique_ptr<ControlPushButton> m_pSortOrder;
+ // Controls to change track color
+ std::unique_ptr<ControlPushButton> m_pTrackColorPrev;
+ std::unique_ptr<ControlPushButton> m_pTrackColorNext;
+
// Font sizes
std::unique_ptr<ControlPushButton> m_pFontSizeIncrement;
std::unique_ptr<ControlPushButton> m_pFontSizeDecrement;
diff --git a/src/library/libraryview.h b/src/library/libraryview.h
index 293b7b1db7..378691c55a 100644
--- a/src/library/libraryview.h
+++ b/src/library/libraryview.h
@@ -1,8 +1,8 @@
-// libraryview.h
-// Created 8/28/2009 by RJ Ryan (rryan@mit.edu)
-//
-// LibraryView is an abstract interface that all views to be used with the
-// Library widget should support.
+/// libraryview.h
+/// Created 8/28/2009 by RJ Ryan (rryan@mit.edu)
+///
+/// LibraryView is an abstract interface that all views to be used with the
+/// Library widget should support.
#ifndef LIBRARYVIEW_H
#define LIBRARYVIEW_H
@@ -15,27 +15,32 @@ class LibraryView {
virtual void onShow() = 0;
virtual bool hasFocus() const = 0;
- // reimplement if LibraryView should be able to search
+ /// Reimplement if LibraryView should be able to search
virtual void onSearch(const QString& text) {Q_UNUSED(text);}
- // If applicable, requests that the LibraryView load the selected
- // track. Does nothing otherwise.
+ /// If applicable, requests that the LibraryView load the selected
+ /// track. Does nothing otherwise.
virtual void loadSelectedTrack() {};
virtual void slotAddToAutoDJBottom() {};
virtual void slotAddToAutoDJTop() {};
virtual void slotAddToAutoDJReplace() {};
- // If applicable, requests that the LibraryView load the selected track to
- // the specified group. Does nothing otherwise.
+ /// If applicable, requests that the LibraryView load the selected track to
+ /// the specified group. Does nothing otherwise.
virtual void loadSelectedTrackToGroup(QString group, bool play) {
Q_UNUSED(group); Q_UNUSED(play);
}
- // If a selection is applicable for this view, request that the selection be
- // increased or decreased by the provided delta. For example, for a value of
- // 1, the view should move to the next selection in the list.
+ /// If a selection is applicable for this view, request that the selection be
+ /// increased or decreased by the provided delta. For example, for a value of
+ /// 1, the view should move to the next selection in the list.
virtual void moveSelection(int delta) {Q_UNUSED(delta);}
+
+ /// If applicable, requests that the LibraryView changes the track color of
+ /// the selected track. Does nothing otherwise.
+ virtual void assignPreviousTrackColor(){};
+ virtual void assignNextTrackColor(){};
};
#endif /* LIBRARYVIEW_H */
diff --git a/src/util/color/colorpalette.cpp b/src/util/color/colorpalette.cpp
index 9d4d7186a9..b0bb2a5388 100644
--- a/src/util/color/colorpalette.cpp
+++ b/src/util/color/colorpalette.cpp
@@ -5,6 +5,17 @@ mixxx::RgbColor ColorPalette::nextColor(mixxx::RgbColor color) const {
return at((indexOf(color) + 1) % size());
}
+mixxx::RgbColor::optional_t ColorPalette::nextColor(mixxx::RgbColor::optional_t color) const {
+ if (color) {
+ // If color is the last element in the palette, return no color
+ if (indexOf(*color) == size() - 1) {
+ return std::nullopt;
+ }
+ return nextColor(*color);
+ }
+ return at(0);
+}
+
mixxx::RgbColor ColorPalette::previousColor(mixxx::RgbColor color) const {
int iIndex = indexOf(color);
if (iIndex < 0) {
@@ -16,6 +27,17 @@ mixxx::RgbColor ColorPalette::previousColor(mixxx::RgbColor color) const {
return at(iIndex);
}
+mixxx::RgbColor::optional_t ColorPalette::previousColor(mixxx::RgbColor::optional_t color) const {
+ if (color) {
+ // If color is the first element in the palette, return no color
+ if (indexOf(*color) == 0) {
+ return std::nullopt;
+ }
+ return previousColor(*color);
+ }
+ return at(size() - 1);
+}
+
mixxx::RgbColor ColorPalette::colorForHotcueIndex(unsigned int hotcueIndex) const {
int colorIndex;
if (m_colorIndicesByHotcue.isEmpty()) {
diff --git a/src/util/color/colorpalette.h b/src/util/color/colorpalette.h
index bdd0f859b4..b3c4872013 100644
--- a/src/util/color/colorpalette.h
+++ b/src/util/color/colorpalette.h
@@ -32,7 +32,9 @@ class ColorPalette final {
}
mixxx::RgbColor nextColor(mixxx::RgbColor color) const;
+ mixxx::RgbColor::optional_t nextColor(mixxx::RgbColor::optional_t color) const;
mixxx::RgbColor previousColor(mixxx::RgbColor color) const;
+ mixxx::RgbColor::optional_t previousColor(mixxx::RgbColor::optional_t color) const;
mixxx::RgbColor colorForHotcueIndex(unsigned int index) const;
QList<mixxx::RgbColor>::const_iterator begin() const {
diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp
index c50b6e56cf..c7c6742dcf 100644
--- a/src/widget/wtracktableview.cpp
+++ b/src/widget/wtracktableview.cpp
@@ -13,6 +13,7 @@
#include "library/trackcollection.h"
#include "library/trackcollectionmanager.h"
#include "mixer/playermanager.h"
+#include "preferences/colorpalettesettings.h"
#include "preferences/dialog/dlgpreflibrary.h"
#include "sources/soundsourceproxy.h"
#include "track/track.h"
@@ -23,6 +24,12 @@
#include "widget/wtrackmenu.h"
#include "widget/wtracktableviewheader.h"
+namespace {
+
+const ConfigKey kConfigKeyAllowTrackLoadToPlayingDeck("[Controls]", "AllowTrackLoadToPlayingDeck");
+
+}
+
WTrackTableView::WTrackTableView(QWidget* parent,
UserSettingsPointer pConfig,
TrackCollectionManager* pTrackCollectionManager,
@@ -39,8 +46,7 @@ WTrackTableView::WTrackTableView(QWidget* parent,
m_selectionChangedSinceLastGuiTick(true),
m_loadCachedOnly(false) {
// Connect slots and signals to make the world go 'round.
- connect(this, &WTrackTableView::doubleClicked,
- this, &WTrackTableView::slotMouseDoubleClicked);
+ connect(this, &WTrackTableView::doubleClicked, this, &WTrackTableView::slotMouseDoubleClicked);
m_pCOTGuiTick = new ControlProxy("[Master]", "guiTick50ms", this);
m_pCOTGuiTick->connectValueChanged(this, &WTrackTableView::slotGuiTick50ms);
@@ -53,13 +59,17 @@ WTrackTableView::WTrackTableView(QWidget* parent,
m_pSortOrder = new ControlProxy("[Library]", "sort_order", this);
m_pSortOrder->connectValueChanged(this, &WTrackTableView::applySortingIfVisible);
- connect(this, &WTrackTableView::scrollValueChanged,
- this, &WTrackTableView::slotScrollValueChanged);
+ connect(this,
+ &WTrackTableView::scrollValueChanged,
+ this,
+ &WTrackTableView::slotScrollValueChanged);
- QShortcut *setFocusShortcut = new QShortcut(
- QKeySequence(tr("ESC", "Focus")), this);
- connect(setFocusShortcut, &QShortcut::activated,
- this, qOverload<>(&WTrackTableView::setFocus));
+ QShortcut* setFocusShortcut =
+ new QShortcut(QKeySequence(tr("ESC", "Focus")), this);
+ connect(setFocusShortcut,
+ &QShortcut::activated,
+ this,
+ qOverload<>(&WTrackTableView::setFocus));
}
WTrackTableView::~WTrackTableView() {
@@ -84,8 +94,8 @@ void WTrackTableView::slotScrollValueChanged(int /*unused*/) {
enableCachedOnly();
}
-void WTrackTableView::selectionChanged(const QItemSelection& selected,
- const QItemSelection& deselected) {
+void WTrackTableView::selectionChanged(
+ const QItemSelection& selected, const QItemSelection& deselected) {
m_selectionChangedSinceLastGuiTick = true;
enableCachedOnly();
QTableView::selectionChanged(selected, deselected);
@@ -96,7 +106,6 @@ void WTrackTableView::slotGuiTick50ms(double /*unused*/) {
// we load un-cached cover arts as well.
mixxx::Duration timeDelta = mixxx::Time::elapsed() - m_lastUserAction;
if (m_loadCachedOnly && timeDelta > mixxx::Duration::fromMillis(100)) {
-
// Show the currently selected track in the large cover art view and
// highlights crate and playlists. Doing this in selectionChanged
// slows down scrolling performance so we wait until the user has
@@ -127,7 +136,7 @@ void WTrackTableView::slotGuiTick50ms(double /*unused*/) {
}
// slot
-void WTrackTableView::loadTrackModel(QAbstractItemModel *model) {
+void WTrackTableView::loadTrackModel(QAbstractItemModel* model) {
qDebug() << "WTrackTableView::loadTrackModel()" << model;
TrackModel* trackModel = dynamic_cast<TrackModel*>(model);
@@ -148,9 +157,10 @@ void WTrackTableView::loadTrackModel(QAbstractItemModel *model) {
if (getTrackModel() == trackModel) {
// Re-sort the table even if the track model is the same. This triggers
// a select() if the table is dirty.
- doSortByColumn(horizontalHeader()->sortIndicatorSection(), horizontalHeader()->sortIndicatorOrder());
+ doSortByColumn(horizontalHeader()->sortIndicatorSection(),
+ horizontalHeader()->sortIndicatorOrder());
return;
- }else{
+ } else {
newModel = trackModel;
saveVScrollBarPos(getTrackModel());
//saving current vertical bar position
@@ -208,7 +218,8 @@ void WTrackTableView::loadTrackModel(QAbstractItemModel *model) {
// Initialize all column-specific things
for (int i = 0; i < model->columnCount(); ++i) {
// Setup delegates according to what the model tells us
- QAbstractItemDelegate* delegate = trackModel->delegateForColumn(i, this);
+ QAbstractItemDelegate* delegate =
+ trackModel->delegateForColumn(i, this);
// We need to delete the old delegates, since the docs say the view will
// not take ownership of them.
QAbstractItemDelegate* old_delegate = itemDelegateForColumn(i);
@@ -227,7 +238,7 @@ void WTrackTableView::loadTrackModel(QAbstractItemModel *model) {
* key column by default unless the user brings it to front
*/
if (trackModel->isColumnHiddenByDefault(i) &&
- !header->hasPersistedHeaderState()) {
+ !header->hasPersistedHeaderState()) {
//qDebug() << "Hiding column" << i;
horizontalHeader()->hideSection(i);
}
@@ -238,8 +249,11 @@ void WTrackTableView::loadTrackModel(QAbstractItemModel *model) {
// But Qt::UniqueConnections do not work for lambdas, non-member functions
// and functors; they only apply to connecting to member functions.
// https://doc.qt.io/qt-5/qobject.html#connect
- connect(horizontalHeader(), &QHeaderView::sortIndicatorChanged,
- this, &WTrackTableView::slotSortingChanged, Qt::AutoConnection);
+ connect(horizontalHeader(),
+ &QHeaderView::sortIndicatorChanged,
+ this,
+ &WTrackTableView::slotSortingChanged,
+ Qt::AutoConnection);
int sortColumn;
Qt::SortOrder sortOrder;
@@ -350,6 +364,48 @@ void WTrackTableView::slotMouseDoubleClicked(const QModelIndex& index) {
}
}
+void WTrackTableView::assignPreviousTrackColor() {
+ QModelIndexList indices = selectionModel()->selectedRows();
+ if (indices.size() <= 0) {
+ return;
+ }
+
+ TrackModel* trackModel = getTrackModel();
+ if (!trackModel) {
+ return;
+ }
+
+ QModelIndex index = indices.at(0);
+ TrackPointer pTrack = trackModel->getTrack(index);
+ if (pTrack) {
+ ColorPaletteSettings colorPaletteSettings(m_pConfig);
+ ColorPalette colorPalette = colorPaletteSettings.getTrackColorPalette();
+ mixxx::RgbColor::optional_t color = pTrack->getColor();
+ pTrack->setColor(colorPalette.previousColor(color));
+ }
+}
+
+void WTrackTableView::assignNextTrackColor() {
+ QModelIndexList indices = selectionModel()->selectedRows();
+ if (indices.size() <= 0) {
+ return;
+ }
+
+ TrackModel* trackModel = getTrackModel();
+ if (!trackModel) {
+ return;
+ }
+
+ QModelIndex index = indices.at(0);
+ TrackPointer pTrack = trackModel->getTrack(index);
+ if (pTrack) {
+ ColorPaletteSettings colorPaletteSettings(m_pConfig);
+ ColorPalette colorPalette = colorPaletteSettings.getTrackColorPalette();
+ mixxx::RgbColor::optional_t color = pTrack->getColor();
+ pTrack->setColor(colorPalette.nextColor(color));
+ }
+}
+
void WTrackTableView::slotPurge() {
QModelIndexList indices = selectionModel()->selectedRows();
if (indices.size() > 0) {
@@ -771,9 +827,8 @@ void WTrackTableView::doSortByColumn(int headerSection, Qt::SortOrder sortOrder)
QItemSelectionModel* currentSelection = selectionModel();
currentSelection->reset(); // remove current selection
- QMap<int,int> selectedRows;
+ QMap<int, int> selectedRows;
for (const auto& trackId : selectedTrackIds) {
-
// TODO(rryan) slowly fixing the issues with BaseSqlTableModel. This
// code is broken for playlists because it assumes each trackid is in
// the table once. This will erroneously select all instances of the
@@ -790,7 +845,7 @@ void WTrackTableView::doSortByColumn(int headerSection, Qt::SortOrder sortOrder)
}
QModelIndex first;
- QMapIterator<int,int> i(selectedRows);
+ QMapIterator<int, int> i(selectedRows);
while (i.hasNext()) {
i.next();
QModelIndex tl = itemModel->index(i.key(), 0);
diff --git a/src/widget/wtracktableview.h b/src/widget/wtracktableview.h
index 4ec2d68017..3d7a41dfd0 100644
--- a/src/widget/wtracktableview.h
+++ b/src/widget/wtracktableview.h
@@ -38,6 +38,8 @@ class WTrackTableView : public WLibraryTableView {
void onShow() override;
bool hasFocus() const override;
void keyPressEvent(QKeyEvent* event) override;
+ void assignNextTrackColor() override;
+ void assignPreviousTrackColor() override;
QList<TrackId> getSelectedTrackIds() const;
void setSelectedTracks(const QList<TrackId>& tracks);
void saveCurrentVScrollBarPos();