From c8e47cdaca895a27d837eaba6ef0445a8705e0a0 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 17 Mar 2020 15:49:53 +0100 Subject: [PATCH 1/5] widget/wcolorpicker: Use QFlags for color picker options --- src/widget/wcolorpicker.cpp | 16 ++++++++-------- src/widget/wcolorpicker.h | 13 ++++++++----- src/widget/wcolorpickeraction.cpp | 4 ++-- src/widget/wcolorpickeraction.h | 2 +- src/widget/wcuemenupopup.cpp | 2 +- src/widget/wtracktableview.cpp | 2 +- 6 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/widget/wcolorpicker.cpp b/src/widget/wcolorpicker.cpp index fb1547206503..4485bf1afe0e 100644 --- a/src/widget/wcolorpicker.cpp +++ b/src/widget/wcolorpicker.cpp @@ -35,9 +35,9 @@ 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_options(options), m_palette(palette) { QGridLayout* pLayout = new QGridLayout(); pLayout->setMargin(0); @@ -84,12 +84,12 @@ void WColorPicker::addColorButtons() { int column = 0; int numColors = m_palette.size(); - if (m_colorOption == ColorOption::AllowNoColor) { + if (m_options.testFlag(Option::AllowNoColor)) { numColors++; } int numColumns = idealColumnCount(numColors); - if (m_colorOption == ColorOption::AllowNoColor) { + if (m_options.testFlag(Option::AllowNoColor)) { addColorButton(std::nullopt, pLayout, row, column); column++; } @@ -144,10 +144,10 @@ void WColorPicker::resetSelectedColor() { if (i == -1) { return; } - if (m_colorOption == ColorOption::AllowNoColor) { + if (m_options.testFlag(Option::AllowNoColor)) { i++; } - } else if (m_colorOption != ColorOption::AllowNoColor) { + } else if (!m_options.testFlag(Option::AllowNoColor)) { return; } @@ -174,10 +174,10 @@ void WColorPicker::setSelectedColor(mixxx::RgbColor::optional_t color) { if (i == -1) { return; } - if (m_colorOption == ColorOption::AllowNoColor) { + if (m_options.testFlag(Option::AllowNoColor)) { i++; } - } else if (m_colorOption != ColorOption::AllowNoColor) { + } else if (!m_options.testFlag(Option::AllowNoColor)) { return; } diff --git a/src/widget/wcolorpicker.h b/src/widget/wcolorpicker.h index d905e6124623..55a735a9b170 100644 --- a/src/widget/wcolorpicker.h +++ b/src/widget/wcolorpicker.h @@ -12,12 +12,13 @@ class WColorPicker : public QWidget { Q_OBJECT public: - enum class ColorOption { - DenyNoColor, - AllowNoColor, + enum class Option { + NoOptions = 0, + AllowNoColor = 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); @@ -33,9 +34,11 @@ class WColorPicker : public QWidget { void addColorButtons(); void removeColorButtons(); void addColorButton(mixxx::RgbColor::optional_t color, QGridLayout* pLayout, int row, int column); - ColorOption m_colorOption; + Options m_options; mixxx::RgbColor::optional_t m_selectedColor; ColorPalette m_palette; QList m_colorButtons; QStyle* m_pStyle; }; + +Q_DECLARE_OPERATORS_FOR_FLAGS(WColorPicker::Options); diff --git a/src/widget/wcolorpickeraction.cpp b/src/widget/wcolorpickeraction.cpp index 8837695ac616..c1d34d916c9c 100644 --- a/src/widget/wcolorpickeraction.cpp +++ b/src/widget/wcolorpickeraction.cpp @@ -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(colorOption, palette)) { + m_pColorPicker(make_parented(options, palette)) { connect(m_pColorPicker.get(), &WColorPicker::colorPicked, this, &WColorPickerAction::colorPicked); QHBoxLayout* pLayout = new QHBoxLayout(); diff --git a/src/widget/wcolorpickeraction.h b/src/widget/wcolorpickeraction.h index ce222ff49cc8..ca173d5a7d57 100644 --- a/src/widget/wcolorpickeraction.h +++ b/src/widget/wcolorpickeraction.h @@ -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); diff --git a/src/widget/wcuemenupopup.cpp b/src/widget/wcuemenupopup.cpp index ecf3f5cdb776..66bd49d3788e 100644 --- a/src/widget/wcuemenupopup.cpp +++ b/src/widget/wcuemenupopup.cpp @@ -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); diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 3fc47d469c2a..b3e581d60660 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -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, From ef7fde8925261d692518b2d9d75e69e651b66171 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 17 Mar 2020 16:01:32 +0100 Subject: [PATCH 2/5] widget/wcolorpicker: Connect colorPicked only once --- src/widget/wcolorpicker.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/widget/wcolorpicker.cpp b/src/widget/wcolorpicker.cpp index 4485bf1afe0e..b7a53f59f3f2 100644 --- a/src/widget/wcolorpicker.cpp +++ b/src/widget/wcolorpicker.cpp @@ -57,6 +57,11 @@ WColorPicker::WColorPicker(Options options, const ColorPalette& palette, QWidget m_pStyle = QStyleFactory::create(QString("fusion")); setLayout(pLayout); addColorButtons(); + + connect(this, + &WColorPicker::colorPicked, + this, + &WColorPicker::slotColorPicked); } void WColorPicker::removeColorButtons() { @@ -124,10 +129,6 @@ void WColorPicker::addColorButton(mixxx::RgbColor::optional_t color, QGridLayout pLayout->addWidget(pColorButton, row, column); - connect(this, - &WColorPicker::colorPicked, - this, - &WColorPicker::slotColorPicked); connect(pColorButton, &QPushButton::clicked, this, From e779252dee0f3ec43a592ab86f9c47dee32503d7 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 17 Mar 2020 16:34:55 +0100 Subject: [PATCH 3/5] widget/wcolorpicker: Do not store no color button in m_colorButtons --- src/widget/wcolorpicker.cpp | 118 ++++++++++++++++++------------------ src/widget/wcolorpicker.h | 5 +- 2 files changed, 62 insertions(+), 61 deletions(-) diff --git a/src/widget/wcolorpicker.cpp b/src/widget/wcolorpicker.cpp index b7a53f59f3f2..c65c876bd33b 100644 --- a/src/widget/wcolorpicker.cpp +++ b/src/widget/wcolorpicker.cpp @@ -38,7 +38,8 @@ inline int idealColumnCount(int numItems) { WColorPicker::WColorPicker(Options options, const ColorPalette& palette, QWidget* parent) : QWidget(parent), m_options(options), - m_palette(palette) { + m_palette(palette), + m_pNoColorButton(nullptr) { QGridLayout* pLayout = new QGridLayout(); pLayout->setMargin(0); pLayout->setContentsMargins(0, 0, 0, 0); @@ -76,6 +77,11 @@ void WColorPicker::removeColorButtons() { pLayout->removeWidget(pColorButton); delete pColorButton; } + + if (m_pNoColorButton) { + pLayout->removeWidget(m_pNoColorButton); + delete m_pNoColorButton; + } } void WColorPicker::addColorButtons() { @@ -95,7 +101,7 @@ void WColorPicker::addColorButtons() { int numColumns = idealColumnCount(numColors); if (m_options.testFlag(Option::AllowNoColor)) { - addColorButton(std::nullopt, pLayout, row, column); + addNoColorButton(pLayout, row, column); column++; } @@ -109,89 +115,81 @@ void WColorPicker::addColorButtons() { } } -void WColorPicker::addColorButton(mixxx::RgbColor::optional_t color, QGridLayout* pLayout, int row, int column) { - parented_ptr pColorButton = make_parented("", this); +void WColorPicker::addColorButton(mixxx::RgbColor color, QGridLayout* pLayout, int row, int column) { + parented_ptr pButton = make_parented("", this); if (m_pStyle) { - pColorButton->setStyle(m_pStyle); - } - - 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); + 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(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_options.testFlag(Option::AllowNoColor)) { - i++; +void WColorPicker::addNoColorButton(QGridLayout* pLayout, int row, int column) { + QPushButton* pButton = m_pNoColorButton; + if (!pButton) { + pButton = make_parented("", this); + if (m_pStyle) { + pButton->setStyle(m_pStyle); } - } else if (!m_options.testFlag(Option::AllowNoColor)) { - 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; } + pLayout->addWidget(pButton, row, column); +} - DEBUG_ASSERT(i < m_colorButtons.size()); +void WColorPicker::setColorButtonChecked(mixxx::RgbColor::optional_t color, bool checked) { + // Unset currently selected color + QPushButton* pButton = nullptr; + if (color) { + int i = m_palette.indexOf(*color); + if (i != -1) { + pButton = m_colorButtons.at(i); + } + } else if (m_options.testFlag(Option::AllowNoColor)) { + pButton = m_pNoColorButton; + } - QPushButton* pButton = m_colorButtons.at(i); - VERIFY_OR_DEBUG_ASSERT(pButton != nullptr) { + if (!pButton) { return; } - pButton->setChecked(false); + + 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; - - int i = 0; - if (color) { - i = m_palette.indexOf(*color); - if (i == -1) { - return; - } - if (m_options.testFlag(Option::AllowNoColor)) { - i++; - } - } else if (!m_options.testFlag(Option::AllowNoColor)) { - return; - } - - DEBUG_ASSERT(i < m_colorButtons.size()); - - QPushButton* pButton = m_colorButtons.at(i); - VERIFY_OR_DEBUG_ASSERT(pButton != nullptr) { - return; - } - pButton->setChecked(true); - // This is needed to re-apply skin styles (e.g. to show/hide a checkmark icon) - pButton->style()->unpolish(pButton); - pButton->style()->polish(pButton); + setColorButtonChecked(m_selectedColor, true); } void WColorPicker::setColorPalette(const ColorPalette& palette) { diff --git a/src/widget/wcolorpicker.h b/src/widget/wcolorpicker.h index 55a735a9b170..8b358728a659 100644 --- a/src/widget/wcolorpicker.h +++ b/src/widget/wcolorpicker.h @@ -31,12 +31,15 @@ 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); + void addColorButton(mixxx::RgbColor color, QGridLayout* pLayout, int row, int column); + void addNoColorButton(QGridLayout* pLayout, int row, int column); Options m_options; mixxx::RgbColor::optional_t m_selectedColor; ColorPalette m_palette; + QPushButton* m_pNoColorButton; QList m_colorButtons; QStyle* m_pStyle; }; From 7403dffdcd63cc5c9ba90d7292742afc6fec41a3 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 17 Mar 2020 16:46:57 +0100 Subject: [PATCH 4/5] widget/wcolorpicker: Add support for custom colors --- src/widget/wcolorpicker.cpp | 42 ++++++++++++++++++++++++++++++++++++- src/widget/wcolorpicker.h | 3 +++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/widget/wcolorpicker.cpp b/src/widget/wcolorpicker.cpp index c65c876bd33b..0c5fde4a764c 100644 --- a/src/widget/wcolorpicker.cpp +++ b/src/widget/wcolorpicker.cpp @@ -1,5 +1,6 @@ #include "widget/wcolorpicker.h" +#include #include #include #include @@ -39,7 +40,8 @@ WColorPicker::WColorPicker(Options options, const ColorPalette& palette, QWidget : QWidget(parent), m_options(options), m_palette(palette), - m_pNoColorButton(nullptr) { + m_pNoColorButton(nullptr), + m_pCustomColorButton(nullptr) { QGridLayout* pLayout = new QGridLayout(); pLayout->setMargin(0); pLayout->setContentsMargins(0, 0, 0, 0); @@ -72,6 +74,11 @@ 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); @@ -98,6 +105,9 @@ void WColorPicker::addColorButtons() { if (m_options.testFlag(Option::AllowNoColor)) { numColors++; } + if (m_options.testFlag(Option::AllowCustomColor)) { + numColors++; + } int numColumns = idealColumnCount(numColors); if (m_options.testFlag(Option::AllowNoColor)) { @@ -113,6 +123,11 @@ void WColorPicker::addColorButtons() { row++; } } + + if (m_options.testFlag(Option::AllowCustomColor)) { + addCustomColorButton(pLayout, row, column); + column++; + } } void WColorPicker::addColorButton(mixxx::RgbColor color, QGridLayout* pLayout, int row, int column) { @@ -159,6 +174,31 @@ void WColorPicker::addNoColorButton(QGridLayout* pLayout, int row, int column) { pLayout->addWidget(pButton, row, column); } +void WColorPicker::addCustomColorButton(QGridLayout* pLayout, int row, int column) { + QPushButton* pButton = m_pCustomColorButton; + if (!pButton) { + pButton = make_parented("", this); + if (m_pStyle) { + pButton->setStyle(m_pStyle); + } + + 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); +} + void WColorPicker::setColorButtonChecked(mixxx::RgbColor::optional_t color, bool checked) { // Unset currently selected color QPushButton* pButton = nullptr; diff --git a/src/widget/wcolorpicker.h b/src/widget/wcolorpicker.h index 8b358728a659..679f235b5603 100644 --- a/src/widget/wcolorpicker.h +++ b/src/widget/wcolorpicker.h @@ -15,6 +15,7 @@ class WColorPicker : public QWidget { enum class Option { NoOptions = 0, AllowNoColor = 1, + AllowCustomColor = 1 << 1, }; Q_DECLARE_FLAGS(Options, Option); @@ -36,10 +37,12 @@ class WColorPicker : public QWidget { void removeColorButtons(); 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 m_colorButtons; QStyle* m_pStyle; }; From bc25e459a127d9a5e15aec1fd5fced0b6ef326a5 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 17 Mar 2020 17:10:36 +0100 Subject: [PATCH 5/5] res/skins/default.qss: Add default style for custom color button --- res/skins/default.qss | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/res/skins/default.qss b/res/skins/default.qss index 5ef73f9cccb8..e9a35ed66305 100644 --- a/res/skins/default.qss +++ b/res/skins/default.qss @@ -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; }