mirror of
https://github.com/fergalmoran/flameshot.git
synced 2025-12-22 09:51:06 +00:00
Customizable ColorPicker (#2202)
* Added spinbox, refactored colorpicker * Added add preset functionality * Added delete preset * Refactored code * Fix
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -11,6 +11,7 @@ target_sources(
|
||||
strftimechooserwidget.cpp
|
||||
styleoverride.cpp
|
||||
uicoloreditor.cpp
|
||||
colorpickereditor.cpp
|
||||
visualseditor.cpp
|
||||
shortcutswidget.cpp
|
||||
setshortcutwidget.cpp
|
||||
|
||||
166
src/config/colorpickereditor.cpp
Normal file
166
src/config/colorpickereditor.cpp
Normal file
@@ -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 <QApplication>
|
||||
#include <QColor>
|
||||
#include <QGridLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
|
||||
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<int>::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<QColor> 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<QColor> 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();
|
||||
}
|
||||
46
src/config/colorpickereditor.h
Normal file
46
src/config/colorpickereditor.h
Normal file
@@ -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 <QWidget>
|
||||
|
||||
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;
|
||||
};
|
||||
@@ -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());
|
||||
|
||||
@@ -13,9 +13,8 @@
|
||||
#include <QVBoxLayout>
|
||||
|
||||
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;
|
||||
|
||||
@@ -12,7 +12,7 @@ class QHBoxLayout;
|
||||
class CaptureToolButton;
|
||||
class ClickableLabel;
|
||||
|
||||
class UIcolorEditor : public QGroupBox
|
||||
class UIcolorEditor : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -3,12 +3,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QTabWidget>
|
||||
#include <QWidget>
|
||||
|
||||
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();
|
||||
|
||||
@@ -112,7 +112,7 @@ static QMap<class QString, QSharedPointer<ValueHandler>>
|
||||
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 ( "" )),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "valuehandler.h"
|
||||
#include "capturetool.h"
|
||||
#include "colorpickerwidget.h"
|
||||
#include "confighandler.h"
|
||||
#include "screengrabber.h"
|
||||
#include <QColor>
|
||||
@@ -378,10 +379,15 @@ bool ButtonList::normalizeButtons(QList<int>& 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<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,
|
||||
QColor() });
|
||||
return QVariant::fromValue(
|
||||
ColorPickerWidget::getDefaultLargeColorPalette());
|
||||
} else {
|
||||
return QVariant::fromValue(QVector<QColor>{ 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<QColor> colors = val.value<QVector<QColor>>();
|
||||
|
||||
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
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "src/widgets/capture/capturetoolbutton.h"
|
||||
#include "src/widgets/colorpickerwidget.h"
|
||||
|
||||
#include <QColor>
|
||||
#include <QList>
|
||||
@@ -193,10 +194,16 @@ public:
|
||||
|
||||
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
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -8,16 +8,11 @@
|
||||
#include <QPainter>
|
||||
|
||||
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)
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include "src/widgets/colorpickerwidget.h"
|
||||
|
||||
class ColorPicker : public QWidget
|
||||
class ColorPicker : public ColorPickerWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@@ -15,17 +15,7 @@ signals:
|
||||
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<QRect> m_colorAreaList;
|
||||
QVector<QColor> m_colorList;
|
||||
|
||||
QColor m_uiColor;
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
};
|
||||
|
||||
156
src/widgets/colorpickerwidget.cpp
Normal file
156
src/widgets/colorpickerwidget.cpp
Normal file
@@ -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 <QMouseEvent>
|
||||
#include <QPainter>
|
||||
|
||||
ColorPickerWidget::ColorPickerWidget(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, m_selectedIndex(1)
|
||||
, m_lastIndex(1)
|
||||
{
|
||||
initColorPicker();
|
||||
}
|
||||
|
||||
const QVector<QColor>& ColorPickerWidget::getDefaultSmallColorPalette()
|
||||
{
|
||||
return defaultSmallColorPalette;
|
||||
}
|
||||
|
||||
const QVector<QColor>& 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<QColor> ColorPickerWidget::defaultSmallColorPalette = {
|
||||
QColor(), Qt::darkRed, Qt::red, Qt::yellow, Qt::green,
|
||||
Qt::darkGreen, Qt::cyan, Qt::blue, Qt::magenta, Qt::darkMagenta
|
||||
};
|
||||
|
||||
QVector<QColor> 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
|
||||
};
|
||||
33
src/widgets/colorpickerwidget.h
Normal file
33
src/widgets/colorpickerwidget.h
Normal file
@@ -0,0 +1,33 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: 2022 Dearsh Oberoi
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class ColorPickerWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ColorPickerWidget(QWidget* parent = nullptr);
|
||||
|
||||
static const QVector<QColor>& getDefaultSmallColorPalette();
|
||||
static const QVector<QColor>& 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<QRect> m_colorAreaList;
|
||||
QVector<QColor> m_colorList;
|
||||
|
||||
QColor m_uiColor;
|
||||
|
||||
private:
|
||||
void initColorPicker();
|
||||
static QVector<QColor> defaultSmallColorPalette, defaultLargeColorPalette;
|
||||
};
|
||||
48
src/widgets/colorspinbox.cpp
Normal file
48
src/widgets/colorspinbox.cpp
Normal file
@@ -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();
|
||||
}
|
||||
24
src/widgets/colorspinbox.h
Normal file
24
src/widgets/colorspinbox.h
Normal file
@@ -0,0 +1,24 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: 2022 Dearsh Oberoi
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QColor>
|
||||
#include <QSpinBox>
|
||||
|
||||
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<QColor> m_colorList;
|
||||
};
|
||||
Reference in New Issue
Block a user