colordialog/wheel/gradient: implemented basic UI components for color picking

This commit is contained in:
itsmattkc
2020-04-02 13:02:30 +11:00
parent 3bec108fee
commit f3290003be
27 changed files with 792 additions and 27 deletions
+3 -1
View File
@@ -5,11 +5,13 @@
ColorButton::ColorButton(QWidget *parent) :
QPushButton(parent)
{
color_ = Color(1.0f, 1.0f, 1.0f);
connect(this, &ColorButton::clicked, this, &ColorButton::ShowColorDialog);
}
void ColorButton::ShowColorDialog()
{
ColorDialog cd(nullptr);
ColorDialog cd(nullptr, color_, this);
cd.exec();
}
+5
View File
@@ -3,6 +3,8 @@
#include <QPushButton>
#include "render/color.h"
class ColorButton : public QPushButton
{
Q_OBJECT
@@ -15,6 +17,9 @@ signals:
private slots:
void ShowColorDialog();
private:
Color color_;
};
#endif // COLORBUTTON_H
+4
View File
@@ -16,6 +16,10 @@
set(OLIVE_SOURCES
${OLIVE_SOURCES}
widget/colorwheel/colorgradientwidget.h
widget/colorwheel/colorgradientwidget.cpp
widget/colorwheel/colorswatchwidget.h
widget/colorwheel/colorswatchwidget.cpp
widget/colorwheel/colorwheelwidget.h
widget/colorwheel/colorwheelwidget.cpp
PARENT_SCOPE
@@ -0,0 +1,57 @@
#include "colorgradientwidget.h"
#include "common/lerp.h"
#include "node/node.h"
ColorGradientGLWidget::ColorGradientGLWidget(Qt::Orientation orientation, QWidget *parent) :
ColorSwatchWidget(parent),
orientation_(orientation)
{
}
void ColorGradientGLWidget::SetColors(const Color &a, const Color &b)
{
a_ = a;
b_ = b;
update();
}
Color ColorGradientGLWidget::GetColorFromCursorPos(const QPoint &p) const
{
float t;
if (orientation_ == Qt::Horizontal) {
t = static_cast<float>(p.x()) / static_cast<float>(width());
} else {
t = static_cast<float>(p.y()) / static_cast<float>(height());
}
return Color(lerp(a_.red(), b_.red(), t),
lerp(a_.green(), b_.green(), t),
lerp(a_.blue(), b_.blue(), t));
}
bool ColorGradientGLWidget::PointIsValid(const QPoint &) const
{
return true;
}
OpenGLShader *ColorGradientGLWidget::CreateShader() const
{
OpenGLShader* s = new OpenGLShader();
s->create();
s->addShaderFromSourceCode(QOpenGLShader::Vertex, OpenGLShader::CodeDefaultVertex());
s->addShaderFromSourceCode(QOpenGLShader::Fragment, Node::ReadFileAsString(QStringLiteral(":/shaders/colorgradient.frag")));
s->link();
return s;
}
void ColorGradientGLWidget::SetShaderUniformValues(OpenGLShader *shader) const
{
shader->setUniformValue("orientation", orientation_);
shader->setUniformValue("color_a", a_.red(), a_.green(), a_.blue());
shader->setUniformValue("color_b", b_.red(), b_.green(), b_.blue());
}
@@ -0,0 +1,33 @@
#ifndef COLORGRADIENTGLWIDGET_H
#define COLORGRADIENTGLWIDGET_H
#include "colorswatchwidget.h"
#include "render/color.h"
class ColorGradientGLWidget : public ColorSwatchWidget
{
Q_OBJECT
public:
ColorGradientGLWidget(Qt::Orientation orientation, QWidget* parent = nullptr);
void SetColors(const Color& a, const Color& b);
protected:
virtual Color GetColorFromCursorPos(const QPoint& p) const override;
virtual bool PointIsValid(const QPoint& p) const override;
virtual OpenGLShader* CreateShader() const override;
virtual void SetShaderUniformValues(OpenGLShader* shader) const override;
private:
Qt::Orientation orientation_;
Color a_;
Color b_;
};
#endif // COLORGRADIENTGLWIDGET_H
@@ -0,0 +1,61 @@
#include "colorswatchwidget.h"
#include <QMouseEvent>
#include "render/backend/opengl/openglrenderfunctions.h"
ColorSwatchWidget::ColorSwatchWidget(QWidget *parent) :
QOpenGLWidget(parent),
shader_(nullptr)
{
// Render with transparent background
setAttribute(Qt::WA_AlwaysStackOnTop);
}
ColorSwatchWidget::~ColorSwatchWidget()
{
CleanUp();
}
void ColorSwatchWidget::initializeGL()
{
CleanUp();
shader_ = CreateShader();
connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &ColorSwatchWidget::CleanUp);
}
void ColorSwatchWidget::paintGL()
{
shader_->bind();
shader_->setUniformValue("ove_resolution", width(), height());
SetShaderUniformValues(shader_);
shader_->release();
OpenGLRenderFunctions::Blit(shader_);
}
void ColorSwatchWidget::CleanUp()
{
delete shader_;
shader_ = nullptr;
}
void ColorSwatchWidget::mousePressEvent(QMouseEvent *e)
{
QOpenGLWidget::mousePressEvent(e);
if (PointIsValid(e->pos())) {
emit ColorChanged(GetColorFromCursorPos(e->pos()));
}
}
void ColorSwatchWidget::mouseMoveEvent(QMouseEvent *e)
{
QOpenGLWidget::mouseMoveEvent(e);
if (e->buttons() & Qt::LeftButton && PointIsValid(e->pos())) {
emit ColorChanged(GetColorFromCursorPos(e->pos()));
}
}
+45
View File
@@ -0,0 +1,45 @@
#ifndef COLORSWATCHWIDGET_H
#define COLORSWATCHWIDGET_H
#include <QOpenGLWidget>
#include "render/backend/opengl/openglshader.h"
#include "render/color.h"
class ColorSwatchWidget : public QOpenGLWidget
{
Q_OBJECT
public:
ColorSwatchWidget(QWidget* parent = nullptr);
virtual ~ColorSwatchWidget() override;
signals:
void ColorChanged(const Color& c);
protected:
virtual void initializeGL() override;
virtual void paintGL() override;
virtual void mousePressEvent(QMouseEvent* e) override;
virtual void mouseMoveEvent(QMouseEvent* e) override;
virtual void SetShaderUniformValues(OpenGLShader*) const {}
virtual Color GetColorFromCursorPos(const QPoint& p) const = 0;
virtual bool PointIsValid(const QPoint& p) const = 0;
virtual OpenGLShader* CreateShader() const = 0;
private slots:
void CleanUp();
private:
OpenGLShader* shader_;
};
#endif // COLORSWATCHWIDGET_H
+73 -10
View File
@@ -1,16 +1,81 @@
#include "colorwheelwidget.h"
#include <QPainter>
#include <QtMath>
#define RADIAN_TO_0_1_RANGE 0.15915494309188486110703542313983
#include "node/node.h"
ColorWheelWidget::ColorWheelWidget(QWidget *parent) :
QWidget(parent)
#define M_180_OVER_PI 57.295791433133264917914229473464
ColorWheelGLWidget::ColorWheelGLWidget(QWidget *parent) :
ColorSwatchWidget(parent),
hsv_value_(1.0f)
{
}
void ColorWheelGLWidget::SetHSVValue(float val)
{
hsv_value_ = val;
update();
}
Color ColorWheelGLWidget::GetColorFromCursorPos(const QPoint &p) const
{
QPoint center = rect().center();
qreal opposite = p.y() - center.y();
qreal adjacent = p.x() - center.x();
qreal distance = qSqrt(qPow(adjacent, 2) + qPow(opposite, 2));
qreal hue = qAtan2(opposite, adjacent) * M_180_OVER_PI + 180.0;
qreal sat = (distance / GetRadius());
qreal value = hsv_value_;
return Color::fromHsv(hue, sat, value);
}
bool ColorWheelGLWidget::PointIsValid(const QPoint &p) const
{
QPoint center = rect().center();
qreal distance = qSqrt(qPow(p.x() - center.x(), 2) + qPow(p.y() - center.y(), 2));
return (distance <= GetRadius());
}
OpenGLShader *ColorWheelGLWidget::CreateShader() const
{
OpenGLShader* s = new OpenGLShader();
s->create();
s->addShaderFromSourceCode(QOpenGLShader::Vertex, OpenGLShader::CodeDefaultVertex());
s->addShaderFromSourceCode(QOpenGLShader::Fragment, Node::ReadFileAsString(QStringLiteral(":/shaders/colorwheel.frag")));
s->link();
return s;
}
void ColorWheelGLWidget::SetShaderUniformValues(OpenGLShader *shader) const
{
shader->setUniformValue("hsv_value", hsv_value_);
}
void ColorWheelGLWidget::resizeEvent(QResizeEvent *e)
{
ColorSwatchWidget::resizeEvent(e);
emit DiameterChanged(GetDiameter());
}
int ColorWheelGLWidget::GetDiameter() const
{
return qMin(width(), height());
}
qreal ColorWheelGLWidget::GetRadius() const
{
return GetDiameter() * 0.5;
}
/* Software/QPainter-based color wheel
void ColorWheelWidget::paintEvent(QPaintEvent *event)
{
QWidget::paintEvent(event);
@@ -20,12 +85,10 @@ void ColorWheelWidget::paintEvent(QPaintEvent *event)
qreal radius = qMin(width(), height()) / 2;
QPoint center = rect().center();
p.setPen(Qt::red);
int x_start = center.x() - radius;
int x_end= center.x() + radius;
int x_end = center.x() + radius;
int y_start = center.y() - radius;
int y_end= center.y() + radius;
int y_end = center.y() + radius;
for (int i=x_start;i<x_end;i++) {
for (int j=y_start;j<y_end;j++) {
@@ -46,4 +109,4 @@ void ColorWheelWidget::paintEvent(QPaintEvent *event)
}
}
}
}
}*/
+39 -4
View File
@@ -1,16 +1,51 @@
#ifndef COLORWHEELWIDGET_H
#define COLORWHEELWIDGET_H
#include <QWidget>
#include <QOpenGLWidget>
class ColorWheelWidget : public QWidget
#include "colorswatchwidget.h"
#include "render/backend/opengl/openglshader.h"
#include "render/color.h"
class ColorWheelGLWidget : public ColorSwatchWidget
{
Q_OBJECT
public:
ColorWheelGLWidget(QWidget* parent = nullptr);
void SetHSVValue(float val);
signals:
void DiameterChanged(int radius);
protected:
virtual Color GetColorFromCursorPos(const QPoint& p) const override;
virtual bool PointIsValid(const QPoint& p) const override;
virtual OpenGLShader* CreateShader() const override;
virtual void SetShaderUniformValues(OpenGLShader* shader) const override;
virtual void resizeEvent(QResizeEvent* e) override;
private:
int GetDiameter() const;
qreal GetRadius() const;
float hsv_value_;
};
/*class ColorWheelWidget : public QWidget
{
public:
ColorWheelWidget(QWidget* parent = nullptr);
protected:
virtual void paintEvent(QPaintEvent* event) override;
virtual void paintEvent(QPaintEvent* e) override;
};
};*/
#endif // COLORWHEELWIDGET_H