diff --git a/flameshot.example.ini b/flameshot.example.ini index 65f1200fcc..f64155ea45 100644 --- a/flameshot.example.ini +++ b/flameshot.example.ini @@ -7,7 +7,7 @@ ;; The colors are arranged counter-clockwise with the first being set to the right of the cursor ;; Colors are any valid hex code or W3C color name ;; "picker" adds a custom color picker -;userColors=#800000, #ff0000, #ffff00, #00ff00, #008000, #00ffff, #0000ff, #ff00ff, #800080, picker +;userColors=picker, #800000, #ff0000, #ffff00, #00ff00, #008000, #00ffff, #0000ff, #ff00ff, #800080 ; ;; Image Save Path ;savePath=/tmp @@ -84,6 +84,9 @@ ;; Upload to imgur without confirmation (bool) ;uploadWithoutConfirmation=false ; +;; Use larger color palette as the default one +; predefinedColorPaletteLarge=false +; ;; Shortcut Settings for all tools ;[Shortcuts] ;TYPE_ARROW=A diff --git a/src/config/CMakeLists.txt b/src/config/CMakeLists.txt index ba9b4c8add..f0ce1b635b 100644 --- a/src/config/CMakeLists.txt +++ b/src/config/CMakeLists.txt @@ -11,6 +11,7 @@ target_sources( strftimechooserwidget.cpp styleoverride.cpp uicoloreditor.cpp + colorpickereditor.cpp visualseditor.cpp shortcutswidget.cpp setshortcutwidget.cpp diff --git a/src/config/colorpickereditor.cpp b/src/config/colorpickereditor.cpp new file mode 100644 index 0000000000..52e7e8fe3e --- /dev/null +++ b/src/config/colorpickereditor.cpp @@ -0,0 +1,166 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileCopyrightText: 2022 Dearsh Oberoi + +#include "colorpickereditor.h" +#include "src/utils/confighandler.h" +#include "src/utils/globalvalues.h" +#include "src/widgets/colorpickerwidget.h" +#include "src/widgets/colorspinbox.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +ColorPickerEditor::ColorPickerEditor(QWidget* parent) + : QWidget(parent) + , m_selectedIndex(1) +{ + ConfigHandler config; + m_color = config.drawColor(); + + m_gLayout = new QGridLayout(this); + + m_colorpicker = new ColorPickerWidget(this); + m_gLayout->addWidget(m_colorpicker, 0, 0); + + m_colorWheel = new color_widgets::ColorWheel(this); + m_colorWheel->setColor(m_color); + const int size = GlobalValues::buttonBaseSize() * 3.5; + m_colorWheel->setMinimumSize(size, size); + m_gLayout->addWidget(m_colorWheel, 1, 0); + + QVBoxLayout* m_vLocalLayout1 = new QVBoxLayout(); + m_vLocalLayout1->addStretch(); + + m_colorSpinboxLabel = new QLabel(tr("Select Preset:"), this); + m_vLocalLayout1->addWidget(m_colorSpinboxLabel); + + m_colorSpinbox = new ColorSpinBox(this); + connect(m_colorSpinbox, + QOverload::of(&QSpinBox::valueChanged), + m_colorpicker, + [=](int val) { + m_selectedIndex = val; + m_colorpicker->updateSelection(val); + }); + m_colorSpinbox->setToolTip(tr("Select preset using the spinbox")); + m_vLocalLayout1->addWidget(m_colorSpinbox); + + m_deletePresetButton = new QPushButton(tr("Delete"), this); + m_deletePresetButton->setToolTip( + tr("Press button to delete the selected preset")); + connect(m_deletePresetButton, + &QPushButton::pressed, + this, + &ColorPickerEditor::onDeletePreset); + m_vLocalLayout1->addWidget(m_deletePresetButton); + + m_vLocalLayout1->addStretch(); + + m_gLayout->addLayout(m_vLocalLayout1, 0, 1); + + QVBoxLayout* m_vLocalLayout2 = new QVBoxLayout(); + m_vLocalLayout2->addStretch(); + + m_addPresetLabel = new QLabel(tr("Add Preset:"), this); + m_vLocalLayout2->addWidget(m_addPresetLabel); + + m_colorInput = new QLineEdit(this); + m_colorInput->setText(m_color.name(QColor::HexRgb)); + m_colorInput->setToolTip( + tr("Enter color manually or select it using the color-wheel")); + connect(m_colorWheel, + &color_widgets::ColorWheel::colorSelected, + this, + [=](QColor c) { + m_color = c; + m_colorInput->setText(m_color.name(QColor::HexRgb)); + }); + m_vLocalLayout2->addWidget(m_colorInput); + + m_addPresetButton = new QPushButton(tr("Add"), this); + m_addPresetButton->setToolTip(tr("Press button to add preset")); + connect(m_addPresetButton, + &QPushButton::pressed, + this, + &ColorPickerEditor::onAddPreset); + m_vLocalLayout2->addWidget(m_addPresetButton); + + m_vLocalLayout2->addStretch(); + + m_gLayout->addLayout(m_vLocalLayout2, 1, 1); +} + +void ColorPickerEditor::addPreset() +{ + ConfigHandler config; + QVector colors = config.userColors(); + + if (colors.contains(m_color)) + return; + + colors << m_color; + + const int maxPresetsAllowed = 17; + + if (colors.size() > maxPresetsAllowed) { + QMessageBox::critical( + this, + tr("Error"), + tr("Unable to add preset. Maximum limit reached.")); + return; + } + + config.setUserColors(colors); +} + +void ColorPickerEditor::deletePreset() +{ + ConfigHandler config; + QVector colors = config.userColors(); + + colors.remove(m_selectedIndex); + + const int minPresetsAllowed = 3; + + if (colors.size() < minPresetsAllowed) { + QMessageBox::critical( + this, + tr("Error"), + tr("Unable to remove preset. Minimum limit reached.")); + return; + } + + config.setUserColors(colors); +} + +void ColorPickerEditor::onAddPreset() +{ + if (QColor::isValidColor(m_colorInput->text())) { + m_color = QColor(m_colorInput->text()); + m_colorInput->setText(m_color.name(QColor::HexRgb)); + } else { + m_colorInput->setText(m_color.name(QColor::HexRgb)); + return; + } + + addPreset(); + m_colorSpinbox->setValue(1); + m_colorpicker->updateWidget(); + m_colorSpinbox->updateWidget(); +} + +void ColorPickerEditor::onDeletePreset() +{ + deletePreset(); + m_colorSpinbox->setValue(1); + m_colorpicker->updateWidget(); + m_colorSpinbox->updateWidget(); +} \ No newline at end of file diff --git a/src/config/colorpickereditor.h b/src/config/colorpickereditor.h new file mode 100644 index 0000000000..b42a35b15d --- /dev/null +++ b/src/config/colorpickereditor.h @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileCopyrightText: 2022 Dearsh Oberoi + +#pragma once + +#include "QtColorWidgets/color_wheel.hpp" +#include + +class ColorSpinBox; +class ColorPickerWidget; +class QLabel; +class QPushButton; +class QLineEdit; +class QColor; +class QGridLayout; + +class ColorPickerEditor : public QWidget +{ + Q_OBJECT +public: + explicit ColorPickerEditor(QWidget* parent = nullptr); + +private slots: + void onAddPreset(); + void onDeletePreset(); + +private: + void addPreset(); + void deletePreset(); + + ColorPickerWidget* m_colorpicker; + color_widgets::ColorWheel* m_colorWheel; + + QLabel* m_colorSpinboxLabel; + ColorSpinBox* m_colorSpinbox; + QPushButton* m_deletePresetButton; + + QLineEdit* m_colorInput; + QLabel* m_addPresetLabel; + QPushButton* m_addPresetButton; + + QColor m_color; + int m_selectedIndex; + + QGridLayout* m_gLayout; +}; diff --git a/src/config/generalconf.cpp b/src/config/generalconf.cpp index aa58c8c027..df26bb5530 100644 --- a/src/config/generalconf.cpp +++ b/src/config/generalconf.cpp @@ -84,6 +84,8 @@ void GeneralConf::_updateComponents(bool allowEmptySavePath) m_autoCloseIdleDaemon->setChecked(config.autoCloseIdleDaemon()); #endif + m_predefinedColorPaletteLarge->setChecked( + config.predefinedColorPaletteLarge()); m_showStartupLaunchMessage->setChecked(config.showStartupLaunchMessage()); m_screenshotPathFixedCheck->setChecked(config.savePathFixed()); m_uploadHistoryMax->setValue(config.uploadHistoryMax()); diff --git a/src/config/uicoloreditor.cpp b/src/config/uicoloreditor.cpp index fc76a1182d..44a003b167 100644 --- a/src/config/uicoloreditor.cpp +++ b/src/config/uicoloreditor.cpp @@ -13,9 +13,8 @@ #include UIcolorEditor::UIcolorEditor(QWidget* parent) - : QGroupBox(parent) + : QWidget(parent) { - setTitle(tr("UI Color Editor")); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); m_hLayout = new QHBoxLayout; m_vLayout = new QVBoxLayout; diff --git a/src/config/uicoloreditor.h b/src/config/uicoloreditor.h index 118b7a2d58..58a172b624 100644 --- a/src/config/uicoloreditor.h +++ b/src/config/uicoloreditor.h @@ -12,7 +12,7 @@ class QHBoxLayout; class CaptureToolButton; class ClickableLabel; -class UIcolorEditor : public QGroupBox +class UIcolorEditor : public QWidget { Q_OBJECT public: diff --git a/src/config/visualseditor.cpp b/src/config/visualseditor.cpp index 2c5d20a8d9..e0719163fd 100644 --- a/src/config/visualseditor.cpp +++ b/src/config/visualseditor.cpp @@ -3,6 +3,7 @@ #include "visualseditor.h" #include "src/config/buttonlistview.h" +#include "src/config/colorpickereditor.h" #include "src/config/extendedslider.h" #include "src/config/uicoloreditor.h" #include "src/utils/confighandler.h" @@ -56,8 +57,22 @@ void VisualsEditor::initOpacitySlider() void VisualsEditor::initWidgets() { + m_tabWidget = new QTabWidget(); + m_layout->addWidget(m_tabWidget); + m_colorEditor = new UIcolorEditor(); - m_layout->addWidget(m_colorEditor); + m_colorEditorTab = new QWidget(); + QVBoxLayout* colorEditorLayout = new QVBoxLayout(m_colorEditorTab); + m_colorEditorTab->setLayout(colorEditorLayout); + colorEditorLayout->addWidget(m_colorEditor); + m_tabWidget->addTab(m_colorEditorTab, tr("UI Color Editor")); + + m_colorpickerEditor = new ColorPickerEditor(); + m_colorpickerEditorTab = new QWidget(); + QVBoxLayout* colorpickerEditorLayout = + new QVBoxLayout(m_colorpickerEditorTab); + colorpickerEditorLayout->addWidget(m_colorpickerEditor); + m_tabWidget->addTab(m_colorpickerEditorTab, tr("Colorpicker Editor")); initOpacitySlider(); diff --git a/src/config/visualseditor.h b/src/config/visualseditor.h index 08653114f2..7d38661895 100644 --- a/src/config/visualseditor.h +++ b/src/config/visualseditor.h @@ -3,12 +3,14 @@ #pragma once +#include #include class ExtendedSlider; class QVBoxLayout; class ButtonListView; class UIcolorEditor; +class ColorPickerEditor; class VisualsEditor : public QWidget { @@ -21,8 +23,16 @@ public slots: private: QVBoxLayout* m_layout; - ButtonListView* m_buttonList; + + QTabWidget* m_tabWidget; + UIcolorEditor* m_colorEditor; + QWidget* m_colorEditorTab; + + ColorPickerEditor* m_colorpickerEditor; + QWidget* m_colorpickerEditorTab; + + ButtonListView* m_buttonList; ExtendedSlider* m_opacitySlider; void initWidgets(); diff --git a/src/utils/confighandler.cpp b/src/utils/confighandler.cpp index 42f531022b..cbd97570d7 100644 --- a/src/utils/confighandler.cpp +++ b/src/utils/confighandler.cpp @@ -112,7 +112,7 @@ static QMap> OPTION("drawThickness" ,LowerBoundedInt (1 , 3 )), OPTION("drawFontSize" ,LowerBoundedInt (1 , 8 )), OPTION("drawColor" ,Color ( Qt::red )), - OPTION("userColors" ,UserColors ( )), + OPTION("userColors" ,UserColors(3, 17 )), OPTION("ignoreUpdateToVersion" ,String ( "" )), OPTION("keepOpenAppLauncher" ,Bool ( false )), OPTION("fontFamily" ,String ( "" )), diff --git a/src/utils/valuehandler.cpp b/src/utils/valuehandler.cpp index bad2c51a4d..dad43a5a6c 100644 --- a/src/utils/valuehandler.cpp +++ b/src/utils/valuehandler.cpp @@ -1,5 +1,6 @@ #include "valuehandler.h" #include "capturetool.h" +#include "colorpickerwidget.h" #include "confighandler.h" #include "screengrabber.h" #include @@ -378,10 +379,15 @@ bool ButtonList::normalizeButtons(QList& buttons) // USER COLORS +UserColors::UserColors(int min, int max) + : m_min(min) + , m_max(max) +{} + bool UserColors::check(const QVariant& val) { if (!val.isValid()) { - return true; + return false; } if (!val.canConvert(QVariant::StringList)) { return false; @@ -391,7 +397,10 @@ bool UserColors::check(const QVariant& val) return false; } } - return true; + + int sz = val.toStringList().size(); + + return sz >= m_min && sz <= m_max; } QVariant UserColors::process(const QVariant& val) @@ -418,40 +427,37 @@ QVariant UserColors::process(const QVariant& val) QVariant UserColors::fallback() { if (ConfigHandler().predefinedColorPaletteLarge()) { - return QVariant::fromValue(QVector{ Qt::white, - Qt::red, - Qt::green, - Qt::blue, - Qt::black, - Qt::darkRed, - Qt::darkGreen, - Qt::darkBlue, - Qt::darkGray, - Qt::cyan, - Qt::magenta, - Qt::yellow, - Qt::lightGray, - Qt::darkCyan, - Qt::darkMagenta, - Qt::darkYellow, - QColor() }); + return QVariant::fromValue( + ColorPickerWidget::getDefaultLargeColorPalette()); } else { - return QVariant::fromValue(QVector{ Qt::darkRed, - Qt::red, - Qt::yellow, - Qt::green, - Qt::darkGreen, - Qt::cyan, - Qt::blue, - Qt::magenta, - Qt::darkMagenta, - QColor() }); + return QVariant::fromValue( + ColorPickerWidget::getDefaultSmallColorPalette()); } } QString UserColors::expected() { - return QStringLiteral("list of colors separated by comma"); + return QStringLiteral( + "list of colors(min %1 and max %2) separated by comma") + .arg(m_min - 1) + .arg(m_max - 1); +} + +QVariant UserColors::representation(const QVariant& val) +{ + QVector colors = val.value>(); + + QStringList strColors; + + for (const auto& col : colors) { + if (col.isValid()) { + strColors.append(col.name(QColor::HexRgb)); + } else { + strColors.append(QStringLiteral("picker")); + } + } + + return QVariant::fromValue(strColors); } // SET SAVE FILE AS EXTENSION diff --git a/src/utils/valuehandler.h b/src/utils/valuehandler.h index 3e9c53704d..2a240f6468 100644 --- a/src/utils/valuehandler.h +++ b/src/utils/valuehandler.h @@ -1,6 +1,7 @@ #pragma once #include "src/widgets/capture/capturetoolbutton.h" +#include "src/widgets/colorpickerwidget.h" #include #include @@ -193,10 +194,16 @@ class ButtonList : public ValueHandler class UserColors : public ValueHandler { +public: + UserColors(int min, int max); bool check(const QVariant& val) override; QVariant process(const QVariant& val) override; QVariant fallback() override; QString expected() override; + QVariant representation(const QVariant& val) override; + +private: + int m_min, m_max; }; class SaveFileExtension : public ValueHandler diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt index f866dc2183..3a800002e9 100644 --- a/src/widgets/CMakeLists.txt +++ b/src/widgets/CMakeLists.txt @@ -17,6 +17,8 @@ target_sources( orientablepushbutton.h historywidget.h updatenotificationwidget.h + colorpickerwidget.h + colorspinbox.h imguploaddialog.h capture/capturetoolobjects.h ) @@ -32,6 +34,8 @@ target_sources( orientablepushbutton.cpp historywidget.cpp updatenotificationwidget.cpp + colorpickerwidget.cpp + colorspinbox.cpp imguploaddialog.cpp capture/capturetoolobjects.cpp ) diff --git a/src/widgets/capture/colorpicker.cpp b/src/widgets/capture/colorpicker.cpp index 43de9bf81c..102dfed7b8 100644 --- a/src/widgets/capture/colorpicker.cpp +++ b/src/widgets/capture/colorpicker.cpp @@ -8,16 +8,11 @@ #include ColorPicker::ColorPicker(QWidget* parent) - : QWidget(parent) - , m_selectedIndex(0) - , m_lastIndex(0) + : ColorPickerWidget(parent) { - ConfigHandler config; - m_colorList = config.userColors(); - m_colorAreaSize = GlobalValues::buttonBaseSize() * 0.6; setMouseTracking(true); - // save the color values in member variables for faster access - m_uiColor = config.uiColor(); + + ConfigHandler config; QColor drawColor = config.drawColor(); for (int i = 0; i < m_colorList.size(); ++i) { if (m_colorList.at(i) == drawColor) { @@ -26,90 +21,6 @@ ColorPicker::ColorPicker(QWidget* parent) break; } } - // extraSize represents the extra space needed for the highlight of the - // selected color. - const int extraSize = 6; - double radius = (m_colorList.size() * m_colorAreaSize / 1.3) / 3.141592; - resize(radius * 2 + m_colorAreaSize + extraSize, - radius * 2 + m_colorAreaSize + extraSize); - double degree = 360 / (m_colorList.size()); - double degreeAcum = degree; - // this line is the radius of the circle which will be rotated to add - // the color components. - QLineF baseLine = - QLineF(QPoint(radius + extraSize / 2, radius + extraSize / 2), - QPoint(radius * 2, radius)); - - for (int i = 0; i < m_colorList.size(); ++i) { - m_colorAreaList.append(QRect( - baseLine.x2(), baseLine.y2(), m_colorAreaSize, m_colorAreaSize)); - baseLine.setAngle(degreeAcum); - degreeAcum += degree; - } -} - -void ColorPicker::paintEvent(QPaintEvent* e) -{ - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing); - painter.setPen(QColor(Qt::black)); - - for (int i = 0; i < m_colorAreaList.size(); ++i) { - if (e->region().contains(m_colorAreaList.at(i))) { - painter.setClipRegion(e->region()); - repaint(i, painter); - } - } -} - -void ColorPicker::repaint(int i, QPainter& painter) -{ - // draw the highlight when we have to draw the selected color - if (i == m_selectedIndex) { - QColor c = QColor(m_uiColor); - c.setAlpha(155); - painter.setBrush(c); - c.setAlpha(100); - painter.setPen(c); - QRect highlight = m_colorAreaList.at(i); - highlight.moveTo(highlight.x() - 3, highlight.y() - 3); - highlight.setHeight(highlight.height() + 6); - highlight.setWidth(highlight.width() + 6); - painter.drawRoundedRect(highlight, 100, 100); - painter.setPen(QColor(Qt::black)); - } - - // draw available colors - if (m_colorList.at(i).isValid()) { - // draw preset color - painter.setBrush(QColor(m_colorList.at(i))); - painter.drawRoundedRect(m_colorAreaList.at(i), 100, 100); - } else { - // draw rainbow (part) for custom color - QRect lastRect = m_colorAreaList.at(i); - int nStep = 1; - int nSteps = lastRect.height() / nStep; - // 0.02 - start rainbow color, 0.33 - end rainbow color from range: - // 0.0 - 1.0 - float h = 0.02; - for (int radius = nSteps; radius > 0; radius -= nStep * 2) { - // calculate color - float fHStep = (0.33 - h) / (nSteps / nStep / 2); - QColor color = QColor::fromHslF(h, 0.95, 0.5); - - // set color and draw circle - painter.setPen(color); - painter.setBrush(color); - painter.drawRoundedRect(lastRect, 100, 100); - - // set next color, circle geometry - h += fHStep; - lastRect.setX(lastRect.x() + nStep); - lastRect.setY(lastRect.y() + nStep); - lastRect.setHeight(lastRect.height() - nStep); - lastRect.setWidth(lastRect.width() - nStep); - } - } } void ColorPicker::mouseMoveEvent(QMouseEvent* e) diff --git a/src/widgets/capture/colorpicker.h b/src/widgets/capture/colorpicker.h index 44778b5e81..979bdc22ff 100644 --- a/src/widgets/capture/colorpicker.h +++ b/src/widgets/capture/colorpicker.h @@ -3,9 +3,9 @@ #pragma once -#include +#include "src/widgets/colorpickerwidget.h" -class ColorPicker : public QWidget +class ColorPicker : public ColorPickerWidget { Q_OBJECT public: @@ -15,17 +15,7 @@ class ColorPicker : public QWidget void colorSelected(QColor c); protected: - void paintEvent(QPaintEvent* event) override; - void repaint(int i, QPainter& painter); - void mouseMoveEvent(QMouseEvent*) override; void showEvent(QShowEvent* event) override; void hideEvent(QHideEvent* event) override; - -private: - int m_colorAreaSize; - int m_selectedIndex, m_lastIndex; - QVector m_colorAreaList; - QVector m_colorList; - - QColor m_uiColor; + void mouseMoveEvent(QMouseEvent* e) override; }; diff --git a/src/widgets/colorpickerwidget.cpp b/src/widgets/colorpickerwidget.cpp new file mode 100644 index 0000000000..cfa71a1b73 --- /dev/null +++ b/src/widgets/colorpickerwidget.cpp @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileCopyrightText: 2022 Dearsh Oberoi + +#include "colorpickerwidget.h" +#include "src/utils/confighandler.h" +#include "src/utils/globalvalues.h" +#include +#include + +ColorPickerWidget::ColorPickerWidget(QWidget* parent) + : QWidget(parent) + , m_selectedIndex(1) + , m_lastIndex(1) +{ + initColorPicker(); +} + +const QVector& ColorPickerWidget::getDefaultSmallColorPalette() +{ + return defaultSmallColorPalette; +} + +const QVector& ColorPickerWidget::getDefaultLargeColorPalette() +{ + return defaultLargeColorPalette; +} + +void ColorPickerWidget::paintEvent(QPaintEvent* e) +{ + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + painter.setPen(QColor(Qt::black)); + + for (int i = 0; i < m_colorAreaList.size(); ++i) { + if (e->region().contains(m_colorAreaList.at(i))) { + painter.setClipRegion(e->region()); + repaint(i, painter); + } + } +} + +void ColorPickerWidget::repaint(int i, QPainter& painter) +{ + // draw the highlight when we have to draw the selected color + if (i == m_selectedIndex) { + QColor c = QColor(m_uiColor); + c.setAlpha(155); + painter.setBrush(c); + c.setAlpha(100); + painter.setPen(c); + QRect highlight = m_colorAreaList.at(i); + const int highlightThickness = 6; + + // makes the highlight and color circles concentric + highlight.moveTo(highlight.x() - (highlightThickness / 2), + highlight.y() - (highlightThickness / 2)); + + highlight.setHeight(highlight.height() + highlightThickness); + highlight.setWidth(highlight.width() + highlightThickness); + painter.drawRoundedRect(highlight, 100, 100); + painter.setPen(QColor(Qt::black)); + } + + // draw available colors + if (m_colorList.at(i).isValid()) { + // draw preset color + painter.setBrush(QColor(m_colorList.at(i))); + painter.drawRoundedRect(m_colorAreaList.at(i), 100, 100); + } else { + // draw rainbow (part) for custom color + QRect lastRect = m_colorAreaList.at(i); + int nStep = 1; + int nSteps = lastRect.height() / nStep; + // 0.02 - start rainbow color, 0.33 - end rainbow color from range: + // 0.0 - 1.0 + float h = 0.02; + for (int radius = nSteps; radius > 0; radius -= nStep * 2) { + // calculate color + float fHStep = (0.33 - h) / (nSteps / nStep / 2); + QColor color = QColor::fromHslF(h, 0.95, 0.5); + + // set color and draw circle + painter.setPen(color); + painter.setBrush(color); + painter.drawRoundedRect(lastRect, 100, 100); + + // set next color, circle geometry + h += fHStep; + lastRect.setX(lastRect.x() + nStep); + lastRect.setY(lastRect.y() + nStep); + lastRect.setHeight(lastRect.height() - nStep); + lastRect.setWidth(lastRect.width() - nStep); + + painter.setPen(QColor(Qt::black)); + } + } +} + +void ColorPickerWidget::updateSelection(int index) +{ + m_selectedIndex = index; + update(m_colorAreaList.at(index) + QMargins(10, 10, 10, 10)); + update(m_colorAreaList.at(m_lastIndex) + QMargins(10, 10, 10, 10)); + m_lastIndex = index; +} + +void ColorPickerWidget::updateWidget() +{ + m_colorAreaList.clear(); + initColorPicker(); + update(); +} + +void ColorPickerWidget::initColorPicker() +{ + ConfigHandler config; + m_colorList = config.userColors(); + m_colorAreaSize = GlobalValues::buttonBaseSize() * 0.6; + // save the color values in member variables for faster access + m_uiColor = config.uiColor(); + + // extraSize represents the extra space needed for the highlight of the + // selected color. + const int extraSize = 6; + double radius = GlobalValues::buttonBaseSize() * 2; + setMinimumSize(radius * 2 + m_colorAreaSize + extraSize, + radius * 2 + m_colorAreaSize + extraSize); + resize(radius * 2 + m_colorAreaSize + extraSize, + radius * 2 + m_colorAreaSize + extraSize); + double degree = (double)360 / m_colorList.size(); + double degreeAcum = 90; + // this line is the radius of the circle which will be rotated to add + // the color components. + QLineF baseLine = + QLineF(QPoint(radius + extraSize / 2, radius + extraSize / 2), + QPoint(radius + extraSize / 2, extraSize / 2)); + + for (int i = 0; i < m_colorList.size(); ++i) { + m_colorAreaList.append(QRect( + baseLine.x2(), baseLine.y2(), m_colorAreaSize, m_colorAreaSize)); + degreeAcum += degree; + baseLine.setAngle(degreeAcum); + } +} + +QVector ColorPickerWidget::defaultSmallColorPalette = { + QColor(), Qt::darkRed, Qt::red, Qt::yellow, Qt::green, + Qt::darkGreen, Qt::cyan, Qt::blue, Qt::magenta, Qt::darkMagenta +}; + +QVector ColorPickerWidget::defaultLargeColorPalette = { + QColor(), Qt::white, Qt::red, Qt::green, Qt::blue, + Qt::black, Qt::darkRed, Qt::darkGreen, Qt::darkBlue, Qt::darkGray, + Qt::cyan, Qt::magenta, Qt::yellow, Qt::lightGray, Qt::darkCyan, + Qt::darkMagenta, Qt::darkYellow +}; diff --git a/src/widgets/colorpickerwidget.h b/src/widgets/colorpickerwidget.h new file mode 100644 index 0000000000..4935960ae0 --- /dev/null +++ b/src/widgets/colorpickerwidget.h @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileCopyrightText: 2022 Dearsh Oberoi + +#pragma once + +#include + +class ColorPickerWidget : public QWidget +{ + Q_OBJECT +public: + explicit ColorPickerWidget(QWidget* parent = nullptr); + + static const QVector& getDefaultSmallColorPalette(); + static const QVector& getDefaultLargeColorPalette(); + void updateWidget(); + void updateSelection(int index); + +protected: + void paintEvent(QPaintEvent* event) override; + void repaint(int i, QPainter& painter); + + int m_colorAreaSize; + int m_selectedIndex, m_lastIndex; + QVector m_colorAreaList; + QVector m_colorList; + + QColor m_uiColor; + +private: + void initColorPicker(); + static QVector defaultSmallColorPalette, defaultLargeColorPalette; +}; diff --git a/src/widgets/colorspinbox.cpp b/src/widgets/colorspinbox.cpp new file mode 100644 index 0000000000..20ab5207ef --- /dev/null +++ b/src/widgets/colorspinbox.cpp @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileCopyrightText: 2022 Dearsh Oberoi + +#include "src/widgets/colorspinbox.h" +#include "src/utils/confighandler.h" + +ColorSpinBox::ColorSpinBox(QWidget* parent) + : QSpinBox(parent) +{ + initColorSpinbox(); +} + +int ColorSpinBox::valueFromText(const QString& text) const +{ + if (!QColor::isValidColor(text)) { + return 1; + } + + const QColor color = QColor(text); + + for (int i = 1; i < m_colorList.size(); ++i) { + if (m_colorList.at(i) == color) { + return i; + } + } + + return 1; +} + +QString ColorSpinBox::textFromValue(int value) const +{ + return m_colorList[value].name(QColor::HexRgb); +} + +void ColorSpinBox::initColorSpinbox() +{ + ConfigHandler config; + m_colorList = config.userColors(); + + setRange(1, m_colorList.size() - 1); + setWrapping(true); +} + +void ColorSpinBox::updateWidget() +{ + initColorSpinbox(); + update(); +} diff --git a/src/widgets/colorspinbox.h b/src/widgets/colorspinbox.h new file mode 100644 index 0000000000..65adbe745d --- /dev/null +++ b/src/widgets/colorspinbox.h @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileCopyrightText: 2022 Dearsh Oberoi + +#pragma once + +#include +#include + +class ColorSpinBox : public QSpinBox +{ + Q_OBJECT +public: + explicit ColorSpinBox(QWidget* parent = nullptr); + void updateWidget(); + +protected: + int valueFromText(const QString& text) const override; + QString textFromValue(int value) const override; + +private: + void initColorSpinbox(); + + QVector m_colorList; +}; \ No newline at end of file