Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Enable Setting hotcue color via controlobject #1830

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
93c0451
added color column to properties dlg but UI and DB dont update
Oct 2, 2018
e0d73a0
fixed functionality broken by previous commit.
Oct 4, 2018
29df355
woverview waveformsmarks will now reflect their hotcue color
Oct 6, 2018
68efc42
markproperties.m_textColor is now the same color as the mark itself; …
Oct 6, 2018
92d381d
followed daschauers request to VERIFY_OR_DEBUG_ASSERT in a case
Oct 13, 2018
d8057bd
followed uklotzde change requests in widget/woverview
Oct 13, 2018
d4e0735
fixed redundant blank line (codefactor complained)
Oct 14, 2018
2c253ff
fixed inverted VERIFY_OR_DEBUG Statement
Oct 14, 2018
f57e682
Added R/W ControlObject for the HotcueColor
Oct 14, 2018
b0270ba
contrastLineColor of Markers now adapt to MarkerColor Brightness
Oct 18, 2018
9833f67
Removed Comment in cuecontrol.cpp
Oct 19, 2018
d52f107
the marker number color is now set by the skin again, not the m_color
Oct 19, 2018
c8c4150
moved brightness function to color.h; rendermark textColor adapts now
Oct 19, 2018
e58b361
Color is now settable via ComboBox in trackpropertie cuepoints table.
Oct 20, 2018
2372bdf
added more utility functions to util/color.h
Oct 20, 2018
3088c1e
minor changes for performance and codefactor
Oct 21, 2018
20ff8dc
Let skins override cue colors
ferranpujolcamins Dec 2, 2018
1b460cf
Add example, revert before merge.
ferranpujolcamins Dec 3, 2018
ca30b3b
Improve color methods efficiency
ferranpujolcamins Dec 28, 2018
b194d21
Rename Color::defaultRepresentation() to makeDefaultRepresentation()
ferranpujolcamins Dec 28, 2018
54798f3
Let skins override cue colors on overview
ferranpujolcamins Dec 28, 2018
3b324f8
Append "Cue" to the skin node name for waveform cue color overrides
ferranpujolcamins Dec 28, 2018
b6a7dd2
Revert "Add example, revert before merge."
ferranpujolcamins Dec 28, 2018
9afc8d4
Fix WOverview cue colors not being mapped after skin reload
ferranpujolcamins Dec 29, 2018
19480bd
Convert color lists to static const vars
ferranpujolcamins Dec 30, 2018
f950c25
Reduce the number of runtime copies of ColorsRepresentation
ferranpujolcamins Dec 30, 2018
f951a94
Move setupCueColorsRepresentation() to SkinContext
ferranpujolcamins Dec 30, 2018
c49961f
Added JS utility object for dealing with hotcue colors from MixxxControl
Jan 1, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions res/controllers/common-controller-scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -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+)\]$/ ;
Expand Down
24 changes: 24 additions & 0 deletions src/engine/cuecontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ void CueControl::trackCuesUpdated() {
} else {
// If the old hotcue is the same, then we only need to update
pControl->setPosition(pCue->getPosition());
pControl->setColor(pCue->getColor());
daschuer marked this conversation as resolved.
Show resolved Hide resolved
}
// Add the hotcue to the list of active hotcues
active_hotcues.insert(hotcue);
Expand Down Expand Up @@ -1018,6 +1019,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"));
Swiftb0y marked this conversation as resolved.
Show resolved Hide resolved
connect(m_hotcueColor, SIGNAL(valueChanged(double)),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a randomly CO and should not be changed directly by skin or controller scrips, right?
In this case you need to connect the valueChangeRequest() and discard changes there. Programmatically you can use setAndConfirm to bypass the request.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just mimicked how the already existing r/w COs work. I'm trying to plan ahead for integration into skin (where writing to the CO might be useful (maybe, I don't know how such a widget would even be implemented).
And what do you mean by "randomly CO"?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

randomly read only

this, SLOT(slotHotcueColorChanged(double)),
Qt::DirectConnection);

m_hotcueSet = new ControlPushButton(keyForControl(i, "set"));
connect(m_hotcueSet, SIGNAL(valueChanged(double)),
this, SLOT(slotHotcueSet(double)),
Expand Down Expand Up @@ -1057,6 +1066,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;
Expand Down Expand Up @@ -1099,6 +1109,11 @@ void HotcueControl::slotHotcuePositionChanged(double newPosition) {
emit(hotcuePositionChanged(this, newPosition));
}

void HotcueControl::slotHotcueColorChanged(double newColor) {
m_pCue->setColor(QColor(static_cast<QRgb>(newColor)));
emit(hotcueColorChanged(this, newColor));
}

double HotcueControl::getPosition() const {
return m_hotcuePosition->get();
}
Expand All @@ -1109,7 +1124,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<QRgb>(m_hotcueColor->get()));
}

void HotcueControl::setColor(QColor newColor) {
m_hotcueColor->set(static_cast<double>(newColor.rgb()));
}
void HotcueControl::resetCue() {
// clear pCue first because we have a null check for valid data else where
// in the code
Expand Down
5 changes: 5 additions & 0 deletions src/engine/cuecontrol.h
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -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);
Expand All @@ -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:
Expand All @@ -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;
Expand Down
40 changes: 36 additions & 4 deletions src/library/dlgtrackinfo.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <QDesktopServices>
#include <QtDebug>
#include <QStringBuilder>
#include <QComboBox>

#include "library/dlgtrackinfo.h"
#include "sources/soundsourceproxy.h"
Expand All @@ -11,9 +12,11 @@
#include "track/keyfactory.h"
#include "track/keyutils.h"
#include "util/duration.h"
#include "util/color.h"

const int kFilterLength = 80;
const int kMinBpm = 30;

// Maximum allowed interval between beats (calculated from kMinBpm).
const mixxx::Duration kMaxInterval = mixxx::Duration::fromMillis(1000.0 * (60.0 / kMinBpm));

Expand Down Expand Up @@ -332,12 +335,30 @@ void DlgTrackInfo::populateCues(TrackPointer pTrack) {
// Make the duration read only
durationItem->setFlags(Qt::NoItemFlags);


QComboBox* colorComboBox = new QComboBox();
const QList<QColor>& 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);
colorComboBox->setItemData(i, Color::chooseContrastColor(color), Qt::TextColorRole);

}
const QColor cueColor = pCue->getColor();
colorComboBox->setCurrentIndex(predefinedColors.contains(cueColor)
? predefinedColors.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(pCue->getLabel()));
// cueTable->setItem(row, 3, new QTableWidgetItem(cueColor.name().toUpper()));
cueTable->setCellWidget(row, 3, colorComboBox);
cueTable->setItem(row, 4, new QTableWidgetItem(pCue->getLabel()));
row += 1;
}
cueTable->setSortingEnabled(true);
Expand Down Expand Up @@ -381,10 +402,13 @@ 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);
QWidget* colorWidget = cueTable->cellWidget(row, 3);
QTableWidgetItem* labelItem = cueTable->item(row, 4);

if (!rowItem || !hotcueItem || !labelItem)
VERIFY_OR_DEBUG_ASSERT(rowItem && hotcueItem && colorWidget && labelItem) {
qWarning() << "unable to retrieve cells from cueTable row";
continue;
}

int oldRow = rowItem->data(Qt::DisplayRole).toInt();
CuePointer pCue(m_cueMap.value(oldRow, CuePointer()));
Expand All @@ -404,6 +428,15 @@ void DlgTrackInfo::saveTrack() {
pCue->setHotCue(-1);
}

auto colorComboBox = qobject_cast<QComboBox*>(colorWidget);
if (colorComboBox) {
QColor color = Color::predefinedColors.at(colorComboBox->currentIndex());
if (color.isValid()) {
pCue->setColor(color);
}
}
// do nothing for now.

QString label = labelItem->data(Qt::DisplayRole).toString();
pCue->setLabel(label);
}
Expand Down Expand Up @@ -444,7 +477,6 @@ void DlgTrackInfo::unloadTrack(bool save) {
}

void DlgTrackInfo::clear() {

disconnect(this, SLOT(updateTrackMetadata()));
m_pLoadedTrack.reset();

Expand Down
5 changes: 5 additions & 0 deletions src/library/dlgtrackinfo.ui
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,11 @@ Often results in higher quality beatgrids, but will not do well on tracks that h
<string>Hotcue</string>
</property>
</column>
<column>
<property name="text">
<string>Color</string>
</property>
</column>
<column>
<property name="text">
<string>Label</string>
Expand Down
13 changes: 13 additions & 0 deletions src/skin/skincontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include "preferences/usersettings.h"
#include "skin/pixmapsource.h"
#include "util/color.h"
#include "widget/wsingletoncontainer.h"
#include "widget/wpixmapstore.h"

Expand Down Expand Up @@ -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;

Expand Down
Loading