Skip to content

Commit

Permalink
Merge pull request mixxxdj#13390 from danferns/static_key_colors
Browse files Browse the repository at this point in the history
feat: static color coding for key column
  • Loading branch information
daschuer authored Jul 13, 2024
2 parents d2752a9 + f75ec58 commit 1b9ebc1
Show file tree
Hide file tree
Showing 14 changed files with 219 additions and 10 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,7 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL
src/library/tabledelegates/bpmdelegate.cpp
src/library/tabledelegates/colordelegate.cpp
src/library/tabledelegates/coverartdelegate.cpp
src/library/tabledelegates/keydelegate.cpp
src/library/tabledelegates/locationdelegate.cpp
src/library/tabledelegates/multilineeditdelegate.cpp
src/library/tabledelegates/playcountdelegate.cpp
Expand Down
39 changes: 29 additions & 10 deletions src/library/basetracktablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "library/tabledelegates/bpmdelegate.h"
#include "library/tabledelegates/colordelegate.h"
#include "library/tabledelegates/coverartdelegate.h"
#include "library/tabledelegates/keydelegate.h"
#include "library/tabledelegates/locationdelegate.h"
#include "library/tabledelegates/multilineeditdelegate.h"
#include "library/tabledelegates/playcountdelegate.h"
Expand All @@ -19,6 +20,7 @@
#include "mixer/playerinfo.h"
#include "mixer/playermanager.h"
#include "moc_basetracktablemodel.cpp"
#include "track/keyutils.h"
#include "track/track.h"
#include "util/assert.h"
#include "util/clipboard.h"
Expand Down Expand Up @@ -99,9 +101,11 @@ QSqlDatabase cloneDatabase(
constexpr int BaseTrackTableModel::kBpmColumnPrecisionDefault;
constexpr int BaseTrackTableModel::kBpmColumnPrecisionMinimum;
constexpr int BaseTrackTableModel::kBpmColumnPrecisionMaximum;
constexpr bool BaseTrackTableModel::kKeyColorsEnabledDefault;

int BaseTrackTableModel::s_bpmColumnPrecision =
kBpmColumnPrecisionDefault;
bool BaseTrackTableModel::s_keyColorsEnabled = kKeyColorsEnabledDefault;

// static
void BaseTrackTableModel::setBpmColumnPrecision(int precision) {
Expand All @@ -114,14 +118,20 @@ void BaseTrackTableModel::setBpmColumnPrecision(int precision) {
s_bpmColumnPrecision = precision;
}

// static
void BaseTrackTableModel::setKeyColorsEnabled(bool keyColorsEnabled) {
// todo: need to refresh the key column when this setting changes
s_keyColorsEnabled = keyColorsEnabled;
}

bool BaseTrackTableModel::s_bApplyPlayedTrackColor =
kApplyPlayedTrackColorDefault;

void BaseTrackTableModel::setApplyPlayedTrackColor(bool apply) {
s_bApplyPlayedTrackColor = apply;
}

//static
// static
QStringList BaseTrackTableModel::defaultTableColumns() {
return kDefaultTableColumns;
}
Expand Down Expand Up @@ -506,6 +516,8 @@ QAbstractItemDelegate* BaseTrackTableModel::delegateForColumn(
this,
&BaseTrackTableModel::slotRefreshCoverRows);
return pCoverArtDelegate;
} else if (index == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_KEY)) {
return new KeyDelegate(pTableView);
}
return nullptr;
}
Expand Down Expand Up @@ -576,7 +588,8 @@ QVariant BaseTrackTableModel::data(
role != Qt::CheckStateRole &&
role != Qt::ToolTipRole &&
role != kDataExportRole &&
role != Qt::TextAlignmentRole) {
role != Qt::TextAlignmentRole &&
role != Qt::UserRole) {
return QVariant();
}

Expand Down Expand Up @@ -889,19 +902,14 @@ QVariant BaseTrackTableModel::roleValue(
case ColumnCache::COLUMN_LIBRARYTABLE_KEY: {
// If we know the semantic key via the LIBRARYTABLE_KEY_ID
// column (as opposed to the string representation of the key
// currently stored in the DB) then lookup the key and render it
// using the user's selected notation.
// currently stored in the DB) then lookup the key and return it
const QVariant keyCodeValue = rawSiblingValue(
index,
ColumnCache::COLUMN_LIBRARYTABLE_KEY_ID);
if (keyCodeValue.isNull()) {
// Otherwise, just use the column value as is
return std::move(rawValue);
}
// Convert or clear invalid values
VERIFY_OR_DEBUG_ASSERT(keyCodeValue.canConvert<int>()) {
return QVariant();
}
bool ok;
const auto keyCode = keyCodeValue.toInt(&ok);
VERIFY_OR_DEBUG_ASSERT(ok) {
Expand All @@ -911,8 +919,7 @@ QVariant BaseTrackTableModel::roleValue(
if (key == mixxx::track::io::key::INVALID) {
return QVariant();
}
// Render the key with the user-provided notation
return KeyUtils::keyToString(key);
return QVariant::fromValue(key);
}
case ColumnCache::COLUMN_LIBRARYTABLE_REPLAYGAIN: {
if (rawValue.isNull()) {
Expand Down Expand Up @@ -1020,6 +1027,18 @@ QVariant BaseTrackTableModel::roleValue(
return QVariant(); // default AlignLeft for all other columns
}
}
case Qt::UserRole: {
switch (field) {

Check warning on line 1031 in src/library/basetracktablemodel.cpp

View workflow job for this annotation

GitHub Actions / coverage

this statement may fall through [-Wimplicit-fallthrough=]
case ColumnCache::COLUMN_LIBRARYTABLE_KEY: {
// return whether or not to display the color rectangle
return QVariant::fromValue(s_keyColorsEnabled);
}
default: {
DEBUG_ASSERT(!"unexpected field for UserRole");
break;
}
}
}
default:
DEBUG_ASSERT(!"unexpected role");
break;
Expand Down
4 changes: 4 additions & 0 deletions src/library/basetracktablemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ class BaseTrackTableModel : public QAbstractTableModel, public TrackModel {
static constexpr int kBpmColumnPrecisionMaximum = 10;
static void setBpmColumnPrecision(int precision);

static constexpr bool kKeyColorsEnabledDefault = true;
static void setKeyColorsEnabled(bool keyColorsEnabled);

static constexpr bool kApplyPlayedTrackColorDefault = true;
static void setApplyPlayedTrackColor(bool apply);

Expand Down Expand Up @@ -293,6 +296,7 @@ class BaseTrackTableModel : public QAbstractTableModel, public TrackModel {
mutable QModelIndex m_toolTipIndex;

static int s_bpmColumnPrecision;
static bool s_keyColorsEnabled;

static bool s_bApplyPlayedTrackColor;
};
62 changes: 62 additions & 0 deletions src/library/tabledelegates/keydelegate.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#include "library/tabledelegates/keydelegate.h"

#include <QPainter>
#include <QStyle>
#include <QTableView>

#include "moc_keydelegate.cpp"
#include "track/keyutils.h"

void KeyDelegate::paintItem(
QPainter* painter,
const QStyleOptionViewItem& option,
const QModelIndex& index) const {
paintItemBackground(painter, option, index);

mixxx::track::io::key::ChromaticKey key =
index.data().value<mixxx::track::io::key::ChromaticKey>();
if (key != mixxx::track::io::key::INVALID) {
// Display the key colors if enabled
bool keyColorsEnabled = index.data(Qt::UserRole).value<bool>();
if (keyColorsEnabled) {
const QColor keyColor = KeyUtils::keyToColor(key);
if (keyColor.isValid()) {
// Draw the colored rectangle next to the key label
painter->fillRect(
option.rect.x(),
option.rect.y() + 2,
4, // width
option.rect.height() - 4,
keyColor);
}
}

// Display the key text with the user-provided notation
int rectWidth = keyColorsEnabled ? 8 : 0; // 4px width + 4px right padding
const QString keyText = KeyUtils::keyToString(key);
QString elidedText = option.fontMetrics.elidedText(
keyText,
Qt::ElideLeft,
columnWidth(index) - rectWidth);

if (option.state & QStyle::State_Selected) {
// This uses selection-color from stylesheet for the text pen:
// #LibraryContainer QTableView {
// selection-color: #fff;
// }
painter->setPen(QPen(option.palette.highlightedText().color()));
}

painter->drawText(option.rect.x() + rectWidth,
option.rect.y(),
option.rect.width() - rectWidth,
option.rect.height(),
Qt::AlignVCenter,
elidedText);
}

// Draw a border if the key cell has focus
if (option.state & QStyle::State_HasFocus) {
drawBorder(painter, m_focusBorderColor, option.rect);
}
}
22 changes: 22 additions & 0 deletions src/library/tabledelegates/keydelegate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

#include <QObject>

#include "library/tabledelegates/tableitemdelegate.h"

class QModelIndex;
class QPainter;
class QStyleOptionViewItem;

class KeyDelegate : public TableItemDelegate {
Q_OBJECT
public:
explicit KeyDelegate(QTableView* pTableView)
: TableItemDelegate(pTableView) {
}

void paintItem(
QPainter* painter,
const QStyleOptionViewItem& option,
const QModelIndex& index) const override;
};
2 changes: 2 additions & 0 deletions src/preferences/colorpalettesettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class ColorPaletteSettings {
void removePalette(const QString& name);
QSet<QString> getColorPaletteNames() const;

DEFINE_PREFERENCE_HELPERS(KeyColorsEnabled, bool, "[Config]", "KeyColorsEnabled", true);

private:
UserSettingsPointer m_pConfig;
};
19 changes: 19 additions & 0 deletions src/preferences/dialog/dlgprefcolors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <QTableView>

#include "dialog/dlgreplacecuecolor.h"
#include "library/basetracktablemodel.h"
#include "library/library.h"
#include "library/trackcollection.h"
#include "moc_dlgprefcolors.cpp"
Expand All @@ -21,6 +22,7 @@ const ConfigKey kAutoHotcueColorsConfigKey("[Controls]", "auto_hotcue_colors");
const ConfigKey kAutoLoopColorsConfigKey("[Controls]", "auto_loop_colors");
const ConfigKey kHotcueDefaultColorIndexConfigKey("[Controls]", "HotcueDefaultColorIndex");
const ConfigKey kLoopDefaultColorIndexConfigKey("[Controls]", "LoopDefaultColorIndex");
const ConfigKey kKeyColorsEnabledConfigKey("[Config]", "KeyColorsEnabled");

} // anonymous namespace

Expand Down Expand Up @@ -66,6 +68,11 @@ DlgPrefColors::DlgPrefColors(
this,
&DlgPrefColors::slotReplaceCueColorClicked);

connect(checkboxKeyColorsEnabled,
&QCheckBox::stateChanged,
this,
&DlgPrefColors::slotKeyColorsEnabled);

setScrollSafeGuardForAllInputWidgets(this);

slotUpdate();
Expand All @@ -77,6 +84,9 @@ DlgPrefColors::~DlgPrefColors() {
void DlgPrefColors::slotUpdate() {
comboBoxHotcueColors->clear();
comboBoxTrackColors->clear();
checkboxKeyColorsEnabled->setChecked(
m_pConfig->getValue(kKeyColorsEnabledConfigKey,
BaseTrackTableModel::kKeyColorsEnabledDefault));
for (const auto& palette : std::as_const(mixxx::PredefinedColorPalettes::kPalettes)) {
QString paletteName = palette.getName();
QIcon paletteIcon = drawPalettePreview(paletteName);
Expand Down Expand Up @@ -161,6 +171,7 @@ void DlgPrefColors::slotResetToDefaults() {
mixxx::PredefinedColorPalettes::kDefaultTrackColorPalette.size());
comboBoxLoopDefaultColor->setCurrentIndex(
mixxx::PredefinedColorPalettes::kDefaultTrackColorPalette.size() - 1);
checkboxKeyColorsEnabled->setChecked(BaseTrackTableModel::kKeyColorsEnabledDefault);
}

// Apply and save any changes made in the dialog
Expand Down Expand Up @@ -215,6 +226,8 @@ void DlgPrefColors::slotApply() {
m_pConfig->setValue(kAutoLoopColorsConfigKey, true);
m_pConfig->setValue(kLoopDefaultColorIndexConfigKey, -1);
}

m_pConfig->setValue(kKeyColorsEnabledConfigKey, checkboxKeyColorsEnabled->checkState());
}

void DlgPrefColors::slotReplaceCueColorClicked() {
Expand Down Expand Up @@ -345,6 +358,12 @@ void DlgPrefColors::slotEditHotcuePaletteClicked() {
openColorPaletteEditor(hotcueColorPaletteName, true);
}

void DlgPrefColors::slotKeyColorsEnabled(int i) {
m_bKeyColorsEnabled = static_cast<bool>(i);
BaseTrackTableModel::setKeyColorsEnabled(m_bKeyColorsEnabled);
m_pConfig->setValue(kKeyColorsEnabledConfigKey, checkboxKeyColorsEnabled->checkState());
}

void DlgPrefColors::openColorPaletteEditor(
const QString& paletteName,
bool editHotcuePalette) {
Expand Down
2 changes: 2 additions & 0 deletions src/preferences/dialog/dlgprefcolors.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class DlgPrefColors : public DlgPreferencePage, public Ui::DlgPrefColorsDlg {
void slotReplaceCueColorClicked();
void slotEditTrackPaletteClicked();
void slotEditHotcuePaletteClicked();
void slotKeyColorsEnabled(int i);

private:
void openColorPaletteEditor(
Expand All @@ -54,6 +55,7 @@ class DlgPrefColors : public DlgPreferencePage, public Ui::DlgPrefColorsDlg {

const UserSettingsPointer m_pConfig;
ColorPaletteSettings m_colorPaletteSettings;
bool m_bKeyColorsEnabled;
// Pointer to color replace dialog
DlgReplaceCueColor* m_pReplaceCueColorDlg;
};
13 changes: 13 additions & 0 deletions src/preferences/dialog/dlgprefcolorsdlg.ui
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,18 @@
</item>

<item row="4" column="0" colspan="2">
<widget class="QCheckBox" name="checkboxKeyColorsEnabled">
<property name="toolTip">
<string>When key colors are enabled, Mixxx will display a color hint
associated with each key.</string>
</property>
<property name="text">
<string>Enable Key Colors</string>
</property>
</widget>
</item>

<item row="5" column="0" colspan="2">
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
Expand All @@ -124,6 +136,7 @@
<tabstop>pushButtonEditHotcuePalette</tabstop>
<tabstop>comboBoxHotcueDefaultColor</tabstop>
<tabstop>pushButtonReplaceCueColor</tabstop>
<tabstop>checkboxKeyColorsEnabled</tabstop>
</tabstops>
<resources/>
<connections/>
Expand Down
6 changes: 6 additions & 0 deletions src/skin/legacy/legacyskinparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1564,6 +1564,12 @@ QWidget* LegacySkinParser::parseLibrary(const QDomElement& node) {
BaseTrackTableModel::kBpmColumnPrecisionDefault);
BaseTrackTableModel::setBpmColumnPrecision(bpmColumnPrecision);

const auto keyColorsEnabled =
m_pConfig->getValue(
ConfigKey("[Config]", "KeyColorsEnabled"),
BaseTrackTableModel::kKeyColorsEnabledDefault);
BaseTrackTableModel::setKeyColorsEnabled(keyColorsEnabled);

const auto applyPlayedTrackColor =
m_pConfig->getValue(
mixxx::library::prefs::kApplyPlayedTrackColorConfigKey,
Expand Down
16 changes: 16 additions & 0 deletions src/track/keyutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include <QRegularExpression>
#include <QtDebug>

#include "util/color/predefinedcolorpalettes.h"
#include "util/color/rgbcolor.h"
#include "util/compatibility/qmutex.h"

using mixxx::track::io::key::ChromaticKey;
Expand Down Expand Up @@ -462,6 +464,20 @@ double KeyUtils::keyToNumericValue(ChromaticKey key) {
return key;
}

// static
QColor KeyUtils::keyToColor(ChromaticKey key) {
int openKeyNumber = keyToOpenKeyNumber(key);

if (openKeyNumber != 0) {
const auto& palette = mixxx::PredefinedColorPalettes::kDefaultKeyColorPalette;
DEBUG_ASSERT(openKeyNumber <= palette.size() && openKeyNumber >= 1);
const auto rgbColor = palette.at(openKeyNumber - 1); // Open Key numbers start from 1
return mixxx::RgbColor::toQColor(rgbColor);
} else {
return {}; // return invalid color
}
}

// static
QPair<ChromaticKey, double> KeyUtils::scaleKeyOctaves(ChromaticKey key, double octave_change) {
// Convert the octave_change from percentage of octave to the nearest
Expand Down
Loading

0 comments on commit 1b9ebc1

Please sign in to comment.