Skip to content

Commit

Permalink
Gui/KnobGuiColor: added (HSV) color selector popup
Browse files Browse the repository at this point in the history
  • Loading branch information
rodlie committed Jun 13, 2021
1 parent c5f15a3 commit fdb47d6
Show file tree
Hide file tree
Showing 9 changed files with 460 additions and 3 deletions.
1 change: 1 addition & 0 deletions Global/Enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ enum PixmapEnum

NATRON_PIXMAP_OPEN_FILE,
NATRON_PIXMAP_COLORWHEEL,
NATRON_PIXMAP_COLORTRIANGLE,
NATRON_PIXMAP_OVERLAY,
NATRON_PIXMAP_ROTO_MERGE,
NATRON_PIXMAP_COLOR_PICKER,
Expand Down
284 changes: 284 additions & 0 deletions Gui/ColorSelectorWidget.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
/* ***** BEGIN LICENSE BLOCK *****
* This file is part of Natron <https://natrongithub.github.io/>,
* (C) 2018-2021 The Natron developers
* (C) 2013-2018 INRIA and Alexandre Gauthier-Foichat
*
* Natron is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Natron is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Natron. If not, see <http://www.gnu.org/licenses/gpl-2.0.html>
* ***** END LICENSE BLOCK ***** */

#include "ColorSelectorWidget.h"

CLANG_DIAG_OFF(deprecated)
CLANG_DIAG_OFF(uninitialized)
#include <QHBoxLayout>
#include <QVBoxLayout>
CLANG_DIAG_ON(deprecated)
CLANG_DIAG_ON(uninitialized)

#include "Gui/Label.h"

NATRON_NAMESPACE_ENTER

ColorSelectorWidget::ColorSelectorWidget(QWidget *parent,
int colorWheelSize) : QWidget(parent)
, spinH(0)
, spinS(0)
, spinV(0)
, slideH(0)
, slideS(0)
, slideV(0)
, triangle(0)
{
QHBoxLayout *mainLayout = new QHBoxLayout(this);
mainLayout->setContentsMargins(5, 5, 5, 10);
mainLayout->setSpacing(0);

triangle = new QtColorTriangle(this);
triangle->setColor( QColor::fromHsvF(0.0, 0.0, 0.0, 1.0) );

triangle->setMinimumSize(colorWheelSize, colorWheelSize);
triangle->setMaximumSize(colorWheelSize, colorWheelSize);
triangle->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

QWidget *hsvWidget = new QWidget(this);
QVBoxLayout *hsvLayout = new QVBoxLayout(hsvWidget);

QWidget *hWidget = new QWidget(this);
QHBoxLayout *hLayout = new QHBoxLayout(hWidget);
QWidget *sWidget = new QWidget(this);
QHBoxLayout *sLayout = new QHBoxLayout(sWidget);
QWidget *vWidget = new QWidget(this);
QHBoxLayout *vLayout = new QHBoxLayout(vWidget);

hLayout->setContentsMargins(0, 0, 0, 0);
sLayout->setContentsMargins(0, 0, 0, 0);
vLayout->setContentsMargins(0, 0, 0, 0);

slideH = new ScaleSliderQWidget(0.,
1.,
0.,
false,
ScaleSliderQWidget::eDataTypeDouble,
NULL,
eScaleTypeLinear,
this);
slideS = new ScaleSliderQWidget(0.,
1.,
0.,
false,
ScaleSliderQWidget::eDataTypeDouble,
NULL,
eScaleTypeLinear,
this);
slideV = new ScaleSliderQWidget(0.,
1.,
0.,
false,
ScaleSliderQWidget::eDataTypeDouble,
NULL,
eScaleTypeLinear,
this);

slideH->setMinimumAndMaximum(0., 1.);
slideS->setMinimumAndMaximum(0., 1.);
slideV->setMinimumAndMaximum(0., 1.);

slideH->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
slideS->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
slideV->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

spinH = new SpinBox(this, SpinBox::eSpinBoxTypeDouble);
spinS = new SpinBox(this, SpinBox::eSpinBoxTypeDouble);
spinV = new SpinBox(this, SpinBox::eSpinBoxTypeDouble);

spinH->decimals(3);
spinS->decimals(3);
spinV->decimals(3);

spinH->setIncrement(0.01);
spinS->setIncrement(0.01);
spinV->setIncrement(0.01);

spinH->setMaximum(1.);
spinH->setMinimum(0.);
spinS->setMaximum(1.);
spinS->setMinimum(0.);
spinV->setMaximum(1.);
spinV->setMinimum(0.);

Label *labelH = new Label(QString::fromUtf8("H"), this);
Label *labelS = new Label(QString::fromUtf8("S"), this);
Label *labelV = new Label(QString::fromUtf8("V"), this);

labelH->setMinimumWidth(10);
labelS->setMinimumWidth(10);
labelV->setMinimumWidth(10);

hLayout->addWidget(labelH);
hLayout->addWidget(spinH);
hLayout->addWidget(slideH);

sLayout->addWidget(labelS);
sLayout->addWidget(spinS);
sLayout->addWidget(slideS);

vLayout->addWidget(labelV);
vLayout->addWidget(spinV);
vLayout->addWidget(slideV);

hsvLayout->addWidget(hWidget);
hsvLayout->addWidget(sWidget);
hsvLayout->addWidget(vWidget);

mainLayout->addWidget(triangle);
mainLayout->addWidget(hsvWidget);

QObject::connect( triangle, SIGNAL( colorChanged(QColor) ),
this, SLOT( handleColorChanged(QColor) ) );

QObject::connect( spinH, SIGNAL( valueChanged(double) ),
this, SLOT( handleColorHChanged(double) ) );
QObject::connect( spinS, SIGNAL( valueChanged(double) ),
this, SLOT( handleColorSChanged(double) ) );
QObject::connect( spinV, SIGNAL( valueChanged(double) ),
this, SLOT( handleColorVChanged(double) ) );

QObject::connect( slideH, SIGNAL( positionChanged(double) ),
this, SLOT( handleSliderHMoved(double) ) );
QObject::connect( slideS, SIGNAL( positionChanged(double) ),
this, SLOT( handleSliderSMoved(double) ) );
QObject::connect( slideV, SIGNAL( positionChanged(double) ),
this, SLOT( handleSliderVMoved(double) ) );
}

const QColor
ColorSelectorWidget::getColor()
{
return triangle->color();
}

void
ColorSelectorWidget::setColor(const QColor &color)
{
triangle->blockSignals(true);
triangle->setColor(color);
triangle->blockSignals(false);
handleColorChanged(color, false);
}

void
ColorSelectorWidget::setH(qreal h)
{
double value = h;
if (value < 0.) {
value = 0.;
}
spinH->blockSignals(true);
slideH->blockSignals(true);
spinH->setValue(value);
slideH->seekScalePosition(value);
spinH->blockSignals(false);
slideH->blockSignals(false);
}

void
ColorSelectorWidget::setS(qreal s)
{
double value = s;
if (value < 0.) {
value = 0.;
}
spinS->blockSignals(true);
slideS->blockSignals(true);
spinS->setValue(value);
slideS->seekScalePosition(value);
spinS->blockSignals(false);
slideS->blockSignals(false);
}

void
ColorSelectorWidget::setV(qreal v)
{
double value = v;
if (value < 0.) {
value = 0.;
}
spinV->blockSignals(true);
slideV->blockSignals(true);
spinV->setValue(value);
slideV->seekScalePosition(value);
spinV->blockSignals(false);
slideV->blockSignals(false);
}

void
ColorSelectorWidget::handleColorChanged(const QColor &color, bool doEmit)
{
setH( color.toHsv().hueF() );
setS( color.toHsv().saturationF() );
setV( color.toHsv().valueF() );
if (doEmit) {
Q_EMIT colorChanged(color);
}
}

void
ColorSelectorWidget::handleColorHChanged(double value)
{
QColor color = triangle->color();
color.setHsvF( value, spinS->value(), spinV->value() );
triangle->setColor(color);
}

void
ColorSelectorWidget::handleColorSChanged(double value)
{
QColor color = triangle->color();
color.setHsvF( spinH->value(), value, spinV->value() );
triangle->setColor(color);
}

void
ColorSelectorWidget::handleColorVChanged(double value)
{
QColor color = triangle->color();
color.setHsvF( spinH->value(), spinS->value(), value );
triangle->setColor(color);
}

void
ColorSelectorWidget::handleSliderHMoved(double value)
{
spinH->setValue(value);
handleColorHChanged(value);
}

void
ColorSelectorWidget::handleSliderSMoved(double value)
{
spinS->setValue(value);
handleColorSChanged(value);
}

void
ColorSelectorWidget::handleSliderVMoved(double value)
{
spinV->setValue(value);
handleColorVChanged(value);
}

NATRON_NAMESPACE_EXIT

NATRON_NAMESPACE_USING
#include "moc_ColorSelectorWidget.cpp"
87 changes: 87 additions & 0 deletions Gui/ColorSelectorWidget.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/* ***** BEGIN LICENSE BLOCK *****
* This file is part of Natron <https://natrongithub.github.io/>,
* (C) 2018-2021 The Natron developers
* (C) 2013-2018 INRIA and Alexandre Gauthier-Foichat
*
* Natron is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Natron is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Natron. If not, see <http://www.gnu.org/licenses/gpl-2.0.html>
* ***** END LICENSE BLOCK ***** */

#ifndef Gui_ColorSelectorWidget_h
#define Gui_ColorSelectorWidget_h

#include "Global/Macros.h"

CLANG_DIAG_OFF(deprecated)
CLANG_DIAG_OFF(uninitialized)
#include <QWidget>
#include <QColor>
#include "Gui/QtColorTriangle.h" // from Qt Solutions
#include <QMouseEvent>
CLANG_DIAG_ON(deprecated)
CLANG_DIAG_ON(uninitialized)

#include "Gui/ScaleSliderQWidget.h"
#include "Gui/SpinBox.h"

NATRON_NAMESPACE_ENTER

class ColorSelectorWidget : public QWidget
{
Q_OBJECT
public:
explicit ColorSelectorWidget(QWidget *parent = NULL,
int colorWheelSize = 120);

Q_SIGNALS:
void colorChanged(const QColor &color);

public Q_SLOTS:
const QColor getColor();
void setColor(const QColor &color);
void setH(qreal h);
void setS(qreal s);
void setV(qreal v);

private:
SpinBox *spinH;
SpinBox *spinS;
SpinBox *spinV;
ScaleSliderQWidget *slideH;
ScaleSliderQWidget *slideS;
ScaleSliderQWidget *slideV;
QtColorTriangle *triangle;

private Q_SLOTS:
void handleColorChanged(const QColor &color, bool doEmit = true);
void handleColorHChanged(double value);
void handleColorSChanged(double value);
void handleColorVChanged(double value);
void handleSliderHMoved(double value);
void handleSliderSMoved(double value);
void handleSliderVMoved(double value);

// https://bugreports.qt.io/browse/QTBUG-47406
void mousePressEvent(QMouseEvent *e)
{
e->accept();
}
void mouseReleaseEvent(QMouseEvent *e)
{
e->accept();
}
};

NATRON_NAMESPACE_EXIT

#endif // Gui_ColorSelectorWidget_h
Loading

0 comments on commit fdb47d6

Please sign in to comment.