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

Color Picker Improvements #2557

Merged
merged 5 commits into from
Mar 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 11 additions & 0 deletions res/skins/default.qss
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ WColorPicker QPushButton[noColor="true"] {
background-color: black;
}

WColorPicker QPushButton[customColor="true"] {
/* Diagonal Rainbow Gradient */
background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1,
stop: 0 #FF0000,
stop: 0.2 #FFFF00,
stop: 0.4 #00FF00,
stop: 0.6 #00FFFF,
stop: 0.8 #0000FF,
stop: 1 #FF00FF)
}

WColorPicker QPushButton[checked="false"] {
qproperty-icon: none;
}
Expand Down
173 changes: 106 additions & 67 deletions src/widget/wcolorpicker.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "widget/wcolorpicker.h"

#include <QColorDialog>
#include <QMapIterator>
#include <QPushButton>
#include <QStyle>
Expand Down Expand Up @@ -35,10 +36,12 @@ inline int idealColumnCount(int numItems) {
return numColumns;
}

WColorPicker::WColorPicker(ColorOption colorOption, const ColorPalette& palette, QWidget* parent)
WColorPicker::WColorPicker(Options options, const ColorPalette& palette, QWidget* parent)
: QWidget(parent),
m_colorOption(colorOption),
m_palette(palette) {
m_options(options),
m_palette(palette),
m_pNoColorButton(nullptr),
m_pCustomColorButton(nullptr) {
QGridLayout* pLayout = new QGridLayout();
pLayout->setMargin(0);
pLayout->setContentsMargins(0, 0, 0, 0);
Expand All @@ -57,6 +60,11 @@ WColorPicker::WColorPicker(ColorOption colorOption, const ColorPalette& palette,
m_pStyle = QStyleFactory::create(QString("fusion"));
setLayout(pLayout);
addColorButtons();

connect(this,
&WColorPicker::colorPicked,
this,
&WColorPicker::slotColorPicked);
}

void WColorPicker::removeColorButtons() {
Expand All @@ -66,11 +74,21 @@ void WColorPicker::removeColorButtons() {
return;
}

if (m_pCustomColorButton) {
pLayout->removeWidget(m_pCustomColorButton);
delete m_pCustomColorButton;
}

while (!m_colorButtons.isEmpty()) {
QPushButton* pColorButton = m_colorButtons.takeLast();
pLayout->removeWidget(pColorButton);
delete pColorButton;
}

if (m_pNoColorButton) {
pLayout->removeWidget(m_pNoColorButton);
delete m_pNoColorButton;
}
}

void WColorPicker::addColorButtons() {
Expand All @@ -84,13 +102,16 @@ void WColorPicker::addColorButtons() {
int column = 0;

int numColors = m_palette.size();
if (m_colorOption == ColorOption::AllowNoColor) {
if (m_options.testFlag(Option::AllowNoColor)) {
numColors++;
}
if (m_options.testFlag(Option::AllowCustomColor)) {
numColors++;
}

int numColumns = idealColumnCount(numColors);
if (m_colorOption == ColorOption::AllowNoColor) {
addColorButton(std::nullopt, pLayout, row, column);
if (m_options.testFlag(Option::AllowNoColor)) {
addNoColorButton(pLayout, row, column);
column++;
}

Expand All @@ -102,97 +123,115 @@ void WColorPicker::addColorButtons() {
row++;
}
}
}

void WColorPicker::addColorButton(mixxx::RgbColor::optional_t color, QGridLayout* pLayout, int row, int column) {
parented_ptr<QPushButton> pColorButton = make_parented<QPushButton>("", this);
if (m_pStyle) {
pColorButton->setStyle(m_pStyle);
if (m_options.testFlag(Option::AllowCustomColor)) {
addCustomColorButton(pLayout, row, column);
column++;
}
}

if (color) {
// Set the background color of the button. This can't be overridden in skin stylesheets.
pColorButton->setStyleSheet(
QString("QPushButton { background-color: %1; }").arg(mixxx::RgbColor::toQString(color)));
} else {
pColorButton->setProperty("noColor", true);
void WColorPicker::addColorButton(mixxx::RgbColor color, QGridLayout* pLayout, int row, int column) {
parented_ptr<QPushButton> pButton = make_parented<QPushButton>("", this);
if (m_pStyle) {
pButton->setStyle(m_pStyle);
}
pColorButton->setToolTip(mixxx::RgbColor::toQString(color, tr("No Color")));

pColorButton->setCheckable(true);
m_colorButtons.append(pColorButton);
// Set the background color of the button. This can't be overridden in skin stylesheets.
pButton->setStyleSheet(
QString("QPushButton { background-color: %1; }").arg(mixxx::RgbColor::toQString(color)));
pButton->setToolTip(mixxx::RgbColor::toQString(color));
pButton->setCheckable(true);
m_colorButtons.append(pButton);

pLayout->addWidget(pColorButton, row, column);

connect(this,
&WColorPicker::colorPicked,
this,
&WColorPicker::slotColorPicked);
connect(pColorButton,
connect(pButton,
&QPushButton::clicked,
this,
[this, color]() {
emit colorPicked(color);
emit colorPicked(mixxx::RgbColor::optional(color));
});
pLayout->addWidget(pButton, row, column);
}

void WColorPicker::resetSelectedColor() {
// Unset currently selected color
int i = 0;
if (m_selectedColor) {
i = m_palette.indexOf(*m_selectedColor);
if (i == -1) {
return;
}
if (m_colorOption == ColorOption::AllowNoColor) {
i++;
void WColorPicker::addNoColorButton(QGridLayout* pLayout, int row, int column) {
QPushButton* pButton = m_pNoColorButton;
if (!pButton) {
pButton = make_parented<QPushButton>("", this);
if (m_pStyle) {
pButton->setStyle(m_pStyle);
}
} else if (m_colorOption != ColorOption::AllowNoColor) {
return;
}

DEBUG_ASSERT(i < m_colorButtons.size());

QPushButton* pButton = m_colorButtons.at(i);
VERIFY_OR_DEBUG_ASSERT(pButton != nullptr) {
return;
pButton->setProperty("noColor", true);
pButton->setToolTip(tr("No color"));
pButton->setCheckable(true);
connect(pButton,
&QPushButton::clicked,
this,
[this]() {
emit colorPicked(std::nullopt);
});
m_pNoColorButton = pButton;
}
pButton->setChecked(false);
// This is needed to re-apply skin styles (e.g. to show/hide a checkmark icon)
pButton->style()->unpolish(pButton);
pButton->style()->polish(pButton);
pLayout->addWidget(pButton, row, column);
}

void WColorPicker::setSelectedColor(mixxx::RgbColor::optional_t color) {
resetSelectedColor();
void WColorPicker::addCustomColorButton(QGridLayout* pLayout, int row, int column) {
QPushButton* pButton = m_pCustomColorButton;
if (!pButton) {
pButton = make_parented<QPushButton>("", this);
if (m_pStyle) {
pButton->setStyle(m_pStyle);
}

m_selectedColor = color;
pButton->setProperty("customColor", true);
pButton->setToolTip(tr("Custom color"));
pButton->setCheckable(true);
connect(pButton,
&QPushButton::clicked,
this,
[this]() {
QColor color = QColorDialog::getColor();
if (color.isValid()) {
emit colorPicked(mixxx::RgbColor::fromQColor(color));
}
});
m_pCustomColorButton = pButton;
}
pLayout->addWidget(pButton, row, column);
}

int i = 0;
void WColorPicker::setColorButtonChecked(mixxx::RgbColor::optional_t color, bool checked) {
// Unset currently selected color
QPushButton* pButton = nullptr;
if (color) {
i = m_palette.indexOf(*color);
if (i == -1) {
return;
int i = m_palette.indexOf(*color);
if (i != -1) {
pButton = m_colorButtons.at(i);
}
if (m_colorOption == ColorOption::AllowNoColor) {
i++;
}
} else if (m_colorOption != ColorOption::AllowNoColor) {
return;
} else if (m_options.testFlag(Option::AllowNoColor)) {
pButton = m_pNoColorButton;
}

DEBUG_ASSERT(i < m_colorButtons.size());

QPushButton* pButton = m_colorButtons.at(i);
VERIFY_OR_DEBUG_ASSERT(pButton != nullptr) {
if (!pButton) {
return;
}
pButton->setChecked(true);

pButton->setChecked(checked);
// This is needed to re-apply skin styles (e.g. to show/hide a checkmark icon)
pButton->style()->unpolish(pButton);
pButton->style()->polish(pButton);
}

void WColorPicker::resetSelectedColor() {
setColorButtonChecked(m_selectedColor, false);
}

void WColorPicker::setSelectedColor(mixxx::RgbColor::optional_t color) {
resetSelectedColor();

m_selectedColor = color;
setColorButtonChecked(m_selectedColor, true);
}

void WColorPicker::setColorPalette(const ColorPalette& palette) {
if (m_palette == palette) {
return;
Expand Down
21 changes: 15 additions & 6 deletions src/widget/wcolorpicker.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@
class WColorPicker : public QWidget {
Q_OBJECT
public:
enum class ColorOption {
DenyNoColor,
AllowNoColor,
enum class Option {
NoOptions = 0,
AllowNoColor = 1,
AllowCustomColor = 1 << 1,
};
Q_DECLARE_FLAGS(Options, Option);

explicit WColorPicker(ColorOption colorOption, const ColorPalette& palette, QWidget* parent = nullptr);
explicit WColorPicker(Options options, const ColorPalette& palette, QWidget* parent = nullptr);

void resetSelectedColor();
void setSelectedColor(mixxx::RgbColor::optional_t color);
Expand All @@ -30,12 +32,19 @@ class WColorPicker : public QWidget {
void slotColorPicked(mixxx::RgbColor::optional_t color);

private:
void setColorButtonChecked(mixxx::RgbColor::optional_t color, bool checked);
void addColorButtons();
void removeColorButtons();
void addColorButton(mixxx::RgbColor::optional_t color, QGridLayout* pLayout, int row, int column);
ColorOption m_colorOption;
void addColorButton(mixxx::RgbColor color, QGridLayout* pLayout, int row, int column);
void addNoColorButton(QGridLayout* pLayout, int row, int column);
void addCustomColorButton(QGridLayout* pLayout, int row, int column);
Options m_options;
mixxx::RgbColor::optional_t m_selectedColor;
ColorPalette m_palette;
QPushButton* m_pNoColorButton;
QPushButton* m_pCustomColorButton;
QList<QPushButton*> m_colorButtons;
QStyle* m_pStyle;
};

Q_DECLARE_OPERATORS_FOR_FLAGS(WColorPicker::Options);
4 changes: 2 additions & 2 deletions src/widget/wcolorpickeraction.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include "widget/wcolorpickeraction.h"

WColorPickerAction::WColorPickerAction(WColorPicker::ColorOption colorOption, const ColorPalette& palette, QWidget* parent)
WColorPickerAction::WColorPickerAction(WColorPicker::Options options, const ColorPalette& palette, QWidget* parent)
: QWidgetAction(parent),
m_pColorPicker(make_parented<WColorPicker>(colorOption, palette)) {
m_pColorPicker(make_parented<WColorPicker>(options, palette)) {
connect(m_pColorPicker.get(), &WColorPicker::colorPicked, this, &WColorPickerAction::colorPicked);

QHBoxLayout* pLayout = new QHBoxLayout();
Expand Down
2 changes: 1 addition & 1 deletion src/widget/wcolorpickeraction.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class WColorPickerAction : public QWidgetAction {
Q_OBJECT
public:
explicit WColorPickerAction(
WColorPicker::ColorOption colorOption,
WColorPicker::Options options,
const ColorPalette& palette,
QWidget* parent = nullptr);

Expand Down
2 changes: 1 addition & 1 deletion src/widget/wcuemenupopup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ WCueMenuPopup::WCueMenuPopup(UserSettingsPointer pConfig, QWidget* parent)
connect(m_pEditLabel, &QLineEdit::textEdited, this, &WCueMenuPopup::slotEditLabel);
connect(m_pEditLabel, &QLineEdit::returnPressed, this, &WCueMenuPopup::hide);

m_pColorPicker = new WColorPicker(WColorPicker::ColorOption::DenyNoColor, m_colorPaletteSettings.getHotcueColorPalette(), this);
m_pColorPicker = new WColorPicker(WColorPicker::Option::NoOptions, m_colorPaletteSettings.getHotcueColorPalette(), this);
m_pColorPicker->setObjectName("CueColorPicker");
connect(m_pColorPicker, &WColorPicker::colorPicked, this, &WCueMenuPopup::slotChangeCueColor);

Expand Down
2 changes: 1 addition & 1 deletion src/widget/wtracktableview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ void WTrackTableView::createActions() {
this, [this] { slotScaleBpm(Beats::THREEHALVES); });

ColorPaletteSettings colorPaletteSettings(m_pConfig);
m_pColorPickerAction = new WColorPickerAction(WColorPicker::ColorOption::AllowNoColor, colorPaletteSettings.getTrackColorPalette(), this);
m_pColorPickerAction = new WColorPickerAction(WColorPicker::Option::AllowNoColor, colorPaletteSettings.getTrackColorPalette(), this);
m_pColorPickerAction->setObjectName("TrackColorPickerAction");
connect(m_pColorPickerAction,
&WColorPickerAction::colorPicked,
Expand Down